mysql Innodb和mvcc

版权声明:转载请标明来源 https://blog.csdn.net/u010652576/article/details/78305943

本文主要解说mysql的Innodb存储引擎和相关mvcc相关内容。下面的解说都是依据Innodb引擎。

mysql的常用的存储引擎有Innodb和MyISAM两种,因为Innodb支持事务、行级锁、mvcc,因此5.7以后默认存储引擎为Innodb,至于两者更具体的细节,可以搜索,这里就不在说明。
mysql默认的事务隔离级别:可重复读,即:保证同一事务内,两次读取同一数据,保证数据是一致的,不会发生更改。同时mysql通过mvcc机制,解决了脏读问题。

MVCC 多版本并发控制协议(Multi-Version Concurrency Control)

详细的多版本并发控制协议就不在详细说明,想了解更多,可以搜索查看,下面主要介绍一下Innodb对mvcc的实现。
在InnoDB的MVCC,在每行记录后面保存两个隐藏的列来实现的,这两个列,分别保存了该行的创建时间(ctime),一个保存的是行的删除时间(dtime)。这里存储的并不是实际的时间值,而是系统版本号(也可以理解为事务的ID),每开始一个新的事务,系统版本号就会自动递增,事务开始时刻的系统版本号会作为事务的ID,这样就保证每个事务ID的唯一性。

1 insert操作

每次插入的时候,把当前系统版本号作为ctime的版本号,如果插入的版本号大于查询事务的版本号,那么肯定不会发生脏读,如果小于,会不会出现脏读。例如刚才查询时,事务5先启动,然后进行了插入操作,并且提交了,那么事务6是否可以查看到?等待下篇文章分析。

2 select操作

每次查询都会有两个隐藏条件,只查询ctime不大于当前事务id和dtime小于当前事务id的行,这样就排除了其他事务新增、删除的数据。
特例:如果事务ID为5,什么也不做,当事务6查询时,事务5新增一条数据,但是还没有提交,那么该条数据的事务id为5,那么事务6再次查询时会不会查到事务5新增的数据?
说明:(1) mysql的默认事务是读已提交和可重复读,无论是那种隔离级别,都不会发生事务6读取事务5新增的数据,这涉及到mysql的缓存问题,等待下一篇讨论。
(2) 如果事务5已经提交了,那么事务6是否可以读取到呢?具体等待下一篇讨论。

3 delete操作

删除数据,并不会立刻删除数据,而是把dtime的版本号设置为当前事务ID。这样同一事务内的查询是不会有影响的,因为当前的删除版本号大于查询的版本号。

4 update操作

mysql进行更新时,并不是直接在原数据上进行修改。实际上是新插入了一行记录,并保存其创建时间为当前事务的ID,同时保存当前事务ID到要UPDATE的行的删除时间。这样就新增的修改数据的版本号大于当前查询的版本号,因此其他事务的修改,并不影响当前事务的查询,如果:修改的版本号低于当前查询的版本号,并且修改的事务已经提交了,如何保证可重复读?

猜你喜欢

转载自blog.csdn.net/u010652576/article/details/78305943