mvcc
程序员文章站
2022-06-14 18:54:29
...
1.mvcc介绍:
multi-version concurrent control,多版本并发控制;mvcc是一种并发控制的方法,它能够实现并发读写不冲突,通常用mvcc代替行级锁(行级排他锁,for update),提高数据库的访问效率;缺点是:每行记录都需要额外的存储空间;mvvm常用于read commit,repeatable read
2.redo log, undo log
* redo log: 开启事务后,记录更新型发生后操作的sql,当执行commit时,才会将redo log中的sql刷新到磁盘
* undo log: 通常用于记录更新型事务发生前的记录,比如update实际上是delete + insert,update前的记录存在undo log中,update后的记录存在redo log中
3.表中隐藏字段
每张表中实际上都有三个隐藏字段,隐藏id,db_trx_id(事务ID),db_roll_id(回滚ID)
* 隐藏id: 类似于elasticsearch的隐藏_id,没啥用
* db_trx_id: 事务ID,每开启一次事务,就会产生一个新的自增的事务ID
* db_roll_id: 回滚ID,记录当前行在开启事务修改后,commit前;通过回滚ID关联修改前的记录在undo log中的存档
4.mvvc具体分析:
insert:
insert语句会先将sql保存到redo log中,并且insert语句中的ID如果是交给数据库来维护的,在将sql存入redo log前,它会自动先对ID赋值,再保存到redo log;因此如果事务1执行insert,事务2页执行insert,然后事务1回滚,事务2提交,事务2的ID得到的是执行前的ID+2
delete:
delete同样先保存到redo log中并对事务ID标记为删除,commit再真正删除;由于mysql事务隔离级别默认是repeatable read,因此事务ID1删除数据,事务ID2只有在双方都commit了才能看到删除数据的效果
update:
在redo log中记录修改后的数据,在undo log中记录修改前的数据,commit就使用redo,rollback就使用undo;并且在redo log中,这一行的事务ID是当前的事务ID,同时会产生回滚ID,关联undo
start transaction;
delete from user;
select * from user; #如果是同一个事务执行select,由于
commit;
select:
select语句只能查询到小于等于select事务的事务ID的数据,或者大于等于select事务的回滚ID的数据,回滚ID为undefined也可以查询到;
因此当事务ID1执行select时,如果事务ID2并发执行update,事务ID3并发执行DML...;事务ID1都只会查询到产生事务ID1时的数据库快照数据
5.总结一句话:
innodb(mvcc的实现)只会从产生事务ID时的数据快照中查找数据,并且只会查找事务ID小于等于此时的事务ID的数据;在commit前,更新也是更新各自数据快照的数据
上一篇: 通过文字传递创建的图形按钮