mysql double write (二次写)是mysql innodb存储引擎的一个重要特性,本人这两天翻阅了相关的资料,结合自己已有的知识,说说自己对double write的理解,供各位看官参考。

页断裂(partial write)

double write技术innodb为解决页断裂(partial write)问题而生,所谓页断裂是数据库宕机时(OS重启,或主机掉电重启),数据库页面只有部分写入磁盘,导致页面出现不一致的情况。数据库,OS和磁盘读写的基本单位是块,也可以称之为(page size)block size。我们知道数据库的块一般为8K,16K;而OS的块则一般为4K;IO块则更小,linux内核要求IO block size<=OS block size。磁盘IO除了IO block size,还有一个概念是扇区(IO sector),扇区是磁盘物理操作的基本单位,而IO 块是磁盘操作的逻辑单位,一个IO块对应一个或多个扇区,扇区大小一般为512个字节。所以各个块大小的关系可以梳理如下:

DB block > OS block >= IO block > 磁盘 sector,而且他们之间保持了整数倍的关系。比如我的系统各个块的大小如下,DB以mysql为例,OS以linux为例。

DB block size

root@(none) 09:13:02>show variables like 'innodb_page_size';

+------------------+-------+

| Variable_name    | Value |

+------------------+-------+

| innodb_page_size | 16384 |

+------------------+-------+

OS block size

[1 Single:CHECK: mysql ~ ]

$ getconf PAGESIZE

4096

IO block size

比如查看sdb1分区的IO block size

[root@chuckkkk]# blockdev --getbsz /dev/sdb1

4096

sector size

[root@chuckkkk]# fdisk -l | grep Sector

Sector size (logical/physical): 512 bytes / 512 bytes

从上面的结果可以看到DB page=4*OS page=IO page=8*sector size。

由于任何DB page的写入,最终都会转为sector的写入,如果在写磁盘的过程中,出现异常重启,就可能会发生一个DB页只写了部分sector到磁盘,进而出现页断裂的情况。

页断裂与数据库一致性

前面我们分析了异常重启一定会导致页断裂,而页断裂就意味着数据库页面不完整,那么数据库页面不完整是否就意味着数据库不一致呢???我们知道,数据库异常重启时,自身有异常恢复机制,我这里不打算展开讲异常恢复机制,因为不同数据库的异常恢复流程不同。主流数据库基本原理类似:第一阶段重做redo日志,恢复数据页和undo页到异常crash时的状态;第二阶段,根据undo页的内容,回滚没有提交事务的修改。通过两个阶段保证了数据库的一致性。对于mysql而言,在第一阶段,若出现页断裂问题,则无法通过重做redo日志恢复,进而导致恢复中断,数据库不一致。这里大家可能会有疑问,数据库的redo不是记录了所有的变更,并且是物理的吗?理论上来说,无论页面是否断裂,从上一个检查点对应的redo位置开始,一直重做redo,页面自然能恢复到正常状态。对吗?讲清楚这个问题,先讲讲重做日志(redo)格式。

重做日志(redo)格式

数据库系统实现日志主要有三种格式,逻辑日志(logical logging),物理日志(physical logging),物理逻辑日志(physiological logging),而对于redo日志,则主要采用物理日志和物理逻辑日志两类。逻辑日志,记录一个个逻辑操作,不涉及物理存储位置信息,比如mysql的binlog;物理日志,则是记录一个个具体物理位置的操作,比如在2号表空间,1号文件,48页的233这个offset地方写入了8个字节的数据,通过(group_id,file_id,page_no,offset)4元组,就能唯一确定数据存储在磁盘的物理位置;物理逻辑日志是物理日志和逻辑日志的混合,如果一个数据库操作(DDL,DML,DCL)产生的日志跨越了多个页面,那么会产生多个物理页面的日志,但对于每个物理页面日志,里面记录则是逻辑信息。这里我举一个简单的INSERT操作来说明几种日志形式。

比如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。

redo格式与数据一致性

回到“发生页断裂后,是否会影响数据库一致性”的问题,发生页断裂后,对于利用纯物理日志实现redo的数据库不受影响,因为每一条redo日志完全不依赖物理页的状态,并且是幂等的(执行一次与N次,结果是一样的)。另外要说明一点,redo日志的页大小一般设计为512个字节,因此redo日志页本身不会发生页断裂。而逻辑物理日志则不行,比如修改页头信息,页内记录数加1,slot信息修改等都依赖于页面处于一个一致状态,否则就无法正确重做redo。而mysql正是采用这种日志类型,所以发生页面断裂时,异常恢复就会出现问题,需要借助于double write技术来辅助处理。

double write处理页断裂

doublewrite是Innodb表空间内部分配的一片缓冲区,一般double write包含128个页,对于pagesize为16k的页,总共2MB,doublewrite页与数据页一样有物理存储空间,存在于共享表空间中。Innodb在写出缓冲区中的数据页时采用的是一次写多个页的方式,这样多个页就可以先顺序写入到doublewrite缓冲区,并调用fsync()保证这些数据被写出到磁盘,然后数据页才被写出到它们实际的存储位置并再次调用fsync()。故障恢复时Innodb检查doublewrite缓冲区与数据页原存储位置的内容,若doublewrite页处于页断裂状态,则简单的丢弃;若数据页不一致,则会从doublewrite页还原。由于doublewrite页落盘与数据页落盘在不同的时间点,不会出现doublewrite页和数据页同时发生断裂的情况,因此doublewrite技术可以解决页断裂问题,进而保证了重做日志能顺利进行,数据库能恢复到一致的状态。

oracle如何处理页断裂

oracle与mysql一样,采用的redo日志也是逻辑物理格式,但没有doublewrite技术。我一直就想着oracle这么牛逼的数据库,一定有它自己的方式来应对这种问题。也许这就是所谓的蛮目崇拜,找了N久资料,中文的英文的,包括咨询何登成大神,基本能得出一个结论oracle遇到页断裂问题,一样会挂,重启不来。但是oracle有一个相对简单的策略来恢复数据库到一致状态,备份+归档日志。备份保证了数据页不发生页断裂,加上归档日志增量可以恢复到某个时间点。为什么不做呢?我想一般使用oracle都会使用DataGuard做容灾,主库发生故障时,备库会承担起主库的责任,然后异常主库通过备份+归档日志的方式来恢复,虽然不如doublewrite技术快,但也是能恢复出来的。

其他方式解决页断裂

前面讨论的都是基于一个假设,异常重启后,一定会导致页断裂,其实在底层设施在一定程度上是可以解决这个问题的,比如文件系统层面,采用ZFS文件系统,ZFS通过日志的方式保证了OS页面的完整性,从底层防止了页断裂问题;在磁盘层面,一般RAID卡都会有带电缓存,即使OS异常重启,缓存数据也不会立即丢失,因而也能保证不发生partial write问题。但是我在想,OS的pagesize比DB的pagesize要小,即使能保证OS page不发生页断裂,也不能保证DB page 不断裂,个人感觉不能彻底解决。当然了,如果将DB pagesize设置成和OS pagesize一样大,就没问题了。

参考文档

http://blog.csdn.net/oneyearlater/article/details/7720723

http://www.percona.com/blog/2006/08/04/innodb-double-write/

http://blog.itpub.net/22664653/viewspace-1140915/?page=2

http://www.vmcd.org/2014/09/1748/

页断裂(partial write)与doublewrite技术的更多相关文章

  1. mysql 原理 ~ double write

    一 简介:今天来聊聊double write 二 细节 1 Double write 是InnoDB在 tablespace(ibdata1)上的128个页(2个区)是2MB: 2 何谓页断裂 所谓页 ...

  2. innodb为什么需要doublewrite(转)

    InnoDB的page size默认是16KB,而操作系统的一个block size是4KB,磁盘io block则更小.那么InnoDB的page刷到磁盘上要写4个操作系统block,在极端情况下( ...

  3. MySQL技术内幕InnoDB存储引擎(二)——InnoDB存储引擎

    1.概述 是一个高性能.高可用.高扩展的存储引擎. 2.InnoDB体系架构 InnoDB存储引擎主要由内存池和后台线程构成. 其中,内存池由许多个内存块组成,作用如下: 维护所有进程和线程需要访问的 ...

  4. [Angularjs]asp.net mvc+angularjs+web api单页应用

    写在前面 最近的工作一直在弄一些h5的单页应用,然后嵌入到app的webview中.之前一直在用angularjs+html+ashx的一套东西.实在是玩腻了.然后就尝试通过asp.net mvc的方 ...

  5. Linux 中的零拷贝技术,第 1 部分

    概述 本系列由两篇文章组成,介绍了当前用于 Linux 操作系统上的几种零拷贝技术,简单描述了各种零拷贝技术的实现,以及它们的特点和适用场景.本文是本系列文章的第一部分,主要是介绍一些零拷贝技术的相关 ...

  6. 基于 Eclipse 平台的代码生成技术

    ------------------------------------------------------------------ 转自http://www.ibm.com/developerwor ...

  7. jquery实战---标签页效果

    在前面的博客中,小编主要简单的介绍了jquery的一些基本知识,今天这篇博文,小编继续来学习jquery的相关知识,今天我们来学习一个标签页的小例子,相关源码小编已经上传,有需要的小伙伴可以自己去下载 ...

  8. 3星|《给产品经理讲技术》:APP开发技术介绍,没有技术背景的话恐怕只能看懂书中的比喻和结论

    基本是APP开发涉及到的相关技术的入门级介绍.涉及到的知识点与技术细节比较多,不少技术相关的内容并没有像标题暗示的那样没有技术背景也可以看懂,而是涉及到许多专业的术语.原理.也有一些内容是用比喻的方法 ...

  9. MVC笔记-模板页布局

    MVC分区后  要加上Ares下的主目录   如:@Html.ActionLink("这个帖子真奇葩", "HotIndex", "Prosceniu ...

随机推荐

  1. c#重点[封装,继承,多肽]

    面向对象的语言三大特点:封装.继承.多态 Ⅰ.封装:是把类的内部隐藏起来,以防止外部世界看见的一个面向对象的概念,通过关键字去控制变量,方法的访问权限. 1).访问修饰符: Ⅱ.继承: eg:我们建一 ...

  2. 【Java每日一题】20161206

    package Dec2016; public class Ques1206 { public static void main(String[] args){ doSex(null); } publ ...

  3. ViewPager+GridView实现首页导航栏布局分页效果

    如图是效果图用ViewPager+GridView实现首页导航栏布局分页效果来实现的效果 Demo下载地址:http://download.csdn.net/detail/qq_29774291/96 ...

  4. sql2000安装的一般问题

    SQLServer2000 在一段时间不使用后突然间不能够运行了.只能打开企业管理器,对数据库进行操作.VS2005不能够连接,试了很多种方式,无结果.于是重新安装 sqlServer2000? 仿真 ...

  5. 12款免费的 WordPress 响应式主题下载

    最流行的内容管理系统(WordPress)和最流行的网页设计技术(响应式设计)结合会是什么样的呢?下面这个列表收集了12款响应式的 Wordpress 主题,能够带给你不一样的网站体验. 您可能感兴趣 ...

  6. css居中完全指南(翻译)

    最近参加了百度的前端技术学院,任务4是要求一个元素在父元素中水平和垂直居中,提供的一篇文章对各种情况都进行了分析,很不错,英文也不是那么难懂,毕竟代码还是主体,翻译过来分享出来,翻译内容带有自己的理解 ...

  7. js方法实现rgb颜色转换成16进制格式的代码的方法

    原文地址:http://www.cnblogs.com/vaal-water/archive/2013/04/08/3008880.html 自己试过很好用 function zero_fill_he ...

  8. Jquery属性获取——attr()与prop()

    今天在项目中使用<select></select>下拉菜单时,使用juery操作,使页面加载完菜单默认选中的值为2,我一开始的操作如下: <!--html部分--> ...

  9. 茎叶图(stem)

    介绍 茎叶图(Stem-and-Leaf display)又称“枝叶图”,由统计学家约翰托奇( Arthur Bowley)设计,它的思路是将数组中的数按位数进行比较,将数的大小基本不变或变化不大的位 ...

  10. sharepoint2013- Office web app server2013详细的安装和部署

    前提条件 Office web app server2013不能跟sharepoint server2013安装在同一台服务器上,如果安装在同一台服务器上将提示如下错误: 后来查询资料:  按照官方文 ...