开发者社区> 架构技术专栏> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

敲黑板:InnoDB的Double Write,你必须知道

简介: InnoDB引擎有几个重点特性,为其带来了更好的性能和可靠性: - 插入缓冲(Insert Buffer) - 两次写(Double Write) - 自适应哈希索引(Adaptive Hash Index) - 异步IO(Async IO) - 刷新邻接页(Flush Neighbor Page)
+关注继续查看

世界上最快的捷径,就是脚踏实地,本文已收录【架构技术专栏】关注这个喜欢分享的地方。

前序

InnoDB引擎有几个重点特性,为其带来了更好的性能和可靠性:

  • 插入缓冲(Insert Buffer)
  • 两次写(Double Write)
  • 自适应哈希索引(Adaptive Hash Index)
  • 异步IO(Async IO)
  • 刷新邻接页(Flush Neighbor Page)

今天我们的主题就是 两次写(Double Write), 先一句话概括下:

上一次我们讲过Insert Buffer 是用来提高存储引擎性能上的提升,Double Write 就是为了在数据库崩溃恢复时保证数据不丢失的一个重要特性,保证了数据的可靠性。

概念点

如图,还是先来说几个基础的概念:

  • 数据库表空间由段(segment)、区(extent)、页(page)组成
  • 默认情况下有一个共享表空间ibdata1,如使用了innodb_file_per_table则每张表独立表空间(指存放数据、索引、插入缓冲bitmap页)
  • 段包括了数据段(B+树的叶子结点)、索引段、回滚段
  • 区,由连续的页组成,任何情况下每个区都为1M,一个区中有64个连续页(16k)
  • 页,数据页(B-tree Node)默认大小为16KB
  • 文件系统一页 默认大小为4KB
  • 盘片被分为许多扇形的区域,每个区域叫一个扇区,硬盘中每个扇区的大小固定为512字节
  • 脏页,当数据从磁盘加载到缓冲池的数据页后,数据页内容被修改后,此数据页称为脏页

出现的问题

通过上次讲的 重要,知识点:InnoDB的插入缓冲 我们知道,脏页会在某些场景下进行刷盘,将缓冲池内的脏页数据落地到磁盘。

因为存储引擎缓冲池内的数据页大小默认为16KB,而文件系统一页大小为4KB,所以在进行刷盘操作时,就有可能发生如下场景:

如图所示,数据库准备刷新脏页时,需要四次IO才能将16KB的数据页刷入磁盘。

但当执行完第二次IO时,数据库发生意外宕机,导致此时才刷了2个文件系统里的页,这种情况被称为写失效(partial page write)。

此时重启后,磁盘上就是不完整的数据页,就算使用redo log也是无法进行恢复的。

注意

  • redo log无法恢复数据页损坏的问题,恢复必须是数据页正常并且redo log正常。
  • 这里要知道一点,redo log中记录的是对页的物理操作,如偏移量600,写'xxxx'记录。
  • 如果这个页本身已经发生了损坏,再对其进行重做是没有意义的

该怎么解决这个问题

那应该怎么来解决这个问题呢?其实大家想一下就会有个大概的答案,就是给它搞个备份呗。

如果写脏页的时候发生宕机,在重启后使用下备份先恢复下数据页在写磁盘就可以了,其实这就是Double Write

Double Write 出现

千呼万唤始出来,为了防止我们可怜的数据被破坏,InnoDB存储引擎提供了重要的Double Write 特性,避免了数据丢失的惨剧发生。

下面我们来慢慢的来看看Double Write 到底是怎么提高可靠性的

Double Write 解决的问题

在数据库进行脏页刷新时,如果此时宕机,有可能会导致磁盘数据页损坏,丢失我们重要的数据。此时就算重做日志也是无法进行恢复的,因为重做日志记录的是对页的物理修改。

其实就是在重做日志前,用户需要一个页的副本,当写入失效发生时,先通过页的副本来还原该页,再进行重做,这就是double write。

Double Write 架构

如图,其实Double Write 分为了两个组成部分:

  • 内存中的double write buffer
  • 物理磁盘上共享表空间中连续的128个页,即2个区(extent),大小同样为2MB

可以看出,有了Double write后的脏页刷新流程就是多了几步操作:

  1. 在对缓冲池的脏页进行刷新时,并不直接写磁盘,而是会通过memcpy函数将脏页先复制到内存中的Double write buffer
  2. 通过Double write buffer再分两次,每次1MB顺序地写入共享表空间的物理磁盘上,然后马上调用fsync函数,同步磁盘,避免缓冲写带来的问题

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 的问题

Double write buffer 它是在物理文件上的一个buffer, 其实也就是file,所以它会导致系统有更多的fsync操作,而因为硬盘的fsync性能问题,所以也会影响到数据库的整体性能。

Double write页是连续的,因此这个过程是顺序写的,开销并不是很大。

在完成Double write页的写入后,再将Double write buffer中的页写入各个数据文件中,此时的写入则是离散的

总结

  1. 当commit 一个修改语句时,如果redo log有空闲区域,直接写redo log,如果redo log没有空闲区域,那么需要把被覆盖的redo log对应的数据页刷新到data file 中,最后改pool buffer中的记录
  1. innodb的redo log 不会记录完整的一页数据,因为这样日志太大,它只会记录那次(sequence)如何操作了(update,insert)哪页(page)的哪行(row)
  1. 因为数据库使用的页(page,默认16KB)大小和操作系统对磁盘的操作页(page,默认4KB)不一样,当提交了一个页需要刷新到磁盘,会有多次IO, 此时刷了前面的8k时异常发生宕机。在系统恢复正常后,如果没有double write机制,此时数据库磁盘内的数据页已损坏,无法使用redo log进行恢复。
  1. 如果有double write buffer,会检查double writer的数据的完整性,如果不完整直接丢弃double write buffer内容,重新执行那条redo log,如果double write buffer的数据是完整的,用double writer buffer的数据更新该数据页,跳过该redo log。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
char、int 、long int、float、double的存储空间长度比较(例题讲解)
char、int 、long int、float、double的存储空间长度比较(例题讲解)
34 0
Povey正式出任小米语音首席科学家,小米移动端框架MACE全面支持Kaldi
今日,小米开发者大会 MIDC 2019 在北京开幕。语音识别大牛、前霍普金斯大学副教授 Daniel Povey 也正式宣布出任小米集团语音首席科学家,而近日更新的小米移动端深度学习框架 MACE 也已支持 Kaldi。
66 0
Povey正式出任小米语音首席科学家,小米移动端框架MACE全面支持Kaldi
今日,小米开发者大会 MIDC 2019 在北京开幕。语音识别大牛、前霍普金斯大学副教授 Daniel Povey 也正式宣布出任小米集团语音首席科学家,而近日更新的小米移动端深度学习框架 MACE 也已支持 Kaldi。
45 0
探索分布式服务框架Dubbo10:Dubbo和Spring Cloud微服务架构对比
本文首发于我的个人公众号:程序员江湖 努力成为最有影响力的程序员自媒体,专注于面试,职场,个人提升三大主题。 干货满满,不容错过。
1813 0
起死回生的分布式神器-Dubbo
Dubbo概述 一个分布式、高性能、透明化的RPC服务框架,提供服务自动注册、自动发现等高效服务治理方案。 Dubbo是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点 具体可以见官网:http://dubbo.io 目前从Dubbo官网发布的公告来看,Dubbo又正式开始更新了,看来得到了阿里内部的重视。
767 0
超级牛B编码王(三):Sublime2之XP下手动安装Zencoding
    今天在机房XP下安装Sublime2,没有问题。随后安装 Package Install也没有问题。谁知,用Package Install安装Zencoding却始终无法装上。
785 0
14
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载