zoukankan      html  css  js  c++  java
  • 8.innodb关键特性之double write 02

    1.前言

      如果说insert buffer带给innodb存储引擎的是性能上的提升,那么doublewrite(两次写),带给innodb存储引擎的是数据页的可靠性

    2.部分写失效

      当发生数据库宕机时,可能innodb存储引擎正在写入某个页到表中,而这个页只写了一部分,比如16kb的页,只写了4kb,之后就发生了宕机,这种现象被称为部分写失效(partial page write).在innodb存储引擎未使用doublewrite技术前,曾经出现过因为部分写失效而导致数据丢失的现象。

    3.错误区

      可能有些DBA认为若果发生写失效了话,可以通过重做日志进行恢复,但是你在用它进行恢复的时候,必须要知道重做日志记录的是对页的物理操作,如偏移量800,写‘aaa’记录,如果这个页的本身发生了损坏,再对其进行重做是没有意义的。因此,在应用重做日志之前,用户需要一个页的副本,当写入失效发生时,先通过页的副本来还原该页,再进行重做,这就是doublewrite. 图如下:

      

    4.doublewrite

      doublewrite有两部分组成,一部分是内存中的doublewrite buffer,大小2MB,另一部分是物理磁盘上共享表空间中连续的128个页,即2个区,大小同样为2MB,在对缓冲池的脏页进行刷新时,并不直接写磁盘,而是会通过memcpy函数将脏页先复制到内存的doublewriter buffer,之后通过doublewrite buffer在分两次,每次1MB顺序写入共享表空间的物理磁盘上,然后马上调用fsync函数,同步磁盘,避免缓冲写带来的问题,在这个过程中,因为doublewrite页是连续的,因此这个过程是顺序写的,开销并不是很大,在完成doublewrite页的写入后,再将doublewrite buffer中的页写入各个表空间文件中,此时的写入则是离散的。可以通过以下命令观察doublewrite运行情况

    root@localhost 10:51:  [(none)]> show global status like 'innodb_dblwr%';
    +----------------------------+-------+
    | Variable_name              | Value |
    +----------------------------+-------+
    | Innodb_dblwr_pages_written | 12    |         #表示已经写入到双写缓冲中的页数
    | Innodb_dblwr_writes        | 1     |         #已经执行完成的doublewrite写操作的次数
    +----------------------------+-------+

    如果发现系统在高峰是的innodb_dblwr_pages_written:innodb_dblwr_writes远远小于64:1,那么可以说明系统写入压力并不高。这里需要注意的是:开启doublewrite后,每次脏页刷新必须要先写doublewrite,而doublewrite存在于磁盘上的是两个连续的区,每个区由连续的页组成,一般情况下一个区最多有64个页,所以一次IO写入应该可以最多写64个页。

    5.doublewrite恢复过程

      数据恢复有三种情况:

      第一种:脏数据写磁盘成功

      刷盘成功,找检查点,进行前滚、回滚就行了。

      第二种:共享表空间ibdata写失败

      如果是写共享表空间失败,那么这些数据不会被写到数据文件,数据库会认为这次刷盘从没发生过,MySQL此时会从磁盘载入原始的数据,然后找检查点,redo log前滚、回滚就行了。

      第三种:脏数据刷数据文件失败

      写共享表空间成功,但是写数据文件失败,在恢复的时候,MySQL直接比较页面的checksum,如果不对的话,直接从共享表空间的double write中找到该页的一个最近的副本,将其复制到表空间文件,再应用redo log,就完成了恢复过程。因为有副本所以也不担心表空间中数据页是否损坏。  

    6.查看doublewrite是否开启 

    root@localhost 10:51:  [(none)]> show variables like '%double%';
    +--------------------+-------+
    | Variable_name      | Value |
    +--------------------+-------+
    | innodb_doublewrite | ON    |
    +--------------------+-------+

      这里也可以在配置文件中进行配置,不配置的话默认是开启的,如果想要关闭doublewrite的话,可以用skip_innodb_doublewrite参数

    7.场景

      首先doublewrite这个特性在Mysql中是默认开启的,如果我们对于需要提供数据高可靠性的主服务器(master server),任何时候用户都应该确保开启doublewrite功能

      不过如果用户有多个从服务器(slave server),需要提供较快的功能(如在slave server上做的是RAID0),可以关闭该特性,还有的文件系统本身就提供了部分写失效的防范机制,如ZFS文件系统,在这种情况下,用户就不要启动doublewrite了。

      

          

  • 相关阅读:
    js对象的sessionStorage,判断对象相等,判断是否包含某属性
    vant-ui的van-area使用
    JavaScript返回格式化的时间字符串
    vant-ui的van-uploader上传图片
    移动端vue页面禁止移动/滚动
    vue项目中的跨域源请求拦截问题CORS头缺少'Access-Control-Allow-Origin'
    项目开发过程中踩坑和填坑
    周报
    构建一个最简单的react程序
    Socket实现简易“多人聊天室”
  • 原文地址:https://www.cnblogs.com/zmc60/p/15222418.html
Copyright © 2011-2022 走看看