Commit 37255705 authored by Simon Riggs's avatar Simon Riggs

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
parent 3b5548a3
...@@ -160,6 +160,7 @@ static int KnownAssignedXidsGetAndSetXmin(TransactionId *xarray, ...@@ -160,6 +160,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.
...@@ -526,6 +527,11 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) ...@@ -526,6 +527,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
...@@ -569,7 +575,6 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) ...@@ -569,7 +575,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
...@@ -599,6 +604,12 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) ...@@ -599,6 +604,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.
...@@ -3340,3 +3351,22 @@ KnownAssignedXidsDisplay(int trace_level) ...@@ -3340,3 +3351,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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment