定义
在计算机系统中,checksum 通常用于校验数据在传输或存取过程中是否发生错误。PostgreSQL从 9.3 开始支持 checksum,以发现数据因磁盘、 I/O 损坏等原因造成的数据异常。 PostgreSQL 从 9.3 开始支持数据页的 checksum,可以在执行 initdb 时指定 -k 或 --data-checksums 参数开启 checksum,但开启 checksum 可能会对系统性能有一定影响,官网描述如下: Use checksums on data pages to help detect corruption by the I/O system that would otherwise be silent. Enabling checksums may incur a noticeable performance penalty. If set, checksums are calculated for all objects, in all databases. All checksum failures will be reported in the pg_stat_database view.
功能
视图pg_stat_database记录了校验和数据页失败的页数。 启用 checksum 后,系统会对每个数据页计算 checksum,从存储读取数据时如果检测 checksum 失败,则会发生错误并终止当前正在执行的事务,该功能使得 PostgreSQL 自身拥有了检测 I/O 或硬件错误的能力。
Checksum 引入一个 GUC 参数 ignore_checksum_failure,该参数若设置为 true,checksum 校验失败后不会产生错误,而是给客户端发送一个警告。当然,checksum 失败意味着磁盘上的数据已经损坏,忽略此类错误可能导致数据损坏扩散甚至导致系统奔溃,此时宜尽早修复,因此,若开启 checksum,该参数建议设置为 false,默认为false。
PostgreSQL checksum 行为:
1、开启checksum后,PostgreSQL 从shared buffer把数据write出去,需要计算checksum。
2、开启checksum后,从shared buffer外面(disk, os page cache)读取BLOCK到shared buffer里面,需要计算block的checksum,对比存储在page head里头的checksum是否一致。
3、已经在shared buffer里面的block,变更、读取时并不需要计算checksum。
数据页的 checksum 在从 Buffer pool 刷到存储时才设置,当页面再次读取至 Buffer pool 时进行检测。PostgreSQL 会在页面从存储读入内存时检测其是否可用,调用函数为 PageIsVerified,该函数不仅会检测正常初始化过的页(non-zero page),还会检测 全零页(all-zero page)。
作用、使用
Checksum 使 PostgreSQL 具备检测因硬件故障或传输导致数据不一致的能力,一旦发生异常,通常会报错并终止当前事务,用户可以尽早察觉数据异常并予以恢复。
当然,开启 checksum 也会引入一些开销,体现在两个方面: 计算数据页的 checksum 会引入一些 CPU 开销,具体开销取决于 checksum 算法的效率 checkpoint 后,若因更新 Hint Bits 将页面第一次置为 dirty 会写一条记录 Full Page Image 的 WAL 日志,以用于恢复因更新 Hint Bits 产生的破碎页。
对于数据可用性要求较高的场景,通常建议将 full_page_writes 和 checksum 都打开,前者用于避免写失败导致的数据缺失,后者用于尽早发现因硬件或传输导致数据不一致的场景,一旦发现,可以利用 full_page_writes 和 checksum 记录在 WAL 日志中的 Full Page Image 进行数据恢复。
版权声明:本文为「小麦苗DBA宝典(www.xmmup.com)」的原创文章,遵循CC 4.0 BY -SA版权协议,转载请附上原文出处链接及本声明。
转载请保留原文链接: https://www.xmmup.com/pg12zhongdepg_checksumsmingling.html