aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Korotkov <akorotkov@postgresql.org>2021-11-06 18:31:21 +0300
committerAlexander Korotkov <akorotkov@postgresql.org>2021-11-06 18:34:21 +0300
commit8f779a1a3eb6716faf47ef10e7bf0b883b8a1170 (patch)
tree94ab5ef32901cd0b56329a5e4f507724a87bb70d
parent3eff168a29ca6d737611e8608504537d4ff18d50 (diff)
downloadpostgresql-8f779a1a3eb6716faf47ef10e7bf0b883b8a1170.tar.gz
postgresql-8f779a1a3eb6716faf47ef10e7bf0b883b8a1170.zip
Reset lastOverflowedXid on standby when needed
Currently, lastOverflowedXid is never reset. It's just adjusted on new transactions known to be overflowed. But if there are no overflowed transactions for a long time, snapshots could be mistakenly marked as suboverflowed due to wraparound. This commit fixes this issue by resetting lastOverflowedXid when needed altogether with KnownAssignedXids. Backpatch to all supported versions. Reported-by: Stan Hu Discussion: https://postgr.es/m/CAMBWrQ%3DFp5UAsU_nATY7EMY7NHczG4-DTDU%3DmCvBQZAQ6wa2xQ%40mail.gmail.com Author: Kyotaro Horiguchi, Alexander Korotkov Reviewed-by: Stan Hu, Simon Riggs, Nikolay Samokhvalov, Andrey Borodin, Dmitry Dolgov
-rw-r--r--src/backend/storage/ipc/procarray.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 33bfde34042..b7146d65219 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -3295,24 +3295,41 @@ ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids,
/*
* ExpireAllKnownAssignedTransactionIds
- * Remove all entries in KnownAssignedXids
+ * Remove all entries in KnownAssignedXids and reset lastOverflowedXid.
*/
void
ExpireAllKnownAssignedTransactionIds(void)
{
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
KnownAssignedXidsRemovePreceding(InvalidTransactionId);
+
+ /*
+ * Reset lastOverflowedXid. Currently, lastOverflowedXid has no use after
+ * the call of this function. But do this for unification with what
+ * ExpireOldKnownAssignedTransactionIds() do.
+ */
+ procArray->lastOverflowedXid = InvalidTransactionId;
LWLockRelease(ProcArrayLock);
}
/*
* ExpireOldKnownAssignedTransactionIds
- * Remove KnownAssignedXids entries preceding the given XID
+ * Remove KnownAssignedXids entries preceding the given XID and
+ * potentially reset lastOverflowedXid.
*/
void
ExpireOldKnownAssignedTransactionIds(TransactionId xid)
{
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
+
+ /*
+ * Reset lastOverflowedXid if we know all transactions that have been
+ * possibly running are being gone. Not doing so could cause an incorrect
+ * lastOverflowedXid value, which makes extra snapshots be marked as
+ * suboverflowed.
+ */
+ if (TransactionIdPrecedes(procArray->lastOverflowedXid, xid))
+ procArray->lastOverflowedXid = InvalidTransactionId;
KnownAssignedXidsRemovePreceding(xid);
LWLockRelease(ProcArrayLock);
}