Skip to content

Commit 412c298

Browse files
committed
Avoid assertion failure with targeted recovery in standby mode.
At the end of recovery, standby mode is turned off to re-fetch the last valid record from archive or pg_wal. Previously, if recovery target was reached and standby mode was turned off while the current WAL source was stream, recovery could try to retrieve WAL file containing the last valid record unexpectedly from stream even though not in standby mode. This caused an assertion failure. That is, the assertion test confirms that WAL file should not be retrieved from stream if standby mode is not true. This commit moves back the current WAL source to archive if it's stream even though not in standby mode, to avoid that assertion failure. This issue doesn't cause the server to crash when built with assertion disabled. In this case, the attempt to retrieve WAL file from stream not in standby mode just fails. And then recovery tries to retrieve WAL file from archive or pg_wal. Back-patch to all supported branches. Author: Kyotaro Horiguchi Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/20200227.124830.2197604521555566121.horikyota.ntt@gmail.com
1 parent 654bd69 commit 412c298

File tree

1 file changed

+22
-1
lines changed
  • src/backend/access/transam

1 file changed

+22
-1
lines changed

src/backend/access/transam/xlog.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7341,7 +7341,11 @@ StartupXLOG(void)
73417341
* We are now done reading the xlog from stream. Turn off streaming
73427342
* recovery to force fetching the files (which would be required at end of
73437343
* recovery, e.g., timeline history file) from archive or pg_wal.
7344+
*
7345+
* Note that standby mode must be turned off after killing WAL receiver,
7346+
* i.e., calling ShutdownWalRcv().
73447347
*/
7348+
Assert(!WalRcvStreaming());
73457349
StandbyMode = false;
73467350

73477351
/*
@@ -11759,12 +11763,23 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
1175911763
* values for "check trigger", "rescan timelines", and "sleep" states,
1176011764
* those actions are taken when reading from the previous source fails, as
1176111765
* part of advancing to the next state.
11766+
*
11767+
* If standby mode is turned off while reading WAL from stream, we move
11768+
* to XLOG_FROM_ARCHIVE and reset lastSourceFailed, to force fetching
11769+
* the files (which would be required at end of recovery, e.g., timeline
11770+
* history file) from archive or pg_wal. We don't need to kill WAL receiver
11771+
* here because it's already stopped when standby mode is turned off at
11772+
* the end of recovery.
1176211773
*-------
1176311774
*/
1176411775
if (!InArchiveRecovery)
1176511776
currentSource = XLOG_FROM_PG_WAL;
11766-
else if (currentSource == 0)
11777+
else if (currentSource == 0 ||
11778+
(!StandbyMode && currentSource == XLOG_FROM_STREAM))
11779+
{
11780+
lastSourceFailed = false;
1176711781
currentSource = XLOG_FROM_ARCHIVE;
11782+
}
1176811783

1176911784
for (;;)
1177011785
{
@@ -11958,6 +11973,12 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
1195811973
{
1195911974
case XLOG_FROM_ARCHIVE:
1196011975
case XLOG_FROM_PG_WAL:
11976+
/*
11977+
* WAL receiver must not be running when reading WAL from
11978+
* archive or pg_wal.
11979+
*/
11980+
Assert(!WalRcvStreaming());
11981+
1196111982
/* Close any old file we might have open. */
1196211983
if (readFile >= 0)
1196311984
{

0 commit comments

Comments
 (0)