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

Commit86e3364

Browse files
Derive oldestActiveXid at correct time for Hot Standby.
There was a timing window between when oldestActiveXid was derivedand when it should have been derived that only shows itself underheavy load. Move code around to ensure correct timing of derivation.No change to StartupSUBTRANS() code, which is where this failed.Bug report by Chris Redekop
1 parent10b7c68 commit86e3364

File tree

5 files changed

+71
-6
lines changed

5 files changed

+71
-6
lines changed

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7636,6 +7636,16 @@ CreateCheckPoint(int flags)
76367636
MemSet(&checkPoint,0,sizeof(checkPoint));
76377637
checkPoint.time= (pg_time_t)time(NULL);
76387638

7639+
/*
7640+
* For Hot Standby, derive the oldestActiveXid before we fix the redo pointer.
7641+
* This allows us to begin accumulating changes to assemble our starting
7642+
* snapshot of locks and transactions.
7643+
*/
7644+
if (!shutdown&&XLogStandbyInfoActive())
7645+
checkPoint.oldestActiveXid=GetOldestActiveTransactionId();
7646+
else
7647+
checkPoint.oldestActiveXid=InvalidTransactionId;
7648+
76397649
/*
76407650
* We must hold WALInsertLock while examining insert state to determine
76417651
* the checkpoint REDO pointer.
@@ -7822,9 +7832,7 @@ CreateCheckPoint(int flags)
78227832
* Update checkPoint.nextXid since we have a later value
78237833
*/
78247834
if (!shutdown&&XLogStandbyInfoActive())
7825-
LogStandbySnapshot(&checkPoint.oldestActiveXid,&checkPoint.nextXid);
7826-
else
7827-
checkPoint.oldestActiveXid=InvalidTransactionId;
7835+
LogStandbySnapshot(&checkPoint.nextXid);
78287836

78297837
START_CRIT_SECTION();
78307838

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1620,6 +1620,63 @@ GetRunningTransactionData(void)
16201620
returnCurrentRunningXacts;
16211621
}
16221622

1623+
/*
1624+
* GetOldestActiveTransactionId()
1625+
*
1626+
* Similar to GetSnapshotData but returns just oldestActiveXid. We include
1627+
* all PGPROCs with an assigned TransactionId, even VACUUM processes.
1628+
* We look at all databases, though there is no need to include WALSender
1629+
* since this has no effect on hot standby conflicts.
1630+
*
1631+
* This is never executed during recovery so there is no need to look at
1632+
* KnownAssignedXids.
1633+
*
1634+
* We don't worry about updating other counters, we want to keep this as
1635+
* simple as possible and leave GetSnapshotData() as the primary code for
1636+
* that bookkeeping.
1637+
*/
1638+
TransactionId
1639+
GetOldestActiveTransactionId(void)
1640+
{
1641+
ProcArrayStruct*arrayP=procArray;
1642+
TransactionIdoldestRunningXid;
1643+
intindex;
1644+
1645+
Assert(!RecoveryInProgress());
1646+
1647+
LWLockAcquire(ProcArrayLock,LW_SHARED);
1648+
1649+
oldestRunningXid=ShmemVariableCache->nextXid;
1650+
1651+
/*
1652+
* Spin over procArray collecting all xids and subxids.
1653+
*/
1654+
for (index=0;index<arrayP->numProcs;index++)
1655+
{
1656+
volatilePGPROC*proc=arrayP->procs[index];
1657+
TransactionIdxid;
1658+
1659+
/* Fetch xid just once - see GetNewTransactionId */
1660+
xid=proc->xid;
1661+
1662+
if (!TransactionIdIsNormal(xid))
1663+
continue;
1664+
1665+
if (TransactionIdPrecedes(xid,oldestRunningXid))
1666+
oldestRunningXid=xid;
1667+
1668+
/*
1669+
* Top-level XID of a transaction is always less than any of its
1670+
* subxids, so we don't need to check if any of the subxids are
1671+
* smaller than oldestRunningXid
1672+
*/
1673+
}
1674+
1675+
LWLockRelease(ProcArrayLock);
1676+
1677+
returnoldestRunningXid;
1678+
}
1679+
16231680
/*
16241681
* GetTransactionsInCommit -- Get the XIDs of transactions that are committing
16251682
*

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ standby_desc(StringInfo buf, uint8 xl_info, char *rec)
815815
* making WAL entries.
816816
*/
817817
void
818-
LogStandbySnapshot(TransactionId*oldestActiveXid,TransactionId*nextXid)
818+
LogStandbySnapshot(TransactionId*nextXid)
819819
{
820820
RunningTransactionsrunning;
821821
xl_standby_lock*locks;
@@ -845,7 +845,6 @@ LogStandbySnapshot(TransactionId *oldestActiveXid, TransactionId *nextXid)
845845
/* GetRunningTransactionData() acquired XidGenLock, we must release it */
846846
LWLockRelease(XidGenLock);
847847

848-
*oldestActiveXid=running->oldestRunningXid;
849848
*nextXid=running->nextXid;
850849
}
851850

‎src/include/storage/procarray.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ extern RunningTransactions GetRunningTransactionData(void);
5050
externboolTransactionIdIsInProgress(TransactionIdxid);
5151
externboolTransactionIdIsActive(TransactionIdxid);
5252
externTransactionIdGetOldestXmin(boolallDbs,boolignoreVacuum);
53+
externTransactionIdGetOldestActiveTransactionId(void);
5354

5455
externintGetTransactionsInCommit(TransactionId**xids_p);
5556
externboolHaveTransactionsInCommit(TransactionId*xids,intnxids);

‎src/include/storage/standby.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,6 @@ typedef RunningTransactionsData *RunningTransactions;
111111
externvoidLogAccessExclusiveLock(OiddbOid,OidrelOid);
112112
externvoidLogAccessExclusiveLockPrepare(void);
113113

114-
externvoidLogStandbySnapshot(TransactionId*oldestActiveXid,TransactionId*nextXid);
114+
externvoidLogStandbySnapshot(TransactionId*nextXid);
115115

116116
#endif/* STANDBY_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp