ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
多版本并发控制(Multi-Version Concurrency Control, MVCC)是 MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,用于实现提交读和可重复读这两种隔离级别。而未提交读隔离级别总是读取最新的数据行,要求很低,无需使用 MVCC。可串行化隔离级别需要对所有读取的行都加锁,单纯使用 MVCC 无法实现 > MVCC只能在REPEATTABLE READ和READ COMMITED两个隔离级别下工作 ### 基本思想 在封锁一节中提到,加锁能解决多个事务同时执行时出现的并发一致性问题。在实际场景中读操作往往多于写操作,因此又引入了读写锁来避免不必要的加锁操作,例如读和读没有互斥关系。读写锁中读和写操作仍然是互斥的,而 MVCC 利用了多版本的思想,写操作更新最新的版本快照,而读操作去读旧版本快照,没有互斥关系,这一点和 CopyOnWrite 类似。 在 MVCC 中事务的修改操作(DELETE、INSERT、UPDATE)会为数据行新增一个版本快照,MVCC是通过保存数据在某一个时间点的快照来实现的,也就是说无论事务执行多久,每个事务看到的数据都是一致的。InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现,这两个列一个保存了行的创建时间,一个保存了行的过期时间(或删除时间),当然,并非存储的是时间,而是系统版本号。每开启一个事务,版本号都会递增,事务开始时刻的系统版本号会作为事务的版本号 ![](https://img.kancloud.cn/b2/a7/b2a79f6708d1894d900af3e45f278416_1104x230.png) #### SELECT * 只查询创建时间版本号小于或等于当前事务版本号的数据行(保证事务读取的行要么在事务开始之前就存在,要么是事务本身插入的行) * 行的删除版本号要么未定义,要么大于当前事务版本号,这样可以确保事务读取到的行,在开始事务之前未被删除 #### INSERT 为插入的数据保存当前系统版本号作为行版本号 #### DELETE 保存当前系统版本号作为删除行版本号 #### UPDATE 插入一行数据,并将当前系统版本号赋予行版本号;同时保存当前系统版本号到原来的行作为删除版本号 脏读和不可重复读最根本的原因是事务读取到其它事务未提交的修改。在事务进行读取操作时,为了解决脏读和不可重复读问题,MVCC 规定只能读取已经提交的快照。当然一个事务可以读取自身未提交的快照,这不算是脏读 ***** 【参考资料】 ### MySQL InnoDB MVCC实现 https://zhuanlan.zhihu.com/p/40208895