两次写(Double Write)
-------------------------------------
|                         内存实例   |
| ------ copy  -------------------- |
| |Page| --->  |                  | |
| ------  1    |                  | |
|              |doublewrite buffer| |
| ------ copy  |                  | |
| |Page| --->  |                  | |
| ------       -------------------  |
|                 /              \  |
-------------------------------------
                /                   \
          write/                      \ write
            2 /                         \ 3
             v                            v
--------------------------------          -----------------
| -------------  ------------- |          |                |
| |doublewrite|  |doublewrite| | recovery |    数据库文件    |
| |    (1MB)  |  |    (1MB)  | |--------->|     (.ibd)    |
| -------------  ------------- |    4     |                |
|                    共享表空间  |          ------------------
--------------------------------
double write由两部分组成:一部分是内存中的double write,大小为2MB; 另一部分是物理磁盘上的共享表空间中连续的128个页(即2个区extent),大小同样为2MB。
- 在对缓冲池的脏页进行刷新时,并不直接写磁盘,而是会通过
memcpy函数将脏页先复制到内存中的double write buffer。 - 之后通过
double write buffer再分两次,每次1MB顺序地写入共享表空间的物理磁盘上,然后马上调用fsync函数,同步磁盘,避免缓冲写带来的问题。这个过程中,因为double write页是
连续的,因此这个过程是顺序写的,开销并不是很大。 - 在完成double write页的写入后,再将double write buffer中的页写入各个
表空间文件中,此时的写入则是离散的。 - (故障时)若操作系统在将页写入磁盘的过程中发生了崩溃,在恢复过程中,InnoDB存储引擎可以从
共享表空间中double write中找到该页的一个副本,将其复制到表空间文件,再应用重做日志。 
mysql> show global status like 'innodb_dblwr%'; +----------------------------+---------+ | Variable_name | Value | +----------------------------+---------+ | Innodb_dblwr_pages_written | 6325194 | | Innodb_dblwr_writes | 100399 | +----------------------------+---------+注:若2个写入页的比例远小于64:1,可说明系统写入压力并不是很高。
注:有些文件系统本身就提供了部分写失效的防范机制,如ZFS。此时就不需要启用double write了。