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

Commit656bba9

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 parentff8451a commit656bba9

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
@@ -7181,6 +7181,16 @@ CreateCheckPoint(int flags)
71817181
MemSet(&checkPoint,0,sizeof(checkPoint));
71827182
checkPoint.time= (pg_time_t)time(NULL);
71837183

7184+
/*
7185+
* For Hot Standby, derive the oldestActiveXid before we fix the redo pointer.
7186+
* This allows us to begin accumulating changes to assemble our starting
7187+
* snapshot of locks and transactions.
7188+
*/
7189+
if (!shutdown&&XLogStandbyInfoActive())
7190+
checkPoint.oldestActiveXid=GetOldestActiveTransactionId();
7191+
else
7192+
checkPoint.oldestActiveXid=InvalidTransactionId;
7193+
71847194
/*
71857195
* We must hold WALInsertLock while examining insert state to determine
71867196
* the checkpoint REDO pointer.
@@ -7367,9 +7377,7 @@ CreateCheckPoint(int flags)
73677377
* Update checkPoint.nextXid since we have a later value
73687378
*/
73697379
if (!shutdown&&XLogStandbyInfoActive())
7370-
LogStandbySnapshot(&checkPoint.oldestActiveXid,&checkPoint.nextXid);
7371-
else
7372-
checkPoint.oldestActiveXid=InvalidTransactionId;
7380+
LogStandbySnapshot(&checkPoint.nextXid);
73737381

73747382
START_CRIT_SECTION();
73757383

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,6 +1509,63 @@ GetRunningTransactionData(void)
15091509
returnCurrentRunningXacts;
15101510
}
15111511

1512+
/*
1513+
* GetOldestActiveTransactionId()
1514+
*
1515+
* Similar to GetSnapshotData but returns just oldestActiveXid. We include
1516+
* all PGPROCs with an assigned TransactionId, even VACUUM processes.
1517+
* We look at all databases, though there is no need to include WALSender
1518+
* since this has no effect on hot standby conflicts.
1519+
*
1520+
* This is never executed during recovery so there is no need to look at
1521+
* KnownAssignedXids.
1522+
*
1523+
* We don't worry about updating other counters, we want to keep this as
1524+
* simple as possible and leave GetSnapshotData() as the primary code for
1525+
* that bookkeeping.
1526+
*/
1527+
TransactionId
1528+
GetOldestActiveTransactionId(void)
1529+
{
1530+
ProcArrayStruct*arrayP=procArray;
1531+
TransactionIdoldestRunningXid;
1532+
intindex;
1533+
1534+
Assert(!RecoveryInProgress());
1535+
1536+
LWLockAcquire(ProcArrayLock,LW_SHARED);
1537+
1538+
oldestRunningXid=ShmemVariableCache->nextXid;
1539+
1540+
/*
1541+
* Spin over procArray collecting all xids and subxids.
1542+
*/
1543+
for (index=0;index<arrayP->numProcs;index++)
1544+
{
1545+
volatilePGPROC*proc=arrayP->procs[index];
1546+
TransactionIdxid;
1547+
1548+
/* Fetch xid just once - see GetNewTransactionId */
1549+
xid=proc->xid;
1550+
1551+
if (!TransactionIdIsNormal(xid))
1552+
continue;
1553+
1554+
if (TransactionIdPrecedes(xid,oldestRunningXid))
1555+
oldestRunningXid=xid;
1556+
1557+
/*
1558+
* Top-level XID of a transaction is always less than any of its
1559+
* subxids, so we don't need to check if any of the subxids are
1560+
* smaller than oldestRunningXid
1561+
*/
1562+
}
1563+
1564+
LWLockRelease(ProcArrayLock);
1565+
1566+
returnoldestRunningXid;
1567+
}
1568+
15121569
/*
15131570
* GetTransactionsInCommit -- Get the XIDs of transactions that are committing
15141571
*

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ standby_desc(StringInfo buf, uint8 xl_info, char *rec)
818818
* making WAL entries.
819819
*/
820820
void
821-
LogStandbySnapshot(TransactionId*oldestActiveXid,TransactionId*nextXid)
821+
LogStandbySnapshot(TransactionId*nextXid)
822822
{
823823
RunningTransactionsrunning;
824824
xl_standby_lock*locks;
@@ -848,7 +848,6 @@ LogStandbySnapshot(TransactionId *oldestActiveXid, TransactionId *nextXid)
848848
/* GetRunningTransactionData() acquired XidGenLock, we must release it */
849849
LWLockRelease(XidGenLock);
850850

851-
*oldestActiveXid=running->oldestRunningXid;
852851
*nextXid=running->nextXid;
853852
}
854853

‎src/include/storage/procarray.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ extern Snapshot GetSnapshotData(Snapshot snapshot);
4646
externboolTransactionIdIsInProgress(TransactionIdxid);
4747
externboolTransactionIdIsActive(TransactionIdxid);
4848
externTransactionIdGetOldestXmin(boolallDbs,boolignoreVacuum);
49+
externTransactionIdGetOldestActiveTransactionId(void);
4950

5051
externintGetTransactionsInCommit(TransactionId**xids_p);
5152
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