MySQL的Innodb doublewrite buffer来龙去脉

     乍一看文档上写的Innodb有个doublewrite buffer,从我们dba的角度一下认为可能是一块内存区域

用来存放某种缓存的数据类型.但是恰恰这个doublewrite buffer是一种比较特殊的buffer,事实上这个buffer

并不是一块内存区域,而是存放在表空间中或是单独指定的某个文件中的一个buffer.

    我们来看os写文件的写机制, 在mysql中,每次写数据(仅数据文件)到磁盘中的时候是以page作为单位的.

一般都是采用的是16KB大小,可以在数据库初始化的时候使用innodb_page_size来定义.

mysql> show global variables like '%innodb_page_size%';

+------------------+-------+

| Variable_name    | Value |

+------------------+-------+

| innodb_page_size | 16384 |

+------------------+-------+

1 row in set (0.00 sec)

   而在os级别写文件是以4KB作为单位的,那么每写一个innodb的page到磁盘上,在os级别上需要写4个块.通过以下

命令可以查看文件系统的块大小.

[root@localhost ~]# dumpe2fs /dev/sda7 | grep "Block size"

dumpe2fs 1.39 (29-May-2006)

Block size:               4096


  当mysql在写一个innodb page到磁盘上时,如果在写这个page的过程中发生了意外的事件,比如断电,mysql崩溃等

就会使这个page数据出现不一样的情形.从而形成一个"断裂"的page.使数据产生混乱.这个时候innodb对这种块错误错误是无

能为力的.


  通过引入doublewrite buffer的方案,每次innodb在准备写出一个page时,先把page写到doublewrite buffer中.如果在写

doublewrite buffer时,发生了意外,但是数据文件中的原来的page不受影响,这样在下次启动时,可以通过innodb的redolog

进行恢复.如果在写doublewrite buffer成功后,mysql会把doublewrite buffer的内容写到数据文件中,如果在这个过程又出现了

意外,没有关系,重启后mysql可以通过从doublewrite buffer找到好的page,再用该好的page去覆盖磁盘上坏的page即可.

   所以在正常的情况下,mysql写数据page时,会写两遍到磁盘上,第一遍是写到doublewrite buffer,第二遍是从doublewrite buffer

写到真正的数据文件中.

   在某些情况下可以关闭doublewrite buffer,从而提高性能,比如比较稳定的系统中,有比较好的主从备份等.

主要的控制参数如下:

mysql> show global variables like '%innodb_doublewrite%';

+-------------------------+-------+

| Variable_name           | Value |

+-------------------------+-------+

| innodb_doublewrite      | ON    |

| innodb_doublewrite_file |       |

+-------------------------+-------+

2 rows in set (0.00 sec)

innodb_doublewrite 控制是否开启doublewrite ,默认是on;innodb_doublewrite_file定义doublewrite存放的位置,如果不定

义就会存放系统表空间中.