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

Mysql-InnoDB 两次写(Doublewrite):为什么 Redo Log 救不了 “破损的页”

要理解 Doublewrite 的必要性,得先搞懂一个致命问题:Redo Log 能修复 “内容错误”,但治不了 “页结构错误”。而 InnoDB 的 “两次写” 机制,正是为了解决 “页结构被破坏” 的灾难(比如断电导致 16KB 数据页只写了 4KB)。

一、Redo Log 的 “能力边界”:只能修内容,不能修结构

Redo Log 记录的是 “对页的物理操作”(比如 “在页的偏移量 800 处写 'abc'”),但它有个前提:页本身必须是完整的
如果发生 “部分页写入(partial page write)”—— 比如 16KB 的页只写了前 4KB 就断电,页的结构已经被破坏(剩下 12KB 是旧数据或乱码),这时 Redo Log 就像 “往破损的纸上写字”,根本无法恢复:

  • 破损页的偏移量 “800” 可能已经不是原来的位置(因为页结构乱了);

  • 即使强行应用 Redo Log,写入的 “abc” 也会被破损页的乱码覆盖,导致数据彻底错误。

二、Doublewrite 的核心逻辑:先写 “完整页副本”,再写数据文件

Doublewrite 的本质是 “给页买保险”—— 在写数据文件前,先把完整的页副本存到 “共享表空间的安全区”,这样即使写数据文件时断电,也能用副本还原页结构。

流程拆解(以 “修改某行数据” 为例):

  1. 修改缓冲池里的页:用户执行UPDATE t SET name='Alice' WHERE id=1,InnoDB 先在缓冲池里找到 id=1 所在的数据页,修改 name 为 'Alice'(此时页变成 “脏页”)。

  2. 记录 Redo Log:把 “在页 X 的偏移量 100 处写 'Alice'” 的操作记录到 Redo Log(保证内容可恢复)。

  3. 复制到 Doublewrite Buffer(内存):用memcpy把整个脏页(16KB)复制到内存中的 Doublewrite Buffer(容量 2MB,可存 128 个页)。

  4. 写入共享表空间的 Doublewrite 区域(磁盘):把 Doublewrite Buffer 里的页顺序写入系统表空间(ibdata)的连续区域(2MB,128 个页),然后调用fsync确保落盘。

  5. 写入数据文件(磁盘):再把脏页写入表的.ibd 文件(可能是随机写,因为数据文件的页分布零散)。

三、崩溃恢复时的 “双保险”:先修结构,再补内容

如果在步骤 5(写数据文件)时断电,恢复流程是:

  1. 用 Doublewrite 副本还原页结构:从共享表空间的 Doublewrite 区域找到页 X 的完整副本,覆盖数据文件中破损的页 X。

  2. 用 Redo Log 补内容:应用 Redo Log 中 “在页 X 偏移量 100 处写 'Alice'” 的操作,确保数据正确。

四、为什么两次写是 “必须的”?

  1. 页大小与操作系统的 “原子写” 不匹配:InnoDB 页是 16KB,而操作系统(如 Linux)的页是 4KB,写 16KB 需要拆成 4 次 4KB 写入。如果在第 2 次写入时断电,页就会 “前 4KB 新,后 12KB 旧”,结构破损。

  2. Redo Log 无法修复破损页:如前所述,Redo Log 是 “往页上写操作”,但页本身破损时,这些操作无效。

  3. Doublewrite 的顺序写优化:共享表空间的 Doublewrite 区域是连续的 2MB 空间,写入时是顺序 IO(速度快);而数据文件的页是零散的(随机 IO,速度慢)。先写顺序的 Doublewrite,再写随机的数据文件,既保证可靠性,又没损失太多性能。

五、类比理解:给 “重要文件” 先备份再修改

假设你要修改一份 16 页的合同(对应 InnoDB 页),但打印机每次只能打 4 页(对应 OS 页)。为了防止打印到第 8 页时断电,导致合同前 8 页新、后 8 页旧(结构破损),你会:

  1. 先复印完整合同(对应写 Doublewrite Buffer);

  2. 再逐页修改原件(对应写数据文件);

  3. 若修改到第 8 页时断电,用复印件还原合同(Doublewrite 副本),再重新修改第 8 页(Redo Log)。

六、总结:Redo Log 和 Doublewrite 的分工

  • Redo Log:负责 “内容恢复”—— 记录页的具体修改,保证事务提交后数据不丢。

  • Doublewrite:负责 “结构恢复”—— 保存页的完整副本,解决 “部分页写入” 导致的结构破损。

两者配合,才让 InnoDB 在宕机后既能恢复数据内容,又能保证数据结构的完整性,成为 MySQL 最可靠的存储引擎之一。


文章转载自:

http://Wiar50Tp.nmfmL.cn
http://CdOZSt2o.nmfmL.cn
http://WFcKpj5h.nmfmL.cn
http://sfJAOR0n.nmfmL.cn
http://VH5znbJc.nmfmL.cn
http://FhSCUz2E.nmfmL.cn
http://SYJPWEKQ.nmfmL.cn
http://fBz6AFfg.nmfmL.cn
http://orjFPBzA.nmfmL.cn
http://qNXULGrM.nmfmL.cn
http://k53KYDCe.nmfmL.cn
http://pTHt2vVi.nmfmL.cn
http://sjDabA3m.nmfmL.cn
http://cEzKOjNy.nmfmL.cn
http://RjQ1xtco.nmfmL.cn
http://kJJ7eVvI.nmfmL.cn
http://aQE6c5Pt.nmfmL.cn
http://T2arQfX6.nmfmL.cn
http://txjW4Ezo.nmfmL.cn
http://DPx7aDf5.nmfmL.cn
http://WMANozqO.nmfmL.cn
http://9Xeoi0Hp.nmfmL.cn
http://kE8YA4dO.nmfmL.cn
http://wVVCMKrf.nmfmL.cn
http://hkOFD7wF.nmfmL.cn
http://1l9kILAZ.nmfmL.cn
http://PVGpaqxz.nmfmL.cn
http://5TJv3saV.nmfmL.cn
http://XZujVtLL.nmfmL.cn
http://3quoTHwg.nmfmL.cn
http://www.dtcms.com/a/376712.html

相关文章:

  • JVM新生代Eden区域深度解析
  • 在ubuntu系统中如何将docker安装在指定目录
  • 力扣hot100:环形链表(快慢指针法)(141)
  • 讯飞星火大模型Spark4.0Ultra的WebSocket交互实现解析
  • LeetCode 2958.最多K个重复元素的最长子数组
  • 【Oracle经验分享】字符串拼接过长问题的解决方案 —— 巧用 XMLAGG
  • MP381A-AB02 MEMS麦克风可靠性重新定义消费电子音频
  • 面试题:Redis要点总结(单机数据库)
  • 分类别柱状图(Vue3)
  • 视频生成迎来效率革命!字节提出视频生成稀疏注意力机制,计算量降20倍,速度升17.79倍!
  • 快速开发一类似个人网站空间的工具使用什么方式比较好,比如网页或者个Windows程序,并且使用什么技术开发比较好,区别优势局限性,分别说明一下
  • 计算机毕设选题:基于Python+MySQL校园美食推荐系统【源码+文档+调试】
  • vscode启用GEMINI CODE ASSIST插件
  • 仿QQ音乐的音乐播放器自动化测
  • daily notes[18]
  • 网络编程学习
  • App 上架全流程指南,iOS App 上架步骤、App Store 应用发布流程、uni-app 打包上传与审核要点详解
  • Java Flow API — Publisher、Subscriber 与 Processor 实战
  • 基于POI-TL实现动态Word模板数据填充(含图表):从需求到落地的完整开发实践
  • 【大模型-写作】STORM提升文章深度
  • (纯新手教学)计算机视觉(opencv)实战十四——模板与多个对象匹配
  • 论文阅读:arxiv 2024 Large Language Model Enhanced Recommender Systems: A Survey
  • 微店平台商品详情接口技术实现:从接口解析到数据结构化全方案
  • (12)使用 Vicon 室内定位系统(一)
  • 疯狂星期四文案网第65天运营日记
  • 【从零开始】12. 一切回归原点
  • JavaSE之深入浅出 IO 流:字节流、字符流与序列化流详解(含完整代码示例)
  • 【大模型推理】Qwen2.5模型硬件要求与4090Ti多并发推理方案
  • Node 中进程与子进程的区别及使用场景
  • 【C++进阶系列】:万字详解红黑树(附模拟实现的源码)