mysql 两次写理解_[MySQL]浅谈InnoDB存储引擎(五)两次写

回顾

上个章节我们深入浅出了MySQL的Insert Buffer和新版本的InnoDB中支持的Change Buffer,从实现原理层面也做了一些探索。由此,我们可以给出结论,对于非聚簇非唯一的索引,通过Change Buffer可以让MySQL的DML操作更快,但是同时,也要注意Change Buffer膨胀导致缓冲池空间紧张的问题。OK,如果说Change Buffer给MySQL的DML操作带来了性能上的提升,那么今天我们来说一说InnoDB的另一个关键特性——doublewrite(两次写)。

为什么需要两次写?

数据库宕机导致数据丢失

如果运行中的MySQL数据库突然发生宕机,此时InnoDB存储引擎正在将缓冲池中的页持久化到磁盘中,但是这个时刻数据库宕机了,那么会导致部分数据刷到了磁盘中,部分数据还在内存中,这种情况在MySQL中称为partial page write

(部分写失效)。

redo log无法对页损坏做恢复

redo log记录的是对页的物理操作,例如:偏移量800,写入'xxx'记录,但是页本身如果是损坏的,那么redo也是无济于事的。

doublewrite是怎么做的?

InnoDB在应用(apply)redo log前,写入了页的副本,当写入失效时,先通过副本还原该页,再进行redo。

doublewrite结构

内存中的doublewrite buffer

大小为2MB

物理磁盘上共享表空间中连续的128个页,即两个区(extent),大小为2MB。

dd8d5cb7f59b

image.png

doublewrite工作原理

在对缓冲池的脏页进行刷新时,并不直接写入磁盘,而是会通过memcpy函数将脏页先复制到内存中的doublewrite buffer,之后通过doublewrite buffer再分两次,每次1MB顺序地写入共享表空间的物理磁盘上,然后马上调用fsync函数,同步磁盘,避免缓冲写带来的问题。在这个过程中,因为doublewrite页是连续的,所以写入double write是顺序写的,开销并不是很大。等数据进入doublewrite的页后,再离散地将数据写入各个表空间文件中。

查看doublewrite的运行情况

> SHOW GLOBAL STATUS LIKE 'innodb_dblwr%'\G;

Innodb_dblwr_pages_written

doublewrite写入缓存的页数

Innodb_dblwr_writes

实际写入磁盘的次数

系统在高峰时的Innodb_dblwr_pages_written:Innodb_dblwr_writes总体符合64:1,这对系统的IO压力并不是很高。

通俗地理解doublewrite

假设你要对一个表执行一段时间较长的SQL,你害怕在这段时间内MySQL断电了导致你的数据变脏了,虽然记录了SQL,但是你需要回到未执行这条SQL前的状态。那么你需要复制出一个一样的表,如果你的SQL失败,那么从copy的表中重新执行这条SQL。笔者认为,这便是doublewrite的思想。

禁用doublewrite

skip_innodb_doublewrite

通过这个参数,你可以禁用doublewrite。但是不建议这么做,任何时候,用户都应该开启doublewrite来保证你的MySQL具备容灾性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值