Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1df21dd

Browse files
committed
Avoid duplicate XIDs at recovery when building initial snapshot
On a primary, sets of XLOG_RUNNING_XACTS records are generated on aperiodic basis to allow recovery to build the initial state oftransactions for a hot standby. The set of transaction IDs is createdby scanning all the entries in ProcArray. However it happens that itslogic never counted on the fact that two-phase transactions finishing toprepare can put ProcArray in a state where there are two entries withthe same transaction ID, one for the initial transaction which getscleared when prepare finishes, and a second, dummy, entry to track thatthe transaction is still running after prepare finishes. This wayensures a continuous presence of the transaction so as callers of forexample TransactionIdIsInProgress() are always able to see it as alive.So, if a XLOG_RUNNING_XACTS takes a standby snapshot while a two-phasetransaction finishes to prepare, the record can finish with duplicatedXIDs, which is a state expected by design. If this record gets appliedon a standby to initial its recovery state, then it would simply fail,so the odds of facing this failure are very low in practice. It wouldbe tempting to change the generation of XLOG_RUNNING_XACTS so asduplicates are removed on the source, but this requires to hold onProcArrayLock for longer and this would impact all workloads,particularly those using heavily two-phase transactions.XLOG_RUNNING_XACTS is also actually used only to initialize the standbystate at recovery, so instead the solution is taken to discardduplicates when applying the initial snapshot.Diagnosed-by: Konstantin KnizhnikAuthor: Michael PaquierDiscussion:https://postgr.es/m/0c96b653-4696-d4b4-6b5d-78143175d113@postgrespro.ruBackpatch-through: 9.3
1 parent8f850f2 commit1df21dd

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

‎src/backend/storage/ipc/procarray.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -799,10 +799,21 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
799799
qsort(xids,nxids,sizeof(TransactionId),xidComparator);
800800

801801
/*
802-
* Add the sorted snapshot into KnownAssignedXids
802+
* Add the sorted snapshot into KnownAssignedXids. The running-xacts
803+
* snapshot may include duplicated xids because of prepared
804+
* transactions, so ignore them.
803805
*/
804806
for (i=0;i<nxids;i++)
807+
{
808+
if (i>0&&TransactionIdEquals(xids[i-1],xids[i]))
809+
{
810+
elog(DEBUG1,
811+
"found duplicated transaction %u for KnownAssignedXids insertion",
812+
xids[i]);
813+
continue;
814+
}
805815
KnownAssignedXidsAdd(xids[i],xids[i], true);
816+
}
806817

807818
KnownAssignedXidsDisplay(trace_recovery(DEBUG3));
808819
}
@@ -1898,7 +1909,8 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc)
18981909
* GetRunningTransactionData -- returns information about running transactions.
18991910
*
19001911
* Similar to GetSnapshotData but returns more information. We include
1901-
* all PGXACTs with an assigned TransactionId, even VACUUM processes.
1912+
* all PGXACTs with an assigned TransactionId, even VACUUM processes and
1913+
* prepared transactions.
19021914
*
19031915
* We acquire XidGenLock and ProcArrayLock, but the caller is responsible for
19041916
* releasing them. Acquiring XidGenLock ensures that no new XIDs enter the proc
@@ -1912,6 +1924,11 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc)
19121924
* This is never executed during recovery so there is no need to look at
19131925
* KnownAssignedXids.
19141926
*
1927+
* Dummy PGXACTs from prepared transaction are included, meaning that this
1928+
* may return entries with duplicated TransactionId values coming from
1929+
* transaction finishing to prepare. Nothing is done about duplicated
1930+
* entries here to not hold on ProcArrayLock more than necessary.
1931+
*
19151932
* We don't worry about updating other counters, we want to keep this as
19161933
* simple as possible and leave GetSnapshotData() as the primary code for
19171934
* that bookkeeping.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp