MySQL中的MVCC(多版本并发控制)个人观点仅供交流

个人观点仅供交流
个人观点所写
个人观点所写
个人观点所写

这篇博客是观看b站上老师讲的,如果按照老师的顺序的提交事务,
那么视频中 readview:[最小未提交事务及其其他未提交事务的集合],最大已创建事务。这么写的。
后来我改变了提交的顺序,发现readview不知道这么写了,或者说按照上面的这种写法我根据undo日志表查到的数据不对,然后查阅了资料,看到了活跃事务id,也没完全看懂。然后我认为
readview :【最小未提交事务及其其他未提交事务的集合】, 最新活跃事务的id
这个最新活跃事务的id是最新一次提交的事务的id。

MVCC

Multi-Version Concurrency Control 多版本并发控制,为提高并发读写的性能、不用锁就能让多个事务并发读写。

针对的隔离级别是 读已提交和可重复读

在我们创建表的时候会有两个隐藏的字段、一个是 DB_TRX_ID 事务id,还有一个是 DB_ROLL_PTR回滚指针

user表

id(主键) name DB_TRX_ID(事务id) DB_ROLL_PTR(回滚指针)
1 zhangshan

创建这个表的时候就会在undo回滚日志表中生成记录。
MySQL中的MVCC(多版本并发控制)个人观点仅供交流
这时候开启三个事务进行修改、仅一个事务提交、另一个事务进行查询,undo回滚日志表中将这些操作添加记录。
(select 每一次查询视为一次事务的开启和提交)
MySQL中的MVCC(多版本并发控制)个人观点仅供交流

select * form user ;–readview:[20,30],40 (查询到的数据为 name= ’zs4‘)

因为是在 读已提交 和 可重复读的隔离级别下、所以读取到的数据是已经提交的,

–readview:最未提交事务id的数组,最新已提交的事务id。
这里的readview 为 readview:[20,30],40
其中数组[20,30] 表示未提交的事务id集合,最新已提交的事务id。
在undo回滚表中由上之下的在 进行中事务id的区间 查找已经提交事务id,然后得到数据。
在这两种隔离级别中 已经提交的事务的数据对其他事务是可见的,未提交的事务修改的数据对其他事务是不可见的。

只要其他事务修改数据、就会在undo回滚表生成记录。
MySQL中的MVCC(多版本并发控制)个人观点仅供交流

因为 id=10的事务未提交、数据是不可见的、不符合查找要求的所以在 进行事务的区间查找的仍在是已经提交的事务的数据。

针对可重复读和读已提交

MySQL中的MVCC(多版本并发控制)个人观点仅供交流
可重复读

如果是可重复读,那么 readview 采用的是第一次就生成的旧 readview:[20,30],40。
此时从上至下的查找,只要在未提交的数组中的事务id都是不可取的,就算它后面提交了,但是在readview也当中未提交。所以就算 事务id=30的提交了,30属于未提交数组中的元素——不符合,继续向下查找。

读已经提交

但如果是在读已提交的隔离级别下、那么每一次查找会生成新的 readview,比如这次查找的readview就为
readview:[20],30 依次查找下来第一个见到的是 name = ‘zs3’