1 /*------------------------------------------------------------------------- 2 * 3 * xact.h 4 * postgres transaction system definitions 5 * 6 * 7 * Portions Copyright (c) 1996-2021, 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 "datatype/timestamp.h" 20 #include "lib/stringinfo.h" 21 #include "nodes/pg_list.h" 22 #include "storage/relfilenode.h" 23 #include "storage/sinval.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 and 76 * 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 /* used during logical streaming of a transaction */ 86 extern PGDLLIMPORT TransactionId CheckXidAlive; 87 extern PGDLLIMPORT bool bsysscan; 88 89 /* 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 94 * recording flags. 95 */ 96 extern int MyXactFlags; 97 98 /* 99 * XACT_FLAGS_ACCESSEDTEMPNAMESPACE - set when a temporary object is accessed. 100 * We don't allow PREPARE TRANSACTION in that case. 101 */ 102 #define XACT_FLAGS_ACCESSEDTEMPNAMESPACE (1U << 0) 103 104 /* 105 * XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK - records whether the top level xact 106 * logged any Access Exclusive Locks. 107 */ 108 #define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK (1U << 1) 109 110 /* 111 * start- and end-of-transaction callbacks for dynamically loaded modules 112 */ 113 typedef enum 114 { 115 XACT_EVENT_COMMIT, 116 XACT_EVENT_PARALLEL_COMMIT, 117 XACT_EVENT_ABORT, 118 XACT_EVENT_PARALLEL_ABORT, 119 XACT_EVENT_PREPARE, 120 XACT_EVENT_PRE_COMMIT, 121 XACT_EVENT_PARALLEL_PRE_COMMIT, 122 XACT_EVENT_PRE_PREPARE 123 } XactEvent; 124 125 typedef void (*XactCallback) (XactEvent event, void *arg); 126 127 typedef enum 128 { 129 SUBXACT_EVENT_START_SUB, 130 SUBXACT_EVENT_COMMIT_SUB, 131 SUBXACT_EVENT_ABORT_SUB, 132 SUBXACT_EVENT_PRE_COMMIT_SUB 133 } SubXactEvent; 134 135 typedef void (*SubXactCallback) (SubXactEvent event, SubTransactionId mySubid, 136 SubTransactionId parentSubid, void *arg); 137 138 139 /* ---------------- 140 * transaction-related XLOG entries 141 * ---------------- 142 */ 143 144 /* 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. 147 */ 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 */ 156 157 /* mask for filtering opcodes out of xl_info */ 158 #define XLOG_XACT_OPMASK 0x70 159 160 /* does this record have a 'xinfo' field or not */ 161 #define XLOG_XACT_HAS_INFO 0x80 162 163 /* 164 * The following flags, stored in xinfo, determine which information is 165 * contained in commit/abort records. 166 */ 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) 175 176 /* 177 * Also stored in xinfo, these indicating a variety of additional actions that 178 * need to occur when emulating transaction effects during recovery. 179 * 180 * They are named XactCompletion... to differentiate them from 181 * EOXact... routines which run at the end of the original transaction 182 * completion. 183 */ 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) 187 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) 195 196 typedef struct xl_xact_assignment 197 { 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; 202 203 #define MinSizeOfXactAssignment offsetof(xl_xact_assignment, xsub) 204 205 /* 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. 209 * 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. 214 * 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. 218 */ 219 220 /* sub-records for commit/abort */ 221 222 typedef struct xl_xact_xinfo 223 { 224 /* 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. 228 */ 229 uint32 xinfo; 230 } xl_xact_xinfo; 231 232 typedef struct xl_xact_dbinfo 233 { 234 Oid dbId; /* MyDatabaseId */ 235 Oid tsId; /* MyDatabaseTableSpace */ 236 } xl_xact_dbinfo; 237 238 typedef struct xl_xact_subxacts 239 { 240 int nsubxacts; /* number of subtransaction XIDs */ 241 TransactionId subxacts[FLEXIBLE_ARRAY_MEMBER]; 242 } xl_xact_subxacts; 243 #define MinSizeOfXactSubxacts offsetof(xl_xact_subxacts, subxacts) 244 245 typedef struct xl_xact_relfilenodes 246 { 247 int nrels; /* number of relations */ 248 RelFileNode xnodes[FLEXIBLE_ARRAY_MEMBER]; 249 } xl_xact_relfilenodes; 250 #define MinSizeOfXactRelfilenodes offsetof(xl_xact_relfilenodes, xnodes) 251 252 typedef struct xl_xact_invals 253 { 254 int nmsgs; /* number of shared inval msgs */ 255 SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER]; 256 } xl_xact_invals; 257 #define MinSizeOfXactInvals offsetof(xl_xact_invals, msgs) 258 259 typedef struct xl_xact_twophase 260 { 261 TransactionId xid; 262 } xl_xact_twophase; 263 264 typedef struct xl_xact_origin 265 { 266 XLogRecPtr origin_lsn; 267 TimestampTz origin_timestamp; 268 } xl_xact_origin; 269 270 typedef struct xl_xact_commit 271 { 272 TimestampTz xact_time; /* time of commit */ 273 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! */ 282 } xl_xact_commit; 283 #define MinSizeOfXactCommit (offsetof(xl_xact_commit, xact_time) + sizeof(TimestampTz)) 284 285 typedef struct xl_xact_abort 286 { 287 TimestampTz xact_time; /* time of abort */ 288 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! */ 297 } xl_xact_abort; 298 #define MinSizeOfXactAbort sizeof(xl_xact_abort) 299 300 typedef struct xl_xact_prepare 301 { 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 */ 316 } xl_xact_prepare; 317 318 /* 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. 322 */ 323 typedef struct xl_xact_parsed_commit 324 { 325 TimestampTz xact_time; 326 uint32 xinfo; 327 328 Oid dbId; /* MyDatabaseId */ 329 Oid tsId; /* MyDatabaseTableSpace */ 330 331 int nsubxacts; 332 TransactionId *subxacts; 333 334 int nrels; 335 RelFileNode *xnodes; 336 337 int nmsgs; 338 SharedInvalidationMessage *msgs; 339 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 */ 344 345 XLogRecPtr origin_lsn; 346 TimestampTz origin_timestamp; 347 } xl_xact_parsed_commit; 348 349 typedef xl_xact_parsed_commit xl_xact_parsed_prepare; 350 351 typedef struct xl_xact_parsed_abort 352 { 353 TimestampTz xact_time; 354 uint32 xinfo; 355 356 Oid dbId; /* MyDatabaseId */ 357 Oid tsId; /* MyDatabaseTableSpace */ 358 359 int nsubxacts; 360 TransactionId *subxacts; 361 362 int nrels; 363 RelFileNode *xnodes; 364 365 TransactionId twophase_xid; /* only for 2PC */ 366 char twophase_gid[GIDSIZE]; /* only for 2PC */ 367 368 XLogRecPtr origin_lsn; 369 TimestampTz origin_timestamp; 370 } xl_xact_parsed_abort; 371 372 373 /* ---------------- 374 * extern definitions 375 * ---------------- 376 */ 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); 435 436 extern bool IsSubTransactionAssignmentPending(void); 437 extern void MarkSubTransactionAssigned(void); 438 439 extern int xactGetCommittedChildren(TransactionId **ptr); 440 441 extern XLogRecPtr XactLogCommitRecord(TimestampTz commit_time, 442 int nsubxacts, TransactionId *subxacts, 443 int nrels, RelFileNode *rels, 444 int nmsgs, SharedInvalidationMessage *msgs, 445 bool relcacheInval, 446 int xactflags, 447 TransactionId twophase_xid, 448 const char *twophase_gid); 449 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); 456 457 /* xactdesc.c */ 458 extern void xact_desc(StringInfo buf, XLogReaderState *record); 459 extern const char *xact_identify(uint8 info); 460 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); 465 466 extern void EnterParallelMode(void); 467 extern void ExitParallelMode(void); 468 extern bool IsInParallelMode(void); 469 470 #endif /* XACT_H */ 471