51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 551|回复: 0
打印 上一主题 下一主题

突然掉电,为啥MySQL也不会丢失数据?

[复制链接]
  • TA的每日心情
    无聊
    3 天前
  • 签到天数: 1050 天

    连续签到: 1 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2022-7-8 10:36:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    MySQL的buffer一页的大小是16K,文件系统一页的大小是4K,也就是说,MySQL将buffer中一页数据刷入磁盘,要写4个文件系统里的页。

    如上图所示,MySQL里page=1的页,物理上对应磁盘上的1+2+3+4四个格。
      那么,问题来了,这个操作并非原子,如果执行到一半断电,会不会出现问题呢?
      会,这就是所谓的“页数据损坏”。


    如上图所示,MySQL内page=1的页准备刷入磁盘,才刷了3个文件系统里的页,掉电了,则会出现:重启后,page=1的页,物理上对应磁盘上的1+2+3+4四个格,数据完整性被破坏。
      画外音:redo无法修复这类“页数据损坏”的异常,修复的前提是“页数据正确”并且redo日志正常。
      如何解决这类“页数据损坏”的问题呢?
      很容易想到的方法是,能有一个“副本”,对原来的页进行还原,这个存储“副本”的地方,就是Double Write Buffer。
      Double Write Buffer,但它与传统的buffer又不同,它分为内存和磁盘的两层架构。
      画外音:传统的buffer,大部分是内存存储;而DWB里的数据,是需要落地的。

    如上图所示,当有页数据要刷盘时:
      第一步:页数据先memcopy到DWB的内存里;
      第二步:DWB的内存里,会先刷到DWB的磁盘上;
      第三步:DWB的内存里,再刷到数据磁盘存储上;
      画外音:DWB由128个页构成,容量只有2M。
      步骤2和步骤3要写2次磁盘,这就是“Double Write”的由来。
      DWB为什么能解决“页数据损坏”问题呢?
      假设步骤2掉电,磁盘里依然是1+2+3+4的完整数据。
      画外音:只要有页数据完整,就能通过redo还原数据。
      假如步骤3掉电,DWB里存储着完整的数据。
      所以,一定不会出现“页数据损坏”问题。
      画外音:写了2次,总有一个地方的数据是OK的。
      自己实验了几十次,仍没能复现“页数据损坏”,在网上找了一个“页数据损坏”时,MySQL重启过程利用DWB修复页数据的图。

    可以看到,启动过程中:
      ·InnoDB检测到上一次为异常关闭;
      · 尝试恢复ibd数据,失败;
      · 从DWB中恢复写了一半的页;
      能够通过DWB保证页数据的完整性,但毕竟DWB要写两次磁盘,会不会导致[url=]数据库[/url]性能急剧降低呢?
      分析DWB执行的三个步骤:
      第一步,页数据memcopy到DWB的内存,速度很快;
      第二步,DWB的内存fsync刷到DWB的磁盘,属于顺序追加写,速度也很快;
      第三步,刷磁盘,随机写,本来就需要进行,不属于额外操作;
      另外,128页(每页16K)2M的DWB,会分两次刷入磁盘,每次最多64页,即1M的数据,执行也是非常之快的。
      综上,性能会有所影响,但影响并不大。
      画外音:
      · write--ahead-log之所以性能高,就是因为顺序追加写;
      · 有第三方测评,评估约10%性能损失;
      更具体的,InnoDB里有两个变量可以查看double write buffer相关的情况:
      · Innodb_dblwr_pages_written:[url=]记录[/url]写入DWB中页的数量。
      · Innodb_dblwr_writes:记录DWB写操作的次数。
      可以通过:
    1.   show global status like "%dblwr%"
    复制代码
      来进行查询。

    结尾
      MySQL有很强的数据安全性机制:
      ·异常崩溃时,如果不出现“页数据损坏”,能够通过redo恢复数据;
      · 在出现“页数据损坏”时,能够通过double write buffer恢复页数据;
      double write buffer:
      · 不是一个内存buffer,是一个内存/磁盘两层的结构,是InnoDB里On-Disk架构里很重要的一部分;
      · 是一个通过写两次,保证页完整性的机制;
      知其然,知其所以然。
      思路比结论重要,希望大家有收获。





    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing

    x
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-24 19:15 , Processed in 0.069942 second(s), 25 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表