Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit014f9f3

Browse files
committed
Move pg_wal_replay_wait() to xlogfuncs.c
This commit moves pg_wal_replay_wait() procedure to be a neighbor ofWAL-related functions in xlogfuncs.c. The implementation of LSN waitingcontinues to reside in the same place.By proposal from Michael Paquier.Reported-by: Peter EisentrautDiscussion:https://postgr.es/m/18c0fa64-0475-415e-a1bd-665d922c5201%40eisentraut.org
1 parent87eeada commit014f9f3

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+
XLogRecPtrtarget_lsn=PG_GETARG_LSN(0);
761+
int64timeout=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-
staticvoid
220+
void
221221
WaitForLSNReplay(XLogRecPtrtargetLSN,int64timeout)
222222
{
223223
XLogRecPtrcurrentLSN;
@@ -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-
XLogRecPtrtarget_lsn=PG_GETARG_LSN(0);
344-
int64timeout=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
externvoidWaitLSNShmemInit(void);
7777
externvoidWaitLSNSetLatches(XLogRecPtrcurrentLSN);
7878
externvoidWaitLSNCleanup(void);
79+
externvoidWaitForLSNReplay(XLogRecPtrtargetLSN,int64timeout);
7980

8081
#endif/* WAIT_LSN_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp