文章目录
一 undo log版本链是什么东西?
数据库的隔离级别,以及脏读,幻读,不可重复读,
为什么mysql的默认隔离级别RR,可以让脏读,不可重复读,幻读都不会发生呢?
这就是由经典的MVCC多版本并发控制机制做到的,讲解这个MVCC机制之前,还得先讲讲undo log版本链的故事。
在数据库中每行数据都有两个隐藏字段,一个是trx_id,一个是roll_pointer,这个trx_id就是最近一次更新这条数据的事务id,roll_pointer就是指向当前这个事务之前生成的undo log。
比如,现在一个事务A(事务id=1),插入了一条数据,那么此时这条数据的隐藏字段以及指向的undo log如下图所示,插入的这个数据的值是X,因为事务A的id是1,所以这条数据的txr_id就是1,roll_pointer指向一个空的undo log,因为之前这条数据是没有的。
下面如果一个线程过来修改了一下这个数据,也就是事务B,把值改成了值N,事务B的id是2,那么此时更新之前会生成一个undo log记录之前的值,然后会让roll_pointer指向这个实际的undo log回滚日志,如下图所示。
多个事务串行执行的时候,每个人修改了一行数据,都会更新隐藏字段trx_id和roll_pointer,同时之前多个数据快照对应的undo log,会通过roll_pointer指针串联起来,形成一个重要的版本链!
二 通过undo log多版本链条实现的ReadView机制
ReadView ,当执行一个事务的时候,就会生成一个对应的ReadView,里面比较关键的东西有4个
- 一个是m_ids,这个就是说明此时有哪些事务在Mysql里执行还没有提交
- 一个是min_trx_id,就是m_ids里最小的值
- 一个是max_trx_id,mysql下一个要生成的事务id,就是最大事务id
- 一个是creator_trx_id,就是你这个事务的id
假设原来数据库里就有一行数据,很早以前就有事务插入过了,事务id是10,它的值为M,如下图所示