【数据库知识】MVCC机制——MySql底层原理版【详细版】

MVCC机制——MySql底层原理版

undo回滚日志+记录版本链(增加了两个字段:事务id和回滚指针(指向历史记录))

readview:活跃事务id组+最大事务id

匹配原则:分段:已提交、已提交/未提交、未提交

   由版本链从上到下进行匹配
(1)当前事务id (2)min_id<=当前事务id<=max_id,则表示当前记录在第二段,表示可能提交,也可能未提交,那么根据readviw,看当前事务id是否在活跃事务id组,若在则表示未提交,继续向下进行匹配,若不在,表示已提交,那么直接读出;                    (3)当前事务id>max_id,则表示当前记录在第三段,表示未提交,那么继续向下匹配。

#事务id=100 #事务id=200 #事务id=300 #select1 #select2
begin; begin; begin; begin; begin;
update test set name='hm' where id=1;        
  update test set name='hm' where id=2;      
    update test set name='yyqx' where id=1;    
    commit;    
      select name from test where id=1; --readview[100,200],300 yyqx  
update test set name='hm1' where id=1;        
update test set name='hm2' where id=1;        
      select name from test where id=1; --readview[100,200],300 yyqx  
commit; update test set name='hm3' where id=1;      
  update test set name='hm4' where id=1;      
      select name from test where id=1; --readview[100,200],300 yyqx select name from test where id=1; --readview[200],300 hm2
  commit;      

        以上是一个事务例子,一共有三个事务,事务id分别为100、200、300,表格从上到下是时间顺序,当执行第一条select语句时,也就是#select1中的select name from test where id=1; 此时版本链是如下这样的:

【数据库知识】MVCC机制——MySql底层原理版【详细版】_第1张图片

匹配原则:由版本链从上到下开始匹配,第一个记录的事务id为300,在未提交/已提交段,那么根据readview,发现不在活跃事务id组,那么表示此记录已提交,直接读出,所以结果就是:yyqx 

       当执行第二条select语句,也就是#select中的select name from test where id=1;此时版本链如下所示:

【数据库知识】MVCC机制——MySql底层原理版【详细版】_第2张图片

 匹配原则:由版本链从上到下开始匹配,第一个记录的事务id为100,在未提交/已提交段,那么根据readview,发现在活跃事务id组,那么表示此记录未提交,继续向下匹配,同样的,第二条记录的事务id还是100,也同样未提交,所以继续向下匹配,第三条记录的事务id是300,在未提交/已提交段,那么根据readview,发现不在活跃id组,那么表示此记录已提交,直接读出,所以结果就是:yyqx 

 当执行第三条select语句时,也就是#select1中的select name from test where id=1;此时版本链如下所示:

【数据库知识】MVCC机制——MySql底层原理版【详细版】_第3张图片

 匹配原则:由版本链从上到下开始匹配,第一个记录的事务id为200,在未提交/已提交段,那么根据readview,发现在活跃事务id组,那么表示此记录未提交,继续向下匹配,同样的,第二条记录的事务id还是200,也同样未提交,所以继续向下匹配,同样的,第三条记录的事务id还是100,也同样未提交,所以继续向下匹配,同样的,第四条记录的事务id还是100,也同样未提交,所以继续向下匹配,第五条记录的事务id是300,在未提交/已提交段,那么根据readview,发现不在活跃id组,那么表示此记录已提交,直接读出,所以结果就是:yyqx 

注:同一个事务的readview是延续第一条select语句的readview,所以查询结果还是yyqx——可重复读

若是读已提交,那么readview会进行更新,这里介绍的是可重复读情况

当执行第四条select语句,也就是#select2中的select name from test where id=1;,此时版本链如下所示:

【数据库知识】MVCC机制——MySql底层原理版【详细版】_第4张图片

匹配原则: 由版本链从上到下开始匹配,第一个记录的事务id为200,在未提交/已提交段,那么根据readview,发现在活跃事务id组,那么表示此记录未提交,继续向下匹配,同样的,第二条记录的事务id还是200,也同样未提交,所以继续向下匹配,第三条记录的事务id是100,在已提交段,所以直接读出,结果为hm2

注:当前重新开始了一个事务,所以重新分配readview

你可能感兴趣的:(数据库,mysql,MVCC)