1
0
mirror of https://github.com/postgres/postgres.git synced 2025-10-25 13:17:41 +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

@@ -370,6 +370,49 @@ FullTransactionIdNewer(FullTransactionId a, FullTransactionId b)
return b;
}
/*
* Compute FullTransactionId for the given TransactionId, assuming xid was
* between [oldestXid, nextXid] at the time when TransamVariables->nextXid was
* nextFullXid. When adding calls, evaluate what prevents xid from preceding
* oldestXid if SetTransactionIdLimit() runs between the collection of xid and
* the collection of nextFullXid.
*/
static inline FullTransactionId
FullTransactionIdFromAllowableAt(FullTransactionId nextFullXid,
TransactionId xid)
{
uint32 epoch;
/* Special transaction ID. */
if (!TransactionIdIsNormal(xid))
return FullTransactionIdFromEpochAndXid(0, xid);
Assert(TransactionIdPrecedesOrEquals(xid,
XidFromFullTransactionId(nextFullXid)));
/*
* The 64 bit result must be <= nextFullXid, since nextFullXid hadn't been
* issued yet when xid was in the past. The xid must therefore be from
* the epoch of nextFullXid or the epoch before. We know this because we
* must remove (by freezing) an XID before assigning the XID half an epoch
* ahead of it.
*
* The unlikely() branch hint is dubious. It's perfect for the first 2^32
* XIDs of a cluster's life. Right at 2^32 XIDs, misprediction shoots to
* 100%, then improves until perfection returns 2^31 XIDs later. Since
* current callers pass relatively-recent XIDs, expect >90% prediction
* accuracy overall. This favors average latency over tail latency.
*/
epoch = EpochFromFullTransactionId(nextFullXid);
if (unlikely(xid > XidFromFullTransactionId(nextFullXid)))
{
Assert(epoch != 0);
epoch--;
}
return FullTransactionIdFromEpochAndXid(epoch, xid);
}
#endif /* FRONTEND */
#endif /* TRANSAM_H */