InnoDB两次写

partial page write问题:

默认情况下,innodb的一个页面时16k大小,其数据校验也是针对这16k来校验的,将数据写入磁盘是以页面为单位的。文件系统是以4k为单位写入的,机械磁盘是以扇区【512字节】为单位写入的,因此不能保证一个16k的页面原子性写入。如果在刷新脏页的时候系统宕机,16k中只有4k写入到磁盘中,那么这个数据文件就是错误的。

 

为了解决partial page write的问题,InnoDB实现了double write buffer;简单来说,就是在写数据页之前,先把这个数据页写入到一块独立的物理文件位置,然后再写入数据页。这样,在数据库宕机重写时,如果出现数据页损坏,那么在应用redo log之前,需要通过该页的副本来还原该页,然后再进行redo log重做,这就是double write。

 

double write由两部分组成,一部分是内存中的double write buffer, 其大小未2M;另一部分为磁盘上 ibdata中连续的128个页,其大小也是2M。

1. 当一系列机制触发缓冲池中脏页刷新时,并不直接写入磁盘数据文件中,而是先拷贝至内存中的double write buffer中。

2. 接着从两次写缓冲区中分两次写入磁盘共享表空间中(连续存储,顺序写,性能很高),每次写1M

3. 待第二部完成之后,再将double write buffer中的脏页数据写入实际的各个表空间文件中(离散写),脏页数据固化后,即进行标记对应的double write数据可覆盖。

再看redo log的写入关系:

 

这里分别介绍MySQL5.5,MySQL5.7 中的两次写实现方式:

a. MySQL3.23.49 中的实现:

       当 Innodb 需要刷新数据页到磁盘上时,要分为以下几步:

  1. 将数据页中内容拷贝到 doublewrite buf 中
  2. 如果 doublewrite buf 没有写满,则将页面直接拷贝到 doublewrite buf 中,同时将页面加入两次写缓冲缓冲的数据页的数组中;
  3. 如果 doublewrite buf 已经写满,则首先需要将 doublewrite buf 中内容一个 Block 块一个 Block块刷新到磁盘中,注意这里是同步写操作;待以上写操作完成后,将两次写缓冲缓冲的数据页数组中的页写入到真实的表空间文件中,这里是异步写操作。而后再从第一步再次尝试。
  4. 页面写入两次写缓冲中后,需要再次判断 doublewrite buf 是否已经写满,如果写满则需要将两次写缓冲中的页写入到磁盘中。

b. 在MySQL57 中,两次写分为单一页面刷盘和批量页面刷盘两种方式:

    MySQL57中,doublewrite buf 中的 128个页,其中前 120 个页用于批量页面刷盘,其他的页用于单一页面刷盘。

  1. 单一页面刷盘:单一页面刷盘即单独一个页面需要写入磁盘的情况

           单一页面刷盘在刷新数据页时首先从 doublewrite buf 的单一页面刷盘空间中找到一个空闲页 block_i,而后将页面添加到两次写缓冲缓冲的数据页数组 buf_block_arr[i]中, 而后直接将页面写入系统表空间文件中两次写空间的两个区中,这里是同步写操作;而后刷新系统表空间,将以上写操作写入到磁盘中;而后将页面写入到真实的表空间中,这时是同步还是异步要看页面刷盘需要是同步的还是异步的。

       2. 批量页面刷盘:因为单一页面刷盘需要大量的磁盘IO,因此出现了批量页面刷盘。

           首先判断 doublewrite buf 中 first_free 页是否到了 srv_doublewrite_batch_size,如果到了,则说明 doublewrite buf 中用于批量页面刷盘的空间已满,需要将 doublewrite buf 中内容写入磁盘;这里以同步IO的方式将 doublewrite buf 中 first_free 前的两个 block的内容一个block一个block写入到系统表空间文件中,而后flush系统表空间文件;而后将 buf_block_arr[i] 中对应的数据页写入到各自真实的表空间文件中,这里是异步IO。

          如果 doublewrite buf 中用于批量页面刷盘的空间未满,则直接将页面的内容拷贝到 doublewrite buf中,同时将页面加入 buf_block_arr 数组中,而后再次判断doublewrite batch 区域是否用满;如果未满,则结束,如果已满,则进行上一步的刷新 doublewrite buf操作。

 

 

 

 

 

 

 

 

 

posted @ 2020-09-22 18:55  卷毛狒狒  阅读(599)  评论(0编辑  收藏  举报