Add recovery target reached hook with stop-boundary metadata PG17#63
Add recovery target reached hook with stop-boundary metadata PG17#63GremSnoort wants to merge 4 commits into
Conversation
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; |
There was a problem hiding this comment.
I propose to remove variables declared as extern from the recoveryTargetReachedInfo struct as they are acessible by Orioledb anyway
| * Resource Managers may choose to do permanent corrective actions | ||
| * at end of recovery. | ||
| */ | ||
| recoveryTargetReachedInfo.recoveryTarget = recoveryTarget; |
There was a problem hiding this comment.
Also all these assignments are no-op if RecoveryTargetReachedHook == NULL. I propose to move remaining assingments into if block below
|
|
||
| if (reachedRecoveryTarget) | ||
| { | ||
| RecoveryTargetReachedInfo recoveryTargetReachedInfo; |
There was a problem hiding this comment.
I propose to move this into if block: if (RecoveryTargetReachedHook != NULL)
| recoveryTargetReachedInfo.recoveryStopXid = recoveryStopXid; | ||
| recoveryTargetReachedInfo.recoveryStopTime = recoveryStopTime; | ||
| recoveryTargetReachedInfo.recoveryStopLSN = recoveryStopLSN; | ||
| recoveryTargetReachedInfo.recoveryStopName = |
There was a problem hiding this comment.
Unused in hook, to remove
| */ | ||
| recoveryTargetReachedInfo.recoveryStopAfter = recoveryStopAfter; | ||
| recoveryTargetReachedInfo.recoveryStopXid = recoveryStopXid; | ||
| recoveryTargetReachedInfo.recoveryStopTime = recoveryStopTime; |
There was a problem hiding this comment.
Unused in hook, to remove
pashkinelfe
left a comment
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Duplicate comment, see R114
|
Applied proposed edits, squashed, and merged |
Summary
Add a new
RecoveryTargetReachedHookthat is invoked after PostgreSQL has determined that a recovery target has been reached, but beforerecovery_target_actionis applied.The hook receives explicit stop-boundary metadata via
RecoveryTargetReachedInfo, including:before/after)xid,time,LSN,name)ReadRecPtr/EndRecPtrfor the record at the stop boundaryProblem
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
RecoveryTargetReachedInfoto carry recovery stop-boundary metadataRecoveryTargetReachedHookTypeRecoveryTargetReachedHookPerformWalRecovery()afterreachedRecoveryTargetand beforerecovery_target_actionis appliedResult
This gives extensions an explicit integration point for target-boundary synchronization/finalization without changing normal replay flow.
Issue
Closes: orioledb/orioledb#820