赞
踩
MVCC是Mysql保证可重复读和读已提交两个级别的隔离性用到的一套机制,串行化执行是通过加锁来实现的,而MVCC机制下在对同一行数据进行读和写时,不会直接加锁互斥。
MVCC主要由undo日志版本链和read-view机制来完成,undo日志版本链是只一行数据被多个事务修改时,会保留修改前的数据undo回滚日志,并且用trx_id(日志id)和roll_pointer把执行undo日志串联起来形成一个历史记录版本链。
在可重复读隔离级别下,当事务开启,执行任何查询sql时,会生成当前事务的一致性试图(read-view),该试图在事务结束前不会变化(读已提交隔离级别下,每次查询重新生成),这个视图由所有的未提交事务id数组和当前最大的事务id(max_id)和最小的事务id(min_id)组成,事务里的任何查询都需要遵循版本链匹配规则和版本链里的最新数据逐条匹配,得到最终的快照数据。
当事务id小于min_id时,认为事务已提交,当事务id大于max_id时认为是未提交事务,当事务id处于min_id和max_id之间时,即可能是已提交也可能是未提交(需和未提交事务id数组比对)。
版本链匹配规则:
row_id == 当前事务id: 可见
row_id < min_id:该记录是已提交事务生成的,可见
min_id <= row_id <=max_id:如果在未提交事务id数组中存在不可见,不存在说明是已提交事务生成的,可见
min_id > max_id: 不可见。
begin/start transaction 命令并不是一个事务的起点,在执行到它们之后的第一个修改操作InnoDB表的语句, 事务才真正启动,才会向mysql申请事务id,mysql内部是严格按照事务的启动顺序来分配事务id的。
innodb执行更新操作时的步骤:
1:将更新的记录所在整页数据加载到buffer pool中
2:将记录写到undolog中
3:更新内存中的数据
4:写redo日志,先写入redobuffer再写入redo(顺序写,速度非常快)日志文件了
5:commit操作,先将记录写到binlog文件,再将commit状态同步到redo日志中
6:bufferpool增页数据刷盘(随机写入,非常耗时)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。