# Copyright (c) 2021-2025, PostgreSQL Global Development Group use strict; use warnings FATAL => 'all'; use File::Compare; use PostgreSQL::Test::Cluster; use PostgreSQL::Test::Utils; use Test::More; # Set up a new database instance. my $node1 = PostgreSQL::Test::Cluster->new('node1'); $node1->init(has_archiving => 1, allows_streaming => 1); $node1->append_conf('postgresql.conf', 'summarize_wal = on'); $node1->start; # Create a table and insert a few test rows into it. VACUUM FREEZE it so that # autovacuum doesn't induce any future modifications unexpectedly. Then # trigger a checkpoint. $node1->safe_psql('postgres', <safe_psql('postgres', <safe_psql('postgres', <poll_query_until('postgres', <= '$base_lsn' ) EOM ok($result, "WAL summarization caught up after insert"); # The WAL summarizer should have generated some IO statistics. my $stats_reads = $node1->safe_psql( 'postgres', qq{SELECT sum(reads) > 0 FROM pg_stat_io WHERE backend_type = 'walsummarizer' AND object = 'wal'}); is($stats_reads, 't', "WAL summarizer generates statistics for WAL reads"); # Find the highest LSN that is summarized on disk. my $summarized_lsn = $node1->safe_psql('postgres', <safe_psql('postgres', <poll_query_until('postgres', < '$summarized_lsn' ) EOM ok($result, "got new WAL summary after update"); # Figure out the exact details for the new summary file. my $details = $node1->safe_psql('postgres', < '$summarized_lsn' EOM my @lines = split(/\n/, $details); is(0 + @lines, 1, "got exactly one new WAL summary"); my ($tli, $start_lsn, $end_lsn) = split(/\|/, $lines[0]); note("examining summary for TLI $tli from $start_lsn to $end_lsn"); # Reconstruct the full pathname for the WAL summary file. my $filename = sprintf "%s/pg_wal/summaries/%08s%08s%08s%08s%08s.summary", $node1->data_dir, $tli, split(m@/@, $start_lsn), split(m@/@, $end_lsn); ok(-f $filename, "WAL summary file exists"); # Run pg_walsummary on it. We expect exactly two blocks to be modified, # block 0 and one other. my ($stdout, $stderr) = run_command([ 'pg_walsummary', '-i', $filename ]); note($stdout); @lines = split(/\n/, $stdout); like($stdout, qr/FORK main: block 0$/m, "stdout shows block 0 modified"); is($stderr, '', 'stderr is empty'); is(0 + @lines, 2, "UPDATE modified 2 blocks"); done_testing();