共计 2652 个字符,预计需要花费 7 分钟才能阅读完成。
这篇文章给大家介绍如何浅析 mysql 中的 double write,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
介绍 double write 之前我们有必要了解 partial page write 问题 :
InnoDB 的 Page Size 一般是 16KB,其数据校验也是针对这 16KB 来计算的,将数据写入到磁盘是以 Page 为单位进行操作的。而计算机硬件和操作系统,在极端情况下(比如断电)往往并不能保证这一操作的原子性,16K 的数据,写入 4K 时,发生了系统断电 /os crash,只有一部分写是成功的,这种情况下就是 partial page write 问题。
很多 DBA 会想到系统恢复后,MySQL 可以根据 redolog 进行恢复,而 mysql 在恢复的过程中是检查 page 的 checksum,checksum 就是 pgae 的最后事务号,发生 partial page write 问题时,page 已经损坏,找不到该 page 中的事务号,就无法恢复。
一 double write 是什么?
Double write 是 InnoDB 在 tablespace 上的 128 个页(2 个区)是 2MB;
其原理:
为了解决 partial page write 问题,当 mysql 将脏数据 flush 到 data file 的时候, 先使用 memcopy 将脏数据复制到内存中的 double write buffer,之后通过 double write buffer 再分 2 次,每次写入 1MB 到共享表空间,然后马上调用 fsync 函数,同步到磁盘上,避免缓冲带来的问题,在这个过程中,doublewrite 是顺序写,开销并不大,在完成 doublewrite 写入后,在将 double write buffer 写入各表空间文件,这时是离散写入。
如果发生了极端情况(断电),InnoDB 再次启动后,发现了一个 Page 数据已经损坏,那么此时就可以从 doublewrite buffer 中进行数据恢复了。
二 double write 的缺点是什么?
位于共享表空间上的 double write buffer 实际上也是一个文件,写 DWB 会导致系统有更多的 fsync 操作, 而硬盘的 fsync 性能, 所以它会降低 mysql 的整体性能. 但是并不会降低到原来的 50%. 这主要是因为:
1) double write 是一个连接的存储空间, 所以硬盘在写数据的时候是顺序写, 而不是随机写, 这样性能更高.
2) 将数据从 double write buffer 写到真正的 segment 中的时候, 系统会自动合并连接空间刷新的方式, 每次可以刷新多个 pages;
三 double write 在恢复的时候是如何工作的?
If there’s a partial page write to the doublewrite buffer itself, the original page will still be on disk in its real location.-
– 如果是写 doublewrite buffer 本身失败, 那么这些数据不会被写到磁盘,InnoDB 此时会从磁盘载入原始的数据, 然后通过 InnoDB 的事务日志来计算出正确的数据, 重新 写入到 doublewrite buffer.
When InnoDB recovers, it will use the original page instead of the corrupted copy in the doublewrite buffer. However, if the doublewrite buffer succeeds and the write to the page’s real location fails, InnoDB will use the copy in the doublewrite buffer during recovery.
– 如果 doublewrite buffer 写成功的话, 但是写磁盘失败,InnoDB 就不用通过事务日志来计算了, 而是直接用 buffer 的数据再写一遍.
InnoDB knows when a page is corrupt because each page has a checksum at the end; the checksum is the last thing to be written, so if the page’s contents don’t match the checksum, the page is corrupt. Upon recovery, therefore, InnoDB just reads each page in the doublewrite buffer and verifies the checksums. If a page’s checksum is incorrect, it reads the page from its original location.
– 在恢复的时候,InnoDB 直接比较页面的 checksum, 如果不对的话, 就从硬盘载入原始数据, 再由事务日志 开始推演出正确的数据. 所以 InnoDB 的恢复通常需要较长的时间.
四 我们是否一定需要 double write?
In some cases, the doublewrite buffer really isn’t necessary—for example, you might want to disable it on slaves. Also, some filesystems (such as ZFS) do the same thing themselves, so it is redundant for InnoDB to do it. You can disable the doublewrite buffer by setting InnoDB_doublewrite to 0.
五 如何使用 double write
InnoDB_doublewrite= 1 表示启动 double write
show status like InnoDB_dblwr% 可以查询 double write 的使用情况;
相关参数与状态
Double write 的使用情况:
show status like %InnoDB_dblwr%
InnoDB_dblwr_pages_written 从 bp flush 到 DBWB 的个数
InnoDB_dblwr_writes 写文件的次数
每次写操作合并 page 的个数 = InnoDB_dblwr_pages_written/InnoDB_dblwr_writes
关于如何浅析 mysql 中的 double write 就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。