【MySQL】浅谈一致性读

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 一 前言   MySQL 在不同的事务隔离级别下提供两种读模式 一致性读(非加锁), 当前读(加锁读)。当前读比较简单,本文主要研究一致性读取。 二 原理概念官方概念 "A consistent read means that InnoDB uses...
一 前言
   MySQL 在不同的事务隔离级别下提供两种读模式  一致性读 (非加锁) 当前读 (加锁读) 。当前读比较简单,本文主要研究一致性读取。
二 原理概念

官方概念
  1. "A consistent read means that InnoDB uses multi-versioning to present to a query a snapshot of the database at a point in time. The query sees the changes made by transactions that committed before that point of time, and no changes made by later or uncommitted transactions.The exception to this rule is that the query sees the changes made by earlier statements within the same transaction. "
一致性读是指使用MVCC机制读取到某个事务已经提交的数据,其实是从undo里面获取的数据快照。不过也有特例: 在本事务内如果修改某个表之后的select 可以读取到该表最新的数据,后面的例子可以验证。   
三 不同事务隔离级别的一致性读
3.1 RR模式
从官方文档 "If the transaction isolation level is REPEATABLE READ (the default level), all consistent reads within the same transaction read the snapshot established by the first such read in that transaction."
 在RR模式下,同一个事务内的一致性读的快照都是基于第一次读取操作时所建立的。下面我们做测试进行对RR模式下一致性读进行解读。
a) RR模式下事务的起始点是以执行的第一条语句为起始点的,而不是以begin作为事务的起始点的。

session 1

session2 

test [RW] 10:01:33 >begin;

Query OK, 0 rows affected (0.00 sec)


test [RW] 10:02:12 >begin;

Query OK, 0 rows affected (0.00 sec)


test [RW] 10:02:22 >select * from ty;

Empty set (0.00 sec)

test [RW] 10:02:36 >insert into ty(a,b) values(1,2);

Query OK, 1 row affected (0.00 sec)

test [RW] 10:02:51 >commit;

Query OK, 0 rows affected (0.00 sec)

test [RW] 10:02:33 >select * from ty;

+----+------+------+

| id | a    | b    |

+----+------+------+

|  1 |    1 |    2 |

+----+------+------+

1 row in set (0.00 sec)




b) RR模式下的一致性读,是以第一条select语句的执行时间点作为snapshot建立的时间点的,即使是访问不同的表。

test [RW] 10:35:11 >begin;

Query OK, 0 rows affected (0.00 sec)

test [RW] 10:35:13 >select * from x;

+----+

| id |

+----+

|  1 |

|  2 |

+----+

2 rows in set (0.00 sec)

test [RW] 10:34:32 >begin;

Query OK, 0 rows affected (0.00 sec)


test [RW] 10:34:51 >insert into ty(a,b) values(2,4);

Query OK, 1 row affected (0.00 sec)

test [RW] 10:35:39 >select * from ty;

+----+------+------+

| id | a    | b    |

+----+------+------+

|  1 |    1 |    2 |

+----+------+------+

1 row in set (0.00 sec)




c) RR模式下,在本事务内如果修改某个表之后的对该表的select语句可以读取到该表最新的数据。

test [RW] 10:42:56 >begin;

Query OK, 0 rows affected (0.00 sec)

test [RW] 10:43:07 >select * from ty;

+----+------+------+

| id | a    | b    |

+----+------+------+

|  1 |    1 |    2 |

|  2 |    2 |    4 |

+----+------+------+

2 rows in set (0.00 sec)

test [RW] 10:35:34 >begin;

Query OK, 0 rows affected (0.00 sec)

test [RW] 10:43:25 >insert into ty(a,b) values(3,5);

Query OK, 1 row affected (0.00 sec)


test [RW] 10:43:38 >select * from ty;

+----+------+------+

| id | a    | b    |

+----+------+------+

|  1 |    1 |    2 |

|  2 |    2 |    4 |

|  3 |    3 |    5 |

+----+------+------+

3 rows in set (0.00 sec)

test [RW] 10:43:14 >update  ty set a = 5 where id=3;

Query OK, 1 row affected (4.23 sec)

Rows matched: 1  Changed: 1  Warnings: 0

test [RW] 10:44:30 >select * from ty;

+----+------+------+

| id | a    | b    |

+----+------+------+

|  1 |    1 |    2 |

|  2 |    2 |    4 |

|  3 |    5 |    5 |

+----+------+------+

3 rows in set (0.00 sec)



d)RR模式下同一个事务内,第一次查询是当前读操作则后续查询可以查看最新的数据。

test [RW] 11:07:23 >begin;

Query OK, 0 rows affected (0.00 sec)

test [RW] 11:07:26 >update ty set a=5 where id=2;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1  Changed: 1  Warnings: 0

test [RW] 11:07:31 >begin;

Query OK, 0 rows affected (0.00 sec)


test [RW] 11:07:33 >select * from ty where id=2 for update;

+----+------+------+

| id | a    | b    |

+----+------+------+

|  2 |    5 |    4 |

+----+------+------+

1 row in set (10.73 sec)

test [RW] 11:07:36 >insert into ty(a,b) values(6,7);

Query OK, 1 row affected (0.00 sec)

test [RW] 11:07:55 >commit;

Query OK, 0 rows affected (0.00 sec)



test [RW] 11:07:58 >select * from ty;

+----+------+------+

| id | a    | b    |

+----+------+------+

|  1 |    2 |    3 |

|  2 |    5 |    4 |

|  3 |    6 |    7 |  <-- 本事务还未commit,已经可以查看其他会话最新插入的数据

+----+------+------+

3 rows in set (0.00 sec)

这个例子要特别说明一下,从上面的实验结果上来看RR事务隔离级别下,一致性快照的建立仅仅和select语句第一次执行有关,不管是不是相关表。而且 与其他 DML(insert,update,delete) 语句、for update 语句无关 ,在事务中第一次执行DML,后面的其他select 查询会是当前读即可获取到最新的数据。
   
3.2 RC模式 
RC 支持在本事务内读取到最新提交的数据,所以 RC 事务隔离级别下的一致性读取比RR模式下的要简单很多。每个事务构建自己的快照,不相互干扰,除非其他事务已经提交,有兴趣的朋友自己测试吧。
  1. With READ COMMITTED isolation level, each consistent read within a transaction sets and reads its own fresh snapshot.
四 当前读 
    和一致性读不太一样 ,当前读需要使用select  xx  for update,或者 lock in share mode ,读取最新的数据并且锁定被访问的行,(RC 加行锁,RR加gap锁 唯一键除外) 不管另外一个事务是否提交,如果另外的事务已经获取了相关的锁,则 for update,lock in share mode 语句则继续等待直到其他事务释放锁,并且获取到最新的数据。
  
五 小结
    从上面的测试来看,RR模式下的一致性快照读会有比较多的特性(姑且叫做特性吧) 。RC模式本身支持不可重复读,能够查询到最新的其他事务最新提交的数据。基于上面的测试,还是比较推荐业务使用RC模式作为事务隔离级别的。
参考文章
[1]  一致性读深入研究
[2]  官方文档
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3月前
|
SQL 运维 关系型数据库
如何对比MySQL主备数据的一致性?
如何在数据库世界中处理大批量数据变更操作,而不影响业务运行。NineData的OnlineDML解决方案通过无锁方式实现数据变更,确保在线业务的顺畅运行。只需两步操作即可开启OnlineDML功能,让NineData自动处理大型DML操作,分批执行并根据数据库压力进行智能调整,简化操作流程并提供直观操作界面。
353 2
如何对比MySQL主备数据的一致性?
|
11月前
|
缓存 NoSQL 关系型数据库
Redis缓存与Mysql数据库的一致性问题解决
Redis缓存与Mysql数据库的一致性问题解决
76 0
|
3月前
|
SQL 关系型数据库 MySQL
深入理解MySQL事务特性:保证数据完整性与一致性
深入理解MySQL事务特性:保证数据完整性与一致性
474 1
|
3月前
|
缓存 NoSQL 关系型数据库
解决MySQL与Redis缓存一致性的问题
选择适合的策略取决于系统的需求和复杂性,通常需要根据业务场景综合考虑,以实现MySQL与Redis缓存的一致性。 买CN2云服务器,免备案服务器,高防服务器,就选蓝易云。百度搜索:蓝易云
47 0
|
消息中间件 canal 缓存
Redis与MySQL双写一致性如何保证:延迟双删?binlog异步删除?
Redis与MySQL双写一致性如何保证:延迟双删?binlog异步删除?
|
3月前
|
缓存 NoSQL 关系型数据库
MySQL缓存策略(一致性问题、数据同步以及缓存故障)
MySQL缓存策略(一致性问题、数据同步以及缓存故障)
149 1
|
3月前
|
缓存 NoSQL 关系型数据库
【中间件】Redis与MySQL双写一致性如何保证?--缓存和数据库在双写场景下一致性是如何保证的
【中间件】Redis与MySQL双写一致性如何保证?--缓存和数据库在双写场景下一致性是如何保证的
207 0
【中间件】Redis与MySQL双写一致性如何保证?--缓存和数据库在双写场景下一致性是如何保证的
|
3月前
|
canal 缓存 关系型数据库
Springcloud Alibaba使用Canal将Mysql数据实时同步到Redis保证缓存的一致性
canal [kə'næl] ,译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费。其诞生的背景是早期阿里巴巴因为杭州和美国双机房部署,存在跨机房同步的业务需求,实现方式主要是基于业务 trigger 获取增量变更。从 2010 年开始,业务逐步尝试数据库日志解析获取增量变更进行同步,由此衍生出了大量的数据库增量订阅和消费业务。
170 0
|
3月前
|
NoSQL 关系型数据库 MySQL
redis与mysql的数据一致性问题(事务一致性)
redis与mysql的数据一致性问题(事务一致性)
57 0
|
12月前
|
存储 关系型数据库 MySQL
如何实现基于Flink的高吞吐、精确一致性数据入湖
APS(ADB Pipeline Service)简介:ADB湖仓版在深化自身湖仓能力建设的同时,还推出了APS(ADB Pipeline Service)数据通道组件,为客户提供实时数据流服务实现数据低成本、低延迟入湖入仓。本文以数据源SLS如何通过APS实现高速精确一致性入湖为例,介绍相关的挑战和解决方法。