summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/transam/xlog.c14
-rw-r--r--src/backend/access/transam/xlogrecovery.c13
-rw-r--r--src/include/access/xlog.h1
-rw-r--r--src/test/recovery/t/004_timeline_switch.pl8
4 files changed, 31 insertions, 5 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index fd91bcd68ec..8c0d9dbfa8b 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -9519,10 +9519,7 @@ void
XLogShutdownWalRcv(void)
{
ShutdownWalRcv();
-
- LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
- XLogCtl->InstallXLogFileSegmentActive = false;
- LWLockRelease(ControlFileLock);
+ ResetInstallXLogFileSegmentActive();
}
/* Enable WAL file recycling and preallocation. */
@@ -9534,6 +9531,15 @@ SetInstallXLogFileSegmentActive(void)
LWLockRelease(ControlFileLock);
}
+/* Disable WAL file recycling and preallocation. */
+void
+ResetInstallXLogFileSegmentActive(void)
+{
+ LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
+ XLogCtl->InstallXLogFileSegmentActive = false;
+ LWLockRelease(ControlFileLock);
+}
+
bool
IsInstallXLogFileSegmentActive(void)
{
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index 3e3c4da01a2..cb62d43077d 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -3687,8 +3687,19 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
* Before we leave XLOG_FROM_STREAM state, make sure that
* walreceiver is not active, so that it won't overwrite
* WAL that we restore from archive.
+ *
+ * If walreceiver is actively streaming (or attempting to
+ * connect), we must shut it down. However, if it's
+ * already in WAITING state (e.g., due to timeline
+ * divergence), we only need to reset the install flag to
+ * allow archive restoration.
*/
- XLogShutdownWalRcv();
+ if (WalRcvStreaming())
+ XLogShutdownWalRcv();
+ else
+ {
+ ResetInstallXLogFileSegmentActive();
+ }
/*
* Before we sleep, re-scan for possible new timelines if
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index a12757e46e5..605280ed8fb 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -269,6 +269,7 @@ extern void SwitchIntoArchiveRecovery(XLogRecPtr EndRecPtr, TimeLineID replayTLI
extern void ReachedEndOfBackup(XLogRecPtr EndRecPtr, TimeLineID tli);
extern void SetInstallXLogFileSegmentActive(void);
extern bool IsInstallXLogFileSegmentActive(void);
+extern void ResetInstallXLogFileSegmentActive(void);
extern void XLogShutdownWalRcv(void);
/*
diff --git a/src/test/recovery/t/004_timeline_switch.pl b/src/test/recovery/t/004_timeline_switch.pl
index 9c8334cf278..13874ff866f 100644
--- a/src/test/recovery/t/004_timeline_switch.pl
+++ b/src/test/recovery/t/004_timeline_switch.pl
@@ -66,6 +66,14 @@ my $result =
$node_standby_2->safe_psql('postgres', "SELECT count(*) FROM tab_int");
is($result, qq(2000), 'check content of standby 2');
+# Check the logs, WAL receiver should not have been stopped while
+# transitioning to its new timeline. There is no need to rely on an
+# offset in this check of the server logs: a new log file is used on
+# node restart when primary_conninfo is updated above.
+ok( !$node_standby_2->log_contains(
+ "FATAL: .* terminating walreceiver process due to administrator command"
+ ),
+ 'WAL receiver should not be stopped across timeline jumps');
# Ensure that a standby is able to follow a primary on a newer timeline
# when WAL archiving is enabled.