合 PG启用checksum数据块校验及pg_checksums、pg_verify_checksums命令
Tags: PG其它命令介绍checksumpg_checksumspg_verify_checksums校验和
checksum简介
在计算机系统中,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)
。
为什么会出现
全零页
呢?
在特定场景下表中可能出现全零页
,比如有进程扩展了一个表,即在该表中添加了一个新页,但在 WAL 日志写入存储之前,进程崩溃了。此时新加的页可能已经在表文件中,下次重启时就会读取到。
对于 non-zero page
,检测其 checksum 是否一致以及 page header 信息是否正确,若 checksum 失败,但 header 信息正确,此时会根据 ignore_checksum_failure
值判断验证是否通过;对于 all-zero page
,如果为全零,则验证通过。
若验证失败,两种处理方式:
若读取数据的模式为
RBM_ZERO_ON_ERROR
且 GUC 参数zero_damaged_pages
为 true,则将该页全部置 0报错,
invalid 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
进行数据恢复。
查看 checksum
PostgreSQL 10 在 pageinspect
插件中添加了函数 page_checksum()
用来查看 page 的 checksum,当然使用 page_header()
也可以查看 page 的 checksum,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | postgres=# create extension pageinspect; CREATE EXTENSION postgres=# SELECT page_checksum(get_raw_page('pg_class', 0), 0); page_checksum --------------- -18438 (1 row) postgres=# SELECT * FROM page_header(get_raw_page('pg_class', 0)); lsn | checksum | flags | lower | upper | special | pagesize | version | prune_xid -----------+----------+-------+-------+-------+---------+----------+---------+----------- 0/184EA10 | -18438 | 1 | 212 | 5752 | 8192 | 8192 | 4 | 505 (1 row) |
PG12命令之pg_checksums
简介
官网:http://postgres.cn/docs/13/app-pgchecksums.html
对于一些数据可靠性要求很高的场景,例如金融领域,建议打开数据块的checksum校验功能。
在PG 12之前,需要在用initdb命令创建数据库的时候加上-k
参数来启用checksum功能;从PG12开始,提供了pg_checksums命令,可以把一个没有checksum功能的数据库转换为具有该功能的数据库。
pg_checksums 的作用是在PostgreSQL数据库集簇中启用、禁用或检查数据校验和。
pg_checksums在PostgreSQL集簇中检查、启用或禁用数据校验和。运行pg_checksums之前,必须彻底关闭服务器。验证校验和时,如果没有校验和错误,则退出状态为零,如果检测到至少一个校验和失败,则退出状态为非零。启用或禁用校验和时,如果操作失败,则退出状态为非零。
验证校验和时,集簇中的每个文件都要被扫描。启用校验和时,集簇中的每个文件都会被原地重写。禁用校验和时,仅更新pg_control
文件。
pg_checksums命令是对pg11的pg_verify_checksums命令的改进,即在PG12中,将命令行工具pg_verify_checksums改名为pg_checksums。
语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | pg_checksums [option...] [[ -D | --pgdata ] datadir] [pg13@lhrpg ~]$ pg_checksums --help pg_checksums enables, disables, or verifies data checksums in a PostgreSQL database cluster. Usage: pg_checksums [OPTION]... [DATADIR] Options: [-D, --pgdata=]DATADIR data directory -c, --check check data checksums (default) -d, --disable disable data checksums -e, --enable enable data checksums -f, --filenode=FILENODE check only relation with specified filenode -N, --no-sync do not wait for changes to be written safely to disk -P, --progress show progress information -v, --verbose output verbose messages -V, --version output version information, then exit -?, --help show this help, then exit If no data directory (DATADIR) is specified, the environment variable PGDATA is used. Report bugs to <pgsql-bugs@lists.postgresql.org>. PostgreSQL home page: <https://www.postgresql.org/> |
下列命令选项可用:
-D *
directory*
--pgdata=*
directory*
指定存储数据库集簇的目录。
-c
--check
检查校验和。如果未指定其它任何内容,这是缺省模式。
-d
--disable
禁用校验和。
-e
--enable
启用校验和。
-f *
filenode*
--filenode=*
filenode*
仅验证文件节点为
filenode
的关系中的校验和。
-N
--no-sync
缺省地,
pg_checksums
会等待所有文件安全地写到磁盘上。该选项使得pg_checksums
不等待就返回,这样更快,但意味着后续如果操作系统崩溃会让更新的数据目录损坏。一般地,该选项对测试有用,但不应用在生产安装上。当使用--check
时,该选项无效。
-P
--progress
启用进度报告。在检查或启用校验和时,打开该选项,会提供进度报告。
本人提供Oracle(OCP、OCM)、MySQL(OCP)、PostgreSQL(PGCA、PGCE、PGCM)等数据库的培训和考证业务,私聊QQ646634621或微信dbaup66,谢谢!