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