mysql完整整理(Mysql隔离性之Read View的用法说明)
mysql完整整理
Mysql隔离性之Read View的用法说明当前事务能读取到哪个历史版本?
read view是事务开启时,当前所有事务的一个集合,这个数据结构中存储了当前read view中最大的id及最小的id。
这就是当前活跃事务列表,如下所示:
|
ct-trx --> trx11 --> trx9 --> trx6 --> trx5 --> trx3; |
ct-trx 表示当前事务的id,对应上面的read_view数据结构如下,
|
read_view->creator_trx_id = ct-trx; read_view->up_limit_id = trx3; 低水位 read_view->low_limit_id = trx11; 高水位 read_view->trx_ids = [trx11, trx9, trx6, trx5, trx3]; |
low_limit_id是“高水位”,即当时活跃事务的最大id,如果读到row的db_trx_id>=low_limit_id,说明这些id在此之前的数据都没有提交,如注释中的描述,这些数据都不可见。
|
if (trx_id >= view ->low_limit_id) { return ( false ); } |
注:readview 部分源码
up_limit_id是“低水位”,即当时活跃事务列表的最小事务id,如果row的db_trx_id<up_limit_id,说明这些数据在事务创建id的时都已经提交,如注释中的描述,这些数据均可见。
|
if (trx_id < view ->up_limit_id) { return ( true ); } |
row的db_trx_id在low_limit_id和up_limit_id之间,则查找该记录的db_trx_id是否在自己事务的read_view->trx_ids列表中,如果在则该记录的当前版本不可见,否则该记录的当前版本可见。
不同隔离级别readview实现方式
1. read-commited:
即:在每次语句执行的过程中,都关闭read_view, 重新在row_search_for_mysql函数中创建当前的一份read_view。这样就会产生不可重复读现象发生。
2. repeatable read:
在repeatable read的隔离级别下,创建事务trx结构的时候,就生成了当前的global read view。使用trx_assign_read_view函数创建,一直维持到事务结束。在事务结束这段时间内 每一次查询都不会重新重建read view , 从而实现了可重复读。
补充:mysql的mvcc和readview
隔离级别标准定义:
read uncommited 一个事务读取到了另一个事务未提交的结果(可能发生回滚),叫脏读,这会带来脏读、幻读、不可重复读问题
read commited 一个事务a读取到了另一个事务b最新提交的结果,使得事务a两次读取的结果不同,其避免了脏读,会出现不可重复读,幻读,通过版本链(mvcc)和readview实现。
repeatable read(mysql的默认隔离级别) 一个事务第一次读过某条记录后,另一个事务修改提交了该条记录后,事务a读取到的还是第一次的值,这就是可重复读,同一个事务中多次读取相同的数据返回的结果是一样的。事务不会读到其他事务对已有数据的修改,即使其他事务已提交,也就是说,事务开始时读到的已有数据是什么,在事务提交前的任意时刻,这些数据的值都是一样的。但是,对于其他事务新插入的数据是可以读到的,这也就引发了幻读问题。其避免了脏读和不可重复读问题,但幻读依然存在。还是会出现幻读,(但是mysql解决了幻读的问题),通过版本链和readview实现
serializable 不允许对同一行记录的读和写的并发操作,必需串行执行,所以不会出现幻读,脏读现象
在mysql中读已提交和可重复读事务隔离级别是通过mvcc和readview实现的
mvcc即multi-version concurrency control,多版本并发控制,维护一个数据的多个版本,使得事务之间的读写按照隔离级别获取相应的结果,不发生冲突
对于隔离级别read committed,每次都生成一个新的readview
对于隔离级别repeatable read,只在事务开启时,生成一个readview,直到事务提交,不发生变化,所以可以保证可重复读。
生成readview时
m_ids:表示活跃事务id列表
min_trx_id:活跃事务中的最小事务id
max_trx_id:已创建的最大事务id
creator_trx_id:当前的事务id
对当前事务来说,按照以下规则从最新的版本开始遍历,获取对应的版本记录。
1、被访问的trx_id与readview中的creator_trx_id相同,表示当前事务在访问自己修改的记录,可见,返回;
2、被访问的trx_id小于min_trx_id,表明该版本已提交,可见,返回;
3、被访问的trx_id大于等于max_trx_id,表明该版本在生成readview时,还未开启,不可见,返回;
4、被访问的trx_id在min_trx_id和max_trx_id之间,判断是否在m_ids中,如果在,则说明生成readview时,该版本事务未提交,该版本不可见;如果不在,则说明生成readview时,该版本事务已提交可见,返回。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持开心学习网。如有错误或未考虑完全的地方,望不吝赐教。
原文链接:https://blog.csdn.net/longgeqiaojie304/article/details/98872857
- thinkphp5.1手动连接mysql数据库(thinkphp5框架结合mysql实现微信登录和自定义分享链接与图文功能示例)
- mysql索引优化有哪些(MySQL如何基于Explain关键字优化索引功能)
- mysql拼接和过滤(mysql 如何动态修改复制过滤器)
- apache搭建php环境(Windows上安装Apache2、PHP5、MySQL5及与Resin配合实现多系统之整合)
- 数据库mysql基本知识(深入理解r2dbc在mysql中的使用)
- mysql密码设置(mysql密码中有特殊字符&在命令行下登录的操作)
- mysql的常见优化(详解GaussDB for MySQL性能优化)
- 创建数据库入门教程mysql(MySQL数据库安装教程一学就会)
- mysql怎么给查询权限(MySql设置指定用户数据库查看查询权限)
- mysql主从复制如何实现(MySql主从复制实现原理及配置)
- mysql从入门到实践万字详解(mysql基础知识扫盲)
- 怎么用docker中的mysql连接数据库(解决Docker之mysql容器数据库更改不生效的问题)
- mysql查看视图注释(详解MySQL的sql_mode查询与设置)
- MySQL配置文件my.cnf的介绍
- mysql建表时指定聚簇索引(一看就懂的MySQL的聚簇索引及聚簇索引是如何长高的)
- mysql操作时间的函数(一篇文章搞定Mysql日期时间函数)
- 记者手记 书记带我去 巡街(记者手记书记带我去)
- 富士胶片集团将向土耳其东南部地震灾民捐赠5000万日元 | 美通社(富士胶片集团将向土耳其东南部地震灾民捐赠5000万日元)
- 二次创业 的富士胶片,在进博会上首次展示完成转型后的全线医疗产品(二次创业的富士胶片)
- 富士胶片 中国 我们对上海的信心没有任何改变(富士胶片中国)
- 赢麻了 富士公布2021年度财报 营利同比增长240(富士公布2021年度财报)
- 医事文化谈屑 | 古人的名 字 号(医事文化谈屑古人的名)
热门推荐
- dedecms主表内容(DEDECMS最为常用的分页标签及分页样式代码)
- angular怎么把组件用在根组件里(详解Angular组件之投影)
- SQL处理字符串的函数
- js如何操作json字符串
- python怎么爬取excel数据(python爬取内容存入Excel实例)
- serv-u突然不允许上传(Serv-U 密匙冲突,Serv-U无法启动处于离线状态解决方法)
- react的基本知识(React中refs的一些常见用法汇总)
- docker 容器端口查不到(docker容器无法访问宿主机端口的解决)
- python3.7对象检测(在Python中使用Neo4j的方法)
- css min-width与max-width
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9