您的位置:首页 > 数据库 > MySQL

InnoDB存储引擎——两次写

2017-03-14 15:06 204 查看
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: 0
2 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了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  InnoDB MySql 两次写