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