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