From 45bbc66c47586243f10a535375496583d7c70030 Mon Sep 17 00:00:00 2001 From: Zsolt Parragi Date: Mon, 17 Aug 2026 11:52:53 +0000 Subject: [PATCH] Report single-page checksum failures in pg_stat_database Base backups reported checksum failures to pg_stat_database only for files with more than one failing page. Commit 6b9e875f728 placed the report inside the block emitting the per-file summary WARNING, which is skipped for a single failure since the per-page WARNING already covers it. As a result, a backup failing on files with one corrupted page each left checksum_failures untouched. Fix by reporting the failures independently of the summary WARNING. --- src/backend/backup/basebackup.c | 3 ++- src/bin/pg_basebackup/t/010_pg_basebackup.pl | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/backend/backup/basebackup.c b/src/backend/backup/basebackup.c index fe5ce23aaba..6a422b76932 100644 --- a/src/backend/backup/basebackup.c +++ b/src/backend/backup/basebackup.c @@ -1811,13 +1811,14 @@ sendFile(bbsink *sink, const char *readfilename, const char *tarfilename, CloseTransientFile(fd); if (checksum_failures > 1) - { ereport(WARNING, (errmsg_plural("file \"%s\" has a total of %d checksum verification failure", "file \"%s\" has a total of %d checksum verification failures", checksum_failures, readfilename, checksum_failures))); + if (checksum_failures > 0) + { pgstat_prepare_report_checksum_failure(dboid); pgstat_report_checksum_failures_in_db(dboid, checksum_failures); } diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl index cfcfdb8b580..b0d8b505dbd 100644 --- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl +++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl @@ -913,6 +913,15 @@ $node->command_checks_all( 'pg_basebackup reports checksum mismatch'); rmtree("$tempdir/backup_corrupt"); +# The failure must be counted in pg_stat_database even though the file only +# has a single corrupted page. The walsender reports the failures when it +# exits, so poll for the counter. +ok( $node->poll_query_until( + 'postgres', + 'SELECT checksum_failures = 1 FROM pg_stat_database ' + . "WHERE datname = 'postgres';"), + 'checksum failure reported in pg_stat_database'); + # induce further corruption in 5 more blocks $node->stop; for my $i (1 .. 5) @@ -942,6 +951,14 @@ $node->command_checks_all( 'pg_basebackup correctly report the total number of checksum mismatches'); rmtree("$tempdir/backup_corrupt3"); +# The counter accumulates the failures of all three backups, including the +# single-page failure of the second file in the last one. +ok( $node->poll_query_until( + 'postgres', + 'SELECT checksum_failures = 14 FROM pg_stat_database ' + . "WHERE datname = 'postgres';"), + 'checksum failures accumulated in pg_stat_database'); + # do not verify checksums, should return ok $node->command_ok( [ -- 2.54.0