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

Commita41c881

Browse files
Ensure no xid gaps during Hot Standby startup
In some cases with higher numbers of subtransactionsit was possible for us to incorrectly initializesubtrans leading to complaints of missing pages.Bug report by Sergey KonoplevAnalysis and fix by Andres Freund
1 parent27e9e86 commita41c881

File tree

3 files changed

+51
-6
lines changed

3 files changed

+51
-6
lines changed

‎src/backend/access/transam/xlog.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6449,6 +6449,9 @@ StartupXLOG(void)
64496449
oldestActiveXID=checkPoint.oldestActiveXid;
64506450
Assert(TransactionIdIsValid(oldestActiveXID));
64516451

6452+
/* Tell procarray about the range of xids it has to deal with */
6453+
ProcArrayInitRecovery(ShmemVariableCache->nextXid);
6454+
64526455
/*
64536456
* Startup commit log and subtrans only. Other SLRUs are not
64546457
* maintained during recovery and need not be started yet.

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

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,28 @@ ProcArrayClearTransaction(PGPROC *proc)
435435
proc->subxids.overflowed= false;
436436
}
437437

438+
/*
439+
* ProcArrayInitRecovery -- initialize recovery xid mgmt environment
440+
*
441+
* Remember up to where the startup process initialized the CLOG and subtrans
442+
* so we can ensure its initialized gaplessly up to the point where necessary
443+
* while in recovery.
444+
*/
445+
void
446+
ProcArrayInitRecovery(TransactionIdinitializedUptoXID)
447+
{
448+
Assert(standbyState==STANDBY_INITIALIZED);
449+
Assert(TransactionIdIsNormal(initializedUptoXID));
450+
451+
/*
452+
* we set latestObservedXid to the xid SUBTRANS has been initialized upto
453+
* so we can extend it from that point onwards when we reach a consistent
454+
* state in ProcArrayApplyRecoveryInfo().
455+
*/
456+
latestObservedXid=initializedUptoXID;
457+
TransactionIdRetreat(latestObservedXid);
458+
}
459+
438460
/*
439461
* ProcArrayApplyRecoveryInfo -- apply recovery info about xids
440462
*
@@ -523,7 +545,10 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
523545
Assert(standbyState==STANDBY_INITIALIZED);
524546

525547
/*
526-
* OK, we need to initialise from the RunningTransactionsData record
548+
* OK, we need to initialise from the RunningTransactionsData record.
549+
*
550+
* NB: this can be reached at least twice, so make sure new code can deal
551+
* with that.
527552
*/
528553

529554
/*
@@ -595,20 +620,32 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
595620
pfree(xids);
596621

597622
/*
623+
* latestObservedXid is set to the the point where SUBTRANS was started up
624+
* to, initialize subtrans from thereon, up to nextXid - 1.
625+
*/
626+
Assert(TransactionIdIsNormal(latestObservedXid));
627+
while (TransactionIdPrecedes(latestObservedXid,running->nextXid))
628+
{
629+
ExtendCLOG(latestObservedXid);
630+
ExtendSUBTRANS(latestObservedXid);
631+
632+
TransactionIdAdvance(latestObservedXid);
633+
}
634+
635+
/* ----------
598636
* Now we've got the running xids we need to set the global values that
599637
* are used to track snapshots as they evolve further.
600638
*
601-
* - latestCompletedXid which will be the xmax for snapshots -
602-
* lastOverflowedXid which shows whether snapshots overflow - nextXid
639+
* - latestCompletedXid which will be the xmax for snapshots
640+
* - lastOverflowedXid which shows whether snapshots overflow
641+
* - nextXid
603642
*
604643
* If the snapshot overflowed, then we still initialise with what we know,
605644
* but the recovery snapshot isn't fully valid yet because we know there
606645
* are some subxids missing. We don't know the specific subxids that are
607646
* missing, so conservatively assume the last one is latestObservedXid.
647+
* ----------
608648
*/
609-
latestObservedXid=running->nextXid;
610-
TransactionIdRetreat(latestObservedXid);
611-
612649
if (running->subxid_overflow)
613650
{
614651
standbyState=STANDBY_SNAPSHOT_PENDING;
@@ -667,6 +704,10 @@ ProcArrayApplyXidAssignment(TransactionId topxid,
667704

668705
Assert(standbyState >=STANDBY_INITIALIZED);
669706

707+
/* can't do anything useful unless we have more state setup */
708+
if (standbyState==STANDBY_INITIALIZED)
709+
return;
710+
670711
max_xid=TransactionIdLatest(topxid,nsubxids,subxids);
671712

672713
/*

‎src/include/storage/procarray.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ extern void ProcArrayRemove(PGPROC *proc, TransactionId latestXid);
2828
externvoidProcArrayEndTransaction(PGPROC*proc,TransactionIdlatestXid);
2929
externvoidProcArrayClearTransaction(PGPROC*proc);
3030

31+
externvoidProcArrayInitRecovery(TransactionIdinitializedUptoXID);
3132
externvoidProcArrayApplyRecoveryInfo(RunningTransactionsrunning);
3233
externvoidProcArrayApplyXidAssignment(TransactionIdtopxid,
3334
intnsubxids,TransactionId*subxids);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp