mysql mvcc readview_mvcc中的read_view

innodb的mvcc和read view

最近读High Performance MySQL,里面提到了innodb事务隔离级别是REPEATABLE-READ时,有这样一段话

引用

SELECT

InnoDB must examine each row to ensure that it meets two criteria:

a. InnoDB must find a version of the row that is at least as old as the transaction

(i.e., its version must be less than or equal to the transaction’s version). This

ensures that either the row existed before the transaction began, or the trans-

action created or altered the row.

b. The row’s deletion version must be undefined or greater than the transaction’s

version. This ensures that the row wasn’t deleted before the transaction began.

Rows that pass both tests may be returned as the query’s result.

来验证一下

show create table 20130302t1;

CREATE TABLE `20130302t1` (

`id` int(11) NOT NULL,

`b` int(11) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB

表中有数据(1,1)

autocommit为false, tx_isolation 是REPEATABLE-READ

考虑以下两种情况

情况1

session A

session B

start transaction;(A)

start transaction

update 20130302t1 set b=2 where id=1;

commit;

select * from 20130302t1;(B)

B处结果为(1,2),似乎不符合那段话里的a条件,A事务看到了transaction version更大的B事务

情况2

session A

session B

start transaction

update 20130302t1 set b=2 where id=1;

start transaction

select * from 20130302t1;

commit;

select * from 20130302t1;(C)

C处结果为(1,1),也就是说,A事务没有看到transaction version更小的B事务

是不是那段话有问题呢,后来终于找到了官方的文档,innodb通过read view来确定一致性读时的数据库snapshot,innodb的read view确定一条记录能否看到,有两条法则

1 看不到read view创建时刻以后启动的事务

2 看不到read view创建时活跃的事务

引用

Rule 1: When the read view object is created it notes down the smallest transaction identifier that is not yet used as a transaction identifier (trx_sys_t::max_trx_id).   The read view calls it the low limit. So the transaction using the read view must not see any transaction with identifier greater than or equal to this low limit.

Rule 2: The transaction using the read view must not see a transaction that was active when the read view was created.

在情况1中,代码A处并没有创建read view,read view是在代码B处创建的.

如果把A处代码改为 START TRANSACTION WITH CONSISTENT SNAPSHOT;

才会创建read view,使得代码B返回(1,1)

在情况2中,B事务在A事务创建read view时处于ACTIVE状态,所以B事务不会被A事务看到.

这篇文章还提到了mysql5.6 在read only事务的优化,值得一看

MySQLMVCC(Multi-Version Concurrency Control,多版本并发控制)是一种多版本的数据控制机制,它允许多个事务同时读取同一个数据快照,而不会出现读取冲突。 MVCC的实现原理主要是通过在每个数据行保存多个版本的数据,每个版本数据都有自己的时间戳,用于标识数据的版本。当一个事务开始时,它会创建一个快照并锁定所有需要修改的数据行,此时其他事务只能读取旧版本的数据。当事务提交时,它会把新版本的数据写入数据库,并释放锁定的数据行。同时,其他事务也可以读取新版本的数据。 MVCC的实现要依赖于InnoDB引擎下的两个重要的结构:undo log和read view。 - undo log:当一个事务对数据进行修改时,InnoDB会将旧版本的数据保存到undo log。在事务回滚时,InnoDB可以通过undo log将数据恢复到之前的版本。 - read view每个事务在启动时会创建一个read view,它记录了事务启动时数据库所有活跃的事务ID列表以及这些事务所对应的undo log的状态。在事务执行过程read view会随着时间不断更新。 通过undo log和read view的协作,InnoDB可以实现多版本并发控制。当一个事务读取数据时,它会根据read view的状态来选择正确的数据版本,即没有被其它事务修改的最新版本。如果出现读取冲突,则InnoDB会自动回滚事务并重新尝试读取数据。 总之,MVCC是通过保存多个版本的数据来实现并发控制的,它可以提高数据库的并发性能和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值