Hi, In standby mode, the state machine in WaitForWALToBecomeAvailable() reads WAL from pg_wal after failing to read from the archive. This is currently implemented in XLogFileReadAnyTLI() by calling XLogFileRead() with source XLOG_FROM_PG_WAL after it fails with source XLOG_FROM_PG_ARCHIVE and the current source isn't changed at all. Also, passing the source to XLogFileReadAnyTLI() in WaitForWALToBecomeAvailable() isn't straight i.e. it's not necessary to pass in XLOG_FROM_ANY at all. These things make the state machine a bit complicated and hard to understand.
The attached patch attempts to simplify the code a bit by changing the current source to XLOG_FROM_PG_WAL after failing in XLOG_FROM_PG_ARCHIVE so that the state machine can move smoothly to read from pg_wal. And we can just pass the current source to XLogFileReadAnyTLI(). It also enables us to reduce a bit of extra XLogFileRead() code in XLogFileReadAnyTLI(). Thoughts? -- Bharath Rupireddy PostgreSQL Contributors Team RDS Open Source Databases Amazon Web Services: https://aws.amazon.com
From e20354b60f4f7040e034cbd26142d8e69dd01be5 Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com> Date: Tue, 18 Oct 2022 05:52:35 +0000 Subject: [PATCH v1] Simplify standby state machine in WaitForWALToBecomeAvailable() In standby mode, the state machine in WaitForWALToBecomeAvailable() reads WAL from pg_wal after failing to read from the archive. This is currently implemented in XLogFileReadAnyTLI() by calling XLogFileRead() with source XLOG_FROM_PG_WAL after it fails with source XLOG_FROM_PG_ARCHIVE and the current source isn't changed at all. Also, passing the source to XLogFileReadAnyTLI() in WaitForWALToBecomeAvailable() isn't straight i.e. it's not necessary to pass in XLOG_FROM_ANY at all. These things make the state machine a bit complicated and hard to understand. This patch attempts to simplify the code a bit by changing the current source to XLOG_FROM_PG_WAL after failing in XLOG_FROM_PG_ARCHIVE so that the state machine can move smoothly to read from pg_wal. And we can just pass the current source to XLogFileReadAnyTLI(). It also enables us to reduce a bit of extra XLogFileRead() code in XLogFileReadAnyTLI(). --- src/backend/access/transam/xlogrecovery.c | 40 ++++++++--------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c index cb07694aea..6ac961f32b 100644 --- a/src/backend/access/transam/xlogrecovery.c +++ b/src/backend/access/transam/xlogrecovery.c @@ -3478,6 +3478,14 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess, switch (currentSource) { case XLOG_FROM_ARCHIVE: + + /* + * After failing to read from archive, we try to read from + * pg_wal. + */ + currentSource = XLOG_FROM_PG_WAL; + break; + case XLOG_FROM_PG_WAL: /* @@ -3632,12 +3640,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess, if (randAccess) curFileTLI = 0; - /* - * Try to restore the file from archive, or read an existing - * file from pg_wal. - */ readFile = XLogFileReadAnyTLI(readSegNo, DEBUG2, - currentSource == XLOG_FROM_ARCHIVE ? XLOG_FROM_ANY : currentSource); if (readFile >= 0) return XLREAD_SUCCESS; /* success! */ @@ -4199,29 +4202,14 @@ XLogFileReadAnyTLI(XLogSegNo segno, int emode, XLogSource source) continue; } - if (source == XLOG_FROM_ANY || source == XLOG_FROM_ARCHIVE) + fd = XLogFileRead(segno, emode, tli, source, true); + if (fd != -1) { - fd = XLogFileRead(segno, emode, tli, - XLOG_FROM_ARCHIVE, true); - if (fd != -1) - { + if (source == XLOG_FROM_ARCHIVE) elog(DEBUG1, "got WAL segment from archive"); - if (!expectedTLEs) - expectedTLEs = tles; - return fd; - } - } - - if (source == XLOG_FROM_ANY || source == XLOG_FROM_PG_WAL) - { - fd = XLogFileRead(segno, emode, tli, - XLOG_FROM_PG_WAL, true); - if (fd != -1) - { - if (!expectedTLEs) - expectedTLEs = tles; - return fd; - } + if (!expectedTLEs) + expectedTLEs = tles; + return fd; } } -- 2.34.1