Mysql MVCC多版本并发控制
Mysql MVCC多版本并发控制
简介
Mysql在可重复读级别下,同样的sql在一个事务里面多次执行查询结果相同,即使有其他事务对数据有修改也不会影响当前事务的查询结果。
这个隔离就是通过MVCC(多版本并发控制 Multi-Version Concurrency Control),对同一行的数据的读和写两个操作是不会通过加锁互斥来保证隔离性,避免频繁加互斥锁。
串行化隔离级别为了保证隔离性将所有操作都加锁互斥来实现。
Mysql在读已提交和可重复读隔离级别下都实现了MVCC。
Undo日志版本链与read view机制详解
Undo日志版本链是指一行数据被多个事务修改后,在每个事务修改完成,Mysql会保存修改前的数据undo回滚日志,并且用两个隐藏字段trx_id和roll_pointer把日志串联起来形成一个历史记录版本链。
注意:
- begin/start transaction并不是一个事务的起点,在执行到它们智慧的第一个操作InnoDB表的语句,事务才真正启动,才向mysql申请事务id,Mysql内部是严格按照事务的启动顺序来分配事务id的。
- 事务id是递增的,后启动的事务id一定大于先启动的事务id。
一致性视图 read-view
构成
- 查询时所有未提交事务id组成的数组(数组里面最小的id为min_id)
- 查询时已创建的最大事务id(max_id)
可重复读和读已提交差别
可重复读:执行任何查询sql是会生成当前事务的read-view,该视图在事务结束之前不会变化。
读已提交:每次执行查询sql都重新生成read-view。
比对规则
- 如果row的trx_id<min_id,说明这个版本是已提交的事务生成的,这个数据是可见的
- 如果row的trx_id>max_id,说明这个版本是将来未启动的事务生成的,是不可见的(如果trx_id就是当前自己的事务是可见的)
- 如果min_id<trx_id<max_id,有两种情况:
- 如果trx_id在视图数组中,说明这个版本是由为提交的事务生成的,不可见(如果trx_id就是当前自己的事务是可见的)
- 如果trx_id不再视图数组中,说明这个版本是已提交的事务生成的,可见。
总结
MVCC机制的实现就是通过read_view机制与undo版本链比对机制,使得不同的事务根据版本链比对规则