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 */
35typedef 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
121typedef 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 */
142typedef 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