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