postgres.git / summary / log / commit / refs

commit    e1fee28a0441652f021045646808a772314798f9
Author:   Alexander Korotkov <akorotkov@postgresql.org>
Date:     Sat Nov 06 15:31:21 2021 +0000
First released in: 15.0, 9.6.24, 10.19, 11.14, 12.9, 13.5, 14.1

    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


src/backend/storage/ipc/procarray.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index a0c497093ed..828ed2a38a1 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -3404,24 +3404,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); } [parent: bf5cdcfd5e44]