mysql Innodb和mvcc

本文介绍MySQL InnoDB存储引擎中MVCC(多版本并发控制)的实现原理,包括插入、查询、删除和更新操作如何利用ctime和dtime来保证事务的一致性和隔离性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文主要解说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的行的删除时间。这样就新增的修改数据的版本号大于当前查询的版本号,因此其他事务的修改,并不影响当前事务的查询,如果:修改的版本号低于当前查询的版本号,并且修改的事务已经提交了,如何保证可重复读?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值