MySQL在InnoDB存储引擎下的加锁规则探讨(一)

本文详细分析了MySQL InnoDB存储引擎在不同隔离级别下的快照读和当前读,特别是当前读(加锁)在各种场景下的表现。以删除操作为例,讨论了在主键、唯一索引、普通索引以及无索引情况下的加锁行为,并通过实例展示了RC和RR隔离级别的加锁差异。此外,还提到了在Serializable隔离级别下,所有读操作都变为当前读,导致并发性降低。
摘要由CSDN通过智能技术生成

本文是在看了何登成大神的技术博客后做的总结,部分图片来自其技术博客,主要是方便自己日后回顾,在此感谢原博客作者提供的经典之作,原作者博客地址:http://hedengcheng.com/?p=771#_Toc374698322

一、什么是快照读与当前读

MVCC(多版本并发控制协议)在InnoDB存储引擎中主要提供两种读方式,一种是快照读,一种是当前读。

快照读:

所谓快照读就是一致性非锁定读,就是读取的是历史版本,不用加锁,提高并发,在数据库不同的隔离级别下读取的历史版本有所不同,在RR(REPEATABLE READ)隔离级别下读的历史版本总是事务刚开始的那一个版本,所以可以避免不可重复读与幻读,因为其对其他事务提交的数据是不可见的。在RC(READ COMMITTED)隔离级别下读的是最新的历史版本,或者是可见版本(另一个事务刚已经提交的数据),这样就会出现不可重复读现象。

SELECT * FROM table WHERE ........

当前读:

当前读时一致性锁定读,采取加锁的方法保证并发数据的一致性:

SELECT * FROM table WHERE ...  LOCK IN SHARE MODE(加的是共享锁(S))

SELECT * FROM table WHERE ...  FOR UPDATE(加的是排他锁(X))

INSERT INTO table ........ (在插入数据前先读取数据,进行唯一性检查,读取数据时会加X锁)

UPDATE table SET .........  (在更新数据之前得先读取数据,在对读取的数据进行修改,读取数据时会加X锁)

DELETE FROM table ........(在删除数据之前也是得先读取数据,读取数据时会对数据加X锁)

说明:在serializable隔离级别下,MVCC退化成了base-lock concurrency control(基于锁的并发控制),也就不存在快照读了,全是当前读,序列化的操作,并发性受到了很大的影响,一般不采用该隔离级别。

二、加锁分析的前提

对于sql加锁的分析,是有一些前提条件的,不能笼统的说加没加锁,加了什么锁。得看过滤条件是不是主键,如果不是主键,有没有索引,索引是否是唯一索引,当前数据库的隔离级别是什么,该sql语句的执行计划是什么(全表扫还是索引扫描)。以上这些就是所说的分析加锁的前提条件,在分析加锁时,得先判断是这些前提条件的那种组合。

对于快照读,也就是不加锁的方式,就不予分析了,对于当前读,选取delete from t1 where id = 10语句对九种组合进行加锁分析:

组合一:id列是主键,RC隔离级别

组合二:id是唯一索引,RC隔离级别

组合三:id是普通索引,非唯一,RC隔离级别

组合四:id没有索引,RC隔离级别

组合五:id是主键,RR隔离级别

组合六:id是唯一索引,RR隔离级别

组合七:id是普通索引,非唯一,RR隔离级别

组合八:id没有索引,RR隔离级别

组合九:serializable隔离级别

三、实例分析

1、组合一:id列是主键,RC隔离级别

表t1:

sql语句:DELETE FROM t1 WHERE id = 10

加锁情况见下图:

测试:

上图中指出了在这种组合下面会对相应的主键记录进行加锁,加的是record lock。

模拟事务A删除id为10的记录,未提交,事务B查询(当前读)id为10的记录,出现锁阻塞:

从上面可见对主键id进行了加锁处理。

 

2、组合二

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值