Skip to content

Commit 014f9f3

Browse files
committed
Move pg_wal_replay_wait() to xlogfuncs.c
This commit moves pg_wal_replay_wait() procedure to be a neighbor of WAL-related functions in xlogfuncs.c. The implementation of LSN waiting continues to reside in the same place. By proposal from Michael Paquier. Reported-by: Peter Eisentraut Discussion: https://postgr.es/m/18c0fa64-0475-415e-a1bd-665d922c5201%40eisentraut.org
1 parent 87eeada commit 014f9f3

File tree

3 files changed

+58
-51
lines changed

3 files changed

+58
-51
lines changed

src/backend/access/transam/xlogfuncs.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,18 @@
2323
#include "access/xlogbackup.h"
2424
#include "access/xlogrecovery.h"
2525
#include "catalog/pg_type.h"
26+
#include "commands/waitlsn.h"
2627
#include "funcapi.h"
2728
#include "miscadmin.h"
2829
#include "pgstat.h"
2930
#include "replication/walreceiver.h"
3031
#include "storage/fd.h"
32+
#include "storage/proc.h"
3133
#include "storage/standby.h"
3234
#include "utils/builtins.h"
3335
#include "utils/memutils.h"
3436
#include "utils/pg_lsn.h"
37+
#include "utils/snapmgr.h"
3538
#include "utils/timestamp.h"
3639

3740
/*
@@ -747,3 +750,56 @@ pg_promote(PG_FUNCTION_ARGS)
747750
wait_seconds)));
748751
PG_RETURN_BOOL(false);
749752
}
753+
754+
/*
755+
* Waits until recovery replays the target LSN with optional timeout.
756+
*/
757+
Datum
758+
pg_wal_replay_wait(PG_FUNCTION_ARGS)
759+
{
760+
XLogRecPtr target_lsn = PG_GETARG_LSN(0);
761+
int64 timeout = PG_GETARG_INT64(1);
762+
763+
if (timeout < 0)
764+
ereport(ERROR,
765+
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
766+
errmsg("\"timeout\" must not be negative")));
767+
768+
/*
769+
* We are going to wait for the LSN replay. We should first care that we
770+
* don't hold a snapshot and correspondingly our MyProc->xmin is invalid.
771+
* Otherwise, our snapshot could prevent the replay of WAL records
772+
* implying a kind of self-deadlock. This is the reason why
773+
* pg_wal_replay_wait() is a procedure, not a function.
774+
*
775+
* At first, we should check there is no active snapshot. According to
776+
* PlannedStmtRequiresSnapshot(), even in an atomic context, CallStmt is
777+
* processed with a snapshot. Thankfully, we can pop this snapshot,
778+
* because PortalRunUtility() can tolerate this.
779+
*/
780+
if (ActiveSnapshotSet())
781+
PopActiveSnapshot();
782+
783+
/*
784+
* At second, invalidate a catalog snapshot if any. And we should be done
785+
* with the preparation.
786+
*/
787+
InvalidateCatalogSnapshot();
788+
789+
/* Give up if there is still an active or registered snapshot. */
790+
if (GetOldestSnapshot())
791+
ereport(ERROR,
792+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
793+
errmsg("pg_wal_replay_wait() must be only called without an active or registered snapshot"),
794+
errdetail("Make sure pg_wal_replay_wait() isn't called within a transaction with an isolation level higher than READ COMMITTED, another procedure, or a function.")));
795+
796+
/*
797+
* As the result we should hold no snapshot, and correspondingly our xmin
798+
* should be unset.
799+
*/
800+
Assert(MyProc->xmin == InvalidTransactionId);
801+
802+
(void) WaitForLSNReplay(target_lsn, timeout);
803+
804+
PG_RETURN_VOID();
805+
}

src/backend/commands/waitlsn.c

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ WaitLSNCleanup(void)
217217
* Wait using MyLatch till the given LSN is replayed, the postmaster dies or
218218
* timeout happens.
219219
*/
220-
static void
220+
void
221221
WaitForLSNReplay(XLogRecPtr targetLSN, int64 timeout)
222222
{
223223
XLogRecPtr currentLSN;
@@ -336,53 +336,3 @@ WaitForLSNReplay(XLogRecPtr targetLSN, int64 timeout)
336336
LSN_FORMAT_ARGS(currentLSN))));
337337
}
338338
}
339-
340-
Datum
341-
pg_wal_replay_wait(PG_FUNCTION_ARGS)
342-
{
343-
XLogRecPtr target_lsn = PG_GETARG_LSN(0);
344-
int64 timeout = PG_GETARG_INT64(1);
345-
346-
if (timeout < 0)
347-
ereport(ERROR,
348-
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
349-
errmsg("\"timeout\" must not be negative")));
350-
351-
/*
352-
* We are going to wait for the LSN replay. We should first care that we
353-
* don't hold a snapshot and correspondingly our MyProc->xmin is invalid.
354-
* Otherwise, our snapshot could prevent the replay of WAL records
355-
* implying a kind of self-deadlock. This is the reason why
356-
* pg_wal_replay_wait() is a procedure, not a function.
357-
*
358-
* At first, we should check there is no active snapshot. According to
359-
* PlannedStmtRequiresSnapshot(), even in an atomic context, CallStmt is
360-
* processed with a snapshot. Thankfully, we can pop this snapshot,
361-
* because PortalRunUtility() can tolerate this.
362-
*/
363-
if (ActiveSnapshotSet())
364-
PopActiveSnapshot();
365-
366-
/*
367-
* At second, invalidate a catalog snapshot if any. And we should be done
368-
* with the preparation.
369-
*/
370-
InvalidateCatalogSnapshot();
371-
372-
/* Give up if there is still an active or registered snapshot. */
373-
if (GetOldestSnapshot())
374-
ereport(ERROR,
375-
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
376-
errmsg("pg_wal_replay_wait() must be only called without an active or registered snapshot"),
377-
errdetail("Make sure pg_wal_replay_wait() isn't called within a transaction with an isolation level higher than READ COMMITTED, another procedure, or a function.")));
378-
379-
/*
380-
* As the result we should hold no snapshot, and correspondingly our xmin
381-
* should be unset.
382-
*/
383-
Assert(MyProc->xmin == InvalidTransactionId);
384-
385-
(void) WaitForLSNReplay(target_lsn, timeout);
386-
387-
PG_RETURN_VOID();
388-
}

src/include/commands/waitlsn.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,6 @@ extern Size WaitLSNShmemSize(void);
7676
extern void WaitLSNShmemInit(void);
7777
extern void WaitLSNSetLatches(XLogRecPtr currentLSN);
7878
extern void WaitLSNCleanup(void);
79+
extern void WaitForLSNReplay(XLogRecPtr targetLSN, int64 timeout);
7980

8081
#endif /* WAIT_LSN_H */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy