首页 > 数据库 >MySQL-锁

MySQL-锁

时间:2023-12-27 22:55:06浏览次数:33  
标签:记录 MySQL 索引 child 数据 id

按粒度划分

全局锁

概念

全局锁就是对整个数据库实例加锁。

应用场景

全库逻辑备份(mysqldump)

实现方式

MySQL 提供了一个加全局读锁的方法,命令是Flush tables with read lock (FTWRL)。

当你需要让整个库处于只读状态的时候,可以使用这个命令,之后其他线程的以下语句会被阻塞:数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)和更新类事务的提交语句。

风险点

如果在主库上备份,那么在备份期间都不能执行更新,业务基本上就能停止。

如果在从库上备份,那么备份期间从库不能执行主库同步过来的binlog,会导致主从延迟。

解决办法

mysqldump使用参数--single-transaction,启动一个事务,确保拿到一致性视图。而由于MVCC的支持,这个过程中数据是可以正常更新的。

表级锁

 概念

当前操作的整张表加锁,最常使用的 MyISAM 与 InnoDB 都支持表级锁定。

MySQL 里面表级别的锁有两种:一种是表锁,一种是元数据锁(meta data lock,MDL)。

实现方式

表锁:lock tables … read/write;

页级锁

概念

页级锁是 MySQL 中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。因此,采取了折衷的页级锁,一次锁定相邻的一组记录。BDB 引擎支持页级锁。

行级锁

概念

行级锁是粒度最低的锁,发生锁冲突的概率也最低、并发度最高。但是加锁慢、开销大,容易发生死锁现象。

MySQL中只有InnoDB支持行级锁,行级锁分为共享锁和排他锁。

实现方式

在MySQL中,行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果一条sql语句操作了主键索引,MySQL就会锁定这条主键索引;如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。在UPDATE、DELETE操作时,MySQL不仅锁定WHERE条件扫描过的所有索引记录,而且会锁定相邻的键值,即所谓的next-key locking。

按模式分类

乐观锁

(1) 概念

乐观锁是相对悲观锁而言的,乐观锁假设数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则返回给用户错误的信息,让用户决定如何去做。

(2) 应用场景

适用于读多写少,因为如果出现大量的写操作,写冲突的可能性就会增大,业务层需要不断重试,会大大降低系统性能。

(3) 实现方式

一般使用数据版本(Version)记录机制实现,在数据库表中增加一个数字类型的“version”字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据。

悲观锁

(1) 概念

悲观锁,正如其名,具有强烈的独占和排他特性,每次去拿数据的时候都认为别人会修改,对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。

(2) 应用场景

适用于并发量不大、写入操作比较频繁、数据一致性比较高的场景。

(3) 实现方式

在MySQL中使用悲观锁,必须关闭MySQL的自动提交,set autocommit=0。共享锁和排它锁是悲观锁的不同的实现,它俩都属于悲观锁的范畴。

按属性分类

共享锁

(1) 概念

共享锁,又称之为读锁,简称S锁,当事务A对数据加上读锁后,其他事务只能对该数据加读锁,不能做任何修改操作,也就是不能添加写锁。只有当事务A上的读锁被释放后,其他事务才能对其添加写锁。

(2) 应用场景

共享锁主要是为了支持并发的读取数据而出现的,读取数据时,不允许其他事务对当前数据进行修改操作,从而避免”不可重读”的问题的出现。

适合于两张表存在关系时的写操作,拿mysql官方文档的例子来说,一个表是child表,一个是parent表,假设child表的某一列child_id映射到parent表的c_child_id列,那么从业务角度讲,此时我直接insert一条child_id=100记录到child表是存在风险的,因为刚insert的时候可能在parent表里删除了这条c_child_id=100的记录,那么业务数据就存在不一致的风险。正确的方法是再插入时执行select * from parent where c_child_id=100 lock in share mode,锁定了parent表的这条记录,然后执行insert into child(child_id)values (100)就不会存在这种问题了。

(3) 实现方式

select …lock in share mode

排它锁

(1) 概念

排它锁,又称之为写锁,简称X锁,当事务对数据加上写锁后,其他事务既不能对该数据添加读写,也不能对该数据添加写锁,写锁与其他锁都是互斥的。只有当前数据写锁被释放后,其他事务才能对其添加写锁或者是读锁。

MySQL InnoDB引擎默认update,delete,insert都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型。

(2) 应用场景

写锁主要是为了解决在修改数据时,不允许其他事务对当前数据进行修改和读取操作,从而可以有效避免”脏读”问题的产生。

(3) 实现方式

select …for update

按状态分类分类

意向共享锁和意向排它锁

1. 概念

意向锁是表锁,为了协调行锁和表锁的关系,支持多粒度(表锁与行锁)的锁并存。

2. 作用

当有事务A有行锁时,MySQL会自动为该表添加意向锁,事务B如果想申请整个表的写锁,那么不需要遍历每一行判断是否存在行锁,而直接判断是否存在意向锁,增强性能。

  意向共享锁(IS) 意向排他锁(IX)
共享锁(S) 兼容 互斥
排他锁(X) 互斥 互斥

 

 

按算法分类

记录锁

记录锁是封锁记录,记录锁也叫行锁,例如:

select *from goods where **`id`=**1 for update;

它会在 id=1 的记录上加上记录锁,以阻止其他事务插入,更新,删除 id=1 这一行。

间隙锁

间隙锁基于非唯一索引,它锁定一段范围内的索引记录。使用间隙锁锁住的是一个区间,而不仅仅是这个区间中的每一条数据。

select* from goods where id between 1 and 10 for update;

即所有在(1,10)区间内的记录行都会被锁住,所有id 为 2、3、4、5、6、7、8、9 的数据行的插入会被阻塞,但是 1和 10 两条记录行并不会被锁住。

临键锁

临键锁,是记录锁与间隙锁的组合,它的封锁范围,既包含索引记录,又包含索引区间,是一个左开右闭区间。临键锁的主要目的,也是为了避免幻读(Phantom Read)。如果把事务的隔离级别降级为RC,临键锁则也会失效。

每个数据行上的非唯一索引列上都会存在一把临键锁,当某个事务持有该数据行的临键锁时,会锁住一段左开右闭区间的数据。需要强调的一点是,InnoDB 中行级锁是基于索引实现的,临键锁只与非唯一索引列有关,在唯一索引列(包括主键列)上不存在临键锁。


标签:记录,MySQL,索引,child,数据,id
From: https://www.cnblogs.com/nxjblog/p/17931607.html

相关文章

  • MYSQL高级SQL语句
    SQL语句----SELECT----显示表格中一个或数个字段的所有数据记录语法:SELECT"字段"FROM"表名";SELECTStore_NameFROMStore_Info;----DISTINCT----不显示重复的数据记录语法:SELECTDISTINCT"字段"FROM"表名";SELECTDISTINCTStore_NameFROMStore_Info;-......
  • mysql怎么保证高可用的?
    分布式系统,高可用是一个很重要的指标。当选择mysql作为分布式系统的数据库,高可用也是必须要考虑的。那么,mysql是如何保证高可用的呢?有的同学可能听过一个词,叫做:mysql主备。对,mysql就是通过主备来保证高可用。搭建mysql主备,需要那些组件呢?见名思义,首先需要一个主库,一个备库......
  • MySQL数据库-3
    MySQL数据库-3第14章_视图#第14章_视图/*1.视图的理解视图,可以看做是一个虚拟表,本身是不存储数据的。视图的本质,就可以看做是存储起来的SELECT语句视图中SELECT语句中涉及到的表,称为基表针对视图做DML操作,会影响到对应的基表中的数据。反之亦然。视图本身的删除,不会导致......
  • mysql_real_query与mysql_query 区别
    mysql_real_query(&mysql,sql,strlen(sql));//多了一个长度mysql_query(&mysql,sql);1、mysql_real_querysql语句中可以包含二进制数据,调用的时候多一个strlen2、mysql_querysql语句只能是字符串,当数据里有0的时候,直接就停了调用的时候  ***多次调用会出现//Comm......
  • MySQL 事务日志
    MySQL事务日志事务有4种特性:原子性,一致性,隔离性和持久性。那么事务的四种特性到底是基于什么机制实现呢(是通过什么来控制的呢)?事务的"隔离性"由锁机制实现(通过加锁来实现隔离)。而事务的"原子性","一致性"和"持久性"由事务的redo日志和undo 日志来保证redolog称......
  • MySQL 8用户及权限管理
    官方链接:https://dev.mysql.com/doc/refman/8.0/en/create-user.htmlTheoptionalWITHclauseisusedtoenableausertograntprivilegestootherusers.TheWITHGRANTOPTIONclausegivestheusertheabilitytogivetootherusersanyprivilegestheuserhas......
  • MySQL 事务的基础知识
    事务的基础知识1.数据库事务概述事务是数据库区别于文件系统的重要特性之一,当我们有了事务就会让数据库中的数据始终保持一致性,同时我们还能通过事务的机制恢复到某个时间地点的数据,这样可以保证已提交到数据库的修改不会因为系统崩溃而丢失。1.1存储引擎的支持情况查询当......
  • 麒麟下mysql安装及使用
    1、进入软件商店--搜索mysql--安装mysql服务器和mysql工作台,重新启动系统;2、检测mysql版本:显示mysqlver8.0.33终端命令:mysql--version 3、启动mysql服务进程终端命令:sudosystemctlmysql4、查看服务状态终端命令:sudosystemctlstatusmysql按esc--:q退出vim返回终......
  • 20 mysql 隔离性的底层原理
    隔离性的原理:1.0隔离性是通过锁机制实现的。当一个事务修改数据时,需要先获取锁。其它事务要修改数据,必须等待之前的事务提交或者回滚,然后释放锁操作之后。myisam只支持表锁,innodb支持表锁和行锁。因为表锁比较影响性能,所以通常情况下,使用行锁就可以了。2.0隔离性的另外一个方面,就是......
  • 18-mysql索引
    一、b+树每次查找数据时把磁盘IO次数控制在一个很小的数量级,最好是常数数量级。那么我们就想到如果一个高度可控的多路搜索树是否能满足需求呢?就这样,b+树应运而生(B+树是通过二叉查找树,再由平衡二叉树,B树演化而来)。1.索引字段要尽量的小:通过上面的分析,我们知道IO次数取决于b+数......