请选择 进入手机版 | 继续访问电脑版
查看: 62|回复: 0

[资料分享] 基于innodb存储引擎中的快照查询解析

[复制链接]

签到天数: 193 天

[LV.7]化身百千

发表于 2019-3-13 20:32:04 | 显示全部楼层 |阅读模式
在innodb存储引擎中,存在一种数据查询方式:快照查询。因为查询的是快照数据,所以查询时不申请共享锁。

当进行一致性非锁定读查询的时候,查询操作不会去等待记录上的独占锁释放,而是直接去读取快照数据。快照数据是通过undo段来实现的,因此它基本不会产生开销。显然,通过这种方式,可以极大的提高读并发性。
1.png


快照数据其实是行版本数据,一个行记录可能会存在多个行版本,并发时这种读取行版本的方式称为多版本并发控制(MVCC)。在隔离级别为read committed和repeatable read时,采取的查询方式就是一致性非锁定读方式。但是,不同的隔离级别下,读取行版本的方式是不一样的。在后面介绍对应的隔离级别时会作出说明。

下面是在innodb默认的隔离级别是repeatable read下的实验,该隔离级别下,事务总是在开启的时候获取最新的行版本,并一直持有该版本直到事务结束。更多的"一致性非锁定读"见后文说明read committed和repeatable read部分。

当前示例表ttt的记录如下:

mysql> select * from ttt;
+------+
| id   |
+------+
|    1 |
|    2 |
+------+
在会话1执行:

mysql> begin;
mysql> update ttt set id=100 where id=1
在会话2中执行:

mysql> begin;
mysql> select * from ttt;
+------+
| id   |
+------+
|    1 |
|    2 |
+------+
查询的结果和预期的一样,来自开启事务前最新提交的行版本数据。

回到会话1提交事务:

mysql> commit;
再回到会话2中查询:

mysql> select * from ttt;
+------+
| id   |
+------+
|    1 |
|    2 |
+------+
再次去会话1更新该记录:

mysql> begin;
mysql> update ttt set id=1000 where id=100;
mysql> commit;
再回到会话2执行查询:

mysql> select * from ttt;
+------+
| id   |
+------+
|    1 |
|    2 |
+------+
这就是repeatable read隔离级别下的一致性非锁定读的特性。

当然,MySQL也支持一致性锁定读的方式。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /2 下一条

返回顶部