zoukankan      html  css  js  c++  java
  • Innodb Double Write

    Innodb Double Write

          如果说ibuf带给InnoDB存储引擎的是性能上的提升,那么doublewrite(两次写)带来的则是数据页的可靠性。
     
          InnoDB的Page Size一般是16KB,其数据校验也是针对这16KB来计算的,将数据写入到磁盘是以Page为单位进行操作的。我们知道磁盘在写入时,都是以512字节为单位,不能保证MySQL数据页面16KB的一次性原子写。试想,在某个Dirty Page flush的过程中,发生了系统断电(或者OS崩溃),16K的数据只有8K被写到磁盘上,只有一部分写是成功的,这种现象被称:部分写失效(partial page write)。一旦partial page writes发生,那么在InnoDB恢复时就很尴尬:在InnoDB的Redo Log file(重做日志文件)中虽然知道这个数据页被修改了,但是却无法知道这个页被修改到什么程度,和这个页面相关的redo也就无法应用了,也就是说如果出现了偏移量问题,再对进行重做就没有意义了。
     

           在讲如何InnoDB存储引擎是如何解决这个问题之前先介绍以下double write的两个组成部分:

    1. 一部分是InnoDB内存中的double write buffer,大小为2M;

    2. 另一部分是物理磁盘上ibdata系统表空间中大小为2MB,共128个连续的Page,既2个分区。其中120个用于批量写脏,另外8个用于Single Page Flush。做区分的原因是批量刷脏是后台线程做的,不影响前台线程。而Single page flush是用户线程发起的,需要尽快的刷脏并替换出一个空闲页出来。

      当一系列机制(main函数触发、checkpoint等)触发数据缓冲池中的脏页进行刷新到data file的时候,并不直接写磁盘,而是会通过memcpy函数将脏页先复制到内存中的double write buffer,之后通过double write buffer再分两次、每次1MB顺序写入共享表空间的物理磁盘上。然后马上调用fsync函数,同步脏页进磁盘上。由于在这个过程中,double write页的存储时连续的,因此写入磁盘为顺序写,性能很高;完成double write后,再将脏页写入实际的各个表空间文件,这时写入就是离散的了。各模块协作情况如下图(第一步应为脏页产生的redo记录log buffer,然后log buffer写入redo log file,为简化次要步骤直接连线表示):

     

    根据上面所说的,可以简单的用以下的图概括:

  • 相关阅读:
    面试试题
    使用NSURLSessionDataTask请求数据(get post方式)
    使用SSZipArchive第三方库解压zip包
    实现图文混编界面
    使用多线程创建单例对象
    SQL语句的种类_外键_表连接(内连接和左外连接)
    使用第三方库(FMDB) 本地数据库存储数据 --使用为了保证线程安全做法
    利用第三方库XML解析 (TBXML)转化成模型数据
    蓝牙传送_多点连接 (适用于>iOS7)
    Unity 产生各不相同的随机数
  • 原文地址:https://www.cnblogs.com/wilburxu/p/9368445.html
Copyright © 2011-2022 走看看