consider vacuum's xmin when truncate csnlog in checkpoint

This commit is contained in:
xiong_xjun 2020-08-19 14:51:50 +08:00
parent 767f9efcdf
commit 92235f7cee
3 changed files with 36 additions and 11 deletions

View File

@ -9975,6 +9975,7 @@ void CreateCheckPoint(int flags)
XLogRecPtr curMinRecLSN = InvalidXLogRecPtr;
bool doFullCheckpoint = !g_instance.attr.attr_storage.enableIncrementalCheckpoint;
TransactionId oldest_active_xid = InvalidTransactionId;
TransactionId globalXmin = InvalidTransactionId;
/*
* An end-of-recovery checkpoint is really a shutdown checkpoint, just
@ -10045,8 +10046,11 @@ void CreateCheckPoint(int flags)
* pointer. This allows us to begin accumulating changes to assemble our
* starting snapshot of locks and transactions.
*/
if (!shutdown) {
oldest_active_xid = GetOldestActiveTransactionId(&globalXmin);
}
if (!shutdown && XLogStandbyInfoActive()) {
checkPoint.oldestActiveXid = oldest_active_xid = GetOldestActiveTransactionId();
checkPoint.oldestActiveXid = oldest_active_xid;
} else {
checkPoint.oldestActiveXid = InvalidTransactionId;
}
@ -10334,8 +10338,8 @@ void CreateCheckPoint(int flags)
* local oldest active xid may lower than oldestxmin,
* don't truncate it for safe.
*/
if (TransactionIdIsNormal(oldest_active_xid) && TransactionIdPrecedes(oldest_active_xid, cutoff_xid)) {
cutoff_xid = oldest_active_xid;
if (TransactionIdIsNormal(globalXmin) && TransactionIdPrecedes(globalXmin, cutoff_xid)) {
cutoff_xid = globalXmin;
}
TruncateCSNLOG(cutoff_xid);
t_thrd.checkpoint_cxt.last_truncate_log_time = now;

View File

@ -2038,12 +2038,18 @@ Datum pg_get_running_xacts(PG_FUNCTION_ARGS)
* simple as possible and leave GetSnapshotData() as the primary code for
* that bookkeeping.
*/
TransactionId GetOldestActiveTransactionId()
TransactionId GetOldestActiveTransactionId(TransactionId *globalXmin)
{
ProcArrayStruct* arrayP = g_instance.proc_array_idx;
TransactionId oldestRunningXid;
int index;
/* xmax is always latestCompletedXid + 1 */
TransactionId xmax = t_thrd.xact_cxt.ShmemVariableCache->latestCompletedXid;
Assert(TransactionIdIsNormal(xmax));
TransactionIdAdvance(xmax);
TransactionId xmin = xmax;
Assert(!RecoveryInProgress());
LWLockAcquire(ProcArrayLock, LW_SHARED);
@ -2065,6 +2071,12 @@ TransactionId GetOldestActiveTransactionId()
volatile PGXACT* pgxact = &g_instance.proc_base_all_xacts[pgprocno];
TransactionId xid;
/* Update globalxmin to be the smallest valid xmin */
xid = pgxact->xmin; /* fetch just once */
if (TransactionIdIsNormal(xid) && TransactionIdPrecedes(xid, xmin))
xmin = xid;
/* Fetch xid just once - see GetNewTransactionId */
xid = pgxact->xid;
@ -2083,6 +2095,15 @@ TransactionId GetOldestActiveTransactionId()
LWLockRelease(ProcArrayLock);
/*
* Update globalxmin to include actual process xids. This is a slightly
* different way of computing it than GetOldestXmin uses, but should give
* the same result.
*/
if (TransactionIdPrecedes(oldestRunningXid, xmin)) {
xmin = oldestRunningXid;
}
*globalXmin = xmin;
return oldestRunningXid;
}
@ -4054,12 +4075,6 @@ void CalculateLocalLatestSnapshot(bool forceCalc)
volatile PGXACT* pgxact = &g_instance.proc_base_all_xacts[pgprocno];
TransactionId xid;
/* Update globalxmin to be the smallest valid xmin */
xid = pgxact->xmin; /* fetch just once */
if (TransactionIdIsNormal(xid) && TransactionIdPrecedes(xid, globalxmin))
globalxmin = xid;
/*
* Backend is doing logical decoding which manages xmin
* separately, check below.
@ -4071,6 +4086,12 @@ void CalculateLocalLatestSnapshot(bool forceCalc)
if (pgxact->vacuumFlags & PROC_IN_VACUUM)
continue;
/* Update globalxmin to be the smallest valid xmin */
xid = pgxact->xmin; /* fetch just once */
if (TransactionIdIsNormal(xid) && TransactionIdPrecedes(xid, globalxmin))
globalxmin = xid;
/* Fetch xid just once - see GetNewTransactionId */
xid = pgxact->xid;

View File

@ -62,7 +62,7 @@ extern bool TransactionIdIsActive(TransactionId xid);
extern TransactionId GetRecentGlobalXmin(void);
extern TransactionId GetOldestXmin(Relation rel, bool bFixRecentGlobalXmin = false);
extern void CheckCurrentTimeline(GTM_Timeline timeline);
extern TransactionId GetOldestActiveTransactionId(void);
extern TransactionId GetOldestActiveTransactionId(TransactionId *globalXmin);
extern void FixCurrentSnapshotByGxid(TransactionId gxid);
extern void CheckSnapshotIsValidException(Snapshot snapshot, const char* location);
extern TransactionId GetOldestSafeDecodingTransactionId(bool catalogOnly);