zoukankan      html  css  js  c++  java
  • mysql 原理 ~ double write

    一 简介:今天来聊聊double write

    二 细节
     1 Double write 是InnoDB在 tablespace(ibdata1)上的128个页(2个区)是2MB;
     2 何谓页断裂
     所谓页断裂是数据库宕机时(OS重启,或主机掉电重启),数据库页面只有部分写入磁盘,导致页面出现不一致的情况
    3 具体过程
     为了解决 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中进行数据恢复了。
    4 相关参数
      innodb_doublewrite 默认开启 推荐开启
      show status like 'InnoDB_dblwr%' 查看使用情况
             InnoDB_dblwr_pages_written 从bp flush 到 DBWB的个数
             InnoDB_dblwr_writes 写文件的次数
      每次写操作合并page的个数= InnoDB_dblwr_pages_written/InnoDB_dblwr_writes
    5 恢复过程
     -如果是写doublewrite buffer本身失败,那么这些数据不会被写到磁盘,InnoDB此时会从磁盘载入原始的数据,然后通过InnoDB的事务日志来计算出正确的数据,重新 写入到doublewrite buffer.
     -如果 doublewrite buffer写成功的话,但是写磁盘失败,InnoDB就不用通过事务日志来计算了,而是直接用buffer的数据再写一遍. 加快恢复过程
     -不用双写,在恢复的时候,InnoDB直接比较页面的checksum,如果不对的话,就从硬盘载入原始数据,再由事务日志 开始推演出正确的数据.所以InnoDB的恢复通常需要较长的时间.

    相关提醒
    1 mysql双1的设置是为了保证日志的高可用,防止事务丢失
    mysql双写的设置是为保证脏页刷新到文件的可用,加快恢复数据的速度,防止数据页的损坏
    2 双写属于顺序IO,理论上来说不会给磁盘造成很大IO压力
    3 双写针对的是页断裂的情况
    4 doublewrite页与数据页一样有物理存储空间,存在于共享表空间中
    5 数据页没有达到一致性状态 是无法应用redo日志恢复的
    为何页断裂会导致无法通过redo日志恢复
    1 对于redo日志,则主要采用物理日志和物理逻辑日志两类。
      逻辑日志,记录一个个逻辑操作,不涉及物理存储位置信息,比如mysql的binlog;
      物理日志,则是记录一个个具体物理位置的操作,比如在2号表空间,1号文件,48页的233这个offset地方写入了8个字节的数据,通过(group_id,file_id,page_no,offset)4元组,就能唯一确定数据存储在磁盘的物理位置
      物理逻辑日志 物理日志和逻辑日志的混合,如果一个数据库操作(DDL,DML,DCL)产生的日志跨越了多个页面,那么会产生多个物理页面的日志,但对于每个物理页面日志,里面记录则是逻辑信息。
      比如innodb表T(c1,c2, key key_c1(c1)),插入记录row1(1,’abc’)
     逻辑日志: 
     <insert OP, T, 1,’abc’>
    逻辑物理日志:
    因为表T含有索引key_c1, 一次插入操作至少涉及两次B树操作,二次B树必然涉及至少两个物理页面,因此至少有两条日志
    <insert OP, page_no_1, log_body>
    <insert OP, page_no_2, log_body>
    物理日志:
    由于一次INSERT操作,物理上来说要修改页头信息(如,页内的记录数要加1),要修改相邻记录里的链表指针,要修改Slot属性等,因此对应逻辑物理日志的每一条日志,都会有N条物理日志产生。
    < group_id,file_id,page_no,offset1, value1>
    < group_id,file_id,page_no,offset2, value2>
    ……
    < group_id,file_id,page_no,offsetN, valueN>
    因此对于上述一个INSERT操作,会产生一条逻辑日志,二条逻辑物理日志,2*N条物理日志。从上面简单的分析可以看出,逻辑日志的日志量最小,而物理日志的日志量最大;物理日志是纯物理的;而逻辑物理日志则页间物理,页内逻辑,所谓physical-to-a-page, logical-within-a-page。
    2
       对于mysql本身的逻辑物理日志不行,比如修改页头信息,页内记录数加1,slot信息修改等都依赖于页面处于一个一致状态,否则就无法正确重做redo。而mysql正是采用这种日志类型,所以发生页面断裂时,异常恢复就会出现问题,需要借助于double write技术来辅助处理。

  • 相关阅读:
    HDU——1596find the safest road(邻接矩阵+优先队列SPFA)
    POJ——3264Balanced Lineup(RMQ模版水题)
    周赛Problem 1025: Hkhv love spent money(RMQ)
    Problem 1004: 蛤玮打扫教室(区间覆盖端点记录)
    周赛Problem 1021: 分蛋糕(埃拉托斯特尼筛法)
    廖雪峰Java11多线程编程-1线程的概念-5中断线程
    廖雪峰Java11多线程编程-1线程的概念-3线程的状态
    廖雪峰Java11多线程编程-1线程的概念-2创建新线程
    廖雪峰Java11多线程编程-1线程的概念-1多线程简介
    廖雪峰Java10加密与安全-6数字证书-1数字证书
  • 原文地址:https://www.cnblogs.com/danhuangpai/p/8602221.html
Copyright © 2011-2022 走看看