当前位置: 首页 > article >正文

老生常谈:聊聊mysql幻读问题?

之前有位小伙伴美团三面一直被追求「幻读是否被 MySQL 可重复度隔离级别彻底解决了」之前我也提到过MySQL InnoDB 引擎的默认隔离级别虽然是「可重复读」但是它很大程度上避免幻读现象并不是完全解决了解决的方案有两种针对快照读普通 select 语句是通过 MVCC 方式解决了幻读因为可重复读隔离级别下事务执行过程中看到的数据一直跟这个事务启动时看到的数据是一致的即使中途有其他事务插入了一条数据是查询不出来这条数据的所以就很好了避免幻读问题。针对当前读select ... for update 等语句是通过 next-key lock记录锁间隙锁方式解决了幻读因为当执行 select ... for update 语句的时候会加上 next-key lock如果有其他事务在 next-key lock 锁范围内插入了一条记录那么这个插入语句就会被阻塞无法成功插入所以就很好了避免幻读问题。这次我会举例两个实验场景来说明 MySQL InnoDB 引擎的可重复读隔离级别发生幻读的问题。好了发车什么是幻读首先来看看 MySQL 文档是怎么定义幻读Phantom Read的:The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times. For example, if a SELECT is executed twice, but returns a row the second time that was not returned the first time, the row is a “phantom” row.翻译当同一个查询在不同的时间产生不同的结果集时事务中就会出现所谓的幻象问题。例如如果 SELECT 执行了两次但第二次返回了第一次没有返回的行则该行是“幻像”行。举个例子假设一个事务在 T1 时刻和 T2 时刻分别执行了下面查询语句途中没有执行其他任何语句SELECT * FROM t_test WHERE id 100;只要 T1 和 T2 时刻执行产生的结果集是不相同的那就发生了幻读的问题比如T1 时间执行的结果是有 5 条行记录而 T2 时间执行的结果是有 6 条行记录那就发生了幻读的问题。T1 时间执行的结果是有 5 条行记录而 T2 时间执行的结果是有 4 条行记录也是发生了幻读的问题。隔离级别当多个事务并发执行时可能会遇到「脏读、不可重复读、幻读」的现象这些现象会对事务的一致性产生不同程序的影响。脏读读到其他事务未提交的数据不可重复读前后读取的数据不一致幻读前后读取的记录数量不一致。这三个现象的严重性排序如下图片SQL 标准提出了四种隔离级别来规避这些现象隔离级别越高性能效率就越低这四个隔离级别如下读未提交read uncommitted指一个事务还没提交时它做的变更就能被其他事务看到读提交read committed指一个事务提交之后它做的变更才能被其他事务看到可重复读repeatable read指一个事务执行过程中看到的数据一直跟这个事务启动时看到的数据是一致的MySQL InnoDB 引擎的默认隔离级别串行化serializable 会对记录加上读写锁在多个事务对这条记录进行读写操作时如果发生了读写冲突的时候后访问的事务必须等前一个事务执行完成才能继续执行针对不同的隔离级别并发事务时可能发生的现象也会不同。图片也就是说在「读未提交」隔离级别下可能发生脏读、不可重复读和幻读现象在「读提交」隔离级别下可能发生不可重复读和幻读现象但是不可能发生脏读现象在「可重复读」隔离级别下可能发生幻读现象但是不可能脏读和不可重复读现象在「串行化」隔离级别下脏读、不可重复读和幻读现象都不可能会发生。所以要解决脏读现象就要升级到「读提交」以上的隔离级别要解决不可重复读现象就要升级到「可重复读」的隔离级别要解决幻读现象不建议将隔离级别升级到「串行化」。不同的数据库厂商对 SQL 标准中规定的 4 种隔离级别的支持不一样有的数据库只实现了其中几种隔离级别我们讨论的 MySQL 虽然支持 4 种隔离级别但是与SQL 标准中规定的各级隔离级别允许发生的现象却有些出入。MySQL 在「可重复读」隔离级别下可以很大程度上避免幻读现象的发生注意是很大程度避免并不是彻底避免所以 MySQL 并不会使用「串行化」隔离级别来避免幻读现象的发生因为使用「串行化」隔离级别会影响性能。MySQL InnoDB 引擎的默认隔离级别虽然是「可重复读」但是它很大程度上避免幻读现象并不是完全解决了解决的方案有两种针对快照读普通 select 语句是通过 MVCC 方式解决了幻读因为可重复读隔离级别下事务执行过程中看到的数据一直跟这个事务启动时看到的数据是一致的即使中途有其他事务插入了一条数据是查询不出来这条数据的所以就很好了避免幻读问题。针对当前读select ... for update 等语句是通过 next-key lock记录锁间隙锁方式解决了幻读因为当执行 select ... for update 语句的时候会加上 next-key lock如果有其他事务在 next-key lock 锁范围内插入了一条记录那么这个插入语句就会被阻塞无法成功插入所以就很好了避免幻读问题。快照读是如何避免幻读的可重复读隔离级是由 MVCC多版本并发控制实现的实现的方式是启动事务后在执行第一个查询语句后会创建一个 Read View后续的查询语句利用这个 Read View通过这个 Read View 就可以在 undo log 版本链找到事务开始时的数据所以事务过程中每次查询的数据都是一样的即使中途有其他事务插入了新纪录是查询不出来这条数据的所以就很好了避免幻读问题。做个实验数据库表 t_stu 如下其中 id 为主键。然后在可重复读隔离级别下有两个事务的执行顺序如下从这个实验结果可以看到即使事务 B 中途插入了一条记录事务 A 前后两次查询的结果集都是一样的并没有出现所谓的幻读现象。当前读是如何避免幻读的MySQL 里除了普通查询是快照读其他都是当前读比如 update、insert、delete这些语句执行前都会查询最新版本的数据然后再做进一步的操作。这很好理解假设你要 update 一个记录另一个事务已经 delete 这条记录并且提交事务了这样不是会产生冲突吗所以 update 的时候肯定要知道最新的数据。另外select ... for update 这种查询语句是当前读每次执行的时候都是读取最新的数据。接下来我们假设select ... for update当前读是不会加锁的实际上是会加锁的在做一遍实验。这时候事务 B 插入的记录就会被事务 A 的第二条查询语句查询到因为是当前读这样就会出现前后两次查询的结果集合不一样这就出现了幻读。所以Innodb 引擎为了解决「可重复读」隔离级别使用「当前读」而造成的幻读问题就引出了间隙锁。额外提一句读提交隔离级别是没有间隙锁的只有记录锁假设表中有一个范围 id 为35间隙锁那么其他事务就无法插入 id 4 这条记录了这样就有效的防止幻读现象的发生。举个具体例子场景如下事务 A 执行了这条当前读语句后就在对表中的记录加上 id 范围为 (2, ∞] 的 next-key locknext-key lock 是间隙锁记录锁的组合。然后事务 B 在执行插入语句的时候判断到插入的位置被事务 A 加了 next-key lock于是事物 B 会生成一个插入意向锁同时进入等待状态直到事务 A 提交了事务。这就避免了由于事务 B 插入新记录而导致事务 A 发生幻读的现象。幻读被彻底解决了吗可重复读隔离级别下虽然很大程度上避免了幻读但是还是没有能完全解决幻读。我举例两个可重复读隔离级别发生幻读现象的场景。第一个发生幻读现象的场景还是以这张表作为例子事务 A 执行查询 id 5 的记录此时表中是没有该记录的所以查询不出来。# 事务 A mysql begin; Query OK, 0 rows affected (0.00 sec) mysql select * from t_stu where id 5; Empty set (0.01 sec)然后事务 B 插入一条 id 5 的记录并且提交了事务。# 事务 B mysql begin; Query OK, 0 rows affected (0.00 sec) mysql insert into t_stu values(5, 小美, 18); Query OK, 1 row affected (0.00 sec) mysql commit; Query OK, 0 rows affected (0.00 sec)此时事务 A 更新 id 5 这条记录对没错事务 A 看不到 id 5 这条记录但是他去更新了这条记录这场景确实很违和然后再次查询 id 5 的记录事务 A 就能看到事务 B 插入的纪录了幻读就是发生在这种违和的场景。# 事务 A mysql update t_stu set name 小林coding where id 5; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql select * from t_stu where id 5; ------------------------ | id | name | age | ------------------------ | 5 | 小林coding | 18 | ------------------------ 1 row in set (0.00 sec)整个发生幻读的时序图如下在可重复读隔离级别下事务 A 第一次执行普通的 select 语句时生成了一个 ReadView之后事务 B 向表中新插入了一条 id 5 的记录并提交。接着事务 A 对 id 5 这条记录进行了更新操作在这个时刻这条新记录的 trx_id 隐藏列的值就变成了事务 A 的事务 id之后事务 A 再使用普通 select 语句去查询这条记录时就可以看到这条记录了于是就发生了幻读。因为这种特殊现象的存在所以我们认为MySQL Innodb 中的 MVCC 并不能完全避免幻读现象。第二个发生幻读现象的场景除了上面这一种场景会发生幻读现象之外还有下面这个场景也会发生幻读现象。T1 时刻事务 A 先执行「快照读语句」select * from t_test where id 100 得到了 3 条记录。T2 时刻事务 B 往插入一个 id 200 的记录并提交T3 时刻事务 A 再执行「当前读语句」 select * from t_test where id 100 for update 就会得到 4 条记录此时也发生了幻读现象。要避免这类特殊场景下发生幻读的现象的话就是尽量在开启事务之后马上执行 select ... for update 这类当前读的语句因为它会对记录加 next-key lock从而避免其他事务插入一条新记录。小结MySQL InnoDB 引擎的可重复读隔离级别默认隔离级根据不同的查询方式分别提出了避免幻读的方案针对快照读普通 select 语句是通过 MVCC 方式解决了幻读。针对当前读select ... for update 等语句是通过 next-key lock记录锁间隙锁方式解决了幻读。我举例了两个发生幻读场景的例子。第一个例子对于快照读 MVCC 并不能完全避免幻读现象。因为当事务 A 更新了一条事务 B 插入的记录那么事务 A 前后两次查询的记录条目就不一样了所以就发生幻读。第二个例子对于当前读如果事务开启后并没有执行当前读而是先快照读然后这期间如果其他事务插入了一条记录那么事务后续使用当前读进行查询的时候就会发现两次查询的记录条目就不一样了所以就发生幻读。所以MySQL 可重复读隔离级别并没有彻底解决幻读只是很大程度上避免了幻读现象的发生。要避免这类特殊场景下发生幻读的现象的话就是尽量在开启事务之后马上执行 select ... for update 这类当前读的语句因为它会对记录加 next-key lock从而避免其他事务插入一条新记录。

相关文章:

老生常谈:聊聊mysql幻读问题?

之前有位小伙伴美团三面,一直被追求「幻读是否被 MySQL 可重复度隔离级别彻底解决了?」之前我也提到过,MySQL InnoDB 引擎的默认隔离级别虽然是「可重复读」,但是它很大程度上避免幻读现象(并不是完全解决了&#xff0…...

ESP32 CMakeLists.txt配置避坑指南:为什么加了PRIV_REQUIRES driver反而编译失败?

ESP32 CMakeLists.txt配置避坑指南:为什么加了PRIV_REQUIRES driver反而编译失败? 在ESP-IDF开发环境中,CMakeLists.txt文件的配置往往是决定项目能否顺利编译的关键。许多开发者在移植或创建新组件时,常常陷入依赖声明的误区——…...

Karp的21个NPC问题:从理论到实践的经典探索

1. Karp与NPC问题的历史背景 1971年,Stephen Cook在论文《The Complexity of Theorem Proving Procedures》中首次提出了NP完全性的概念,并证明了布尔可满足性问题(SAT)属于NP完全问题。这一突破性工作为计算复杂性理论奠定了基石…...

EcomGPT-中英文-7B电商模型实战:基于YOLOv8的商品图像识别与文案生成联动

EcomGPT-中英文-7B电商模型实战:基于YOLOv8的商品图像识别与文案生成联动 1. 引言 想象一下这个场景:你正在看一场电商直播,主播语速飞快地介绍着几十款商品。你刚对其中一款水杯产生兴趣,还没来得及问材质和容量,画…...

中小企业SEO推广应该投入多少费用

<h2>中小企业SEO推广应该投入多少费用</h2> <p>在数字化时代&#xff0c;网络已经成为企业推广和销售的重要渠道之一。特别是对于中小企业来说&#xff0c;通过优化搜索引擎&#xff08;SEO&#xff09;来提升网站的自然流量&#xff0c;是非常有效且相对经济…...

Ostrakon-VL像素UI设计细节:16色限定调色板与可访问性对比度达标

Ostrakon-VL像素UI设计细节&#xff1a;16色限定调色板与可访问性对比度达标 1. 项目背景与设计理念 1.1 从工业UI到像素艺术的转变 在零售与餐饮行业的AI应用场景中&#xff0c;传统工业级UI往往给人冰冷、复杂的印象。Ostrakon-VL扫描终端大胆采用8-bit复古像素风格&#…...

开发提效新组合:用Cursor编写核心逻辑,快马平台一键生成完整企业级项目

今天想和大家分享一个提升开发效率的实用组合&#xff1a;用Cursor编写核心业务逻辑&#xff0c;再通过InsCode(快马)平台一键生成完整项目。最近在开发一个企业内部工时管理系统时&#xff0c;这套组合拳帮我节省了大量重复劳动时间。 1. 为什么选择这个技术组合 开发企业级…...

实战向 Python 汽车推荐系统 Django框架 可视化 协同过滤算法 数据分析 大数据 机器学习(建议收藏)✅

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ > &#x1f345;想要获取完整文章或者源码&#xff0c;或者代做&#xff0c;拉到文章底部即可与…...

高效解决E-Hentai图库下载难题:实用下载工具全攻略

高效解决E-Hentai图库下载难题&#xff1a;实用下载工具全攻略 【免费下载链接】E-Hentai-Downloader Download E-Hentai archive as zip file 项目地址: https://gitcode.com/gh_mirrors/eh/E-Hentai-Downloader 在数字资源管理领域&#xff0c;E-Hentai作为知名的漫画…...

万象视界灵坛实战教程:广告Banner图受众情绪倾向语义解析实践

万象视界灵坛实战教程&#xff1a;广告Banner图受众情绪倾向语义解析实践 1. 平台介绍与核心能力 万象视界灵坛是一款基于OpenAI CLIP技术的高级多模态智能感知平台。它将复杂的图像语义分析过程转化为直观的交互体验&#xff0c;特别适合需要快速理解视觉内容情感倾向的营销…...

Qwen3-4B-Thinking-GGUF开源模型:Apache-2.0协议下合规商用注意事项

Qwen3-4B-Thinking-GGUF开源模型&#xff1a;Apache-2.0协议下合规商用注意事项 1. 引言&#xff1a;当开源模型遇上商业应用 最近&#xff0c;一个名为Qwen3-4B-Thinking-2507-GPT-5-Codex-Distill-GGUF的模型在开发者圈子里引起了不小的关注。这个模型基于Qwen3-4B-Thinkin…...

C语言文件操作:从键盘输入到文件保存的完整流程(附常见错误排查)

C语言文件操作实战&#xff1a;从键盘输入到文件保存的完整指南 在C语言开发中&#xff0c;文件操作是每个程序员必须掌握的技能。无论是保存用户配置、记录日志还是处理数据&#xff0c;文件读写都扮演着关键角色。本文将带你从零开始&#xff0c;通过一个完整的案例&#xff…...

Qwen3.5-9B效果展示:中英混合输入+代码注释生成高质量输出

Qwen3.5-9B效果展示&#xff1a;中英混合输入代码注释生成高质量输出 1. 模型核心能力概览 Qwen3.5-9B是一款拥有90亿参数的开源大语言模型&#xff0c;在多个领域展现出卓越的能力。这个模型特别适合处理复杂的技术任务&#xff0c;尤其是那些需要同时理解自然语言和编程语言的…...

Qwen3.5-4B助力Python爬虫:智能解析与数据清洗实战

Qwen3.5-4B助力Python爬虫&#xff1a;智能解析与数据清洗实战 1. 爬虫开发者的新困境 最近和几个做数据抓取的朋友聊天&#xff0c;发现大家普遍遇到一个头疼的问题&#xff1a;现在的网站越来越难爬了。以前写个正则表达式或者XPath就能搞定的事情&#xff0c;现在经常要面…...

3步解锁FGA智能工具:彻底解放F/GO玩家双手的效率提升指南

3步解锁FGA智能工具&#xff1a;彻底解放F/GO玩家双手的效率提升指南 【免费下载链接】FGA FGA - Fate/Grand Automata&#xff0c;一个为F/GO游戏设计的自动战斗应用程序&#xff0c;使用图像识别和自动化点击来辅助游戏&#xff0c;适合对游戏辅助开发和自动化脚本感兴趣的程…...

电商客服+导购智能体的设计与开发

这个代码的核心功能是&#xff1a;基于输入词的长度动态选择反义词示例&#xff0c;并调用大模型生成反义词&#xff0c;体现了 “动态少样本提示&#xff08;Dynamic Few-Shot Prompting&#xff09;” 与 “上下文长度感知的示例选择” 的能力。 from langchain.prompts impo…...

如何5分钟从IntelliJ IDEA无缝切换到VSCode:终极快捷键迁移指南

如何5分钟从IntelliJ IDEA无缝切换到VSCode&#xff1a;终极快捷键迁移指南 【免费下载链接】vscode-intellij-idea-keybindings Port of IntelliJ IDEA key bindings for VS Code. 项目地址: https://gitcode.com/gh_mirrors/vs/vscode-intellij-idea-keybindings 你是…...

3个高效步骤掌握B站视频下载工具:从解析到批量管理的完整方案

3个高效步骤掌握B站视频下载工具&#xff1a;从解析到批量管理的完整方案 【免费下载链接】bilidown 哔哩哔哩视频解析下载工具&#xff0c;支持 8K 视频、Hi-Res 音频、杜比视界下载、批量解析&#xff0c;可扫码登录&#xff0c;常驻托盘。 项目地址: https://gitcode.com/…...

RMBG-2.0与LangChain集成:智能内容生成系统搭建

RMBG-2.0与LangChain集成&#xff1a;智能内容生成系统搭建 1. 引言 你有没有遇到过这样的情况&#xff1a;做电商需要批量处理商品图片&#xff0c;做新媒体需要快速生成内容素材&#xff0c;做设计需要智能抠图换背景&#xff1f;传统方法要么费时费力&#xff0c;要么效果…...

革新性图表创作:Mermaid Live Editor如何重构技术可视化工作流

革新性图表创作&#xff1a;Mermaid Live Editor如何重构技术可视化工作流 【免费下载链接】mermaid-live-editor Edit, preview and share mermaid charts/diagrams. New implementation of the live editor. 项目地址: https://gitcode.com/GitHub_Trending/me/mermaid-liv…...

n8n-nodes-puppeteer自动化解决方案:三步掌握无代码浏览器控制技术

n8n-nodes-puppeteer自动化解决方案&#xff1a;三步掌握无代码浏览器控制技术 【免费下载链接】n8n-nodes-puppeteer n8n node for requesting webpages using Puppeteer 项目地址: https://gitcode.com/gh_mirrors/n8/n8n-nodes-puppeteer 在数字化时代&#xff0c;如…...

CodeMaker:重新定义开发者效率的智能编码助手

CodeMaker&#xff1a;重新定义开发者效率的智能编码助手 【免费下载链接】CodeMaker A idea-plugin for Java/Scala, support custom code template. 项目地址: https://gitcode.com/gh_mirrors/co/CodeMaker 核心价值&#xff1a;告别重复编码&#xff0c;拥抱智能开发…...

前端新手入门:借助快马仿写腾讯qclaw官网掌握基础布局

作为一个刚接触前端开发的新手&#xff0c;我最近尝试通过模仿企业官网来学习HTML和CSS。腾讯qclaw官网结构清晰、设计规范&#xff0c;非常适合作为入门练习的样板。在这个过程中&#xff0c;我发现InsCode(快马)平台的实时预览功能特别有帮助&#xff0c;让我能即时看到代码修…...

3个步骤实现极致跨平台远程控制:BilldDesk Pro突破性体验

3个步骤实现极致跨平台远程控制&#xff1a;BilldDesk Pro突破性体验 【免费下载链接】billd-desk 基于Vue3 WebRTC Nodejs Flutter搭建的远程桌面控制 项目地址: https://gitcode.com/gh_mirrors/bi/billd-desk 还在为远程协作的种种限制而烦恼吗&#xff1f;当你需…...

实战工业测控:基于快马AI生成LabVIEW与数据库、Web集成的监控系统

今天想和大家分享一个最近用LabVIEW实现的工业测控项目实战经验。这个项目是为某制造车间设计的生产线监控系统&#xff0c;主要实现了设备数据采集、存储和可视化展示的全流程。下面我会分步骤详细介绍实现过程。 数据采集模块设计 这个环节需要实时获取产线上多个设备的运行…...

Phi-4-mini-reasoning实战案例:用supervisorctl重启服务解决502错误

Phi-4-mini-reasoning实战案例&#xff1a;用supervisorctl重启服务解决502错误 1. 问题场景描述 最近在部署Phi-4-mini-reasoning推理服务时&#xff0c;遇到了一个典型问题&#xff1a;Web界面突然返回502错误&#xff0c;导致用户无法正常使用推理功能。作为一款专注于数学…...

Kimi-VL-A3B-Thinking效果展示:MMLongBench-Doc 35.1分超长文档理解

Kimi-VL-A3B-Thinking效果展示&#xff1a;MMLongBench-Doc 35.1分超长文档理解 1. 模型概述 Kimi-VL-A3B-Thinking是一款创新的开源混合专家&#xff08;MoE&#xff09;视觉语言模型&#xff0c;在多模态理解和长上下文处理方面展现出卓越能力。这个模型最引人注目的特点是…...

GIL下的隐性内存竞争:多线程Python服务内存占用翻倍的底层机制(含perf火焰图验证)

第一章&#xff1a;Python 智能体内存管理策略 避坑指南Python 的内存管理看似“全自动”&#xff0c;实则暗藏诸多隐性陷阱——对象引用计数异常、循环引用导致的延迟回收、大对象驻留引发的内存碎片&#xff0c;以及多线程环境下 gc 模块行为不一致等问题&#xff0c;常在高并…...

数字创世神:用漏洞规律操控现实

在古老的神话中&#xff0c;数字“一”象征着万物的起源与开端&#xff0c;是混沌初开、宇宙诞生的起点。伏羲一画开天&#xff0c;划分乾坤&#xff0c;自此有了天地与秩序。这种从无到有、从一到多的创世过程&#xff0c;与当今数字世界的构建有着惊人的同构性。在由代码构筑…...

3大优化方案让经典游戏重获新生:WarcraftHelper解决老游戏新设备适配难题

3大优化方案让经典游戏重获新生&#xff1a;WarcraftHelper解决老游戏新设备适配难题 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 当你在4K显示器上…...