C/C++教程

oracle为什么不用double write ?

本文主要是介绍oracle为什么不用double write ?,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

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

这篇关于oracle为什么不用double write ?的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!