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

Commitbf70bf4

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 parent93b915b commitbf70bf4

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
@@ -7598,6 +7598,16 @@ CreateCheckPoint(int flags)
75987598
MemSet(&checkPoint,0,sizeof(checkPoint));
75997599
checkPoint.time= (pg_time_t)time(NULL);
76007600

7601+
/*
7602+
* For Hot Standby, derive the oldestActiveXid before we fix the redo pointer.
7603+
* This allows us to begin accumulating changes to assemble our starting
7604+
* snapshot of locks and transactions.
7605+
*/
7606+
if (!shutdown&&XLogStandbyInfoActive())
7607+
checkPoint.oldestActiveXid=GetOldestActiveTransactionId();
7608+
else
7609+
checkPoint.oldestActiveXid=InvalidTransactionId;
7610+
76017611
/*
76027612
* We must hold WALInsertLock while examining insert state to determine
76037613
* the checkpoint REDO pointer.
@@ -7784,9 +7794,7 @@ CreateCheckPoint(int flags)
77847794
* Update checkPoint.nextXid since we have a later value
77857795
*/
77867796
if (!shutdown&&XLogStandbyInfoActive())
7787-
LogStandbySnapshot(&checkPoint.oldestActiveXid,&checkPoint.nextXid);
7788-
else
7789-
checkPoint.oldestActiveXid=InvalidTransactionId;
7797+
LogStandbySnapshot(&checkPoint.nextXid);
77907798

77917799
START_CRIT_SECTION();
77927800

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,6 +1528,63 @@ GetRunningTransactionData(void)
15281528
returnCurrentRunningXacts;
15291529
}
15301530

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

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

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

847-
*oldestActiveXid=running->oldestRunningXid;
848847
*nextXid=running->nextXid;
849848
}
850849

‎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