Hi, A recent commit [1] added --save-fullpage option to pg_waldump to extract full page images (FPI) from WAL records and save them into files (one file per FPI) under a specified directory. While it added tests to check the LSN from the FPI file name and the FPI file contents, it missed to further check the FPI contents like the tuples on the page. I'm attaching a patch that basically reads the FPI file (saved by pg_waldump) contents and raw page from the table file (using pageinspect extension) and compares the tuples from both of them. This test ensures that the pg_waldump outputs the correct FPI. This idea is also discussed elsewhere [2].
Thoughts? [1] https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=d497093cbecccf6df26365e06a5f8f8614b591c8 [2] https://www.postgresql.org/message-id/calj2acxesn9dtjgsekm8fig7cxhhxqfqp4fcisjgcmp9wrz...@mail.gmail.com -- Bharath Rupireddy PostgreSQL Contributors Team RDS Open Source Databases Amazon Web Services: https://aws.amazon.com
From f714f13f47f98c7b9a4f88539c76862cacaffe49 Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com> Date: Sat, 7 Jan 2023 08:29:28 +0000 Subject: [PATCH v1] Strengthen pg_waldump's --save-fullpage tests --- src/bin/pg_waldump/Makefile | 2 ++ src/bin/pg_waldump/t/002_save_fullpage.pl | 34 +++++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/bin/pg_waldump/Makefile b/src/bin/pg_waldump/Makefile index d6459e17c7..924fb6ad20 100644 --- a/src/bin/pg_waldump/Makefile +++ b/src/bin/pg_waldump/Makefile @@ -3,6 +3,8 @@ PGFILEDESC = "pg_waldump - decode and display WAL" PGAPPICON=win32 +EXTRA_INSTALL = contrib/pageinspect + subdir = src/bin/pg_waldump top_builddir = ../../.. include $(top_builddir)/src/Makefile.global diff --git a/src/bin/pg_waldump/t/002_save_fullpage.pl b/src/bin/pg_waldump/t/002_save_fullpage.pl index 5072703a3d..193887a115 100644 --- a/src/bin/pg_waldump/t/002_save_fullpage.pl +++ b/src/bin/pg_waldump/t/002_save_fullpage.pl @@ -38,16 +38,24 @@ max_wal_senders = 4 }); $node->start; +$node->safe_psql('postgres', q(CREATE EXTENSION pageinspect)); + # Generate data/WAL to examine that will have full pages in them. $node->safe_psql( 'postgres', "SELECT 'init' FROM pg_create_physical_replication_slot('regress_pg_waldump_slot', true, false); -CREATE TABLE test_table AS SELECT generate_series(1,100) a; +CREATE TABLE test_table AS SELECT generate_series(1,2) a; -- Force FPWs on the next writes. CHECKPOINT; -UPDATE test_table SET a = a + 1; +UPDATE test_table SET a = a * 100 WHERE a = 1; "); +# Get raw page from the table. +my $page_from_table = $node->safe_psql( + 'postgres', + q(SELECT get_raw_page('test_table', 0)) +); + ($walfile_name, $blocksize) = split '\|' => $node->safe_psql('postgres', "SELECT pg_walfile_name(pg_switch_wal()), current_setting('block_size')"); @@ -108,4 +116,26 @@ for my $fullpath (glob "$tmp_folder/raw/*") ok($file_count > 0, 'verify that at least one block has been saved'); +# Check that the pg_waldump saves FPI file. +my @fpi_files = glob "$tmp_folder/raw/*_main"; +is(scalar(@fpi_files), 1, 'one FPI file was created'); + +# Read the content of the saved FPI file. +my $page_from_fpi_file = $node->safe_psql( + 'postgres', + qq{SELECT pg_read_binary_file('$fpi_files[0]')} +); + +# Compare the raw page from table and FPI file saved, they must contain same rows. +my $result = $node->safe_psql( + 'postgres', + qq{SELECT tuple_data_split('test_table'::regclass, t_data, t_infomask, t_infomask2, t_bits) + FROM heap_page_items('$page_from_table') + EXCEPT + SELECT tuple_data_split('test_table'::regclass, t_data, t_infomask, t_infomask2, t_bits) + FROM heap_page_items('$page_from_fpi_file')} +); + +is($result, '', 'verify that rows in raw page from table and FPI file saved are same'); + done_testing(); -- 2.34.1