57 #include "utils/fmgroids.h"
155 bool skip_locked =
false;
159 bool disable_page_skipping =
false;
160 bool process_main =
true;
161 bool process_toast =
true;
163 bool skip_database_stats =
false;
164 bool only_database_stats =
false;
187 if (strcmp(opt->
defname,
"verbose") == 0)
189 else if (strcmp(opt->
defname,
"skip_locked") == 0)
191 else if (strcmp(opt->
defname,
"buffer_usage_limit") == 0)
195 char *vac_buffer_size;
208 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
209 errmsg(
"BUFFER_USAGE_LIMIT option must be 0 or between %d kB and %d kB",
211 hintmsg ?
errhint(
"%s",
_(hintmsg)) : 0));
218 (
errcode(ERRCODE_SYNTAX_ERROR),
223 else if (strcmp(opt->
defname,
"analyze") == 0)
225 else if (strcmp(opt->
defname,
"freeze") == 0)
227 else if (strcmp(opt->
defname,
"full") == 0)
229 else if (strcmp(opt->
defname,
"disable_page_skipping") == 0)
231 else if (strcmp(opt->
defname,
"index_cleanup") == 0)
247 else if (strcmp(opt->
defname,
"process_main") == 0)
249 else if (strcmp(opt->
defname,
"process_toast") == 0)
251 else if (strcmp(opt->
defname,
"truncate") == 0)
253 else if (strcmp(opt->
defname,
"parallel") == 0)
255 if (opt->
arg == NULL)
258 (
errcode(ERRCODE_SYNTAX_ERROR),
259 errmsg(
"parallel option requires a value between 0 and %d",
270 (
errcode(ERRCODE_SYNTAX_ERROR),
271 errmsg(
"parallel workers for vacuum must be between 0 and %d",
285 else if (strcmp(opt->
defname,
"skip_database_stats") == 0)
287 else if (strcmp(opt->
defname,
"only_database_stats") == 0)
291 (
errcode(ERRCODE_SYNTAX_ERROR),
317 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
318 errmsg(
"VACUUM FULL cannot be performed in parallel")));
328 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
329 errmsg(
"BUFFER_USAGE_LIMIT cannot be specified for VACUUM FULL")));
336 foreach(lc, vacstmt->
rels)
342 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
343 errmsg(
"ANALYZE option must be specified when a column list is provided")));
354 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
355 errmsg(
"VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL")));
361 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
362 errmsg(
"PROCESS_TOAST required with VACUUM FULL")));
370 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
371 errmsg(
"ONLY_DATABASE_STATS cannot be specified with a list of tables")));
379 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
380 errmsg(
"ONLY_DATABASE_STATS cannot be specified with other VACUUM options")));
449 vacuum(vacstmt->
rels, ¶ms, bstrategy, vac_context, isTopLevel);
481 static bool in_vacuum =
false;
483 const char *stmttype;
484 volatile bool in_outer_xact,
502 in_outer_xact =
false;
514 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
515 errmsg(
"%s cannot be executed from VACUUM or ANALYZE",
527 else if (relations !=
NIL)
532 foreach(lc, relations)
563 use_own_xacts =
true;
568 use_own_xacts =
true;
569 else if (in_outer_xact)
570 use_own_xacts =
false;
572 use_own_xacts =
true;
574 use_own_xacts =
false;
616 foreach(
cur, relations)
640 vrel->
va_cols, in_outer_xact, bstrategy);
733 (
errmsg(
"permission denied to vacuum \"%s\", skipping it",
746 (
errmsg(
"permission denied to analyze \"%s\", skipping it",
765 bool rel_lock =
true;
802 if (relation == NULL)
823 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
824 errmsg(
"skipping vacuum of \"%s\" --- lock not available",
829 errmsg(
"skipping vacuum of \"%s\" --- relation no longer exists",
844 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
845 errmsg(
"skipping analyze of \"%s\" --- lock not available",
850 errmsg(
"skipping analyze of \"%s\" --- relation no longer exists",
883 vacrels =
lappend(vacrels, vrel);
920 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
921 errmsg(
"skipping vacuum of \"%s\" --- lock not available",
925 (
errcode(ERRCODE_LOCK_NOT_AVAILABLE),
926 errmsg(
"skipping analyze of \"%s\" --- lock not available",
937 elog(
ERROR,
"cache lookup failed for relation %u", relid);
954 include_parts = (classForm->relkind == RELKIND_PARTITIONED_TABLE);
971 foreach(part_lc, part_oids)
975 if (part_oid == relid)
1028 Oid relid = classForm->oid;
1035 if (classForm->relkind != RELKIND_RELATION &&
1036 classForm->relkind != RELKIND_MATVIEW &&
1037 classForm->relkind != RELKIND_PARTITIONED_TABLE)
1079 multixact_freeze_min_age,
1081 multixact_freeze_table_age,
1082 effective_multixact_freeze_max_age;
1085 aggressiveXIDCutoff;
1088 aggressiveMXIDCutoff;
1137 safeOldestMxact = nextMXID - effective_multixact_freeze_max_age;
1142 (
errmsg(
"cutoff for removing and freezing tuples is far in the past"),
1143 errhint(
"Close open transactions soon to avoid wraparound problems.\n"
1144 "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
1147 (
errmsg(
"cutoff for freezing multixacts is far in the past"),
1148 errhint(
"Close open transactions soon to avoid wraparound problems.\n"
1149 "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
1157 if (freeze_min_age < 0)
1160 Assert(freeze_min_age >= 0);
1176 if (multixact_freeze_min_age < 0)
1178 multixact_freeze_min_age =
Min(multixact_freeze_min_age,
1179 effective_multixact_freeze_max_age / 2);
1180 Assert(multixact_freeze_min_age >= 0);
1199 if (freeze_table_age < 0)
1202 Assert(freeze_table_age >= 0);
1203 aggressiveXIDCutoff = nextXID - freeze_table_age;
1207 aggressiveXIDCutoff))
1218 if (multixact_freeze_table_age < 0)
1220 multixact_freeze_table_age =
1221 Min(multixact_freeze_table_age,
1222 effective_multixact_freeze_max_age * 0.95);
1223 Assert(multixact_freeze_table_age >= 0);
1224 aggressiveMXIDCutoff = nextMXID - multixact_freeze_table_age;
1228 aggressiveMXIDCutoff))
1249 int skip_index_vacuum;
1308 double scanned_tuples)
1311 double old_rel_tuples = relation->
rd_rel->reltuples;
1313 double unscanned_pages;
1314 double total_tuples;
1317 if (scanned_pages >= total_pages)
1318 return scanned_tuples;
1334 if (old_rel_pages == total_pages &&
1335 scanned_pages < (
double) total_pages * 0.02)
1336 return old_rel_tuples;
1337 if (scanned_pages <= 1)
1338 return old_rel_tuples;
1344 if (old_rel_tuples < 0 || old_rel_pages == 0)
1345 return floor((scanned_tuples / scanned_pages) * total_pages + 0.5);
1353 old_density = old_rel_tuples / old_rel_pages;
1354 unscanned_pages = (double) total_pages - (
double) scanned_pages;
1355 total_tuples = old_density * unscanned_pages + scanned_tuples;
1356 return floor(total_tuples + 0.5);
1406 bool *frozenxid_updated,
bool *minmulti_updated,
1424 elog(
ERROR,
"pg_class entry for relid %u vanished during vacuuming",
1431 if (pgcform->relpages != (
int32) num_pages)
1433 pgcform->relpages = (
int32) num_pages;
1436 if (pgcform->reltuples != (
float4) num_tuples)
1438 pgcform->reltuples = (
float4) num_tuples;
1441 if (pgcform->relallvisible != (
int32) num_all_visible_pages)
1443 pgcform->relallvisible = (
int32) num_all_visible_pages;
1454 if (pgcform->relhasindex && !hasindex)
1456 pgcform->relhasindex =
false;
1461 if (pgcform->relhasrules && relation->
rd_rules == NULL)
1463 pgcform->relhasrules =
false;
1466 if (pgcform->relhastriggers && relation->
trigdesc == NULL)
1468 pgcform->relhastriggers =
false;
1483 oldfrozenxid = pgcform->relfrozenxid;
1485 if (frozenxid_updated)
1486 *frozenxid_updated =
false;
1489 bool update =
false;
1494 futurexid = update =
true;
1498 pgcform->relfrozenxid = frozenxid;
1500 if (frozenxid_updated)
1501 *frozenxid_updated =
true;
1506 oldminmulti = pgcform->relminmxid;
1508 if (minmulti_updated)
1509 *minmulti_updated =
false;
1512 bool update =
false;
1517 futuremxid = update =
true;
1521 pgcform->relminmxid = minmulti;
1523 if (minmulti_updated)
1524 *minmulti_updated =
true;
1537 errmsg_internal(
"overwrote invalid relfrozenxid value %u with new value %u for table \"%s\"",
1538 oldfrozenxid, frozenxid,
1543 errmsg_internal(
"overwrote invalid relminmxid value %u with new value %u for table \"%s\"",
1544 oldminmulti, minmulti,
1631 if (classForm->relkind != RELKIND_RELATION &&
1632 classForm->relkind != RELKIND_MATVIEW &&
1633 classForm->relkind != RELKIND_TOASTVALUE)
1668 newFrozenXid = classForm->relfrozenxid;
1682 newMinMulti = classForm->relminmxid;
1706 Anum_pg_database_oid,
1726 if (dbform->datfrozenxid != newFrozenXid &&
1730 dbform->datfrozenxid = newFrozenXid;
1734 newFrozenXid = dbform->datfrozenxid;
1737 if (dbform->datminmxid != newMinMulti &&
1741 dbform->datminmxid = newMinMulti;
1745 newMinMulti = dbform->datminmxid;
1760 lastSaneFrozenXid, lastSaneMinMulti);
1791 Oid oldestxid_datoid;
1792 Oid minmulti_datoid;
1794 bool frozenAlreadyWrapped =
false;
1843 "skipping invalid database \"%s\" while computing relfrozenxid",
1862 frozenAlreadyWrapped =
true;
1866 oldestxid_datoid = dbform->oid;
1872 minmulti_datoid = dbform->oid;
1886 if (frozenAlreadyWrapped)
1889 (
errmsg(
"some databases have not been vacuumed in over 2 billion transactions"),
1890 errdetail(
"You might have already suffered transaction-wraparound data loss.")));
1959 int save_sec_context;
2053 if (rel->
rd_rel->relkind != RELKIND_RELATION &&
2054 rel->
rd_rel->relkind != RELKIND_MATVIEW &&
2055 rel->
rd_rel->relkind != RELKIND_TOASTVALUE &&
2056 rel->
rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
2059 (
errmsg(
"skipping \"%s\" --- cannot vacuum non-tables or special system tables",
2087 if (rel->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2120 vacuum_index_cleanup =
2129 Assert(vacuum_index_cleanup ==
2157 toast_relid = rel->
rd_rel->reltoastrelid;
2229 memcpy(&toast_vacuum_params, params,
sizeof(
VacuumParams));
2232 vacuum_rel(toast_relid, NULL, &toast_vacuum_params, bstrategy);
2279 foreach(indexoidscan, indexoidlist)
2286 (*Irel)[
i++] = indrel;
2481 (
void *) dead_items);
2484 (
errmsg(
"scanned index \"%s\" to remove %d row versions",
2503 (
errmsg(
"index \"%s\" now contains %.0f row versions in %u pages",
2507 errdetail(
"%.0f index row versions were removed.\n"
2508 "%u index pages were newly deleted.\n"
2509 "%u index pages are currently deleted, of which %u are currently reusable.",
2555 if (item < litem || item > ritem)
2564 return (
res != NULL);
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
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
bool IsAutoVacuumWorkerProcess(void)
void AutoVacuumUpdateCostLimit(void)
#define MAX_PARALLEL_WORKER_LIMIT
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)
static void PGresult * res
elog(ERROR, "%s: %s", p2, msg)
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)
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 AtEOXact_GUC(bool isCommit, int nestLevel)
#define GUC_check_errdetail
void ProcessConfigFile(GucContext context)
void heap_inplace_update(Relation relation, HeapTuple tuple)
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
HeapTuple heap_copytuple(HeapTuple tuple)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
static int64 itemptr_encode(ItemPointer itemptr)
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
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
ItemPointerData * ItemPointer
struct ItemPointerData ItemPointerData
Assert(fmt[strlen(fmt) - 1] !='\n')
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 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)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
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)
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
ItemPointerData items[FLEXIBLE_ARRAY_MEMBER]
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)
#define SearchSysCacheCopy1(cacheId, 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 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)
IndexBulkDeleteResult * vac_bulkdel_one_index(IndexVacuumInfo *ivinfo, IndexBulkDeleteResult *istat, VacDeadItems *dead_items)
void ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
pg_atomic_uint32 * VacuumActiveNWorkers
static void vac_truncate_clog(TransactionId frozenXID, MultiXactId minMulti, TransactionId lastSaneFrozenXid, MultiXactId lastSaneMinMulti)
Size vac_max_items_to_alloc_size(int max_items)
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)
bool vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, bits32 options)
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)
static int vac_cmp_itemptr(const void *left, const void *right)
#define VACOPT_SKIP_LOCKED
#define MAXDEADITEMS(avail_mem)
#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)