1 /*-------------------------------------------------------------------------
4 * top level transaction system support routines
6 * See src/backend/access/transam/README for more information.
8 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
13 * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.285 2010/02/13 16:15:46 sriggs Exp $
15 *-------------------------------------------------------------------------
23 #include "access/multixact.h"
24 #include "access/subtrans.h"
25 #include "access/transam.h"
26 #include "access/twophase.h"
27 #include "access/xact.h"
28 #include "access/xlogutils.h"
29 #include "catalog/catalog.h"
30 #include "catalog/namespace.h"
31 #include "catalog/storage.h"
32 #include "commands/async.h"
33 #include "commands/tablecmds.h"
34 #include "commands/trigger.h"
35 #include "executor/spi.h"
36 #include "libpq/be-fsstubs.h"
37 #include "miscadmin.h"
39 #include "storage/bufmgr.h"
40 #include "storage/fd.h"
41 #include "storage/lmgr.h"
42 #include "storage/procarray.h"
43 #include "storage/sinvaladt.h"
44 #include "storage/smgr.h"
45 #include "storage/standby.h"
46 #include "utils/combocid.h"
47 #include "utils/guc.h"
48 #include "utils/inval.h"
49 #include "utils/memutils.h"
50 #include "utils/relcache.h"
51 #include "utils/relmapper.h"
52 #include "utils/snapmgr.h"
57 * User-tweakable parameters
59 int DefaultXactIsoLevel = XACT_READ_COMMITTED;
62 bool DefaultXactReadOnly = false;
65 bool XactSyncCommit = true;
67 int CommitDelay = 0; /* precommit delay in microseconds */
68 int CommitSiblings = 5; /* # concurrent xacts needed to sleep */
71 * MyXactAccessedTempRel is set when a temporary relation is accessed.
72 * We don't allow PREPARE TRANSACTION in that case. (This is global
73 * so that it can be set from heapam.c.)
75 bool MyXactAccessedTempRel = false;
79 * transaction states - transaction state from server perspective
81 typedef enum TransState
83 TRANS_DEFAULT, /* idle */
84 TRANS_START, /* transaction starting */
85 TRANS_INPROGRESS, /* inside a valid transaction */
86 TRANS_COMMIT, /* commit in progress */
87 TRANS_ABORT, /* abort in progress */
88 TRANS_PREPARE /* prepare in progress */
92 * transaction block states - transaction state of client queries
94 * Note: the subtransaction states are used only for non-topmost
95 * transactions; the others appear only in the topmost transaction.
97 typedef enum TBlockState
99 /* not-in-transaction-block states */
100 TBLOCK_DEFAULT, /* idle */
101 TBLOCK_STARTED, /* running single-query transaction */
103 /* transaction block states */
104 TBLOCK_BEGIN, /* starting transaction block */
105 TBLOCK_INPROGRESS, /* live transaction */
106 TBLOCK_END, /* COMMIT received */
107 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
108 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
109 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
110 TBLOCK_PREPARE, /* live xact, PREPARE received */
112 /* subtransaction states */
113 TBLOCK_SUBBEGIN, /* starting a subtransaction */
114 TBLOCK_SUBINPROGRESS, /* live subtransaction */
115 TBLOCK_SUBEND, /* RELEASE received */
116 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
117 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
118 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
119 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
120 TBLOCK_SUBABORT_RESTART /* failed subxact, ROLLBACK TO received */
124 * transaction state structure
126 typedef struct TransactionStateData
128 TransactionId transactionId; /* my XID, or Invalid if none */
129 SubTransactionId subTransactionId; /* my subxact ID */
130 char *name; /* savepoint name, if any */
131 int savepointLevel; /* savepoint level */
132 TransState state; /* low-level state */
133 TBlockState blockState; /* high-level state */
134 int nestingLevel; /* transaction nesting depth */
135 int gucNestLevel; /* GUC context nesting depth */
136 MemoryContext curTransactionContext; /* my xact-lifetime context */
137 ResourceOwner curTransactionOwner; /* my query resources */
138 TransactionId *childXids; /* subcommitted child XIDs, in XID order */
139 int nChildXids; /* # of subcommitted child XIDs */
140 int maxChildXids; /* allocated size of childXids[] */
141 Oid prevUser; /* previous CurrentUserId setting */
142 int prevSecContext; /* previous SecurityRestrictionContext */
143 bool prevXactReadOnly; /* entry-time xact r/o state */
144 bool startedInRecovery; /* did we start in recovery? */
145 struct TransactionStateData *parent; /* back link to parent */
146 } TransactionStateData;
148 typedef TransactionStateData *TransactionState;
151 * CurrentTransactionState always points to the current transaction state
152 * block. It will point to TopTransactionStateData when not in a
153 * transaction at all, or when in a top-level transaction.
155 static TransactionStateData TopTransactionStateData = {
156 0, /* transaction id */
157 0, /* subtransaction id */
158 NULL, /* savepoint name */
159 0, /* savepoint level */
160 TRANS_DEFAULT, /* transaction state */
161 TBLOCK_DEFAULT, /* transaction block state from the client
163 0, /* transaction nesting depth */
164 0, /* GUC context nesting depth */
165 NULL, /* cur transaction context */
166 NULL, /* cur transaction resource owner */
167 NULL, /* subcommitted child Xids */
168 0, /* # of subcommitted child Xids */
169 0, /* allocated size of childXids[] */
170 InvalidOid, /* previous CurrentUserId setting */
171 0, /* previous SecurityRestrictionContext */
172 false, /* entry-time xact r/o state */
173 false, /* startedInRecovery */
174 NULL /* link to parent state block */
178 * unreportedXids holds XIDs of all subtransactions that have not yet been
179 * reported in a XLOG_XACT_ASSIGNMENT record.
181 static int nUnreportedXids;
182 static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS];
184 static TransactionState CurrentTransactionState = &TopTransactionStateData;
187 * The subtransaction ID and command ID assignment counters are global
188 * to a whole transaction, so we do not keep them in the state stack.
190 static SubTransactionId currentSubTransactionId;
191 static CommandId currentCommandId;
192 static bool currentCommandIdUsed;
195 * xactStartTimestamp is the value of transaction_timestamp().
196 * stmtStartTimestamp is the value of statement_timestamp().
197 * xactStopTimestamp is the time at which we log a commit or abort WAL record.
198 * These do not change as we enter and exit subtransactions, so we don't
199 * keep them inside the TransactionState stack.
201 static TimestampTz xactStartTimestamp;
202 static TimestampTz stmtStartTimestamp;
203 static TimestampTz xactStopTimestamp;
206 * GID to be used for preparing the current transaction. This is also
207 * global to a whole transaction, so we don't keep it in the state stack.
209 static char *prepareGID;
212 * Some commands want to force synchronous commit.
214 static bool forceSyncCommit = false;
217 * Private context for transaction-abort work --- we reserve space for this
218 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
219 * when we've run out of memory.
221 static MemoryContext TransactionAbortContext = NULL;
224 * List of add-on start- and end-of-xact callbacks
226 typedef struct XactCallbackItem
228 struct XactCallbackItem *next;
229 XactCallback callback;
233 static XactCallbackItem *Xact_callbacks = NULL;
236 * List of add-on start- and end-of-subxact callbacks
238 typedef struct SubXactCallbackItem
240 struct SubXactCallbackItem *next;
241 SubXactCallback callback;
243 } SubXactCallbackItem;
245 static SubXactCallbackItem *SubXact_callbacks = NULL;
248 /* local function prototypes */
249 static void AssignTransactionId(TransactionState s);
250 static void AbortTransaction(void);
251 static void AtAbort_Memory(void);
252 static void AtCleanup_Memory(void);
253 static void AtAbort_ResourceOwner(void);
254 static void AtCCI_LocalCache(void);
255 static void AtCommit_Memory(void);
256 static void AtStart_Cache(void);
257 static void AtStart_Memory(void);
258 static void AtStart_ResourceOwner(void);
259 static void CallXactCallbacks(XactEvent event);
260 static void CallSubXactCallbacks(SubXactEvent event,
261 SubTransactionId mySubid,
262 SubTransactionId parentSubid);
263 static void CleanupTransaction(void);
264 static void CommitTransaction(void);
265 static TransactionId RecordTransactionAbort(bool isSubXact);
266 static void StartTransaction(void);
268 static void StartSubTransaction(void);
269 static void CommitSubTransaction(void);
270 static void AbortSubTransaction(void);
271 static void CleanupSubTransaction(void);
272 static void PushTransaction(void);
273 static void PopTransaction(void);
275 static void AtSubAbort_Memory(void);
276 static void AtSubCleanup_Memory(void);
277 static void AtSubAbort_ResourceOwner(void);
278 static void AtSubCommit_Memory(void);
279 static void AtSubStart_Memory(void);
280 static void AtSubStart_ResourceOwner(void);
282 static void ShowTransactionState(const char *str);
283 static void ShowTransactionStateRec(TransactionState state);
284 static const char *BlockStateAsString(TBlockState blockState);
285 static const char *TransStateAsString(TransState state);
288 /* ----------------------------------------------------------------
289 * transaction state accessors
290 * ----------------------------------------------------------------
296 * This returns true if we are inside a valid transaction; that is,
297 * it is safe to initiate database access, take heavyweight locks, etc.
300 IsTransactionState(void)
302 TransactionState s = CurrentTransactionState;
305 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
306 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
307 * TRANS_PREPARE since it might be too soon or too late within those
308 * transition states to do anything interesting. Hence, the only "valid"
309 * state is TRANS_INPROGRESS.
311 return (s->state == TRANS_INPROGRESS);
315 * IsAbortedTransactionBlockState
317 * This returns true if we are within an aborted transaction block.
320 IsAbortedTransactionBlockState(void)
322 TransactionState s = CurrentTransactionState;
324 if (s->blockState == TBLOCK_ABORT ||
325 s->blockState == TBLOCK_SUBABORT)
333 * GetTopTransactionId
335 * This will return the XID of the main transaction, assigning one if
336 * it's not yet set. Be careful to call this only inside a valid xact.
339 GetTopTransactionId(void)
341 if (!TransactionIdIsValid(TopTransactionStateData.transactionId))
342 AssignTransactionId(&TopTransactionStateData);
343 return TopTransactionStateData.transactionId;
347 * GetTopTransactionIdIfAny
349 * This will return the XID of the main transaction, if one is assigned.
350 * It will return InvalidTransactionId if we are not currently inside a
351 * transaction, or inside a transaction that hasn't yet been assigned an XID.
354 GetTopTransactionIdIfAny(void)
356 return TopTransactionStateData.transactionId;
360 * GetCurrentTransactionId
362 * This will return the XID of the current transaction (main or sub
363 * transaction), assigning one if it's not yet set. Be careful to call this
364 * only inside a valid xact.
367 GetCurrentTransactionId(void)
369 TransactionState s = CurrentTransactionState;
371 if (!TransactionIdIsValid(s->transactionId))
372 AssignTransactionId(s);
373 return s->transactionId;
377 * GetCurrentTransactionIdIfAny
379 * This will return the XID of the current sub xact, if one is assigned.
380 * It will return InvalidTransactionId if we are not currently inside a
381 * transaction, or inside a transaction that hasn't been assigned an XID yet.
384 GetCurrentTransactionIdIfAny(void)
386 return CurrentTransactionState->transactionId;
391 * AssignTransactionId
393 * Assigns a new permanent XID to the given TransactionState.
394 * We do not assign XIDs to transactions until/unless this is called.
395 * Also, any parent TransactionStates that don't yet have XIDs are assigned
396 * one; this maintains the invariant that a child transaction has an XID
397 * following its parent's.
400 AssignTransactionId(TransactionState s)
402 bool isSubXact = (s->parent != NULL);
403 ResourceOwner currentOwner;
405 if (RecoveryInProgress())
406 elog(ERROR, "cannot assign TransactionIds during recovery");
408 /* Assert that caller didn't screw up */
409 Assert(!TransactionIdIsValid(s->transactionId));
410 Assert(s->state == TRANS_INPROGRESS);
413 * Ensure parent(s) have XIDs, so that a child always has an XID later
416 if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
417 AssignTransactionId(s->parent);
420 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
422 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
423 * shared storage other than PG_PROC; because if there's no room for it in
424 * PG_PROC, the subtrans entry is needed to ensure that other backends see
425 * the Xid as "running". See GetNewTransactionId.
427 s->transactionId = GetNewTransactionId(isSubXact);
430 SubTransSetParent(s->transactionId, s->parent->transactionId, false);
433 * Acquire lock on the transaction XID. (We assume this cannot block.) We
434 * have to ensure that the lock is assigned to the transaction's own
437 currentOwner = CurrentResourceOwner;
440 CurrentResourceOwner = s->curTransactionOwner;
441 XactLockTableInsert(s->transactionId);
445 /* Ensure CurrentResourceOwner is restored on error */
446 CurrentResourceOwner = currentOwner;
450 CurrentResourceOwner = currentOwner;
453 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
454 * top-level transaction we issue a WAL record for the assignment. We
455 * include the top-level xid and all the subxids that have not yet been
456 * reported using XLOG_XACT_ASSIGNMENT records.
458 * This is required to limit the amount of shared memory required in a
459 * hot standby server to keep track of in-progress XIDs. See notes for
460 * RecordKnownAssignedTransactionIds().
462 * We don't keep track of the immediate parent of each subxid,
463 * only the top-level transaction that each subxact belongs to. This
464 * is correct in recovery only because aborted subtransactions are
465 * separately WAL logged.
467 if (isSubXact && XLogStandbyInfoActive())
469 unreportedXids[nUnreportedXids] = s->transactionId;
472 /* ensure this test matches similar one in RecoverPreparedTransactions() */
473 if (nUnreportedXids >= PGPROC_MAX_CACHED_SUBXIDS)
475 XLogRecData rdata[2];
476 xl_xact_assignment xlrec;
479 * xtop is always set by now because we recurse up transaction
480 * stack to the highest unassigned xid and then come back down
482 xlrec.xtop = GetTopTransactionId();
483 Assert(TransactionIdIsValid(xlrec.xtop));
484 xlrec.nsubxacts = nUnreportedXids;
486 rdata[0].data = (char *) &xlrec;
487 rdata[0].len = MinSizeOfXactAssignment;
488 rdata[0].buffer = InvalidBuffer;
489 rdata[0].next = &rdata[1];
491 rdata[1].data = (char *) unreportedXids;
492 rdata[1].len = PGPROC_MAX_CACHED_SUBXIDS * sizeof(TransactionId);
493 rdata[1].buffer = InvalidBuffer;
494 rdata[1].next = NULL;
496 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT, rdata);
504 * GetCurrentSubTransactionId
507 GetCurrentSubTransactionId(void)
509 TransactionState s = CurrentTransactionState;
511 return s->subTransactionId;
516 * GetCurrentCommandId
518 * "used" must be TRUE if the caller intends to use the command ID to mark
519 * inserted/updated/deleted tuples. FALSE means the ID is being fetched
520 * for read-only purposes (ie, as a snapshot validity cutoff). See
521 * CommandCounterIncrement() for discussion.
524 GetCurrentCommandId(bool used)
526 /* this is global to a transaction, not subtransaction-local */
528 currentCommandIdUsed = true;
529 return currentCommandId;
533 * GetCurrentTransactionStartTimestamp
536 GetCurrentTransactionStartTimestamp(void)
538 return xactStartTimestamp;
542 * GetCurrentStatementStartTimestamp
545 GetCurrentStatementStartTimestamp(void)
547 return stmtStartTimestamp;
551 * GetCurrentTransactionStopTimestamp
553 * We return current time if the transaction stop time hasn't been set
554 * (which can happen if we decide we don't need to log an XLOG record).
557 GetCurrentTransactionStopTimestamp(void)
559 if (xactStopTimestamp != 0)
560 return xactStopTimestamp;
561 return GetCurrentTimestamp();
565 * SetCurrentStatementStartTimestamp
568 SetCurrentStatementStartTimestamp(void)
570 stmtStartTimestamp = GetCurrentTimestamp();
574 * SetCurrentTransactionStopTimestamp
577 SetCurrentTransactionStopTimestamp(void)
579 xactStopTimestamp = GetCurrentTimestamp();
583 * GetCurrentTransactionNestLevel
585 * Note: this will return zero when not inside any transaction, one when
586 * inside a top-level transaction, etc.
589 GetCurrentTransactionNestLevel(void)
591 TransactionState s = CurrentTransactionState;
593 return s->nestingLevel;
598 * TransactionIdIsCurrentTransactionId
601 TransactionIdIsCurrentTransactionId(TransactionId xid)
606 * We always say that BootstrapTransactionId is "not my transaction ID"
607 * even when it is (ie, during bootstrap). Along with the fact that
608 * transam.c always treats BootstrapTransactionId as already committed,
609 * this causes the tqual.c routines to see all tuples as committed, which
610 * is what we need during bootstrap. (Bootstrap mode only inserts tuples,
611 * it never updates or deletes them, so all tuples can be presumed good
614 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
615 * not my transaction ID, so we can just return "false" immediately for
616 * any non-normal XID.
618 if (!TransactionIdIsNormal(xid))
622 * We will return true for the Xid of the current subtransaction, any of
623 * its subcommitted children, any of its parents, or any of their
624 * previously subcommitted children. However, a transaction being aborted
625 * is no longer "current", even though it may still have an entry on the
628 for (s = CurrentTransactionState; s != NULL; s = s->parent)
633 if (s->state == TRANS_ABORT)
635 if (!TransactionIdIsValid(s->transactionId))
636 continue; /* it can't have any child XIDs either */
637 if (TransactionIdEquals(xid, s->transactionId))
639 /* As the childXids array is ordered, we can use binary search */
641 high = s->nChildXids - 1;
647 middle = low + (high - low) / 2;
648 probe = s->childXids[middle];
649 if (TransactionIdEquals(probe, xid))
651 else if (TransactionIdPrecedes(probe, xid))
662 * TransactionStartedDuringRecovery
664 * Returns true if the current transaction started while recovery was still
665 * in progress. Recovery might have ended since so RecoveryInProgress() might
666 * return false already.
669 TransactionStartedDuringRecovery(void)
671 return CurrentTransactionState->startedInRecovery;
675 * CommandCounterIncrement
678 CommandCounterIncrement(void)
681 * If the current value of the command counter hasn't been "used" to mark
682 * tuples, we need not increment it, since there's no need to distinguish
683 * a read-only command from others. This helps postpone command counter
684 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
686 if (currentCommandIdUsed)
688 currentCommandId += 1;
689 if (currentCommandId == FirstCommandId) /* check for overflow */
691 currentCommandId -= 1;
693 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
694 errmsg("cannot have more than 2^32-1 commands in a transaction")));
696 currentCommandIdUsed = false;
698 /* Propagate new command ID into static snapshots */
699 SnapshotSetCommandId(currentCommandId);
702 * Make any catalog changes done by the just-completed command visible
703 * in the local syscache. We obviously don't need to do this after a
704 * read-only command. (But see hacks in inval.c to make real sure we
705 * don't think a command that queued inval messages was read-only.)
711 * Make any other backends' catalog changes visible to me.
713 * XXX this is probably in the wrong place: CommandCounterIncrement should
714 * be purely a local operation, most likely. However fooling with this
715 * will affect asynchronous cross-backend interactions, which doesn't seem
716 * like a wise thing to do in late beta, so save improving this for
717 * another day - tgl 2007-11-30
725 * Interface routine to allow commands to force a synchronous commit of the
726 * current top-level transaction
729 ForceSyncCommit(void)
731 forceSyncCommit = true;
735 /* ----------------------------------------------------------------
736 * StartTransaction stuff
737 * ----------------------------------------------------------------
746 AcceptInvalidationMessages();
755 TransactionState s = CurrentTransactionState;
758 * If this is the first time through, create a private context for
759 * AbortTransaction to work in. By reserving some space now, we can
760 * insulate AbortTransaction from out-of-memory scenarios. Like
761 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
762 * size, so that space will be reserved immediately.
764 if (TransactionAbortContext == NULL)
765 TransactionAbortContext =
766 AllocSetContextCreate(TopMemoryContext,
767 "TransactionAbortContext",
773 * We shouldn't have a transaction context already.
775 Assert(TopTransactionContext == NULL);
778 * Create a toplevel context for the transaction.
780 TopTransactionContext =
781 AllocSetContextCreate(TopMemoryContext,
782 "TopTransactionContext",
783 ALLOCSET_DEFAULT_MINSIZE,
784 ALLOCSET_DEFAULT_INITSIZE,
785 ALLOCSET_DEFAULT_MAXSIZE);
788 * In a top-level transaction, CurTransactionContext is the same as
789 * TopTransactionContext.
791 CurTransactionContext = TopTransactionContext;
792 s->curTransactionContext = CurTransactionContext;
794 /* Make the CurTransactionContext active. */
795 MemoryContextSwitchTo(CurTransactionContext);
799 * AtStart_ResourceOwner
802 AtStart_ResourceOwner(void)
804 TransactionState s = CurrentTransactionState;
807 * We shouldn't have a transaction resource owner already.
809 Assert(TopTransactionResourceOwner == NULL);
812 * Create a toplevel resource owner for the transaction.
814 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
816 TopTransactionResourceOwner = s->curTransactionOwner;
817 CurTransactionResourceOwner = s->curTransactionOwner;
818 CurrentResourceOwner = s->curTransactionOwner;
821 /* ----------------------------------------------------------------
822 * StartSubTransaction stuff
823 * ----------------------------------------------------------------
830 AtSubStart_Memory(void)
832 TransactionState s = CurrentTransactionState;
834 Assert(CurTransactionContext != NULL);
837 * Create a CurTransactionContext, which will be used to hold data that
838 * survives subtransaction commit but disappears on subtransaction abort.
839 * We make it a child of the immediate parent's CurTransactionContext.
841 CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
842 "CurTransactionContext",
843 ALLOCSET_DEFAULT_MINSIZE,
844 ALLOCSET_DEFAULT_INITSIZE,
845 ALLOCSET_DEFAULT_MAXSIZE);
846 s->curTransactionContext = CurTransactionContext;
848 /* Make the CurTransactionContext active. */
849 MemoryContextSwitchTo(CurTransactionContext);
853 * AtSubStart_ResourceOwner
856 AtSubStart_ResourceOwner(void)
858 TransactionState s = CurrentTransactionState;
860 Assert(s->parent != NULL);
863 * Create a resource owner for the subtransaction. We make it a child of
864 * the immediate parent's resource owner.
866 s->curTransactionOwner =
867 ResourceOwnerCreate(s->parent->curTransactionOwner,
870 CurTransactionResourceOwner = s->curTransactionOwner;
871 CurrentResourceOwner = s->curTransactionOwner;
874 /* ----------------------------------------------------------------
875 * CommitTransaction stuff
876 * ----------------------------------------------------------------
880 * RecordTransactionCommit
882 * Returns latest XID among xact and its children, or InvalidTransactionId
883 * if the xact has no XID. (We compute that here just because it's easier.)
886 RecordTransactionCommit(void)
888 TransactionId xid = GetTopTransactionIdIfAny();
889 bool markXidCommitted = TransactionIdIsValid(xid);
890 TransactionId latestXid = InvalidTransactionId;
895 TransactionId *children;
897 SharedInvalidationMessage *invalMessages = NULL;
898 bool RelcacheInitFileInval;
900 /* Get data needed for commit record */
901 nrels = smgrGetPendingDeletes(true, &rels, &haveNonTemp);
902 nchildren = xactGetCommittedChildren(&children);
903 nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
904 &RelcacheInitFileInval);
906 * If we haven't been assigned an XID yet, we neither can, nor do we want
907 * to write a COMMIT record.
909 if (!markXidCommitted)
912 * We expect that every smgrscheduleunlink is followed by a catalog
913 * update, and hence XID assignment, so we shouldn't get here with any
914 * pending deletes. Use a real test not just an Assert to check this,
915 * since it's a bit fragile.
918 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
920 /* Can't have child XIDs either; AssignTransactionId enforces this */
921 Assert(nchildren == 0);
924 * If we didn't create XLOG entries, we're done here; otherwise we
925 * should flush those entries the same as a commit record. (An
926 * example of a possible record that wouldn't cause an XID to be
927 * assigned is a sequence advance record due to nextval() --- we want
928 * to flush that to disk before reporting commit.)
930 if (XactLastRecEnd.xrecoff == 0)
936 * Begin commit critical section and insert the commit XLOG record.
938 XLogRecData rdata[4];
940 xl_xact_commit xlrec;
942 /* Tell bufmgr and smgr to prepare for commit */
946 * Set flags required for recovery processing of commits.
949 if (RelcacheInitFileInval)
950 xlrec.xinfo |= XACT_COMPLETION_UPDATE_RELCACHE_FILE;
952 xlrec.xinfo |= XACT_COMPLETION_FORCE_SYNC_COMMIT;
954 xlrec.dbId = MyDatabaseId;
955 xlrec.tsId = MyDatabaseTableSpace;
958 * Mark ourselves as within our "commit critical section". This
959 * forces any concurrent checkpoint to wait until we've updated
960 * pg_clog. Without this, it is possible for the checkpoint to set
961 * REDO after the XLOG record but fail to flush the pg_clog update to
962 * disk, leading to loss of the transaction commit if the system
963 * crashes a little later.
965 * Note: we could, but don't bother to, set this flag in
966 * RecordTransactionAbort. That's because loss of a transaction abort
967 * is noncritical; the presumption would be that it aborted, anyway.
969 * It's safe to change the inCommit flag of our own backend without
970 * holding the ProcArrayLock, since we're the only one modifying it.
971 * This makes checkpoint's determination of which xacts are inCommit a
972 * bit fuzzy, but it doesn't matter.
974 START_CRIT_SECTION();
975 MyProc->inCommit = true;
977 SetCurrentTransactionStopTimestamp();
978 xlrec.xact_time = xactStopTimestamp;
980 xlrec.nsubxacts = nchildren;
982 rdata[0].data = (char *) (&xlrec);
983 rdata[0].len = MinSizeOfXactCommit;
984 rdata[0].buffer = InvalidBuffer;
985 /* dump rels to delete */
988 rdata[0].next = &(rdata[1]);
989 rdata[1].data = (char *) rels;
990 rdata[1].len = nrels * sizeof(RelFileNode);
991 rdata[1].buffer = InvalidBuffer;
994 /* dump committed child Xids */
997 rdata[lastrdata].next = &(rdata[2]);
998 rdata[2].data = (char *) children;
999 rdata[2].len = nchildren * sizeof(TransactionId);
1000 rdata[2].buffer = InvalidBuffer;
1003 /* dump shared cache invalidation messages */
1006 rdata[lastrdata].next = &(rdata[3]);
1007 rdata[3].data = (char *) invalMessages;
1008 rdata[3].len = nmsgs * sizeof(SharedInvalidationMessage);
1009 rdata[3].buffer = InvalidBuffer;
1012 rdata[lastrdata].next = NULL;
1014 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
1018 * Check if we want to commit asynchronously. If the user has set
1019 * synchronous_commit = off, and we're not doing cleanup of any non-temp
1020 * rels nor committing any command that wanted to force sync commit, then
1021 * we can defer flushing XLOG. (We must not allow asynchronous commit if
1022 * there are any non-temp tables to be deleted, because we might delete
1023 * the files before the COMMIT record is flushed to disk. We do allow
1024 * asynchronous commit if all to-be-deleted tables are temporary though,
1025 * since they are lost anyway if we crash.)
1027 if (XactSyncCommit || forceSyncCommit || haveNonTemp)
1030 * Synchronous commit case.
1032 * Sleep before flush! So we can flush more than one commit records
1033 * per single fsync. (The idea is some other backend may do the
1034 * XLogFlush while we're sleeping. This needs work still, because on
1035 * most Unixen, the minimum select() delay is 10msec or more, which is
1038 * We do not sleep if enableFsync is not turned on, nor if there are
1039 * fewer than CommitSiblings other backends with active transactions.
1041 if (CommitDelay > 0 && enableFsync &&
1042 CountActiveBackends() >= CommitSiblings)
1043 pg_usleep(CommitDelay);
1045 XLogFlush(XactLastRecEnd);
1048 * Now we may update the CLOG, if we wrote a COMMIT record above
1050 if (markXidCommitted)
1051 TransactionIdCommitTree(xid, nchildren, children);
1056 * Asynchronous commit case.
1058 * Report the latest async commit LSN, so that the WAL writer knows to
1059 * flush this commit.
1061 XLogSetAsyncCommitLSN(XactLastRecEnd);
1064 * We must not immediately update the CLOG, since we didn't flush the
1065 * XLOG. Instead, we store the LSN up to which the XLOG must be
1066 * flushed before the CLOG may be updated.
1068 if (markXidCommitted)
1069 TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1073 * If we entered a commit critical section, leave it now, and let
1074 * checkpoints proceed.
1076 if (markXidCommitted)
1078 MyProc->inCommit = false;
1082 /* Compute latestXid while we have the child XIDs handy */
1083 latestXid = TransactionIdLatest(xid, nchildren, children);
1085 /* Reset XactLastRecEnd until the next transaction writes something */
1086 XactLastRecEnd.xrecoff = 0;
1089 /* Clean up local data */
1101 AtCCI_LocalCache(void)
1104 * Make any pending relation map changes visible. We must do this
1105 * before processing local sinval messages, so that the map changes
1106 * will get reflected into the relcache when relcache invals are
1109 AtCCI_RelationMap();
1112 * Make catalog changes visible to me for the next command.
1114 CommandEndInvalidationMessages();
1121 AtCommit_Memory(void)
1124 * Now that we're "out" of a transaction, have the system allocate things
1125 * in the top memory context instead of per-transaction contexts.
1127 MemoryContextSwitchTo(TopMemoryContext);
1130 * Release all transaction-local memory.
1132 Assert(TopTransactionContext != NULL);
1133 MemoryContextDelete(TopTransactionContext);
1134 TopTransactionContext = NULL;
1135 CurTransactionContext = NULL;
1136 CurrentTransactionState->curTransactionContext = NULL;
1139 /* ----------------------------------------------------------------
1140 * CommitSubTransaction stuff
1141 * ----------------------------------------------------------------
1145 * AtSubCommit_Memory
1148 AtSubCommit_Memory(void)
1150 TransactionState s = CurrentTransactionState;
1152 Assert(s->parent != NULL);
1154 /* Return to parent transaction level's memory context. */
1155 CurTransactionContext = s->parent->curTransactionContext;
1156 MemoryContextSwitchTo(CurTransactionContext);
1159 * Ordinarily we cannot throw away the child's CurTransactionContext,
1160 * since the data it contains will be needed at upper commit. However, if
1161 * there isn't actually anything in it, we can throw it away. This avoids
1162 * a small memory leak in the common case of "trivial" subxacts.
1164 if (MemoryContextIsEmpty(s->curTransactionContext))
1166 MemoryContextDelete(s->curTransactionContext);
1167 s->curTransactionContext = NULL;
1172 * AtSubCommit_childXids
1174 * Pass my own XID and my child XIDs up to my parent as committed children.
1177 AtSubCommit_childXids(void)
1179 TransactionState s = CurrentTransactionState;
1182 Assert(s->parent != NULL);
1185 * The parent childXids array will need to hold my XID and all my
1186 * childXids, in addition to the XIDs already there.
1188 new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1190 /* Allocate or enlarge the parent array if necessary */
1191 if (s->parent->maxChildXids < new_nChildXids)
1193 int new_maxChildXids;
1194 TransactionId *new_childXids;
1197 * Make it 2x what's needed right now, to avoid having to enlarge it
1198 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1199 * is what ensures that we don't need to worry about integer overflow
1200 * here or in the calculation of new_nChildXids.)
1202 new_maxChildXids = Min(new_nChildXids * 2,
1203 (int) (MaxAllocSize / sizeof(TransactionId)));
1205 if (new_maxChildXids < new_nChildXids)
1207 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1208 errmsg("maximum number of committed subtransactions (%d) exceeded",
1209 (int) (MaxAllocSize / sizeof(TransactionId)))));
1212 * We keep the child-XID arrays in TopTransactionContext; this avoids
1213 * setting up child-transaction contexts for what might be just a few
1214 * bytes of grandchild XIDs.
1216 if (s->parent->childXids == NULL)
1218 MemoryContextAlloc(TopTransactionContext,
1219 new_maxChildXids * sizeof(TransactionId));
1221 new_childXids = repalloc(s->parent->childXids,
1222 new_maxChildXids * sizeof(TransactionId));
1224 s->parent->childXids = new_childXids;
1225 s->parent->maxChildXids = new_maxChildXids;
1229 * Copy all my XIDs to parent's array.
1231 * Note: We rely on the fact that the XID of a child always follows that
1232 * of its parent. By copying the XID of this subtransaction before the
1233 * XIDs of its children, we ensure that the array stays ordered.
1234 * Likewise, all XIDs already in the array belong to subtransactions
1235 * started and subcommitted before us, so their XIDs must precede ours.
1237 s->parent->childXids[s->parent->nChildXids] = s->transactionId;
1239 if (s->nChildXids > 0)
1240 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1242 s->nChildXids * sizeof(TransactionId));
1244 s->parent->nChildXids = new_nChildXids;
1246 /* Release child's array to avoid leakage */
1247 if (s->childXids != NULL)
1248 pfree(s->childXids);
1249 /* We must reset these to avoid double-free if fail later in commit */
1250 s->childXids = NULL;
1252 s->maxChildXids = 0;
1255 /* ----------------------------------------------------------------
1256 * AbortTransaction stuff
1257 * ----------------------------------------------------------------
1261 * RecordTransactionAbort
1263 * Returns latest XID among xact and its children, or InvalidTransactionId
1264 * if the xact has no XID. (We compute that here just because it's easier.)
1266 static TransactionId
1267 RecordTransactionAbort(bool isSubXact)
1269 TransactionId xid = GetCurrentTransactionIdIfAny();
1270 TransactionId latestXid;
1274 TransactionId *children;
1275 XLogRecData rdata[3];
1277 xl_xact_abort xlrec;
1280 * If we haven't been assigned an XID, nobody will care whether we aborted
1281 * or not. Hence, we're done in that case. It does not matter if we have
1282 * rels to delete (note that this routine is not responsible for actually
1283 * deleting 'em). We cannot have any child XIDs, either.
1285 if (!TransactionIdIsValid(xid))
1287 /* Reset XactLastRecEnd until the next transaction writes something */
1289 XactLastRecEnd.xrecoff = 0;
1290 return InvalidTransactionId;
1294 * We have a valid XID, so we should write an ABORT record for it.
1296 * We do not flush XLOG to disk here, since the default assumption after a
1297 * crash would be that we aborted, anyway. For the same reason, we don't
1298 * need to worry about interlocking against checkpoint start.
1302 * Check that we haven't aborted halfway through RecordTransactionCommit.
1304 if (TransactionIdDidCommit(xid))
1305 elog(PANIC, "cannot abort transaction %u, it was already committed",
1308 /* Fetch the data we need for the abort record */
1309 nrels = smgrGetPendingDeletes(false, &rels, NULL);
1310 nchildren = xactGetCommittedChildren(&children);
1312 /* XXX do we really need a critical section here? */
1313 START_CRIT_SECTION();
1315 /* Write the ABORT record */
1317 xlrec.xact_time = GetCurrentTimestamp();
1320 SetCurrentTransactionStopTimestamp();
1321 xlrec.xact_time = xactStopTimestamp;
1323 xlrec.nrels = nrels;
1324 xlrec.nsubxacts = nchildren;
1325 rdata[0].data = (char *) (&xlrec);
1326 rdata[0].len = MinSizeOfXactAbort;
1327 rdata[0].buffer = InvalidBuffer;
1328 /* dump rels to delete */
1331 rdata[0].next = &(rdata[1]);
1332 rdata[1].data = (char *) rels;
1333 rdata[1].len = nrels * sizeof(RelFileNode);
1334 rdata[1].buffer = InvalidBuffer;
1337 /* dump committed child Xids */
1340 rdata[lastrdata].next = &(rdata[2]);
1341 rdata[2].data = (char *) children;
1342 rdata[2].len = nchildren * sizeof(TransactionId);
1343 rdata[2].buffer = InvalidBuffer;
1346 rdata[lastrdata].next = NULL;
1348 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
1351 * Mark the transaction aborted in clog. This is not absolutely necessary
1352 * but we may as well do it while we are here; also, in the subxact case
1353 * it is helpful because XactLockTableWait makes use of it to avoid
1354 * waiting for already-aborted subtransactions. It is OK to do it without
1355 * having flushed the ABORT record to disk, because in event of a crash
1356 * we'd be assumed to have aborted anyway.
1358 TransactionIdAbortTree(xid, nchildren, children);
1362 /* Compute latestXid while we have the child XIDs handy */
1363 latestXid = TransactionIdLatest(xid, nchildren, children);
1366 * If we're aborting a subtransaction, we can immediately remove failed
1367 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1368 * subxacts, because we already have the child XID array at hand. For
1369 * main xacts, the equivalent happens just after this function returns.
1372 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1374 /* Reset XactLastRecEnd until the next transaction writes something */
1376 XactLastRecEnd.xrecoff = 0;
1378 /* And clean up local data */
1389 AtAbort_Memory(void)
1392 * Switch into TransactionAbortContext, which should have some free space
1393 * even if nothing else does. We'll work in this context until we've
1394 * finished cleaning up.
1396 * It is barely possible to get here when we've not been able to create
1397 * TransactionAbortContext yet; if so use TopMemoryContext.
1399 if (TransactionAbortContext != NULL)
1400 MemoryContextSwitchTo(TransactionAbortContext);
1402 MemoryContextSwitchTo(TopMemoryContext);
1409 AtSubAbort_Memory(void)
1411 Assert(TransactionAbortContext != NULL);
1413 MemoryContextSwitchTo(TransactionAbortContext);
1418 * AtAbort_ResourceOwner
1421 AtAbort_ResourceOwner(void)
1424 * Make sure we have a valid ResourceOwner, if possible (else it will be
1425 * NULL, which is OK)
1427 CurrentResourceOwner = TopTransactionResourceOwner;
1431 * AtSubAbort_ResourceOwner
1434 AtSubAbort_ResourceOwner(void)
1436 TransactionState s = CurrentTransactionState;
1438 /* Make sure we have a valid ResourceOwner */
1439 CurrentResourceOwner = s->curTransactionOwner;
1444 * AtSubAbort_childXids
1447 AtSubAbort_childXids(void)
1449 TransactionState s = CurrentTransactionState;
1452 * We keep the child-XID arrays in TopTransactionContext (see
1453 * AtSubCommit_childXids). This means we'd better free the array
1454 * explicitly at abort to avoid leakage.
1456 if (s->childXids != NULL)
1457 pfree(s->childXids);
1458 s->childXids = NULL;
1460 s->maxChildXids = 0;
1463 * We could prune the unreportedXids array here. But we don't bother.
1464 * That would potentially reduce number of XLOG_XACT_ASSIGNMENT records
1465 * but it would likely introduce more CPU time into the more common
1466 * paths, so we choose not to do that.
1470 /* ----------------------------------------------------------------
1471 * CleanupTransaction stuff
1472 * ----------------------------------------------------------------
1479 AtCleanup_Memory(void)
1481 Assert(CurrentTransactionState->parent == NULL);
1484 * Now that we're "out" of a transaction, have the system allocate things
1485 * in the top memory context instead of per-transaction contexts.
1487 MemoryContextSwitchTo(TopMemoryContext);
1490 * Clear the special abort context for next time.
1492 if (TransactionAbortContext != NULL)
1493 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1496 * Release all transaction-local memory.
1498 if (TopTransactionContext != NULL)
1499 MemoryContextDelete(TopTransactionContext);
1500 TopTransactionContext = NULL;
1501 CurTransactionContext = NULL;
1502 CurrentTransactionState->curTransactionContext = NULL;
1506 /* ----------------------------------------------------------------
1507 * CleanupSubTransaction stuff
1508 * ----------------------------------------------------------------
1512 * AtSubCleanup_Memory
1515 AtSubCleanup_Memory(void)
1517 TransactionState s = CurrentTransactionState;
1519 Assert(s->parent != NULL);
1521 /* Make sure we're not in an about-to-be-deleted context */
1522 MemoryContextSwitchTo(s->parent->curTransactionContext);
1523 CurTransactionContext = s->parent->curTransactionContext;
1526 * Clear the special abort context for next time.
1528 if (TransactionAbortContext != NULL)
1529 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1532 * Delete the subxact local memory contexts. Its CurTransactionContext can
1533 * go too (note this also kills CurTransactionContexts from any children
1536 if (s->curTransactionContext)
1537 MemoryContextDelete(s->curTransactionContext);
1538 s->curTransactionContext = NULL;
1541 /* ----------------------------------------------------------------
1542 * interface routines
1543 * ----------------------------------------------------------------
1550 StartTransaction(void)
1553 VirtualTransactionId vxid;
1556 * Let's just make sure the state stack is empty
1558 s = &TopTransactionStateData;
1559 CurrentTransactionState = s;
1562 * check the current transaction state
1564 if (s->state != TRANS_DEFAULT)
1565 elog(WARNING, "StartTransaction while in %s state",
1566 TransStateAsString(s->state));
1569 * set the current transaction state information appropriately during
1572 s->state = TRANS_START;
1573 s->transactionId = InvalidTransactionId; /* until assigned */
1576 * Make sure we've reset xact state variables
1578 * If recovery is still in progress, mark this transaction as read-only.
1579 * We have lower level defences in XLogInsert and elsewhere to stop us
1580 * from modifying data during recovery, but this gives the normal
1581 * indication to the user that the transaction is read-only.
1583 if (RecoveryInProgress())
1585 s->startedInRecovery = true;
1586 XactReadOnly = true;
1590 s->startedInRecovery = false;
1591 XactReadOnly = DefaultXactReadOnly;
1593 XactIsoLevel = DefaultXactIsoLevel;
1594 forceSyncCommit = false;
1595 MyXactAccessedTempRel = false;
1598 * reinitialize within-transaction counters
1600 s->subTransactionId = TopSubTransactionId;
1601 currentSubTransactionId = TopSubTransactionId;
1602 currentCommandId = FirstCommandId;
1603 currentCommandIdUsed = false;
1606 * initialize reported xid accounting
1608 nUnreportedXids = 0;
1611 * must initialize resource-management stuff first
1614 AtStart_ResourceOwner();
1617 * Assign a new LocalTransactionId, and combine it with the backendId to
1618 * form a virtual transaction id.
1620 vxid.backendId = MyBackendId;
1621 vxid.localTransactionId = GetNextLocalTransactionId();
1624 * Lock the virtual transaction id before we announce it in the proc array
1626 VirtualXactLockTableInsert(vxid);
1629 * Advertise it in the proc array. We assume assignment of
1630 * LocalTransactionID is atomic, and the backendId should be set already.
1632 Assert(MyProc->backendId == vxid.backendId);
1633 MyProc->lxid = vxid.localTransactionId;
1635 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
1638 * set transaction_timestamp() (a/k/a now()). We want this to be the same
1639 * as the first command's statement_timestamp(), so don't do a fresh
1640 * GetCurrentTimestamp() call (which'd be expensive anyway). Also, mark
1641 * xactStopTimestamp as unset.
1643 xactStartTimestamp = stmtStartTimestamp;
1644 xactStopTimestamp = 0;
1645 pgstat_report_xact_timestamp(xactStartTimestamp);
1648 * initialize current transaction state fields
1650 * note: prevXactReadOnly is not used at the outermost level
1652 s->nestingLevel = 1;
1653 s->gucNestLevel = 1;
1654 s->childXids = NULL;
1656 s->maxChildXids = 0;
1657 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
1658 /* SecurityRestrictionContext should never be set outside a transaction */
1659 Assert(s->prevSecContext == 0);
1662 * initialize other subsystems for new transaction
1667 AfterTriggerBeginXact();
1670 * done with start processing, set current transaction state to "in
1673 s->state = TRANS_INPROGRESS;
1675 ShowTransactionState("StartTransaction");
1682 * NB: if you change this routine, better look at PrepareTransaction too!
1685 CommitTransaction(void)
1687 TransactionState s = CurrentTransactionState;
1688 TransactionId latestXid;
1690 ShowTransactionState("CommitTransaction");
1693 * check the current transaction state
1695 if (s->state != TRANS_INPROGRESS)
1696 elog(WARNING, "CommitTransaction while in %s state",
1697 TransStateAsString(s->state));
1698 Assert(s->parent == NULL);
1701 * Do pre-commit processing (most of this stuff requires database access,
1702 * and in fact could still cause an error...)
1704 * It is possible for CommitHoldablePortals to invoke functions that queue
1705 * deferred triggers, and it's also possible that triggers create holdable
1706 * cursors. So we have to loop until there's nothing left to do.
1711 * Fire all currently pending deferred triggers.
1713 AfterTriggerFireDeferred();
1716 * Convert any open holdable cursors into static portals. If there
1717 * weren't any, we are done ... otherwise loop back to check if they
1718 * queued deferred triggers. Lather, rinse, repeat.
1720 if (!CommitHoldablePortals())
1724 /* Now we can shut down the deferred-trigger manager */
1725 AfterTriggerEndXact(true);
1727 /* Close any open regular cursors */
1731 * Let ON COMMIT management do its thing (must happen after closing
1732 * cursors, to avoid dangling-reference problems)
1734 PreCommit_on_commit_actions();
1736 /* close large objects before lower-level cleanup */
1737 AtEOXact_LargeObject(true);
1739 /* NOTIFY commit must come before lower-level cleanup */
1742 /* Prevent cancel/die interrupt while cleaning up */
1745 /* Commit updates to the relation map --- do this as late as possible */
1746 AtEOXact_RelationMap(true);
1749 * set the current transaction state information appropriately during
1752 s->state = TRANS_COMMIT;
1755 * Here is where we really truly commit.
1757 latestXid = RecordTransactionCommit();
1759 TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
1762 * Let others know about no transaction in progress by me. Note that this
1763 * must be done _before_ releasing locks we hold and _after_
1764 * RecordTransactionCommit.
1766 ProcArrayEndTransaction(MyProc, latestXid);
1769 * This is all post-commit cleanup. Note that if an error is raised here,
1770 * it's too late to abort the transaction. This should be just
1771 * noncritical resource releasing.
1773 * The ordering of operations is not entirely random. The idea is:
1774 * release resources visible to other backends (eg, files, buffer pins);
1775 * then release locks; then release backend-local resources. We want to
1776 * release locks at the point where any backend waiting for us will see
1777 * our transaction as being fully cleaned up.
1779 * Resources that can be associated with individual queries are handled by
1780 * the ResourceOwner mechanism. The other calls here are for backend-wide
1784 CallXactCallbacks(XACT_EVENT_COMMIT);
1786 ResourceOwnerRelease(TopTransactionResourceOwner,
1787 RESOURCE_RELEASE_BEFORE_LOCKS,
1790 /* Check we've released all buffer pins */
1791 AtEOXact_Buffers(true);
1793 /* Clean up the relation cache */
1794 AtEOXact_RelationCache(true);
1796 /* Clean up the snapshot manager */
1797 AtEarlyCommit_Snapshot();
1800 * Make catalog changes visible to all backends. This has to happen after
1801 * relcache references are dropped (see comments for
1802 * AtEOXact_RelationCache), but before locks are released (if anyone is
1803 * waiting for lock on a relation we've modified, we want them to know
1804 * about the catalog change before they start using the relation).
1806 AtEOXact_Inval(true);
1809 * Likewise, dropping of files deleted during the transaction is best done
1810 * after releasing relcache and buffer pins. (This is not strictly
1811 * necessary during commit, since such pins should have been released
1812 * already, but this ordering is definitely critical during abort.)
1814 smgrDoPendingDeletes(true);
1816 AtEOXact_MultiXact();
1818 ResourceOwnerRelease(TopTransactionResourceOwner,
1819 RESOURCE_RELEASE_LOCKS,
1821 ResourceOwnerRelease(TopTransactionResourceOwner,
1822 RESOURCE_RELEASE_AFTER_LOCKS,
1825 /* Check we've released all catcache entries */
1826 AtEOXact_CatCache(true);
1828 AtEOXact_GUC(true, 1);
1830 AtEOXact_on_commit_actions(true);
1831 AtEOXact_Namespace(true);
1832 /* smgrcommit already done */
1834 AtEOXact_ComboCid();
1835 AtEOXact_HashTables(true);
1836 AtEOXact_PgStat(true);
1837 AtEOXact_Snapshot(true);
1838 pgstat_report_xact_timestamp(0);
1840 CurrentResourceOwner = NULL;
1841 ResourceOwnerDelete(TopTransactionResourceOwner);
1842 s->curTransactionOwner = NULL;
1843 CurTransactionResourceOwner = NULL;
1844 TopTransactionResourceOwner = NULL;
1848 s->transactionId = InvalidTransactionId;
1849 s->subTransactionId = InvalidSubTransactionId;
1850 s->nestingLevel = 0;
1851 s->gucNestLevel = 0;
1852 s->childXids = NULL;
1854 s->maxChildXids = 0;
1857 * done with commit processing, set current transaction state back to
1860 s->state = TRANS_DEFAULT;
1862 RESUME_INTERRUPTS();
1867 * PrepareTransaction
1869 * NB: if you change this routine, better look at CommitTransaction too!
1872 PrepareTransaction(void)
1874 TransactionState s = CurrentTransactionState;
1875 TransactionId xid = GetCurrentTransactionId();
1876 GlobalTransaction gxact;
1877 TimestampTz prepared_at;
1879 ShowTransactionState("PrepareTransaction");
1882 * check the current transaction state
1884 if (s->state != TRANS_INPROGRESS)
1885 elog(WARNING, "PrepareTransaction while in %s state",
1886 TransStateAsString(s->state));
1887 Assert(s->parent == NULL);
1890 * Do pre-commit processing (most of this stuff requires database access,
1891 * and in fact could still cause an error...)
1893 * It is possible for PrepareHoldablePortals to invoke functions that
1894 * queue deferred triggers, and it's also possible that triggers create
1895 * holdable cursors. So we have to loop until there's nothing left to do.
1900 * Fire all currently pending deferred triggers.
1902 AfterTriggerFireDeferred();
1905 * Convert any open holdable cursors into static portals. If there
1906 * weren't any, we are done ... otherwise loop back to check if they
1907 * queued deferred triggers. Lather, rinse, repeat.
1909 if (!PrepareHoldablePortals())
1913 /* Now we can shut down the deferred-trigger manager */
1914 AfterTriggerEndXact(true);
1916 /* Close any open regular cursors */
1920 * Let ON COMMIT management do its thing (must happen after closing
1921 * cursors, to avoid dangling-reference problems)
1923 PreCommit_on_commit_actions();
1925 /* close large objects before lower-level cleanup */
1926 AtEOXact_LargeObject(true);
1928 /* NOTIFY will be handled below */
1931 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
1932 * this transaction. Having the prepared xact hold locks on another
1933 * backend's temp table seems a bad idea --- for instance it would prevent
1934 * the backend from exiting. There are other problems too, such as how to
1935 * clean up the source backend's local buffers and ON COMMIT state if the
1936 * prepared xact includes a DROP of a temp table.
1938 * We must check this after executing any ON COMMIT actions, because they
1939 * might still access a temp relation.
1941 * XXX In principle this could be relaxed to allow some useful special
1942 * cases, such as a temp table created and dropped all within the
1943 * transaction. That seems to require much more bookkeeping though.
1945 if (MyXactAccessedTempRel)
1947 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1948 errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
1950 /* Prevent cancel/die interrupt while cleaning up */
1954 * set the current transaction state information appropriately during
1955 * prepare processing
1957 s->state = TRANS_PREPARE;
1959 prepared_at = GetCurrentTimestamp();
1961 /* Tell bufmgr and smgr to prepare for commit */
1965 * Reserve the GID for this transaction. This could fail if the requested
1966 * GID is invalid or already in use.
1968 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
1969 GetUserId(), MyDatabaseId);
1973 * Collect data for the 2PC state file. Note that in general, no actual
1974 * state change should happen in the called modules during this step,
1975 * since it's still possible to fail before commit, and in that case we
1976 * want transaction abort to be able to clean up. (In particular, the
1977 * AtPrepare routines may error out if they find cases they cannot
1978 * handle.) State cleanup should happen in the PostPrepare routines
1979 * below. However, some modules can go ahead and clear state here because
1980 * they wouldn't do anything with it during abort anyway.
1982 * Note: because the 2PC state file records will be replayed in the same
1983 * order they are made, the order of these calls has to match the order in
1984 * which we want things to happen during COMMIT PREPARED or ROLLBACK
1985 * PREPARED; in particular, pay attention to whether things should happen
1986 * before or after releasing the transaction's locks.
1988 StartPrepare(gxact);
1993 AtPrepare_MultiXact();
1994 AtPrepare_RelationMap();
1997 * Here is where we really truly prepare.
1999 * We have to record transaction prepares even if we didn't make any
2000 * updates, because the transaction manager might get confused if we lose
2001 * a global transaction.
2006 * Now we clean up backend-internal state and release internal resources.
2009 /* Reset XactLastRecEnd until the next transaction writes something */
2010 XactLastRecEnd.xrecoff = 0;
2013 * Let others know about no transaction in progress by me. This has to be
2014 * done *after* the prepared transaction has been marked valid, else
2015 * someone may think it is unlocked and recyclable.
2017 ProcArrayClearTransaction(MyProc);
2020 * This is all post-transaction cleanup. Note that if an error is raised
2021 * here, it's too late to abort the transaction. This should be just
2022 * noncritical resource releasing. See notes in CommitTransaction.
2025 CallXactCallbacks(XACT_EVENT_PREPARE);
2027 ResourceOwnerRelease(TopTransactionResourceOwner,
2028 RESOURCE_RELEASE_BEFORE_LOCKS,
2031 /* Check we've released all buffer pins */
2032 AtEOXact_Buffers(true);
2034 /* Clean up the relation cache */
2035 AtEOXact_RelationCache(true);
2037 /* Clean up the snapshot manager */
2038 AtEarlyCommit_Snapshot();
2040 /* notify doesn't need a postprepare call */
2042 PostPrepare_PgStat();
2044 PostPrepare_Inval();
2048 PostPrepare_MultiXact(xid);
2050 PostPrepare_Locks(xid);
2052 ResourceOwnerRelease(TopTransactionResourceOwner,
2053 RESOURCE_RELEASE_LOCKS,
2055 ResourceOwnerRelease(TopTransactionResourceOwner,
2056 RESOURCE_RELEASE_AFTER_LOCKS,
2059 /* Check we've released all catcache entries */
2060 AtEOXact_CatCache(true);
2062 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2063 AtEOXact_GUC(true, 1);
2065 AtEOXact_on_commit_actions(true);
2066 AtEOXact_Namespace(true);
2067 /* smgrcommit already done */
2069 AtEOXact_ComboCid();
2070 AtEOXact_HashTables(true);
2071 /* don't call AtEOXact_PgStat here */
2072 AtEOXact_Snapshot(true);
2074 CurrentResourceOwner = NULL;
2075 ResourceOwnerDelete(TopTransactionResourceOwner);
2076 s->curTransactionOwner = NULL;
2077 CurTransactionResourceOwner = NULL;
2078 TopTransactionResourceOwner = NULL;
2082 s->transactionId = InvalidTransactionId;
2083 s->subTransactionId = InvalidSubTransactionId;
2084 s->nestingLevel = 0;
2085 s->gucNestLevel = 0;
2086 s->childXids = NULL;
2088 s->maxChildXids = 0;
2091 * done with 1st phase commit processing, set current transaction state
2094 s->state = TRANS_DEFAULT;
2096 RESUME_INTERRUPTS();
2104 AbortTransaction(void)
2106 TransactionState s = CurrentTransactionState;
2107 TransactionId latestXid;
2109 /* Prevent cancel/die interrupt while cleaning up */
2112 /* Make sure we have a valid memory context and resource owner */
2114 AtAbort_ResourceOwner();
2117 * Release any LW locks we might be holding as quickly as possible.
2118 * (Regular locks, however, must be held till we finish aborting.)
2119 * Releasing LW locks is critical since we might try to grab them again
2120 * while cleaning up!
2124 /* Clean up buffer I/O and buffer context locks, too */
2129 * Also clean up any open wait for lock, since the lock manager will choke
2130 * if we try to wait for another lock before doing this.
2135 * check the current transaction state
2137 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2138 elog(WARNING, "AbortTransaction while in %s state",
2139 TransStateAsString(s->state));
2140 Assert(s->parent == NULL);
2143 * set the current transaction state information appropriately during the
2146 s->state = TRANS_ABORT;
2149 * Reset user ID which might have been changed transiently. We need this
2150 * to clean up in case control escaped out of a SECURITY DEFINER function
2151 * or other local change of CurrentUserId; therefore, the prior value of
2152 * SecurityRestrictionContext also needs to be restored.
2154 * (Note: it is not necessary to restore session authorization or role
2155 * settings here because those can only be changed via GUC, and GUC will
2156 * take care of rolling them back if need be.)
2158 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
2161 * do abort processing
2163 AfterTriggerEndXact(false); /* 'false' means it's abort */
2165 AtEOXact_LargeObject(false);
2167 AtEOXact_RelationMap(false);
2170 * Advertise the fact that we aborted in pg_clog (assuming that we got as
2171 * far as assigning an XID to advertise).
2173 latestXid = RecordTransactionAbort(false);
2175 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
2178 * Let others know about no transaction in progress by me. Note that this
2179 * must be done _before_ releasing locks we hold and _after_
2180 * RecordTransactionAbort.
2182 ProcArrayEndTransaction(MyProc, latestXid);
2185 * Post-abort cleanup. See notes in CommitTransaction() concerning
2186 * ordering. We can skip all of it if the transaction failed before
2187 * creating a resource owner.
2189 if (TopTransactionResourceOwner != NULL)
2191 CallXactCallbacks(XACT_EVENT_ABORT);
2193 ResourceOwnerRelease(TopTransactionResourceOwner,
2194 RESOURCE_RELEASE_BEFORE_LOCKS,
2196 AtEOXact_Buffers(false);
2197 AtEOXact_RelationCache(false);
2198 AtEOXact_Inval(false);
2199 smgrDoPendingDeletes(false);
2200 AtEOXact_MultiXact();
2201 ResourceOwnerRelease(TopTransactionResourceOwner,
2202 RESOURCE_RELEASE_LOCKS,
2204 ResourceOwnerRelease(TopTransactionResourceOwner,
2205 RESOURCE_RELEASE_AFTER_LOCKS,
2207 AtEOXact_CatCache(false);
2209 AtEOXact_GUC(false, 1);
2210 AtEOXact_SPI(false);
2211 AtEOXact_on_commit_actions(false);
2212 AtEOXact_Namespace(false);
2214 AtEOXact_ComboCid();
2215 AtEOXact_HashTables(false);
2216 AtEOXact_PgStat(false);
2217 AtEOXact_Snapshot(false);
2218 pgstat_report_xact_timestamp(0);
2222 * State remains TRANS_ABORT until CleanupTransaction().
2224 RESUME_INTERRUPTS();
2228 * CleanupTransaction
2231 CleanupTransaction(void)
2233 TransactionState s = CurrentTransactionState;
2236 * State should still be TRANS_ABORT from AbortTransaction().
2238 if (s->state != TRANS_ABORT)
2239 elog(FATAL, "CleanupTransaction: unexpected state %s",
2240 TransStateAsString(s->state));
2243 * do abort cleanup processing
2245 AtCleanup_Portals(); /* now safe to release portal memory */
2247 CurrentResourceOwner = NULL; /* and resource owner */
2248 if (TopTransactionResourceOwner)
2249 ResourceOwnerDelete(TopTransactionResourceOwner);
2250 s->curTransactionOwner = NULL;
2251 CurTransactionResourceOwner = NULL;
2252 TopTransactionResourceOwner = NULL;
2254 AtCleanup_Memory(); /* and transaction memory */
2256 s->transactionId = InvalidTransactionId;
2257 s->subTransactionId = InvalidSubTransactionId;
2258 s->nestingLevel = 0;
2259 s->gucNestLevel = 0;
2260 s->childXids = NULL;
2262 s->maxChildXids = 0;
2265 * done with abort processing, set current transaction state back to
2268 s->state = TRANS_DEFAULT;
2272 * StartTransactionCommand
2275 StartTransactionCommand(void)
2277 TransactionState s = CurrentTransactionState;
2279 switch (s->blockState)
2282 * if we aren't in a transaction block, we just do our usual start
2285 case TBLOCK_DEFAULT:
2287 s->blockState = TBLOCK_STARTED;
2291 * We are somewhere in a transaction block or subtransaction and
2292 * about to start a new command. For now we do nothing, but
2293 * someday we may do command-local resource initialization. (Note
2294 * that any needed CommandCounterIncrement was done by the
2295 * previous CommitTransactionCommand.)
2297 case TBLOCK_INPROGRESS:
2298 case TBLOCK_SUBINPROGRESS:
2302 * Here we are in a failed transaction block (one of the commands
2303 * caused an abort) so we do nothing but remain in the abort
2304 * state. Eventually we will get a ROLLBACK command which will
2305 * get us out of this state. (It is up to other code to ensure
2306 * that no commands other than ROLLBACK will be processed in these
2310 case TBLOCK_SUBABORT:
2313 /* These cases are invalid. */
2314 case TBLOCK_STARTED:
2316 case TBLOCK_SUBBEGIN:
2319 case TBLOCK_ABORT_END:
2320 case TBLOCK_SUBABORT_END:
2321 case TBLOCK_ABORT_PENDING:
2322 case TBLOCK_SUBABORT_PENDING:
2323 case TBLOCK_SUBRESTART:
2324 case TBLOCK_SUBABORT_RESTART:
2325 case TBLOCK_PREPARE:
2326 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2327 BlockStateAsString(s->blockState));
2332 * We must switch to CurTransactionContext before returning. This is
2333 * already done if we called StartTransaction, otherwise not.
2335 Assert(CurTransactionContext != NULL);
2336 MemoryContextSwitchTo(CurTransactionContext);
2340 * CommitTransactionCommand
2343 CommitTransactionCommand(void)
2345 TransactionState s = CurrentTransactionState;
2347 switch (s->blockState)
2350 * This shouldn't happen, because it means the previous
2351 * StartTransactionCommand didn't set the STARTED state
2354 case TBLOCK_DEFAULT:
2355 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2356 BlockStateAsString(s->blockState));
2360 * If we aren't in a transaction block, just do our usual
2361 * transaction commit, and return to the idle state.
2363 case TBLOCK_STARTED:
2364 CommitTransaction();
2365 s->blockState = TBLOCK_DEFAULT;
2369 * We are completing a "BEGIN TRANSACTION" command, so we change
2370 * to the "transaction block in progress" state and return. (We
2371 * assume the BEGIN did nothing to the database, so we need no
2372 * CommandCounterIncrement.)
2375 s->blockState = TBLOCK_INPROGRESS;
2379 * This is the case when we have finished executing a command
2380 * someplace within a transaction block. We increment the command
2381 * counter and return.
2383 case TBLOCK_INPROGRESS:
2384 case TBLOCK_SUBINPROGRESS:
2385 CommandCounterIncrement();
2389 * We are completing a "COMMIT" command. Do it and return to the
2393 CommitTransaction();
2394 s->blockState = TBLOCK_DEFAULT;
2398 * Here we are in the middle of a transaction block but one of the
2399 * commands caused an abort so we do nothing but remain in the
2400 * abort state. Eventually we will get a ROLLBACK comand.
2403 case TBLOCK_SUBABORT:
2407 * Here we were in an aborted transaction block and we just got
2408 * the ROLLBACK command from the user, so clean up the
2409 * already-aborted transaction and return to the idle state.
2411 case TBLOCK_ABORT_END:
2412 CleanupTransaction();
2413 s->blockState = TBLOCK_DEFAULT;
2417 * Here we were in a perfectly good transaction block but the user
2418 * told us to ROLLBACK anyway. We have to abort the transaction
2419 * and then clean up.
2421 case TBLOCK_ABORT_PENDING:
2423 CleanupTransaction();
2424 s->blockState = TBLOCK_DEFAULT;
2428 * We are completing a "PREPARE TRANSACTION" command. Do it and
2429 * return to the idle state.
2431 case TBLOCK_PREPARE:
2432 PrepareTransaction();
2433 s->blockState = TBLOCK_DEFAULT;
2437 * We were just issued a SAVEPOINT inside a transaction block.
2438 * Start a subtransaction. (DefineSavepoint already did
2439 * PushTransaction, so as to have someplace to put the SUBBEGIN
2442 case TBLOCK_SUBBEGIN:
2443 StartSubTransaction();
2444 s->blockState = TBLOCK_SUBINPROGRESS;
2448 * We were issued a COMMIT or RELEASE command, so we end the
2449 * current subtransaction and return to the parent transaction.
2450 * The parent might be ended too, so repeat till we are all the
2451 * way out or find an INPROGRESS transaction.
2456 CommitSubTransaction();
2457 s = CurrentTransactionState; /* changed by pop */
2458 } while (s->blockState == TBLOCK_SUBEND);
2459 /* If we had a COMMIT command, finish off the main xact too */
2460 if (s->blockState == TBLOCK_END)
2462 Assert(s->parent == NULL);
2463 CommitTransaction();
2464 s->blockState = TBLOCK_DEFAULT;
2466 else if (s->blockState == TBLOCK_PREPARE)
2468 Assert(s->parent == NULL);
2469 PrepareTransaction();
2470 s->blockState = TBLOCK_DEFAULT;
2474 Assert(s->blockState == TBLOCK_INPROGRESS ||
2475 s->blockState == TBLOCK_SUBINPROGRESS);
2480 * The current already-failed subtransaction is ending due to a
2481 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2482 * examine the parent (which could be in any of several states).
2484 case TBLOCK_SUBABORT_END:
2485 CleanupSubTransaction();
2486 CommitTransactionCommand();
2490 * As above, but it's not dead yet, so abort first.
2492 case TBLOCK_SUBABORT_PENDING:
2493 AbortSubTransaction();
2494 CleanupSubTransaction();
2495 CommitTransactionCommand();
2499 * The current subtransaction is the target of a ROLLBACK TO
2500 * command. Abort and pop it, then start a new subtransaction
2501 * with the same name.
2503 case TBLOCK_SUBRESTART:
2508 /* save name and keep Cleanup from freeing it */
2511 savepointLevel = s->savepointLevel;
2513 AbortSubTransaction();
2514 CleanupSubTransaction();
2516 DefineSavepoint(NULL);
2517 s = CurrentTransactionState; /* changed by push */
2519 s->savepointLevel = savepointLevel;
2521 /* This is the same as TBLOCK_SUBBEGIN case */
2522 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2523 StartSubTransaction();
2524 s->blockState = TBLOCK_SUBINPROGRESS;
2529 * Same as above, but the subtransaction had already failed, so we
2530 * don't need AbortSubTransaction.
2532 case TBLOCK_SUBABORT_RESTART:
2537 /* save name and keep Cleanup from freeing it */
2540 savepointLevel = s->savepointLevel;
2542 CleanupSubTransaction();
2544 DefineSavepoint(NULL);
2545 s = CurrentTransactionState; /* changed by push */
2547 s->savepointLevel = savepointLevel;
2549 /* This is the same as TBLOCK_SUBBEGIN case */
2550 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2551 StartSubTransaction();
2552 s->blockState = TBLOCK_SUBINPROGRESS;
2559 * AbortCurrentTransaction
2562 AbortCurrentTransaction(void)
2564 TransactionState s = CurrentTransactionState;
2566 switch (s->blockState)
2568 case TBLOCK_DEFAULT:
2569 if (s->state == TRANS_DEFAULT)
2571 /* we are idle, so nothing to do */
2576 * We can get here after an error during transaction start
2577 * (state will be TRANS_START). Need to clean up the
2578 * incompletely started transaction. First, adjust the
2579 * low-level state to suppress warning message from
2582 if (s->state == TRANS_START)
2583 s->state = TRANS_INPROGRESS;
2585 CleanupTransaction();
2590 * if we aren't in a transaction block, we just do the basic abort
2591 * & cleanup transaction.
2593 case TBLOCK_STARTED:
2595 CleanupTransaction();
2596 s->blockState = TBLOCK_DEFAULT;
2600 * If we are in TBLOCK_BEGIN it means something screwed up right
2601 * after reading "BEGIN TRANSACTION". We assume that the user
2602 * will interpret the error as meaning the BEGIN failed to get him
2603 * into a transaction block, so we should abort and return to idle
2608 CleanupTransaction();
2609 s->blockState = TBLOCK_DEFAULT;
2613 * We are somewhere in a transaction block and we've gotten a
2614 * failure, so we abort the transaction and set up the persistent
2615 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
2617 case TBLOCK_INPROGRESS:
2619 s->blockState = TBLOCK_ABORT;
2620 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
2624 * Here, we failed while trying to COMMIT. Clean up the
2625 * transaction and return to idle state (we do not want to stay in
2630 CleanupTransaction();
2631 s->blockState = TBLOCK_DEFAULT;
2635 * Here, we are already in an aborted transaction state and are
2636 * waiting for a ROLLBACK, but for some reason we failed again! So
2637 * we just remain in the abort state.
2640 case TBLOCK_SUBABORT:
2644 * We are in a failed transaction and we got the ROLLBACK command.
2645 * We have already aborted, we just need to cleanup and go to idle
2648 case TBLOCK_ABORT_END:
2649 CleanupTransaction();
2650 s->blockState = TBLOCK_DEFAULT;
2654 * We are in a live transaction and we got a ROLLBACK command.
2655 * Abort, cleanup, go to idle state.
2657 case TBLOCK_ABORT_PENDING:
2659 CleanupTransaction();
2660 s->blockState = TBLOCK_DEFAULT;
2664 * Here, we failed while trying to PREPARE. Clean up the
2665 * transaction and return to idle state (we do not want to stay in
2668 case TBLOCK_PREPARE:
2670 CleanupTransaction();
2671 s->blockState = TBLOCK_DEFAULT;
2675 * We got an error inside a subtransaction. Abort just the
2676 * subtransaction, and go to the persistent SUBABORT state until
2679 case TBLOCK_SUBINPROGRESS:
2680 AbortSubTransaction();
2681 s->blockState = TBLOCK_SUBABORT;
2685 * If we failed while trying to create a subtransaction, clean up
2686 * the broken subtransaction and abort the parent. The same
2687 * applies if we get a failure while ending a subtransaction.
2689 case TBLOCK_SUBBEGIN:
2691 case TBLOCK_SUBABORT_PENDING:
2692 case TBLOCK_SUBRESTART:
2693 AbortSubTransaction();
2694 CleanupSubTransaction();
2695 AbortCurrentTransaction();
2699 * Same as above, except the Abort() was already done.
2701 case TBLOCK_SUBABORT_END:
2702 case TBLOCK_SUBABORT_RESTART:
2703 CleanupSubTransaction();
2704 AbortCurrentTransaction();
2710 * PreventTransactionChain
2712 * This routine is to be called by statements that must not run inside
2713 * a transaction block, typically because they have non-rollback-able
2714 * side effects or do internal commits.
2716 * If we have already started a transaction block, issue an error; also issue
2717 * an error if we appear to be running inside a user-defined function (which
2718 * could issue more commands and possibly cause a failure after the statement
2719 * completes). Subtransactions are verboten too.
2721 * isTopLevel: passed down from ProcessUtility to determine whether we are
2722 * inside a function or multi-query querystring. (We will always fail if
2723 * this is false, but it's convenient to centralize the check here instead of
2724 * making callers do it.)
2725 * stmtType: statement type name, for error messages.
2728 PreventTransactionChain(bool isTopLevel, const char *stmtType)
2731 * xact block already started?
2733 if (IsTransactionBlock())
2735 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2736 /* translator: %s represents an SQL statement name */
2737 errmsg("%s cannot run inside a transaction block",
2743 if (IsSubTransaction())
2745 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2746 /* translator: %s represents an SQL statement name */
2747 errmsg("%s cannot run inside a subtransaction",
2751 * inside a function call?
2755 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2756 /* translator: %s represents an SQL statement name */
2757 errmsg("%s cannot be executed from a function or multi-command string",
2760 /* If we got past IsTransactionBlock test, should be in default state */
2761 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2762 CurrentTransactionState->blockState != TBLOCK_STARTED)
2763 elog(FATAL, "cannot prevent transaction chain");
2768 * RequireTransactionChain
2770 * This routine is to be called by statements that must run inside
2771 * a transaction block, because they have no effects that persist past
2772 * transaction end (and so calling them outside a transaction block
2773 * is presumably an error). DECLARE CURSOR is an example.
2775 * If we appear to be running inside a user-defined function, we do not
2776 * issue an error, since the function could issue more commands that make
2777 * use of the current statement's results. Likewise subtransactions.
2778 * Thus this is an inverse for PreventTransactionChain.
2780 * isTopLevel: passed down from ProcessUtility to determine whether we are
2781 * inside a function.
2782 * stmtType: statement type name, for error messages.
2785 RequireTransactionChain(bool isTopLevel, const char *stmtType)
2788 * xact block already started?
2790 if (IsTransactionBlock())
2796 if (IsSubTransaction())
2800 * inside a function call?
2806 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2807 /* translator: %s represents an SQL statement name */
2808 errmsg("%s can only be used in transaction blocks",
2813 * IsInTransactionChain
2815 * This routine is for statements that need to behave differently inside
2816 * a transaction block than when running as single commands. ANALYZE is
2817 * currently the only example.
2819 * isTopLevel: passed down from ProcessUtility to determine whether we are
2820 * inside a function.
2823 IsInTransactionChain(bool isTopLevel)
2826 * Return true on same conditions that would make PreventTransactionChain
2829 if (IsTransactionBlock())
2832 if (IsSubTransaction())
2838 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2839 CurrentTransactionState->blockState != TBLOCK_STARTED)
2847 * Register or deregister callback functions for start- and end-of-xact
2850 * These functions are intended for use by dynamically loaded modules.
2851 * For built-in modules we generally just hardwire the appropriate calls
2852 * (mainly because it's easier to control the order that way, where needed).
2854 * At transaction end, the callback occurs post-commit or post-abort, so the
2855 * callback functions can only do noncritical cleanup.
2858 RegisterXactCallback(XactCallback callback, void *arg)
2860 XactCallbackItem *item;
2862 item = (XactCallbackItem *)
2863 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
2864 item->callback = callback;
2866 item->next = Xact_callbacks;
2867 Xact_callbacks = item;
2871 UnregisterXactCallback(XactCallback callback, void *arg)
2873 XactCallbackItem *item;
2874 XactCallbackItem *prev;
2877 for (item = Xact_callbacks; item; prev = item, item = item->next)
2879 if (item->callback == callback && item->arg == arg)
2882 prev->next = item->next;
2884 Xact_callbacks = item->next;
2892 CallXactCallbacks(XactEvent event)
2894 XactCallbackItem *item;
2896 for (item = Xact_callbacks; item; item = item->next)
2897 (*item->callback) (event, item->arg);
2902 * Register or deregister callback functions for start- and end-of-subxact
2905 * Pretty much same as above, but for subtransaction events.
2907 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
2908 * so the callback functions can only do noncritical cleanup. At
2909 * subtransaction start, the callback is called when the subtransaction has
2910 * finished initializing.
2913 RegisterSubXactCallback(SubXactCallback callback, void *arg)
2915 SubXactCallbackItem *item;
2917 item = (SubXactCallbackItem *)
2918 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
2919 item->callback = callback;
2921 item->next = SubXact_callbacks;
2922 SubXact_callbacks = item;
2926 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
2928 SubXactCallbackItem *item;
2929 SubXactCallbackItem *prev;
2932 for (item = SubXact_callbacks; item; prev = item, item = item->next)
2934 if (item->callback == callback && item->arg == arg)
2937 prev->next = item->next;
2939 SubXact_callbacks = item->next;
2947 CallSubXactCallbacks(SubXactEvent event,
2948 SubTransactionId mySubid,
2949 SubTransactionId parentSubid)
2951 SubXactCallbackItem *item;
2953 for (item = SubXact_callbacks; item; item = item->next)
2954 (*item->callback) (event, mySubid, parentSubid, item->arg);
2958 /* ----------------------------------------------------------------
2959 * transaction block support
2960 * ----------------------------------------------------------------
2964 * BeginTransactionBlock
2965 * This executes a BEGIN command.
2968 BeginTransactionBlock(void)
2970 TransactionState s = CurrentTransactionState;
2972 switch (s->blockState)
2975 * We are not inside a transaction block, so allow one to begin.
2977 case TBLOCK_STARTED:
2978 s->blockState = TBLOCK_BEGIN;
2982 * Already a transaction block in progress.
2984 case TBLOCK_INPROGRESS:
2985 case TBLOCK_SUBINPROGRESS:
2987 case TBLOCK_SUBABORT:
2989 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2990 errmsg("there is already a transaction in progress")));
2993 /* These cases are invalid. */
2994 case TBLOCK_DEFAULT:
2996 case TBLOCK_SUBBEGIN:
2999 case TBLOCK_ABORT_END:
3000 case TBLOCK_SUBABORT_END:
3001 case TBLOCK_ABORT_PENDING:
3002 case TBLOCK_SUBABORT_PENDING:
3003 case TBLOCK_SUBRESTART:
3004 case TBLOCK_SUBABORT_RESTART:
3005 case TBLOCK_PREPARE:
3006 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3007 BlockStateAsString(s->blockState));
3013 * PrepareTransactionBlock
3014 * This executes a PREPARE command.
3016 * Since PREPARE may actually do a ROLLBACK, the result indicates what
3017 * happened: TRUE for PREPARE, FALSE for ROLLBACK.
3019 * Note that we don't actually do anything here except change blockState.
3020 * The real work will be done in the upcoming PrepareTransaction().
3021 * We do it this way because it's not convenient to change memory context,
3022 * resource owner, etc while executing inside a Portal.
3025 PrepareTransactionBlock(char *gid)
3030 /* Set up to commit the current transaction */
3031 result = EndTransactionBlock();
3033 /* If successful, change outer tblock state to PREPARE */
3036 s = CurrentTransactionState;
3038 while (s->parent != NULL)
3041 if (s->blockState == TBLOCK_END)
3043 /* Save GID where PrepareTransaction can find it again */
3044 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
3046 s->blockState = TBLOCK_PREPARE;
3051 * ignore case where we are not in a transaction;
3052 * EndTransactionBlock already issued a warning.
3054 Assert(s->blockState == TBLOCK_STARTED);
3055 /* Don't send back a PREPARE result tag... */
3064 * EndTransactionBlock
3065 * This executes a COMMIT command.
3067 * Since COMMIT may actually do a ROLLBACK, the result indicates what
3068 * happened: TRUE for COMMIT, FALSE for ROLLBACK.
3070 * Note that we don't actually do anything here except change blockState.
3071 * The real work will be done in the upcoming CommitTransactionCommand().
3072 * We do it this way because it's not convenient to change memory context,
3073 * resource owner, etc while executing inside a Portal.
3076 EndTransactionBlock(void)
3078 TransactionState s = CurrentTransactionState;
3079 bool result = false;
3081 switch (s->blockState)
3084 * We are in a transaction block, so tell CommitTransactionCommand
3087 case TBLOCK_INPROGRESS:
3088 s->blockState = TBLOCK_END;
3093 * We are in a failed transaction block. Tell
3094 * CommitTransactionCommand it's time to exit the block.
3097 s->blockState = TBLOCK_ABORT_END;
3101 * We are in a live subtransaction block. Set up to subcommit all
3102 * open subtransactions and then commit the main transaction.
3104 case TBLOCK_SUBINPROGRESS:
3105 while (s->parent != NULL)
3107 if (s->blockState == TBLOCK_SUBINPROGRESS)
3108 s->blockState = TBLOCK_SUBEND;
3110 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3111 BlockStateAsString(s->blockState));
3114 if (s->blockState == TBLOCK_INPROGRESS)
3115 s->blockState = TBLOCK_END;
3117 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3118 BlockStateAsString(s->blockState));
3123 * Here we are inside an aborted subtransaction. Treat the COMMIT
3124 * as ROLLBACK: set up to abort everything and exit the main
3127 case TBLOCK_SUBABORT:
3128 while (s->parent != NULL)
3130 if (s->blockState == TBLOCK_SUBINPROGRESS)
3131 s->blockState = TBLOCK_SUBABORT_PENDING;
3132 else if (s->blockState == TBLOCK_SUBABORT)
3133 s->blockState = TBLOCK_SUBABORT_END;
3135 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3136 BlockStateAsString(s->blockState));
3139 if (s->blockState == TBLOCK_INPROGRESS)
3140 s->blockState = TBLOCK_ABORT_PENDING;
3141 else if (s->blockState == TBLOCK_ABORT)
3142 s->blockState = TBLOCK_ABORT_END;
3144 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3145 BlockStateAsString(s->blockState));
3149 * The user issued COMMIT when not inside a transaction. Issue a
3150 * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
3151 * CommitTransactionCommand() will then close the transaction and
3152 * put us back into the default state.
3154 case TBLOCK_STARTED:
3156 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3157 errmsg("there is no transaction in progress")));
3161 /* These cases are invalid. */
3162 case TBLOCK_DEFAULT:
3164 case TBLOCK_SUBBEGIN:
3167 case TBLOCK_ABORT_END:
3168 case TBLOCK_SUBABORT_END:
3169 case TBLOCK_ABORT_PENDING:
3170 case TBLOCK_SUBABORT_PENDING:
3171 case TBLOCK_SUBRESTART:
3172 case TBLOCK_SUBABORT_RESTART:
3173 case TBLOCK_PREPARE:
3174 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3175 BlockStateAsString(s->blockState));
3183 * UserAbortTransactionBlock
3184 * This executes a ROLLBACK command.
3186 * As above, we don't actually do anything here except change blockState.
3189 UserAbortTransactionBlock(void)
3191 TransactionState s = CurrentTransactionState;
3193 switch (s->blockState)
3196 * We are inside a transaction block and we got a ROLLBACK command
3197 * from the user, so tell CommitTransactionCommand to abort and
3198 * exit the transaction block.
3200 case TBLOCK_INPROGRESS:
3201 s->blockState = TBLOCK_ABORT_PENDING;
3205 * We are inside a failed transaction block and we got a ROLLBACK
3206 * command from the user. Abort processing is already done, so
3207 * CommitTransactionCommand just has to cleanup and go back to
3211 s->blockState = TBLOCK_ABORT_END;
3215 * We are inside a subtransaction. Mark everything up to top
3216 * level as exitable.
3218 case TBLOCK_SUBINPROGRESS:
3219 case TBLOCK_SUBABORT:
3220 while (s->parent != NULL)
3222 if (s->blockState == TBLOCK_SUBINPROGRESS)
3223 s->blockState = TBLOCK_SUBABORT_PENDING;
3224 else if (s->blockState == TBLOCK_SUBABORT)
3225 s->blockState = TBLOCK_SUBABORT_END;
3227 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3228 BlockStateAsString(s->blockState));
3231 if (s->blockState == TBLOCK_INPROGRESS)
3232 s->blockState = TBLOCK_ABORT_PENDING;
3233 else if (s->blockState == TBLOCK_ABORT)
3234 s->blockState = TBLOCK_ABORT_END;
3236 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3237 BlockStateAsString(s->blockState));
3241 * The user issued ABORT when not inside a transaction. Issue a
3242 * WARNING and go to abort state. The upcoming call to
3243 * CommitTransactionCommand() will then put us back into the
3246 case TBLOCK_STARTED:
3248 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3249 errmsg("there is no transaction in progress")));
3250 s->blockState = TBLOCK_ABORT_PENDING;
3253 /* These cases are invalid. */
3254 case TBLOCK_DEFAULT:
3256 case TBLOCK_SUBBEGIN:
3259 case TBLOCK_ABORT_END:
3260 case TBLOCK_SUBABORT_END:
3261 case TBLOCK_ABORT_PENDING:
3262 case TBLOCK_SUBABORT_PENDING:
3263 case TBLOCK_SUBRESTART:
3264 case TBLOCK_SUBABORT_RESTART:
3265 case TBLOCK_PREPARE:
3266 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3267 BlockStateAsString(s->blockState));
3274 * This executes a SAVEPOINT command.
3277 DefineSavepoint(char *name)
3279 TransactionState s = CurrentTransactionState;
3281 switch (s->blockState)
3283 case TBLOCK_INPROGRESS:
3284 case TBLOCK_SUBINPROGRESS:
3285 /* Normal subtransaction start */
3287 s = CurrentTransactionState; /* changed by push */
3290 * Savepoint names, like the TransactionState block itself, live
3291 * in TopTransactionContext.
3294 s->name = MemoryContextStrdup(TopTransactionContext, name);
3297 /* These cases are invalid. */
3298 case TBLOCK_DEFAULT:
3299 case TBLOCK_STARTED:
3301 case TBLOCK_SUBBEGIN:
3305 case TBLOCK_SUBABORT:
3306 case TBLOCK_ABORT_END:
3307 case TBLOCK_SUBABORT_END:
3308 case TBLOCK_ABORT_PENDING:
3309 case TBLOCK_SUBABORT_PENDING:
3310 case TBLOCK_SUBRESTART:
3311 case TBLOCK_SUBABORT_RESTART:
3312 case TBLOCK_PREPARE:
3313 elog(FATAL, "DefineSavepoint: unexpected state %s",
3314 BlockStateAsString(s->blockState));
3321 * This executes a RELEASE command.
3323 * As above, we don't actually do anything here except change blockState.
3326 ReleaseSavepoint(List *options)
3328 TransactionState s = CurrentTransactionState;
3329 TransactionState target,
3334 switch (s->blockState)
3337 * We can't rollback to a savepoint if there is no savepoint
3340 case TBLOCK_INPROGRESS:
3342 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3343 errmsg("no such savepoint")));
3347 * We are in a non-aborted subtransaction. This is the only valid
3350 case TBLOCK_SUBINPROGRESS:
3353 /* These cases are invalid. */
3354 case TBLOCK_DEFAULT:
3355 case TBLOCK_STARTED:
3357 case TBLOCK_SUBBEGIN:
3361 case TBLOCK_SUBABORT:
3362 case TBLOCK_ABORT_END:
3363 case TBLOCK_SUBABORT_END:
3364 case TBLOCK_ABORT_PENDING:
3365 case TBLOCK_SUBABORT_PENDING:
3366 case TBLOCK_SUBRESTART:
3367 case TBLOCK_SUBABORT_RESTART:
3368 case TBLOCK_PREPARE:
3369 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3370 BlockStateAsString(s->blockState));
3374 foreach(cell, options)
3376 DefElem *elem = lfirst(cell);
3378 if (strcmp(elem->defname, "savepoint_name") == 0)
3379 name = strVal(elem->arg);
3382 Assert(PointerIsValid(name));
3384 for (target = s; PointerIsValid(target); target = target->parent)
3386 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3390 if (!PointerIsValid(target))
3392 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3393 errmsg("no such savepoint")));
3395 /* disallow crossing savepoint level boundaries */
3396 if (target->savepointLevel != s->savepointLevel)
3398 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3399 errmsg("no such savepoint")));
3402 * Mark "commit pending" all subtransactions up to the target
3403 * subtransaction. The actual commits will happen when control gets to
3404 * CommitTransactionCommand.
3406 xact = CurrentTransactionState;
3409 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3410 xact->blockState = TBLOCK_SUBEND;
3413 xact = xact->parent;
3414 Assert(PointerIsValid(xact));
3419 * RollbackToSavepoint
3420 * This executes a ROLLBACK TO <savepoint> command.
3422 * As above, we don't actually do anything here except change blockState.
3425 RollbackToSavepoint(List *options)
3427 TransactionState s = CurrentTransactionState;
3428 TransactionState target,
3433 switch (s->blockState)
3436 * We can't rollback to a savepoint if there is no savepoint
3439 case TBLOCK_INPROGRESS:
3442 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3443 errmsg("no such savepoint")));
3447 * There is at least one savepoint, so proceed.
3449 case TBLOCK_SUBINPROGRESS:
3450 case TBLOCK_SUBABORT:
3453 /* These cases are invalid. */
3454 case TBLOCK_DEFAULT:
3455 case TBLOCK_STARTED:
3457 case TBLOCK_SUBBEGIN:
3460 case TBLOCK_ABORT_END:
3461 case TBLOCK_SUBABORT_END:
3462 case TBLOCK_ABORT_PENDING:
3463 case TBLOCK_SUBABORT_PENDING:
3464 case TBLOCK_SUBRESTART:
3465 case TBLOCK_SUBABORT_RESTART:
3466 case TBLOCK_PREPARE:
3467 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3468 BlockStateAsString(s->blockState));
3472 foreach(cell, options)
3474 DefElem *elem = lfirst(cell);
3476 if (strcmp(elem->defname, "savepoint_name") == 0)
3477 name = strVal(elem->arg);
3480 Assert(PointerIsValid(name));
3482 for (target = s; PointerIsValid(target); target = target->parent)
3484 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3488 if (!PointerIsValid(target))
3490 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3491 errmsg("no such savepoint")));
3493 /* disallow crossing savepoint level boundaries */
3494 if (target->savepointLevel != s->savepointLevel)
3496 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3497 errmsg("no such savepoint")));
3500 * Mark "abort pending" all subtransactions up to the target
3501 * subtransaction. The actual aborts will happen when control gets to
3502 * CommitTransactionCommand.
3504 xact = CurrentTransactionState;
3509 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3510 xact->blockState = TBLOCK_SUBABORT_PENDING;
3511 else if (xact->blockState == TBLOCK_SUBABORT)
3512 xact->blockState = TBLOCK_SUBABORT_END;
3514 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3515 BlockStateAsString(xact->blockState));
3516 xact = xact->parent;
3517 Assert(PointerIsValid(xact));
3520 /* And mark the target as "restart pending" */
3521 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3522 xact->blockState = TBLOCK_SUBRESTART;
3523 else if (xact->blockState == TBLOCK_SUBABORT)
3524 xact->blockState = TBLOCK_SUBABORT_RESTART;
3526 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3527 BlockStateAsString(xact->blockState));
3531 * BeginInternalSubTransaction
3532 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
3533 * TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
3534 * used in functions that might be called when not inside a BEGIN block
3535 * or when running deferred triggers at COMMIT/PREPARE time. Also, it
3536 * automatically does CommitTransactionCommand/StartTransactionCommand
3537 * instead of expecting the caller to do it.
3540 BeginInternalSubTransaction(char *name)
3542 TransactionState s = CurrentTransactionState;
3544 switch (s->blockState)
3546 case TBLOCK_STARTED:
3547 case TBLOCK_INPROGRESS:
3549 case TBLOCK_PREPARE:
3550 case TBLOCK_SUBINPROGRESS:
3551 /* Normal subtransaction start */
3553 s = CurrentTransactionState; /* changed by push */
3556 * Savepoint names, like the TransactionState block itself, live
3557 * in TopTransactionContext.
3560 s->name = MemoryContextStrdup(TopTransactionContext, name);
3563 /* These cases are invalid. */
3564 case TBLOCK_DEFAULT:
3566 case TBLOCK_SUBBEGIN:
3569 case TBLOCK_SUBABORT:
3570 case TBLOCK_ABORT_END:
3571 case TBLOCK_SUBABORT_END:
3572 case TBLOCK_ABORT_PENDING:
3573 case TBLOCK_SUBABORT_PENDING:
3574 case TBLOCK_SUBRESTART:
3575 case TBLOCK_SUBABORT_RESTART:
3576 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
3577 BlockStateAsString(s->blockState));
3581 CommitTransactionCommand();
3582 StartTransactionCommand();
3586 * ReleaseCurrentSubTransaction
3588 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
3589 * savepoint name (if any).
3590 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3593 ReleaseCurrentSubTransaction(void)
3595 TransactionState s = CurrentTransactionState;
3597 if (s->blockState != TBLOCK_SUBINPROGRESS)
3598 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
3599 BlockStateAsString(s->blockState));
3600 Assert(s->state == TRANS_INPROGRESS);
3601 MemoryContextSwitchTo(CurTransactionContext);
3602 CommitSubTransaction();
3603 s = CurrentTransactionState; /* changed by pop */
3604 Assert(s->state == TRANS_INPROGRESS);
3608 * RollbackAndReleaseCurrentSubTransaction
3610 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
3611 * of its savepoint name (if any).
3612 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3615 RollbackAndReleaseCurrentSubTransaction(void)
3617 TransactionState s = CurrentTransactionState;
3619 switch (s->blockState)
3621 /* Must be in a subtransaction */
3622 case TBLOCK_SUBINPROGRESS:
3623 case TBLOCK_SUBABORT:
3626 /* These cases are invalid. */
3627 case TBLOCK_DEFAULT:
3628 case TBLOCK_STARTED:
3630 case TBLOCK_SUBBEGIN:
3631 case TBLOCK_INPROGRESS:
3635 case TBLOCK_ABORT_END:
3636 case TBLOCK_SUBABORT_END:
3637 case TBLOCK_ABORT_PENDING:
3638 case TBLOCK_SUBABORT_PENDING:
3639 case TBLOCK_SUBRESTART:
3640 case TBLOCK_SUBABORT_RESTART:
3641 case TBLOCK_PREPARE:
3642 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
3643 BlockStateAsString(s->blockState));
3648 * Abort the current subtransaction, if needed.
3650 if (s->blockState == TBLOCK_SUBINPROGRESS)
3651 AbortSubTransaction();
3653 /* And clean it up, too */
3654 CleanupSubTransaction();
3656 s = CurrentTransactionState; /* changed by pop */
3657 AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
3658 s->blockState == TBLOCK_INPROGRESS ||
3659 s->blockState == TBLOCK_STARTED);
3663 * AbortOutOfAnyTransaction
3665 * This routine is provided for error recovery purposes. It aborts any
3666 * active transaction or transaction block, leaving the system in a known
3670 AbortOutOfAnyTransaction(void)
3672 TransactionState s = CurrentTransactionState;
3675 * Get out of any transaction or nested transaction
3679 switch (s->blockState)
3681 case TBLOCK_DEFAULT:
3682 /* Not in a transaction, do nothing */
3684 case TBLOCK_STARTED:
3686 case TBLOCK_INPROGRESS:
3688 case TBLOCK_ABORT_PENDING:
3689 case TBLOCK_PREPARE:
3690 /* In a transaction, so clean up */
3692 CleanupTransaction();
3693 s->blockState = TBLOCK_DEFAULT;
3696 case TBLOCK_ABORT_END:
3697 /* AbortTransaction already done, still need Cleanup */
3698 CleanupTransaction();
3699 s->blockState = TBLOCK_DEFAULT;
3703 * In a subtransaction, so clean it up and abort parent too
3705 case TBLOCK_SUBBEGIN:
3706 case TBLOCK_SUBINPROGRESS:
3708 case TBLOCK_SUBABORT_PENDING:
3709 case TBLOCK_SUBRESTART:
3710 AbortSubTransaction();
3711 CleanupSubTransaction();
3712 s = CurrentTransactionState; /* changed by pop */
3715 case TBLOCK_SUBABORT:
3716 case TBLOCK_SUBABORT_END:
3717 case TBLOCK_SUBABORT_RESTART:
3718 /* As above, but AbortSubTransaction already done */
3719 CleanupSubTransaction();
3720 s = CurrentTransactionState; /* changed by pop */
3723 } while (s->blockState != TBLOCK_DEFAULT);
3725 /* Should be out of all subxacts now */
3726 Assert(s->parent == NULL);
3730 * IsTransactionBlock --- are we within a transaction block?
3733 IsTransactionBlock(void)
3735 TransactionState s = CurrentTransactionState;
3737 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
3744 * IsTransactionOrTransactionBlock --- are we within either a transaction
3745 * or a transaction block? (The backend is only really "idle" when this
3748 * This should match up with IsTransactionBlock and IsTransactionState.
3751 IsTransactionOrTransactionBlock(void)
3753 TransactionState s = CurrentTransactionState;
3755 if (s->blockState == TBLOCK_DEFAULT)
3762 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
3765 TransactionBlockStatusCode(void)
3767 TransactionState s = CurrentTransactionState;
3769 switch (s->blockState)
3771 case TBLOCK_DEFAULT:
3772 case TBLOCK_STARTED:
3773 return 'I'; /* idle --- not in transaction */
3775 case TBLOCK_SUBBEGIN:
3776 case TBLOCK_INPROGRESS:
3777 case TBLOCK_SUBINPROGRESS:
3780 case TBLOCK_PREPARE:
3781 return 'T'; /* in transaction */
3783 case TBLOCK_SUBABORT:
3784 case TBLOCK_ABORT_END:
3785 case TBLOCK_SUBABORT_END:
3786 case TBLOCK_ABORT_PENDING:
3787 case TBLOCK_SUBABORT_PENDING:
3788 case TBLOCK_SUBRESTART:
3789 case TBLOCK_SUBABORT_RESTART:
3790 return 'E'; /* in failed transaction */
3793 /* should never get here */
3794 elog(FATAL, "invalid transaction block state: %s",
3795 BlockStateAsString(s->blockState));
3796 return 0; /* keep compiler quiet */
3803 IsSubTransaction(void)
3805 TransactionState s = CurrentTransactionState;
3807 if (s->nestingLevel >= 2)
3814 * StartSubTransaction
3816 * If you're wondering why this is separate from PushTransaction: it's because
3817 * we can't conveniently do this stuff right inside DefineSavepoint. The
3818 * SAVEPOINT utility command will be executed inside a Portal, and if we
3819 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
3820 * the Portal will undo those settings. So we make DefineSavepoint just
3821 * push a dummy transaction block, and when control returns to the main
3822 * idle loop, CommitTransactionCommand will be called, and we'll come here
3823 * to finish starting the subtransaction.
3826 StartSubTransaction(void)
3828 TransactionState s = CurrentTransactionState;
3830 if (s->state != TRANS_DEFAULT)
3831 elog(WARNING, "StartSubTransaction while in %s state",
3832 TransStateAsString(s->state));
3834 s->state = TRANS_START;
3837 * Initialize subsystems for new subtransaction
3839 * must initialize resource-management stuff first
3841 AtSubStart_Memory();
3842 AtSubStart_ResourceOwner();
3844 AtSubStart_Notify();
3845 AfterTriggerBeginSubXact();
3847 s->state = TRANS_INPROGRESS;
3850 * Call start-of-subxact callbacks
3852 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
3853 s->parent->subTransactionId);
3855 ShowTransactionState("StartSubTransaction");
3859 * CommitSubTransaction
3861 * The caller has to make sure to always reassign CurrentTransactionState
3862 * if it has a local pointer to it after calling this function.
3865 CommitSubTransaction(void)
3867 TransactionState s = CurrentTransactionState;
3869 ShowTransactionState("CommitSubTransaction");
3871 if (s->state != TRANS_INPROGRESS)
3872 elog(WARNING, "CommitSubTransaction while in %s state",
3873 TransStateAsString(s->state));
3875 /* Pre-commit processing goes here -- nothing to do at the moment */
3877 s->state = TRANS_COMMIT;
3879 /* Must CCI to ensure commands of subtransaction are seen as done */
3880 CommandCounterIncrement();
3883 * Prior to 8.4 we marked subcommit in clog at this point. We now only
3884 * perform that step, if required, as part of the atomic update of the
3885 * whole transaction tree at top level commit or abort.
3888 /* Post-commit cleanup */
3889 if (TransactionIdIsValid(s->transactionId))
3890 AtSubCommit_childXids();
3891 AfterTriggerEndSubXact(true);
3892 AtSubCommit_Portals(s->subTransactionId,
3893 s->parent->subTransactionId,
3894 s->parent->curTransactionOwner);
3895 AtEOSubXact_LargeObject(true, s->subTransactionId,
3896 s->parent->subTransactionId);
3897 AtSubCommit_Notify();
3899 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
3900 s->parent->subTransactionId);
3902 ResourceOwnerRelease(s->curTransactionOwner,
3903 RESOURCE_RELEASE_BEFORE_LOCKS,
3905 AtEOSubXact_RelationCache(true, s->subTransactionId,
3906 s->parent->subTransactionId);
3907 AtEOSubXact_Inval(true);
3911 * The only lock we actually release here is the subtransaction XID lock.
3912 * The rest just get transferred to the parent resource owner.
3914 CurrentResourceOwner = s->curTransactionOwner;
3915 if (TransactionIdIsValid(s->transactionId))
3916 XactLockTableDelete(s->transactionId);
3918 ResourceOwnerRelease(s->curTransactionOwner,
3919 RESOURCE_RELEASE_LOCKS,
3921 ResourceOwnerRelease(s->curTransactionOwner,
3922 RESOURCE_RELEASE_AFTER_LOCKS,
3925 AtEOXact_GUC(true, s->gucNestLevel);
3926 AtEOSubXact_SPI(true, s->subTransactionId);
3927 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
3928 s->parent->subTransactionId);
3929 AtEOSubXact_Namespace(true, s->subTransactionId,
3930 s->parent->subTransactionId);
3931 AtEOSubXact_Files(true, s->subTransactionId,
3932 s->parent->subTransactionId);
3933 AtEOSubXact_HashTables(true, s->nestingLevel);
3934 AtEOSubXact_PgStat(true, s->nestingLevel);
3935 AtSubCommit_Snapshot(s->nestingLevel);
3938 * We need to restore the upper transaction's read-only state, in case the
3939 * upper is read-write while the child is read-only; GUC will incorrectly
3940 * think it should leave the child state in place.
3942 XactReadOnly = s->prevXactReadOnly;
3944 CurrentResourceOwner = s->parent->curTransactionOwner;
3945 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3946 ResourceOwnerDelete(s->curTransactionOwner);
3947 s->curTransactionOwner = NULL;
3949 AtSubCommit_Memory();
3951 s->state = TRANS_DEFAULT;
3957 * AbortSubTransaction
3960 AbortSubTransaction(void)
3962 TransactionState s = CurrentTransactionState;
3964 /* Prevent cancel/die interrupt while cleaning up */
3967 /* Make sure we have a valid memory context and resource owner */
3968 AtSubAbort_Memory();
3969 AtSubAbort_ResourceOwner();
3972 * Release any LW locks we might be holding as quickly as possible.
3973 * (Regular locks, however, must be held till we finish aborting.)
3974 * Releasing LW locks is critical since we might try to grab them again
3975 * while cleaning up!
3977 * FIXME This may be incorrect --- Are there some locks we should keep?
3978 * Buffer locks, for example? I don't think so but I'm not sure.
3988 * check the current transaction state
3990 ShowTransactionState("AbortSubTransaction");
3992 if (s->state != TRANS_INPROGRESS)
3993 elog(WARNING, "AbortSubTransaction while in %s state",
3994 TransStateAsString(s->state));
3996 s->state = TRANS_ABORT;
3999 * Reset user ID which might have been changed transiently. (See notes in
4000 * AbortTransaction.)
4002 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
4005 * We can skip all this stuff if the subxact failed before creating a
4008 if (s->curTransactionOwner)
4010 AfterTriggerEndSubXact(false);
4011 AtSubAbort_Portals(s->subTransactionId,
4012 s->parent->subTransactionId,
4013 s->parent->curTransactionOwner);
4014 AtEOSubXact_LargeObject(false, s->subTransactionId,
4015 s->parent->subTransactionId);
4016 AtSubAbort_Notify();
4018 /* Advertise the fact that we aborted in pg_clog. */
4019 (void) RecordTransactionAbort(true);
4021 /* Post-abort cleanup */
4022 if (TransactionIdIsValid(s->transactionId))
4023 AtSubAbort_childXids();
4025 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
4026 s->parent->subTransactionId);
4028 ResourceOwnerRelease(s->curTransactionOwner,
4029 RESOURCE_RELEASE_BEFORE_LOCKS,
4031 AtEOSubXact_RelationCache(false, s->subTransactionId,
4032 s->parent->subTransactionId);
4033 AtEOSubXact_Inval(false);
4035 ResourceOwnerRelease(s->curTransactionOwner,
4036 RESOURCE_RELEASE_LOCKS,
4038 ResourceOwnerRelease(s->curTransactionOwner,
4039 RESOURCE_RELEASE_AFTER_LOCKS,
4042 AtEOXact_GUC(false, s->gucNestLevel);
4043 AtEOSubXact_SPI(false, s->subTransactionId);
4044 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
4045 s->parent->subTransactionId);
4046 AtEOSubXact_Namespace(false, s->subTransactionId,
4047 s->parent->subTransactionId);
4048 AtEOSubXact_Files(false, s->subTransactionId,
4049 s->parent->subTransactionId);
4050 AtEOSubXact_HashTables(false, s->nestingLevel);
4051 AtEOSubXact_PgStat(false, s->nestingLevel);
4052 AtSubAbort_Snapshot(s->nestingLevel);
4056 * Restore the upper transaction's read-only state, too. This should be
4057 * redundant with GUC's cleanup but we may as well do it for consistency
4058 * with the commit case.
4060 XactReadOnly = s->prevXactReadOnly;
4062 RESUME_INTERRUPTS();
4066 * CleanupSubTransaction
4068 * The caller has to make sure to always reassign CurrentTransactionState
4069 * if it has a local pointer to it after calling this function.
4072 CleanupSubTransaction(void)
4074 TransactionState s = CurrentTransactionState;
4076 ShowTransactionState("CleanupSubTransaction");
4078 if (s->state != TRANS_ABORT)
4079 elog(WARNING, "CleanupSubTransaction while in %s state",
4080 TransStateAsString(s->state));
4082 AtSubCleanup_Portals(s->subTransactionId);
4084 CurrentResourceOwner = s->parent->curTransactionOwner;
4085 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4086 if (s->curTransactionOwner)
4087 ResourceOwnerDelete(s->curTransactionOwner);
4088 s->curTransactionOwner = NULL;
4090 AtSubCleanup_Memory();
4092 s->state = TRANS_DEFAULT;
4099 * Create transaction state stack entry for a subtransaction
4101 * The caller has to make sure to always reassign CurrentTransactionState
4102 * if it has a local pointer to it after calling this function.
4105 PushTransaction(void)
4107 TransactionState p = CurrentTransactionState;
4111 * We keep subtransaction state nodes in TopTransactionContext.
4113 s = (TransactionState)
4114 MemoryContextAllocZero(TopTransactionContext,
4115 sizeof(TransactionStateData));
4118 * Assign a subtransaction ID, watching out for counter wraparound.
4120 currentSubTransactionId += 1;
4121 if (currentSubTransactionId == InvalidSubTransactionId)
4123 currentSubTransactionId -= 1;
4126 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
4127 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
4131 * We can now stack a minimally valid subtransaction without fear of
4134 s->transactionId = InvalidTransactionId; /* until assigned */
4135 s->subTransactionId = currentSubTransactionId;
4137 s->nestingLevel = p->nestingLevel + 1;
4138 s->gucNestLevel = NewGUCNestLevel();
4139 s->savepointLevel = p->savepointLevel;
4140 s->state = TRANS_DEFAULT;
4141 s->blockState = TBLOCK_SUBBEGIN;
4142 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
4143 s->prevXactReadOnly = XactReadOnly;
4145 CurrentTransactionState = s;
4148 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
4149 * with the subtransaction from here on out; in particular they should not
4150 * assume that it necessarily has a transaction context, resource owner,
4157 * Pop back to parent transaction state
4159 * The caller has to make sure to always reassign CurrentTransactionState
4160 * if it has a local pointer to it after calling this function.
4163 PopTransaction(void)
4165 TransactionState s = CurrentTransactionState;
4167 if (s->state != TRANS_DEFAULT)
4168 elog(WARNING, "PopTransaction while in %s state",
4169 TransStateAsString(s->state));
4171 if (s->parent == NULL)
4172 elog(FATAL, "PopTransaction with no parent");
4174 CurrentTransactionState = s->parent;
4176 /* Let's just make sure CurTransactionContext is good */
4177 CurTransactionContext = s->parent->curTransactionContext;
4178 MemoryContextSwitchTo(CurTransactionContext);
4180 /* Ditto for ResourceOwner links */
4181 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4182 CurrentResourceOwner = s->parent->curTransactionOwner;
4184 /* Free the old child structure */
4191 * ShowTransactionState
4195 ShowTransactionState(const char *str)
4197 /* skip work if message will definitely not be printed */
4198 if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
4200 elog(DEBUG3, "%s", str);
4201 ShowTransactionStateRec(CurrentTransactionState);
4206 * ShowTransactionStateRec
4207 * Recursive subroutine for ShowTransactionState
4210 ShowTransactionStateRec(TransactionState s)
4214 initStringInfo(&buf);
4216 if (s->nChildXids > 0)
4220 appendStringInfo(&buf, "%u", s->childXids[0]);
4221 for (i = 1; i < s->nChildXids; i++)
4222 appendStringInfo(&buf, " %u", s->childXids[i]);
4226 ShowTransactionStateRec(s->parent);
4228 /* use ereport to suppress computation if msg will not be printed */
4230 (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u%s, nestlvl: %d, children: %s",
4231 PointerIsValid(s->name) ? s->name : "unnamed",
4232 BlockStateAsString(s->blockState),
4233 TransStateAsString(s->state),
4234 (unsigned int) s->transactionId,
4235 (unsigned int) s->subTransactionId,
4236 (unsigned int) currentCommandId,
4237 currentCommandIdUsed ? " (used)" : "",
4238 s->nestingLevel, buf.data)));
4244 * BlockStateAsString
4248 BlockStateAsString(TBlockState blockState)
4252 case TBLOCK_DEFAULT:
4254 case TBLOCK_STARTED:
4258 case TBLOCK_INPROGRESS:
4259 return "INPROGRESS";
4264 case TBLOCK_ABORT_END:
4266 case TBLOCK_ABORT_PENDING:
4267 return "ABORT PEND";
4268 case TBLOCK_PREPARE:
4270 case TBLOCK_SUBBEGIN:
4272 case TBLOCK_SUBINPROGRESS:
4273 return "SUB INPROGRS";
4276 case TBLOCK_SUBABORT:
4278 case TBLOCK_SUBABORT_END:
4279 return "SUB ABORT END";
4280 case TBLOCK_SUBABORT_PENDING:
4281 return "SUB ABRT PEND";
4282 case TBLOCK_SUBRESTART:
4283 return "SUB RESTART";
4284 case TBLOCK_SUBABORT_RESTART:
4285 return "SUB AB RESTRT";
4287 return "UNRECOGNIZED";
4291 * TransStateAsString
4295 TransStateAsString(TransState state)
4303 case TRANS_INPROGRESS:
4312 return "UNRECOGNIZED";
4316 * xactGetCommittedChildren
4318 * Gets the list of committed children of the current transaction. The return
4319 * value is the number of child transactions. *ptr is set to point to an
4320 * array of TransactionIds. The array is allocated in TopTransactionContext;
4321 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
4322 * If there are no subxacts, *ptr is set to NULL.
4325 xactGetCommittedChildren(TransactionId **ptr)
4327 TransactionState s = CurrentTransactionState;
4329 if (s->nChildXids == 0)
4332 *ptr = s->childXids;
4334 return s->nChildXids;
4338 * XLOG support routines
4342 * Before 8.5 this was a fairly short function, but now it performs many
4343 * actions for which the order of execution is critical.
4346 xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid, XLogRecPtr lsn)
4348 TransactionId *sub_xids;
4349 SharedInvalidationMessage *inval_msgs;
4350 TransactionId max_xid;
4353 /* subxid array follows relfilenodes */
4354 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4355 /* invalidation messages array follows subxids */
4356 inval_msgs = (SharedInvalidationMessage *) &(sub_xids[xlrec->nsubxacts]);
4358 max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
4361 * Make sure nextXid is beyond any XID mentioned in the record.
4363 * We don't expect anyone else to modify nextXid, hence we
4364 * don't need to hold a lock while checking this. We still acquire
4365 * the lock to modify it, though.
4367 if (TransactionIdFollowsOrEquals(max_xid,
4368 ShmemVariableCache->nextXid))
4370 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4371 ShmemVariableCache->nextXid = max_xid;
4372 TransactionIdAdvance(ShmemVariableCache->nextXid);
4373 LWLockRelease(XidGenLock);
4379 * Mark the transaction committed in pg_clog.
4381 TransactionIdCommitTree(xid, xlrec->nsubxacts, sub_xids);
4386 * If a transaction completion record arrives that has as-yet
4387 * unobserved subtransactions then this will not have been fully
4388 * handled by the call to RecordKnownAssignedTransactionIds() in the
4389 * main recovery loop in xlog.c. So we need to do bookkeeping again to
4390 * cover that case. This is confusing and it is easy to think this
4391 * call is irrelevant, which has happened three times in development
4392 * already. Leave it in.
4394 RecordKnownAssignedTransactionIds(max_xid);
4397 * Mark the transaction committed in pg_clog. We use async commit
4398 * protocol during recovery to provide information on database
4399 * consistency for when users try to set hint bits. It is important
4400 * that we do not set hint bits until the minRecoveryPoint is past
4401 * this commit record. This ensures that if we crash we don't see
4402 * hint bits set on changes made by transactions that haven't yet
4403 * recovered. It's unlikely but it's good to be safe.
4405 TransactionIdAsyncCommitTree(xid, xlrec->nsubxacts, sub_xids, lsn);
4408 * We must mark clog before we update the ProcArray.
4410 ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids);
4413 * Send any cache invalidations attached to the commit. We must
4414 * maintain the same order of invalidation then release locks
4417 ProcessCommittedInvalidationMessages(inval_msgs, xlrec->nmsgs,
4418 XactCompletionRelcacheInitFileInval(xlrec),
4419 xlrec->dbId, xlrec->tsId);
4422 * Release locks, if any. We do this for both two phase and normal
4423 * one phase transactions. In effect we are ignoring the prepare
4424 * phase and just going straight to lock release.
4426 StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
4429 /* Make sure files supposed to be dropped are dropped */
4430 for (i = 0; i < xlrec->nrels; i++)
4432 SMgrRelation srel = smgropen(xlrec->xnodes[i]);
4435 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4437 if (smgrexists(srel, fork))
4439 XLogDropRelation(xlrec->xnodes[i], fork);
4440 smgrdounlink(srel, fork, false, true);
4447 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit() in
4448 * normal operation. For example, in DROP DATABASE, we delete all the files
4449 * belonging to the database, and then commit the transaction. If we crash
4450 * after all the files have been deleted but before the commit, you have an
4451 * entry in pg_database without any files. To minimize the window for that,
4452 * we use ForceSyncCommit() to rush the commit record to disk as quick as
4453 * possible. We have the same window during recovery, and forcing an
4454 * XLogFlush() (which updates minRecoveryPoint during recovery) helps
4455 * to reduce that problem window, for any user that requested ForceSyncCommit().
4457 if (XactCompletionForceSyncCommit(xlrec))
4462 * Be careful with the order of execution, as with xact_redo_commit().
4463 * The two functions are similar but differ in key places.
4465 * Note also that an abort can be for a subtransaction and its children,
4466 * not just for a top level abort. That means we have to consider
4467 * topxid != xid, whereas in commit we would find topxid == xid always
4468 * because subtransaction commit is never WAL logged.
4471 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
4473 TransactionId *sub_xids;
4474 TransactionId max_xid;
4477 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4478 max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
4480 /* Make sure nextXid is beyond any XID mentioned in the record */
4481 /* We don't expect anyone else to modify nextXid, hence we
4482 * don't need to hold a lock while checking this. We still acquire
4483 * the lock to modify it, though.
4485 if (TransactionIdFollowsOrEquals(max_xid,
4486 ShmemVariableCache->nextXid))
4488 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4489 ShmemVariableCache->nextXid = max_xid;
4490 TransactionIdAdvance(ShmemVariableCache->nextXid);
4491 LWLockRelease(XidGenLock);
4497 * If a transaction completion record arrives that has as-yet unobserved
4498 * subtransactions then this will not have been fully handled by the call
4499 * to RecordKnownAssignedTransactionIds() in the main recovery loop in
4500 * xlog.c. So we need to do bookkeeping again to cover that case. This is
4501 * confusing and it is easy to think this call is irrelevant, which has
4502 * happened three times in development already. Leave it in.
4504 RecordKnownAssignedTransactionIds(max_xid);
4507 /* Mark the transaction aborted in pg_clog, no need for async stuff */
4508 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4513 * We must mark clog before we update the ProcArray.
4515 ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids);
4518 * There are no flat files that need updating, nor invalidation
4519 * messages to send or undo.
4523 * Release locks, if any. There are no invalidations to send.
4525 StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
4528 /* Make sure files supposed to be dropped are dropped */
4529 for (i = 0; i < xlrec->nrels; i++)
4531 SMgrRelation srel = smgropen(xlrec->xnodes[i]);
4534 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4536 if (smgrexists(srel, fork))
4538 XLogDropRelation(xlrec->xnodes[i], fork);
4539 smgrdounlink(srel, fork, false, true);
4547 xact_redo(XLogRecPtr lsn, XLogRecord *record)
4549 uint8 info = record->xl_info & ~XLR_INFO_MASK;
4551 /* Backup blocks are not used in xact records */
4552 Assert(!(record->xl_info & XLR_BKP_BLOCK_MASK));
4554 if (info == XLOG_XACT_COMMIT)
4556 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
4558 xact_redo_commit(xlrec, record->xl_xid, lsn);
4560 else if (info == XLOG_XACT_ABORT)
4562 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
4564 xact_redo_abort(xlrec, record->xl_xid);
4566 else if (info == XLOG_XACT_PREPARE)
4568 /* the record contents are exactly the 2PC file */
4569 RecreateTwoPhaseFile(record->xl_xid,
4570 XLogRecGetData(record), record->xl_len);
4572 else if (info == XLOG_XACT_COMMIT_PREPARED)
4574 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
4576 xact_redo_commit(&xlrec->crec, xlrec->xid, lsn);
4577 RemoveTwoPhaseFile(xlrec->xid, false);
4579 else if (info == XLOG_XACT_ABORT_PREPARED)
4581 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
4583 xact_redo_abort(&xlrec->arec, xlrec->xid);
4584 RemoveTwoPhaseFile(xlrec->xid, false);
4586 else if (info == XLOG_XACT_ASSIGNMENT)
4588 xl_xact_assignment *xlrec = (xl_xact_assignment *) XLogRecGetData(record);
4591 ProcArrayApplyXidAssignment(xlrec->xtop,
4592 xlrec->nsubxacts, xlrec->xsub);
4595 elog(PANIC, "xact_redo: unknown op code %u", info);
4599 xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
4602 TransactionId *xacts;
4604 xacts = (TransactionId *) &xlrec->xnodes[xlrec->nrels];
4606 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4608 if (xlrec->nrels > 0)
4610 appendStringInfo(buf, "; rels:");
4611 for (i = 0; i < xlrec->nrels; i++)
4613 char *path = relpath(xlrec->xnodes[i], MAIN_FORKNUM);
4615 appendStringInfo(buf, " %s", path);
4619 if (xlrec->nsubxacts > 0)
4621 appendStringInfo(buf, "; subxacts:");
4622 for (i = 0; i < xlrec->nsubxacts; i++)
4623 appendStringInfo(buf, " %u", xacts[i]);
4625 if (xlrec->nmsgs > 0)
4627 SharedInvalidationMessage *msgs;
4629 msgs = (SharedInvalidationMessage *) &xacts[xlrec->nsubxacts];
4631 if (XactCompletionRelcacheInitFileInval(xlrec))
4632 appendStringInfo(buf, "; relcache init file inval dbid %u tsid %u",
4633 xlrec->dbId, xlrec->tsId);
4635 appendStringInfo(buf, "; inval msgs:");
4636 for (i = 0; i < xlrec->nmsgs; i++)
4638 SharedInvalidationMessage *msg = &msgs[i];
4641 appendStringInfo(buf, " catcache %d", msg->id);
4642 else if (msg->id == SHAREDINVALCATALOG_ID)
4643 appendStringInfo(buf, " catalog %u", msg->cat.catId);
4644 else if (msg->id == SHAREDINVALRELCACHE_ID)
4645 appendStringInfo(buf, " relcache %u", msg->rc.relId);
4646 /* remaining cases not expected, but print something anyway */
4647 else if (msg->id == SHAREDINVALSMGR_ID)
4648 appendStringInfo(buf, " smgr");
4649 else if (msg->id == SHAREDINVALRELMAP_ID)
4650 appendStringInfo(buf, " relmap");
4652 appendStringInfo(buf, " unknown id %d", msg->id);
4658 xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
4662 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4663 if (xlrec->nrels > 0)
4665 appendStringInfo(buf, "; rels:");
4666 for (i = 0; i < xlrec->nrels; i++)
4668 char *path = relpath(xlrec->xnodes[i], MAIN_FORKNUM);
4670 appendStringInfo(buf, " %s", path);
4674 if (xlrec->nsubxacts > 0)
4676 TransactionId *xacts = (TransactionId *)
4677 &xlrec->xnodes[xlrec->nrels];
4679 appendStringInfo(buf, "; subxacts:");
4680 for (i = 0; i < xlrec->nsubxacts; i++)
4681 appendStringInfo(buf, " %u", xacts[i]);
4686 xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
4690 appendStringInfo(buf, "subxacts:");
4692 for (i = 0; i < xlrec->nsubxacts; i++)
4693 appendStringInfo(buf, " %u", xlrec->xsub[i]);
4697 xact_desc(StringInfo buf, uint8 xl_info, char *rec)
4699 uint8 info = xl_info & ~XLR_INFO_MASK;
4701 if (info == XLOG_XACT_COMMIT)
4703 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
4705 appendStringInfo(buf, "commit: ");
4706 xact_desc_commit(buf, xlrec);
4708 else if (info == XLOG_XACT_ABORT)
4710 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
4712 appendStringInfo(buf, "abort: ");
4713 xact_desc_abort(buf, xlrec);
4715 else if (info == XLOG_XACT_PREPARE)
4717 appendStringInfo(buf, "prepare");
4719 else if (info == XLOG_XACT_COMMIT_PREPARED)
4721 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
4723 appendStringInfo(buf, "commit prepared %u: ", xlrec->xid);
4724 xact_desc_commit(buf, &xlrec->crec);
4726 else if (info == XLOG_XACT_ABORT_PREPARED)
4728 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
4730 appendStringInfo(buf, "abort prepared %u: ", xlrec->xid);
4731 xact_desc_abort(buf, &xlrec->arec);
4733 else if (info == XLOG_XACT_ASSIGNMENT)
4735 xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
4738 * Note that we ignore the WAL record's xid, since we're more
4739 * interested in the top-level xid that issued the record
4740 * and which xids are being reported here.
4742 appendStringInfo(buf, "xid assignment xtop %u: ", xlrec->xtop);
4743 xact_desc_assignment(buf, xlrec);
4746 appendStringInfo(buf, "UNKNOWN");