InnoDB存储引擎——两次写

来源:互联网 发布:beta理财师软件 编辑:程序博客网 时间:2024/04/28 16:17

Insert Buffer给InnoDB存储引擎带来的是性能上的提升,doublewrite(两次写)给InnoDB存储引擎带来的是数据页的可靠性。

当数据库发生宕机时,可能InnoDB存储引擎正在写入某个页表中,而这个页只写了一部分,比如16K的页,只写了前4K,之后就发生了宕机,这种情况被称为部分写失效。
在InnoDB存储引擎未使用doublewrite技术前,曾经出现过因为部分写失效而导致数据丢失的情况。

这里写图片描述

doublewrite由两部分组成,一部分是内存中的doublewrite buffer,大小为2MB,另一部分是物理磁盘上共享表空间中连续的128个页,即2个区(extent),大小也为2MB。
第一次写:在对缓冲池的脏页进行刷新时,并不直接写磁盘,而是会通过memcpy函数将脏页先复制到内存中的doublewrite buffer,之后通过doublewrite buffer再分两次,每次1MB顺序地写入共享表空间的物理磁盘上,然后马上调用fsync函数,同步磁盘,避免缓冲写带来的问题。这个过程中是顺序写的,所以开销并不大。
第二次写:在完成doublewrite页的写入后,再将doublewrite buffer中的页写入各个表空间文件中,此时的写入是离散的。
可以通过下面的命令观察到doublewrite运行的情况:

mysql> show global status like 'innodb_dblwr%'\G*************************** 1. row ***************************Variable_name: Innodb_dblwr_pages_written        Value: 0*************************** 2. row ***************************Variable_name: Innodb_dblwr_writes        Value: 02 rows in set (0.03 sec)

从上面可以看出doublewirte一共写了Innodb_dblwr_pages_written个页,但实际的写入次数为Innodb_dblwr_writes。

如果操作系统在第二次写的时候,也就是从doublewrite buffer中将页写入到磁盘的过程中发生了崩溃,在恢复过程中,InnoDB存储引擎可以从共享表空间中的doublewrite中找到该页的一个副本,将其复制到表空间中,再应用重做日志。

Innodb_buffer_pool_pages_flushed变量表示当前缓冲池中刷新到磁盘页的数量。因为在默认情况下,缓冲中的所有页首先都需要放入到doublewrite中,因此该变量应该和Innodb_dblwr_pages_written一致。

参数skip_innodb_doulewrite可以禁止使用doublewrite功能,不过这时可能会引起前面说的写失效问题。

有些文件系统本身就提供了部分写失效的防范机制,比如ZFS文件系统。在这种情况下,用户就不要启动doublewrite了。

0 0
原创粉丝点击