| 1 | /*------------------------------------------------------------------------- |
| 2 | * |
| 3 | * snapmgr.h |
| 4 | * POSTGRES snapshot manager |
| 5 | * |
| 6 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
| 7 | * Portions Copyright (c) 1994, Regents of the University of California |
| 8 | * |
| 9 | * src/include/utils/snapmgr.h |
| 10 | * |
| 11 | *------------------------------------------------------------------------- |
| 12 | */ |
| 13 | #ifndef SNAPMGR_H |
| 14 | #define SNAPMGR_H |
| 15 | |
| 16 | #include "access/transam.h" |
| 17 | #include "fmgr.h" |
| 18 | #include "utils/relcache.h" |
| 19 | #include "utils/resowner.h" |
| 20 | #include "utils/snapshot.h" |
| 21 | |
| 22 | |
| 23 | /* |
| 24 | * The structure used to map times to TransactionId values for the "snapshot |
| 25 | * too old" feature must have a few entries at the tail to hold old values; |
| 26 | * otherwise the lookup will often fail and the expected early pruning or |
| 27 | * vacuum will not usually occur. It is best if this padding is for a number |
| 28 | * of minutes greater than a thread would normally be stalled, but it's OK if |
| 29 | * early vacuum opportunities are occasionally missed, so there's no need to |
| 30 | * use an extreme value or get too fancy. 10 minutes seems plenty. |
| 31 | */ |
| 32 | #define OLD_SNAPSHOT_PADDING_ENTRIES 10 |
| 33 | #define OLD_SNAPSHOT_TIME_MAP_ENTRIES (old_snapshot_threshold + OLD_SNAPSHOT_PADDING_ENTRIES) |
| 34 | |
| 35 | /* |
| 36 | * Common definition of relation properties that allow early pruning/vacuuming |
| 37 | * when old_snapshot_threshold >= 0. |
| 38 | */ |
| 39 | #define RelationAllowsEarlyPruning(rel) \ |
| 40 | ( \ |
| 41 | RelationNeedsWAL(rel) \ |
| 42 | && !IsCatalogRelation(rel) \ |
| 43 | && !RelationIsAccessibleInLogicalDecoding(rel) \ |
| 44 | ) |
| 45 | |
| 46 | #define EarlyPruningEnabled(rel) (old_snapshot_threshold >= 0 && RelationAllowsEarlyPruning(rel)) |
| 47 | |
| 48 | /* GUC variables */ |
| 49 | extern PGDLLIMPORT int old_snapshot_threshold; |
| 50 | |
| 51 | |
| 52 | extern Size SnapMgrShmemSize(void); |
| 53 | extern void SnapMgrInit(void); |
| 54 | extern TimestampTz GetSnapshotCurrentTimestamp(void); |
| 55 | extern TimestampTz GetOldSnapshotThresholdTimestamp(void); |
| 56 | |
| 57 | extern bool FirstSnapshotSet; |
| 58 | |
| 59 | extern PGDLLIMPORT TransactionId TransactionXmin; |
| 60 | extern PGDLLIMPORT TransactionId RecentXmin; |
| 61 | extern PGDLLIMPORT TransactionId RecentGlobalXmin; |
| 62 | extern PGDLLIMPORT TransactionId RecentGlobalDataXmin; |
| 63 | |
| 64 | /* Variables representing various special snapshot semantics */ |
| 65 | extern PGDLLIMPORT SnapshotData SnapshotSelfData; |
| 66 | extern PGDLLIMPORT SnapshotData SnapshotAnyData; |
| 67 | extern PGDLLIMPORT SnapshotData CatalogSnapshotData; |
| 68 | |
| 69 | #define SnapshotSelf (&SnapshotSelfData) |
| 70 | #define SnapshotAny (&SnapshotAnyData) |
| 71 | |
| 72 | /* |
| 73 | * We don't provide a static SnapshotDirty variable because it would be |
| 74 | * non-reentrant. Instead, users of that snapshot type should declare a |
| 75 | * local variable of type SnapshotData, and initialize it with this macro. |
| 76 | */ |
| 77 | #define InitDirtySnapshot(snapshotdata) \ |
| 78 | ((snapshotdata).snapshot_type = SNAPSHOT_DIRTY) |
| 79 | |
| 80 | /* |
| 81 | * Similarly, some initialization is required for a NonVacuumable snapshot. |
| 82 | * The caller must supply the xmin horizon to use (e.g., RecentGlobalXmin). |
| 83 | */ |
| 84 | #define InitNonVacuumableSnapshot(snapshotdata, xmin_horizon) \ |
| 85 | ((snapshotdata).snapshot_type = SNAPSHOT_NON_VACUUMABLE, \ |
| 86 | (snapshotdata).xmin = (xmin_horizon)) |
| 87 | |
| 88 | /* |
| 89 | * Similarly, some initialization is required for SnapshotToast. We need |
| 90 | * to set lsn and whenTaken correctly to support snapshot_too_old. |
| 91 | */ |
| 92 | #define InitToastSnapshot(snapshotdata, l, w) \ |
| 93 | ((snapshotdata).snapshot_type = SNAPSHOT_TOAST, \ |
| 94 | (snapshotdata).lsn = (l), \ |
| 95 | (snapshotdata).whenTaken = (w)) |
| 96 | |
| 97 | /* This macro encodes the knowledge of which snapshots are MVCC-safe */ |
| 98 | #define IsMVCCSnapshot(snapshot) \ |
| 99 | ((snapshot)->snapshot_type == SNAPSHOT_MVCC || \ |
| 100 | (snapshot)->snapshot_type == SNAPSHOT_HISTORIC_MVCC) |
| 101 | |
| 102 | |
| 103 | extern Snapshot GetTransactionSnapshot(void); |
| 104 | extern Snapshot GetLatestSnapshot(void); |
| 105 | extern void SnapshotSetCommandId(CommandId curcid); |
| 106 | extern Snapshot GetOldestSnapshot(void); |
| 107 | |
| 108 | extern Snapshot GetCatalogSnapshot(Oid relid); |
| 109 | extern Snapshot GetNonHistoricCatalogSnapshot(Oid relid); |
| 110 | extern void InvalidateCatalogSnapshot(void); |
| 111 | extern void InvalidateCatalogSnapshotConditionally(void); |
| 112 | |
| 113 | extern void PushActiveSnapshot(Snapshot snapshot); |
| 114 | extern void PushCopiedSnapshot(Snapshot snapshot); |
| 115 | extern void UpdateActiveSnapshotCommandId(void); |
| 116 | extern void PopActiveSnapshot(void); |
| 117 | extern Snapshot GetActiveSnapshot(void); |
| 118 | extern bool ActiveSnapshotSet(void); |
| 119 | |
| 120 | extern Snapshot RegisterSnapshot(Snapshot snapshot); |
| 121 | extern void UnregisterSnapshot(Snapshot snapshot); |
| 122 | extern Snapshot RegisterSnapshotOnOwner(Snapshot snapshot, ResourceOwner owner); |
| 123 | extern void UnregisterSnapshotFromOwner(Snapshot snapshot, ResourceOwner owner); |
| 124 | |
| 125 | extern FullTransactionId GetFullRecentGlobalXmin(void); |
| 126 | |
| 127 | extern void AtSubCommit_Snapshot(int level); |
| 128 | extern void AtSubAbort_Snapshot(int level); |
| 129 | extern void AtEOXact_Snapshot(bool isCommit, bool resetXmin); |
| 130 | |
| 131 | extern void ImportSnapshot(const char *idstr); |
| 132 | extern bool XactHasExportedSnapshots(void); |
| 133 | extern void DeleteAllExportedSnapshotFiles(void); |
| 134 | extern bool ThereAreNoPriorRegisteredSnapshots(void); |
| 135 | extern TransactionId TransactionIdLimitedForOldSnapshots(TransactionId recentXmin, |
| 136 | Relation relation); |
| 137 | extern void MaintainOldSnapshotTimeMapping(TimestampTz whenTaken, |
| 138 | TransactionId xmin); |
| 139 | |
| 140 | extern char *ExportSnapshot(Snapshot snapshot); |
| 141 | |
| 142 | /* |
| 143 | * Utility functions for implementing visibility routines in table AMs. |
| 144 | */ |
| 145 | extern bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot); |
| 146 | |
| 147 | /* Support for catalog timetravel for logical decoding */ |
| 148 | struct HTAB; |
| 149 | extern struct HTAB *HistoricSnapshotGetTupleCids(void); |
| 150 | extern void SetupHistoricSnapshot(Snapshot snapshot_now, struct HTAB *tuplecids); |
| 151 | extern void TeardownHistoricSnapshot(bool is_error); |
| 152 | extern bool HistoricSnapshotActive(void); |
| 153 | |
| 154 | extern Size EstimateSnapshotSpace(Snapshot snapshot); |
| 155 | extern void SerializeSnapshot(Snapshot snapshot, char *start_address); |
| 156 | extern Snapshot RestoreSnapshot(char *start_address); |
| 157 | extern void RestoreTransactionSnapshot(Snapshot snapshot, void *master_pgproc); |
| 158 | |
| 159 | #endif /* SNAPMGR_H */ |
| 160 | |