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、应用程序自己确保更新的数据条数没有发生变化。

相关推荐
尘土哥10 分钟前
Mysql 索引下推(Index Condition Pushdown, ICP)详解
sql·mysql
xiaobin8899915 分钟前
PowerDesigner安装教程(附加安装包)PowerDesigner详细安装教程PowerDesigner 16.6 最新版安装教程
数据库·其他
程序员是干活的25 分钟前
Java EE前端技术编程脚本语言JavaScript
java·大数据·前端·数据库·人工智能
wei3872452321 小时前
集训总结2
java·数据库·mysql
t_hj1 小时前
Scrapy
前端·数据库·scrapy
种树达人1 小时前
数据库常用DDL语言
java·数据库·oracle
Gauss松鼠会2 小时前
华为云DRS实现Oracle到GaussDB数据库迁移的全流程技术方案
数据库·sql·安全·华为云·database·gaussdb
可涵不会debug2 小时前
AI浪潮涌,数据库“融合智能”奏响产业新乐章
数据库·人工智能
wei_shuo3 小时前
融合与智能:AI 浪潮驱动下数据库的多维度进化与产业格局重塑新范式
数据库·人工智能·金仓数据库
Fireworkitte3 小时前
Java 常用数据库详解
java·数据库