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