世界上最快的捷径,就是脚踏实地,本文已收录【架构技术专栏】关注这个喜欢分享的地方。
InnoDB引擎有几个重点特性,为其带来了更好的性能和可靠性:
今天我们的主题就是 两次写(Double Write)
, 先一句话概括下:
上一次我们讲过Insert Buffer 是用来提高存储引擎性能上的提升,Double Write 就是为了在数据库崩溃恢复时保证数据不丢失的一个重要特性,保证了数据的可靠性。
如图,还是先来说几个基础的概念:
通过上次讲的 重要,知识点:InnoDB的插入缓冲 我们知道,脏页会在某些场景下进行刷盘,将缓冲池内的脏页数据落地到磁盘。
因为存储引擎缓冲池内的数据页大小默认为16KB,而文件系统一页大小为4KB,所以在进行刷盘操作时,就有可能发生如下场景:
如图所示,数据库准备刷新脏页时,需要四次IO才能将16KB的数据页刷入磁盘。
但当执行完第二次IO时,数据库发生意外宕机,导致此时才刷了2个文件系统里的页,这种情况被称为写失效(partial page write)。
此时重启后,磁盘上就是不完整的数据页,就算使用redo log也是无法进行恢复的。
**注意**:
**该怎么解决这个问题**
那应该怎么来解决这个问题呢?其实大家想一下就会有个大概的答案,就是给它搞个备份呗。
如果写脏页的时候发生宕机,在重启后使用下备份先恢复下数据页在写磁盘就可以了,其实这就是Double Write
。
千呼万唤始出来,为了防止我们可怜的数据被破坏,InnoDB存储引擎提供了重要的Double Write 特性,避免了数据丢失的惨剧发生。
下面我们来慢慢的来看看Double Write 到底是怎么提高可靠性的
在数据库进行脏页刷新时,如果此时宕机,有可能会导致磁盘数据页损坏,丢失我们重要的数据。此时就算重做日志也是无法进行恢复的,因为重做日志记录的是对页的物理修改。
其实就是在重做日志前,用户需要一个页的副本,当写入失效发生时,先通过页的副本来还原该页,再进行重做,这就是double write。
如图,其实Double Write 分为了两个组成部分:
可以看出,有了Double write后的脏页刷新流程就是多了几步操作:
如图,如果操作系统在将页写入磁盘的过程中发生了崩溃,在恢复过程中,InnoDB存储引擎可以从共享表空间中的Double write中找到该页的一个副本,将其复制到表空间文件,再应用重做日志。
下面显示了一个由Double write进行恢复的情况:
090923 12:36:32 mysqld restarted
090923 12:26:33 InnoDB: Database was not shut down normally!
InnoDB: Starting crash recovery.
InnoDB: Reading tablespace information from the .ibd files...
InnoDB: Crash recovery may have faild for some .ibd files!
InnoDB: Restoring possible half-written data pages from the doublewrite.
InnoDB: buffer...
Double write buffer 它是在物理文件上的一个buffer, 其实也就是file,所以它会导致系统有更多的fsync操作,而因为硬盘的fsync性能问题,所以也会影响到数据库的整体性能。
Double write页是连续的,因此这个过程是顺序写的,开销并不是很大。
在完成Double write页的写入后,再将Double write buffer中的页写入各个数据文件中,此时的写入则是离散的
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。