合 PG 13新特性之pg_verifybackup
Tags: PG备份恢复新特性PG 13pg_verifybackup备份校验
简介
PG13版本引入两个特性来增强备份的验证:backup manifests (备份清单)和 pg_verifybackup。
- backup manifests:使用 pg_basebackup 列出物理备份获取的内容。backup_manifest是json格式的,里边存放有每个文件的Checksum-Algorithm以及校验值,以及Timeline信息等。
- pg_verifybackup:根据备份清单检查备份的完整性。
PG 13新增视图pg_stat_progress_basebackup来追踪查询流式备份的进度; 查询pg_stat_progress_basebackup视图可以获取流式基础备份的进度信息
1 | select * from pg_stat_progress_basebackup; |
这将返回一个结果集,显示当前正在进行的流式基础备份的进度。
PG 13新增视图pg_stat_progress_analyze来获取ANALYZE命令的进度信息:
1 | SELECT * FROM pg_stat_progress_analyze; |
这将返回一个结果集,显示当前正在进行的ANALYZE命令的进度。
一、backup manifests (备份清单)
备份清单是在使用pg_basebackup
创建完整物理备份时创建的。
可以用pg_basebackup命令的参数--no-manifest来禁止生成backup_manifest文件pg_basebackup执行时,可以指定Checksum,Checksum值包括SHA224, SHA256, SHA384, SHA512, CRC32C. CRC32C 是默认值,比如改成SHA512,见如下参数:pg_basebackup --manifest-checksums=SHA512
1、pg_basebackup
pg_basebackup - 物理备份的工具
backup manifest 相关选项:
1 2 3 4 5 6 7 8 | --manifest-checksums=algorithm 指定应应用于备份清单中包含的每个文件的校验和算法。目前,可用的算法有NONE、CRC32C、SHA224、SHA256、 SHA384和SHA512。默认值为CRC32C。 --manifest-force-encode 强制备份清单中的所有文件名采用十六进制编码。如果未指定此选项,则仅对非UTF8文件名进行十六进制编码 --no-manifest 禁用备份清单的生成。如果未指定此选项,则服务器将生成并发送备份清单,可以使用pg_verifybackup进行验证。清单是备份中存在的每个文件的列表,可能包含的所有WAL文件除外。它还存储大小、上次修改时间和每个文件的可选校验和。 |
2、内容
备份完成后在目标目录下会存在backup_manifest
文件,一个JSON格式的对象:
PostgreSQL-Backup-Manifest-Version
: 清单的版本Files
: 备份中包含的文件列表,以及每个文件的相对路径,来自 PGDATA 和重要的元数据,例如大小、最后修改时间和校验和WAL-Ranges
: 时间线、备份开始的LSN、备份结束的LSN等信息Manifest-Checksum
: 清单文件的校验和
1 2 3 4 5 6 7 8 9 10 | { "PostgreSQL-Backup-Manifest-Version": 1, "Files": [ { "Path": "backup_label", "Size": 226, "Last-Modified": "2022-06-06 03:13:02 GMT", "Checksum-Algorithm": "CRC32C", "Checksum": "9c1588c0" }, { "Path": "global/1262", "Size": 8192, "Last-Modified": "2022-06-02 09:47:56 GMT", "Checksum-Algorithm": "CRC32C", "Checksum": "a806d90f" }, …… ], "WAL-Ranges": [ { "Timeline": 1, "Start-LSN": "0/6F000028", "End-LSN": "0/6F000138" } ], "Manifest-Checksum": "6241b42fdc594dbf23c48390b9e204b6599d4cb6cef420efc374034e4d5a972b"} |
二、pg_verifybackup
pg_verifybackup - 验证备份完整性的工具
根据pg_basebackup进行备份时生成的backup_manifest
进行检查。
- plain 格式
- tar 格式:解压后才能进行验证
常用选项:
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 26 27 | -e --exit-on-error 检测到备份问题后立即退出。 如果没有指定这个选项,pg_verifybackup 将在检测到问题后继续检查备份,并将检测到的所有问题报告为错误。 -i path --ignore=path 在将备份中实际存在的数据文件列表与 backup_manifest 文件中列出的数据文件列表进行比较时,忽略指定的文件或目录,该文件或目录应表示为相对路径名。 -m path --manifest-path=path 使用指定路径的清单文件,而不是位于备份目录根目录中的清单文件。 -n --no-parse-wal 不要试图解析从该备份恢复所需的预写式日志数据。 -q --quiet 成功验证备份后不要打印任何内容。 -s --skip-checksums 不要验证数据文件校验和。但仍检查是否存在文件以及这些文件的大小。这样将会快得多,因为文件本身不需要读取。 -w path --wal-directory=path 尝试解析存储在指定目录中的 WAL 文件,而不是 pg_wal。 如果备份存储在与WAL存档不同的位置,则这可能很有用。 |
三、测试用例
情况一:不备份wal、plain
1)备份
1 2 3 4 5 6 7 8 9 10 11 | -- backup_manifest { "PostgreSQL-Backup-Manifest-Version": 1, "Files": [ { "Path": "backup_label", "Size": 226, "Last-Modified": "2022-06-06 03:13:02 GMT", "Checksum-Algorithm": "CRC32C", "Checksum": "9c1588c0" }, { "Path": "global/1262", "Size": 8192, "Last-Modified": "2022-06-02 09:47:56 GMT", "Checksum-Algorithm": "CRC32C", "Checksum": "a806d90f" }, …… ], "WAL-Ranges": [ { "Timeline": 1, "Start-LSN": "0/6F000028", "End-LSN": "0/6F000138" } ], "Manifest-Checksum": "6241b42fdc594dbf23c48390b9e204b6599d4cb6cef420efc374034e4d5a972b"} |
2)验证
1 2 3 4 5 6 7 | [postgres@node1 ~]$ /opt/pg13/bin/pg_verifybackup /backup/basebackup/test01/ pg_waldump: fatal: could not find any WAL file pg_verifybackup: error: WAL parsing failed for timeline 1 -- 加上 -n 选项 [postgres@node1 ~]$ /opt/pg13/bin/pg_verifybackup -n /backup/basebackup/test01/ backup successfully verified |
情况二:wal、plain
1)备份
2)验证
1 2 | [postgres@node1 ~]$ /opt/pg13/bin/pg_verifybackup /backup/basebackup/test02 backup successfully verified |
情况三:wal、tar
1)备份
四、原理
src/bin/pg_verifybackup/pg_verifybackup.c
pg_verifybackup 检查备份完整的步骤:
1、检查备份目录
- 忽略
backup_manifest
文件 - 忽略
pg_wal
目录,通过单独的机制验证 - 忽略
postgresql.auto.conf, recovery.signal, 和standby.signal
文件,这些文件可能会在pg_basebackup时创建会更改
2、查找并读取backup_manifest文件
解析backup_manifest
文件时遇到的任何错误都视为FATAL
默认情况下在备份目录中查找,使用-m, --manifest-path=PATH
可以指定清单的位置
parse_manifest_file() - 解析清单文件,创建一个hash树 --> json_parse_manifest() - 解析JSON格式的清单文件 —>
-->1)pg_parse_json() - 实际的JSON解析器
-->2)verify_manifest_checksum() - 验证清单文件的校验和。清单文件的最后一行被排除在清单校验和之外,因为最后一行应该包含覆盖文件其余部分的校验和。
3、扫描备份目录的文件
将backup_manifest
上的记录的文件和磁盘上的文件进行比较,如果存在且size
也匹配的话,则会在清单的相应文件条目设置matched
标志。
没有设置标志的则是manifest
上提单的但是备份目录中不存在的
verify_backup_directory - 扫描备份目录,遍历备份目录下每一个文件
-->1)verify_backup_file() - 是目录:递归调用verify_backup_directory();
-->2)manifest_files_lookup() - 检查清单哈希中是否有条目,为NULL,则报错提示“XXX is present on disk but not in the manifest”
-->3)检查 size 是否匹配
report_extra_backup_files() - 扫描哈希表中未设置“匹配”标志的条目,报错提示“XXX is present in the manifest but not on disk”
4、验证文件的 checksum
这个步骤需要花费较大的代价
1 | -s, --skip-checksums |