Hi, Attached patch covers a case where TLI in the filename for a record being read is different from where it belongs to. In other words, it covers following case noted in StartupXLOG():
/* * EndOfLogTLI is the TLI in the filename of the XLOG segment containing * the end-of-log. It could be different from the timeline that EndOfLog * nominally belongs to, if there was a timeline switch in that segment, * and we were reading the old WAL from a segment belonging to a higher * timeline. */ EndOfLogTLI = xlogreader->seg.ws_tli; Test tried to set recovery target just before the end-of-recovery WAL record. Unfortunately, the test couldn't directly verify EndOfLogTLI != replayTLI case, I am not sure how to do that -- any suggestions will be greatly appreciated. Perhaps, having this test is good to improve xlog.c test coverage. Also, if you see in other angle test covers a case where recovery_target_lsn and recovery_target_inclusive=off which doesn't exist as of now and that is the reason I have added this test to 003_recovery_targets.pl file. Thoughts? Suggestions? -- Regards, Amul Sul EDB: http://www.enterprisedb.com
From 4e2bbb37d4874c910494ba221c7be7e02a29c8c1 Mon Sep 17 00:00:00 2001 From: Amul Sul <amul.sul@enterprisedb.com> Date: Mon, 22 Nov 2021 09:16:51 -0500 Subject: [PATCH v1] TAP test for EndOfLogTLI --- src/test/recovery/t/003_recovery_targets.pl | 55 ++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/src/test/recovery/t/003_recovery_targets.pl b/src/test/recovery/t/003_recovery_targets.pl index 0d0636b85c0..b0d59a181e4 100644 --- a/src/test/recovery/t/003_recovery_targets.pl +++ b/src/test/recovery/t/003_recovery_targets.pl @@ -6,7 +6,7 @@ use strict; use warnings; use PostgreSQL::Test::Cluster; use PostgreSQL::Test::Utils; -use Test::More tests => 9; +use Test::More tests => 10; use Time::HiRes qw(usleep); # Create and test a standby from given backup, with a certain recovery target. @@ -182,3 +182,56 @@ $logfile = slurp_file($node_standby->logfile()); ok( $logfile =~ qr/FATAL: .* recovery ended before configured recovery target was reached/, 'recovery end before target reached is a fatal error'); + +# Test to cover a case where that we are looking for WAL record that ought to be +# in for e.g 000000010000000000000001 we don't find it; instead we find +# 000000020000000000000003 because of various reasons such as there was a +# timeline switch in that segment, and we were reading the old WAL from a +# segment belonging to a higher timeline or our recovery target timeline is 2, +# or something that has 2 in its history. + +# Insert few more data to primary +$node_primary->safe_psql('postgres', + "INSERT INTO tab_int VALUES (generate_series(6001,7000))"); +my $lsn6 = $node_primary->safe_psql('postgres', + "SELECT pg_current_wal_lsn()"); + +# Setup new standby and enable WAL archiving to archive WAL files at the same +# location as the primary. +my $archive_cmd = $node_primary->safe_psql('postgres', + "SELECT current_setting('archive_command')"); +$node_standby = PostgreSQL::Test::Cluster->new('standby_9'); +$node_standby->init_from_backup( + $node_primary, 'my_backup', + has_streaming => 1); +$node_standby->append_conf( + 'postgresql.conf', qq( +archive_mode = on +archive_command = '$archive_cmd' +)); +$node_standby->start; +# Wait until necessary replay has been done on standby +$node_primary->wait_for_catchup($node_standby, 'replay', + $node_primary->lsn('write')); +$node_standby->promote; +$node_standby->safe_psql('postgres', + "INSERT INTO tab_int VALUES (generate_series(7001,8000))"); +# Force archiving of WAL file +$node_standby->safe_psql('postgres', "SELECT pg_switch_wal()"); +$node_standby->stop; + +# Another standby whose recovery target lsn will be in the WAL file has +# a different TLI than the target LSN belongs to. +$node_standby = PostgreSQL::Test::Cluster->new('standby_10'); +$node_standby->init_from_backup( + $node_primary, 'my_backup', + has_restoring => 1); +$node_standby->append_conf( + 'postgresql.conf', qq( +recovery_target_lsn = '$lsn6' +recovery_target_inclusive = off +)); +$node_standby->start; +my $result = $node_standby->safe_psql('postgres', + "SELECT count(*) FROM tab_int"); +is($result, '7000', "check standby content before timeline switch $lsn6"); -- 2.18.0