v2-0001-pg_wal_replay_wait-Improve-handling-of-standby-pr.patch
application/octet-stream
Filename: v2-0001-pg_wal_replay_wait-Improve-handling-of-standby-pr.patch
Type: application/octet-stream
Part: 1
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v2-0001
Subject: pg_wal_replay_wait(): Improve handling of standby promotion
| File | + | − |
|---|---|---|
| src/backend/access/transam/xlogfuncs.c | 12 | 6 |
| src/backend/access/transam/xlogwait.c | 4 | 2 |
From 4c8ef6795234c1314a33c03eba4cba790e787cca Mon Sep 17 00:00:00 2001
From: Alexander Korotkov <akorotkov@postgresql.org>
Date: Mon, 4 Nov 2024 06:18:08 +0200
Subject: [PATCH v2 1/2] pg_wal_replay_wait(): Improve handling of standby
promotion
Currently, when pg_wal_replay_wait() finds the server to be not in recovery,
it assumes concurrent promotion happened. That leads to certain problems
including:
1. No distinction between local recovery as streaming WAL replay,
2. Weird error reporting when there was no recovery.
This commit uses PromoteIsTriggered() checks to improve the situation in
the following ways:
1. Accept last replay LSN not in recovery mode only when standby was
promoted,
2. Show last replay LSN in errdetail() only if standby was promoted.
Reported-by: Heikki Linnakangas
Discussion: https://postgr.es/m/ab0eddce-06d4-4db2-87ce-46fa2427806c%40iki.fi
---
src/backend/access/transam/xlogfuncs.c | 18 ++++++++++++------
src/backend/access/transam/xlogwait.c | 6 ++++--
2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index bca1d395683..8abea2dbb57 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -827,12 +827,18 @@ pg_wal_replay_wait(PG_FUNCTION_ARGS)
break;
case WAIT_LSN_RESULT_NOT_IN_RECOVERY:
- ereport(ERROR,
- (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
- errmsg("recovery is not in progress"),
- errdetail("Recovery ended before replaying target LSN %X/%X; last replay LSN %X/%X.",
- LSN_FORMAT_ARGS(target_lsn),
- LSN_FORMAT_ARGS(GetXLogReplayRecPtr(NULL)))));
+ if (PromoteIsTriggered())
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("recovery is not in progress"),
+ errdetail("Recovery ended before replaying target LSN %X/%X; last replay LSN %X/%X.",
+ LSN_FORMAT_ARGS(target_lsn),
+ LSN_FORMAT_ARGS(GetXLogReplayRecPtr(NULL)))));
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("recovery is not in progress"),
+ errhint("Waiting for LSN can only be executed during recovery.")));
break;
}
diff --git a/src/backend/access/transam/xlogwait.c b/src/backend/access/transam/xlogwait.c
index 0ec0898cfbf..fa40762c66a 100644
--- a/src/backend/access/transam/xlogwait.c
+++ b/src/backend/access/transam/xlogwait.c
@@ -238,7 +238,8 @@ WaitForLSNReplay(XLogRecPtr targetLSN, int64 timeout)
* the procedure call, while target LSN is replayed. So, we still
* check the last replay LSN before reporting an error.
*/
- if (targetLSN <= GetXLogReplayRecPtr(NULL))
+ if (PromoteIsTriggered() &&
+ targetLSN <= GetXLogReplayRecPtr(NULL))
return WAIT_LSN_RESULT_SUCCESS;
return WAIT_LSN_RESULT_NOT_IN_RECOVERY;
}
@@ -276,7 +277,8 @@ WaitForLSNReplay(XLogRecPtr targetLSN, int64 timeout)
*/
deleteLSNWaiter();
currentLSN = GetXLogReplayRecPtr(NULL);
- if (targetLSN <= currentLSN)
+ if (PromoteIsTriggered() &&
+ targetLSN <= currentLSN)
return WAIT_LSN_RESULT_SUCCESS;
return WAIT_LSN_RESULT_NOT_IN_RECOVERY;
}
--
2.39.5 (Apple Git-154)