值得注意的是mysql中只要可重复读和读提交这两个隔离级别需要用到mvcc。
搞清楚Mysql中的MVCC我们要先搞清楚三个概念。
隐藏列: trx_id:事务id。记录最新更新的事务id roll_pointer:上一版本指针
版本链: 每一行的更新操作都会在undolog里记录一条数据的更新操作,记录这一行数据、事务idroll_pointer,通过roll_pointer形成一个版本链表。
readview: 记录所有活跃中的事务
mysql中只有两个事务隔离级别通过mvcc完成控制的:读提交和可重复读。
这个两个区别在readview生成的时机不同。
读提交是在事务中每一次查询是都会生成一个readview,可以理解为刷新一次readview操作。
可重复读只有在事务开启的时候生成readview,在整个事务的周期里所有的查询都是用的一个readview。
通过版本链和readview我们就可以找到行更新中不同事务中已提交和未提交的版本数据。
可重复读场景下:
假设表里有一条id=1的行记录。那边此时undlog版本链中就有一条插入记录。此时有一个未提交的事务10,更新了id=1的字段,此时版本链中新增一条更新记录
此时有一个事务id=20的事务开启,select id = 10000 的数据操作。会先在版本链中就近找到一条记录,发现trx_id=10,存在readView中,排除此记录,继续沿着roll_pointer往下找。发现zhansan的记录trx_id=1,对比不在readview中,那么本次事务查询的记录为张三版本的的记录。这样子实现了可重复读的场景需求。
以上就是关于mysql MVCC的总结概况。
值得注意的是mysql中只要可重复读和读提交这两个隔离级别需要用到mvcc。
这里想延伸说下”可重复读“这种隔离级别的困扰?不知道大家是否思考过什么样的场景适合用可重复读这种隔离级别呢?貌似不应该”读提交“更科学点吗?一条查询在一个事务里读两次?既然得不到最新的结果,那边何必又查询一次呢?其实拿到最新的结果不应该更好的吗?
理解可重复读,得跳槽那个解释课重复读的demo(深入细节),只看单个查询,也就是单行的数据版本是很难理解可重复读的合理性的。应该从整个库的角度去看待,可重复读其实就是在一个时间点的库的快照中操作,也就是整个库的数据的版本在事务周期内要保持一致。
除特别注明外,本站所有文章均为作者原创。 或分享自己的编程经验,或探讨工作中的问题,或聊以人生趣事。 转载请注明出处来自 https://www.qiusuoweb.com/147.html
运营天数
总访问量
文章数量
-
-
-
交流群:157451741
新浪微博:草莽兴
发布评论