From ff2c82596b61d848ae9450b27ffb09171129b59b Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Thu, 16 Jan 2025 15:00:46 -0800 Subject: [PATCH v10 4/5] Move GlobalVisState definition to snapmgr_internal.h. This commit expose the GlobalVisState struct in snapmgr_internal.h. This is a preparatory work for parallel vacuum heap scan. Author: Reviewed-by: Discussion: https://postgr.es/m/ Backpatch-through: --- src/backend/storage/ipc/procarray.c | 74 ---------------------- src/include/utils/snapmgr.h | 2 +- src/include/utils/snapmgr_internal.h | 91 ++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 75 deletions(-) create mode 100644 src/include/utils/snapmgr_internal.h diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 2e54c11f880..4813a07860d 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -99,80 +99,6 @@ typedef struct ProcArrayStruct int pgprocnos[FLEXIBLE_ARRAY_MEMBER]; } ProcArrayStruct; -/* - * State for the GlobalVisTest* family of functions. Those functions can - * e.g. be used to decide if a deleted row can be removed without violating - * MVCC semantics: If the deleted row's xmax is not considered to be running - * by anyone, the row can be removed. - * - * To avoid slowing down GetSnapshotData(), we don't calculate a precise - * cutoff XID while building a snapshot (looking at the frequently changing - * xmins scales badly). Instead we compute two boundaries while building the - * snapshot: - * - * 1) definitely_needed, indicating that rows deleted by XIDs >= - * definitely_needed are definitely still visible. - * - * 2) maybe_needed, indicating that rows deleted by XIDs < maybe_needed can - * definitely be removed - * - * When testing an XID that falls in between the two (i.e. XID >= maybe_needed - * && XID < definitely_needed), the boundaries can be recomputed (using - * ComputeXidHorizons()) to get a more accurate answer. This is cheaper than - * maintaining an accurate value all the time. - * - * As it is not cheap to compute accurate boundaries, we limit the number of - * times that happens in short succession. See GlobalVisTestShouldUpdate(). - * - * - * There are three backend lifetime instances of this struct, optimized for - * different types of relations. As e.g. a normal user defined table in one - * database is inaccessible to backends connected to another database, a test - * specific to a relation can be more aggressive than a test for a shared - * relation. Currently we track four different states: - * - * 1) GlobalVisSharedRels, which only considers an XID's - * effects visible-to-everyone if neither snapshots in any database, nor a - * replication slot's xmin, nor a replication slot's catalog_xmin might - * still consider XID as running. - * - * 2) GlobalVisCatalogRels, which only considers an XID's - * effects visible-to-everyone if neither snapshots in the current - * database, nor a replication slot's xmin, nor a replication slot's - * catalog_xmin might still consider XID as running. - * - * I.e. the difference to GlobalVisSharedRels is that - * snapshot in other databases are ignored. - * - * 3) GlobalVisDataRels, which only considers an XID's - * effects visible-to-everyone if neither snapshots in the current - * database, nor a replication slot's xmin consider XID as running. - * - * I.e. the difference to GlobalVisCatalogRels is that - * replication slot's catalog_xmin is not taken into account. - * - * 4) GlobalVisTempRels, which only considers the current session, as temp - * tables are not visible to other sessions. - * - * GlobalVisTestFor(relation) returns the appropriate state - * for the relation. - * - * The boundaries are FullTransactionIds instead of TransactionIds to avoid - * wraparound dangers. There e.g. would otherwise exist no procarray state to - * prevent maybe_needed to become old enough after the GetSnapshotData() - * call. - * - * The typedef is in the header. - */ -struct GlobalVisState -{ - /* XIDs >= are considered running by some backend */ - FullTransactionId definitely_needed; - - /* XIDs < are not considered to be running by any backend */ - FullTransactionId maybe_needed; -}; - /* * Result of ComputeXidHorizons(). */ diff --git a/src/include/utils/snapmgr.h b/src/include/utils/snapmgr.h index d346be71642..3b6fb603544 100644 --- a/src/include/utils/snapmgr.h +++ b/src/include/utils/snapmgr.h @@ -17,6 +17,7 @@ #include "utils/relcache.h" #include "utils/resowner.h" #include "utils/snapshot.h" +#include "utils/snapmgr_internal.h" extern PGDLLIMPORT bool FirstSnapshotSet; @@ -95,7 +96,6 @@ extern char *ExportSnapshot(Snapshot snapshot); * These live in procarray.c because they're intimately linked to the * procarray contents, but thematically they better fit into snapmgr.h. */ -typedef struct GlobalVisState GlobalVisState; extern GlobalVisState *GlobalVisTestFor(Relation rel); extern bool GlobalVisTestIsRemovableXid(GlobalVisState *state, TransactionId xid); extern bool GlobalVisTestIsRemovableFullXid(GlobalVisState *state, FullTransactionId fxid); diff --git a/src/include/utils/snapmgr_internal.h b/src/include/utils/snapmgr_internal.h new file mode 100644 index 00000000000..4363adf7f62 --- /dev/null +++ b/src/include/utils/snapmgr_internal.h @@ -0,0 +1,91 @@ +/*------------------------------------------------------------------------- + * + * snapmgr_internal.h + * This file contains declarations of structs for snapshot manager + * for internal use. + * + * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/snapmgr_internal.h + * + *------------------------------------------------------------------------- + */ +#ifndef SNAPMGR_INTERNAL_H +#define SNAPMGR_INTERNAL_H + +#include "access/transam.h" + +/* + * State for the GlobalVisTest* family of functions. Those functions can + * e.g. be used to decide if a deleted row can be removed without violating + * MVCC semantics: If the deleted row's xmax is not considered to be running + * by anyone, the row can be removed. + * + * To avoid slowing down GetSnapshotData(), we don't calculate a precise + * cutoff XID while building a snapshot (looking at the frequently changing + * xmins scales badly). Instead we compute two boundaries while building the + * snapshot: + * + * 1) definitely_needed, indicating that rows deleted by XIDs >= + * definitely_needed are definitely still visible. + * + * 2) maybe_needed, indicating that rows deleted by XIDs < maybe_needed can + * definitely be removed + * + * When testing an XID that falls in between the two (i.e. XID >= maybe_needed + * && XID < definitely_needed), the boundaries can be recomputed (using + * ComputeXidHorizons()) to get a more accurate answer. This is cheaper than + * maintaining an accurate value all the time. + * + * As it is not cheap to compute accurate boundaries, we limit the number of + * times that happens in short succession. See GlobalVisTestShouldUpdate(). + * + * + * There are three backend lifetime instances of this struct, optimized for + * different types of relations. As e.g. a normal user defined table in one + * database is inaccessible to backends connected to another database, a test + * specific to a relation can be more aggressive than a test for a shared + * relation. Currently we track four different states: + * + * 1) GlobalVisSharedRels, which only considers an XID's + * effects visible-to-everyone if neither snapshots in any database, nor a + * replication slot's xmin, nor a replication slot's catalog_xmin might + * still consider XID as running. + * + * 2) GlobalVisCatalogRels, which only considers an XID's + * effects visible-to-everyone if neither snapshots in the current + * database, nor a replication slot's xmin, nor a replication slot's + * catalog_xmin might still consider XID as running. + * + * I.e. the difference to GlobalVisSharedRels is that + * snapshot in other databases are ignored. + * + * 3) GlobalVisDataRels, which only considers an XID's + * effects visible-to-everyone if neither snapshots in the current + * database, nor a replication slot's xmin consider XID as running. + * + * I.e. the difference to GlobalVisCatalogRels is that + * replication slot's catalog_xmin is not taken into account. + * + * 4) GlobalVisTempRels, which only considers the current session, as temp + * tables are not visible to other sessions. + * + * GlobalVisTestFor(relation) returns the appropriate state + * for the relation. + * + * The boundaries are FullTransactionIds instead of TransactionIds to avoid + * wraparound dangers. There e.g. would otherwise exist no procarray state to + * prevent maybe_needed to become old enough after the GetSnapshotData() + * call. + */ +typedef struct GlobalVisState +{ + /* XIDs >= are considered running by some backend */ + FullTransactionId definitely_needed; + + /* XIDs < are not considered to be running by any backend */ + FullTransactionId maybe_needed; +} GlobalVisState; + +#endif /* SNAPMGR_INTERNAL_H */ -- 2.43.5