当前位置:网站首页>MySQL隔离性实现原理
MySQL隔离性实现原理
2022-08-07 21:23:00 【江南无故人】
MySQL数据库读写并发存在线程安全问题,比如脏读、幻读、不可重复读
MySQL实现隔离性本质是通过MVCC和Read View
多版本并发控制(MVCC):
是MySQL解决读写冲突的一种无锁的策略,根据事务开始的先后顺序,按递增为事务分配不同的事务ID
记录的一些隐藏字段:
DB_TRX_ID:最近修改改记录的事务ID
DB_ROLL_PTR: 回滚指针,指向这条记录的上一个版本
DB_ROW_ID: 隐藏主键,如果数据表没有主键, InnoDB以 DB_ROW_ID 生成一个聚簇索引
记录的不同的版本通过回滚指针相连形成了版本链
假如有一条记录是姓名为张三,ID为7的事务修改姓名为李四,ID为9的事务修改姓名为王五,形成的版本链大致如下:
回滚操作就是用历史版本覆盖当前版本,一个个版本可以叫做一个个快照
版本链存在MySQL的undo日志当中,undo日志可以理解为MySQL中的一段缓冲区
当前读和快照读:
读取某条记录的最新版本就是当前读,读取历史版本叫做快照读。
增删改都是当前读,需要加锁,select操作也有可能是当前读,这时也需要加锁
这时候这些当前读就是串行化的。快照读读取的是历史版本,所以不用加锁,这就是mvcc提高读写并发效率的方式。
select是当前读还是快照读取决于隔离级别,而确认读取版本链中的哪个版本还需要Read View
Read View 是MySQL 源码中的一个类
事务进行 快照读 的时候生产读视图 (Read View),可以记录维护系统当前活跃的事务的ID等信息。
Read View类成员中影响快照读读取哪个版本的成员有如下几个:
m_ids; //Read View生成时刻活跃事务ID的列表
up_limit_id; //m_ids列表中最小的ID
low_limit_id; //目前已出现过的事务ID的最大值+1
creator_trx_id //创建该ReadView的事务ID
确认读取版本链中的哪个版本就是通过版本中的ID和上面的类成员比较
如果隔离级别是读提交,可以认为没有隔离性,不用上述的方式,隔离级别如果是串行化,操作都加锁自然也不需要上述方式,读提交和可重复读这两种隔离级别都会用到MVCC+Read View的方式来确定读取到的记录是哪一个版本
而读提交和可重复读隔离级别不同,也就是快照读读到的版本不同的原因在于:
读提交隔离级别在某个事务中的每一次快照读都会产生新的Read View,而可重复读隔离级别在某个事务中只在第一次快照读时产生Read View,之后不管其他事务做什么,这个Read View都不变。
总之,MySQL的隔离性本质的实现原理就是多版本并发控制(MVCC)和读视图(Read View)同时起作用。
边栏推荐
猜你喜欢
随机推荐
"Daily practice, happy water problem" 1408. String matching in arrays
dp数组解决背包问题
可信认证之九阴真经一
云计算学习8——OpenStack高级运维企业实战竞赛题目
股票网上开户安全不,怎么开
【LeetCode】875. Keke who loves bananas
STL——list
没有鼠标怎么用键盘控制电脑 用键盘怎么代替鼠标移动
如何加密excel文件 excel文档加密如何设置
ECCV2022|面向大规模场景的小目标检测:综述和 benchmark
《MySQL核心知识》第7章:插入、更新、删除
图像增强和滤波图像滤波
PL2303GT USB to RS232 Serial Bridge Controller (Built in RS232 XCVR)驱动地址
注册中心设计(1)-注册中心的作用及设计分析
如何打开本地组策略编辑器 打开组策略编辑器方法
笔记本电脑能装内存条吗 笔记本电脑如何安装内存条
Vim基础用法,最常用、最实用的命令介绍(保姆级教程)
Thymeleaf
LeetCode_双指针_中等_633.平方数之和
【目标检测】YOLOv5:添加漏检率和虚检率输出









