双写缓冲区是InnoDB的三大特性之一,还有两个是 Buffer Pool简称BP、自适应Hash索引。doublewrite缓冲区是一个存储区,在该存储区中,InnoDB将页面写入InnoDB数据文件中的适当位置之前,先从缓冲池中刷新页面 。如果在页面写入过程中存在操作系统存储子系统或意外的mysqld进程退出,则InnoDB可以在崩溃恢复期间从doublewrite缓冲区中找到页面的良好副本。注意:系统恢复后,MySQL 可以根据redolog 进行恢复,而mysql在恢复的过程中是检查page的checksum,checksum就是pgae的最后事务号,发生partial page write 问题时,page已经损坏,找不到该page中的事务号,就无法恢复。

    为什么需要双写?个人理解宏观上还是与InnoDB需要支持事务(ACID)特性有关,而底层的原因是为了解决Partial Write Page问题

    之前在分析Mysql - InnoDB引擎对事务ACID的实现原理分析时个人认为已经透彻的分析了事务的实现过程,而为了实现事务InnoDB引入了比较多的组件,设计的特别复杂,InnoDB级别包括:(行锁、临建锁、间隙锁)锁和加锁规则、MVCC、redo log、undo log、视图(Read View)。而官方文档也在隔离型和持久性上面明确指向了数据双写机制,如下图

    InnoDB的页大小默认为16K,可以使用参数innodb_page_size设置, 可设置的值有: 64KB,32KB,16KB(默认),8KB和4KB。并且在数据校验时也针对页进行计算,即他们是一个整个对待,包括把数据持久化到磁盘的操作。而计算机的硬件和操作系统在极端情况下(比如断电、系统崩溃)时,刚写入了4K或8K数据,那么就不能保证该操作的原子性,称为部分页面写问题(Partial Write Page)

    此时就引入了双写缓存区的机制,当发生极端情况时,可以从系统表空间的Double Write Buffer【磁盘上】进行恢复,下面是InnoDB的架构图、双写和恢复流程图。为了方便对比,将组件放在了相同的位置:

    这样在极端情况下也能解决 Partial Write page问题了,但是如果我自己的系统本身数据要求没有那么高(比如日志数据库),这样的话毕竟双写是有一定的性能开销的。可以通过参数innodb_doublewrite = 0进行关闭,设置为1表示开启。官方认为,尽管需要写入两次数据,但是写缓冲区不需要两次的 io开销或操作,因为只需要调用一次操作系统的fsync() 就可以将批量数据顺序写入磁盘 -> 系统表空间的Double Write Buffer(如上图),这里是顺序写而不是随机写(性能可以保证),当然前提是配置刷盘策略参数innodb_flush_method为默认的O_DIRECT。其实还有一点就是真正提交的时候会使用组提交,我们可以用参数控制:binlog_group_commit_sync_delay:组提交执行fsync() 延迟的微妙数,延迟时间越长批量数据越多,磁盘io越少性能越高。binlog_group_commit_sync_no_delay_count:组提交执行fsync的批个数。


Mysql - 知识图谱总览

Mysql - 配置大全(my.cnf)

Mysql - Mysql架构图

Mysql - MySQL索引(复合索引、覆盖索引、索引下推、前缀索引)

Mysql - 优化器阶段的索引选择过程

Mysql - 争取一文讲清楚Mysql中的锁(全局锁、表级锁、行级锁)和加锁规则

Mysql - InnoDB引擎对事务ACID的实现原理分析

Mysql - binlog日志、主从复制过程

Mysql - InnoDB三大特性之Buffer Pool缓冲池

Mysql - InnoDB三大特性之双写缓冲区(Double Write Buffer)

Mysql - InnoDB三大特性之自适应Hash索引(从数据结构角度分析Mysql中的Hash索引)

Mysql - 普通索引与唯一索引之间性能差别change buffer

Mysql - 大表全表查询过程(分析底层的数据流转过程)

Mysql - delete、重建表过程以及内部的锁状态变化

Mysql - count(字段)<count(主键 id)<count(1)≈count(*)

Mysql - join类型和实现的效果

Mysql - join(索引和非索引)的实现原理和优化手段

Mysql - order by执行原理

Mysql - 深度分页问题的解决方案

Mysql - 范围查询过程分析底层的锁实现机制(解决幻读、版本读的不可重复读问题)

Mysql - 不同级别数据恢复问题

Mysql - 脏页刷新机制

Mysql - 慢查询和执行计划

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐