友情支持
如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜
有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。
公众号的微信号是: jikerizhi 。因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。 |
7. 锁
7.1. 全局锁
全局锁就是对整个数据库实例加锁。
-
FLUSH TABLES WITH READ LOCK
— 简称 FTWRL。让整个库处于只读状态,数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)和更新类事务的提交语句都会被阻塞。通常用于全库逻辑备份,保证数据是出于某个时间点的。如果客户端链接异常中断,那么锁会自动释放。 -
mysqldump
+–single-transaction
参数 — 当mysqldump
使用参数–single-transaction
的时候,导数据之前就会启动一个事务,来确保拿到一致性视图。而由于 MVCC 的支持,这个过程中数据是可以正常更新的。这就要求引擎支持 MVCC,像 MyISAM 引擎就不行。 -
SET GLOBAL readonly = TRUE
— 客户端链接断开也不会释放锁;通常判断是否为只读库也是使用readonly
的值来判断,影响面更大。
FTWRL 前有读写的话, FTWRL 都会等待读写执行完毕后才执行。FTWRL 执行的时候要刷脏页的数据到磁盘,因为要保持数据的一致性 ,理解的执行 FTWRL 时候是 所有事务 都提交完毕的时候。
全库只读 readonly = true
在 slave 上,如果用户有超级权限的话 readonly 是失效的。
7.2. 表级锁
7.2.1. 表锁 LOCK TABLES tableName READ/WRITE
-
共享锁 Shared Lock,简称 S 锁
-
独占锁 Exclusive Lock,也称排他锁,简称 X 锁
-
意向共享锁 Intention Shared Lock,简称 IS 锁。当事务准备在某条记录上加 S 锁时,需要先在表级别加一个 IS 锁。
-
意向独占锁 Intention Exclusive Lock,简称 IX 锁。当事务准备在某条记录上加 X 锁时,需要先在表级别加一个 IX 锁。
意向共享锁 和 意向独占锁 并不是真正的锁,而是相当于一个公告牌。表示有记录被锁定了。避免在锁表(对表加 共享锁 或 独占锁 时去遍历全部记录。) |
7.2.2. 元数据锁 MDL(metadata lock)
当对一个表做增删改查操作的时候,加 MDL 读锁;当要对表做结构变更操作的时候,加 MDL 写锁。
另外,MDL 锁是自动加的,如果事务长时间不提交,也会导致整个库挂掉。所以,要尽量避免耗时长的事务。
7.2.3. AUTO-INC 锁
AUTO_INCREMENT 有两种实现方式:
-
AUTO-INC 锁,在执行插入语句时,就加一个表级别的 AUTO-INC 锁,然后为每条待插入记录的 AUTO_INCREMENT 列分配递增的值。锁单个插入语句,完成插入即释放锁。
-
轻量级锁,为插入语句的 AUTO_INCREMENT 列获取轻量级锁,在生成所需要的值后,就释放该锁,而不需要等待完成插入后才释放。插入数据有可能是乱序的,导致主从复制不安全。
可以通过设置 innodb_autoinc_lock_mode
来控制使用哪种方式: 0
即 AUTO-INC 锁;2
即轻量级锁; 1
是混着用(插入数量确定时采用轻量级锁;不确定时采用 AUTO-INC 锁)。
7.3. 行锁
7.3.1. Record Lock
Record Lock 即是常说的行锁,仅仅把一条记录锁上。
Record Lock 有 S 锁 和 X 锁之分。
S 锁 和 X 锁类似 Java 中的 |
7.3.2. 间隙锁 Gap Lock
间隙锁主要是为了解决插入时的幻读问题。由于插入时,还没有数据记录,所以,无法创建该数据对应的 Record Lock。所以,提出了 Gap Lock 锁。
Gap Lock 的作用仅仅是为了防止插入幻影记录而已。
给一条记录加 Gap 锁,则不允许其他事务向这条记录前面的插入新记录。为了解决之后可能插入新记录的问题,可以在索引中最后一条记录所在页面的 Supremum
记录(表示该页中最大的记录)上加 Gap 锁,这样就可以阻止其他事务插入新记录了。
7.3.3. Next-Key Lock
Next-Key Lock = Record Lock + Gap Lock。
7.3.4. 插入意向锁 Insert Intention Lock
在内存中生成的一个锁结构,表示有事务想在某个间隙插入新记录,但是现在处于等待状态。
插入意向锁并不会阻止别的事务继续获取该记录上的任何类型的锁,非常鸡肋。