Hi,

On Tue, Sep 01, 2026 at 12:31:42AM +0100, Zsolt Parragi wrote:
> > I found a case where the source's online enable occurs after divergence and 
> > was
> > never seen by the target, but replay skips it instead of applying it:
> > ....
> > Maybe the watermark needs timeline context, or pg_rewind needs to adjust it
> > when it comes from the target's divergent history?
> 
> Thanks! v8 adds the latter, with a new test case verifying this scenario.

Thanks!

As far the new test:

=== 1

+# Clean switchover back to A; enable checksums online on it.
+$node_b->stop('fast');
+$node_a->promote;

IIUC, the preceding wait_for_catchup() does not cover the shutdown checkpoint
written by stop(). Therefore, the divergence checkpoint in scenario 2 is not
guaranteed to carry off, as described.

=== 2

+enable_data_checksums($node_b, wait => 'on');
+test_checksum_state($node_b, 'on');
...
+$node_a->wait_for_catchup($node_b, 'replay', $node_a->lsn('insert'));
+test_checksum_state($node_b, 'on');

The target is already "on" before pg_rewind, so the final assertion does not
prove that the source's enable record was replayed.

Please find attached a small patch addressing those two test comments to apply
on top of v8. What do you think?

=== 3

+   /*
+    * End of the newest XLOG2_CHECKSUMS record this node has written or
+    * applied.

and

+    * would skip them as already applied.  Clamp it to the divergence point,
+    * so that every transition record on the source's history takes effect.
+    */
+   if (ControlFile_new.data_checksum_lsn > divergerec)
+       ControlFile_new.data_checksum_lsn = divergerec;

divergerec is not necessarily the end of an XLOG2_CHECKSUMS record, so the
comment no longer describes every value the field may contain. Maybe it should
describe it as the WAL position through which checksum transitions are covered?

Regards,

-- 
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
diff --git 
a/src/test/modules/test_checksums/t/021_rewind_divergent_transitions.pl 
b/src/test/modules/test_checksums/t/021_rewind_divergent_transitions.pl
--- a/src/test/modules/test_checksums/t/021_rewind_divergent_transitions.pl
+++ b/src/test/modules/test_checksums/t/021_rewind_divergent_transitions.pl
@@ -40,6 +40,19 @@ sub controldata_watermark
        return (hex($1) << 32) + hex($2);
 }
 
+sub wait_for_shutdown_checkpoint_replay
+{
+       my ($primary, $standby) = @_;
+       my ($stdout) = run_command([ 'pg_controldata', $primary->data_dir ]);
+       $stdout =~ /^Latest checkpoint location:\s*([0-9A-F\/]+)$/m
+         or die "checkpoint location missing from pg_controldata output";
+       my $shutdown_checkpoint = $1;
+
+       $standby->poll_query_until('postgres',
+               "SELECT pg_last_wal_replay_lsn() > 
'$shutdown_checkpoint'::pg_lsn;")
+         or die "standby never replayed the shutdown checkpoint";
+}
+
 # Old primary, checksums off.  wal_log_hints is required by pg_rewind
 # on a cluster without data checksums.
 my $node_a = PostgreSQL::Test::Cluster->new('node_a');
@@ -63,6 +76,7 @@ $node_a->wait_for_catchup($node_b, 'replay', 
$node_a->lsn('insert'));
 
 # Clean switchover to B; enable checksums online on it.
 $node_a->stop('fast');
+wait_for_shutdown_checkpoint_replay($node_a, $node_b);
 $node_b->promote;
 enable_data_checksums($node_b, wait => 'on');
 test_checksum_state($node_b, 'on');
@@ -123,9 +137,11 @@ test_checksum_state($node_a, 'off');
 
 # Clean switchover back to A; enable checksums online on it.
 $node_b->stop('fast');
+wait_for_shutdown_checkpoint_replay($node_b, $node_a);
 $node_a->promote;
 enable_data_checksums($node_a, wait => 'on');
 test_checksum_state($node_a, 'on');
+my $source_enable_watermark = controldata_watermark($node_a);
 
 # The old primary restarts on its old timeline and enables checksums
 # online independently: both control files say "on", the divergence
@@ -162,6 +178,8 @@ is($node_b->safe_psql('postgres', "SELECT count(*) FROM 
t_div;"),
        '0', 'divergent insert was rewound');
 
 $node_b->stop('fast');
+is(controldata_watermark($node_b), $source_enable_watermark,
+       'rewound node replayed the source checksum transition');
 command_ok([ 'pg_checksums', '--check', '-D', $node_b->data_dir ],
        'checksums valid on the rewound node');
 

Reply via email to