当前位置:Gxlcms > 数据库问题 > Mysql 中的MVCC原理,undo日志的依赖

Mysql 中的MVCC原理,undo日志的依赖

时间:2021-07-01 10:21:17 帮助过:13人阅读

start transaction;
insert into tb(name) values('shenjian') ;
insert into tb(name) values('zhangshan');
insert into tb(name) values('lisi');
commit;
id name 创建时间(事务ID) 删除时间(事务ID)
1 shenjian 1 undefinded
2 zhangsan 1 undefinded
3 lisi 1 undefinded

对select 的影响:

  1. innodb 只会去查找版本好小于或等于(早于)当前事务ID的数据行,这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的

  2. 行的删除版本要么未定义,要么大于当前事务版本号,这可以确保事务读取到的行,在事务开始之前未被删除.
    只有1、2同时满足的记录,才能返回作为查询结果.

例2:delete操作
InnoDB会为删除的每一行保存当前系统的版本号(事务的ID)作为删除标识.
看下面的具体例子分析:
第二个事务,ID为2;

start transaction;
select * from tb;  //(第一步操作:1)
select * from tb;  //(第二部操作:2)
commit; 

假设:在这个事务的的执行过程中到第一步操作:1 的时候。
又开启了一个新事务(ID 为3)向表中执行Insert 操作插入数据

start transaction;
insert into tb(name) values('wangwu') ;
commit;

此时的表中数据为:

id name 创建时间(事务ID) 删除时间(事务ID)
1 shenjian 1 undefinded
2 zhangsan 1 undefinded
3 lisi 1 undefinded
4 wangwu 3 undefinded

然后刚才事务2,中的第二步:2 开始执行,引文id=4的数据的创建时间(事务ID为3),执行当前事务的ID为2,而InnoDB只会查找事务ID小于等于当前事务ID的数据行,所以id=4的数据行并不会在执行事务2中的第二步:2 中被检索出来,在事务2中的两条select 语句检索出来的数据都只会下表:

id name 创建时间(事务ID) 删除时间(事务ID)
1 shenjian 1 undefinded
2 zhangsan 1 undefinded
3 lisi 1 undefinded

再假设:假设在执行事务ID为2的过程中,刚执行到了第一步:1,假设事务执行完事务3后,接着又执行了事务4;
事务4:

st art transaction;
delete  from tb where id=1;
commit;

此时数据库中的表为:

id name 创建时间(事务ID) 删除时间(事务ID)
1 shenjian 1 4
2 zhangsan 1 undefinded
3 lisi 1 undefinded
4 wangwu 3 undefinded

接着执行事务ID为2的第二步:2,根据select 检索条件可以知道,它会检索创建时间(创建事务的ID)小于当前事务ID的行和删除时间(删除事务的ID)大于当前事务的行,而id=4的行上面已经说过,而id=1的行由于删除时间(删除事务的ID)大于当前事务的ID,所以事务2的第二步:2 select * from tb 会把id=1的数据检索出来.所以,事务2中的两条select 语句检索出来的数据都如下:

id name 创建时间(事务ID) 删除时间(事务ID)
1 shenjian 1 4
2 zhangsan 1 undefinded
3 lisi 1 undefinded

update:
InnoDB执行UPDATE,实际上是新插入了一行记录,并保存其创建时间为当前事务的ID,同时保存当前事务ID到要UPDATE的行的删除时间.

再再假设:
假设在执行完事务2的第一步:1 后又执行,其它用户执行了事务3,4,这时,又有一个用户对这张表执行了UPDATE操作:

第5个事务:

start transaction;
update tb set name='xxx' where id=2;
commit;

按照update的更新原则:会生成新的一行,并在原来要修改的列的删除时间列上添加本事务ID,得到表如下:

id name 创建时间(事务ID) 删除时间(事务ID)
1 shenjian 1 4
2 zhangsan 1 5
3 lisi 1 undefinded
4 wangwu 3 undefinded
2 xxx 5 undefinded

继续执行事务2第二步:2,根据select 语句的检索条件(创建时间事务ID小于自己查询事务ID的,和删除时间事务ID大于自身的查询事务ID),得到下表:

id name 创建时间(事务ID) 删除时间(事务ID)
1 shenjian 1 4
2 zhangsan 1 5
3 lisi 1 undefinded

并得不到上上个表的ID=4的第四行(因为创建事务ID=3 > 查询事务ID=2) 和第五行Update 事务创建的ID=2 的更新数据(因为 创建他的Update 事务ID=5 > 查询事务ID=2)

Mysql 中的MVCC原理,undo日志的依赖

标签:prim   mvc   大于   初始   name   targe   一起   日志   detail   

人气教程排行