mysql无锁查询快照读_快照读与加锁读 - MySQL 8.0官方文档笔记(三)

本篇主要介绍InnoDB的快照读与加锁读。

快照读严格来说应该翻译为一致的无锁读(Consistent Nonlocking Reads),但国内一般都称作快照读。在之前的篇章中提到的普通读、无锁读和一致读等等,实际上讲的都是快照读的概念。

快照读

快照读,指的是InnoDB使用多版本机制,为一次查询提供数据库在特定时间点的快照。查询可以看到时间点之前已提交事务产生的变更,看不到未提交或时间点之后提交的。但有个特例,同一事物内快照生成之前产生的变更,也是可以看到的。这个特性会致使这样一种奇怪的情形:如果你更新了表的一些行,SELECT语句可以看到你做出的变更,但也可能看到某些行的老版本。如果其它事务也更新了这个表的一些行,你所看到的表的状态可能从未在数据库中存在过。

如果事务的隔离级别是可重复读(默认级别),同一事务内的所有快照读都会读取事务内第一次快照读时建立的快照。通过提交当前事物和发起新的查询,可以刷新快照。

而在读已提交级别下,每次快照读都会建立最新快照。

在读已提交和可重复读级别下,InnoDB会将SELECT语句全部转换为快照读。快照读不会给它读取的表上任何锁,因此在快照读执行的同时,其它事务可以对表进行任意修改。

假设你在默认的可重复读级别下,当你发起一次快照读(也就是普通的SELECT语句),InnoDB会给你的事务分配一个时间点:即记录查询看到数据库数据的时间点。如果其它事务在这个时间点之后删除了一行并提交,你的事务将不会感知到行被删除,插入和更新同理。

注意

数据库快照机制会应用在事务中的SELECT语句,但不会应用于DML语句。如果你插入或修改了某些行然后提交,同时另一个可重复读事务发起的DELETE或UPDATE语句,可以影响到这些刚刚提交的行,即使不能查询到它们。如果一个事务对另一个事务提交的行做更新或删除操作,这些本来不可见的变更将对前者可见。例如,你可能会遇到如下场景:

SELECT COUNT(c1) FROM t1 WHERE c1 = 'xyz';

-- 返回 0:没有匹配记录。

DELETE FROM t1 WHERE c1 = 'xyz';

-- 将删除其它事务最近提交的若干行。

SELECT COUNT(c2) FROM t1 WHERE c2 = 'abc';

-- 返回 0:没有匹配记录。

UPDATE t1 SET c2 = 'cba' WHERE c2 = 'abc';

-- 影响 10 行:另一个事务刚刚提交了10条值为‘abc’的记录。

SELECT COUNT(c2) FROM t1 WHERE c2 = &

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值