Pg_verifybackup was introduced in PostgreSQL 13 and is used to check the integrity of a base backup taken using Pg_basebackup against the backup_manifest file generated by the server.
The manifest is a JSON document containing information about the backup files, including their paths, sizes, last modification times, and, optionally, checksums. For example:
{ "PostgreSQL-Backup-Manifest-Version": 2, "System-Identifier": 7694938432524117566, "Files": [ { "Path": "backup_label", "Size": 227, "Last-Modified": "2026-10-10 07:42:44 GMT", "Checksum-Algorithm": "CRC32C", "Checksum": "509e2e33" }, { "Path": "global/1262", "Size": 8192, "Last-Modified": "2026-10-10 07:35:34 GMT", "Checksum-Algorithm": "CRC32C", "Checksum": "d7e25e67" }, { "Path": "global/2964", "Size": 0, "Last-Modified": "2026-10-10 07:31:08 GMT", "Checksum-Algorithm": "CRC32C", "Checksum": "00000000" }, { "Path": "global/1213", "Size": 8192, "Last-Modified": "2026-10-10 07:31:09 GMT", "Checksum-Algorithm": "CRC32C", "Checksum": "332b6c66" }, { "Path": "global/1260", "Size": 8192, "Last-Modified": "2026-10-10 07:31:09 GMT", "Checksum-Algorithm": "CRC32C", "Checksum": "bd0707e0" }, pg_verifybackup uses the information in this file to verify the backup. However, this tool cannot guarantee that the database can be restored successfully. It checks specific aspects of the backup’s integrity and consistency.
Creating and Verifying a Backup
First, let’s create a backup using pg_basebackup:
[postgres@OEL98-PG ~]$ pg_basebackup -D /backup/ -v pg_basebackup: initiating base backup, waiting for checkpoint to complete pg_basebackup: checkpoint completed pg_basebackup: write-ahead log start point: 0/4A000118 on timeline 1 pg_basebackup: starting background WAL receiver pg_basebackup: created temporary replication slot "pg_basebackup_2003" pg_basebackup: write-ahead log end point: 0/4A000328 pg_basebackup: waiting for background process to finish streaming ... pg_basebackup: syncing data to disk ... pg_basebackup: renaming backup_manifest.tmp to backup_manifest pg_basebackup: base backup completed Now, let’s verify the backup:
[postgres@OEL98-PG ~]$ pg_verifybackup /backup/ -P 740739/740739 kB (100%) verified backup successfully verified The output indicates that the verification completed successfully.
Identifying Missing and Extra Files
If we rename a file in the backup, pg_verifybackup will identify the changes. For example:
[postgres@OEL98-PG ~]$ mv /backup/global/1213 /backup/global/1213-old Now, execute the command again:
[postgres@OEL98-PG ~]$ pg_verifybackup /backup/ -P pg_verifybackup: error: "global/1213-old" is present on disk but not in the manifest pg_verifybackup: error: "global/1213" is present in the manifest but not on disk 740731/740731 kB (100%) verified Two errors occurred. The first indicates that an extra file (1213-old) is present on disk but not in the manifest, while the second indicates that an expected file (1213) is missing.
Although the progress reaches 100%, the verification has failed because errors were detected.
Now, let’s restore the original filename:
[postgres@OEL98-PG ~]$ mv /backup/global/1213-old /backup/global/1213 Identifying Modified Files In the next step, I want to modify a file and execute this tool again.
First, let’s check the file’s details:
[postgres@OEL98-PG 16384]$ ll /backup/base/16384/3456 -rw-------. 1 postgres postgres 122880 Oct 10 10:42 /backup/base/16384/3456 Now, modify the file’s contents:
[postgres@OEL98-PG ~]$ printf 'curropt' |dd of=/backup/base/16384/3456 bs=1 seek=100 conv=notrunc status=none Execute the tool again:
[postgres@OEL98-PG ~]$ pg_verifybackup /backup/ -P pg_verifybackup: error: checksum mismatch for file "base/16384/3456" 740739/740739 kB (100%) verified The checksum verification failed, identifying a file whose contents differ from those recorded in the manifest. This indicates that the file has been modified, although it does not necessarily mean that accidental corruption occurred.
However, we can skip data-file checksum verification using — skip-checksums:
[postgres@OEL98-PG ~]$ pg_verifybackup /backup/ -P --skip-checksums backup successfully verified Note that skipping checksums does not repair the modified file. It disables data-file checksum verification, so this successful result does not mean that the backup is intact. Other checks, such as file presence, file sizes, and WAL verification, are still performed unless separately disabled.
WAL Verification
One of the more complex features of pg_verifybackup is WAL verification. This tool verifies the required WAL records using the WAL-Ranges section in the manifest file. For example:
"WAL-Ranges": [ { "Timeline": 1, "Start-LSN": "0/4A000118", "End-LSN": "0/4A000328" } ], Each range contains three important fields: Timeline, Start-LSN, and End-LSN.
PostgreSQL’s pg_verifybackup invokes the companion utility pg_waldump to parse the required WAL records. It passes the timeline and the start and end LSNs obtained from the manifest, using quiet mode so that only errors are reported.
A successful WAL check does not prove that every record will perform the correct operation during recovery. It checks whether the required WAL records can be read and parsed, but it cannot guarantee that recovery will succeed in every situation.
