MySQL MVCC 设计缺陷

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介:

    虽然SQL-92规定了四种隔离级别,但是在引入MVCC后,RC/RR都是snapshot isolation下的变体。至于对隔离性和一致性的吐槽,引用沈洵的话:“快照读以更低的代价实现了更高的并发度,却不得不委身在原有事务框架内。其实ACID也只是一个标准,并非真理。”

    既然是snapshot isolation,MySQL有什么问题呢,直接上案例:

准备工作:

create table mvcc(x int auto_increment primary key,y int default 1);
insert into mvcc(y)  select 1 from mvcc; -- many times
Query OK, 2097152 rows affected (13.24 sec)
Records: 2097152  Duplicates: 0  Warnings: 0

RC/RR && autocommit = 0

T Session1 Session2
T0
1
2
select  from  mvcc  where  y>1;
Empty  set

T1
1
update  mvcc  set  y=3  where  y>1;

T2
1
updating
1
2
3
4
5
6
7
8
9
10
update  mvcc  set  y=2 
where  x=3000000;
select  from  mvcc  where  y>1;
+ ---------+------+
| x | y |
+ ---------+------+
| 3000000 | 2 |
+ ---------+------+
commit
Query OK, 0  rows  affected
T3
1
2
3
4
5
6
7
8
Query OK, 1 row affected (1.76 sec)
Rows  matched: 1 Changed: 1
select  from  mvcc  where  y>1;
+ ---------+------+
| x | y |
+ ---------+------+
| 3000000 | 3 |
+ ---------+------+

    按照snapshot isolation来说session2的trx_id 大于session1的trx_id,从而session2的修改对session1应该是不可见的:即session1应该更新0行,但是MySQL在这里却对y=2进行了更新。

    MySQL官方在5.5+的文档也针对该问题做出了Note:

The snapshot of the database state applies to SELECT statements within a transaction, not necessarily to DMLstatements. If you insert or modify some rows and then commit that transaction, a DELETE or UPDATE statement issued from another concurrent REPEATABLE READ transaction could affect those just-committed rows, even though the session could not query them. If a transaction does update or delete rows committed by a different transaction, those changes do become visible to the current transaction.

    根本原因在于MySQL在update/delete/insert/select for update/select lock in share mode时进行的是current read(select_lock_type != LOCK_NONE)而非consistent read。而Oracle解决这个问题的方式是对比current read和consistent read来决定是否进行query restart;对于该案例,session1在T2时更新到x=3000000时发现y发生了变化从而回滚了这个变更并进入query restart,最终结果就是在T3时更新了0行。

    因此,如果业务依赖事务但是又不清楚具体数据库的实现细节,很容易就掉到坑里了;比如这个案例,就产生了"错误的"更新。

    下面针对MySQL RR 给出一个非谓词更新的一个案例:如果不理解这块事务,在T3时想当然就会觉得结果应该是6000,可能就犯错了。

RR && autocommit=0

T Session1 Session2
T1
1
2
3
4
5
6
7
8
begin ;
select  from  where  x = 88;
+ ----+------+
| x | y |
+ ----+------+
| 88 | 3000 |
+ ----+------+
1 row  in  set  (0.00 sec)

T2
1
2
3
4
5
update  t1  set  b = 8000
where  x = 88;
Query OK, 1 row affected
Rows  matched: 1 Changed: 1
commit
T3
1
2
3
4
5
6
7
8
9
10
select  from  t1  where  a = 88;
+ ----+------+
| x | y |
+ ----+------+
| 88 | 3000 |
+ ----+------+
1 row  in  set  (0.00 sec)
update  t1  set  y = y + 3000  where  x = 88;
Query OK, 1 row affected (0.00 sec)
Rows  matched: 1 Changed: 1 Warnings: 0


1
2
3
4
5
6
7
select  from  t1  where  x = 88;
+ ----+-------+
| x | y |
+ ----+-------+
| 88 | 11000 |
+ ----+-------+
1 row  in  set  (0.00 sec)


本文转自MIKE老毕 51CTO博客,原文链接:http://blog.51cto.com/boylook/1689256,如需转载请自行联系原作者


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
关系型数据库 MySQL
Mysql的MVCC机制
Mysql的MVCC机制
|
Oracle 关系型数据库 MySQL
MySQL相关(六)- 事务隔离级别的实现方案(MVCC)
MySQL相关(六)- 事务隔离级别的实现方案(MVCC)
175 0
|
5月前
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
存储 关系型数据库 MySQL
MySQL MVCC全面解读:掌握并发控制的核心机制
【10月更文挑战第15天】 在数据库管理系统中,MySQL的InnoDB存储引擎采用了一种称为MVCC(Multi-Version Concurrency Control,多版本并发控制)的技术来处理事务的并发访问。MVCC不仅提高了数据库的并发性能,还保证了事务的隔离性。本文将深入探讨MySQL中的MVCC机制,为你在面试中遇到的相关问题提供全面的解答。
921 2
|
10月前
|
SQL 关系型数据库 MySQL
京东面试:MySQL MVCC是如何实现的?如何通过MVCC实现读已提交、可重复读隔离级别的?
1.请解释什么是MVCC,它在数据库中的作用是什么? 2.在MySQL中,MVCC是如何实现的?请简述其工作原理。 3.MVCC是如何解决读-写和写-写冲突的? 4.在并发环境中,当多个事务同时读取同一行数据时,MVCC是如何保证每个事务看到的数据版本是一致的? 5.MVCC如何帮助提高数据库的并发性能?
京东面试:MySQL MVCC是如何实现的?如何通过MVCC实现读已提交、可重复读隔离级别的?
|
存储 关系型数据库 MySQL
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
|
11月前
|
SQL 存储 关系型数据库
MySQL进阶突击系列(05)突击MVCC核心原理 | 左右护法ReadView视图和undoLog版本链强强联合
2024年小结:感谢阿里云开发者社区每月的分享交流活动,支持持续学习和进步。过去五个月投稿29篇,其中17篇获高分认可。本文详细介绍了MySQL InnoDB存储引擎的MVCC机制,包括数据版本链、readView视图及解决脏读、不可重复读、幻读问题的demo演示。
|
存储 关系型数据库 MySQL
MySQL MVCC深度解析:掌握并发控制的艺术
【10月更文挑战第23天】 在数据库领域,MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种重要的并发控制机制,它允许多个事务并发执行而不产生冲突。MySQL作为广泛使用的数据库系统,其InnoDB存储引擎就采用了MVCC来处理事务。本文将深入探讨MySQL中的MVCC机制,帮助你在面试中自信应对相关问题。
437 3
|
关系型数据库 MySQL 数据库
MySQL高级篇——MVCC多版本并发控制
什么是MVCC、快照读与当前读、隐藏字段、Undo Log版本链、ReadView、举例说明、InnoDB 解决幻读问题
MySQL高级篇——MVCC多版本并发控制
|
SQL 关系型数据库 MySQL
Mysql原理与调优-事务与MVCC
【8月更文挑战第19天】

推荐镜像

更多