1 /*------------------------------------------------------------------------- 2 * 3 * snapshot.h 4 * POSTGRES snapshot definition 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/snapshot.h 10 * 11 *------------------------------------------------------------------------- 12 */ 13 #ifndef SNAPSHOT_H 14 #define SNAPSHOT_H 15 16 #include "access/htup.h" 17 #include "access/xlogdefs.h" 18 #include "datatype/timestamp.h" 19 #include "lib/pairingheap.h" 20 #include "storage/buf.h" 21 22 23 /* 24 * The different snapshot types. We use SnapshotData structures to represent 25 * both "regular" (MVCC) snapshots and "special" snapshots that have non-MVCC 26 * semantics. The specific semantics of a snapshot are encoded by its type. 27 * 28 * The behaviour of each type of snapshot should be documented alongside its 29 * enum value, best in terms that are not specific to an individual table AM. 30 * 31 * The reason the snapshot type rather than a callback as it used to be is 32 * that that allows to use the same snapshot for different table AMs without 33 * having one callback per AM. 34 */ 35 typedef enum SnapshotType 36 { 37 /*------------------------------------------------------------------------- 38 * A tuple is visible iff the tuple is valid for the given MVCC snapshot. 39 * 40 * Here, we consider the effects of: 41 * - all transactions committed as of the time of the given snapshot 42 * - previous commands of this transaction 43 * 44 * Does _not_ include: 45 * - transactions shown as in-progress by the snapshot 46 * - transactions started after the snapshot was taken 47 * - changes made by the current command 48 * ------------------------------------------------------------------------- 49 */ 50 SNAPSHOT_MVCC = 0, 51 52 /*------------------------------------------------------------------------- 53 * A tuple is visible iff the tuple is valid "for itself". 54 * 55 * Here, we consider the effects of: 56 * - all committed transactions (as of the current instant) 57 * - previous commands of this transaction 58 * - changes made by the current command 59 * 60 * Does _not_ include: 61 * - in-progress transactions (as of the current instant) 62 * ------------------------------------------------------------------------- 63 */ 64 SNAPSHOT_SELF, 65 66 /* 67 * Any tuple is visible. 68 */ 69 SNAPSHOT_ANY, 70 71 /* 72 * A tuple is visible iff the tuple is valid as a TOAST row. 73 */ 74 SNAPSHOT_TOAST, 75 76 /*------------------------------------------------------------------------- 77 * A tuple is visible iff the tuple is valid including effects of open 78 * transactions. 79 * 80 * Here, we consider the effects of: 81 * - all committed and in-progress transactions (as of the current instant) 82 * - previous commands of this transaction 83 * - changes made by the current command 84 * 85 * This is essentially like SNAPSHOT_SELF as far as effects of the current 86 * transaction and committed/aborted xacts are concerned. However, it 87 * also includes the effects of other xacts still in progress. 88 * 89 * A special hack is that when a snapshot of this type is used to 90 * determine tuple visibility, the passed-in snapshot struct is used as an 91 * output argument to return the xids of concurrent xacts that affected 92 * the tuple. snapshot->xmin is set to the tuple's xmin if that is 93 * another transaction that's still in progress; or to 94 * InvalidTransactionId if the tuple's xmin is committed good, committed 95 * dead, or my own xact. Similarly for snapshot->xmax and the tuple's 96 * xmax. If the tuple was inserted speculatively, meaning that the 97 * inserter might still back down on the insertion without aborting the 98 * whole transaction, the associated token is also returned in 99 * snapshot->speculativeToken. See also InitDirtySnapshot(). 100 * ------------------------------------------------------------------------- 101 */ 102 SNAPSHOT_DIRTY, 103 104 /* 105 * A tuple is visible iff it follows the rules of SNAPSHOT_MVCC, but 106 * supports being called in timetravel context (for decoding catalog 107 * contents in the context of logical decoding). 108 */ 109 SNAPSHOT_HISTORIC_MVCC, 110 111 /* 112 * A tuple is visible iff the tuple might be visible to some transaction; 113 * false if it's surely dead to everyone, i.e., vacuumable. 114 * 115 * For visibility checks snapshot->min must have been set up with the xmin 116 * horizon to use. 117 */ 118 SNAPSHOT_NON_VACUUMABLE 119 } SnapshotType; 120 121 typedef struct SnapshotData *Snapshot; 122 123 #define InvalidSnapshot ((Snapshot) NULL) 124 125 /* 126 * Struct representing all kind of possible snapshots. 127 * 128 * There are several different kinds of snapshots: 129 * * Normal MVCC snapshots 130 * * MVCC snapshots taken during recovery (in Hot-Standby mode) 131 * * Historic MVCC snapshots used during logical decoding 132 * * snapshots passed to HeapTupleSatisfiesDirty() 133 * * snapshots passed to HeapTupleSatisfiesNonVacuumable() 134 * * snapshots used for SatisfiesAny, Toast, Self where no members are 135 * accessed. 136 * 137 * TODO: It's probably a good idea to split this struct using a NodeTag 138 * similar to how parser and executor nodes are handled, with one type for 139 * each different kind of snapshot to avoid overloading the meaning of 140 * individual fields. 141 */ 142 typedef struct SnapshotData 143 { 144 SnapshotType snapshot_type; /* type of snapshot */ 145 146 /* 147 * The remaining fields are used only for MVCC snapshots, and are normally 148 * just zeroes in special snapshots. (But xmin and xmax are used 149 * specially by HeapTupleSatisfiesDirty, and xmin is used specially by 150 * HeapTupleSatisfiesNonVacuumable.) 151 * 152 * An MVCC snapshot can never see the effects of XIDs >= xmax. It can see 153 * the effects of all older XIDs except those listed in the snapshot. xmin 154 * is stored as an optimization to avoid needing to search the XID arrays 155 * for most tuples. 156 */ 157 TransactionId xmin; /* all XID < xmin are visible to me */ 158 TransactionId xmax; /* all XID >= xmax are invisible to me */ 159 160 /* 161 * For normal MVCC snapshot this contains the all xact IDs that are in 162 * progress, unless the snapshot was taken during recovery in which case 163 * it's empty. For historic MVCC snapshots, the meaning is inverted, i.e. 164 * it contains *committed* transactions between xmin and xmax. 165 * 166 * note: all ids in xip[] satisfy xmin <= xip[i] < xmax 167 */ 168 TransactionId *xip; 169 uint32 xcnt; /* # of xact ids in xip[] */ 170 171 /* 172 * For non-historic MVCC snapshots, this contains subxact IDs that are in 173 * progress (and other transactions that are in progress if taken during 174 * recovery). For historic snapshot it contains *all* xids assigned to the 175 * replayed transaction, including the toplevel xid. 176 * 177 * note: all ids in subxip[] are >= xmin, but we don't bother filtering 178 * out any that are >= xmax 179 */ 180 TransactionId *subxip; 181 int32 subxcnt; /* # of xact ids in subxip[] */ 182 bool suboverflowed; /* has the subxip array overflowed? */ 183 184 bool takenDuringRecovery; /* recovery-shaped snapshot? */ 185 bool copied; /* false if it's a static snapshot */ 186 187 CommandId curcid; /* in my xact, CID < curcid are visible */ 188 189 /* 190 * An extra return value for HeapTupleSatisfiesDirty, not used in MVCC 191 * snapshots. 192 */ 193 uint32 speculativeToken; 194 195 /* 196 * Book-keeping information, used by the snapshot manager 197 */ 198 uint32 active_count; /* refcount on ActiveSnapshot stack */ 199 uint32 regd_count; /* refcount on RegisteredSnapshots */ 200 pairingheap_node ph_node; /* link in the RegisteredSnapshots heap */ 201 202 TimestampTz whenTaken; /* timestamp when snapshot was taken */ 203 XLogRecPtr lsn; /* position in the WAL stream when taken */ 204 } SnapshotData; 205 206 #endif /* SNAPSHOT_H */ 207