73#define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var))))
339#define xc_by_recent_xmin_inc() (xc_by_recent_xmin++)
340#define xc_by_known_xact_inc() (xc_by_known_xact++)
341#define xc_by_my_xact_inc() (xc_by_my_xact++)
342#define xc_by_latest_xid_inc() (xc_by_latest_xid++)
343#define xc_by_main_xid_inc() (xc_by_main_xid++)
344#define xc_by_child_xid_inc() (xc_by_child_xid++)
345#define xc_by_known_assigned_inc() (xc_by_known_assigned++)
346#define xc_no_overflow_inc() (xc_no_overflow++)
347#define xc_slow_answer_inc() (xc_slow_answer++)
352#define xc_by_recent_xmin_inc() ((void) 0)
353#define xc_by_known_xact_inc() ((void) 0)
354#define xc_by_my_xact_inc() ((void) 0)
355#define xc_by_latest_xid_inc() ((void) 0)
356#define xc_by_main_xid_inc() ((void) 0)
357#define xc_by_child_xid_inc() ((void) 0)
358#define xc_by_known_assigned_inc() ((void) 0)
359#define xc_no_overflow_inc() ((void) 0)
360#define xc_slow_answer_inc() ((void) 0)
395#define PROCARRAY_MAXPROCS (MaxBackends + max_prepared_xacts)
410#define TOTAL_MAX_CACHED_SUBXIDS \
411 ((PGPROC_MAX_CACHED_SUBXIDS + 1) * PROCARRAY_MAXPROCS)
484 errmsg(
"sorry, too many clients already")));
611 &
arrayP->pgprocnos[myoff + 1],
883 nextproc->procArrayGroupMember =
false;
1116 "recovery snapshots are now enabled");
1120 "recovery snapshot waiting for non-overflowed snapshot or "
1121 "until oldest active xid on standby is at least %u (now %u)",
1175 xids[
nxids++] = xid;
1183 elog(
ERROR,
"KnownAssignedXids is not empty");
1207 "found duplicated transaction %u for KnownAssignedXids insertion",
1295 elog(
DEBUG1,
"recovery snapshots are now enabled");
1298 "recovery snapshot waiting for non-overflowed snapshot or "
1299 "until oldest active xid on standby is at least %u (now %u)",
1456 errmsg(
"out of memory")));
1468 latestCompletedXid =
1479 numProcs =
arrayP->numProcs;
1480 for (
int pgxactoff = 0; pgxactoff < numProcs; pgxactoff++)
1519 pgprocno =
arrayP->pgprocnos[pgxactoff];
1953 return horizons.shared_oldest_nonremovable;
1955 return horizons.catalog_oldest_nonremovable;
1957 return horizons.data_oldest_nonremovable;
1959 return horizons.temp_oldest_nonremovable;
1979 return horizons.oldest_considered_running;
1998 *xmin =
horizons.shared_oldest_nonremovable_raw;
1999 *catalog_xmin =
horizons.slot_catalog_xmin;
2076 snapshot->
copied =
false;
2122 bool suboverflowed =
false;
2156 errmsg(
"out of memory")));
2163 errmsg(
"out of memory")));
2202 int numProcs =
arrayP->numProcs;
2204 int *pgprocnos =
arrayP->pgprocnos;
2212 for (
int pgxactoff = 0; pgxactoff < numProcs; pgxactoff++)
2283 if (subxidStates[pgxactoff].overflowed)
2284 suboverflowed =
true;
2291 int pgprocno = pgprocnos[pgxactoff];
2340 suboverflowed =
true;
2440 snapshot->
xmin = xmin;
2441 snapshot->
xmax = xmax;
2442 snapshot->
xcnt = count;
2455 snapshot->
copied =
false;
2668 errmsg(
"out of memory")));
2674 suboverflowed =
false;
2683 latestCompletedXid =
2685 oldestDatabaseRunningXid = oldestRunningXid =
2723 oldestRunningXid = xid;
2736 oldestDatabaseRunningXid = xid;
2740 suboverflowed =
true;
2750 xids[count++] = xid;
2889 oldestRunningXid = xid;
2899 return oldestRunningXid;
3042 vxids[count++] = vxid;
3141 *overflowed =
false;
3205 if (proc->
pid == pid)
3342 vxids[count++] = vxid;
3408 errmsg(
"out of memory")));
3443 vxids[count++] = vxid;
3477 if (proc->
pid == pid)
3635 return count >= min;
3720 if (proc->
roleId == roleid)
3759#define MAXAUTOVACPIDS 10
3768#ifdef USE_INJECTION_POINTS
3773 for (
int tries = 0; tries <
ntries; tries++)
3859 int pgprocno =
arrayP->pgprocnos[
i];
3878 errmsg(
"database \"%s\" is being used by prepared transactions",
3881 "There are %d prepared transactions using the database.",
3914 errmsg(
"permission denied to terminate process"),
3915 errdetail(
"Only roles with the %s attribute may terminate processes of roles with the %s attribute.",
3916 "SUPERUSER",
"SUPERUSER")));
3922 errmsg(
"permission denied to terminate process"),
3923 errdetail(
"Only roles with privileges of the role whose process is being terminated or with privileges of the \"%s\" role may terminate this process.",
3924 "pg_signal_backend")));
3977 elog(
DEBUG1,
"xmin required by slots: data %u, catalog %u",
3978 xmin, catalog_xmin);
3996 if (catalog_xmin !=
NULL)
4082 elog(
WARNING,
"did not find subXID %u in MyProc", xid);
4093#ifdef XIDCACHE_DEBUG
4102 "XidCache: xmin: %ld, known: %ld, myxact: %ld, latest: %ld, mainxid: %ld, childxid: %ld, knownassigned: %ld, nooflo: %ld, slow: %ld\n",
4178 state->definitely_needed))
4190 horizons->shared_oldest_nonremovable);
4193 horizons->catalog_oldest_nonremovable);
4196 horizons->data_oldest_nonremovable);
4199 horizons->temp_oldest_nonremovable);
4462 elog(
DEBUG4,
"record known xact %u latestObservedXid %u",
4732#define KAX_COMPRESS_FREQUENCY 128
4733#define KAX_COMPRESS_IDLE_INTERVAL 1000
4740 tail =
pArray->tailKnownAssignedXids;
4741 nelements = head - tail;
4749 if (nelements ==
pArray->numKnownAssignedXids)
4802 for (
i = tail;
i < head;
i++)
4813 pArray->tailKnownAssignedXids = 0;
4869 head =
pArray->headKnownAssignedXids;
4870 tail =
pArray->tailKnownAssignedXids;
4884 elog(
ERROR,
"out-of-order XID insertion in KnownAssignedXids");
4894 head =
pArray->headKnownAssignedXids;
4901 elog(
ERROR,
"too many KnownAssignedXids");
4926 pArray->headKnownAssignedXids = head;
4949 head =
pArray->headKnownAssignedXids;
4964 while (first <= last)
4993 pArray->numKnownAssignedXids--;
5008 pArray->headKnownAssignedXids = 0;
5009 pArray->tailKnownAssignedXids = 0;
5013 pArray->tailKnownAssignedXids = tail;
5044 elog(
DEBUG4,
"remove KnownAssignedXid %u", xid);
5098 elog(
DEBUG4,
"removing all KnownAssignedXids");
5099 pArray->numKnownAssignedXids = 0;
5100 pArray->headKnownAssignedXids =
pArray->tailKnownAssignedXids = 0;
5110 tail =
pArray->tailKnownAssignedXids;
5111 head =
pArray->headKnownAssignedXids;
5113 for (
i = tail;
i < head;
i++)
5130 pArray->numKnownAssignedXids -= count;
5136 for (
i = tail;
i < head;
i++)
5144 pArray->headKnownAssignedXids = 0;
5145 pArray->tailKnownAssignedXids = 0;
5149 pArray->tailKnownAssignedXids =
i;
5200 for (
i = tail;
i < head;
i++)
5250 for (
i = tail;
i < head;
i++)
5280 tail =
pArray->tailKnownAssignedXids;
5281 head =
pArray->headKnownAssignedXids;
5285 for (
i = tail;
i < head;
i++)
5296 pArray->numKnownAssignedXids,
5297 pArray->tailKnownAssignedXids,
5298 pArray->headKnownAssignedXids,
5315 pArray->numKnownAssignedXids = 0;
5316 pArray->tailKnownAssignedXids = 0;
5317 pArray->headKnownAssignedXids = 0;
bool has_privs_of_role(Oid member, Oid role)
static bool pg_atomic_compare_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 *expected, uint32 newval)
static uint32 pg_atomic_fetch_or_u32(volatile pg_atomic_uint32 *ptr, uint32 or_)
#define pg_read_barrier()
#define pg_write_barrier()
static void pg_atomic_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
static uint32 pg_atomic_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 newval)
TimestampTz GetCurrentTimestamp(void)
void TerminateBackgroundWorkersForDatabase(Oid databaseId)
#define Assert(condition)
#define FLEXIBLE_ARRAY_MEMBER
#define OidIsValid(objectId)
bool IsCatalogRelation(Relation relation)
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
#define fprintf(file, fmt, msg)
int errcode(int sqlerrcode)
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ereport(elevel,...)
int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...) pg_attribute_printf(1
#define palloc_array(type, count)
#define IS_INJECTION_POINT_ATTACHED(name)
List * lappend_int(List *list, int datum)
#define VirtualTransactionIdIsValid(vxid)
#define GET_VXID_FROM_PGPROC(vxid_dst, proc)
#define InvalidLocalTransactionId
#define VirtualTransactionIdEquals(vxid1, vxid2)
char * get_database_name(Oid dbid)
bool LWLockHeldByMe(LWLock *lock)
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
bool LWLockHeldByMeInMode(LWLock *lock, LWLockMode mode)
void LWLockRelease(LWLock *lock)
bool LWLockConditionalAcquire(LWLock *lock, LWLockMode mode)
void pfree(void *pointer)
#define AmStartupProcess()
#define IsBootstrapProcessingMode()
#define CHECK_FOR_INTERRUPTS()
static bool pg_lfind32(uint32 key, const uint32 *base, uint32 nelem)
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define qsort(a, b, c, d)
void PGSemaphoreUnlock(PGSemaphore sema)
void PGSemaphoreLock(PGSemaphore sema)
#define PROC_IN_LOGICAL_DECODING
#define NUM_AUXILIARY_PROCS
#define DELAY_CHKPT_IN_COMMIT
#define PROC_AFFECTS_ALL_HORIZONS
#define GetPGProcByNumber(n)
#define GetNumberFromPGProc(proc)
#define PROC_VACUUM_STATE_MASK
#define PROC_IS_AUTOVACUUM
@ KAX_STARTUP_PROCESS_IDLE
static GlobalVisState GlobalVisDataRels
TransactionId GetOldestNonRemovableTransactionId(Relation rel)
#define TOTAL_MAX_CACHED_SUBXIDS
static GlobalVisState GlobalVisSharedRels
void ProcArrayGetReplicationSlotXmin(TransactionId *xmin, TransactionId *catalog_xmin)
static GlobalVisState GlobalVisCatalogRels
RunningTransactions GetRunningTransactionData(Oid dbid)
VirtualTransactionId * GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0, bool allDbs, int excludeVacuum, int *nvxids)
bool SignalRecoveryConflictWithVirtualXID(VirtualTransactionId vxid, RecoveryConflictReason reason)
bool GlobalVisCheckRemovableFullXid(Relation rel, FullTransactionId fxid)
static void KnownAssignedXidsCompress(KAXCompressReason reason, bool haveLock)
TransactionId GetOldestSafeDecodingTransactionId(bool catalogOnly)
void XidCacheRemoveRunningXids(TransactionId xid, int nxids, const TransactionId *xids, TransactionId latestXid)
static FullTransactionId FullXidRelativeTo(FullTransactionId rel, TransactionId xid)
bool MinimumActiveBackends(int min)
void TerminateOtherDBBackends(Oid databaseId)
#define xc_no_overflow_inc()
static TransactionId standbySnapshotPendingXmin
void ExpireAllKnownAssignedTransactionIds(void)
#define UINT32_ACCESS_ONCE(var)
static void KnownAssignedXidsRemoveTree(TransactionId xid, int nsubxids, TransactionId *subxids)
static int KnownAssignedXidsGetAndSetXmin(TransactionId *xarray, TransactionId *xmin, TransactionId xmax)
#define xc_by_recent_xmin_inc()
void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
void ProcNumberGetTransactionIds(ProcNumber procNumber, TransactionId *xid, TransactionId *xmin, int *nsubxid, bool *overflowed)
void RecordKnownAssignedTransactionIds(TransactionId xid)
static int KnownAssignedXidsGet(TransactionId *xarray, TransactionId xmax)
TransactionId GetOldestTransactionIdConsideredRunning(void)
static TransactionId latestObservedXid
static ProcArrayStruct * procArray
int GetMaxSnapshotSubxidCount(void)
int CountDBConnections(Oid databaseid)
static GlobalVisState GlobalVisTempRels
#define xc_by_my_xact_inc()
#define xc_by_known_assigned_inc()
static void ProcArrayShmemInit(void *arg)
#define PROCARRAY_MAXPROCS
void GetReplicationHorizons(TransactionId *xmin, TransactionId *catalog_xmin)
static bool GlobalVisTestShouldUpdate(GlobalVisState *state)
static void ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId latestXid)
static void KnownAssignedXidsRemovePreceding(TransactionId removeXid)
void ProcArrayAdd(PGPROC *proc)
static TransactionId * KnownAssignedXids
#define xc_by_child_xid_inc()
Snapshot GetSnapshotData(Snapshot snapshot)
const struct ShmemCallbacks ProcArrayShmemCallbacks
static bool * KnownAssignedXidsValid
bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
static void KnownAssignedXidsRemove(TransactionId xid)
void SignalRecoveryConflictWithDatabase(Oid databaseid, RecoveryConflictReason reason)
void KnownAssignedTransactionIdsIdleMaintenance(void)
static void GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons)
int GetMaxSnapshotXidCount(void)
static void ProcArrayShmemRequest(void *arg)
int CountDBBackends(Oid databaseid)
PGPROC * BackendPidGetProcWithLock(int pid)
static void ProcArrayShmemAttach(void *arg)
bool GlobalVisCheckRemovableXid(Relation rel, TransactionId xid)
PGPROC * BackendPidGetProc(int pid)
bool ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc)
PGPROC * ProcNumberGetProc(ProcNumber procNumber)
#define KAX_COMPRESS_FREQUENCY
GlobalVisState * GlobalVisTestFor(Relation rel)
bool GlobalVisTestIsRemovableXid(GlobalVisState *state, TransactionId xid, bool allow_update)
static TransactionId KnownAssignedXidsGetOldestXmin(void)
bool GlobalVisTestXidConsideredRunning(GlobalVisState *state, TransactionId xid, bool allow_update)
void ProcArrayApplyRecoveryInfo(RunningTransactions running)
void ProcArrayClearTransaction(PGPROC *proc)
int CountUserBackends(Oid roleid)
static TransactionId ComputeXidHorizonsResultLastXmin
static void GlobalVisUpdate(void)
#define xc_slow_answer_inc()
static void KnownAssignedXidsDisplay(int trace_level)
#define xc_by_main_xid_inc()
static void MaintainLatestCompletedXidRecovery(TransactionId latestXid)
static void ComputeXidHorizons(ComputeXidHorizonsResult *h)
void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)
static bool KnownAssignedXidExists(TransactionId xid)
bool GlobalVisTestIsRemovableFullXid(GlobalVisState *state, FullTransactionId fxid, bool allow_update)
TransactionId GetOldestActiveTransactionId(bool inCommitOnly, bool allDbs)
bool CountOtherDBBackends(Oid databaseId, int *nbackends, int *nprepared)
int BackendXidGetPid(TransactionId xid)
#define xc_by_latest_xid_inc()
bool IsBackendPid(int pid)
#define xc_by_known_xact_inc()
static bool KnownAssignedXidsSearch(TransactionId xid, bool remove)
static void KnownAssignedXidsReset(void)
static GlobalVisHorizonKind GlobalVisHorizonKindForRel(Relation rel)
void ProcArraySetReplicationSlotXmin(TransactionId xmin, TransactionId catalog_xmin, bool already_locked)
void ProcArrayInitRecovery(TransactionId initializedUptoXID)
void ProcArrayRemove(PGPROC *proc, TransactionId latestXid)
#define KAX_COMPRESS_IDLE_INTERVAL
VirtualTransactionId * GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
static void MaintainLatestCompletedXid(TransactionId latestXid)
static void ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid)
void ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids, TransactionId *subxids, TransactionId max_xid)
bool SignalRecoveryConflict(PGPROC *proc, pid_t pid, RecoveryConflictReason reason)
VirtualTransactionId * GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
static TransactionId cachedXidIsNotInProgress
bool ProcArrayInstallImportedXmin(TransactionId xmin, VirtualTransactionId *sourcevxid)
static bool GetSnapshotDataReuse(Snapshot snapshot)
static void KnownAssignedXidsAdd(TransactionId from_xid, TransactionId to_xid, bool exclusive_lock)
bool TransactionIdIsInProgress(TransactionId xid)
void ExpireOldKnownAssignedTransactionIds(TransactionId xid)
#define INVALID_PROC_NUMBER
int SendProcSignal(pid_t pid, ProcSignalReason reason, ProcNumber procNumber)
@ PROCSIG_RECOVERY_CONFLICT
#define RELATION_IS_LOCAL(relation)
#define RelationIsAccessibleInLogicalDecoding(relation)
Size add_size(Size s1, Size s2)
Size mul_size(Size s1, Size s2)
#define ShmemRequestStruct(...)
void pg_usleep(long microsec)
TransactionId TransactionXmin
void StandbyReleaseOldLocks(TransactionId oldxid)
void appendStringInfo(StringInfo str, const char *fmt,...)
void initStringInfo(StringInfo str)
TransactionId slot_catalog_xmin
TransactionId data_oldest_nonremovable
TransactionId temp_oldest_nonremovable
TransactionId shared_oldest_nonremovable
TransactionId oldest_considered_running
FullTransactionId latest_completed
TransactionId catalog_oldest_nonremovable
TransactionId shared_oldest_nonremovable_raw
FullTransactionId definitely_needed
FullTransactionId maybe_needed
bool procArrayGroupMember
pg_atomic_uint32 procArrayGroupNext
XidCacheStatus subxidStatus
pg_atomic_uint32 pendingRecoveryConflicts
TransactionId procArrayGroupMemberXid
XidCacheStatus * subxidStates
TransactionId replication_slot_xmin
TransactionId replication_slot_catalog_xmin
int pgprocnos[FLEXIBLE_ARRAY_MEMBER]
TransactionId lastOverflowedXid
int tailKnownAssignedXids
int headKnownAssignedXids
TransactionId oldestRunningXid
TransactionId latestCompletedXid
subxids_array_status subxid_status
ShmemRequestCallback request_fn
uint64 snapXactCompletionCount
FullTransactionId latestCompletedXid
FullTransactionId nextXid
uint64 xactCompletionCount
LocalTransactionId localTransactionId
TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS]
void SubTransSetParent(TransactionId xid, TransactionId parent)
TransactionId SubTransGetTopmostTransaction(TransactionId xid)
void ExtendSUBTRANS(TransactionId newestXact)
bool superuser_arg(Oid roleid)
TransactionId TransactionIdLatest(TransactionId mainxid, int nxids, const TransactionId *xids)
bool TransactionIdDidCommit(TransactionId transactionId)
bool TransactionIdDidAbort(TransactionId transactionId)
static bool TransactionIdFollows(TransactionId id1, TransactionId id2)
#define FullTransactionIdIsNormal(x)
static FullTransactionId FullTransactionIdNewer(FullTransactionId a, FullTransactionId b)
#define TransactionIdRetreat(dest)
#define InvalidTransactionId
static void FullTransactionIdRetreat(FullTransactionId *dest)
#define U64FromFullTransactionId(x)
static bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2)
static FullTransactionId FullTransactionIdFromU64(uint64 value)
#define FullTransactionIdFollowsOrEquals(a, b)
static bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
#define AssertTransactionIdInAllowableRange(xid)
#define TransactionIdEquals(id1, id2)
#define NormalTransactionIdPrecedes(id1, id2)
#define XidFromFullTransactionId(x)
static void FullTransactionIdAdvance(FullTransactionId *dest)
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
#define TransactionIdAdvance(dest)
#define FullTransactionIdPrecedes(a, b)
#define FullTransactionIdIsValid(x)
static TransactionId TransactionIdOlder(TransactionId a, TransactionId b)
static bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
bool StandbyTransactionIdIsPrepared(TransactionId xid)
#define TimestampTzPlusMilliseconds(tz, ms)
void AdvanceNextFullTransactionIdPastXid(TransactionId xid)
TransamVariablesData * TransamVariables
static void pgstat_report_wait_start(uint32 wait_event_info)
static void pgstat_report_wait_end(void)
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
CommandId GetCurrentCommandId(bool used)
int xidLogicalComparator(const void *arg1, const void *arg2)
bool RecoveryInProgress(void)
HotStandbyState standbyState
@ STANDBY_SNAPSHOT_PENDING