55 #include "utils/fmgroids.h"
151 bool skip_locked =
false;
155 bool disable_page_skipping =
false;
156 bool process_main =
true;
157 bool process_toast =
true;
159 bool skip_database_stats =
false;
160 bool only_database_stats =
false;
186 if (strcmp(opt->
defname,
"verbose") == 0)
188 else if (strcmp(opt->
defname,
"skip_locked") == 0)
190 else if (strcmp(opt->
defname,
"buffer_usage_limit") == 0)
194 char *vac_buffer_size;
207 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
208 errmsg(
"BUFFER_USAGE_LIMIT option must be 0 or between %d kB and %d kB",
210 hintmsg ?
errhint(
"%s",
_(hintmsg)) : 0));
217 (
errcode(ERRCODE_SYNTAX_ERROR),
222 else if (strcmp(opt->
defname,
"analyze") == 0)
224 else if (strcmp(opt->
defname,
"freeze") == 0)
226 else if (strcmp(opt->
defname,
"full") == 0)
228 else if (strcmp(opt->
defname,
"disable_page_skipping") == 0)
230 else if (strcmp(opt->
defname,
"index_cleanup") == 0)
246 else if (strcmp(opt->
defname,
"process_main") == 0)
248 else if (strcmp(opt->
defname,
"process_toast") == 0)
250 else if (strcmp(opt->
defname,
"truncate") == 0)
252 else if (strcmp(opt->
defname,
"parallel") == 0)
254 if (opt->
arg == NULL)
257 (
errcode(ERRCODE_SYNTAX_ERROR),
258 errmsg(
"parallel option requires a value between 0 and %d",
269 (
errcode(ERRCODE_SYNTAX_ERROR),
270 errmsg(
"parallel workers for vacuum must be between 0 and %d",
284 else if (strcmp(opt->
defname,
"skip_database_stats") == 0)
286 else if (strcmp(opt->
defname,
"only_database_stats") == 0)
290 (
errcode(ERRCODE_SYNTAX_ERROR),
316 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
317 errmsg(
"VACUUM FULL cannot be performed in parallel")));
327 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
328 errmsg(
"BUFFER_USAGE_LIMIT cannot be specified for VACUUM FULL")));
335 foreach(lc, vacstmt->
rels)
341 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
342 errmsg(
"ANALYZE option must be specified when a column list is provided")));
353 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
354 errmsg(
"VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL")));
360 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
361 errmsg(
"PROCESS_TOAST required with VACUUM FULL")));
369 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
370 errmsg(
"ONLY_DATABASE_STATS cannot be specified with a list of tables")));
378 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
379 errmsg(
"ONLY_DATABASE_STATS cannot be specified with other VACUUM options")));
448 vacuum(vacstmt->
rels, ¶ms, bstrategy, vac_context, isTopLevel);
480 static bool in_vacuum =
false;
482 const char *stmttype;
483 volatile bool in_outer_xact,
501 in_outer_xact =
false;
513 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
514 errmsg(
"%s cannot be executed from VACUUM or ANALYZE",
526 else if (relations !=
NIL)
531 foreach(lc, relations)
562 use_own_xacts =
true;
567 use_own_xacts =
true;
568 else if (in_outer_xact)
569 use_own_xacts =
false;
571 use_own_xacts =
true;
573 use_own_xacts =
false;
612 foreach(
cur, relations)
636 vrel->
va_cols, in_outer_xact, bstrategy);
717 !reltuple->relisshared) ||
726 (
errmsg(
"permission denied to vacuum \"%s\", skipping it",
739 (
errmsg(
"permission denied to analyze \"%s\", skipping it",
758 bool rel_lock =
true;
795 if (relation == NULL)
816 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
817 errmsg(
"skipping vacuum of \"%s\" --- lock not available",
822 errmsg(
"skipping vacuum of \"%s\" --- relation no longer exists",
837 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
838 errmsg(
"skipping analyze of \"%s\" --- lock not available",
843 errmsg(
"skipping analyze of \"%s\" --- relation no longer exists",
876 vacrels =
lappend(vacrels, vrel);
888 bool include_children;
889 bool is_partitioned_table;
917 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
918 errmsg(
"skipping vacuum of \"%s\" --- lock not available",
922 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
923 errmsg(
"skipping analyze of \"%s\" --- lock not available",
934 elog(
ERROR,
"cache lookup failed for relation %u", relid);
956 is_partitioned_table = (classForm->relkind == RELKIND_PARTITIONED_TABLE);
959 (
errmsg(
"VACUUM ONLY of partitioned table \"%s\" has no effect",
974 if (include_children)
979 foreach(part_lc, part_oids)
983 if (part_oid == relid)
1036 Oid relid = classForm->oid;
1043 if (classForm->relkind != RELKIND_RELATION &&
1044 classForm->relkind != RELKIND_MATVIEW &&
1045 classForm->relkind != RELKIND_PARTITIONED_TABLE)
1087 multixact_freeze_min_age,
1089 multixact_freeze_table_age,
1090 effective_multixact_freeze_max_age;
1093 aggressiveXIDCutoff;
1096 aggressiveMXIDCutoff;
1145 safeOldestMxact = nextMXID - effective_multixact_freeze_max_age;
1150 (
errmsg(
"cutoff for removing and freezing tuples is far in the past"),
1151 errhint(
"Close open transactions soon to avoid wraparound problems.\n"
1152 "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
1155 (
errmsg(
"cutoff for freezing multixacts is far in the past"),
1156 errhint(
"Close open transactions soon to avoid wraparound problems.\n"
1157 "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
1165 if (freeze_min_age < 0)
1168 Assert(freeze_min_age >= 0);
1184 if (multixact_freeze_min_age < 0)
1186 multixact_freeze_min_age =
Min(multixact_freeze_min_age,
1187 effective_multixact_freeze_max_age / 2);
1188 Assert(multixact_freeze_min_age >= 0);
1207 if (freeze_table_age < 0)
1210 Assert(freeze_table_age >= 0);
1211 aggressiveXIDCutoff = nextXID - freeze_table_age;
1215 aggressiveXIDCutoff))
1226 if (multixact_freeze_table_age < 0)
1228 multixact_freeze_table_age =
1229 Min(multixact_freeze_table_age,
1230 effective_multixact_freeze_max_age * 0.95);
1231 Assert(multixact_freeze_table_age >= 0);
1232 aggressiveMXIDCutoff = nextMXID - multixact_freeze_table_age;
1236 aggressiveMXIDCutoff))
1257 int skip_index_vacuum;
1316 double scanned_tuples)
1319 double old_rel_tuples = relation->
rd_rel->reltuples;
1321 double unscanned_pages;
1322 double total_tuples;
1325 if (scanned_pages >= total_pages)
1326 return scanned_tuples;
1342 if (old_rel_pages == total_pages &&
1343 scanned_pages < (
double) total_pages * 0.02)
1344 return old_rel_tuples;
1345 if (scanned_pages <= 1)
1346 return old_rel_tuples;
1352 if (old_rel_tuples < 0 || old_rel_pages == 0)
1353 return floor((scanned_tuples / scanned_pages) * total_pages + 0.5);
1361 old_density = old_rel_tuples / old_rel_pages;
1362 unscanned_pages = (double) total_pages - (
double) scanned_pages;
1363 total_tuples = old_density * unscanned_pages + scanned_tuples;
1364 return floor(total_tuples + 0.5);
1414 bool *frozenxid_updated,
bool *minmulti_updated,
1421 void *inplace_state;
1437 NULL, 1,
key, &ctup, &inplace_state);
1439 elog(
ERROR,
"pg_class entry for relid %u vanished during vacuuming",
1446 if (pgcform->relpages != (
int32) num_pages)
1448 pgcform->relpages = (
int32) num_pages;
1451 if (pgcform->reltuples != (
float4) num_tuples)
1453 pgcform->reltuples = (
float4) num_tuples;
1456 if (pgcform->relallvisible != (
int32) num_all_visible_pages)
1458 pgcform->relallvisible = (
int32) num_all_visible_pages;
1469 if (pgcform->relhasindex && !hasindex)
1471 pgcform->relhasindex =
false;
1476 if (pgcform->relhasrules && relation->
rd_rules == NULL)
1478 pgcform->relhasrules =
false;
1481 if (pgcform->relhastriggers && relation->
trigdesc == NULL)
1483 pgcform->relhastriggers =
false;
1498 oldfrozenxid = pgcform->relfrozenxid;
1500 if (frozenxid_updated)
1501 *frozenxid_updated =
false;
1504 bool update =
false;
1509 futurexid = update =
true;
1513 pgcform->relfrozenxid = frozenxid;
1515 if (frozenxid_updated)
1516 *frozenxid_updated =
true;
1521 oldminmulti = pgcform->relminmxid;
1523 if (minmulti_updated)
1524 *minmulti_updated =
false;
1527 bool update =
false;
1532 futuremxid = update =
true;
1536 pgcform->relminmxid = minmulti;
1538 if (minmulti_updated)
1539 *minmulti_updated =
true;
1554 errmsg_internal(
"overwrote invalid relfrozenxid value %u with new value %u for table \"%s\"",
1555 oldfrozenxid, frozenxid,
1560 errmsg_internal(
"overwrote invalid relminmxid value %u with new value %u for table \"%s\"",
1561 oldminmulti, minmulti,
1599 void *inplace_state;
1653 if (classForm->relkind != RELKIND_RELATION &&
1654 classForm->relkind != RELKIND_MATVIEW &&
1655 classForm->relkind != RELKIND_TOASTVALUE)
1690 newFrozenXid = relfrozenxid;
1704 newMinMulti = relminmxid;
1729 Anum_pg_database_oid,
1734 NULL, 1,
key, &tuple, &inplace_state);
1746 if (dbform->datfrozenxid != newFrozenXid &&
1750 dbform->datfrozenxid = newFrozenXid;
1754 newFrozenXid = dbform->datfrozenxid;
1757 if (dbform->datminmxid != newMinMulti &&
1761 dbform->datminmxid = newMinMulti;
1765 newMinMulti = dbform->datminmxid;
1782 lastSaneFrozenXid, lastSaneMinMulti);
1813 Oid oldestxid_datoid;
1814 Oid minmulti_datoid;
1816 bool frozenAlreadyWrapped =
false;
1865 "skipping invalid database \"%s\" while computing relfrozenxid",
1884 frozenAlreadyWrapped =
true;
1888 oldestxid_datoid = dbform->oid;
1894 minmulti_datoid = dbform->oid;
1908 if (frozenAlreadyWrapped)
1911 (
errmsg(
"some databases have not been vacuumed in over 2 billion transactions"),
1912 errdetail(
"You might have already suffered transaction-wraparound data loss.")));
1982 int save_sec_context;
2085 if (rel->
rd_rel->relkind != RELKIND_RELATION &&
2086 rel->
rd_rel->relkind != RELKIND_MATVIEW &&
2087 rel->
rd_rel->relkind != RELKIND_TOASTVALUE &&
2088 rel->
rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
2091 (
errmsg(
"skipping \"%s\" --- cannot vacuum non-tables or special system tables",
2119 if (rel->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2152 vacuum_index_cleanup =
2161 Assert(vacuum_index_cleanup ==
2189 toast_relid = rel->
rd_rel->reltoastrelid;
2267 memcpy(&toast_vacuum_params, params,
sizeof(
VacuumParams));
2271 vacuum_rel(toast_relid, NULL, &toast_vacuum_params, bstrategy);
2318 foreach(indexoidscan, indexoidlist)
2325 (*Irel)[
i++] = indrel;
2520 (
void *) dead_items);
2523 (
errmsg(
"scanned index \"%s\" to remove %lld row versions",
2525 (
long long) dead_items_info->
num_items)));
2542 (
errmsg(
"index \"%s\" now contains %.0f row versions in %u pages",
2546 errdetail(
"%.0f index row versions were removed.\n"
2547 "%u index pages were newly deleted.\n"
2548 "%u index pages are currently deleted, of which %u are currently reusable.",
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
static uint32 pg_atomic_sub_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 sub_)
static uint32 pg_atomic_add_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 add_)
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
void VacuumUpdateCosts(void)
int autovacuum_multixact_freeze_max_age
int autovacuum_freeze_max_age
void AutoVacuumUpdateCostLimit(void)
#define MAX_PARALLEL_WORKER_LIMIT
#define Assert(condition)
TransactionId MultiXactId
#define OidIsValid(objectId)
void TruncateCLOG(TransactionId oldestXact, Oid oldestxid_datoid)
void cluster_rel(Oid tableOid, Oid indexOid, ClusterParams *params)
void analyze_rel(Oid relid, RangeVar *relation, VacuumParams *params, List *va_cols, bool in_outer_xact, BufferAccessStrategy bstrategy)
void AdvanceOldestCommitTsXid(TransactionId oldestXact)
void TruncateCommitTs(TransactionId oldestXact)
bool database_is_invalid_form(Form_pg_database datform)
int32 defGetInt32(DefElem *def)
bool defGetBoolean(DefElem *def)
char * defGetString(DefElem *def)
int errmsg_internal(const char *fmt,...)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
BufferAccessStrategy GetAccessStrategyWithSize(BufferAccessStrategyType btype, int ring_size_kb)
void systable_endscan(SysScanDesc sysscan)
void systable_inplace_update_cancel(void *state)
void systable_inplace_update_begin(Relation relation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, const ScanKeyData *key, HeapTuple *oldtupcopy, void **state)
void systable_inplace_update_finish(void *state, HeapTuple tuple)
HeapTuple systable_getnext(SysScanDesc sysscan)
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
volatile sig_atomic_t InterruptPending
int VacuumBufferUsageLimit
bool parse_int(const char *value, int *result, int flags, const char **hintmsg)
int NewGUCNestLevel(void)
void RestrictSearchPath(void)
void AtEOXact_GUC(bool isCommit, int nestLevel)
#define GUC_check_errdetail
void ProcessConfigFile(GucContext context)
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
IndexBulkDeleteResult * index_vacuum_cleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *istat)
void index_close(Relation relation, LOCKMODE lockmode)
IndexBulkDeleteResult * index_bulk_delete(IndexVacuumInfo *info, IndexBulkDeleteResult *istat, IndexBulkDeleteCallback callback, void *callback_state)
Relation index_open(Oid relationId, LOCKMODE lockmode)
volatile sig_atomic_t ConfigReloadPending
List * lappend(List *list, void *datum)
void list_free(List *list)
List * list_concat(List *list1, const List *list2)
bool ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode)
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
void LockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
void UnlockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
void LockDatabaseFrozenIds(LOCKMODE lockmode)
#define AccessExclusiveLock
#define ShareUpdateExclusiveLock
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
void LWLockRelease(LWLock *lock)
VacuumRelation * makeVacuumRelation(RangeVar *relation, Oid oid, List *va_cols)
void pfree(void *pointer)
void MemoryContextDelete(MemoryContext context)
MemoryContext PortalContext
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define AmAutoVacuumWorkerProcess()
#define MIN_BAS_VAC_RING_SIZE_KB
#define MAX_BAS_VAC_RING_SIZE_KB
#define SECURITY_RESTRICTED_OPERATION
#define CHECK_FOR_INTERRUPTS()
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
void SetUserIdAndSecContext(Oid userid, int sec_context)
bool MultiXactIdPrecedes(MultiXactId multi1, MultiXactId multi2)
bool MultiXactIdPrecedesOrEquals(MultiXactId multi1, MultiXactId multi2)
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
MultiXactId GetOldestMultiXactId(void)
int MultiXactMemberFreezeThreshold(void)
MultiXactId ReadNextMultiXactId(void)
void TruncateMultiXact(MultiXactId newOldestMulti, Oid newOldestMultiDB)
#define MultiXactIdIsValid(multi)
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
int parser_errposition(ParseState *pstate, int location)
#define ERRCODE_DATA_CORRUPTED
FormData_pg_class * Form_pg_class
TransactionId datfrozenxid
FormData_pg_database * Form_pg_database
List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
#define lfirst_node(type, lc)
static int list_length(const List *l)
static rewind_source * source
#define ERRCODE_UNDEFINED_TABLE
#define PostmasterIsAlive()
int pg_strcasecmp(const char *s1, const char *s2)
static Datum ObjectIdGetDatum(Oid X)
#define PROC_VACUUM_FOR_WRAPAROUND
TransactionId GetOldestNonRemovableTransactionId(Relation rel)
MemoryContextSwitchTo(old_ctx)
static long analyze(struct nfa *nfa)
#define RelationGetRelid(relation)
#define RelationGetRelationName(relation)
#define RELATION_IS_OTHER_TEMP(relation)
@ STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO
@ STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF
@ STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON
List * RelationGetIndexList(Relation relation)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
void pg_usleep(long microsec)
Snapshot GetTransactionSnapshot(void)
void PushActiveSnapshot(Snapshot snapshot)
bool ActiveSnapshotSet(void)
void PopActiveSnapshot(void)
void relation_close(Relation relation, LOCKMODE lockmode)
Relation try_relation_open(Oid relationId, LOCKMODE lockmode)
#define BTEqualStrategyNumber
BlockNumber pages_deleted
BlockNumber pages_newly_deleted
TransactionId FreezeLimit
TransactionId relfrozenxid
MultiXactId MultiXactCutoff
int multixact_freeze_min_age
int multixact_freeze_table_age
VacOptValue index_cleanup
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
TableScanDesc table_beginscan_catalog(Relation relation, int nkeys, struct ScanKeyData *key)
static void table_endscan(TableScanDesc scan)
static void table_relation_vacuum(Relation rel, struct VacuumParams *params, BufferAccessStrategy bstrategy)
bool TidStoreIsMember(TidStore *ts, ItemPointer tid)
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2)
static TransactionId ReadNextTransactionId(void)
#define FirstNormalTransactionId
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
static bool vac_tid_reaped(ItemPointer itemptr, void *state)
void ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
IndexBulkDeleteResult * vac_bulkdel_one_index(IndexVacuumInfo *ivinfo, IndexBulkDeleteResult *istat, TidStore *dead_items, VacDeadItemsInfo *dead_items_info)
pg_atomic_uint32 * VacuumActiveNWorkers
static void vac_truncate_clog(TransactionId frozenXID, MultiXactId minMulti, TransactionId lastSaneFrozenXid, MultiXactId lastSaneMinMulti)
int vacuum_freeze_min_age
static List * expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, int options)
static double compute_parallel_delay(void)
static VacOptValue get_vacoptval_from_boolean(DefElem *def)
void vac_open_indexes(Relation relation, LOCKMODE lockmode, int *nindexes, Relation **Irel)
void vacuum(List *relations, VacuumParams *params, BufferAccessStrategy bstrategy, MemoryContext vac_context, bool isTopLevel)
bool check_vacuum_buffer_usage_limit(int *newval, void **extra, GucSource source)
int VacuumCostBalanceLocal
static List * get_all_vacuum_rels(MemoryContext vac_context, int options)
void vac_update_relstats(Relation relation, BlockNumber num_pages, double num_tuples, BlockNumber num_all_visible_pages, bool hasindex, TransactionId frozenxid, MultiXactId minmulti, bool *frozenxid_updated, bool *minmulti_updated, bool in_outer_xact)
int vacuum_multixact_freeze_table_age
int vacuum_freeze_table_age
int vacuum_multixact_failsafe_age
int vacuum_multixact_freeze_min_age
Relation vacuum_open_relation(Oid relid, RangeVar *relation, bits32 options, bool verbose, LOCKMODE lmode)
static bool vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, BufferAccessStrategy bstrategy)
void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode)
void vacuum_delay_point(void)
void vac_update_datfrozenxid(void)
bool vacuum_get_cutoffs(Relation rel, const VacuumParams *params, struct VacuumCutoffs *cutoffs)
bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs)
pg_atomic_uint32 * VacuumSharedCostBalance
bool VacuumFailsafeActive
double vac_estimate_reltuples(Relation relation, BlockNumber total_pages, BlockNumber scanned_pages, double scanned_tuples)
IndexBulkDeleteResult * vac_cleanup_one_index(IndexVacuumInfo *ivinfo, IndexBulkDeleteResult *istat)
bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, bits32 options)
#define VACOPT_SKIP_LOCKED
#define VACOPT_SKIP_DATABASE_STATS
@ VACOPTVALUE_UNSPECIFIED
#define VACOPT_PROCESS_TOAST
#define VACOPT_DISABLE_PAGE_SKIPPING
#define VACOPT_ONLY_DATABASE_STATS
#define VACOPT_PROCESS_MAIN
void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
bool ForceTransactionIdLimitUpdate(void)
static void pgstat_report_wait_start(uint32 wait_event_info)
static void pgstat_report_wait_end(void)
bool IsInTransactionBlock(bool isTopLevel)
void CommandCounterIncrement(void)
void PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
void StartTransactionCommand(void)
void CommitTransactionCommand(void)