14.2.2.2 Consistent Nonlocking Reads 一致性非锁定读

14.2.2.2 Consistent Nonlocking Reads

一个一致读 意味着 InnoDB 使用多版本来提出一个查询数据库的快照 在一个时间点。

查询看到的事务的做出的改变,被提交了 在那个时间点之前,

之后没有改变或者没有提交的事务。 次规则的例外是 查询看到相同事务里早的语句的改变,

这个异常导致以下异常:如果你更新表的一些记录,一个SELECT 看到的最新的更新的记录的版本,

但是它也看到了任何记录老的版本。如果其他会话同时更新相同的表,你可能会看到 表从没在数据库中存在过的状态。

如果 事务隔离级别是 REPEATABLE READ(默认级别),所有的一致性读在相同的事务读取第一个读取建立的快照。

你可以得到一个新鲜的快照为你的查询通过提交当前的事务,然后执行新的查询。

READ COMMITTED 隔离级别,每个一致性读在一个事务内,读取它自己的新鲜的快照。

一致性读是默认的模式 InnoDB 处理SELECT 语句 在 READ COMMITTED and REPEATABLE READ 隔离级别。

一个一致读不在表上设置任何锁,因此其他的会话是自由的同时修改那些表 一个一致性读是在表上执行。

假设 你运行在默认的REPEATABLE READ隔离模式。 当你执行一致性读

(即,一个普通的SELECT 语句) InnoDB 给你的事务一个时间点根据你的查询看到的数据库。

如果另外的事务删除一条记录,提交在你分配的时间点之后,

你不会看到行已经被删掉了,insert和updates 也一样。

注意:

数据库状态的快照 应用于SELECT 语句在事务内,不是对于DML语句。如果插入或者修改一些记录

然后提交那个事务, 一个DELETE 或者UPDATE 语句被执行从另外一个并发的 REPEATABLE READ 事务

可能影响那些刚刚提交的行,尽管 session 不能查询它们。如果一个事务更新或者删除被不同的事务提交的记录,

那些改变变得对当前事务可见,比如,你可能遇到如下情况:

SELECT COUNT(c1) FROM t1 WHERE c1 = ‘xyz’; – Returns 0: no rows match.

DELETE FROM t1 WHERE c1 = ‘xyz’; – Deletes several rows recently committed by other transaction.

SELECT COUNT(c2) FROM t1 WHERE c2 = ‘abc’; – Returns 0: no rows match.
UPDATE t1 SET c2 = ‘cba’ WHERE c2 = ‘abc’; – Affects 10 rows: another txn just committed 10 rows with ‘abc’

values.
SELECT COUNT(c2) FROM t1 WHERE c2 = ‘cba’; – Returns 10: this txn can now see the rows it just updated.

你可以提高你的提交事务的时间点, 然后做另外的r SELECT or START TRANSACTION WITH CONSISTENT SNAPSHOT.

这个被称为多版本控制

在下面的例子中,SESSION A 看到 B插入的记录只有当B提交插入和 A也提交:

         Session A              Session B

       SET autocommit=0;      SET autocommit=0;

time
| SELECT * FROM t;
| empty set
| INSERT INTO t VALUES (1, 2);
|
v SELECT * FROM t;
empty set
COMMIT;

       SELECT * FROM t;
       empty set

       COMMIT;

       SELECT * FROM t;
       ---------------------
       |    1    |    2    |
       ---------------------

如果你想看到最新鲜的数据库状态,
使用READ COMMITED 隔离机制或者锁定读:

SELECT * FROM t LOCK IN SHARE MODE;

READ COMMITED 隔离级别, 每个一致读在一个事务设置,读取它自己的新鲜的快照。

在LOCK IN SHARE MODE, 一个locking read 发生代替:一个SEELCT 堵塞指导事务包含最新的记录结束。

一致读在某些DDL语句不工作:

  1. 一致性读在DROP TABLE不工作,因为MySQL 不能使用一个已经被删除的表

  2. 一致性读在ALTER TABLE不工作,

读取不同的类型用于SELECT 自己像 INSERT INTO … SELECT, UPDATE … (SELECT), and CREATE TABLE … SELECT

不指定UPDATE 或者LOCK 在共享模式下:

默认情况下, InnoDB 使用更强的锁.SELECT 部分像READ COMMITTED,

每个一致性读,即使在相同的会话里,设置和读取它自己的最新的快照。

为了使用一致性读在这些情况下,启动innodb_locks_unsafe_for_binlog option 设置隔离级别为

READ UNCOMMITTED, READ COMMITTED, or REPEATABLE READ

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scan724

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值