共计 1652 个字符,预计需要花费 5 分钟才能阅读完成。
数据库,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> Disk Block,而且他们之间放弃着整数倍的关系。比方 DB 以 mysql 为例,OS 以 linux 为例:
DB block size
mysql> show variables like ‘innodb_page_size’;
| Variable_name | Value |
| innodb_page_size | 16384 |
1 row in set (0.01 sec)
OS block size
IO block size
Sector size
Sector size (logical/physical): 512 bytes / 512 bytes
从下面的后果能够看到 DB page=4OS page=16IO pages=32*sector size
因为任何 DB page 的写入,最终都会转为 sector 的写入,如果在写磁盘的过程中,出现异常重启,就可能会产生一个 DB 页只写了局部 sector 到磁盘,进而呈现页断裂的状况。
InnoDB 的 page size 个别是 16KB,其数据校验也是针对这 16KB 计算的,将数据写入到磁盘是以 page 为单位进行操作的。而计算机硬件和操作系统,在极其状况下(比方断电)往往并不能保障这一操作的原子性,16K 的数据,写入 4K 时,产生了零碎断电 /os crash,只有一部分写是胜利的,这种状况写就是 partial page write。
很多 DBA 会想到零碎复原后,Mysql 能够依据 redo log 进行复原,而 mysql 在复原的过程中是查看 page 的 checksum, checksum 就是 page 的最初事务号,产生 partial page write 问题时,page 曾经损坏,找不到改 page 的事务号,就无奈复原。
所以说,当 page 损坏后,利用 redo 是没有意义的,这时候无奈应用 redo 来复原,因为游戏原始页曾经损坏了,会产生数据失落。
在 InnoDB 将 Buffer Pool 中的 Dirty Page 刷到磁盘上时,首先会将 (memcpy 函数) page 刷到 InnoDB system tablespace(ibdata1)的一个区域中,咱们称该区域为 double write buffer (大小为 2MB,每次写入 1MB,128 个页)。在向 dwww.cungun.comouble write buffer 写入胜利后,第二步再将数据拷贝到数据文件对应的地位。
当第二步过程中产生故障,也就是产生 partial page write 的问题。复原的时候先查看页内的 checksum 是否雷同,不统一,则间接从 doublewrite 中复原
1)如果写 doublewrite buffer 失败,那么这些数据不会写到磁盘,innodb 会载入磁盘原始数据和 redo 日志比拟,并从新刷到 doublewrite buffer。
2) 如果写 doublewrite buffer 胜利,然而刷新到磁盘失败,那么 innodb 就不会通过事务日志来复原了,而是间接刷新 doublewrite buffer 中的数据。
mysql> show variables like ‘%double%’;
| Variable_name | Value |
| innodb_doublewrite | ON |
1 row in set (0.00 sec)
mysql> show status like ‘%innodb_dblw%’;
| Variable_name | Value |
| Innodb_dblwr_pages_written | 5951 |
| Innodb_dblwr_writes | 1383 |