1 /*-------------------------------------------------------------------------
4 * postgres transaction system definitions
7 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
10 * src/include/access/xact.h
12 *-------------------------------------------------------------------------
17 #include "access/transam.h"
18 #include "access/xlogreader.h"
19 #include "datatype/timestamp.h"
20 #include "lib/stringinfo.h"
21 #include "nodes/pg_list.h"
22 #include "storage/relfilenode.h"
23 #include "storage/sinval.h"
26 * Maximum size of Global Transaction ID (including '\0').
28 * Note that the max value of GIDSIZE must fit in the uint16 gidlen,
29 * specified in TwoPhaseFileHeader.
34 * Xact isolation levels
36 #define XACT_READ_UNCOMMITTED 0
37 #define XACT_READ_COMMITTED 1
38 #define XACT_REPEATABLE_READ 2
39 #define XACT_SERIALIZABLE 3
41 extern int DefaultXactIsoLevel
;
42 extern PGDLLIMPORT
int XactIsoLevel
;
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.
51 #define IsolationUsesXactSnapshot() (XactIsoLevel >= XACT_REPEATABLE_READ)
52 #define IsolationIsSerializable() (XactIsoLevel == XACT_SERIALIZABLE)
54 /* Xact read-only state */
55 extern bool DefaultXactReadOnly
;
56 extern bool XactReadOnly
;
58 /* flag for logging statements in this transaction */
59 extern bool xact_is_sampled
;
62 * Xact is deferrable -- only meaningful (currently) for read only
63 * SERIALIZABLE transactions
65 extern bool DefaultXactDeferrable
;
66 extern bool XactDeferrable
;
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
74 SYNCHRONOUS_COMMIT_REMOTE_FLUSH
, /* wait for local and remote flush */
75 SYNCHRONOUS_COMMIT_REMOTE_APPLY
/* wait for local and remote flush and
79 /* Define the default setting for synchronous_commit */
80 #define SYNCHRONOUS_COMMIT_ON SYNCHRONOUS_COMMIT_REMOTE_FLUSH
82 /* Synchronous commit level */
83 extern int synchronous_commit
;
85 /* used during logical streaming of a transaction */
86 extern PGDLLIMPORT TransactionId CheckXidAlive
;
87 extern PGDLLIMPORT
bool bsysscan
;
90 * Miscellaneous flag bits to record events which occur on the top level
91 * transaction. These flags are only persisted in MyXactFlags and are intended
92 * so we remember to do certain things later in the transaction. This is
93 * globally accessible, so can be set from anywhere in the code which requires
96 extern int MyXactFlags
;
99 * XACT_FLAGS_ACCESSEDTEMPNAMESPACE - set when a temporary object is accessed.
100 * We don't allow PREPARE TRANSACTION in that case.
102 #define XACT_FLAGS_ACCESSEDTEMPNAMESPACE (1U << 0)
105 * XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK - records whether the top level xact
106 * logged any Access Exclusive Locks.
108 #define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK (1U << 1)
111 * start- and end-of-transaction callbacks for dynamically loaded modules
116 XACT_EVENT_PARALLEL_COMMIT
,
118 XACT_EVENT_PARALLEL_ABORT
,
120 XACT_EVENT_PRE_COMMIT
,
121 XACT_EVENT_PARALLEL_PRE_COMMIT
,
122 XACT_EVENT_PRE_PREPARE
125 typedef void (*XactCallback
) (XactEvent event
, void *arg
);
129 SUBXACT_EVENT_START_SUB
,
130 SUBXACT_EVENT_COMMIT_SUB
,
131 SUBXACT_EVENT_ABORT_SUB
,
132 SUBXACT_EVENT_PRE_COMMIT_SUB
135 typedef void (*SubXactCallback
) (SubXactEvent event
, SubTransactionId mySubid
,
136 SubTransactionId parentSubid
, void *arg
);
140 * transaction-related XLOG entries
145 * XLOG allows to store some information in high 4 bits of log record xl_info
146 * field. We use 3 for the opcode, and one about an optional flag variable.
148 #define XLOG_XACT_COMMIT 0x00
149 #define XLOG_XACT_PREPARE 0x10
150 #define XLOG_XACT_ABORT 0x20
151 #define XLOG_XACT_COMMIT_PREPARED 0x30
152 #define XLOG_XACT_ABORT_PREPARED 0x40
153 #define XLOG_XACT_ASSIGNMENT 0x50
154 #define XLOG_XACT_INVALIDATIONS 0x60
155 /* free opcode 0x70 */
157 /* mask for filtering opcodes out of xl_info */
158 #define XLOG_XACT_OPMASK 0x70
160 /* does this record have a 'xinfo' field or not */
161 #define XLOG_XACT_HAS_INFO 0x80
164 * The following flags, stored in xinfo, determine which information is
165 * contained in commit/abort records.
167 #define XACT_XINFO_HAS_DBINFO (1U << 0)
168 #define XACT_XINFO_HAS_SUBXACTS (1U << 1)
169 #define XACT_XINFO_HAS_RELFILENODES (1U << 2)
170 #define XACT_XINFO_HAS_INVALS (1U << 3)
171 #define XACT_XINFO_HAS_TWOPHASE (1U << 4)
172 #define XACT_XINFO_HAS_ORIGIN (1U << 5)
173 #define XACT_XINFO_HAS_AE_LOCKS (1U << 6)
174 #define XACT_XINFO_HAS_GID (1U << 7)
177 * Also stored in xinfo, these indicating a variety of additional actions that
178 * need to occur when emulating transaction effects during recovery.
180 * They are named XactCompletion... to differentiate them from
181 * EOXact... routines which run at the end of the original transaction
184 #define XACT_COMPLETION_APPLY_FEEDBACK (1U << 29)
185 #define XACT_COMPLETION_UPDATE_RELCACHE_FILE (1U << 30)
186 #define XACT_COMPLETION_FORCE_SYNC_COMMIT (1U << 31)
188 /* Access macros for above flags */
189 #define XactCompletionApplyFeedback(xinfo) \
190 ((xinfo & XACT_COMPLETION_APPLY_FEEDBACK) != 0)
191 #define XactCompletionRelcacheInitFileInval(xinfo) \
192 ((xinfo & XACT_COMPLETION_UPDATE_RELCACHE_FILE) != 0)
193 #define XactCompletionForceSyncCommit(xinfo) \
194 ((xinfo & XACT_COMPLETION_FORCE_SYNC_COMMIT) != 0)
196 typedef struct xl_xact_assignment
198 TransactionId xtop
; /* assigned XID's top-level XID */
199 int nsubxacts
; /* number of subtransaction XIDs */
200 TransactionId xsub
[FLEXIBLE_ARRAY_MEMBER
]; /* assigned subxids */
201 } xl_xact_assignment
;
203 #define MinSizeOfXactAssignment offsetof(xl_xact_assignment, xsub)
206 * Commit and abort records can contain a lot of information. But a large
207 * portion of the records won't need all possible pieces of information. So we
208 * only include what's needed.
210 * A minimal commit/abort record only consists of a xl_xact_commit/abort
211 * struct. The presence of additional information is indicated by bits set in
212 * 'xl_xact_xinfo->xinfo'. The presence of the xinfo field itself is signaled
213 * by a set XLOG_XACT_HAS_INFO bit in the xl_info field.
215 * NB: All the individual data chunks should be sized to multiples of
216 * sizeof(int) and only require int32 alignment. If they require bigger
217 * alignment, they need to be copied upon reading.
220 /* sub-records for commit/abort */
222 typedef struct xl_xact_xinfo
225 * Even though we right now only require 1 byte of space in xinfo we use
226 * four so following records don't have to care about alignment. Commit
227 * records can be large, so copying large portions isn't attractive.
232 typedef struct xl_xact_dbinfo
234 Oid dbId
; /* MyDatabaseId */
235 Oid tsId
; /* MyDatabaseTableSpace */
238 typedef struct xl_xact_subxacts
240 int nsubxacts
; /* number of subtransaction XIDs */
241 TransactionId subxacts
[FLEXIBLE_ARRAY_MEMBER
];
243 #define MinSizeOfXactSubxacts offsetof(xl_xact_subxacts, subxacts)
245 typedef struct xl_xact_relfilenodes
247 int nrels
; /* number of relations */
248 RelFileNode xnodes
[FLEXIBLE_ARRAY_MEMBER
];
249 } xl_xact_relfilenodes
;
250 #define MinSizeOfXactRelfilenodes offsetof(xl_xact_relfilenodes, xnodes)
252 typedef struct xl_xact_invals
254 int nmsgs
; /* number of shared inval msgs */
255 SharedInvalidationMessage msgs
[FLEXIBLE_ARRAY_MEMBER
];
257 #define MinSizeOfXactInvals offsetof(xl_xact_invals, msgs)
259 typedef struct xl_xact_twophase
264 typedef struct xl_xact_origin
266 XLogRecPtr origin_lsn
;
267 TimestampTz origin_timestamp
;
270 typedef struct xl_xact_commit
272 TimestampTz xact_time
; /* time of commit */
274 /* xl_xact_xinfo follows if XLOG_XACT_HAS_INFO */
275 /* xl_xact_dbinfo follows if XINFO_HAS_DBINFO */
276 /* xl_xact_subxacts follows if XINFO_HAS_SUBXACT */
277 /* xl_xact_relfilenodes follows if XINFO_HAS_RELFILENODES */
278 /* xl_xact_invals follows if XINFO_HAS_INVALS */
279 /* xl_xact_twophase follows if XINFO_HAS_TWOPHASE */
280 /* twophase_gid follows if XINFO_HAS_GID. As a null-terminated string. */
281 /* xl_xact_origin follows if XINFO_HAS_ORIGIN, stored unaligned! */
283 #define MinSizeOfXactCommit (offsetof(xl_xact_commit, xact_time) + sizeof(TimestampTz))
285 typedef struct xl_xact_abort
287 TimestampTz xact_time
; /* time of abort */
289 /* xl_xact_xinfo follows if XLOG_XACT_HAS_INFO */
290 /* xl_xact_dbinfo follows if XINFO_HAS_DBINFO */
291 /* xl_xact_subxacts follows if XINFO_HAS_SUBXACT */
292 /* xl_xact_relfilenodes follows if XINFO_HAS_RELFILENODES */
293 /* No invalidation messages needed. */
294 /* xl_xact_twophase follows if XINFO_HAS_TWOPHASE */
295 /* twophase_gid follows if XINFO_HAS_GID. As a null-terminated string. */
296 /* xl_xact_origin follows if XINFO_HAS_ORIGIN, stored unaligned! */
298 #define MinSizeOfXactAbort sizeof(xl_xact_abort)
300 typedef struct xl_xact_prepare
302 uint32 magic
; /* format identifier */
303 uint32 total_len
; /* actual file length */
304 TransactionId xid
; /* original transaction XID */
305 Oid database
; /* OID of database it was in */
306 TimestampTz prepared_at
; /* time of preparation */
307 Oid owner
; /* user running the transaction */
308 int32 nsubxacts
; /* number of following subxact XIDs */
309 int32 ncommitrels
; /* number of delete-on-commit rels */
310 int32 nabortrels
; /* number of delete-on-abort rels */
311 int32 ninvalmsgs
; /* number of cache invalidation messages */
312 bool initfileinval
; /* does relcache init file need invalidation? */
313 uint16 gidlen
; /* length of the GID - GID follows the header */
314 XLogRecPtr origin_lsn
; /* lsn of this record at origin node */
315 TimestampTz origin_timestamp
; /* time of prepare at origin node */
319 * Commit/Abort records in the above form are a bit verbose to parse, so
320 * there's a deconstructed versions generated by ParseCommit/AbortRecord() for
321 * easier consumption.
323 typedef struct xl_xact_parsed_commit
325 TimestampTz xact_time
;
328 Oid dbId
; /* MyDatabaseId */
329 Oid tsId
; /* MyDatabaseTableSpace */
332 TransactionId
*subxacts
;
338 SharedInvalidationMessage
*msgs
;
340 TransactionId twophase_xid
; /* only for 2PC */
341 char twophase_gid
[GIDSIZE
]; /* only for 2PC */
342 int nabortrels
; /* only for 2PC */
343 RelFileNode
*abortnodes
; /* only for 2PC */
345 XLogRecPtr origin_lsn
;
346 TimestampTz origin_timestamp
;
347 } xl_xact_parsed_commit
;
349 typedef xl_xact_parsed_commit xl_xact_parsed_prepare
;
351 typedef struct xl_xact_parsed_abort
353 TimestampTz xact_time
;
356 Oid dbId
; /* MyDatabaseId */
357 Oid tsId
; /* MyDatabaseTableSpace */
360 TransactionId
*subxacts
;
365 TransactionId twophase_xid
; /* only for 2PC */
366 char twophase_gid
[GIDSIZE
]; /* only for 2PC */
368 XLogRecPtr origin_lsn
;
369 TimestampTz origin_timestamp
;
370 } xl_xact_parsed_abort
;
377 extern bool IsTransactionState(void);
378 extern bool IsAbortedTransactionBlockState(void);
379 extern TransactionId
GetTopTransactionId(void);
380 extern TransactionId
GetTopTransactionIdIfAny(void);
381 extern TransactionId
GetCurrentTransactionId(void);
382 extern TransactionId
GetCurrentTransactionIdIfAny(void);
383 extern TransactionId
GetStableLatestTransactionId(void);
384 extern SubTransactionId
GetCurrentSubTransactionId(void);
385 extern FullTransactionId
GetTopFullTransactionId(void);
386 extern FullTransactionId
GetTopFullTransactionIdIfAny(void);
387 extern FullTransactionId
GetCurrentFullTransactionId(void);
388 extern FullTransactionId
GetCurrentFullTransactionIdIfAny(void);
389 extern void MarkCurrentTransactionIdLoggedIfAny(void);
390 extern bool SubTransactionIsActive(SubTransactionId subxid
);
391 extern CommandId
GetCurrentCommandId(bool used
);
392 extern void SetParallelStartTimestamps(TimestampTz xact_ts
, TimestampTz stmt_ts
);
393 extern TimestampTz
GetCurrentTransactionStartTimestamp(void);
394 extern TimestampTz
GetCurrentStatementStartTimestamp(void);
395 extern TimestampTz
GetCurrentTransactionStopTimestamp(void);
396 extern void SetCurrentStatementStartTimestamp(void);
397 extern int GetCurrentTransactionNestLevel(void);
398 extern bool TransactionIdIsCurrentTransactionId(TransactionId xid
);
399 extern void CommandCounterIncrement(void);
400 extern void ForceSyncCommit(void);
401 extern void StartTransactionCommand(void);
402 extern void SaveTransactionCharacteristics(void);
403 extern void RestoreTransactionCharacteristics(void);
404 extern void CommitTransactionCommand(void);
405 extern void AbortCurrentTransaction(void);
406 extern void BeginTransactionBlock(void);
407 extern bool EndTransactionBlock(bool chain
);
408 extern bool PrepareTransactionBlock(const char *gid
);
409 extern void UserAbortTransactionBlock(bool chain
);
410 extern void BeginImplicitTransactionBlock(void);
411 extern void EndImplicitTransactionBlock(void);
412 extern void ReleaseSavepoint(const char *name
);
413 extern void DefineSavepoint(const char *name
);
414 extern void RollbackToSavepoint(const char *name
);
415 extern void BeginInternalSubTransaction(const char *name
);
416 extern void ReleaseCurrentSubTransaction(void);
417 extern void RollbackAndReleaseCurrentSubTransaction(void);
418 extern bool IsSubTransaction(void);
419 extern Size
EstimateTransactionStateSpace(void);
420 extern void SerializeTransactionState(Size maxsize
, char *start_address
);
421 extern void StartParallelWorkerTransaction(char *tstatespace
);
422 extern void EndParallelWorkerTransaction(void);
423 extern bool IsTransactionBlock(void);
424 extern bool IsTransactionOrTransactionBlock(void);
425 extern char TransactionBlockStatusCode(void);
426 extern void AbortOutOfAnyTransaction(void);
427 extern void PreventInTransactionBlock(bool isTopLevel
, const char *stmtType
);
428 extern void RequireTransactionBlock(bool isTopLevel
, const char *stmtType
);
429 extern void WarnNoTransactionBlock(bool isTopLevel
, const char *stmtType
);
430 extern bool IsInTransactionBlock(bool isTopLevel
);
431 extern void RegisterXactCallback(XactCallback callback
, void *arg
);
432 extern void UnregisterXactCallback(XactCallback callback
, void *arg
);
433 extern void RegisterSubXactCallback(SubXactCallback callback
, void *arg
);
434 extern void UnregisterSubXactCallback(SubXactCallback callback
, void *arg
);
436 extern bool IsSubTransactionAssignmentPending(void);
437 extern void MarkSubTransactionAssigned(void);
439 extern int xactGetCommittedChildren(TransactionId
**ptr
);
441 extern XLogRecPtr
XactLogCommitRecord(TimestampTz commit_time
,
442 int nsubxacts
, TransactionId
*subxacts
,
443 int nrels
, RelFileNode
*rels
,
444 int nmsgs
, SharedInvalidationMessage
*msgs
,
447 TransactionId twophase_xid
,
448 const char *twophase_gid
);
450 extern XLogRecPtr
XactLogAbortRecord(TimestampTz abort_time
,
451 int nsubxacts
, TransactionId
*subxacts
,
452 int nrels
, RelFileNode
*rels
,
453 int xactflags
, TransactionId twophase_xid
,
454 const char *twophase_gid
);
455 extern void xact_redo(XLogReaderState
*record
);
458 extern void xact_desc(StringInfo buf
, XLogReaderState
*record
);
459 extern const char *xact_identify(uint8 info
);
461 /* also in xactdesc.c, so they can be shared between front/backend code */
462 extern void ParseCommitRecord(uint8 info
, xl_xact_commit
*xlrec
, xl_xact_parsed_commit
*parsed
);
463 extern void ParseAbortRecord(uint8 info
, xl_xact_abort
*xlrec
, xl_xact_parsed_abort
*parsed
);
464 extern void ParsePrepareRecord(uint8 info
, xl_xact_prepare
*xlrec
, xl_xact_parsed_prepare
*parsed
);
466 extern void EnterParallelMode(void);
467 extern void ExitParallelMode(void);
468 extern bool IsInParallelMode(void);