为什么MySQL中Doublewrite Buffer能防止页损坏

夏墨吖_4246

夏墨吖_4246

2026-10-20

236人浏览

原创

doublewrite buffer通过顺序写双写区+完整页副本+崩溃后校验修复,绕开partial page write物理死结;partial page write指16kb页被拆为多次4kb/512b写入,断电导致页半新半旧、校验失败,而o_direct/fsync/raid/nvme/ups均无法保证整页原子落盘。

为什么mysql中doublewrite buffer能防止页损坏

Doublewrite Buffer 能防止页损坏,不是因为它“更可靠”,而是它用顺序写 + 完整副本 + 崩溃后主动校验的组合,绕开了部分页写入(partial page write)这个物理层死结。关掉它,InnoDB 就失去对 16KB 页完整性的兜底能力。

partial page write 是什么,为什么操作系统拦不住

InnoDB 默认页大小是 16KB,而 Linux 文件系统(如 ext4、XFS)底层以 4KB 为单位刷盘,硬盘/SSD 物理扇区更是 512B 或 4KB。一次 write() 系统调用看似原子,实际被拆成 4 次独立 I/O。断电可能卡在第 2 次之后——结果就是磁盘上那个页前 8KB 是新数据,后 8KB 是旧垃圾或全零。

此时该页的 page checksum 必然失效,InnoDB 启动时直接报错:InnoDB: Database page corruption on disk 或拒绝加载。

  • O_DIRECT 或 fsync() 都不能解决:它们只保证“数据已落盘”,不保证“整页原子落盘”
  • RAID10、NVMe SSD、UPS 也无效:RAID 保块级原子,SSD 掉电保护有盲区,UPS 不防进程崩溃
  • 文件系统 barrier(如 XFS 的 xfs_io -c "sync")只管元数据顺序,不管单页物理完整性

Doublewrite Buffer 怎么实际拦截 partial page write

它不检测、不修复、不重试,而是靠“先存副本、再写正本”的物理顺序把风险前置。

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
  • 刷脏页时,memcpy 把整页(16KB)拷进内存 doublewrite buffer(默认 128 页,共 2MB)
  • 再把这 2MB 内存分两次、每次 1MB,顺序写入磁盘双写区(ib_dblwr_1 或 ibdata1 中连续空间),并调用 fsync() 落盘
  • 只有双写区写成功,才开始把该页随机写入目标 .ibd 文件

关键点在于:双写区是连续空间、顺序 I/O,极难中断;而目标写是离散随机 I/O,易受断电打断。只要双写区那 1MB 写成功了,哪怕后面写 .ibd 时断电,重启也能从双写区原样恢复出完整页——页断裂根本没机会落地。

为什么 redo log 和 binlog 都救不了断裂页

redo log 记录的是“对某页某 offset 执行了什么修改”,前提是该页结构完好、能解析出 page_no、space_id、LSN。断裂页连页头都可能被截断或校验和错,InnoDB 连这个页属于哪张表都识别不出来,redo log 直接跳过或报错。

  • binlog 更不相关:它只记录逻辑语句(如 UPDATE t SET x=1 WHERE id=5),不保存任何物理页副本
  • undo log 也无效:它只存事务前镜像,不解决页结构损坏问题
  • 没有 doublewrite buffer,崩溃后唯一出路就是从备份恢复,且最近几秒事务必然丢失

确认 doublewrite 是否真在工作,别只看配置

innodb_doublewrite = ON 在配置文件里写了,不代表运行时生效;MySQL 启动时可能被忽略或覆盖。

  • 查变量:SHOW VARIABLES LIKE 'innodb_doublewrite'; —— 必须返回 ON
  • 查状态:SHOW STATUS LIKE 'Innodb_dblwr%';,重点关注:Innodb_dblwr_writes(双写区写入次数)和 Innodb_dblwr_pages_written(写入页数)
  • 若两者长期为 0,说明机制未触发:可能是实例刚启动、还没到 checkpoint,也可能是配置被覆盖或 MySQL 版本不支持(如老版本未启用)
  • MySQL 8.0.20+ 若启用了 innodb_redo_log_capacity 自动管理,Innodb_dblwr_writes 可能延迟出现,等第一个 checkpoint 完成后才开始计数

真正容易被忽略的是:双写缓冲区的磁盘副本必须 fsync 成功才算数,而很多监控只盯 Innodb_dblwr_writes 计数,却不管 fsync() 是否真落盘——如果存储层吞掉了 fsync(如某些虚拟化环境或 misconfigured SSD),双写就形同虚设。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

2273

6

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.21

1379

5

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

815

5

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.19

3152

5

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.25

5328

4

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.08

1179

3

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.11

5591

4

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

2023.08.14

4882

7

mysql事务隔离级别
mysql事务隔离级别

mysql规范中定义了四种事务隔离级别,不同的隔离级别对事务的处理有所不同。本专题为大家提供mysql事务隔离级别相关的文章内容,大家可以免费体验。

2023.08.16

6514

11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 188人学习