Mysql技术内幕之InnoDB锁探究 (2)

Mysql技术内幕之InnoDB锁探究

image-20201222084952786

上图直观地展现了InnoDB存储引擎一致性的非锁定读。之所以称为非锁定读,因为不需要等待访问的行上X锁的释放。快照数据是指该行的之前版本

的数据,该实现是通过undo段来完成。而undo用来在事务中回滚数据,因此快照数据本身是没有额外的开销。此外,读取快照数据是不需要上锁的,

因为没有事务需要对历史的数据进行修改操作。

通过上图可以知道,快照数据其实就是当前行数据之前的历史版本,每行记录可能有多个版本,一般称这种技术为行多版本技术。由此带来的并发控制,

称之为多版本并发控制(Multi Version Concurrency Control, MVCC)。

在事务隔离级别READ COMMITTED和REPEATABLE READ下,InnoDB存储引擎使用非锁定的一致性读。然而,对于快照数据的定义却不相同。在READ

COMMITTED事务隔离级别下,对于快照数据,非一致性读总是读取被锁定行的最新一份快照数据。而在REPEATABLE READ事务隔离级别下,对于快照

数据,非一致性读总是读取事务开始时的行数据版本。如下表所示示例:

时间 会话A 会话B
1   begin      
2   select * from t_user where id = 1;      
3       begin  
4       update t_user set id = 10 where id = 1;  
5   select * from t_user where id = 1;      
6       commit;  
7   select * from t_user where id = 1;      
8   commit;      

假设原本id = 1的记录是存在的,大家可以按上表时间顺序执行对应的会话,比较及验证2者的不同。

2.3 一致性锁定读

在默认配置下,在事务的隔离级别为REPEATABLE READ模式下,InnoDB存储引擎的select操作使用一致性非锁定读。但是在某些情况下,用户需要显示地

对数据库读取操作进行加锁以保证数据逻辑的一致性。而这要求数据库支持加锁语句,即使时对于select的只读操作。InnoDB存储引擎对于select语句支持两

种一致性的锁定读(locking read)操作:

select ··· for update

select ··· lock in share mode

select ··· for update对读取的行记录加一个X锁,其他事务不能对已锁定的行加上任何锁。select ··· lock in share mode对读取的行记录加一个S锁,其他事务可

以向被锁定的行加S锁,但是如果加X锁,则会被阻塞。

对于一致性非锁定读,即使读取的行已被执行了select ··· for update,也是可以进行读取的。此外,select ··· for update或者select ··· lock in share mode必须在

一个事务中,当事务提交了,锁也就释放了。因此在使用上述两种select锁定语句时,务必加上begin,start transaction或者set autocommit=0。

3 锁的算法 3.1行锁的3中算法

InnoDB存储引擎有3种行锁的算法,其分别是:

Record Lock:单个行记录上的锁

Gap Lock:间隙锁,锁定一个范围,但不包含记录本身

Next-Key Lock:Gap Lock + Record Lock,锁定一个范围,并且锁定记录本身

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfggd.html