Hi,

On 1/11/23 5:17 AM, Bharath Rupireddy wrote:
On Wed, Jan 11, 2023 at 6:32 AM Michael Paquier <mich...@paquier.xyz> wrote:

On Tue, Jan 10, 2023 at 05:25:44PM +0100, Drouvot, Bertrand wrote:
I like the idea of comparing the full page (and not just the LSN) but
I'm not sure that adding the pageinspect dependency is a good thing.

What about extracting the block directly from the relation file and
comparing it with the one extracted from the WAL? (We'd need to skip the
first 8 bytes to skip the LSN though).

Byte-by-byte counting for the page hole?

I've in mind to use diff on the whole page (minus the LSN).

The page checksum would
matter as well,

Right, but the TAP test is done without checksum and we could also
skip the checksum from the page if we really want to.

Right. LSN of FPI from the WAL record and page from the table won't be
the same, essentially FPI LSN <= table page.

Right, that's why I proposed to exclude it for the comparison.

What about something like the attached?

Regards,

--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
diff --git a/src/bin/pg_waldump/t/002_save_fullpage.pl 
b/src/bin/pg_waldump/t/002_save_fullpage.pl
index 5072703a3d..21adee7771 100644
--- a/src/bin/pg_waldump/t/002_save_fullpage.pl
+++ b/src/bin/pg_waldump/t/002_save_fullpage.pl
@@ -10,6 +10,19 @@ use PostgreSQL::Test::Utils;
 use Test::More;
 
 my ($blocksize, $walfile_name);
+my $node = PostgreSQL::Test::Cluster->new('main');
+my $pgdata = $node->data_dir;
+
+# Returns the filesystem path for the named relation.
+sub relation_filepath
+{
+    my ($relname) = @_;
+
+    my $rel    = $node->safe_psql('postgres',
+        qq(SELECT pg_relation_filepath('$relname')));
+    die "path not found for relation $relname" unless defined $rel;
+    return "$pgdata/$rel";
+}
 
 # Function to extract the LSN from the given block structure
 sub get_block_lsn
@@ -29,7 +42,6 @@ sub get_block_lsn
        return ($lsn_hi, $lsn_lo);
 }
 
-my $node = PostgreSQL::Test::Cluster->new('main');
 $node->init;
 $node->append_conf(
        'postgresql.conf', q{
@@ -45,7 +57,8 @@ $node->safe_psql(
 CREATE TABLE test_table AS SELECT generate_series(1,100) a;
 -- Force FPWs on the next writes.
 CHECKPOINT;
-UPDATE test_table SET a = a + 1;
+UPDATE test_table SET a = a + 1 where a = 1;
+CHECKPOINT;
 ");
 
 ($walfile_name, $blocksize) = split '\|' => $node->safe_psql('postgres',
@@ -108,4 +121,62 @@ 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');
+
+# Now extract the block from the relation file and compare with the FPI
+my $relpath = relation_filepath('test_table');
+my $blk;
+my $blkfpi;
+
+my $frel;
+my $blkfrel;
+my $blkfpifh;
+my $blkfpinolsn;
+
+open($frel, '+<', $relpath)
+  or BAIL_OUT("open failed: $!");
+
+open($blkfrel, '+>', "$tmp_folder/test_table.blk0")
+  or BAIL_OUT("open failed: $!");
+
+open($blkfpifh, '+<', $fpi_files[0])
+  or BAIL_OUT("open failed: $!");
+
+open($blkfpinolsn, '+>', "$tmp_folder/fpinolsn")
+  or BAIL_OUT("open failed: $!");
+
+binmode $frel;
+binmode $blkfrel;
+binmode $blkfpifh;
+binmode $blkfpinolsn;
+
+# Extract the binary data without the LSN from the relation's block
+sysseek($frel, 8, 0); #bypass the LSN
+sysread($frel, $blk, 8184) or die "sysread failed: $!";
+syswrite($blkfrel, $blk) or die "syswrite failed: $!";
+
+# Extract the binary data without the LSN from the FPI
+sysseek($blkfpifh, 8, 0); #bypass the LSN
+sysread($blkfpifh, $blkfpi, 8184) or die "sysread failed: $!";
+syswrite($blkfpinolsn, $blkfpi) or die "syswrite failed: $!";
+
+close($frel)
+  or BAIL_OUT("close failed: $!");
+
+close($blkfrel)
+  or BAIL_OUT("close failed: $!");
+
+close($blkfpifh)
+  or BAIL_OUT("close failed: $!");
+
+close($blkfpinolsn)
+  or BAIL_OUT("close failed: $!");
+
+# Compare the blocks (LSN excluded)
+command_ok(
+    [ 'diff', $tmp_folder . '/fpinolsn', $tmp_folder . '/test_table.blk0' ],
+    'compare both pages');
+
 done_testing();

Reply via email to