diff options
Diffstat (limited to 'src/backend/storage/ipc')
-rw-r--r-- | src/backend/storage/ipc/procarray.c | 11 | ||||
-rw-r--r-- | src/backend/storage/ipc/standby.c | 27 |
2 files changed, 26 insertions, 12 deletions
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 9e8b6756fe0..283517d9566 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -3337,12 +3337,17 @@ GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0, * GetConflictingVirtualXIDs -- returns an array of currently active VXIDs. * * Usage is limited to conflict resolution during recovery on standby servers. - * limitXmin is supplied as either latestRemovedXid, or InvalidTransactionId - * in cases where we cannot accurately determine a value for latestRemovedXid. + * limitXmin is supplied as either a cutoff with snapshotConflictHorizon + * semantics, or InvalidTransactionId in cases where caller cannot accurately + * determine a safe snapshotConflictHorizon value. * * If limitXmin is InvalidTransactionId then we want to kill everybody, * so we're not worried if they have a snapshot or not, nor does it really - * matter what type of lock we hold. + * matter what type of lock we hold. Caller must avoid calling here with + * snapshotConflictHorizon style cutoffs that were set to InvalidTransactionId + * during original execution, since that actually indicates that there is + * definitely no need for a recovery conflict (the snapshotConflictHorizon + * convention for InvalidTransactionId values is the opposite of our own!). * * All callers that are checking xmins always now supply a valid and useful * value for limitXmin. The limitXmin is always lower than the lowest diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c index 7db86f7885f..f43229dfda6 100644 --- a/src/backend/storage/ipc/standby.c +++ b/src/backend/storage/ipc/standby.c @@ -464,8 +464,18 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, } } +/* + * Generate whatever recovery conflicts are needed to eliminate snapshots that + * might see XIDs <= snapshotConflictHorizon as still running. + * + * snapshotConflictHorizon cutoffs are our standard approach to generating + * granular recovery conflicts. Note that InvalidTransactionId values are + * interpreted as "definitely don't need any conflicts" here, which is a + * general convention that WAL records can (and often do) depend on. + */ void -ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileLocator locator) +ResolveRecoveryConflictWithSnapshot(TransactionId snapshotConflictHorizon, + RelFileLocator locator) { VirtualTransactionId *backends; @@ -480,12 +490,11 @@ ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileLocat * which is sufficient for the deletion operation must take place before * replay of the deletion record itself). */ - if (!TransactionIdIsValid(latestRemovedXid)) + if (!TransactionIdIsValid(snapshotConflictHorizon)) return; - backends = GetConflictingVirtualXIDs(latestRemovedXid, + backends = GetConflictingVirtualXIDs(snapshotConflictHorizon, locator.dbOid); - ResolveRecoveryConflictWithVirtualXIDs(backends, PROCSIG_RECOVERY_CONFLICT_SNAPSHOT, WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT, @@ -497,7 +506,7 @@ ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileLocat * FullTransactionId values */ void -ResolveRecoveryConflictWithSnapshotFullXid(FullTransactionId latestRemovedFullXid, +ResolveRecoveryConflictWithSnapshotFullXid(FullTransactionId snapshotConflictHorizon, RelFileLocator locator) { /* @@ -510,13 +519,13 @@ ResolveRecoveryConflictWithSnapshotFullXid(FullTransactionId latestRemovedFullXi uint64 diff; diff = U64FromFullTransactionId(nextXid) - - U64FromFullTransactionId(latestRemovedFullXid); + U64FromFullTransactionId(snapshotConflictHorizon); if (diff < MaxTransactionId / 2) { - TransactionId latestRemovedXid; + TransactionId truncated; - latestRemovedXid = XidFromFullTransactionId(latestRemovedFullXid); - ResolveRecoveryConflictWithSnapshot(latestRemovedXid, locator); + truncated = XidFromFullTransactionId(snapshotConflictHorizon); + ResolveRecoveryConflictWithSnapshot(truncated, locator); } } |