1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-04 20:11:56 +03:00

Merge copies of converting an XID to a FullTransactionId.

Assume twophase.c is the performance-sensitive caller, and preserve its
choice of unlikely() branch hint.  Add some retrospective rationale for
that choice.  Back-patch to v17, for the next commit to use it.

Reviewed (in earlier versions) by Michael Paquier.

Discussion: https://postgr.es/m/17821-dd8c334263399284@postgresql.org
Discussion: https://postgr.es/m/20250116010051.f3.nmisch@google.com
This commit is contained in:
Noah Misch
2025-01-25 11:28:14 -08:00
parent 4f6ec3831d
commit 81772a495e
5 changed files with 77 additions and 93 deletions

View File

@@ -97,15 +97,11 @@ static bool
TransactionIdInRecentPast(FullTransactionId fxid, TransactionId *extracted_xid)
{
TransactionId xid = XidFromFullTransactionId(fxid);
uint32 now_epoch;
TransactionId now_epoch_next_xid;
FullTransactionId now_fullxid;
TransactionId oldest_xid;
FullTransactionId oldest_fxid;
TransactionId oldest_clog_xid;
FullTransactionId oldest_clog_fxid;
now_fullxid = ReadNextFullTransactionId();
now_epoch_next_xid = XidFromFullTransactionId(now_fullxid);
now_epoch = EpochFromFullTransactionId(now_fullxid);
if (extracted_xid != NULL)
*extracted_xid = xid;
@@ -135,52 +131,19 @@ TransactionIdInRecentPast(FullTransactionId fxid, TransactionId *extracted_xid)
/*
* If fxid is not older than TransamVariables->oldestClogXid, the relevant
* CLOG entry is guaranteed to still exist. Convert
* TransamVariables->oldestClogXid into a FullTransactionId to compare it
* with fxid. Determine the right epoch knowing that oldest_fxid
* shouldn't be more than 2^31 older than now_fullxid.
* CLOG entry is guaranteed to still exist.
*
* TransamVariables->oldestXid governs allowable XIDs. Usually,
* oldestClogXid==oldestXid. It's also possible for oldestClogXid to
* follow oldestXid, in which case oldestXid might advance after our
* ReadNextFullTransactionId() call. If oldestXid has advanced, that
* advancement reinstated the usual oldestClogXid==oldestXid. Whether or
* not that happened, oldestClogXid is allowable relative to now_fullxid.
*/
oldest_xid = TransamVariables->oldestClogXid;
Assert(TransactionIdPrecedesOrEquals(oldest_xid, now_epoch_next_xid));
if (oldest_xid <= now_epoch_next_xid)
{
oldest_fxid = FullTransactionIdFromEpochAndXid(now_epoch, oldest_xid);
}
else
{
Assert(now_epoch > 0);
oldest_fxid = FullTransactionIdFromEpochAndXid(now_epoch - 1, oldest_xid);
}
return !FullTransactionIdPrecedes(fxid, oldest_fxid);
}
/*
* Convert a TransactionId obtained from a snapshot held by the caller to a
* FullTransactionId. Use next_fxid as a reference FullTransactionId, so that
* we can compute the high order bits. It must have been obtained by the
* caller with ReadNextFullTransactionId() after the snapshot was created.
*/
static FullTransactionId
widen_snapshot_xid(TransactionId xid, FullTransactionId next_fxid)
{
TransactionId next_xid = XidFromFullTransactionId(next_fxid);
uint32 epoch = EpochFromFullTransactionId(next_fxid);
/* Special transaction ID. */
if (!TransactionIdIsNormal(xid))
return FullTransactionIdFromEpochAndXid(0, xid);
/*
* The 64 bit result must be <= next_fxid, since next_fxid hadn't been
* issued yet when the snapshot was created. Every TransactionId in the
* snapshot must therefore be from the same epoch as next_fxid, or the
* epoch before. We know this because next_fxid is never allow to get
* more than one epoch ahead of the TransactionIds in any snapshot.
*/
if (xid > next_xid)
epoch--;
return FullTransactionIdFromEpochAndXid(epoch, xid);
oldest_clog_xid = TransamVariables->oldestClogXid;
oldest_clog_fxid =
FullTransactionIdFromAllowableAt(now_fullxid, oldest_clog_xid);
return !FullTransactionIdPrecedes(fxid, oldest_clog_fxid);
}
/*
@@ -420,12 +383,18 @@ pg_current_snapshot(PG_FUNCTION_ARGS)
nxip = cur->xcnt;
snap = palloc(PG_SNAPSHOT_SIZE(nxip));
/* fill */
snap->xmin = widen_snapshot_xid(cur->xmin, next_fxid);
snap->xmax = widen_snapshot_xid(cur->xmax, next_fxid);
/*
* Fill. This is the current backend's active snapshot, so MyProc->xmin
* is <= all these XIDs. As long as that remains so, oldestXid can't
* advance past any of these XIDs. Hence, these XIDs remain allowable
* relative to next_fxid.
*/
snap->xmin = FullTransactionIdFromAllowableAt(next_fxid, cur->xmin);
snap->xmax = FullTransactionIdFromAllowableAt(next_fxid, cur->xmax);
snap->nxip = nxip;
for (i = 0; i < nxip; i++)
snap->xip[i] = widen_snapshot_xid(cur->xip[i], next_fxid);
snap->xip[i] =
FullTransactionIdFromAllowableAt(next_fxid, cur->xip[i]);
/*
* We want them guaranteed to be in ascending order. This also removes