1 /*-------------------------------------------------------------------------
2  *
3  * xact.h
4  *	  postgres transaction system definitions
5  *
6  *
7  * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * src/include/access/xact.h
11  *
12  *-------------------------------------------------------------------------
13  */
14 #ifndef XACT_H
15 #define XACT_H
16 
17 #include "access/xlogreader.h"
18 #include "lib/stringinfo.h"
19 #include "nodes/pg_list.h"
20 #include "storage/relfilenode.h"
21 #include "storage/sinval.h"
22 #include "utils/datetime.h"
23 
24 
25 /*
26  * Xact isolation levels
27  */
28 #define XACT_READ_UNCOMMITTED	0
29 #define XACT_READ_COMMITTED		1
30 #define XACT_REPEATABLE_READ	2
31 #define XACT_SERIALIZABLE		3
32 
33 extern int	DefaultXactIsoLevel;
34 extern PGDLLIMPORT int XactIsoLevel;
35 
36 /*
37  * We implement three isolation levels internally.
38  * The two stronger ones use one snapshot per database transaction;
39  * the others use one snapshot per statement.
40  * Serializable uses predicate locks in addition to snapshots.
41  * These macros should be used to check which isolation level is selected.
42  */
43 #define IsolationUsesXactSnapshot() (XactIsoLevel >= XACT_REPEATABLE_READ)
44 #define IsolationIsSerializable() (XactIsoLevel == XACT_SERIALIZABLE)
45 
46 /* Xact read-only state */
47 extern bool DefaultXactReadOnly;
48 extern bool XactReadOnly;
49 
50 /*
51  * Xact is deferrable -- only meaningful (currently) for read only
52  * SERIALIZABLE transactions
53  */
54 extern bool DefaultXactDeferrable;
55 extern bool XactDeferrable;
56 
57 typedef enum
58 {
59 	SYNCHRONOUS_COMMIT_OFF,		/* asynchronous commit */
60 	SYNCHRONOUS_COMMIT_LOCAL_FLUSH,		/* wait for local flush only */
61 	SYNCHRONOUS_COMMIT_REMOTE_WRITE,	/* wait for local flush and remote
62 										 * write */
63 	SYNCHRONOUS_COMMIT_REMOTE_FLUSH,	/* wait for local and remote flush */
64 	SYNCHRONOUS_COMMIT_REMOTE_APPLY		/* wait for local and remote flush
65 										   and remote apply */
66 }	SyncCommitLevel;
67 
68 /* Define the default setting for synchronous_commit */
69 #define SYNCHRONOUS_COMMIT_ON	SYNCHRONOUS_COMMIT_REMOTE_FLUSH
70 
71 /* Synchronous commit level */
72 extern int	synchronous_commit;
73 
74 /* Kluge for 2PC support */
75 extern bool MyXactAccessedTempRel;
76 
77 /*
78  *	start- and end-of-transaction callbacks for dynamically loaded modules
79  */
80 typedef enum
81 {
82 	XACT_EVENT_COMMIT,
83 	XACT_EVENT_PARALLEL_COMMIT,
84 	XACT_EVENT_ABORT,
85 	XACT_EVENT_PARALLEL_ABORT,
86 	XACT_EVENT_PREPARE,
87 	XACT_EVENT_PRE_COMMIT,
88 	XACT_EVENT_PARALLEL_PRE_COMMIT,
89 	XACT_EVENT_PRE_PREPARE
90 } XactEvent;
91 
92 typedef void (*XactCallback) (XactEvent event, void *arg);
93 
94 typedef enum
95 {
96 	SUBXACT_EVENT_START_SUB,
97 	SUBXACT_EVENT_COMMIT_SUB,
98 	SUBXACT_EVENT_ABORT_SUB,
99 	SUBXACT_EVENT_PRE_COMMIT_SUB
100 } SubXactEvent;
101 
102 typedef void (*SubXactCallback) (SubXactEvent event, SubTransactionId mySubid,
103 									SubTransactionId parentSubid, void *arg);
104 
105 
106 /* ----------------
107  *		transaction-related XLOG entries
108  * ----------------
109  */
110 
111 /*
112  * XLOG allows to store some information in high 4 bits of log record xl_info
113  * field. We use 3 for the opcode, and one about an optional flag variable.
114  */
115 #define XLOG_XACT_COMMIT			0x00
116 #define XLOG_XACT_PREPARE			0x10
117 #define XLOG_XACT_ABORT				0x20
118 #define XLOG_XACT_COMMIT_PREPARED	0x30
119 #define XLOG_XACT_ABORT_PREPARED	0x40
120 #define XLOG_XACT_ASSIGNMENT		0x50
121 /* free opcode 0x60 */
122 /* free opcode 0x70 */
123 
124 /* mask for filtering opcodes out of xl_info */
125 #define XLOG_XACT_OPMASK			0x70
126 
127 /* does this record have a 'xinfo' field or not */
128 #define XLOG_XACT_HAS_INFO			0x80
129 
130 /*
131  * The following flags, stored in xinfo, determine which information is
132  * contained in commit/abort records.
133  */
134 #define XACT_XINFO_HAS_DBINFO			(1U << 0)
135 #define XACT_XINFO_HAS_SUBXACTS			(1U << 1)
136 #define XACT_XINFO_HAS_RELFILENODES		(1U << 2)
137 #define XACT_XINFO_HAS_INVALS			(1U << 3)
138 #define XACT_XINFO_HAS_TWOPHASE			(1U << 4)
139 #define XACT_XINFO_HAS_ORIGIN			(1U << 5)
140 
141 /*
142  * Also stored in xinfo, these indicating a variety of additional actions that
143  * need to occur when emulating transaction effects during recovery.
144  *
145  * They are named XactCompletion... to differentiate them from
146  * EOXact... routines which run at the end of the original transaction
147  * completion.
148  */
149 #define XACT_COMPLETION_APPLY_FEEDBACK			(1U << 29)
150 #define XACT_COMPLETION_UPDATE_RELCACHE_FILE	(1U << 30)
151 #define XACT_COMPLETION_FORCE_SYNC_COMMIT		(1U << 31)
152 
153 /* Access macros for above flags */
154 #define XactCompletionApplyFeedback(xinfo) \
155 	((xinfo & XACT_COMPLETION_APPLY_FEEDBACK) != 0)
156 #define XactCompletionRelcacheInitFileInval(xinfo) \
157 	((xinfo & XACT_COMPLETION_UPDATE_RELCACHE_FILE) != 0)
158 #define XactCompletionForceSyncCommit(xinfo) \
159 	((xinfo & XACT_COMPLETION_FORCE_SYNC_COMMIT) != 0)
160 
161 typedef struct xl_xact_assignment
162 {
163 	TransactionId xtop;			/* assigned XID's top-level XID */
164 	int			nsubxacts;		/* number of subtransaction XIDs */
165 	TransactionId xsub[FLEXIBLE_ARRAY_MEMBER];	/* assigned subxids */
166 } xl_xact_assignment;
167 
168 #define MinSizeOfXactAssignment offsetof(xl_xact_assignment, xsub)
169 
170 /*
171  * Commit and abort records can contain a lot of information. But a large
172  * portion of the records won't need all possible pieces of information. So we
173  * only include what's needed.
174  *
175  * A minimal commit/abort record only consists of a xl_xact_commit/abort
176  * struct. The presence of additional information is indicated by bits set in
177  * 'xl_xact_xinfo->xinfo'. The presence of the xinfo field itself is signalled
178  * by a set XLOG_XACT_HAS_INFO bit in the xl_info field.
179  *
180  * NB: All the individual data chunks should be sized to multiples of
181  * sizeof(int) and only require int32 alignment. If they require bigger
182  * alignment, they need to be copied upon reading.
183  */
184 
185 /* sub-records for commit/abort */
186 
187 typedef struct xl_xact_xinfo
188 {
189 	/*
190 	 * Even though we right now only require 1 byte of space in xinfo we use
191 	 * four so following records don't have to care about alignment. Commit
192 	 * records can be large, so copying large portions isn't attractive.
193 	 */
194 	uint32		xinfo;
195 } xl_xact_xinfo;
196 
197 typedef struct xl_xact_dbinfo
198 {
199 	Oid			dbId;			/* MyDatabaseId */
200 	Oid			tsId;			/* MyDatabaseTableSpace */
201 } xl_xact_dbinfo;
202 
203 typedef struct xl_xact_subxacts
204 {
205 	int			nsubxacts;		/* number of subtransaction XIDs */
206 	TransactionId subxacts[FLEXIBLE_ARRAY_MEMBER];
207 } xl_xact_subxacts;
208 #define MinSizeOfXactSubxacts offsetof(xl_xact_subxacts, subxacts)
209 
210 typedef struct xl_xact_relfilenodes
211 {
212 	int			nrels;			/* number of subtransaction XIDs */
213 	RelFileNode xnodes[FLEXIBLE_ARRAY_MEMBER];
214 } xl_xact_relfilenodes;
215 #define MinSizeOfXactRelfilenodes offsetof(xl_xact_relfilenodes, xnodes)
216 
217 typedef struct xl_xact_invals
218 {
219 	int			nmsgs;			/* number of shared inval msgs */
220 	SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER];
221 } xl_xact_invals;
222 #define MinSizeOfXactInvals offsetof(xl_xact_invals, msgs)
223 
224 typedef struct xl_xact_twophase
225 {
226 	TransactionId xid;
227 } xl_xact_twophase;
228 
229 typedef struct xl_xact_origin
230 {
231 	XLogRecPtr	origin_lsn;
232 	TimestampTz origin_timestamp;
233 } xl_xact_origin;
234 
235 typedef struct xl_xact_commit
236 {
237 	TimestampTz xact_time;		/* time of commit */
238 
239 	/* xl_xact_xinfo follows if XLOG_XACT_HAS_INFO */
240 	/* xl_xact_dbinfo follows if XINFO_HAS_DBINFO */
241 	/* xl_xact_subxacts follows if XINFO_HAS_SUBXACT */
242 	/* xl_xact_relfilenodes follows if XINFO_HAS_RELFILENODES */
243 	/* xl_xact_invals follows if XINFO_HAS_INVALS */
244 	/* xl_xact_twophase follows if XINFO_HAS_TWOPHASE */
245 	/* xl_xact_origin follows if XINFO_HAS_ORIGIN, stored unaligned! */
246 } xl_xact_commit;
247 #define MinSizeOfXactCommit (offsetof(xl_xact_commit, xact_time) + sizeof(TimestampTz))
248 
249 typedef struct xl_xact_abort
250 {
251 	TimestampTz xact_time;		/* time of abort */
252 
253 	/* xl_xact_xinfo follows if XLOG_XACT_HAS_INFO */
254 	/* No db_info required */
255 	/* xl_xact_subxacts follows if HAS_SUBXACT */
256 	/* xl_xact_relfilenodes follows if HAS_RELFILENODES */
257 	/* No invalidation messages needed. */
258 	/* xl_xact_twophase follows if XINFO_HAS_TWOPHASE */
259 } xl_xact_abort;
260 #define MinSizeOfXactAbort sizeof(xl_xact_abort)
261 
262 /*
263  * Commit/Abort records in the above form are a bit verbose to parse, so
264  * there's a deconstructed versions generated by ParseCommit/AbortRecord() for
265  * easier consumption.
266  */
267 typedef struct xl_xact_parsed_commit
268 {
269 	TimestampTz xact_time;
270 
271 	uint32		xinfo;
272 
273 	Oid			dbId;			/* MyDatabaseId */
274 	Oid			tsId;			/* MyDatabaseTableSpace */
275 
276 	int			nsubxacts;
277 	TransactionId *subxacts;
278 
279 	int			nrels;
280 	RelFileNode *xnodes;
281 
282 	int			nmsgs;
283 	SharedInvalidationMessage *msgs;
284 
285 	TransactionId twophase_xid; /* only for 2PC */
286 
287 	XLogRecPtr	origin_lsn;
288 	TimestampTz origin_timestamp;
289 } xl_xact_parsed_commit;
290 
291 typedef struct xl_xact_parsed_abort
292 {
293 	TimestampTz xact_time;
294 	uint32		xinfo;
295 
296 	int			nsubxacts;
297 	TransactionId *subxacts;
298 
299 	int			nrels;
300 	RelFileNode *xnodes;
301 
302 	TransactionId twophase_xid; /* only for 2PC */
303 } xl_xact_parsed_abort;
304 
305 
306 /* ----------------
307  *		extern definitions
308  * ----------------
309  */
310 extern bool IsTransactionState(void);
311 extern bool IsAbortedTransactionBlockState(void);
312 extern TransactionId GetTopTransactionId(void);
313 extern TransactionId GetTopTransactionIdIfAny(void);
314 extern TransactionId GetCurrentTransactionId(void);
315 extern TransactionId GetCurrentTransactionIdIfAny(void);
316 extern TransactionId GetStableLatestTransactionId(void);
317 extern SubTransactionId GetCurrentSubTransactionId(void);
318 extern void MarkCurrentTransactionIdLoggedIfAny(void);
319 extern bool SubTransactionIsActive(SubTransactionId subxid);
320 extern CommandId GetCurrentCommandId(bool used);
321 extern void SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts);
322 extern TimestampTz GetCurrentTransactionStartTimestamp(void);
323 extern TimestampTz GetCurrentStatementStartTimestamp(void);
324 extern TimestampTz GetCurrentTransactionStopTimestamp(void);
325 extern void SetCurrentStatementStartTimestamp(void);
326 extern int	GetCurrentTransactionNestLevel(void);
327 extern bool TransactionIdIsCurrentTransactionId(TransactionId xid);
328 extern void CommandCounterIncrement(void);
329 extern void ForceSyncCommit(void);
330 extern void StartTransactionCommand(void);
331 extern void CommitTransactionCommand(void);
332 extern void AbortCurrentTransaction(void);
333 extern void BeginTransactionBlock(void);
334 extern bool EndTransactionBlock(void);
335 extern bool PrepareTransactionBlock(char *gid);
336 extern void UserAbortTransactionBlock(void);
337 extern void ReleaseSavepoint(List *options);
338 extern void DefineSavepoint(char *name);
339 extern void RollbackToSavepoint(List *options);
340 extern void BeginInternalSubTransaction(char *name);
341 extern void ReleaseCurrentSubTransaction(void);
342 extern void RollbackAndReleaseCurrentSubTransaction(void);
343 extern bool IsSubTransaction(void);
344 extern Size EstimateTransactionStateSpace(void);
345 extern void SerializeTransactionState(Size maxsize, char *start_address);
346 extern void StartParallelWorkerTransaction(char *tstatespace);
347 extern void EndParallelWorkerTransaction(void);
348 extern bool IsTransactionBlock(void);
349 extern bool IsTransactionOrTransactionBlock(void);
350 extern char TransactionBlockStatusCode(void);
351 extern void AbortOutOfAnyTransaction(void);
352 extern void PreventTransactionChain(bool isTopLevel, const char *stmtType);
353 extern void RequireTransactionChain(bool isTopLevel, const char *stmtType);
354 extern void WarnNoTransactionChain(bool isTopLevel, const char *stmtType);
355 extern bool IsInTransactionChain(bool isTopLevel);
356 extern void RegisterXactCallback(XactCallback callback, void *arg);
357 extern void UnregisterXactCallback(XactCallback callback, void *arg);
358 extern void RegisterSubXactCallback(SubXactCallback callback, void *arg);
359 extern void UnregisterSubXactCallback(SubXactCallback callback, void *arg);
360 
361 extern int	xactGetCommittedChildren(TransactionId **ptr);
362 
363 extern XLogRecPtr XactLogCommitRecord(TimestampTz commit_time,
364 					int nsubxacts, TransactionId *subxacts,
365 					int nrels, RelFileNode *rels,
366 					int nmsgs, SharedInvalidationMessage *msgs,
367 					bool relcacheInval, bool forceSync,
368 					TransactionId twophase_xid);
369 
370 extern XLogRecPtr XactLogAbortRecord(TimestampTz abort_time,
371 				   int nsubxacts, TransactionId *subxacts,
372 				   int nrels, RelFileNode *rels,
373 				   TransactionId twophase_xid);
374 extern void xact_redo(XLogReaderState *record);
375 
376 /* xactdesc.c */
377 extern void xact_desc(StringInfo buf, XLogReaderState *record);
378 extern const char *xact_identify(uint8 info);
379 
380 /* also in xactdesc.c, so they can be shared between front/backend code */
381 extern void ParseCommitRecord(uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *parsed);
382 extern void ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed);
383 
384 extern void EnterParallelMode(void);
385 extern void ExitParallelMode(void);
386 extern bool IsInParallelMode(void);
387 
388 #endif   /* XACT_H */
389