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