Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/backend/access/transam/xlogrecovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -1848,6 +1848,23 @@ PerformWalRecovery(void)
* Resource Managers may choose to do permanent corrective actions
* at end of recovery.
*/

/*
* Pass the exact stop-boundary metadata to extensions so they can
* synchronize custom replay state against the record that caused
* recovery to stop.
*/
if (RecoveryTargetReachedHook != NULL)
{
RecoveryTargetReachedInfo recoveryTargetReachedInfo;

recoveryTargetReachedInfo.recoveryStopAfter = recoveryStopAfter;
recoveryTargetReachedInfo.recordPtr = xlogreader->ReadRecPtr;
recoveryTargetReachedInfo.recordEndPtr = xlogreader->EndRecPtr;

RecoveryTargetReachedHook(&recoveryTargetReachedInfo);
}

switch (recoveryTargetAction)
{
case RECOVERY_TARGET_ACTION_SHUTDOWN:
Expand Down Expand Up @@ -4589,6 +4606,8 @@ GetReplayXlogPtrHookType GetReplayXlogPtrHook = NULL;

RecoveryStopsBeforeHookType RecoveryStopsBeforeHook = NULL;

RecoveryTargetReachedHookType RecoveryTargetReachedHook = NULL;

/*
* Get effective latest redo apply position.
*
Expand Down
29 changes: 28 additions & 1 deletion src/include/access/xlogrecovery.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,26 @@ typedef bool (*RecoveryStopsBeforeHookType) (XLogReaderState *record,
TransactionId *recordXid,
TimestampTz *recordXtime);

/*
* Metadata describing the recovery stop boundary that PostgreSQL has just
* reached. This is passed to extensions so they can synchronize or finalize
* their own replay state before recovery_target_action is applied.
*/
typedef struct RecoveryTargetReachedInfo
{
bool recoveryStopAfter;
XLogRecPtr recordPtr; /* ReadRecPtr of the record at the stop boundary */
XLogRecPtr recordEndPtr; /* EndRecPtr of the record at the stop boundary */
} RecoveryTargetReachedInfo;

/*
* Hook for extensions to synchronize or finalize custom replay state after
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate comment, see R114

* PostgreSQL has reached a recovery target, but before recovery_target_action
* is applied. The hook receives explicit metadata describing the stop
* boundary that was reached.
*/
typedef void (*RecoveryTargetReachedHookType) (const RecoveryTargetReachedInfo *info);

/* User-settable GUC parameters */
extern PGDLLIMPORT bool recoveryTargetInclusive;
extern PGDLLIMPORT int recoveryTargetAction;
Expand Down Expand Up @@ -86,11 +106,18 @@ extern PGDLLIMPORT bool StandbyMode;
extern PGDLLIMPORT GetReplayXlogPtrHookType GetReplayXlogPtrHook;

/*
* Hook for extensions to be able to decides to stop applying the WAL files
* Hook for extensions to be able to decide whether to stop applying WAL
* based on custom WAL records.
*/
extern PGDLLIMPORT RecoveryStopsBeforeHookType RecoveryStopsBeforeHook;

/*
* Hook for extensions to synchronize or finalize custom replay state after
* PostgreSQL has reached a recovery target, but before recovery_target_action
* is applied.
*/
extern PGDLLIMPORT RecoveryTargetReachedHookType RecoveryTargetReachedHook;

extern Size XLogRecoveryShmemSize(void);
extern void XLogRecoveryShmemInit(void);

Expand Down