码迷,mamicode.com
首页 > 数据库 > 详细

MySQL-DoubleWrite

时间:2021-06-02 14:07:46      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:页面   gae   缓冲区   完成   重要   也会   通过   文件中   比较   

今天主要介绍下mysql一个崩溃恢复很重要的特性-重复写入。

doublewrite缓冲区是位于系统表空间中的存储区域,在该区域中,InnoDB会在将页面写入数据文件中的适当位置之前,从InnoDB缓冲池中刷新这些页面。仅在刷新页面并将其写入doublewrite缓冲区后,InnoDB才会将页面写入其适当位置。如果在页面写入过程中发生操作系统,存储子系统或mysqld进程崩溃,InnoDB稍后可以在崩溃恢复期间从doublewrite缓冲区中找到该页面的良好副本。

部分页面写

InnoDB的页面大小通常是16KB,其数据校验也是针对这16KB来计算的,将数据写入到磁盘并以页面为单位进行操作的。而计算机硬件和操作系统,在极端情况下(有时断电) )通常并不能保证这一步的原子性,16K的数据,写入4K时,发生了系统断电/ os崩溃,只有一部分写是成功的,这种情况下就是局部页面写问题。

很多DBA会想到系统恢复后,MySQL可以根据redolog进行恢复,而mysql在恢复的过程中是检查页面的校验和,checksum就是pgae的最后事务号,发生部分页面写问题,页面已经损坏,找不到该页面中的事务号,就无法恢复。

技术图片

double white原理

Double write是InnoDB在表空间上的128个页(2个区)是2MB;

其原理:

为了解决部分页写问题,当mysql将脏数据刷新到数据文件的时候,先使用内存复制将脏数据复制到内存中的double write buffer,之后通过double write buffer再分2次,每次写入1MB到共享表空间,然后立即调用fsync函数,同步到磁盘上,避免缓冲带来的问题,在这个过程中,doublewrite是顺序写,不会大小写大,在完成doublewrite写入后,在将double write buffer写入各个表空间文件,这时是离散写入。

如果发生了极端情况(断电),InnoDB再次启动后,发现了一个页面数据已经损坏,那么此时就可以从doublewrite buffer中进行数据恢复了。

技术图片

double对性能的影响

在共享表空间上的双重写缓冲区实际上也是一个文件,写DWB会导致系统有更多的fsync操作,而硬盘的fsync性能,所以它会降低mysql的整体性能。但是并不会降低到原来的50%。这主要是因为:

1)double write是一个连接的存储空间,所以硬盘在写数据的时候是顺序写,而不是随机写,这样性能更高。

2)将数据从双写缓冲区写入到真正的segment中的时候,系统会自动合并连接空间刷新的方式,每次可以刷新多个页面;

如果页面大小是16k,那么就有128个页面(1M)需要写,但是128个页面写入到共享表空间是1次IO完成,则doublewrite写入是1 + 128次。其中128次是写数据文件表空间。

doublewrite写入是顺序的,性能开销转化为量,通常5%-25%的性能影响。

double在恢复的时候是如何工作的?

如果部分页面写入doublewrite缓冲区本身,则原始页面仍将保留在磁盘上的实际位置。

如果是写双写缓冲区本身失败,那么这些数据不会被写入磁盘,InnoDB此时会从磁盘加载原始数据,然后通过InnoDB的事务日志来计算出正确的数据,重新写入到双写缓冲区。

当InnoDB恢复时,它将使用原始页面而不是doublewrite缓冲区中的损坏副本。但是,如果双写缓冲区成功并且对页面实际位置的写入失败,则InnoDB将在恢复期间使用双写缓冲区中的副本。

如果doublewrite buffer写成功的话,但是写磁盘失败,InnoDB就不用通过事务日志来计算了,或者直接用buffer的数据再写一遍。

InnoDB知道页面何时损坏,因为每个页面的末尾都有一个校验和。校验和是最后要写入的内容,因此,如果页面的内容与校验和不匹配,则页面已损坏。因此,恢复后,InnoDB只会读取doublewrite缓冲区中的每个页面并验证校验和。如果页面的校验和不正确,它将从其原始位置读取页面。

在恢复的时候,InnoDB直接比较页面的校验和,如果不对的话,就从硬盘加载原始数据,再由事务日志开始推演正确的数据。所以InnoDB的恢复通常需要花费时间。

重复写相关参数

InnoDB_doublewrite = 1表示启动双写,显示状态为‘InnoDB_dblwr%‘可以查询双写的使用情况;

#是否开启double write

mysql>显示类似‘%double%write%‘的变量;

#Double write的使用情况

mysql>显示状态,例如“%InnoDB_dblwr%”;

InnoDB_dblwr_pages_write#从bp刷新到DBWB的个数

InnoDB_dblwr_writes#写文件的次数

每次写操作合并page的个数= InnoDB_dblwr_pages_write / InnoDB_dblwr_writes

技术图片

是否一定需要重复写

在某些情况下,确实没有必要使用doublewrite缓冲区-例如,您可能想在从属服务器上禁用它。另外,某些文件系统(例如ZFS)本身也会执行相同的操作,因此InnoDB这样做是多余的。您可以通过将InnoDB_doublewrite设置为0来禁用双写缓冲区。

1,Fursion-io原子写,如果每次写16k就是16k,每次写都是16k不会出现部分写partial write写4k的情况。

2,特定的文件系统(b-tree文件系统),支持原子写。

MySQL-DoubleWrite

标签:页面   gae   缓冲区   完成   重要   也会   通过   文件中   比较   

原文地址:https://www.cnblogs.com/lovezhr/p/14820974.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!