简介:
大家好,我是xp,我又诈尸了
mvcc,想必大家都不陌生,每个Java程序员都或多或少的了解过,不过不知道大家都是怎么学习的,是不是简单的百度一下呢?下面,我来带大家装个13,调试mvcc。咳,不是源码哈,但有那味了。
开卷开卷。
首先介绍一下mvcc的字面意思,全称:Multiversion Concurrency Control,翻译下来就是多版本并发控制技术。
脏读、不可重复读、幻读的概念就不多啰嗦了,mvcc具体的含义也不多啰嗦了,可以自行百度。mvcc解决了脏读、不可重复读、部分幻读,包含了3个重要成分:
undo log作用:
回滚
多个行版本控制
在数据修改的时候,不仅记录了redo log,还记录了undo log。但是不同于redo log,undo log是逻辑日志。简单理解成,delete的时候,undo log会出现一条insert,update的时候,undo log会出现一条旧数据,用来事务失败之后的回滚。
3个隐式字段:
DB_ROW_ID:行id
DB_TRX_ID:事务id
DB_ROLL_PTR:回滚指针
Read View:
m_creator_trx_id:事务id
m_low_limit_id:= max_trx_id:全局变量,每次分配的事务id,就是这个id,用完+1
m_up_limit_id:m_ids的第一个事务id,m_ids是升序列表
m_ids:创建该Read View时的活跃事务id列表
好了,理论讲完了,让我们嗨起来。
嗨之前,有一个情况单独说一下:
可以看到,此时的trx_id非常大,这是因为此时是只读事务。对于只读事务,InnoDB 并不会分配 trx_id,只有发生dml才会分配。这样有2个好处:
减少活跃事务的数量
减少 trx_id 的申请次数
至于这2个好处具体的作用,这里就不细说了,想知道的可以百度或者留言。
当commit了之后,我们使用SHOW ENGINE INNODB STATUS查看:
可以看到,显示该事务并没有开始。
好,回到正轨,相信大家都知道,视图可见性判断(不知道的先百度mvcc):
整体是这样的:
第一步我们以38488为开始值,把name更新成111,并且commit
第二步以38490把name更新成222,333,但是不commit
当38490第一次修改为222的时候,数据结构大致是这样的:
使用SHOW ENGINE INNODB STATUS侧面验证:
当38490第二次修改为333的时候,数据结构大致是这样的:
使用SHOW ENGINE INNODB STATUS侧面验证:
第三步以38491去查询,此时生成的m_ids应该是[348490,38491]
使用SHOW ENGINE INNODB STATUS侧面验证:
此时ReadView的几个属性值为:
m_creator_trx_id:38491
m_low_limit_id:38492
m_up_limit_id:348490
m_ids:[348490,38491]
接下来我们来验证结论:
1:不用验证,当前事务修改的肯定自己可见
2:38491查询id=1的记录,name为111
38488 < 348490,所以111可见
3:不用验证,38492是下个事务的id,还没生成呢,当前事务,肯定看不见下个事务修改的值
4:我们先把38491commit,把id为20的name更新成111
然后再开一个事务38496:
此时查id为20,是可见的
m_ids:[348490,38496],因为38491已经commit了,所以m_ids没有。此时的38491在m_ids之间,但是在m_ids里面找不到,所以可见。
好了,愉快的装13结束了,兄弟们,下次见。
页面更新:2024-05-08
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号