1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-08 22:02:03 +03:00

Fix bug in early startup of Hot Standby with subtransactions.

When HS startup is deferred because of overflowed subtransactions, ensure
that we re-initialize KnownAssignedXids for when both existing and incoming
snapshots have non-zero qualifying xids.

Fixes bug #6661 reported by Valentine Gogichashvili.

Analysis and fix by Andres Freund
This commit is contained in:
Simon Riggs 2012-06-08 17:35:22 +01:00
parent 16222f32ed
commit 557433f48a

View File

@ -158,6 +158,7 @@ static int KnownAssignedXidsGetAndSetXmin(TransactionId *xarray,
TransactionId xmax); TransactionId xmax);
static TransactionId KnownAssignedXidsGetOldestXmin(void); static TransactionId KnownAssignedXidsGetOldestXmin(void);
static void KnownAssignedXidsDisplay(int trace_level); static void KnownAssignedXidsDisplay(int trace_level);
static void KnownAssignedXidsReset(void);
/* /*
* Report shared-memory space needed by CreateSharedProcArray. * Report shared-memory space needed by CreateSharedProcArray.
@ -493,6 +494,11 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
*/ */
if (!running->subxid_overflow || running->xcnt == 0) if (!running->subxid_overflow || running->xcnt == 0)
{ {
/*
* If we have already collected known assigned xids, we need to
* throw them away before we apply the recovery snapshot.
*/
KnownAssignedXidsReset();
standbyState = STANDBY_INITIALIZED; standbyState = STANDBY_INITIALIZED;
} }
else else
@ -536,7 +542,6 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
* xids to subtrans. If RunningXacts is overflowed then we don't have * xids to subtrans. If RunningXacts is overflowed then we don't have
* enough information to correctly update subtrans anyway. * enough information to correctly update subtrans anyway.
*/ */
Assert(procArray->numKnownAssignedXids == 0);
/* /*
* Allocate a temporary array to avoid modifying the array passed as * Allocate a temporary array to avoid modifying the array passed as
@ -566,6 +571,12 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
if (nxids > 0) if (nxids > 0)
{ {
if (procArray->numKnownAssignedXids != 0)
{
LWLockRelease(ProcArrayLock);
elog(ERROR, "KnownAssignedXids is not empty");
}
/* /*
* Sort the array so that we can add them safely into * Sort the array so that we can add them safely into
* KnownAssignedXids. * KnownAssignedXids.
@ -3159,3 +3170,22 @@ KnownAssignedXidsDisplay(int trace_level)
pfree(buf.data); pfree(buf.data);
} }
/*
* KnownAssignedXidsReset
* Resets KnownAssignedXids to be empty
*/
static void
KnownAssignedXidsReset(void)
{
/* use volatile pointer to prevent code rearrangement */
volatile ProcArrayStruct *pArray = procArray;
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
pArray->numKnownAssignedXids = 0;
pArray->tailKnownAssignedXids = 0;
pArray->headKnownAssignedXids = 0;
LWLockRelease(ProcArrayLock);
}