aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon Riggs <simon@2ndQuadrant.com>2012-06-08 17:34:04 +0100
committerSimon Riggs <simon@2ndQuadrant.com>2012-06-08 17:34:04 +0100
commit37255705399b57b2e413814799f0bc9b94fda14a (patch)
treec59d9dc1f32934a6637a62374ba47815c81d9022 /src
parent3b5548a3d524e3b37d49f79f707d2119ecdfa303 (diff)
downloadpostgresql-37255705399b57b2e413814799f0bc9b94fda14a.tar.gz
postgresql-37255705399b57b2e413814799f0bc9b94fda14a.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/backend/storage/ipc/procarray.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 26469c4f79d..d986418a10a 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -160,6 +160,7 @@ static int KnownAssignedXidsGetAndSetXmin(TransactionId *xarray,
TransactionId xmax);
static TransactionId KnownAssignedXidsGetOldestXmin(void);
static void KnownAssignedXidsDisplay(int trace_level);
+static void KnownAssignedXidsReset(void);
/*
* Report shared-memory space needed by CreateSharedProcArray.
@@ -526,6 +527,11 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
*/
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;
}
else
@@ -569,7 +575,6 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
* xids to subtrans. If RunningXacts is overflowed then we don't have
* enough information to correctly update subtrans anyway.
*/
- Assert(procArray->numKnownAssignedXids == 0);
/*
* Allocate a temporary array to avoid modifying the array passed as
@@ -599,6 +604,12 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
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
* KnownAssignedXids.
@@ -3340,3 +3351,22 @@ KnownAssignedXidsDisplay(int trace_level)
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);
+}