1、概述
MySQL 表级锁是以单个表为粒度的锁,InnoDB 和 MyISAM 引擎都支持表级锁;
2、表锁分类及原理
2.1 表级共享锁和表级排它锁
加锁方式:lock tables … read/write;
解锁方式:可以使用 unlock table; 主动解锁,也可以等客户端断开连接时自动释放;
兼容性:
共享锁可以兼容其他共享锁,但不兼容排它锁,排它锁则不兼容任何锁;
注意:
lock tables 语法除了会限制别的线程的读写外,也限定了本线程的操作对象;
举例说明:如果在某个线程 A 中执行 lock table t1 read, t2 write; 这个语句,则其他线程写 t1、读写 t2 的语句都会被阻塞。同时,线程 A 在执行 unlock tables 之前,也只能执行读 t1、读写 t2 的操作。连写 t1 都不允许,自然也不能访问其他表;
2.2 意向共享锁和意向排它锁
意向锁是用来解决表级锁和行级锁的共存问题的,那么它如何做到呢?
例如:事务 A 在表的某一行中加了记录锁,事务 B 想在该表上添加表级排它锁,这时,事务 B 想要知道是否可以添加表级排它锁,就要做全表扫描,看是否有记录上有记录锁,这样效率极其低下,基本不可用,这时就需要意向锁来解决该问题;
有了意向锁之后,事务 A 在申请记录锁之前,数据库会自动先给事务 A 先申请表的意向排他锁,当事务 B 去申请表级排它锁时就会失败,因为表上有意向排他锁之后事务 B 申请表级排它锁时会被阻塞,这样事务 B 就避免了全表扫描操作了;
所以,总结一下意向锁的作用:
当一个事务在需要获取资源的锁定时,数据库会自动给该事务申请一个该表的意向锁,如果需要一个共享锁定,就申请一个意向共享锁,如果需要排他锁定,则申请一个意向排他锁,这样其他事务再来申请资源的时候,就不用扫描全表来判断是否有冲突了;
2.3 自增锁
自增锁是一种专门针对 AUTO_INCREMENT 类型的列的锁,用来保证自增主键的顺序和唯一性,有几种模式可选,通过 innodb_autoinc_lock_mode 参数来设置模式,同一种模式对于不同的插入类型起到的作用会不同;
2.3.1 插入类型
Simple Insert(简单插入):
插入的记录数以及内容都确认,语句包括:insert into values、replace;
Bulk Insert(批量插入):
插入的记录数不能马上确认,语句包括:INSERT ... SELECT、REPLACE ... SELECT、LOAD DATA;
Mixed-mode Insert(混合插入):
指插入的值中有部分 value 的 id 确认,另一部分则默认自增,如:
- INSERT INTO t1 (c1,c2) VALUES (1,‘a‘), (NULL,‘b‘), (5,‘c‘), (NULL,‘d‘);
- INSERT ... ON DUPLICATE KEY UPDATE;
2.3.2 自增模式
innodb_autoinc_lock_mode = 0
优点:极其安全;
缺点:写入性能差,任何一种 Insert 语句,都会产生一个自增锁,即:所有的插入语句都串行执行;
innodb_autoinc_lock_mode = 1
优点:非常安全,对于 “innodb_autoinc_lock_mode = 0”,性能要好很多;
缺点:依然会产生自增锁;
运行原理:
- 当发生 Bulk Inserts 时,会产生一个特殊的自增锁直到语句结束,注意:(这里是语句结束就释放锁,并不是事务结束哦,因为一个事务可能包含很多语句),对于 Simple Inserts,则使用的是一种轻量级锁,只要获取了相应的自增 key 就释放锁,并不会等到语句结束;
- 当有自增锁时,这种轻量级的锁也不会加锁成功,会等待;
思考:这里的自增锁起到什么作用呢?
他能保证 Bulk Insert 自增 id 的连续性,防止在 Bulk Insert 的时候,被其他的插入语句抢走自增值;
innodb_autoinc_lock_mode = 2
优点:性能最好;
缺点:Bulk Insert 时可能得到不连续的自增 id,SBR 模式下,会导致复制出错;
原理:当进行 Bulk Insert 的时候,不会产生自增锁,因为它是允许其他插入语句同时进行插入,来一个记录,插入分配一个自增值,不会预分配;
2.4 MDL 读锁和 MDL 写锁
MDL 锁也叫元数据锁,不需要显示添加,是在访问表的时候自动添加,若在表上做增删改查,则添加 MDL 读锁,若对表结构进行变更,则添加 MDL 写锁;
读锁之间不互斥,读写锁、写锁之间互斥;
3、总结
- InnoDB 和 MySIAM 都支持表级锁;
- 表级共享锁和表级排它锁可以主动加锁解锁,其他表级锁都不需要主动操作;
- 意向锁解决了表级锁和行级锁共存的问题;
- 自增锁有三种模式可选,我们可根据业务需要灵活配置;
- MDL 锁只在修改表结构的时候起作用;
4、参考资料
- 表级共享锁和表级排它锁:极客时间《MySQL实战45讲》
- 意向锁:https://blog.csdn.net/zcl_love_wx/article/details/82015281
- 自增锁:https://blog.csdn.net/luolaifa000/article/details/81099622
- 自增锁:http://blog.itpub.net/15498/viewspace-2141640/
- MDL 锁:极客时间《MySQL实战45讲》
5、遗留问题
MySQL 的 SBR 模式是什么,如何工作,有什么优缺点?
网友评论