关于InnoDB的Double Write技术的理解

 

当InnoDB表的数据有修改时,先更新 InnoDB Buffer Pool 中所在的页,并将此操作记录到redo log中,此时这些页在 InnoDB Buffer Pool 将被标记为脏页。在没有Double Write或文件系统没有相关防范机制的情况下,这些脏页会直接被写到磁盘上去。需要注意的是InnoDB写磁盘是以页为操作单位进行的(页大小一般是16K),而本身操作系统写文件是以4KB为单位的,当写入阶段操作系统crash or power outage时,必将导致页写不全(partial page write),数据丢失。并且由于该页没有一个可靠的副本,redo log对此也无法恢复。

 

为了解决这个问题,InnoDB引入了Double Write技术,在共享表空间内预留出一块double write segment,用于存储页的副本,当写入时发生崩溃后,供redo log借助该副本进行恢复。此外,在类Unix操作系统中,doublewrite 降低了fsync的操作频率,改善了性能。

《MySQL Manual》14.15.1 InnoDB Disk I/O:It adds safety to recovery following a crash or power outage, and improves performance on most varieties of Unix by reducing the need for fsync() operations.

 

实现Double Write的几个参与角色:在内存中需要划分1个名为 double write buffer 的区,而磁盘上则需要共享表空间 ibdata 和独立表空间XXX.ibd文件的配合。

 

Double Write的实现方法:

在刷新innodb_buffer_pool里的脏页时,首先会先将其拷贝到内存中的double write buffer中去,接下来会开始写两遍磁盘的过程。

第一遍写:double write buffer中的页将以1M一次的方式(64个页)写入共享表空间ibdata中称之为double write segment的区,一共需要操作两次。然后主动调用fsync写磁盘(顺序写,开销不大)。

第二遍写:double write buffer中的页将被分别写到所属表的独立表空间内,并再次调用fsync(离散写)。注:页是InnoDB磁盘管理的最小单位,大小16K,不会出现一个页里面存了多个表数据的情况。

 

 

下面来看下在不同的写入阶段,操作系统crash后,double write带来的保护机制:

 

阶段一:copy过程中,操作系统crash,重启之后,脏页未刷到磁盘,但更早的数据并没有发生损坏,重新写入即可

阶段二:write到共享表空间过程中,操作系统crash,重启之后,脏页未刷到磁盘,但更早的数据并没有发生损坏,重新写入即可

阶段三:write到独立表空间过程中,操作系统crash,重启之后,发现:(1)数据文件内的页损坏:头尾checksum值不匹配(即出现了partial page write的问题)。从共享表空间中d的doublewrite segment内恢复该页的一个副本到数据文件,再应用redo log;(2)若页自身的checksum匹配,但与doublewrite segment中对应页的checksum不匹配,则统一可以通过apply redo log来恢复。)

阶段X:recover过程中,操作系统crash,重启之后,innodb面对的情况同阶段三一样(数据文件损坏,但共享表空间内有副本),再次拷贝副本并应用redo log即可。

 

附:error-log 中记录的利用double write恢复的过程:

Version: '5.5.54-log'  socket: '/usr/local/mysql/run/mysqld.sock'  port: 3306  Source distribution
170610 18:08:02 [Note] Plugin 'FEDERATED' is disabled.
170610 18:08:02 InnoDB: The InnoDB memory heap is disabled
170610 18:08:02 InnoDB: Mutexes and rw_locks use GCC atomic builtins
170610 18:08:02 InnoDB: Compressed tables use zlib 1.2.3
170610 18:08:02 InnoDB: Initializing buffer pool, size = 128.0M
170610 18:08:02 InnoDB: Completed initialization of buffer pool
170610 18:08:02 InnoDB: highest supported file format is Barracuda.
InnoDB: The log sequence number in ibdata files does not match
InnoDB: the log sequence number in the ib_logfiles!
170610 18:08:02  InnoDB: Database was not shut down normally!
InnoDB: Starting crash recovery.
InnoDB: Reading tablespace information from the .ibd files...
InnoDB: Restoring possible half-written data pages from the doublewrite
InnoDB: buffer...
170610 18:08:02 InnoDB: Waiting for the background threads to start
170610 18:08:03 InnoDB: 5.5.54 started; log sequence number 1595685
170610 18:08:03 [Note] Recovering after a crash using /usr/local/mysql/log/mysql-bin
170610 18:08:03 [Note] Starting crash recovery...
170610 18:08:03 [Note] Crash recovery finished.
170610 18:08:03 [Note] Server hostname (bind-address): '0.0.0.0'; port: 3306
170610 18:08:03 [Note]   - '0.0.0.0' resolves to '0.0.0.0';
170610 18:08:03 [Note] Server socket created on IP: '0.0.0.0'.
170610 18:08:03 [Note] Event Scheduler: Loaded 0 events
170610 18:08:03 [Note] /usr/local/mysql/bin/mysqld: ready for connections.

 

 

两个doublewrite相关的status值:

mysql> show status like "%dblwr%";
+---------------------------------------+----------+
| Variable_name                       | Value |
+---------------------------------------+----------+
| Innodb_dblwr_pages_written |         
| Innodb_dblwr_writes              |    
+---------------------------------------+-----------+

Innodb_dblwr_pages_written:从 innodb_buffer_pool 拷贝到 doublewrite buffer 过程中,flush的page数;

Innodb_dblwr_writes:从 doublewrite buffer 写数据文件时,调用write的次数。

 

 

 

参考资料:

https://www.percona.com/blog/2006/08/04/innodb-double-write/

http://hedengcheng.com/?p=183

注:图取自姜总的《MySQL技术内幕:InnoDB存储引擎》

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值