【MYSQL】innodb两次写(double write)实现解析
发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,在innodb存储引擎中,有一个叫doublewrite技术模块,是可选的。它通过参数InnoDB_doublewrite的值来控制,如果为0表示不启用,可以通过show status like "%
千家信息网最后更新 2025年02月02日【MYSQL】innodb两次写(double write)实现解析在innodb存储引擎中,有一个叫doublewrite技术模块,是可选的。它通过参数InnoDB_doublewrite的值来控制,如果为0表示不启用,可以通过show status like "%InnoDB_dblwr%"来查看,doublewrite技术带给innodb存储引擎的是数据页的可靠性,下面对doublewrite技术进行解析,让大家充分理解doublewrite是如何做到保障数据页的可靠性。
一、doublewrite应用场景:
我们知道,innodb的数据页一般大小是16KB,MySQL存取数据的最小单位也是页,而操作系统并不能保障一个数据页的原子性,也就是说当写入数据时,有可能在一个页中写入一半时(比如8K)数据库宕机,这种情况称为部分写失效(partial page write),从而导致数据丢失。
大家也许会问,难道我不可以根据redo log进行数据恢复吗?答案是肯定的也是否定的,要分为两种情况:1、数据库宕机,物理文件完好无损,是可以通过redo log进行崩溃恢复。2、数据库宕机,正在刷新到磁盘的页发生partial page write,而正好在磁盘上的这个数据页由于宕机发生损坏,这时就无法通过redo log进行数据恢复了,为什么?我们必须要清楚的认识到,redo log里记录的是对页的物理操作!比如一条redo记录"page number xx,偏移量 800 写记录 "this is abc"",那当页损坏时,这条redo记录还有意义吗?于是在这种特殊情况下,doublewrite就派上用场啦!
二、doublewrite体系结构及工作流程:
doublewrite由两部分组成,一部分为内存中的doublewrite buffer,其大小为2MB,另一部分是磁盘上共享表空间(ibdata x)中连续的128个页,即2个区(extent),大小也是2M。doublewrite工作流程如下:
1、当一系列机制(main函数触发、checkpoint等)触发数据缓冲池中的脏页进行刷新时,并不直接写磁盘,而是会通过memcpy函数将脏页先复制到内存中的doublewrite buffer,之后通过doublewrite buffer再分两次、每次1MB顺序写入共享表空间的物理磁盘上。
2、马上调用fsync函数,同步脏页进磁盘
由于在这个过程中,doublewrite页的存储时连续的,因此写入磁盘为顺序写,性能很高;完成doublewrite后,再将脏页写入实际的各个表空间文件,这时写入就是离散的了。各模块协作情况如下图(第一步应为脏页产生的redo记录logbuffer,然后logbuffer写入redo log file,为简化次要步骤直接连线表示):
查看doublewrite工作情况,可以执行命令:
mysql> show global status like 'innodb_dblwr%'\G
*************************** 1. row ***************************
Variable_name: Innodb_dblwr_pages_written
Value: 61932183
*************************** 2. row ***************************
Variable_name: Innodb_dblwr_writes
Value: 15237891
2 rows in set (0.00 sec)
以上数据显示,doublewrite一共写了 61932183个页,一共写了15237891次,从这组数据我们可以分析,之前讲过在开启doublewrite后,每次脏页刷新必须要先写doublewrite,而doublewrite存在于磁盘上的是两个连续的区,每个区由连续的页组成,一般情况下一个区最多有64个页,所以一次IO写入应该可以最多写64个页。而根据以上我这个系统Innodb_dblwr_pages_written与Innodb_dblwr_writes的比例来看,大概在4左右,远远还没到64,所以从这个角度也可以看出,系统写入压力并不高。
三、崩溃恢复
如果操作系统在将页写入磁盘的过程中发生崩溃,如上图,在恢复过程中,innodb存储引擎可以从共享表空间的doublewrite中找到该页的一个最近的副本,将其复制到表空间文件,再应用redo log,就完成了恢复过程。因为有副本所以也不担心表空间中数据页是否损坏。
四、建议
innodb存储引擎引入double write技术后,参数skip_innodb_doublewrite虽然可以禁止使用doublewrite功能,但还是强烈建议大家使用doublewrite。避免部分写失效问题,当然,有些文件系统本身就提供了部分写失效防范机制,如ZFS文件系统,在这种情况下,就可以不开启doublewrite了
一、doublewrite应用场景:
我们知道,innodb的数据页一般大小是16KB,MySQL存取数据的最小单位也是页,而操作系统并不能保障一个数据页的原子性,也就是说当写入数据时,有可能在一个页中写入一半时(比如8K)数据库宕机,这种情况称为部分写失效(partial page write),从而导致数据丢失。
大家也许会问,难道我不可以根据redo log进行数据恢复吗?答案是肯定的也是否定的,要分为两种情况:1、数据库宕机,物理文件完好无损,是可以通过redo log进行崩溃恢复。2、数据库宕机,正在刷新到磁盘的页发生partial page write,而正好在磁盘上的这个数据页由于宕机发生损坏,这时就无法通过redo log进行数据恢复了,为什么?我们必须要清楚的认识到,redo log里记录的是对页的物理操作!比如一条redo记录"page number xx,偏移量 800 写记录 "this is abc"",那当页损坏时,这条redo记录还有意义吗?于是在这种特殊情况下,doublewrite就派上用场啦!
二、doublewrite体系结构及工作流程:
doublewrite由两部分组成,一部分为内存中的doublewrite buffer,其大小为2MB,另一部分是磁盘上共享表空间(ibdata x)中连续的128个页,即2个区(extent),大小也是2M。doublewrite工作流程如下:
1、当一系列机制(main函数触发、checkpoint等)触发数据缓冲池中的脏页进行刷新时,并不直接写磁盘,而是会通过memcpy函数将脏页先复制到内存中的doublewrite buffer,之后通过doublewrite buffer再分两次、每次1MB顺序写入共享表空间的物理磁盘上。
2、马上调用fsync函数,同步脏页进磁盘
由于在这个过程中,doublewrite页的存储时连续的,因此写入磁盘为顺序写,性能很高;完成doublewrite后,再将脏页写入实际的各个表空间文件,这时写入就是离散的了。各模块协作情况如下图(第一步应为脏页产生的redo记录logbuffer,然后logbuffer写入redo log file,为简化次要步骤直接连线表示):
查看doublewrite工作情况,可以执行命令:
mysql> show global status like 'innodb_dblwr%'\G
*************************** 1. row ***************************
Variable_name: Innodb_dblwr_pages_written
Value: 61932183
*************************** 2. row ***************************
Variable_name: Innodb_dblwr_writes
Value: 15237891
2 rows in set (0.00 sec)
以上数据显示,doublewrite一共写了 61932183个页,一共写了15237891次,从这组数据我们可以分析,之前讲过在开启doublewrite后,每次脏页刷新必须要先写doublewrite,而doublewrite存在于磁盘上的是两个连续的区,每个区由连续的页组成,一般情况下一个区最多有64个页,所以一次IO写入应该可以最多写64个页。而根据以上我这个系统Innodb_dblwr_pages_written与Innodb_dblwr_writes的比例来看,大概在4左右,远远还没到64,所以从这个角度也可以看出,系统写入压力并不高。
三、崩溃恢复
如果操作系统在将页写入磁盘的过程中发生崩溃,如上图,在恢复过程中,innodb存储引擎可以从共享表空间的doublewrite中找到该页的一个最近的副本,将其复制到表空间文件,再应用redo log,就完成了恢复过程。因为有副本所以也不担心表空间中数据页是否损坏。
四、建议
innodb存储引擎引入double write技术后,参数skip_innodb_doublewrite虽然可以禁止使用doublewrite功能,但还是强烈建议大家使用doublewrite。避免部分写失效问题,当然,有些文件系统本身就提供了部分写失效防范机制,如ZFS文件系统,在这种情况下,就可以不开启doublewrite了
数据
磁盘
情况
空间
系统
文件
存储
引擎
技术
过程
部分
函数
大小
数据库
物理
工作
操作系统
内存
副本
参数
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
湖南网络安全审计硬件设备提供商
棋牌数据库安装
数据库字段命名需要驼峰吗
数据库中找出并列第二的数据
ORL_92x112人脸数据库
易用财务软件数据库类型
滦州企业网络技术不二之选
南山网络安全运维哪家好
数据库怎么查找删除的文件
合耀上海网络技术有限公司
古为网络技术有限公司怎么样
华为服务器固态硬盘
河南华为服务器维修调试虚拟主机
软件开发5年在郑州多少工资
游戏的数据库在哪里找
守望先锋服务器意外出现错误
软件开发定制介绍
手机上应用服务器错误
西城网络安全认证
go聊天软件开发
口碑好的网络技术咨询软件
修改软件界面数据库
香港物理服务器怎么看安全组
iphone软件开发环境
软件开发管理办法国家规范
中科云网互联网科技有限公司
专利数据库运维工作内容
sql 访问其他服务器
大国网络安全博弈不单是
38岁软件开发失业