幻读“异常”引出的快照读创建点问题

简介: 幻读“异常”引出的快照读创建点问题

导读

重温快照读、当前读。

本文节选自叶金荣有赞专栏《乱弹MySQL》。

关于InnoDB在事务中何时创建read view,我在 InnoDB MVCC何时创建read view 这篇文章里已经说过,在RC(read committed)隔离级别下是每次SELECT都会构造最新的read view,而在RR(repeatable read)隔离级别下是在事务中发起第一个SELECT时构造read view。接下来我们来看一个幻读的案例。先看运行环境:

[root@yejr.me]>\s
...
Server version:     5.6.21-log MySQL Community Server (GPL)
...
[root@yejr.me]>select * from information_schema.GLOBAL_VARIABLES where
    VARIABLE_NAME = 'innodb_locks_unsafe_for_binlog';
+--------------------------------+----------------+
| VARIABLE_NAME                  | VARIABLE_VALUE |
+--------------------------------+----------------+
| INNODB_LOCKS_UNSAFE_FOR_BINLOG | ON             |
+--------------------------------+----------------+

[root@yejr.me]>select @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ       |
+-----------------------+

也就是在RR隔离级别下,又设置了 INNODB_LOCKS_UNSAFE_FOR_BINLOG=1,其效果相当于禁用GAP LOCK。换言之,也相当于是把隔离级别降到了RC,这时候会产生幻读。P.S,关于INNODB_LOCKS_UNSAFE_FOR_BINLOG=1有几点提醒:

  • 已经使用RR级别时,最好就不要再将该选项设置为1了,否则有可能会造成主从数据不一致(这时应该同时设置binlog_format=ROW
  • 该选项设置为1时,唯一键和外键约束检测依然会使用next-key lock
  • 该选项只能在启动时设置,且不能在运行过程中动态修改,而事务隔离级别则可以在运行过程中动态修改。从这方面出发,其实有需要的话,最好是自行调整隔离级别就好,而不是设置本选项
  • 该选项从8.0版本开始已经被删除

接来看下这种情况下的幻读案例场景。关于测试表的背景信息:

[root@yejr.me]> show create table t1\G

CREATE TABLE `t1` (
`c1` int(10) unsigned NOT NULL DEFAULT 0,
`c2` int(10) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`c1`),
KEY `c2` (`c2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

场景1

session1 session2
begin; begin;
select from t1 where c2 = 5;
...
| 5 | 5 |


select from t1 where c2 = 5;
...
| 5 | 5 |
insert into t1 select 7,5;
commit;


select from t1 where c2 = 5 for update;
...
| 5 | 5 |
| 7 | 5 |

select from t1 where c2 = 5;
#去掉for update后,只能看到一条记录
...
| 5 | 5 |

场景2

session1 session2
begin; begin;
select from t1 where c2 = 5;
...
| 5 | 5 |


select from t1 where c2 = 5 for update;
...
| 5 | 5 |
insert into t1 select 7,5;
commit;
#不会被阻塞


select from t1 where c2 = 5;
...
| 5 | 5 |
| 7 | 5 |
#看到两条记录,疑似发生了幻读?

场景3

session1 session2
begin; start transaction with consistent snapshot;
select from t1 where c2 = 5;
...
| 5 | 5 |

insert into t1 select 7,5;
commit;


select from t1 where c2 = 5 for update;
...
| 5 | 5 |
| 7 | 5 |

select from t1 where c2 = 5;
#去掉for update后,只能看到一条记录
...
| 5 | 5 |

咦,这个案例看起来和场景1有点像?注意到上面3个案例之间的区别了吗,我们来罗列一下:

  • 场景1,session2的第一个select是在session1执行commit之后发起的,此时构建read view
  • 场景2,session2的第一次读是select ... for update形式的,此时似乎没有创建read view
  • 场景3,session2发起事务时直接加了with consistent snapshot,也就是要求创建一致性快照读
  • 看起来场景1和场景3,都是在事务提交前创建了read view
  • 而场景2里,session2是在第二次的select才创建快照,而不是在第一次select ... for update时就创建read viw

上面其实已经提到了几个关键信息:

  1. 在RR隔离级别下,遇到第一个普通SELECT才会开始创建read view。而如果SELECT ... FOR UPDATE/FOR SHARE这样的,叫做当前读或加锁读,这种是不会创建read view的
  2. 即便是 innodb_locks_unsafe_for_binlog=1 的时候,在RR隔离级别下,事务中第一个普通SELECT创建的快照在整个事务过程中依然有效,这个选项的作用只是禁用了gap lock,并不会影响RR级别的其他行为
  3. 发起事务时,如果加上with consistent snapshot会立即创建read view,和事务启动后立刻发起普通SELECT相同效果
  4. 在RC隔离级别下,还是每次普通SELECT都会重新创建read view

好了,就酱。Enjoy MySQL :)

            </div>
相关文章
|
2天前
|
弹性计算 运维 搜索推荐
三翼鸟携手阿里云ECS g9i:智慧家庭场景的效能革命与未来生活新范式
三翼鸟是海尔智家旗下全球首个智慧家庭场景品牌,致力于提供覆盖衣、食、住、娱的一站式全场景解决方案。截至2025年,服务近1亿家庭,连接设备超5000万台。面对高并发、低延迟与稳定性挑战,全面升级为阿里云ECS g9i实例,实现连接能力提升40%、故障率下降90%、响应速度提升至120ms以内,成本降低20%,推动智慧家庭体验全面跃迁。
|
3天前
|
数据采集 人工智能 自然语言处理
3分钟采集134篇AI文章!深度解析如何通过云无影AgentBay实现25倍并发 + LlamaIndex智能推荐
结合阿里云无影 AgentBay 云端并发采集与 LlamaIndex 智能分析,3分钟高效抓取134篇 AI Agent 文章,实现 AI 推荐、智能问答与知识沉淀,打造从数据获取到价值提炼的完整闭环。
351 91
|
10天前
|
人工智能 自然语言处理 前端开发
Qoder全栈开发实战指南:开启AI驱动的下一代编程范式
Qoder是阿里巴巴于2025年发布的AI编程平台,首创“智能代理式编程”,支持自然语言驱动的全栈开发。通过仓库级理解、多智能体协同与云端沙箱执行,实现从需求到上线的端到端自动化,大幅提升研发效率,重塑程序员角色,引领AI原生开发新范式。
851 156
|
3天前
|
数据采集 缓存 数据可视化
Android 无侵入式数据采集:从手动埋点到字节码插桩的演进之路
本文深入探讨Android无侵入式埋点技术,通过AOP与字节码插桩(如ASM)实现数据采集自动化,彻底解耦业务代码与埋点逻辑。涵盖页面浏览、点击事件自动追踪及注解驱动的半自动化方案,提升数据质量与研发效率,助力团队迈向高效、稳定的智能化埋点体系。(238字)
257 156
|
4天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
11天前
|
机器人 API 调度
基于 DMS Dify+Notebook+Airflow 实现 Agent 的一站式开发
本文提出“DMS Dify + Notebook + Airflow”三位一体架构,解决 Dify 在代码执行与定时调度上的局限。通过 Notebook 扩展 Python 环境,Airflow实现任务调度,构建可扩展、可运维的企业级智能 Agent 系统,提升大模型应用的工程化能力。
|
人工智能 前端开发 API
前端接入通义千问(Qwen)API:5 分钟实现你的 AI 问答助手
本文介绍如何在5分钟内通过前端接入通义千问(Qwen)API,快速打造一个AI问答助手。涵盖API配置、界面设计、流式响应、历史管理、错误重试等核心功能,并提供安全与性能优化建议,助你轻松集成智能对话能力到前端应用中。
816 154