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

Reply via email to