mysql的mvcc

快速搞懂mvcc

全称 multi-version concurrency control 多版本并发控制。

自动开启事务

MySQL默认每个对数据库进行修改的SQL语句都会自动开启事务:insert into ,update,delete from 另外加锁的SQL语句也会自动开启事务:select * from table_name lock in share mode, select * from table_name where condition for update。

undo log

每个事务在修改某条记录的时候都会先将老数据备份入undo log中,然后新增一条记录,并在隐藏字段db_tx_id中记录新增这个条数据的事务id,在隐藏字段db_roll_pointer中记录刚刚备份的原数据的db_row_id(db_row_id也是隐藏字段)。这样每个事务对数据的修改并没有覆盖原有数据。事务提交后,就处于不活跃状态。

读视图(read_view)

每个事务读取数据时会创建一个读视图(read_view),read_view 包含:活跃的事务id列表,最大事务id,最小事务id,创建读视图的事务id。事务id都是自增长的,值越大,说明创建的时间越晚。

结果过滤

然后用read_view过滤查询结果:

查询结果中db_tx_id>最大事务id,说明该结果是由读视图创建后的事务创建的,应不可见,丢弃;

db_tx_id<最小事务id,说明该结果在读视图创建前就已经提交,应可见;

最小事务id<=db_tx_id<=最大事务id,db_tx_id不在活跃的事务id列表中,说明该结果已经提交,应可见,db_tx_id在活跃的事务id列表中,则说明此创建该结果的事务还没提交,该结果应不可见。
这样保证了每个并发事务都读取已提交的结果,而且整个读取过程没有解锁,并发性能得到提升。

mvcc只在读已提交和可重复读隔离级别下运作

mvcc在读已提交和可重复读模式下运行,mvcc最主要的就是实现多个并发事务读已提交的数据,所以读未提交隔离级别下允许读未提交,跟mvcc向北,mvcc是不会运作的。可序列化隔离级别下,事务都是串行的,不存在并发,所以此隔离级别下,mvcc也是不运作的。

读已提交隔离级别下,

事务每次读取都要重新创建视图,在此期间有新事务创建,也有新事务提交,所以每此创建的视图都不一样,用试图过滤出来的结果以及结果的条数也不一样,所以会出现不可重复读(读出的结果变了)和幻读(读出的结果条数变了)。

可重复读隔离级别下,

只有在刚进入事务时会创建一个视图,由于mvcc的过滤原则时只提取已提交的数据,所以随着时间的推移,进入事务之后的查询,能查出来新增的数据的事务id都是比刚进入事务时查出来的数据事务id大,新的数据不会被筛选出来

。所以筛选结果跟第一次一样。此隔离级别下可以保证可重复读,但有些新增或删除的数据可能已提交(第一次没有筛选出来的数据),而活跃的事务id没有更新,导致本该读出来的数据没有读出来,所以避免不了幻读。

总的来说mvcc是为了提高数据库并发性能而设计的,它实现了读已提交。为了保证并发性能,它本身不加锁。它只在读已提交和可重复读隔离级别下工作。

读已提交隔离级别下,

防止不可重复读:

1、将事务隔离级别设为可重复读(推荐)。

2、使用共享(读锁 select...in share mode)(不推荐)。

3、使用排他锁(写锁 select...for update)(不推荐)。

防止幻读:

1、将事务隔离级别设为可重复读,然后使用排他锁select... for update,会自动应用间隙锁(推荐)

2、使用排他锁select... for update,条件用主键筛选,会应用间隙锁(推荐)

3、应用程序自己确保更新的数据条数没有发生变化。

相关推荐
捕鲸叉27 分钟前
第01章 07 MySQL+VTK C++示例代码,实现医学影像数据的IO数据库存储
数据库·mysql·vtk
九河云1 小时前
腾讯CDN vs 阿里云CDN:哪个更适合你的业务?
数据库·阿里云·云计算
m0_748254091 小时前
Linux下MySQL的简单使用
linux·mysql·adb
落霞与孤鹭齐飞。。1 小时前
SSM宠物医院信息管理系统
java·开发语言·mysql·毕业设计·课程设计
Jiutwo2 小时前
ClickHouse 入门
数据库·clickhouse
然然阿然然2 小时前
2025.1.20——一、[RCTF2015]EasySQL1 二次注入|报错注入|代码审计
数据库·sql·学习·安全·web安全·网络安全
yngsqq2 小时前
ent.SetDatabaseDefaults()
数据库
Ray.19982 小时前
postgresql的用户、数据库和表
数据库·postgresql·oracle
GIS小小研究僧2 小时前
数据库基础知识:记录、表、字段、数据类型、约束、主键、外键、规范化、索引、序列
数据库·postgresql·oracle·postgis
寒山李白4 小时前
MySQL union和union all
java·数据库·sql·mysql