如题,学完MVCC机制后回味了一下,发现事务的提交操作好像完全不会反应在行记录本身的数据机构中,好像只是在某个记录所有事务状态的地方改了一下自己的状态。
然后别的事务,按照“读已提交”以上的规则来读时,是不是也跟MVCC类似,也是能拿到一连串当前记录的历史版本来视情况挑选的?
比如一个查询任务,拿到当前记录事务id后,得去对比一下该事务状态,哦还没提交,那我不用你,沿着指针去undo log里找上一版本;上一版本的事务id也拿出来对比一下,哦你的提交了,那就把你这条返回给客户端。
也就是这个“已提交”的状态完全不反映在记录本身上,而是通过将来的使用者(查询者)对比事务id、事务活跃列表等操作来“模拟”出类似查找已提交数据的效果。
不太确定我自己的理解对不对。主要是commit这个操作,印象中总是一大堆东西批量发送、批量打包、批量改状态的操作。但这里却只改一个事务id的对应状态,很小的一个值,等于这个行记录的提交状态本身并不存在,是到查询时才用一套逻辑综合对比判断出来的。有点反直觉,就有点不太确定自己的理解是不是有偏差。
事务是通过乐观锁悲观锁等机制实现的,更新的时候会将其余的挂起
mysql的mvcc中有几个核心参数,活跃事务id集合,最小活跃事务id,最大事务id + 1,其实当你提交事务的时候,你是会影响到活跃事务id集合这个数据集的。
很简单的一个场景,事务1,2,3,4,事务1两次读取数据,事务4会提交,假设在rc隔离级别下,事务1第一次读取事务4提交前的活跃事务id集合是[1,2,3,4],事务4提交后,事务1再去读取数据,重新生成readview,活跃事务id就变成[1,2,3](rr隔离级别下直接是复用上次的readview,此时还是[1,23,4],在活跃事务事务中又不是修改事务本身,数据被跳过),这时候就符合min <= tx_id < max + 1并且不在活跃事务中的场景了,数据被正常读取
看懵了。不会了。下次换个行吧。
不知道你这个问题是否已经解决, 如果还没有解决的话: