数据库,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 |