Skip to content

Add recovery target reached hook with stop-boundary metadata PG17#63

Closed
GremSnoort wants to merge 4 commits into
patches17from
recovery-target-reached-hook
Closed

Add recovery target reached hook with stop-boundary metadata PG17#63
GremSnoort wants to merge 4 commits into
patches17from
recovery-target-reached-hook

Conversation

@GremSnoort
Copy link
Copy Markdown
Contributor

Summary

Add a new RecoveryTargetReachedHook that is invoked after PostgreSQL has determined that a recovery target has been reached, but before recovery_target_action is applied.

The hook receives explicit stop-boundary metadata via RecoveryTargetReachedInfo, including:

  • target type
  • stop semantics (before / after)
  • stop metadata (xid, time, LSN, name)
  • ReadRecPtr / EndRecPtr for the record at the stop boundary

Problem

PostgreSQL can reach a recovery target before an extension with custom replay/finalization logic has fully synchronized its own visible state to that same stop boundary.

In such cases, PostgreSQL already considers the target reached, but the extension-visible state may still lag behind the actual recovery stop point. This makes it difficult for extensions to guarantee correct target-point visibility semantics using only generic replay-progress information.

Motivation

Extensions with custom replay/finalization logic may need to synchronize their internal state against the actual recovery stop boundary before PostgreSQL exposes the target-reached state.

A generic replay-progress pointer is not always sufficient for this, especially for target types where extension-visible state must match the precise stop boundary semantics.

Changes

  • add RecoveryTargetReachedInfo to carry recovery stop-boundary metadata
  • add RecoveryTargetReachedHookType
  • add RecoveryTargetReachedHook
  • invoke the hook in PerformWalRecovery() after reachedRecoveryTarget and before recovery_target_action is applied

Result

This gives extensions an explicit integration point for target-boundary synchronization/finalization without changing normal replay flow.

Issue

Closes: orioledb/orioledb#820

Add a new RecoveryTargetReachedHook for extensions.

The hook is invoked after PostgreSQL reaches a recovery target and before
recovery_target_action is applied. It receives a
RecoveryTargetReachedInfo structure with the target type, stop metadata,
and the ReadRecPtr/EndRecPtr of the record at the stop boundary.

This gives extensions an explicit recovery stop-boundary context for
synchronizing or finalizing custom replay state before PostgreSQL
exposes the target-reached state.
* Resource Managers may choose to do permanent corrective actions
* at end of recovery.
*/
recoveryTargetReachedInfo.recoveryTarget = recoveryTarget;
Copy link
Copy Markdown
Contributor

@pashkinelfe pashkinelfe Apr 23, 2026

Choose a reason for hiding this comment

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

I propose to remove variables declared as extern from the recoveryTargetReachedInfo struct as they are acessible by Orioledb anyway

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 0ffa7c4

* Resource Managers may choose to do permanent corrective actions
* at end of recovery.
*/
recoveryTargetReachedInfo.recoveryTarget = recoveryTarget;
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.

Also all these assignments are no-op if RecoveryTargetReachedHook == NULL. I propose to move remaining assingments into if block below

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 531a214


if (reachedRecoveryTarget)
{
RecoveryTargetReachedInfo recoveryTargetReachedInfo;
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.

I propose to move this into if block: if (RecoveryTargetReachedHook != NULL)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 531a214

recoveryTargetReachedInfo.recoveryStopXid = recoveryStopXid;
recoveryTargetReachedInfo.recoveryStopTime = recoveryStopTime;
recoveryTargetReachedInfo.recoveryStopLSN = recoveryStopLSN;
recoveryTargetReachedInfo.recoveryStopName =
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.

Unused in hook, to remove

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 531a214

*/
recoveryTargetReachedInfo.recoveryStopAfter = recoveryStopAfter;
recoveryTargetReachedInfo.recoveryStopXid = recoveryStopXid;
recoveryTargetReachedInfo.recoveryStopTime = recoveryStopTime;
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.

Unused in hook, to remove

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 531a214

@GremSnoort GremSnoort changed the title Add recovery target reached hook with stop-boundary metadata Add recovery target reached hook with stop-boundary metadata PG17 Apr 27, 2026
Copy link
Copy Markdown
Contributor

@pashkinelfe pashkinelfe left a comment

Choose a reason for hiding this comment

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

After removing duplicate comments, squashing and adding commit message, PR is ready to merge

} 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

@pashkinelfe
Copy link
Copy Markdown
Contributor

Applied proposed edits, squashed, and merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants