1 /*-------------------------------------------------------------------------
4 * top level transaction system support routines
6 * See src/backend/access/transam/README for more information.
8 * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
13 * src/backend/access/transam/xact.c
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 "replication/walsender.h"
40 #include "replication/syncrep.h"
41 #include "storage/lmgr.h"
42 #include "storage/predicate.h"
43 #include "storage/procarray.h"
44 #include "storage/sinvaladt.h"
45 #include "storage/smgr.h"
46 #include "utils/combocid.h"
47 #include "utils/guc.h"
48 #include "utils/inval.h"
49 #include "utils/memutils.h"
50 #include "utils/relmapper.h"
51 #include "utils/snapmgr.h"
52 #include "utils/timestamp.h"
57 * User-tweakable parameters
59 int DefaultXactIsoLevel = XACT_READ_COMMITTED;
62 bool DefaultXactReadOnly = false;
65 bool DefaultXactDeferrable = false;
68 int synchronous_commit = SYNCHRONOUS_COMMIT_ON;
70 int CommitDelay = 0; /* precommit delay in microseconds */
71 int CommitSiblings = 5; /* # concurrent xacts needed to sleep */
74 * MyXactAccessedTempRel is set when a temporary relation is accessed.
75 * We don't allow PREPARE TRANSACTION in that case. (This is global
76 * so that it can be set from heapam.c.)
78 bool MyXactAccessedTempRel = false;
82 * transaction states - transaction state from server perspective
84 typedef enum TransState
86 TRANS_DEFAULT, /* idle */
87 TRANS_START, /* transaction starting */
88 TRANS_INPROGRESS, /* inside a valid transaction */
89 TRANS_COMMIT, /* commit in progress */
90 TRANS_ABORT, /* abort in progress */
91 TRANS_PREPARE /* prepare in progress */
95 * transaction block states - transaction state of client queries
97 * Note: the subtransaction states are used only for non-topmost
98 * transactions; the others appear only in the topmost transaction.
100 typedef enum TBlockState
102 /* not-in-transaction-block states */
103 TBLOCK_DEFAULT, /* idle */
104 TBLOCK_STARTED, /* running single-query transaction */
106 /* transaction block states */
107 TBLOCK_BEGIN, /* starting transaction block */
108 TBLOCK_INPROGRESS, /* live transaction */
109 TBLOCK_END, /* COMMIT received */
110 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
111 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
112 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
113 TBLOCK_PREPARE, /* live xact, PREPARE received */
115 /* subtransaction states */
116 TBLOCK_SUBBEGIN, /* starting a subtransaction */
117 TBLOCK_SUBINPROGRESS, /* live subtransaction */
118 TBLOCK_SUBRELEASE, /* RELEASE received */
119 TBLOCK_SUBCOMMIT, /* COMMIT received while TBLOCK_SUBINPROGRESS */
120 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
121 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
122 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
123 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
124 TBLOCK_SUBABORT_RESTART /* failed subxact, ROLLBACK TO received */
128 * transaction state structure
130 typedef struct TransactionStateData
132 TransactionId transactionId; /* my XID, or Invalid if none */
133 SubTransactionId subTransactionId; /* my subxact ID */
134 char *name; /* savepoint name, if any */
135 int savepointLevel; /* savepoint level */
136 TransState state; /* low-level state */
137 TBlockState blockState; /* high-level state */
138 int nestingLevel; /* transaction nesting depth */
139 int gucNestLevel; /* GUC context nesting depth */
140 MemoryContext curTransactionContext; /* my xact-lifetime context */
141 ResourceOwner curTransactionOwner; /* my query resources */
142 TransactionId *childXids; /* subcommitted child XIDs, in XID order */
143 int nChildXids; /* # of subcommitted child XIDs */
144 int maxChildXids; /* allocated size of childXids[] */
145 Oid prevUser; /* previous CurrentUserId setting */
146 int prevSecContext; /* previous SecurityRestrictionContext */
147 bool prevXactReadOnly; /* entry-time xact r/o state */
148 bool startedInRecovery; /* did we start in recovery? */
149 struct TransactionStateData *parent; /* back link to parent */
150 } TransactionStateData;
152 typedef TransactionStateData *TransactionState;
155 * CurrentTransactionState always points to the current transaction state
156 * block. It will point to TopTransactionStateData when not in a
157 * transaction at all, or when in a top-level transaction.
159 static TransactionStateData TopTransactionStateData = {
160 0, /* transaction id */
161 0, /* subtransaction id */
162 NULL, /* savepoint name */
163 0, /* savepoint level */
164 TRANS_DEFAULT, /* transaction state */
165 TBLOCK_DEFAULT, /* transaction block state from the client
167 0, /* transaction nesting depth */
168 0, /* GUC context nesting depth */
169 NULL, /* cur transaction context */
170 NULL, /* cur transaction resource owner */
171 NULL, /* subcommitted child Xids */
172 0, /* # of subcommitted child Xids */
173 0, /* allocated size of childXids[] */
174 InvalidOid, /* previous CurrentUserId setting */
175 0, /* previous SecurityRestrictionContext */
176 false, /* entry-time xact r/o state */
177 false, /* startedInRecovery */
178 NULL /* link to parent state block */
182 * unreportedXids holds XIDs of all subtransactions that have not yet been
183 * reported in a XLOG_XACT_ASSIGNMENT record.
185 static int nUnreportedXids;
186 static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS];
188 static TransactionState CurrentTransactionState = &TopTransactionStateData;
191 * The subtransaction ID and command ID assignment counters are global
192 * to a whole transaction, so we do not keep them in the state stack.
194 static SubTransactionId currentSubTransactionId;
195 static CommandId currentCommandId;
196 static bool currentCommandIdUsed;
199 * xactStartTimestamp is the value of transaction_timestamp().
200 * stmtStartTimestamp is the value of statement_timestamp().
201 * xactStopTimestamp is the time at which we log a commit or abort WAL record.
202 * These do not change as we enter and exit subtransactions, so we don't
203 * keep them inside the TransactionState stack.
205 static TimestampTz xactStartTimestamp;
206 static TimestampTz stmtStartTimestamp;
207 static TimestampTz xactStopTimestamp;
210 * GID to be used for preparing the current transaction. This is also
211 * global to a whole transaction, so we don't keep it in the state stack.
213 static char *prepareGID;
216 * Some commands want to force synchronous commit.
218 static bool forceSyncCommit = false;
221 * Private context for transaction-abort work --- we reserve space for this
222 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
223 * when we've run out of memory.
225 static MemoryContext TransactionAbortContext = NULL;
228 * List of add-on start- and end-of-xact callbacks
230 typedef struct XactCallbackItem
232 struct XactCallbackItem *next;
233 XactCallback callback;
237 static XactCallbackItem *Xact_callbacks = NULL;
240 * List of add-on start- and end-of-subxact callbacks
242 typedef struct SubXactCallbackItem
244 struct SubXactCallbackItem *next;
245 SubXactCallback callback;
247 } SubXactCallbackItem;
249 static SubXactCallbackItem *SubXact_callbacks = NULL;
252 /* local function prototypes */
253 static void AssignTransactionId(TransactionState s);
254 static void AbortTransaction(void);
255 static void AtAbort_Memory(void);
256 static void AtCleanup_Memory(void);
257 static void AtAbort_ResourceOwner(void);
258 static void AtCCI_LocalCache(void);
259 static void AtCommit_Memory(void);
260 static void AtStart_Cache(void);
261 static void AtStart_Memory(void);
262 static void AtStart_ResourceOwner(void);
263 static void CallXactCallbacks(XactEvent event);
264 static void CallSubXactCallbacks(SubXactEvent event,
265 SubTransactionId mySubid,
266 SubTransactionId parentSubid);
267 static void CleanupTransaction(void);
268 static void CommitTransaction(void);
269 static TransactionId RecordTransactionAbort(bool isSubXact);
270 static void StartTransaction(void);
272 static void StartSubTransaction(void);
273 static void CommitSubTransaction(void);
274 static void AbortSubTransaction(void);
275 static void CleanupSubTransaction(void);
276 static void PushTransaction(void);
277 static void PopTransaction(void);
279 static void AtSubAbort_Memory(void);
280 static void AtSubCleanup_Memory(void);
281 static void AtSubAbort_ResourceOwner(void);
282 static void AtSubCommit_Memory(void);
283 static void AtSubStart_Memory(void);
284 static void AtSubStart_ResourceOwner(void);
286 static void ShowTransactionState(const char *str);
287 static void ShowTransactionStateRec(TransactionState state);
288 static const char *BlockStateAsString(TBlockState blockState);
289 static const char *TransStateAsString(TransState state);
292 /* ----------------------------------------------------------------
293 * transaction state accessors
294 * ----------------------------------------------------------------
300 * This returns true if we are inside a valid transaction; that is,
301 * it is safe to initiate database access, take heavyweight locks, etc.
304 IsTransactionState(void)
306 TransactionState s = CurrentTransactionState;
309 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
310 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
311 * TRANS_PREPARE since it might be too soon or too late within those
312 * transition states to do anything interesting. Hence, the only "valid"
313 * state is TRANS_INPROGRESS.
315 return (s->state == TRANS_INPROGRESS);
319 * IsAbortedTransactionBlockState
321 * This returns true if we are within an aborted transaction block.
324 IsAbortedTransactionBlockState(void)
326 TransactionState s = CurrentTransactionState;
328 if (s->blockState == TBLOCK_ABORT ||
329 s->blockState == TBLOCK_SUBABORT)
337 * GetTopTransactionId
339 * This will return the XID of the main transaction, assigning one if
340 * it's not yet set. Be careful to call this only inside a valid xact.
343 GetTopTransactionId(void)
345 if (!TransactionIdIsValid(TopTransactionStateData.transactionId))
346 AssignTransactionId(&TopTransactionStateData);
347 return TopTransactionStateData.transactionId;
351 * GetTopTransactionIdIfAny
353 * This will return the XID of the main transaction, if one is assigned.
354 * It will return InvalidTransactionId if we are not currently inside a
355 * transaction, or inside a transaction that hasn't yet been assigned an XID.
358 GetTopTransactionIdIfAny(void)
360 return TopTransactionStateData.transactionId;
364 * GetCurrentTransactionId
366 * This will return the XID of the current transaction (main or sub
367 * transaction), assigning one if it's not yet set. Be careful to call this
368 * only inside a valid xact.
371 GetCurrentTransactionId(void)
373 TransactionState s = CurrentTransactionState;
375 if (!TransactionIdIsValid(s->transactionId))
376 AssignTransactionId(s);
377 return s->transactionId;
381 * GetCurrentTransactionIdIfAny
383 * This will return the XID of the current sub xact, if one is assigned.
384 * It will return InvalidTransactionId if we are not currently inside a
385 * transaction, or inside a transaction that hasn't been assigned an XID yet.
388 GetCurrentTransactionIdIfAny(void)
390 return CurrentTransactionState->transactionId;
395 * GetStableLatestTransactionIdIfAny
397 * Get the latest XID once and then return same value for rest of transaction.
398 * Acts as a useful reference point for maintenance tasks.
401 GetStableLatestTransactionId(void)
403 static LocalTransactionId lxid = InvalidLocalTransactionId;
404 static TransactionId stablexid = InvalidTransactionId;
406 if (lxid != MyProc->lxid ||
407 !TransactionIdIsValid(stablexid))
410 stablexid = ReadNewTransactionId();
417 * AssignTransactionId
419 * Assigns a new permanent XID to the given TransactionState.
420 * We do not assign XIDs to transactions until/unless this is called.
421 * Also, any parent TransactionStates that don't yet have XIDs are assigned
422 * one; this maintains the invariant that a child transaction has an XID
423 * following its parent's.
426 AssignTransactionId(TransactionState s)
428 bool isSubXact = (s->parent != NULL);
429 ResourceOwner currentOwner;
431 /* Assert that caller didn't screw up */
432 Assert(!TransactionIdIsValid(s->transactionId));
433 Assert(s->state == TRANS_INPROGRESS);
436 * Ensure parent(s) have XIDs, so that a child always has an XID later
437 * than its parent. Musn't recurse here, or we might get a stack overflow
438 * if we're at the bottom of a huge stack of subtransactions none of which
441 if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
443 TransactionState p = s->parent;
444 TransactionState *parents;
445 size_t parentOffset = 0;
447 parents = palloc(sizeof(TransactionState) * s->nestingLevel);
448 while (p != NULL && !TransactionIdIsValid(p->transactionId))
450 parents[parentOffset++] = p;
455 * This is technically a recursive call, but the recursion will never
456 * be more than one layer deep.
458 while (parentOffset != 0)
459 AssignTransactionId(parents[--parentOffset]);
465 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
467 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
468 * shared storage other than PG_PROC; because if there's no room for it in
469 * PG_PROC, the subtrans entry is needed to ensure that other backends see
470 * the Xid as "running". See GetNewTransactionId.
472 s->transactionId = GetNewTransactionId(isSubXact);
475 SubTransSetParent(s->transactionId, s->parent->transactionId, false);
478 * If it's a top-level transaction, the predicate locking system needs to
479 * be told about it too.
482 RegisterPredicateLockingXid(s->transactionId);
485 * Acquire lock on the transaction XID. (We assume this cannot block.) We
486 * have to ensure that the lock is assigned to the transaction's own
489 currentOwner = CurrentResourceOwner;
492 CurrentResourceOwner = s->curTransactionOwner;
493 XactLockTableInsert(s->transactionId);
497 /* Ensure CurrentResourceOwner is restored on error */
498 CurrentResourceOwner = currentOwner;
502 CurrentResourceOwner = currentOwner;
505 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
506 * top-level transaction we issue a WAL record for the assignment. We
507 * include the top-level xid and all the subxids that have not yet been
508 * reported using XLOG_XACT_ASSIGNMENT records.
510 * This is required to limit the amount of shared memory required in a hot
511 * standby server to keep track of in-progress XIDs. See notes for
512 * RecordKnownAssignedTransactionIds().
514 * We don't keep track of the immediate parent of each subxid, only the
515 * top-level transaction that each subxact belongs to. This is correct in
516 * recovery only because aborted subtransactions are separately WAL
519 if (isSubXact && XLogStandbyInfoActive())
521 unreportedXids[nUnreportedXids] = s->transactionId;
525 * ensure this test matches similar one in
526 * RecoverPreparedTransactions()
528 if (nUnreportedXids >= PGPROC_MAX_CACHED_SUBXIDS)
530 XLogRecData rdata[2];
531 xl_xact_assignment xlrec;
534 * xtop is always set by now because we recurse up transaction
535 * stack to the highest unassigned xid and then come back down
537 xlrec.xtop = GetTopTransactionId();
538 Assert(TransactionIdIsValid(xlrec.xtop));
539 xlrec.nsubxacts = nUnreportedXids;
541 rdata[0].data = (char *) &xlrec;
542 rdata[0].len = MinSizeOfXactAssignment;
543 rdata[0].buffer = InvalidBuffer;
544 rdata[0].next = &rdata[1];
546 rdata[1].data = (char *) unreportedXids;
547 rdata[1].len = PGPROC_MAX_CACHED_SUBXIDS * sizeof(TransactionId);
548 rdata[1].buffer = InvalidBuffer;
549 rdata[1].next = NULL;
551 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT, rdata);
559 * GetCurrentSubTransactionId
562 GetCurrentSubTransactionId(void)
564 TransactionState s = CurrentTransactionState;
566 return s->subTransactionId;
571 * GetCurrentCommandId
573 * "used" must be TRUE if the caller intends to use the command ID to mark
574 * inserted/updated/deleted tuples. FALSE means the ID is being fetched
575 * for read-only purposes (ie, as a snapshot validity cutoff). See
576 * CommandCounterIncrement() for discussion.
579 GetCurrentCommandId(bool used)
581 /* this is global to a transaction, not subtransaction-local */
583 currentCommandIdUsed = true;
584 return currentCommandId;
588 * GetCurrentTransactionStartTimestamp
591 GetCurrentTransactionStartTimestamp(void)
593 return xactStartTimestamp;
597 * GetCurrentStatementStartTimestamp
600 GetCurrentStatementStartTimestamp(void)
602 return stmtStartTimestamp;
606 * GetCurrentTransactionStopTimestamp
608 * We return current time if the transaction stop time hasn't been set
609 * (which can happen if we decide we don't need to log an XLOG record).
612 GetCurrentTransactionStopTimestamp(void)
614 if (xactStopTimestamp != 0)
615 return xactStopTimestamp;
616 return GetCurrentTimestamp();
620 * SetCurrentStatementStartTimestamp
623 SetCurrentStatementStartTimestamp(void)
625 stmtStartTimestamp = GetCurrentTimestamp();
629 * SetCurrentTransactionStopTimestamp
632 SetCurrentTransactionStopTimestamp(void)
634 xactStopTimestamp = GetCurrentTimestamp();
638 * GetCurrentTransactionNestLevel
640 * Note: this will return zero when not inside any transaction, one when
641 * inside a top-level transaction, etc.
644 GetCurrentTransactionNestLevel(void)
646 TransactionState s = CurrentTransactionState;
648 return s->nestingLevel;
653 * TransactionIdIsCurrentTransactionId
656 TransactionIdIsCurrentTransactionId(TransactionId xid)
661 * We always say that BootstrapTransactionId is "not my transaction ID"
662 * even when it is (ie, during bootstrap). Along with the fact that
663 * transam.c always treats BootstrapTransactionId as already committed,
664 * this causes the tqual.c routines to see all tuples as committed, which
665 * is what we need during bootstrap. (Bootstrap mode only inserts tuples,
666 * it never updates or deletes them, so all tuples can be presumed good
669 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
670 * not my transaction ID, so we can just return "false" immediately for
671 * any non-normal XID.
673 if (!TransactionIdIsNormal(xid))
677 * We will return true for the Xid of the current subtransaction, any of
678 * its subcommitted children, any of its parents, or any of their
679 * previously subcommitted children. However, a transaction being aborted
680 * is no longer "current", even though it may still have an entry on the
683 for (s = CurrentTransactionState; s != NULL; s = s->parent)
688 if (s->state == TRANS_ABORT)
690 if (!TransactionIdIsValid(s->transactionId))
691 continue; /* it can't have any child XIDs either */
692 if (TransactionIdEquals(xid, s->transactionId))
694 /* As the childXids array is ordered, we can use binary search */
696 high = s->nChildXids - 1;
702 middle = low + (high - low) / 2;
703 probe = s->childXids[middle];
704 if (TransactionIdEquals(probe, xid))
706 else if (TransactionIdPrecedes(probe, xid))
717 * TransactionStartedDuringRecovery
719 * Returns true if the current transaction started while recovery was still
720 * in progress. Recovery might have ended since so RecoveryInProgress() might
721 * return false already.
724 TransactionStartedDuringRecovery(void)
726 return CurrentTransactionState->startedInRecovery;
730 * CommandCounterIncrement
733 CommandCounterIncrement(void)
736 * If the current value of the command counter hasn't been "used" to mark
737 * tuples, we need not increment it, since there's no need to distinguish
738 * a read-only command from others. This helps postpone command counter
739 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
741 if (currentCommandIdUsed)
743 currentCommandId += 1;
744 if (currentCommandId == FirstCommandId) /* check for overflow */
746 currentCommandId -= 1;
748 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
749 errmsg("cannot have more than 2^32-1 commands in a transaction")));
751 currentCommandIdUsed = false;
753 /* Propagate new command ID into static snapshots */
754 SnapshotSetCommandId(currentCommandId);
757 * Make any catalog changes done by the just-completed command visible
758 * in the local syscache. We obviously don't need to do this after a
759 * read-only command. (But see hacks in inval.c to make real sure we
760 * don't think a command that queued inval messages was read-only.)
769 * Interface routine to allow commands to force a synchronous commit of the
770 * current top-level transaction
773 ForceSyncCommit(void)
775 forceSyncCommit = true;
779 /* ----------------------------------------------------------------
780 * StartTransaction stuff
781 * ----------------------------------------------------------------
790 AcceptInvalidationMessages();
799 TransactionState s = CurrentTransactionState;
802 * If this is the first time through, create a private context for
803 * AbortTransaction to work in. By reserving some space now, we can
804 * insulate AbortTransaction from out-of-memory scenarios. Like
805 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
806 * size, so that space will be reserved immediately.
808 if (TransactionAbortContext == NULL)
809 TransactionAbortContext =
810 AllocSetContextCreate(TopMemoryContext,
811 "TransactionAbortContext",
817 * We shouldn't have a transaction context already.
819 Assert(TopTransactionContext == NULL);
822 * Create a toplevel context for the transaction.
824 TopTransactionContext =
825 AllocSetContextCreate(TopMemoryContext,
826 "TopTransactionContext",
827 ALLOCSET_DEFAULT_MINSIZE,
828 ALLOCSET_DEFAULT_INITSIZE,
829 ALLOCSET_DEFAULT_MAXSIZE);
832 * In a top-level transaction, CurTransactionContext is the same as
833 * TopTransactionContext.
835 CurTransactionContext = TopTransactionContext;
836 s->curTransactionContext = CurTransactionContext;
838 /* Make the CurTransactionContext active. */
839 MemoryContextSwitchTo(CurTransactionContext);
843 * AtStart_ResourceOwner
846 AtStart_ResourceOwner(void)
848 TransactionState s = CurrentTransactionState;
851 * We shouldn't have a transaction resource owner already.
853 Assert(TopTransactionResourceOwner == NULL);
856 * Create a toplevel resource owner for the transaction.
858 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
860 TopTransactionResourceOwner = s->curTransactionOwner;
861 CurTransactionResourceOwner = s->curTransactionOwner;
862 CurrentResourceOwner = s->curTransactionOwner;
865 /* ----------------------------------------------------------------
866 * StartSubTransaction stuff
867 * ----------------------------------------------------------------
874 AtSubStart_Memory(void)
876 TransactionState s = CurrentTransactionState;
878 Assert(CurTransactionContext != NULL);
881 * Create a CurTransactionContext, which will be used to hold data that
882 * survives subtransaction commit but disappears on subtransaction abort.
883 * We make it a child of the immediate parent's CurTransactionContext.
885 CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
886 "CurTransactionContext",
887 ALLOCSET_DEFAULT_MINSIZE,
888 ALLOCSET_DEFAULT_INITSIZE,
889 ALLOCSET_DEFAULT_MAXSIZE);
890 s->curTransactionContext = CurTransactionContext;
892 /* Make the CurTransactionContext active. */
893 MemoryContextSwitchTo(CurTransactionContext);
897 * AtSubStart_ResourceOwner
900 AtSubStart_ResourceOwner(void)
902 TransactionState s = CurrentTransactionState;
904 Assert(s->parent != NULL);
907 * Create a resource owner for the subtransaction. We make it a child of
908 * the immediate parent's resource owner.
910 s->curTransactionOwner =
911 ResourceOwnerCreate(s->parent->curTransactionOwner,
914 CurTransactionResourceOwner = s->curTransactionOwner;
915 CurrentResourceOwner = s->curTransactionOwner;
918 /* ----------------------------------------------------------------
919 * CommitTransaction stuff
920 * ----------------------------------------------------------------
924 * RecordTransactionCommit
926 * Returns latest XID among xact and its children, or InvalidTransactionId
927 * if the xact has no XID. (We compute that here just because it's easier.)
930 RecordTransactionCommit(void)
932 TransactionId xid = GetTopTransactionIdIfAny();
933 bool markXidCommitted = TransactionIdIsValid(xid);
934 TransactionId latestXid = InvalidTransactionId;
938 TransactionId *children;
940 SharedInvalidationMessage *invalMessages = NULL;
941 bool RelcacheInitFileInval = false;
944 /* Get data needed for commit record */
945 nrels = smgrGetPendingDeletes(true, &rels);
946 nchildren = xactGetCommittedChildren(&children);
947 if (XLogStandbyInfoActive())
948 nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
949 &RelcacheInitFileInval);
950 wrote_xlog = (XactLastRecEnd.xrecoff != 0);
953 * If we haven't been assigned an XID yet, we neither can, nor do we want
954 * to write a COMMIT record.
956 if (!markXidCommitted)
959 * We expect that every smgrscheduleunlink is followed by a catalog
960 * update, and hence XID assignment, so we shouldn't get here with any
961 * pending deletes. Use a real test not just an Assert to check this,
962 * since it's a bit fragile.
965 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
967 /* Can't have child XIDs either; AssignTransactionId enforces this */
968 Assert(nchildren == 0);
971 * If we didn't create XLOG entries, we're done here; otherwise we
972 * should flush those entries the same as a commit record. (An
973 * example of a possible record that wouldn't cause an XID to be
974 * assigned is a sequence advance record due to nextval() --- we want
975 * to flush that to disk before reporting commit.)
983 * Begin commit critical section and insert the commit XLOG record.
985 /* Tell bufmgr and smgr to prepare for commit */
989 * Mark ourselves as within our "commit critical section". This
990 * forces any concurrent checkpoint to wait until we've updated
991 * pg_clog. Without this, it is possible for the checkpoint to set
992 * REDO after the XLOG record but fail to flush the pg_clog update to
993 * disk, leading to loss of the transaction commit if the system
994 * crashes a little later.
996 * Note: we could, but don't bother to, set this flag in
997 * RecordTransactionAbort. That's because loss of a transaction abort
998 * is noncritical; the presumption would be that it aborted, anyway.
1000 * It's safe to change the inCommit flag of our own backend without
1001 * holding the ProcArrayLock, since we're the only one modifying it.
1002 * This makes checkpoint's determination of which xacts are inCommit a
1003 * bit fuzzy, but it doesn't matter.
1005 START_CRIT_SECTION();
1006 MyPgXact->inCommit = true;
1008 SetCurrentTransactionStopTimestamp();
1011 * Do we need the long commit record? If not, use the compact format.
1013 if (nrels > 0 || nmsgs > 0 || RelcacheInitFileInval || forceSyncCommit)
1015 XLogRecData rdata[4];
1017 xl_xact_commit xlrec;
1019 * Set flags required for recovery processing of commits.
1022 if (RelcacheInitFileInval)
1023 xlrec.xinfo |= XACT_COMPLETION_UPDATE_RELCACHE_FILE;
1024 if (forceSyncCommit)
1025 xlrec.xinfo |= XACT_COMPLETION_FORCE_SYNC_COMMIT;
1027 xlrec.dbId = MyDatabaseId;
1028 xlrec.tsId = MyDatabaseTableSpace;
1030 xlrec.xact_time = xactStopTimestamp;
1031 xlrec.nrels = nrels;
1032 xlrec.nsubxacts = nchildren;
1033 xlrec.nmsgs = nmsgs;
1034 rdata[0].data = (char *) (&xlrec);
1035 rdata[0].len = MinSizeOfXactCommit;
1036 rdata[0].buffer = InvalidBuffer;
1037 /* dump rels to delete */
1040 rdata[0].next = &(rdata[1]);
1041 rdata[1].data = (char *) rels;
1042 rdata[1].len = nrels * sizeof(RelFileNode);
1043 rdata[1].buffer = InvalidBuffer;
1046 /* dump committed child Xids */
1049 rdata[lastrdata].next = &(rdata[2]);
1050 rdata[2].data = (char *) children;
1051 rdata[2].len = nchildren * sizeof(TransactionId);
1052 rdata[2].buffer = InvalidBuffer;
1055 /* dump shared cache invalidation messages */
1058 rdata[lastrdata].next = &(rdata[3]);
1059 rdata[3].data = (char *) invalMessages;
1060 rdata[3].len = nmsgs * sizeof(SharedInvalidationMessage);
1061 rdata[3].buffer = InvalidBuffer;
1064 rdata[lastrdata].next = NULL;
1066 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
1070 XLogRecData rdata[2];
1072 xl_xact_commit_compact xlrec;
1073 xlrec.xact_time = xactStopTimestamp;
1074 xlrec.nsubxacts = nchildren;
1075 rdata[0].data = (char *) (&xlrec);
1076 rdata[0].len = MinSizeOfXactCommitCompact;
1077 rdata[0].buffer = InvalidBuffer;
1078 /* dump committed child Xids */
1081 rdata[0].next = &(rdata[1]);
1082 rdata[1].data = (char *) children;
1083 rdata[1].len = nchildren * sizeof(TransactionId);
1084 rdata[1].buffer = InvalidBuffer;
1087 rdata[lastrdata].next = NULL;
1089 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT_COMPACT, rdata);
1094 * Check if we want to commit asynchronously. We can allow the XLOG flush
1095 * to happen asynchronously if synchronous_commit=off, or if the current
1096 * transaction has not performed any WAL-logged operation. The latter
1097 * case can arise if the current transaction wrote only to temporary
1098 * and/or unlogged tables. In case of a crash, the loss of such a
1099 * transaction will be irrelevant since temp tables will be lost anyway,
1100 * and unlogged tables will be truncated. (Given the foregoing, you might
1101 * think that it would be unnecessary to emit the XLOG record at all in
1102 * this case, but we don't currently try to do that. It would certainly
1103 * cause problems at least in Hot Standby mode, where the
1104 * KnownAssignedXids machinery requires tracking every XID assignment. It
1105 * might be OK to skip it only when wal_level < hot_standby, but for now
1108 * However, if we're doing cleanup of any non-temp rels or committing any
1109 * command that wanted to force sync commit, then we must flush XLOG
1110 * immediately. (We must not allow asynchronous commit if there are any
1111 * non-temp tables to be deleted, because we might delete the files before
1112 * the COMMIT record is flushed to disk. We do allow asynchronous commit
1113 * if all to-be-deleted tables are temporary though, since they are lost
1114 * anyway if we crash.)
1116 if ((wrote_xlog && synchronous_commit > SYNCHRONOUS_COMMIT_OFF) ||
1117 forceSyncCommit || nrels > 0)
1120 * Synchronous commit case:
1122 * Sleep before flush! So we can flush more than one commit records
1123 * per single fsync. (The idea is some other backend may do the
1124 * XLogFlush while we're sleeping. This needs work still, because on
1125 * most Unixen, the minimum select() delay is 10msec or more, which is
1128 * We do not sleep if enableFsync is not turned on, nor if there are
1129 * fewer than CommitSiblings other backends with active transactions.
1131 if (CommitDelay > 0 && enableFsync &&
1132 MinimumActiveBackends(CommitSiblings))
1133 pg_usleep(CommitDelay);
1135 XLogFlush(XactLastRecEnd);
1138 * Wake up all walsenders to send WAL up to the COMMIT record
1139 * immediately if replication is enabled
1141 if (max_wal_senders > 0)
1145 * Now we may update the CLOG, if we wrote a COMMIT record above
1147 if (markXidCommitted)
1148 TransactionIdCommitTree(xid, nchildren, children);
1153 * Asynchronous commit case:
1155 * This enables possible committed transaction loss in the case of a
1156 * postmaster crash because WAL buffers are left unwritten. Ideally we
1157 * could issue the WAL write without the fsync, but some
1158 * wal_sync_methods do not allow separate write/fsync.
1160 * Report the latest async commit LSN, so that the WAL writer knows to
1161 * flush this commit.
1163 XLogSetAsyncXactLSN(XactLastRecEnd);
1166 * We must not immediately update the CLOG, since we didn't flush the
1167 * XLOG. Instead, we store the LSN up to which the XLOG must be
1168 * flushed before the CLOG may be updated.
1170 if (markXidCommitted)
1171 TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1175 * If we entered a commit critical section, leave it now, and let
1176 * checkpoints proceed.
1178 if (markXidCommitted)
1180 MyPgXact->inCommit = false;
1184 /* Compute latestXid while we have the child XIDs handy */
1185 latestXid = TransactionIdLatest(xid, nchildren, children);
1188 * Wait for synchronous replication, if required.
1190 * Note that at this stage we have marked clog, but still show as running
1191 * in the procarray and continue to hold locks.
1194 SyncRepWaitForLSN(XactLastRecEnd);
1196 /* Reset XactLastRecEnd until the next transaction writes something */
1197 XactLastRecEnd.xrecoff = 0;
1200 /* Clean up local data */
1212 AtCCI_LocalCache(void)
1215 * Make any pending relation map changes visible. We must do this before
1216 * processing local sinval messages, so that the map changes will get
1217 * reflected into the relcache when relcache invals are processed.
1219 AtCCI_RelationMap();
1222 * Make catalog changes visible to me for the next command.
1224 CommandEndInvalidationMessages();
1231 AtCommit_Memory(void)
1234 * Now that we're "out" of a transaction, have the system allocate things
1235 * in the top memory context instead of per-transaction contexts.
1237 MemoryContextSwitchTo(TopMemoryContext);
1240 * Release all transaction-local memory.
1242 Assert(TopTransactionContext != NULL);
1243 MemoryContextDelete(TopTransactionContext);
1244 TopTransactionContext = NULL;
1245 CurTransactionContext = NULL;
1246 CurrentTransactionState->curTransactionContext = NULL;
1249 /* ----------------------------------------------------------------
1250 * CommitSubTransaction stuff
1251 * ----------------------------------------------------------------
1255 * AtSubCommit_Memory
1258 AtSubCommit_Memory(void)
1260 TransactionState s = CurrentTransactionState;
1262 Assert(s->parent != NULL);
1264 /* Return to parent transaction level's memory context. */
1265 CurTransactionContext = s->parent->curTransactionContext;
1266 MemoryContextSwitchTo(CurTransactionContext);
1269 * Ordinarily we cannot throw away the child's CurTransactionContext,
1270 * since the data it contains will be needed at upper commit. However, if
1271 * there isn't actually anything in it, we can throw it away. This avoids
1272 * a small memory leak in the common case of "trivial" subxacts.
1274 if (MemoryContextIsEmpty(s->curTransactionContext))
1276 MemoryContextDelete(s->curTransactionContext);
1277 s->curTransactionContext = NULL;
1282 * AtSubCommit_childXids
1284 * Pass my own XID and my child XIDs up to my parent as committed children.
1287 AtSubCommit_childXids(void)
1289 TransactionState s = CurrentTransactionState;
1292 Assert(s->parent != NULL);
1295 * The parent childXids array will need to hold my XID and all my
1296 * childXids, in addition to the XIDs already there.
1298 new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1300 /* Allocate or enlarge the parent array if necessary */
1301 if (s->parent->maxChildXids < new_nChildXids)
1303 int new_maxChildXids;
1304 TransactionId *new_childXids;
1307 * Make it 2x what's needed right now, to avoid having to enlarge it
1308 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1309 * is what ensures that we don't need to worry about integer overflow
1310 * here or in the calculation of new_nChildXids.)
1312 new_maxChildXids = Min(new_nChildXids * 2,
1313 (int) (MaxAllocSize / sizeof(TransactionId)));
1315 if (new_maxChildXids < new_nChildXids)
1317 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1318 errmsg("maximum number of committed subtransactions (%d) exceeded",
1319 (int) (MaxAllocSize / sizeof(TransactionId)))));
1322 * We keep the child-XID arrays in TopTransactionContext; this avoids
1323 * setting up child-transaction contexts for what might be just a few
1324 * bytes of grandchild XIDs.
1326 if (s->parent->childXids == NULL)
1328 MemoryContextAlloc(TopTransactionContext,
1329 new_maxChildXids * sizeof(TransactionId));
1331 new_childXids = repalloc(s->parent->childXids,
1332 new_maxChildXids * sizeof(TransactionId));
1334 s->parent->childXids = new_childXids;
1335 s->parent->maxChildXids = new_maxChildXids;
1339 * Copy all my XIDs to parent's array.
1341 * Note: We rely on the fact that the XID of a child always follows that
1342 * of its parent. By copying the XID of this subtransaction before the
1343 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1344 * all XIDs already in the array belong to subtransactions started and
1345 * subcommitted before us, so their XIDs must precede ours.
1347 s->parent->childXids[s->parent->nChildXids] = s->transactionId;
1349 if (s->nChildXids > 0)
1350 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1352 s->nChildXids * sizeof(TransactionId));
1354 s->parent->nChildXids = new_nChildXids;
1356 /* Release child's array to avoid leakage */
1357 if (s->childXids != NULL)
1358 pfree(s->childXids);
1359 /* We must reset these to avoid double-free if fail later in commit */
1360 s->childXids = NULL;
1362 s->maxChildXids = 0;
1365 /* ----------------------------------------------------------------
1366 * AbortTransaction stuff
1367 * ----------------------------------------------------------------
1371 * RecordTransactionAbort
1373 * Returns latest XID among xact and its children, or InvalidTransactionId
1374 * if the xact has no XID. (We compute that here just because it's easier.)
1376 static TransactionId
1377 RecordTransactionAbort(bool isSubXact)
1379 TransactionId xid = GetCurrentTransactionIdIfAny();
1380 TransactionId latestXid;
1384 TransactionId *children;
1385 XLogRecData rdata[3];
1387 xl_xact_abort xlrec;
1390 * If we haven't been assigned an XID, nobody will care whether we aborted
1391 * or not. Hence, we're done in that case. It does not matter if we have
1392 * rels to delete (note that this routine is not responsible for actually
1393 * deleting 'em). We cannot have any child XIDs, either.
1395 if (!TransactionIdIsValid(xid))
1397 /* Reset XactLastRecEnd until the next transaction writes something */
1399 XactLastRecEnd.xrecoff = 0;
1400 return InvalidTransactionId;
1404 * We have a valid XID, so we should write an ABORT record for it.
1406 * We do not flush XLOG to disk here, since the default assumption after a
1407 * crash would be that we aborted, anyway. For the same reason, we don't
1408 * need to worry about interlocking against checkpoint start.
1412 * Check that we haven't aborted halfway through RecordTransactionCommit.
1414 if (TransactionIdDidCommit(xid))
1415 elog(PANIC, "cannot abort transaction %u, it was already committed",
1418 /* Fetch the data we need for the abort record */
1419 nrels = smgrGetPendingDeletes(false, &rels);
1420 nchildren = xactGetCommittedChildren(&children);
1422 /* XXX do we really need a critical section here? */
1423 START_CRIT_SECTION();
1425 /* Write the ABORT record */
1427 xlrec.xact_time = GetCurrentTimestamp();
1430 SetCurrentTransactionStopTimestamp();
1431 xlrec.xact_time = xactStopTimestamp;
1433 xlrec.nrels = nrels;
1434 xlrec.nsubxacts = nchildren;
1435 rdata[0].data = (char *) (&xlrec);
1436 rdata[0].len = MinSizeOfXactAbort;
1437 rdata[0].buffer = InvalidBuffer;
1438 /* dump rels to delete */
1441 rdata[0].next = &(rdata[1]);
1442 rdata[1].data = (char *) rels;
1443 rdata[1].len = nrels * sizeof(RelFileNode);
1444 rdata[1].buffer = InvalidBuffer;
1447 /* dump committed child Xids */
1450 rdata[lastrdata].next = &(rdata[2]);
1451 rdata[2].data = (char *) children;
1452 rdata[2].len = nchildren * sizeof(TransactionId);
1453 rdata[2].buffer = InvalidBuffer;
1456 rdata[lastrdata].next = NULL;
1458 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
1461 * Report the latest async abort LSN, so that the WAL writer knows to
1462 * flush this abort. There's nothing to be gained by delaying this, since
1463 * WALWriter may as well do this when it can. This is important with
1464 * streaming replication because if we don't flush WAL regularly we will
1465 * find that large aborts leave us with a long backlog for when commits
1466 * occur after the abort, increasing our window of data loss should
1467 * problems occur at that point.
1470 XLogSetAsyncXactLSN(XactLastRecEnd);
1473 * Mark the transaction aborted in clog. This is not absolutely necessary
1474 * but we may as well do it while we are here; also, in the subxact case
1475 * it is helpful because XactLockTableWait makes use of it to avoid
1476 * waiting for already-aborted subtransactions. It is OK to do it without
1477 * having flushed the ABORT record to disk, because in event of a crash
1478 * we'd be assumed to have aborted anyway.
1480 TransactionIdAbortTree(xid, nchildren, children);
1484 /* Compute latestXid while we have the child XIDs handy */
1485 latestXid = TransactionIdLatest(xid, nchildren, children);
1488 * If we're aborting a subtransaction, we can immediately remove failed
1489 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1490 * subxacts, because we already have the child XID array at hand. For
1491 * main xacts, the equivalent happens just after this function returns.
1494 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1496 /* Reset XactLastRecEnd until the next transaction writes something */
1498 XactLastRecEnd.xrecoff = 0;
1500 /* And clean up local data */
1511 AtAbort_Memory(void)
1514 * Switch into TransactionAbortContext, which should have some free space
1515 * even if nothing else does. We'll work in this context until we've
1516 * finished cleaning up.
1518 * It is barely possible to get here when we've not been able to create
1519 * TransactionAbortContext yet; if so use TopMemoryContext.
1521 if (TransactionAbortContext != NULL)
1522 MemoryContextSwitchTo(TransactionAbortContext);
1524 MemoryContextSwitchTo(TopMemoryContext);
1531 AtSubAbort_Memory(void)
1533 Assert(TransactionAbortContext != NULL);
1535 MemoryContextSwitchTo(TransactionAbortContext);
1540 * AtAbort_ResourceOwner
1543 AtAbort_ResourceOwner(void)
1546 * Make sure we have a valid ResourceOwner, if possible (else it will be
1547 * NULL, which is OK)
1549 CurrentResourceOwner = TopTransactionResourceOwner;
1553 * AtSubAbort_ResourceOwner
1556 AtSubAbort_ResourceOwner(void)
1558 TransactionState s = CurrentTransactionState;
1560 /* Make sure we have a valid ResourceOwner */
1561 CurrentResourceOwner = s->curTransactionOwner;
1566 * AtSubAbort_childXids
1569 AtSubAbort_childXids(void)
1571 TransactionState s = CurrentTransactionState;
1574 * We keep the child-XID arrays in TopTransactionContext (see
1575 * AtSubCommit_childXids). This means we'd better free the array
1576 * explicitly at abort to avoid leakage.
1578 if (s->childXids != NULL)
1579 pfree(s->childXids);
1580 s->childXids = NULL;
1582 s->maxChildXids = 0;
1585 * We could prune the unreportedXids array here. But we don't bother. That
1586 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1587 * would likely introduce more CPU time into the more common paths, so we
1588 * choose not to do that.
1592 /* ----------------------------------------------------------------
1593 * CleanupTransaction stuff
1594 * ----------------------------------------------------------------
1601 AtCleanup_Memory(void)
1603 Assert(CurrentTransactionState->parent == NULL);
1606 * Now that we're "out" of a transaction, have the system allocate things
1607 * in the top memory context instead of per-transaction contexts.
1609 MemoryContextSwitchTo(TopMemoryContext);
1612 * Clear the special abort context for next time.
1614 if (TransactionAbortContext != NULL)
1615 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1618 * Release all transaction-local memory.
1620 if (TopTransactionContext != NULL)
1621 MemoryContextDelete(TopTransactionContext);
1622 TopTransactionContext = NULL;
1623 CurTransactionContext = NULL;
1624 CurrentTransactionState->curTransactionContext = NULL;
1628 /* ----------------------------------------------------------------
1629 * CleanupSubTransaction stuff
1630 * ----------------------------------------------------------------
1634 * AtSubCleanup_Memory
1637 AtSubCleanup_Memory(void)
1639 TransactionState s = CurrentTransactionState;
1641 Assert(s->parent != NULL);
1643 /* Make sure we're not in an about-to-be-deleted context */
1644 MemoryContextSwitchTo(s->parent->curTransactionContext);
1645 CurTransactionContext = s->parent->curTransactionContext;
1648 * Clear the special abort context for next time.
1650 if (TransactionAbortContext != NULL)
1651 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1654 * Delete the subxact local memory contexts. Its CurTransactionContext can
1655 * go too (note this also kills CurTransactionContexts from any children
1658 if (s->curTransactionContext)
1659 MemoryContextDelete(s->curTransactionContext);
1660 s->curTransactionContext = NULL;
1663 /* ----------------------------------------------------------------
1664 * interface routines
1665 * ----------------------------------------------------------------
1672 StartTransaction(void)
1675 VirtualTransactionId vxid;
1678 * Let's just make sure the state stack is empty
1680 s = &TopTransactionStateData;
1681 CurrentTransactionState = s;
1684 * check the current transaction state
1686 if (s->state != TRANS_DEFAULT)
1687 elog(WARNING, "StartTransaction while in %s state",
1688 TransStateAsString(s->state));
1691 * set the current transaction state information appropriately during
1694 s->state = TRANS_START;
1695 s->transactionId = InvalidTransactionId; /* until assigned */
1698 * Make sure we've reset xact state variables
1700 * If recovery is still in progress, mark this transaction as read-only.
1701 * We have lower level defences in XLogInsert and elsewhere to stop us
1702 * from modifying data during recovery, but this gives the normal
1703 * indication to the user that the transaction is read-only.
1705 if (RecoveryInProgress())
1707 s->startedInRecovery = true;
1708 XactReadOnly = true;
1712 s->startedInRecovery = false;
1713 XactReadOnly = DefaultXactReadOnly;
1715 XactDeferrable = DefaultXactDeferrable;
1716 XactIsoLevel = DefaultXactIsoLevel;
1717 forceSyncCommit = false;
1718 MyXactAccessedTempRel = false;
1721 * reinitialize within-transaction counters
1723 s->subTransactionId = TopSubTransactionId;
1724 currentSubTransactionId = TopSubTransactionId;
1725 currentCommandId = FirstCommandId;
1726 currentCommandIdUsed = false;
1729 * initialize reported xid accounting
1731 nUnreportedXids = 0;
1734 * must initialize resource-management stuff first
1737 AtStart_ResourceOwner();
1740 * Assign a new LocalTransactionId, and combine it with the backendId to
1741 * form a virtual transaction id.
1743 vxid.backendId = MyBackendId;
1744 vxid.localTransactionId = GetNextLocalTransactionId();
1747 * Lock the virtual transaction id before we announce it in the proc array
1749 VirtualXactLockTableInsert(vxid);
1752 * Advertise it in the proc array. We assume assignment of
1753 * LocalTransactionID is atomic, and the backendId should be set already.
1755 Assert(MyProc->backendId == vxid.backendId);
1756 MyProc->lxid = vxid.localTransactionId;
1758 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
1761 * set transaction_timestamp() (a/k/a now()). We want this to be the same
1762 * as the first command's statement_timestamp(), so don't do a fresh
1763 * GetCurrentTimestamp() call (which'd be expensive anyway). Also, mark
1764 * xactStopTimestamp as unset.
1766 xactStartTimestamp = stmtStartTimestamp;
1767 xactStopTimestamp = 0;
1768 pgstat_report_xact_timestamp(xactStartTimestamp);
1771 * initialize current transaction state fields
1773 * note: prevXactReadOnly is not used at the outermost level
1775 s->nestingLevel = 1;
1776 s->gucNestLevel = 1;
1777 s->childXids = NULL;
1779 s->maxChildXids = 0;
1780 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
1781 /* SecurityRestrictionContext should never be set outside a transaction */
1782 Assert(s->prevSecContext == 0);
1785 * initialize other subsystems for new transaction
1790 AfterTriggerBeginXact();
1793 * done with start processing, set current transaction state to "in
1796 s->state = TRANS_INPROGRESS;
1798 ShowTransactionState("StartTransaction");
1805 * NB: if you change this routine, better look at PrepareTransaction too!
1808 CommitTransaction(void)
1810 TransactionState s = CurrentTransactionState;
1811 TransactionId latestXid;
1813 ShowTransactionState("CommitTransaction");
1816 * check the current transaction state
1818 if (s->state != TRANS_INPROGRESS)
1819 elog(WARNING, "CommitTransaction while in %s state",
1820 TransStateAsString(s->state));
1821 Assert(s->parent == NULL);
1824 * Do pre-commit processing that involves calling user-defined code, such
1825 * as triggers. Since closing cursors could queue trigger actions,
1826 * triggers could open cursors, etc, we have to keep looping until there's
1827 * nothing left to do.
1832 * Fire all currently pending deferred triggers.
1834 AfterTriggerFireDeferred();
1837 * Close open portals (converting holdable ones into static portals).
1838 * If there weren't any, we are done ... otherwise loop back to check
1839 * if they queued deferred triggers. Lather, rinse, repeat.
1841 if (!PreCommit_Portals(false))
1846 * The remaining actions cannot call any user-defined code, so it's safe
1847 * to start shutting down within-transaction services. But note that most
1848 * of this stuff could still throw an error, which would switch us into
1849 * the transaction-abort path.
1852 /* Shut down the deferred-trigger manager */
1853 AfterTriggerEndXact(true);
1856 * Let ON COMMIT management do its thing (must happen after closing
1857 * cursors, to avoid dangling-reference problems)
1859 PreCommit_on_commit_actions();
1861 /* close large objects before lower-level cleanup */
1862 AtEOXact_LargeObject(true);
1865 * Mark serializable transaction as complete for predicate locking
1866 * purposes. This should be done as late as we can put it and still allow
1867 * errors to be raised for failure patterns found at commit.
1869 PreCommit_CheckForSerializationFailure();
1872 * Insert notifications sent by NOTIFY commands into the queue. This
1873 * should be late in the pre-commit sequence to minimize time spent
1874 * holding the notify-insertion lock.
1878 /* Prevent cancel/die interrupt while cleaning up */
1881 /* Commit updates to the relation map --- do this as late as possible */
1882 AtEOXact_RelationMap(true);
1885 * set the current transaction state information appropriately during
1888 s->state = TRANS_COMMIT;
1891 * Here is where we really truly commit.
1893 latestXid = RecordTransactionCommit();
1895 TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
1898 * Let others know about no transaction in progress by me. Note that this
1899 * must be done _before_ releasing locks we hold and _after_
1900 * RecordTransactionCommit.
1902 ProcArrayEndTransaction(MyProc, latestXid);
1905 * This is all post-commit cleanup. Note that if an error is raised here,
1906 * it's too late to abort the transaction. This should be just
1907 * noncritical resource releasing.
1909 * The ordering of operations is not entirely random. The idea is:
1910 * release resources visible to other backends (eg, files, buffer pins);
1911 * then release locks; then release backend-local resources. We want to
1912 * release locks at the point where any backend waiting for us will see
1913 * our transaction as being fully cleaned up.
1915 * Resources that can be associated with individual queries are handled by
1916 * the ResourceOwner mechanism. The other calls here are for backend-wide
1920 CallXactCallbacks(XACT_EVENT_COMMIT);
1922 ResourceOwnerRelease(TopTransactionResourceOwner,
1923 RESOURCE_RELEASE_BEFORE_LOCKS,
1926 /* Check we've released all buffer pins */
1927 AtEOXact_Buffers(true);
1929 /* Clean up the relation cache */
1930 AtEOXact_RelationCache(true);
1933 * Make catalog changes visible to all backends. This has to happen after
1934 * relcache references are dropped (see comments for
1935 * AtEOXact_RelationCache), but before locks are released (if anyone is
1936 * waiting for lock on a relation we've modified, we want them to know
1937 * about the catalog change before they start using the relation).
1939 AtEOXact_Inval(true);
1942 * Likewise, dropping of files deleted during the transaction is best done
1943 * after releasing relcache and buffer pins. (This is not strictly
1944 * necessary during commit, since such pins should have been released
1945 * already, but this ordering is definitely critical during abort.)
1947 smgrDoPendingDeletes(true);
1949 AtEOXact_MultiXact();
1951 ResourceOwnerRelease(TopTransactionResourceOwner,
1952 RESOURCE_RELEASE_LOCKS,
1954 ResourceOwnerRelease(TopTransactionResourceOwner,
1955 RESOURCE_RELEASE_AFTER_LOCKS,
1958 /* Check we've released all catcache entries */
1959 AtEOXact_CatCache(true);
1962 AtEOXact_GUC(true, 1);
1964 AtEOXact_on_commit_actions(true);
1965 AtEOXact_Namespace(true);
1966 /* smgrcommit already done */
1968 AtEOXact_ComboCid();
1969 AtEOXact_HashTables(true);
1970 AtEOXact_PgStat(true);
1971 AtEOXact_Snapshot(true);
1972 pgstat_report_xact_timestamp(0);
1974 CurrentResourceOwner = NULL;
1975 ResourceOwnerDelete(TopTransactionResourceOwner);
1976 s->curTransactionOwner = NULL;
1977 CurTransactionResourceOwner = NULL;
1978 TopTransactionResourceOwner = NULL;
1982 s->transactionId = InvalidTransactionId;
1983 s->subTransactionId = InvalidSubTransactionId;
1984 s->nestingLevel = 0;
1985 s->gucNestLevel = 0;
1986 s->childXids = NULL;
1988 s->maxChildXids = 0;
1991 * done with commit processing, set current transaction state back to
1994 s->state = TRANS_DEFAULT;
1996 RESUME_INTERRUPTS();
2001 * PrepareTransaction
2003 * NB: if you change this routine, better look at CommitTransaction too!
2006 PrepareTransaction(void)
2008 TransactionState s = CurrentTransactionState;
2009 TransactionId xid = GetCurrentTransactionId();
2010 GlobalTransaction gxact;
2011 TimestampTz prepared_at;
2013 ShowTransactionState("PrepareTransaction");
2016 * check the current transaction state
2018 if (s->state != TRANS_INPROGRESS)
2019 elog(WARNING, "PrepareTransaction while in %s state",
2020 TransStateAsString(s->state));
2021 Assert(s->parent == NULL);
2024 * Do pre-commit processing that involves calling user-defined code, such
2025 * as triggers. Since closing cursors could queue trigger actions,
2026 * triggers could open cursors, etc, we have to keep looping until there's
2027 * nothing left to do.
2032 * Fire all currently pending deferred triggers.
2034 AfterTriggerFireDeferred();
2037 * Close open portals (converting holdable ones into static portals).
2038 * If there weren't any, we are done ... otherwise loop back to check
2039 * if they queued deferred triggers. Lather, rinse, repeat.
2041 if (!PreCommit_Portals(true))
2046 * The remaining actions cannot call any user-defined code, so it's safe
2047 * to start shutting down within-transaction services. But note that most
2048 * of this stuff could still throw an error, which would switch us into
2049 * the transaction-abort path.
2052 /* Shut down the deferred-trigger manager */
2053 AfterTriggerEndXact(true);
2056 * Let ON COMMIT management do its thing (must happen after closing
2057 * cursors, to avoid dangling-reference problems)
2059 PreCommit_on_commit_actions();
2061 /* close large objects before lower-level cleanup */
2062 AtEOXact_LargeObject(true);
2065 * Mark serializable transaction as complete for predicate locking
2066 * purposes. This should be done as late as we can put it and still allow
2067 * errors to be raised for failure patterns found at commit.
2069 PreCommit_CheckForSerializationFailure();
2071 /* NOTIFY will be handled below */
2074 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2075 * this transaction. Having the prepared xact hold locks on another
2076 * backend's temp table seems a bad idea --- for instance it would prevent
2077 * the backend from exiting. There are other problems too, such as how to
2078 * clean up the source backend's local buffers and ON COMMIT state if the
2079 * prepared xact includes a DROP of a temp table.
2081 * We must check this after executing any ON COMMIT actions, because they
2082 * might still access a temp relation.
2084 * XXX In principle this could be relaxed to allow some useful special
2085 * cases, such as a temp table created and dropped all within the
2086 * transaction. That seems to require much more bookkeeping though.
2088 if (MyXactAccessedTempRel)
2090 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2091 errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
2094 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2095 * supported if we added cleanup logic to twophase.c, but for now it
2096 * doesn't seem worth the trouble.
2098 if (XactHasExportedSnapshots())
2100 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2101 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2103 /* Prevent cancel/die interrupt while cleaning up */
2107 * set the current transaction state information appropriately during
2108 * prepare processing
2110 s->state = TRANS_PREPARE;
2112 prepared_at = GetCurrentTimestamp();
2114 /* Tell bufmgr and smgr to prepare for commit */
2118 * Reserve the GID for this transaction. This could fail if the requested
2119 * GID is invalid or already in use.
2121 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
2122 GetUserId(), MyDatabaseId);
2126 * Collect data for the 2PC state file. Note that in general, no actual
2127 * state change should happen in the called modules during this step,
2128 * since it's still possible to fail before commit, and in that case we
2129 * want transaction abort to be able to clean up. (In particular, the
2130 * AtPrepare routines may error out if they find cases they cannot
2131 * handle.) State cleanup should happen in the PostPrepare routines
2132 * below. However, some modules can go ahead and clear state here because
2133 * they wouldn't do anything with it during abort anyway.
2135 * Note: because the 2PC state file records will be replayed in the same
2136 * order they are made, the order of these calls has to match the order in
2137 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2138 * PREPARED; in particular, pay attention to whether things should happen
2139 * before or after releasing the transaction's locks.
2141 StartPrepare(gxact);
2145 AtPrepare_PredicateLocks();
2147 AtPrepare_MultiXact();
2148 AtPrepare_RelationMap();
2151 * Here is where we really truly prepare.
2153 * We have to record transaction prepares even if we didn't make any
2154 * updates, because the transaction manager might get confused if we lose
2155 * a global transaction.
2160 * Now we clean up backend-internal state and release internal resources.
2163 /* Reset XactLastRecEnd until the next transaction writes something */
2164 XactLastRecEnd.xrecoff = 0;
2167 * Let others know about no transaction in progress by me. This has to be
2168 * done *after* the prepared transaction has been marked valid, else
2169 * someone may think it is unlocked and recyclable.
2171 ProcArrayClearTransaction(MyProc);
2174 * This is all post-transaction cleanup. Note that if an error is raised
2175 * here, it's too late to abort the transaction. This should be just
2176 * noncritical resource releasing. See notes in CommitTransaction.
2179 CallXactCallbacks(XACT_EVENT_PREPARE);
2181 ResourceOwnerRelease(TopTransactionResourceOwner,
2182 RESOURCE_RELEASE_BEFORE_LOCKS,
2185 /* Check we've released all buffer pins */
2186 AtEOXact_Buffers(true);
2188 /* Clean up the relation cache */
2189 AtEOXact_RelationCache(true);
2191 /* notify doesn't need a postprepare call */
2193 PostPrepare_PgStat();
2195 PostPrepare_Inval();
2199 PostPrepare_MultiXact(xid);
2201 PostPrepare_Locks(xid);
2202 PostPrepare_PredicateLocks(xid);
2204 ResourceOwnerRelease(TopTransactionResourceOwner,
2205 RESOURCE_RELEASE_LOCKS,
2207 ResourceOwnerRelease(TopTransactionResourceOwner,
2208 RESOURCE_RELEASE_AFTER_LOCKS,
2211 /* Check we've released all catcache entries */
2212 AtEOXact_CatCache(true);
2214 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2215 AtEOXact_GUC(true, 1);
2217 AtEOXact_on_commit_actions(true);
2218 AtEOXact_Namespace(true);
2219 /* smgrcommit already done */
2221 AtEOXact_ComboCid();
2222 AtEOXact_HashTables(true);
2223 /* don't call AtEOXact_PgStat here */
2224 AtEOXact_Snapshot(true);
2226 CurrentResourceOwner = NULL;
2227 ResourceOwnerDelete(TopTransactionResourceOwner);
2228 s->curTransactionOwner = NULL;
2229 CurTransactionResourceOwner = NULL;
2230 TopTransactionResourceOwner = NULL;
2234 s->transactionId = InvalidTransactionId;
2235 s->subTransactionId = InvalidSubTransactionId;
2236 s->nestingLevel = 0;
2237 s->gucNestLevel = 0;
2238 s->childXids = NULL;
2240 s->maxChildXids = 0;
2243 * done with 1st phase commit processing, set current transaction state
2246 s->state = TRANS_DEFAULT;
2248 RESUME_INTERRUPTS();
2256 AbortTransaction(void)
2258 TransactionState s = CurrentTransactionState;
2259 TransactionId latestXid;
2261 /* Prevent cancel/die interrupt while cleaning up */
2264 /* Make sure we have a valid memory context and resource owner */
2266 AtAbort_ResourceOwner();
2269 * Release any LW locks we might be holding as quickly as possible.
2270 * (Regular locks, however, must be held till we finish aborting.)
2271 * Releasing LW locks is critical since we might try to grab them again
2272 * while cleaning up!
2276 /* Clean up buffer I/O and buffer context locks, too */
2281 * Also clean up any open wait for lock, since the lock manager will choke
2282 * if we try to wait for another lock before doing this.
2287 * check the current transaction state
2289 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2290 elog(WARNING, "AbortTransaction while in %s state",
2291 TransStateAsString(s->state));
2292 Assert(s->parent == NULL);
2295 * set the current transaction state information appropriately during the
2298 s->state = TRANS_ABORT;
2301 * Reset user ID which might have been changed transiently. We need this
2302 * to clean up in case control escaped out of a SECURITY DEFINER function
2303 * or other local change of CurrentUserId; therefore, the prior value of
2304 * SecurityRestrictionContext also needs to be restored.
2306 * (Note: it is not necessary to restore session authorization or role
2307 * settings here because those can only be changed via GUC, and GUC will
2308 * take care of rolling them back if need be.)
2310 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
2313 * do abort processing
2315 AfterTriggerEndXact(false); /* 'false' means it's abort */
2317 AtEOXact_LargeObject(false);
2319 AtEOXact_RelationMap(false);
2322 * Advertise the fact that we aborted in pg_clog (assuming that we got as
2323 * far as assigning an XID to advertise).
2325 latestXid = RecordTransactionAbort(false);
2327 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
2330 * Let others know about no transaction in progress by me. Note that this
2331 * must be done _before_ releasing locks we hold and _after_
2332 * RecordTransactionAbort.
2334 ProcArrayEndTransaction(MyProc, latestXid);
2337 * Post-abort cleanup. See notes in CommitTransaction() concerning
2338 * ordering. We can skip all of it if the transaction failed before
2339 * creating a resource owner.
2341 if (TopTransactionResourceOwner != NULL)
2343 CallXactCallbacks(XACT_EVENT_ABORT);
2345 ResourceOwnerRelease(TopTransactionResourceOwner,
2346 RESOURCE_RELEASE_BEFORE_LOCKS,
2348 AtEOXact_Buffers(false);
2349 AtEOXact_RelationCache(false);
2350 AtEOXact_Inval(false);
2351 smgrDoPendingDeletes(false);
2352 AtEOXact_MultiXact();
2353 ResourceOwnerRelease(TopTransactionResourceOwner,
2354 RESOURCE_RELEASE_LOCKS,
2356 ResourceOwnerRelease(TopTransactionResourceOwner,
2357 RESOURCE_RELEASE_AFTER_LOCKS,
2359 AtEOXact_CatCache(false);
2361 AtEOXact_GUC(false, 1);
2362 AtEOXact_SPI(false);
2363 AtEOXact_on_commit_actions(false);
2364 AtEOXact_Namespace(false);
2366 AtEOXact_ComboCid();
2367 AtEOXact_HashTables(false);
2368 AtEOXact_PgStat(false);
2369 pgstat_report_xact_timestamp(0);
2373 * State remains TRANS_ABORT until CleanupTransaction().
2375 RESUME_INTERRUPTS();
2379 * CleanupTransaction
2382 CleanupTransaction(void)
2384 TransactionState s = CurrentTransactionState;
2387 * State should still be TRANS_ABORT from AbortTransaction().
2389 if (s->state != TRANS_ABORT)
2390 elog(FATAL, "CleanupTransaction: unexpected state %s",
2391 TransStateAsString(s->state));
2394 * do abort cleanup processing
2396 AtCleanup_Portals(); /* now safe to release portal memory */
2397 AtEOXact_Snapshot(false); /* and release the transaction's snapshots */
2399 CurrentResourceOwner = NULL; /* and resource owner */
2400 if (TopTransactionResourceOwner)
2401 ResourceOwnerDelete(TopTransactionResourceOwner);
2402 s->curTransactionOwner = NULL;
2403 CurTransactionResourceOwner = NULL;
2404 TopTransactionResourceOwner = NULL;
2406 AtCleanup_Memory(); /* and transaction memory */
2408 s->transactionId = InvalidTransactionId;
2409 s->subTransactionId = InvalidSubTransactionId;
2410 s->nestingLevel = 0;
2411 s->gucNestLevel = 0;
2412 s->childXids = NULL;
2414 s->maxChildXids = 0;
2417 * done with abort processing, set current transaction state back to
2420 s->state = TRANS_DEFAULT;
2424 * StartTransactionCommand
2427 StartTransactionCommand(void)
2429 TransactionState s = CurrentTransactionState;
2431 switch (s->blockState)
2434 * if we aren't in a transaction block, we just do our usual start
2437 case TBLOCK_DEFAULT:
2439 s->blockState = TBLOCK_STARTED;
2443 * We are somewhere in a transaction block or subtransaction and
2444 * about to start a new command. For now we do nothing, but
2445 * someday we may do command-local resource initialization. (Note
2446 * that any needed CommandCounterIncrement was done by the
2447 * previous CommitTransactionCommand.)
2449 case TBLOCK_INPROGRESS:
2450 case TBLOCK_SUBINPROGRESS:
2454 * Here we are in a failed transaction block (one of the commands
2455 * caused an abort) so we do nothing but remain in the abort
2456 * state. Eventually we will get a ROLLBACK command which will
2457 * get us out of this state. (It is up to other code to ensure
2458 * that no commands other than ROLLBACK will be processed in these
2462 case TBLOCK_SUBABORT:
2465 /* These cases are invalid. */
2466 case TBLOCK_STARTED:
2468 case TBLOCK_SUBBEGIN:
2470 case TBLOCK_SUBRELEASE:
2471 case TBLOCK_SUBCOMMIT:
2472 case TBLOCK_ABORT_END:
2473 case TBLOCK_SUBABORT_END:
2474 case TBLOCK_ABORT_PENDING:
2475 case TBLOCK_SUBABORT_PENDING:
2476 case TBLOCK_SUBRESTART:
2477 case TBLOCK_SUBABORT_RESTART:
2478 case TBLOCK_PREPARE:
2479 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2480 BlockStateAsString(s->blockState));
2485 * We must switch to CurTransactionContext before returning. This is
2486 * already done if we called StartTransaction, otherwise not.
2488 Assert(CurTransactionContext != NULL);
2489 MemoryContextSwitchTo(CurTransactionContext);
2493 * CommitTransactionCommand
2496 CommitTransactionCommand(void)
2498 TransactionState s = CurrentTransactionState;
2500 switch (s->blockState)
2503 * This shouldn't happen, because it means the previous
2504 * StartTransactionCommand didn't set the STARTED state
2507 case TBLOCK_DEFAULT:
2508 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2509 BlockStateAsString(s->blockState));
2513 * If we aren't in a transaction block, just do our usual
2514 * transaction commit, and return to the idle state.
2516 case TBLOCK_STARTED:
2517 CommitTransaction();
2518 s->blockState = TBLOCK_DEFAULT;
2522 * We are completing a "BEGIN TRANSACTION" command, so we change
2523 * to the "transaction block in progress" state and return. (We
2524 * assume the BEGIN did nothing to the database, so we need no
2525 * CommandCounterIncrement.)
2528 s->blockState = TBLOCK_INPROGRESS;
2532 * This is the case when we have finished executing a command
2533 * someplace within a transaction block. We increment the command
2534 * counter and return.
2536 case TBLOCK_INPROGRESS:
2537 case TBLOCK_SUBINPROGRESS:
2538 CommandCounterIncrement();
2542 * We are completing a "COMMIT" command. Do it and return to the
2546 CommitTransaction();
2547 s->blockState = TBLOCK_DEFAULT;
2551 * Here we are in the middle of a transaction block but one of the
2552 * commands caused an abort so we do nothing but remain in the
2553 * abort state. Eventually we will get a ROLLBACK comand.
2556 case TBLOCK_SUBABORT:
2560 * Here we were in an aborted transaction block and we just got
2561 * the ROLLBACK command from the user, so clean up the
2562 * already-aborted transaction and return to the idle state.
2564 case TBLOCK_ABORT_END:
2565 CleanupTransaction();
2566 s->blockState = TBLOCK_DEFAULT;
2570 * Here we were in a perfectly good transaction block but the user
2571 * told us to ROLLBACK anyway. We have to abort the transaction
2572 * and then clean up.
2574 case TBLOCK_ABORT_PENDING:
2576 CleanupTransaction();
2577 s->blockState = TBLOCK_DEFAULT;
2581 * We are completing a "PREPARE TRANSACTION" command. Do it and
2582 * return to the idle state.
2584 case TBLOCK_PREPARE:
2585 PrepareTransaction();
2586 s->blockState = TBLOCK_DEFAULT;
2590 * We were just issued a SAVEPOINT inside a transaction block.
2591 * Start a subtransaction. (DefineSavepoint already did
2592 * PushTransaction, so as to have someplace to put the SUBBEGIN
2595 case TBLOCK_SUBBEGIN:
2596 StartSubTransaction();
2597 s->blockState = TBLOCK_SUBINPROGRESS;
2601 * We were issued a RELEASE command, so we end the
2602 * current subtransaction and return to the parent transaction.
2603 * The parent might be ended too, so repeat till we find an
2604 * INPROGRESS transaction or subtransaction.
2606 case TBLOCK_SUBRELEASE:
2609 CommitSubTransaction();
2610 s = CurrentTransactionState; /* changed by pop */
2611 } while (s->blockState == TBLOCK_SUBRELEASE);
2613 Assert(s->blockState == TBLOCK_INPROGRESS ||
2614 s->blockState == TBLOCK_SUBINPROGRESS);
2618 * We were issued a COMMIT, so we end the current subtransaction
2619 * hierarchy and perform final commit. We do this by rolling up
2620 * any subtransactions into their parent, which leads to O(N^2)
2621 * operations with respect to resource owners - this isn't that
2622 * bad until we approach a thousands of savepoints but is necessary
2623 * for correctness should after triggers create new resource
2626 case TBLOCK_SUBCOMMIT:
2629 CommitSubTransaction();
2630 s = CurrentTransactionState; /* changed by pop */
2631 } while (s->blockState == TBLOCK_SUBCOMMIT);
2632 /* If we had a COMMIT command, finish off the main xact too */
2633 if (s->blockState == TBLOCK_END)
2635 Assert(s->parent == NULL);
2636 CommitTransaction();
2637 s->blockState = TBLOCK_DEFAULT;
2639 else if (s->blockState == TBLOCK_PREPARE)
2641 Assert(s->parent == NULL);
2642 PrepareTransaction();
2643 s->blockState = TBLOCK_DEFAULT;
2646 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
2647 BlockStateAsString(s->blockState));
2651 * The current already-failed subtransaction is ending due to a
2652 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2653 * examine the parent (which could be in any of several states).
2655 case TBLOCK_SUBABORT_END:
2656 CleanupSubTransaction();
2657 CommitTransactionCommand();
2661 * As above, but it's not dead yet, so abort first.
2663 case TBLOCK_SUBABORT_PENDING:
2664 AbortSubTransaction();
2665 CleanupSubTransaction();
2666 CommitTransactionCommand();
2670 * The current subtransaction is the target of a ROLLBACK TO
2671 * command. Abort and pop it, then start a new subtransaction
2672 * with the same name.
2674 case TBLOCK_SUBRESTART:
2679 /* save name and keep Cleanup from freeing it */
2682 savepointLevel = s->savepointLevel;
2684 AbortSubTransaction();
2685 CleanupSubTransaction();
2687 DefineSavepoint(NULL);
2688 s = CurrentTransactionState; /* changed by push */
2690 s->savepointLevel = savepointLevel;
2692 /* This is the same as TBLOCK_SUBBEGIN case */
2693 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2694 StartSubTransaction();
2695 s->blockState = TBLOCK_SUBINPROGRESS;
2700 * Same as above, but the subtransaction had already failed, so we
2701 * don't need AbortSubTransaction.
2703 case TBLOCK_SUBABORT_RESTART:
2708 /* save name and keep Cleanup from freeing it */
2711 savepointLevel = s->savepointLevel;
2713 CleanupSubTransaction();
2715 DefineSavepoint(NULL);
2716 s = CurrentTransactionState; /* changed by push */
2718 s->savepointLevel = savepointLevel;
2720 /* This is the same as TBLOCK_SUBBEGIN case */
2721 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2722 StartSubTransaction();
2723 s->blockState = TBLOCK_SUBINPROGRESS;
2730 * AbortCurrentTransaction
2733 AbortCurrentTransaction(void)
2735 TransactionState s = CurrentTransactionState;
2737 switch (s->blockState)
2739 case TBLOCK_DEFAULT:
2740 if (s->state == TRANS_DEFAULT)
2742 /* we are idle, so nothing to do */
2747 * We can get here after an error during transaction start
2748 * (state will be TRANS_START). Need to clean up the
2749 * incompletely started transaction. First, adjust the
2750 * low-level state to suppress warning message from
2753 if (s->state == TRANS_START)
2754 s->state = TRANS_INPROGRESS;
2756 CleanupTransaction();
2761 * if we aren't in a transaction block, we just do the basic abort
2762 * & cleanup transaction.
2764 case TBLOCK_STARTED:
2766 CleanupTransaction();
2767 s->blockState = TBLOCK_DEFAULT;
2771 * If we are in TBLOCK_BEGIN it means something screwed up right
2772 * after reading "BEGIN TRANSACTION". We assume that the user
2773 * will interpret the error as meaning the BEGIN failed to get him
2774 * into a transaction block, so we should abort and return to idle
2779 CleanupTransaction();
2780 s->blockState = TBLOCK_DEFAULT;
2784 * We are somewhere in a transaction block and we've gotten a
2785 * failure, so we abort the transaction and set up the persistent
2786 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
2788 case TBLOCK_INPROGRESS:
2790 s->blockState = TBLOCK_ABORT;
2791 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
2795 * Here, we failed while trying to COMMIT. Clean up the
2796 * transaction and return to idle state (we do not want to stay in
2801 CleanupTransaction();
2802 s->blockState = TBLOCK_DEFAULT;
2806 * Here, we are already in an aborted transaction state and are
2807 * waiting for a ROLLBACK, but for some reason we failed again! So
2808 * we just remain in the abort state.
2811 case TBLOCK_SUBABORT:
2815 * We are in a failed transaction and we got the ROLLBACK command.
2816 * We have already aborted, we just need to cleanup and go to idle
2819 case TBLOCK_ABORT_END:
2820 CleanupTransaction();
2821 s->blockState = TBLOCK_DEFAULT;
2825 * We are in a live transaction and we got a ROLLBACK command.
2826 * Abort, cleanup, go to idle state.
2828 case TBLOCK_ABORT_PENDING:
2830 CleanupTransaction();
2831 s->blockState = TBLOCK_DEFAULT;
2835 * Here, we failed while trying to PREPARE. Clean up the
2836 * transaction and return to idle state (we do not want to stay in
2839 case TBLOCK_PREPARE:
2841 CleanupTransaction();
2842 s->blockState = TBLOCK_DEFAULT;
2846 * We got an error inside a subtransaction. Abort just the
2847 * subtransaction, and go to the persistent SUBABORT state until
2850 case TBLOCK_SUBINPROGRESS:
2851 AbortSubTransaction();
2852 s->blockState = TBLOCK_SUBABORT;
2856 * If we failed while trying to create a subtransaction, clean up
2857 * the broken subtransaction and abort the parent. The same
2858 * applies if we get a failure while ending a subtransaction.
2860 case TBLOCK_SUBBEGIN:
2861 case TBLOCK_SUBRELEASE:
2862 case TBLOCK_SUBCOMMIT:
2863 case TBLOCK_SUBABORT_PENDING:
2864 case TBLOCK_SUBRESTART:
2865 AbortSubTransaction();
2866 CleanupSubTransaction();
2867 AbortCurrentTransaction();
2871 * Same as above, except the Abort() was already done.
2873 case TBLOCK_SUBABORT_END:
2874 case TBLOCK_SUBABORT_RESTART:
2875 CleanupSubTransaction();
2876 AbortCurrentTransaction();
2882 * PreventTransactionChain
2884 * This routine is to be called by statements that must not run inside
2885 * a transaction block, typically because they have non-rollback-able
2886 * side effects or do internal commits.
2888 * If we have already started a transaction block, issue an error; also issue
2889 * an error if we appear to be running inside a user-defined function (which
2890 * could issue more commands and possibly cause a failure after the statement
2891 * completes). Subtransactions are verboten too.
2893 * isTopLevel: passed down from ProcessUtility to determine whether we are
2894 * inside a function or multi-query querystring. (We will always fail if
2895 * this is false, but it's convenient to centralize the check here instead of
2896 * making callers do it.)
2897 * stmtType: statement type name, for error messages.
2900 PreventTransactionChain(bool isTopLevel, const char *stmtType)
2903 * xact block already started?
2905 if (IsTransactionBlock())
2907 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2908 /* translator: %s represents an SQL statement name */
2909 errmsg("%s cannot run inside a transaction block",
2915 if (IsSubTransaction())
2917 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2918 /* translator: %s represents an SQL statement name */
2919 errmsg("%s cannot run inside a subtransaction",
2923 * inside a function call?
2927 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2928 /* translator: %s represents an SQL statement name */
2929 errmsg("%s cannot be executed from a function or multi-command string",
2932 /* If we got past IsTransactionBlock test, should be in default state */
2933 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2934 CurrentTransactionState->blockState != TBLOCK_STARTED)
2935 elog(FATAL, "cannot prevent transaction chain");
2940 * RequireTransactionChain
2942 * This routine is to be called by statements that must run inside
2943 * a transaction block, because they have no effects that persist past
2944 * transaction end (and so calling them outside a transaction block
2945 * is presumably an error). DECLARE CURSOR is an example.
2947 * If we appear to be running inside a user-defined function, we do not
2948 * issue an error, since the function could issue more commands that make
2949 * use of the current statement's results. Likewise subtransactions.
2950 * Thus this is an inverse for PreventTransactionChain.
2952 * isTopLevel: passed down from ProcessUtility to determine whether we are
2953 * inside a function.
2954 * stmtType: statement type name, for error messages.
2957 RequireTransactionChain(bool isTopLevel, const char *stmtType)
2960 * xact block already started?
2962 if (IsTransactionBlock())
2968 if (IsSubTransaction())
2972 * inside a function call?
2978 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2979 /* translator: %s represents an SQL statement name */
2980 errmsg("%s can only be used in transaction blocks",
2985 * IsInTransactionChain
2987 * This routine is for statements that need to behave differently inside
2988 * a transaction block than when running as single commands. ANALYZE is
2989 * currently the only example.
2991 * isTopLevel: passed down from ProcessUtility to determine whether we are
2992 * inside a function.
2995 IsInTransactionChain(bool isTopLevel)
2998 * Return true on same conditions that would make PreventTransactionChain
3001 if (IsTransactionBlock())
3004 if (IsSubTransaction())
3010 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
3011 CurrentTransactionState->blockState != TBLOCK_STARTED)
3019 * Register or deregister callback functions for start- and end-of-xact
3022 * These functions are intended for use by dynamically loaded modules.
3023 * For built-in modules we generally just hardwire the appropriate calls
3024 * (mainly because it's easier to control the order that way, where needed).
3026 * At transaction end, the callback occurs post-commit or post-abort, so the
3027 * callback functions can only do noncritical cleanup.
3030 RegisterXactCallback(XactCallback callback, void *arg)
3032 XactCallbackItem *item;
3034 item = (XactCallbackItem *)
3035 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
3036 item->callback = callback;
3038 item->next = Xact_callbacks;
3039 Xact_callbacks = item;
3043 UnregisterXactCallback(XactCallback callback, void *arg)
3045 XactCallbackItem *item;
3046 XactCallbackItem *prev;
3049 for (item = Xact_callbacks; item; prev = item, item = item->next)
3051 if (item->callback == callback && item->arg == arg)
3054 prev->next = item->next;
3056 Xact_callbacks = item->next;
3064 CallXactCallbacks(XactEvent event)
3066 XactCallbackItem *item;
3068 for (item = Xact_callbacks; item; item = item->next)
3069 (*item->callback) (event, item->arg);
3074 * Register or deregister callback functions for start- and end-of-subxact
3077 * Pretty much same as above, but for subtransaction events.
3079 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3080 * so the callback functions can only do noncritical cleanup. At
3081 * subtransaction start, the callback is called when the subtransaction has
3082 * finished initializing.
3085 RegisterSubXactCallback(SubXactCallback callback, void *arg)
3087 SubXactCallbackItem *item;
3089 item = (SubXactCallbackItem *)
3090 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
3091 item->callback = callback;
3093 item->next = SubXact_callbacks;
3094 SubXact_callbacks = item;
3098 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
3100 SubXactCallbackItem *item;
3101 SubXactCallbackItem *prev;
3104 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3106 if (item->callback == callback && item->arg == arg)
3109 prev->next = item->next;
3111 SubXact_callbacks = item->next;
3119 CallSubXactCallbacks(SubXactEvent event,
3120 SubTransactionId mySubid,
3121 SubTransactionId parentSubid)
3123 SubXactCallbackItem *item;
3125 for (item = SubXact_callbacks; item; item = item->next)
3126 (*item->callback) (event, mySubid, parentSubid, item->arg);
3130 /* ----------------------------------------------------------------
3131 * transaction block support
3132 * ----------------------------------------------------------------
3136 * BeginTransactionBlock
3137 * This executes a BEGIN command.
3140 BeginTransactionBlock(void)
3142 TransactionState s = CurrentTransactionState;
3144 switch (s->blockState)
3147 * We are not inside a transaction block, so allow one to begin.
3149 case TBLOCK_STARTED:
3150 s->blockState = TBLOCK_BEGIN;
3154 * Already a transaction block in progress.
3156 case TBLOCK_INPROGRESS:
3157 case TBLOCK_SUBINPROGRESS:
3159 case TBLOCK_SUBABORT:
3161 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3162 errmsg("there is already a transaction in progress")));
3165 /* These cases are invalid. */
3166 case TBLOCK_DEFAULT:
3168 case TBLOCK_SUBBEGIN:
3170 case TBLOCK_SUBRELEASE:
3171 case TBLOCK_SUBCOMMIT:
3172 case TBLOCK_ABORT_END:
3173 case TBLOCK_SUBABORT_END:
3174 case TBLOCK_ABORT_PENDING:
3175 case TBLOCK_SUBABORT_PENDING:
3176 case TBLOCK_SUBRESTART:
3177 case TBLOCK_SUBABORT_RESTART:
3178 case TBLOCK_PREPARE:
3179 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3180 BlockStateAsString(s->blockState));
3186 * PrepareTransactionBlock
3187 * This executes a PREPARE command.
3189 * Since PREPARE may actually do a ROLLBACK, the result indicates what
3190 * happened: TRUE for PREPARE, FALSE for ROLLBACK.
3192 * Note that we don't actually do anything here except change blockState.
3193 * The real work will be done in the upcoming PrepareTransaction().
3194 * We do it this way because it's not convenient to change memory context,
3195 * resource owner, etc while executing inside a Portal.
3198 PrepareTransactionBlock(char *gid)
3203 /* Set up to commit the current transaction */
3204 result = EndTransactionBlock();
3206 /* If successful, change outer tblock state to PREPARE */
3209 s = CurrentTransactionState;
3211 while (s->parent != NULL)
3214 if (s->blockState == TBLOCK_END)
3216 /* Save GID where PrepareTransaction can find it again */
3217 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
3219 s->blockState = TBLOCK_PREPARE;
3224 * ignore case where we are not in a transaction;
3225 * EndTransactionBlock already issued a warning.
3227 Assert(s->blockState == TBLOCK_STARTED);
3228 /* Don't send back a PREPARE result tag... */
3237 * EndTransactionBlock
3238 * This executes a COMMIT command.
3240 * Since COMMIT may actually do a ROLLBACK, the result indicates what
3241 * happened: TRUE for COMMIT, FALSE for ROLLBACK.
3243 * Note that we don't actually do anything here except change blockState.
3244 * The real work will be done in the upcoming CommitTransactionCommand().
3245 * We do it this way because it's not convenient to change memory context,
3246 * resource owner, etc while executing inside a Portal.
3249 EndTransactionBlock(void)
3251 TransactionState s = CurrentTransactionState;
3252 bool result = false;
3254 switch (s->blockState)
3257 * We are in a transaction block, so tell CommitTransactionCommand
3260 case TBLOCK_INPROGRESS:
3261 s->blockState = TBLOCK_END;
3266 * We are in a failed transaction block. Tell
3267 * CommitTransactionCommand it's time to exit the block.
3270 s->blockState = TBLOCK_ABORT_END;
3274 * We are in a live subtransaction block. Set up to subcommit all
3275 * open subtransactions and then commit the main transaction.
3277 case TBLOCK_SUBINPROGRESS:
3278 while (s->parent != NULL)
3280 if (s->blockState == TBLOCK_SUBINPROGRESS)
3281 s->blockState = TBLOCK_SUBCOMMIT;
3283 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3284 BlockStateAsString(s->blockState));
3287 if (s->blockState == TBLOCK_INPROGRESS)
3288 s->blockState = TBLOCK_END;
3290 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3291 BlockStateAsString(s->blockState));
3296 * Here we are inside an aborted subtransaction. Treat the COMMIT
3297 * as ROLLBACK: set up to abort everything and exit the main
3300 case TBLOCK_SUBABORT:
3301 while (s->parent != NULL)
3303 if (s->blockState == TBLOCK_SUBINPROGRESS)
3304 s->blockState = TBLOCK_SUBABORT_PENDING;
3305 else if (s->blockState == TBLOCK_SUBABORT)
3306 s->blockState = TBLOCK_SUBABORT_END;
3308 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3309 BlockStateAsString(s->blockState));
3312 if (s->blockState == TBLOCK_INPROGRESS)
3313 s->blockState = TBLOCK_ABORT_PENDING;
3314 else if (s->blockState == TBLOCK_ABORT)
3315 s->blockState = TBLOCK_ABORT_END;
3317 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3318 BlockStateAsString(s->blockState));
3322 * The user issued COMMIT when not inside a transaction. Issue a
3323 * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
3324 * CommitTransactionCommand() will then close the transaction and
3325 * put us back into the default state.
3327 case TBLOCK_STARTED:
3329 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3330 errmsg("there is no transaction in progress")));
3334 /* These cases are invalid. */
3335 case TBLOCK_DEFAULT:
3337 case TBLOCK_SUBBEGIN:
3339 case TBLOCK_SUBRELEASE:
3340 case TBLOCK_SUBCOMMIT:
3341 case TBLOCK_ABORT_END:
3342 case TBLOCK_SUBABORT_END:
3343 case TBLOCK_ABORT_PENDING:
3344 case TBLOCK_SUBABORT_PENDING:
3345 case TBLOCK_SUBRESTART:
3346 case TBLOCK_SUBABORT_RESTART:
3347 case TBLOCK_PREPARE:
3348 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3349 BlockStateAsString(s->blockState));
3357 * UserAbortTransactionBlock
3358 * This executes a ROLLBACK command.
3360 * As above, we don't actually do anything here except change blockState.
3363 UserAbortTransactionBlock(void)
3365 TransactionState s = CurrentTransactionState;
3367 switch (s->blockState)
3370 * We are inside a transaction block and we got a ROLLBACK command
3371 * from the user, so tell CommitTransactionCommand to abort and
3372 * exit the transaction block.
3374 case TBLOCK_INPROGRESS:
3375 s->blockState = TBLOCK_ABORT_PENDING;
3379 * We are inside a failed transaction block and we got a ROLLBACK
3380 * command from the user. Abort processing is already done, so
3381 * CommitTransactionCommand just has to cleanup and go back to
3385 s->blockState = TBLOCK_ABORT_END;
3389 * We are inside a subtransaction. Mark everything up to top
3390 * level as exitable.
3392 case TBLOCK_SUBINPROGRESS:
3393 case TBLOCK_SUBABORT:
3394 while (s->parent != NULL)
3396 if (s->blockState == TBLOCK_SUBINPROGRESS)
3397 s->blockState = TBLOCK_SUBABORT_PENDING;
3398 else if (s->blockState == TBLOCK_SUBABORT)
3399 s->blockState = TBLOCK_SUBABORT_END;
3401 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3402 BlockStateAsString(s->blockState));
3405 if (s->blockState == TBLOCK_INPROGRESS)
3406 s->blockState = TBLOCK_ABORT_PENDING;
3407 else if (s->blockState == TBLOCK_ABORT)
3408 s->blockState = TBLOCK_ABORT_END;
3410 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3411 BlockStateAsString(s->blockState));
3415 * The user issued ABORT when not inside a transaction. Issue a
3416 * WARNING and go to abort state. The upcoming call to
3417 * CommitTransactionCommand() will then put us back into the
3420 case TBLOCK_STARTED:
3422 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3423 errmsg("there is no transaction in progress")));
3424 s->blockState = TBLOCK_ABORT_PENDING;
3427 /* These cases are invalid. */
3428 case TBLOCK_DEFAULT:
3430 case TBLOCK_SUBBEGIN:
3432 case TBLOCK_SUBRELEASE:
3433 case TBLOCK_SUBCOMMIT:
3434 case TBLOCK_ABORT_END:
3435 case TBLOCK_SUBABORT_END:
3436 case TBLOCK_ABORT_PENDING:
3437 case TBLOCK_SUBABORT_PENDING:
3438 case TBLOCK_SUBRESTART:
3439 case TBLOCK_SUBABORT_RESTART:
3440 case TBLOCK_PREPARE:
3441 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3442 BlockStateAsString(s->blockState));
3449 * This executes a SAVEPOINT command.
3452 DefineSavepoint(char *name)
3454 TransactionState s = CurrentTransactionState;
3456 switch (s->blockState)
3458 case TBLOCK_INPROGRESS:
3459 case TBLOCK_SUBINPROGRESS:
3460 /* Normal subtransaction start */
3462 s = CurrentTransactionState; /* changed by push */
3465 * Savepoint names, like the TransactionState block itself, live
3466 * in TopTransactionContext.
3469 s->name = MemoryContextStrdup(TopTransactionContext, name);
3472 /* These cases are invalid. */
3473 case TBLOCK_DEFAULT:
3474 case TBLOCK_STARTED:
3476 case TBLOCK_SUBBEGIN:
3478 case TBLOCK_SUBRELEASE:
3479 case TBLOCK_SUBCOMMIT:
3481 case TBLOCK_SUBABORT:
3482 case TBLOCK_ABORT_END:
3483 case TBLOCK_SUBABORT_END:
3484 case TBLOCK_ABORT_PENDING:
3485 case TBLOCK_SUBABORT_PENDING:
3486 case TBLOCK_SUBRESTART:
3487 case TBLOCK_SUBABORT_RESTART:
3488 case TBLOCK_PREPARE:
3489 elog(FATAL, "DefineSavepoint: unexpected state %s",
3490 BlockStateAsString(s->blockState));
3497 * This executes a RELEASE command.
3499 * As above, we don't actually do anything here except change blockState.
3502 ReleaseSavepoint(List *options)
3504 TransactionState s = CurrentTransactionState;
3505 TransactionState target,
3510 switch (s->blockState)
3513 * We can't rollback to a savepoint if there is no savepoint
3516 case TBLOCK_INPROGRESS:
3518 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3519 errmsg("no such savepoint")));
3523 * We are in a non-aborted subtransaction. This is the only valid
3526 case TBLOCK_SUBINPROGRESS:
3529 /* These cases are invalid. */
3530 case TBLOCK_DEFAULT:
3531 case TBLOCK_STARTED:
3533 case TBLOCK_SUBBEGIN:
3535 case TBLOCK_SUBRELEASE:
3536 case TBLOCK_SUBCOMMIT:
3538 case TBLOCK_SUBABORT:
3539 case TBLOCK_ABORT_END:
3540 case TBLOCK_SUBABORT_END:
3541 case TBLOCK_ABORT_PENDING:
3542 case TBLOCK_SUBABORT_PENDING:
3543 case TBLOCK_SUBRESTART:
3544 case TBLOCK_SUBABORT_RESTART:
3545 case TBLOCK_PREPARE:
3546 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3547 BlockStateAsString(s->blockState));
3551 foreach(cell, options)
3553 DefElem *elem = lfirst(cell);
3555 if (strcmp(elem->defname, "savepoint_name") == 0)
3556 name = strVal(elem->arg);
3559 Assert(PointerIsValid(name));
3561 for (target = s; PointerIsValid(target); target = target->parent)
3563 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3567 if (!PointerIsValid(target))
3569 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3570 errmsg("no such savepoint")));
3572 /* disallow crossing savepoint level boundaries */
3573 if (target->savepointLevel != s->savepointLevel)
3575 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3576 errmsg("no such savepoint")));
3579 * Mark "commit pending" all subtransactions up to the target
3580 * subtransaction. The actual commits will happen when control gets to
3581 * CommitTransactionCommand.
3583 xact = CurrentTransactionState;
3586 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3587 xact->blockState = TBLOCK_SUBRELEASE;
3590 xact = xact->parent;
3591 Assert(PointerIsValid(xact));
3596 * RollbackToSavepoint
3597 * This executes a ROLLBACK TO <savepoint> command.
3599 * As above, we don't actually do anything here except change blockState.
3602 RollbackToSavepoint(List *options)
3604 TransactionState s = CurrentTransactionState;
3605 TransactionState target,
3610 switch (s->blockState)
3613 * We can't rollback to a savepoint if there is no savepoint
3616 case TBLOCK_INPROGRESS:
3619 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3620 errmsg("no such savepoint")));
3624 * There is at least one savepoint, so proceed.
3626 case TBLOCK_SUBINPROGRESS:
3627 case TBLOCK_SUBABORT:
3630 /* These cases are invalid. */
3631 case TBLOCK_DEFAULT:
3632 case TBLOCK_STARTED:
3634 case TBLOCK_SUBBEGIN:
3636 case TBLOCK_SUBRELEASE:
3637 case TBLOCK_SUBCOMMIT:
3638 case TBLOCK_ABORT_END:
3639 case TBLOCK_SUBABORT_END:
3640 case TBLOCK_ABORT_PENDING:
3641 case TBLOCK_SUBABORT_PENDING:
3642 case TBLOCK_SUBRESTART:
3643 case TBLOCK_SUBABORT_RESTART:
3644 case TBLOCK_PREPARE:
3645 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3646 BlockStateAsString(s->blockState));
3650 foreach(cell, options)
3652 DefElem *elem = lfirst(cell);
3654 if (strcmp(elem->defname, "savepoint_name") == 0)
3655 name = strVal(elem->arg);
3658 Assert(PointerIsValid(name));
3660 for (target = s; PointerIsValid(target); target = target->parent)
3662 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3666 if (!PointerIsValid(target))
3668 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3669 errmsg("no such savepoint")));
3671 /* disallow crossing savepoint level boundaries */
3672 if (target->savepointLevel != s->savepointLevel)
3674 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3675 errmsg("no such savepoint")));
3678 * Mark "abort pending" all subtransactions up to the target
3679 * subtransaction. The actual aborts will happen when control gets to
3680 * CommitTransactionCommand.
3682 xact = CurrentTransactionState;
3687 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3688 xact->blockState = TBLOCK_SUBABORT_PENDING;
3689 else if (xact->blockState == TBLOCK_SUBABORT)
3690 xact->blockState = TBLOCK_SUBABORT_END;
3692 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3693 BlockStateAsString(xact->blockState));
3694 xact = xact->parent;
3695 Assert(PointerIsValid(xact));
3698 /* And mark the target as "restart pending" */
3699 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3700 xact->blockState = TBLOCK_SUBRESTART;
3701 else if (xact->blockState == TBLOCK_SUBABORT)
3702 xact->blockState = TBLOCK_SUBABORT_RESTART;
3704 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3705 BlockStateAsString(xact->blockState));
3709 * BeginInternalSubTransaction
3710 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
3711 * TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
3712 * used in functions that might be called when not inside a BEGIN block
3713 * or when running deferred triggers at COMMIT/PREPARE time. Also, it
3714 * automatically does CommitTransactionCommand/StartTransactionCommand
3715 * instead of expecting the caller to do it.
3718 BeginInternalSubTransaction(char *name)
3720 TransactionState s = CurrentTransactionState;
3722 switch (s->blockState)
3724 case TBLOCK_STARTED:
3725 case TBLOCK_INPROGRESS:
3727 case TBLOCK_PREPARE:
3728 case TBLOCK_SUBINPROGRESS:
3729 /* Normal subtransaction start */
3731 s = CurrentTransactionState; /* changed by push */
3734 * Savepoint names, like the TransactionState block itself, live
3735 * in TopTransactionContext.
3738 s->name = MemoryContextStrdup(TopTransactionContext, name);
3741 /* These cases are invalid. */
3742 case TBLOCK_DEFAULT:
3744 case TBLOCK_SUBBEGIN:
3745 case TBLOCK_SUBRELEASE:
3746 case TBLOCK_SUBCOMMIT:
3748 case TBLOCK_SUBABORT:
3749 case TBLOCK_ABORT_END:
3750 case TBLOCK_SUBABORT_END:
3751 case TBLOCK_ABORT_PENDING:
3752 case TBLOCK_SUBABORT_PENDING:
3753 case TBLOCK_SUBRESTART:
3754 case TBLOCK_SUBABORT_RESTART:
3755 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
3756 BlockStateAsString(s->blockState));
3760 CommitTransactionCommand();
3761 StartTransactionCommand();
3765 * ReleaseCurrentSubTransaction
3767 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
3768 * savepoint name (if any).
3769 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3772 ReleaseCurrentSubTransaction(void)
3774 TransactionState s = CurrentTransactionState;
3776 if (s->blockState != TBLOCK_SUBINPROGRESS)
3777 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
3778 BlockStateAsString(s->blockState));
3779 Assert(s->state == TRANS_INPROGRESS);
3780 MemoryContextSwitchTo(CurTransactionContext);
3781 CommitSubTransaction();
3782 s = CurrentTransactionState; /* changed by pop */
3783 Assert(s->state == TRANS_INPROGRESS);
3787 * RollbackAndReleaseCurrentSubTransaction
3789 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
3790 * of its savepoint name (if any).
3791 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3794 RollbackAndReleaseCurrentSubTransaction(void)
3796 TransactionState s = CurrentTransactionState;
3798 switch (s->blockState)
3800 /* Must be in a subtransaction */
3801 case TBLOCK_SUBINPROGRESS:
3802 case TBLOCK_SUBABORT:
3805 /* These cases are invalid. */
3806 case TBLOCK_DEFAULT:
3807 case TBLOCK_STARTED:
3809 case TBLOCK_SUBBEGIN:
3810 case TBLOCK_INPROGRESS:
3812 case TBLOCK_SUBRELEASE:
3813 case TBLOCK_SUBCOMMIT:
3815 case TBLOCK_ABORT_END:
3816 case TBLOCK_SUBABORT_END:
3817 case TBLOCK_ABORT_PENDING:
3818 case TBLOCK_SUBABORT_PENDING:
3819 case TBLOCK_SUBRESTART:
3820 case TBLOCK_SUBABORT_RESTART:
3821 case TBLOCK_PREPARE:
3822 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
3823 BlockStateAsString(s->blockState));
3828 * Abort the current subtransaction, if needed.
3830 if (s->blockState == TBLOCK_SUBINPROGRESS)
3831 AbortSubTransaction();
3833 /* And clean it up, too */
3834 CleanupSubTransaction();
3836 s = CurrentTransactionState; /* changed by pop */
3837 AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
3838 s->blockState == TBLOCK_INPROGRESS ||
3839 s->blockState == TBLOCK_STARTED);
3843 * AbortOutOfAnyTransaction
3845 * This routine is provided for error recovery purposes. It aborts any
3846 * active transaction or transaction block, leaving the system in a known
3850 AbortOutOfAnyTransaction(void)
3852 TransactionState s = CurrentTransactionState;
3855 * Get out of any transaction or nested transaction
3859 switch (s->blockState)
3861 case TBLOCK_DEFAULT:
3862 /* Not in a transaction, do nothing */
3864 case TBLOCK_STARTED:
3866 case TBLOCK_INPROGRESS:
3868 case TBLOCK_ABORT_PENDING:
3869 case TBLOCK_PREPARE:
3870 /* In a transaction, so clean up */
3872 CleanupTransaction();
3873 s->blockState = TBLOCK_DEFAULT;
3876 case TBLOCK_ABORT_END:
3877 /* AbortTransaction already done, still need Cleanup */
3878 CleanupTransaction();
3879 s->blockState = TBLOCK_DEFAULT;
3883 * In a subtransaction, so clean it up and abort parent too
3885 case TBLOCK_SUBBEGIN:
3886 case TBLOCK_SUBINPROGRESS:
3887 case TBLOCK_SUBRELEASE:
3888 case TBLOCK_SUBCOMMIT:
3889 case TBLOCK_SUBABORT_PENDING:
3890 case TBLOCK_SUBRESTART:
3891 AbortSubTransaction();
3892 CleanupSubTransaction();
3893 s = CurrentTransactionState; /* changed by pop */
3896 case TBLOCK_SUBABORT:
3897 case TBLOCK_SUBABORT_END:
3898 case TBLOCK_SUBABORT_RESTART:
3899 /* As above, but AbortSubTransaction already done */
3900 CleanupSubTransaction();
3901 s = CurrentTransactionState; /* changed by pop */
3904 } while (s->blockState != TBLOCK_DEFAULT);
3906 /* Should be out of all subxacts now */
3907 Assert(s->parent == NULL);
3911 * IsTransactionBlock --- are we within a transaction block?
3914 IsTransactionBlock(void)
3916 TransactionState s = CurrentTransactionState;
3918 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
3925 * IsTransactionOrTransactionBlock --- are we within either a transaction
3926 * or a transaction block? (The backend is only really "idle" when this
3929 * This should match up with IsTransactionBlock and IsTransactionState.
3932 IsTransactionOrTransactionBlock(void)
3934 TransactionState s = CurrentTransactionState;
3936 if (s->blockState == TBLOCK_DEFAULT)
3943 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
3946 TransactionBlockStatusCode(void)
3948 TransactionState s = CurrentTransactionState;
3950 switch (s->blockState)
3952 case TBLOCK_DEFAULT:
3953 case TBLOCK_STARTED:
3954 return 'I'; /* idle --- not in transaction */
3956 case TBLOCK_SUBBEGIN:
3957 case TBLOCK_INPROGRESS:
3958 case TBLOCK_SUBINPROGRESS:
3960 case TBLOCK_SUBRELEASE:
3961 case TBLOCK_SUBCOMMIT:
3962 case TBLOCK_PREPARE:
3963 return 'T'; /* in transaction */
3965 case TBLOCK_SUBABORT:
3966 case TBLOCK_ABORT_END:
3967 case TBLOCK_SUBABORT_END:
3968 case TBLOCK_ABORT_PENDING:
3969 case TBLOCK_SUBABORT_PENDING:
3970 case TBLOCK_SUBRESTART:
3971 case TBLOCK_SUBABORT_RESTART:
3972 return 'E'; /* in failed transaction */
3975 /* should never get here */
3976 elog(FATAL, "invalid transaction block state: %s",
3977 BlockStateAsString(s->blockState));
3978 return 0; /* keep compiler quiet */
3985 IsSubTransaction(void)
3987 TransactionState s = CurrentTransactionState;
3989 if (s->nestingLevel >= 2)
3996 * StartSubTransaction
3998 * If you're wondering why this is separate from PushTransaction: it's because
3999 * we can't conveniently do this stuff right inside DefineSavepoint. The
4000 * SAVEPOINT utility command will be executed inside a Portal, and if we
4001 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
4002 * the Portal will undo those settings. So we make DefineSavepoint just
4003 * push a dummy transaction block, and when control returns to the main
4004 * idle loop, CommitTransactionCommand will be called, and we'll come here
4005 * to finish starting the subtransaction.
4008 StartSubTransaction(void)
4010 TransactionState s = CurrentTransactionState;
4012 if (s->state != TRANS_DEFAULT)
4013 elog(WARNING, "StartSubTransaction while in %s state",
4014 TransStateAsString(s->state));
4016 s->state = TRANS_START;
4019 * Initialize subsystems for new subtransaction
4021 * must initialize resource-management stuff first
4023 AtSubStart_Memory();
4024 AtSubStart_ResourceOwner();
4026 AtSubStart_Notify();
4027 AfterTriggerBeginSubXact();
4029 s->state = TRANS_INPROGRESS;
4032 * Call start-of-subxact callbacks
4034 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
4035 s->parent->subTransactionId);
4037 ShowTransactionState("StartSubTransaction");
4041 * CommitSubTransaction
4043 * The caller has to make sure to always reassign CurrentTransactionState
4044 * if it has a local pointer to it after calling this function.
4047 CommitSubTransaction(void)
4049 TransactionState s = CurrentTransactionState;
4051 ShowTransactionState("CommitSubTransaction");
4053 if (s->state != TRANS_INPROGRESS)
4054 elog(WARNING, "CommitSubTransaction while in %s state",
4055 TransStateAsString(s->state));
4057 /* Pre-commit processing goes here -- nothing to do at the moment */
4059 s->state = TRANS_COMMIT;
4061 /* Must CCI to ensure commands of subtransaction are seen as done */
4062 CommandCounterIncrement();
4065 * Prior to 8.4 we marked subcommit in clog at this point. We now only
4066 * perform that step, if required, as part of the atomic update of the
4067 * whole transaction tree at top level commit or abort.
4070 /* Post-commit cleanup */
4071 if (TransactionIdIsValid(s->transactionId))
4072 AtSubCommit_childXids();
4073 AfterTriggerEndSubXact(true);
4074 AtSubCommit_Portals(s->subTransactionId,
4075 s->parent->subTransactionId,
4076 s->parent->curTransactionOwner);
4077 AtEOSubXact_LargeObject(true, s->subTransactionId,
4078 s->parent->subTransactionId);
4079 AtSubCommit_Notify();
4081 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
4082 s->parent->subTransactionId);
4084 ResourceOwnerRelease(s->curTransactionOwner,
4085 RESOURCE_RELEASE_BEFORE_LOCKS,
4087 AtEOSubXact_RelationCache(true, s->subTransactionId,
4088 s->parent->subTransactionId);
4089 AtEOSubXact_Inval(true);
4093 * The only lock we actually release here is the subtransaction XID lock.
4095 CurrentResourceOwner = s->curTransactionOwner;
4096 if (TransactionIdIsValid(s->transactionId))
4097 XactLockTableDelete(s->transactionId);
4100 * Other locks should get transferred to their parent resource owner.
4102 ResourceOwnerRelease(s->curTransactionOwner,
4103 RESOURCE_RELEASE_LOCKS,
4105 ResourceOwnerRelease(s->curTransactionOwner,
4106 RESOURCE_RELEASE_AFTER_LOCKS,
4109 AtEOXact_GUC(true, s->gucNestLevel);
4110 AtEOSubXact_SPI(true, s->subTransactionId);
4111 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
4112 s->parent->subTransactionId);
4113 AtEOSubXact_Namespace(true, s->subTransactionId,
4114 s->parent->subTransactionId);
4115 AtEOSubXact_Files(true, s->subTransactionId,
4116 s->parent->subTransactionId);
4117 AtEOSubXact_HashTables(true, s->nestingLevel);
4118 AtEOSubXact_PgStat(true, s->nestingLevel);
4119 AtSubCommit_Snapshot(s->nestingLevel);
4122 * We need to restore the upper transaction's read-only state, in case the
4123 * upper is read-write while the child is read-only; GUC will incorrectly
4124 * think it should leave the child state in place.
4126 XactReadOnly = s->prevXactReadOnly;
4128 CurrentResourceOwner = s->parent->curTransactionOwner;
4129 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4130 ResourceOwnerDelete(s->curTransactionOwner);
4131 s->curTransactionOwner = NULL;
4133 AtSubCommit_Memory();
4135 s->state = TRANS_DEFAULT;
4141 * AbortSubTransaction
4144 AbortSubTransaction(void)
4146 TransactionState s = CurrentTransactionState;
4148 /* Prevent cancel/die interrupt while cleaning up */
4151 /* Make sure we have a valid memory context and resource owner */
4152 AtSubAbort_Memory();
4153 AtSubAbort_ResourceOwner();
4156 * Release any LW locks we might be holding as quickly as possible.
4157 * (Regular locks, however, must be held till we finish aborting.)
4158 * Releasing LW locks is critical since we might try to grab them again
4159 * while cleaning up!
4161 * FIXME This may be incorrect --- Are there some locks we should keep?
4162 * Buffer locks, for example? I don't think so but I'm not sure.
4172 * check the current transaction state
4174 ShowTransactionState("AbortSubTransaction");
4176 if (s->state != TRANS_INPROGRESS)
4177 elog(WARNING, "AbortSubTransaction while in %s state",
4178 TransStateAsString(s->state));
4180 s->state = TRANS_ABORT;
4183 * Reset user ID which might have been changed transiently. (See notes in
4184 * AbortTransaction.)
4186 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
4189 * We can skip all this stuff if the subxact failed before creating a
4192 if (s->curTransactionOwner)
4194 AfterTriggerEndSubXact(false);
4195 AtSubAbort_Portals(s->subTransactionId,
4196 s->parent->subTransactionId,
4197 s->parent->curTransactionOwner);
4198 AtEOSubXact_LargeObject(false, s->subTransactionId,
4199 s->parent->subTransactionId);
4200 AtSubAbort_Notify();
4202 /* Advertise the fact that we aborted in pg_clog. */
4203 (void) RecordTransactionAbort(true);
4205 /* Post-abort cleanup */
4206 if (TransactionIdIsValid(s->transactionId))
4207 AtSubAbort_childXids();
4209 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
4210 s->parent->subTransactionId);
4212 ResourceOwnerRelease(s->curTransactionOwner,
4213 RESOURCE_RELEASE_BEFORE_LOCKS,
4215 AtEOSubXact_RelationCache(false, s->subTransactionId,
4216 s->parent->subTransactionId);
4217 AtEOSubXact_Inval(false);
4219 ResourceOwnerRelease(s->curTransactionOwner,
4220 RESOURCE_RELEASE_LOCKS,
4222 ResourceOwnerRelease(s->curTransactionOwner,
4223 RESOURCE_RELEASE_AFTER_LOCKS,
4226 AtEOXact_GUC(false, s->gucNestLevel);
4227 AtEOSubXact_SPI(false, s->subTransactionId);
4228 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
4229 s->parent->subTransactionId);
4230 AtEOSubXact_Namespace(false, s->subTransactionId,
4231 s->parent->subTransactionId);
4232 AtEOSubXact_Files(false, s->subTransactionId,
4233 s->parent->subTransactionId);
4234 AtEOSubXact_HashTables(false, s->nestingLevel);
4235 AtEOSubXact_PgStat(false, s->nestingLevel);
4236 AtSubAbort_Snapshot(s->nestingLevel);
4240 * Restore the upper transaction's read-only state, too. This should be
4241 * redundant with GUC's cleanup but we may as well do it for consistency
4242 * with the commit case.
4244 XactReadOnly = s->prevXactReadOnly;
4246 RESUME_INTERRUPTS();
4250 * CleanupSubTransaction
4252 * The caller has to make sure to always reassign CurrentTransactionState
4253 * if it has a local pointer to it after calling this function.
4256 CleanupSubTransaction(void)
4258 TransactionState s = CurrentTransactionState;
4260 ShowTransactionState("CleanupSubTransaction");
4262 if (s->state != TRANS_ABORT)
4263 elog(WARNING, "CleanupSubTransaction while in %s state",
4264 TransStateAsString(s->state));
4266 AtSubCleanup_Portals(s->subTransactionId);
4268 CurrentResourceOwner = s->parent->curTransactionOwner;
4269 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4270 if (s->curTransactionOwner)
4271 ResourceOwnerDelete(s->curTransactionOwner);
4272 s->curTransactionOwner = NULL;
4274 AtSubCleanup_Memory();
4276 s->state = TRANS_DEFAULT;
4283 * Create transaction state stack entry for a subtransaction
4285 * The caller has to make sure to always reassign CurrentTransactionState
4286 * if it has a local pointer to it after calling this function.
4289 PushTransaction(void)
4291 TransactionState p = CurrentTransactionState;
4295 * We keep subtransaction state nodes in TopTransactionContext.
4297 s = (TransactionState)
4298 MemoryContextAllocZero(TopTransactionContext,
4299 sizeof(TransactionStateData));
4302 * Assign a subtransaction ID, watching out for counter wraparound.
4304 currentSubTransactionId += 1;
4305 if (currentSubTransactionId == InvalidSubTransactionId)
4307 currentSubTransactionId -= 1;
4310 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
4311 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
4315 * We can now stack a minimally valid subtransaction without fear of
4318 s->transactionId = InvalidTransactionId; /* until assigned */
4319 s->subTransactionId = currentSubTransactionId;
4321 s->nestingLevel = p->nestingLevel + 1;
4322 s->gucNestLevel = NewGUCNestLevel();
4323 s->savepointLevel = p->savepointLevel;
4324 s->state = TRANS_DEFAULT;
4325 s->blockState = TBLOCK_SUBBEGIN;
4326 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
4327 s->prevXactReadOnly = XactReadOnly;
4329 CurrentTransactionState = s;
4332 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
4333 * with the subtransaction from here on out; in particular they should not
4334 * assume that it necessarily has a transaction context, resource owner,
4341 * Pop back to parent transaction state
4343 * The caller has to make sure to always reassign CurrentTransactionState
4344 * if it has a local pointer to it after calling this function.
4347 PopTransaction(void)
4349 TransactionState s = CurrentTransactionState;
4351 if (s->state != TRANS_DEFAULT)
4352 elog(WARNING, "PopTransaction while in %s state",
4353 TransStateAsString(s->state));
4355 if (s->parent == NULL)
4356 elog(FATAL, "PopTransaction with no parent");
4358 CurrentTransactionState = s->parent;
4360 /* Let's just make sure CurTransactionContext is good */
4361 CurTransactionContext = s->parent->curTransactionContext;
4362 MemoryContextSwitchTo(CurTransactionContext);
4364 /* Ditto for ResourceOwner links */
4365 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4366 CurrentResourceOwner = s->parent->curTransactionOwner;
4368 /* Free the old child structure */
4375 * ShowTransactionState
4379 ShowTransactionState(const char *str)
4381 /* skip work if message will definitely not be printed */
4382 if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
4384 elog(DEBUG3, "%s", str);
4385 ShowTransactionStateRec(CurrentTransactionState);
4390 * ShowTransactionStateRec
4391 * Recursive subroutine for ShowTransactionState
4394 ShowTransactionStateRec(TransactionState s)
4398 initStringInfo(&buf);
4400 if (s->nChildXids > 0)
4404 appendStringInfo(&buf, "%u", s->childXids[0]);
4405 for (i = 1; i < s->nChildXids; i++)
4406 appendStringInfo(&buf, " %u", s->childXids[i]);
4410 ShowTransactionStateRec(s->parent);
4412 /* use ereport to suppress computation if msg will not be printed */
4414 (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u%s, nestlvl: %d, children: %s",
4415 PointerIsValid(s->name) ? s->name : "unnamed",
4416 BlockStateAsString(s->blockState),
4417 TransStateAsString(s->state),
4418 (unsigned int) s->transactionId,
4419 (unsigned int) s->subTransactionId,
4420 (unsigned int) currentCommandId,
4421 currentCommandIdUsed ? " (used)" : "",
4422 s->nestingLevel, buf.data)));
4428 * BlockStateAsString
4432 BlockStateAsString(TBlockState blockState)
4436 case TBLOCK_DEFAULT:
4438 case TBLOCK_STARTED:
4442 case TBLOCK_INPROGRESS:
4443 return "INPROGRESS";
4448 case TBLOCK_ABORT_END:
4450 case TBLOCK_ABORT_PENDING:
4451 return "ABORT PEND";
4452 case TBLOCK_PREPARE:
4454 case TBLOCK_SUBBEGIN:
4456 case TBLOCK_SUBINPROGRESS:
4457 return "SUB INPROGRS";
4458 case TBLOCK_SUBRELEASE:
4459 return "SUB RELEASE";
4460 case TBLOCK_SUBCOMMIT:
4461 return "SUB COMMIT";
4462 case TBLOCK_SUBABORT:
4464 case TBLOCK_SUBABORT_END:
4465 return "SUB ABORT END";
4466 case TBLOCK_SUBABORT_PENDING:
4467 return "SUB ABRT PEND";
4468 case TBLOCK_SUBRESTART:
4469 return "SUB RESTART";
4470 case TBLOCK_SUBABORT_RESTART:
4471 return "SUB AB RESTRT";
4473 return "UNRECOGNIZED";
4477 * TransStateAsString
4481 TransStateAsString(TransState state)
4489 case TRANS_INPROGRESS:
4498 return "UNRECOGNIZED";
4502 * xactGetCommittedChildren
4504 * Gets the list of committed children of the current transaction. The return
4505 * value is the number of child transactions. *ptr is set to point to an
4506 * array of TransactionIds. The array is allocated in TopTransactionContext;
4507 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
4508 * If there are no subxacts, *ptr is set to NULL.
4511 xactGetCommittedChildren(TransactionId **ptr)
4513 TransactionState s = CurrentTransactionState;
4515 if (s->nChildXids == 0)
4518 *ptr = s->childXids;
4520 return s->nChildXids;
4524 * XLOG support routines
4528 * Before 9.0 this was a fairly short function, but now it performs many
4529 * actions for which the order of execution is critical.
4532 xact_redo_commit_internal(TransactionId xid, XLogRecPtr lsn,
4533 TransactionId *sub_xids, int nsubxacts,
4534 SharedInvalidationMessage *inval_msgs, int nmsgs,
4535 RelFileNode *xnodes, int nrels,
4539 TransactionId max_xid;
4542 max_xid = TransactionIdLatest(xid, nsubxacts, sub_xids);
4545 * Make sure nextXid is beyond any XID mentioned in the record.
4547 * We don't expect anyone else to modify nextXid, hence we don't need to
4548 * hold a lock while checking this. We still acquire the lock to modify
4551 if (TransactionIdFollowsOrEquals(max_xid,
4552 ShmemVariableCache->nextXid))
4554 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4555 ShmemVariableCache->nextXid = max_xid;
4556 TransactionIdAdvance(ShmemVariableCache->nextXid);
4557 LWLockRelease(XidGenLock);
4560 if (standbyState == STANDBY_DISABLED)
4563 * Mark the transaction committed in pg_clog.
4565 TransactionIdCommitTree(xid, nsubxacts, sub_xids);
4570 * If a transaction completion record arrives that has as-yet
4571 * unobserved subtransactions then this will not have been fully
4572 * handled by the call to RecordKnownAssignedTransactionIds() in the
4573 * main recovery loop in xlog.c. So we need to do bookkeeping again to
4574 * cover that case. This is confusing and it is easy to think this
4575 * call is irrelevant, which has happened three times in development
4576 * already. Leave it in.
4578 RecordKnownAssignedTransactionIds(max_xid);
4581 * Mark the transaction committed in pg_clog. We use async commit
4582 * protocol during recovery to provide information on database
4583 * consistency for when users try to set hint bits. It is important
4584 * that we do not set hint bits until the minRecoveryPoint is past
4585 * this commit record. This ensures that if we crash we don't see hint
4586 * bits set on changes made by transactions that haven't yet
4587 * recovered. It's unlikely but it's good to be safe.
4589 TransactionIdAsyncCommitTree(xid, nsubxacts, sub_xids, lsn);
4592 * We must mark clog before we update the ProcArray.
4594 ExpireTreeKnownAssignedTransactionIds(xid, nsubxacts, sub_xids, max_xid);
4597 * Send any cache invalidations attached to the commit. We must
4598 * maintain the same order of invalidation then release locks as
4599 * occurs in CommitTransaction().
4601 ProcessCommittedInvalidationMessages(inval_msgs, nmsgs,
4602 XactCompletionRelcacheInitFileInval(xinfo),
4606 * Release locks, if any. We do this for both two phase and normal one
4607 * phase transactions. In effect we are ignoring the prepare phase and
4608 * just going straight to lock release.
4610 StandbyReleaseLockTree(xid, nsubxacts, sub_xids);
4613 /* Make sure files supposed to be dropped are dropped */
4614 for (i = 0; i < nrels; i++)
4616 SMgrRelation srel = smgropen(xnodes[i], InvalidBackendId);
4619 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4621 XLogDropRelation(xnodes[i], fork);
4622 smgrdounlink(srel, fork, true);
4628 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
4629 * in normal operation. For example, in DROP DATABASE, we delete all the
4630 * files belonging to the database, and then commit the transaction. If we
4631 * crash after all the files have been deleted but before the commit, you
4632 * have an entry in pg_database without any files. To minimize the window
4633 * for that, we use ForceSyncCommit() to rush the commit record to disk as
4634 * quick as possible. We have the same window during recovery, and forcing
4635 * an XLogFlush() (which updates minRecoveryPoint during recovery) helps
4636 * to reduce that problem window, for any user that requested
4637 * ForceSyncCommit().
4639 if (XactCompletionForceSyncCommit(xinfo))
4644 * Utility function to call xact_redo_commit_internal after breaking down xlrec
4647 xact_redo_commit(xl_xact_commit *xlrec,
4648 TransactionId xid, XLogRecPtr lsn)
4650 TransactionId *subxacts;
4651 SharedInvalidationMessage *inval_msgs;
4653 /* subxid array follows relfilenodes */
4654 subxacts = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4655 /* invalidation messages array follows subxids */
4656 inval_msgs = (SharedInvalidationMessage *) &(subxacts[xlrec->nsubxacts]);
4658 xact_redo_commit_internal(xid, lsn, subxacts, xlrec->nsubxacts,
4659 inval_msgs, xlrec->nmsgs,
4660 xlrec->xnodes, xlrec->nrels,
4667 * Utility function to call xact_redo_commit_internal for compact form of message.
4670 xact_redo_commit_compact(xl_xact_commit_compact *xlrec,
4671 TransactionId xid, XLogRecPtr lsn)
4673 xact_redo_commit_internal(xid, lsn, xlrec->subxacts, xlrec->nsubxacts,
4674 NULL, 0, /* inval msgs */
4675 NULL, 0, /* relfilenodes */
4676 InvalidOid, /* dbId */
4677 InvalidOid, /* tsId */
4682 * Be careful with the order of execution, as with xact_redo_commit().
4683 * The two functions are similar but differ in key places.
4685 * Note also that an abort can be for a subtransaction and its children,
4686 * not just for a top level abort. That means we have to consider
4687 * topxid != xid, whereas in commit we would find topxid == xid always
4688 * because subtransaction commit is never WAL logged.
4691 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
4693 TransactionId *sub_xids;
4694 TransactionId max_xid;
4697 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4698 max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
4701 * Make sure nextXid is beyond any XID mentioned in the record.
4703 * We don't expect anyone else to modify nextXid, hence we don't need to
4704 * hold a lock while checking this. We still acquire the lock to modify
4707 if (TransactionIdFollowsOrEquals(max_xid,
4708 ShmemVariableCache->nextXid))
4710 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4711 ShmemVariableCache->nextXid = max_xid;
4712 TransactionIdAdvance(ShmemVariableCache->nextXid);
4713 LWLockRelease(XidGenLock);
4716 if (standbyState == STANDBY_DISABLED)
4718 /* Mark the transaction aborted in pg_clog, no need for async stuff */
4719 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4724 * If a transaction completion record arrives that has as-yet
4725 * unobserved subtransactions then this will not have been fully
4726 * handled by the call to RecordKnownAssignedTransactionIds() in the
4727 * main recovery loop in xlog.c. So we need to do bookkeeping again to
4728 * cover that case. This is confusing and it is easy to think this
4729 * call is irrelevant, which has happened three times in development
4730 * already. Leave it in.
4732 RecordKnownAssignedTransactionIds(max_xid);
4734 /* Mark the transaction aborted in pg_clog, no need for async stuff */
4735 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4738 * We must update the ProcArray after we have marked clog.
4740 ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids, max_xid);
4743 * There are no flat files that need updating, nor invalidation
4744 * messages to send or undo.
4748 * Release locks, if any. There are no invalidations to send.
4750 StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
4753 /* Make sure files supposed to be dropped are dropped */
4754 for (i = 0; i < xlrec->nrels; i++)
4756 SMgrRelation srel = smgropen(xlrec->xnodes[i], InvalidBackendId);
4759 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4761 XLogDropRelation(xlrec->xnodes[i], fork);
4762 smgrdounlink(srel, fork, true);
4769 xact_redo(XLogRecPtr lsn, XLogRecord *record)
4771 uint8 info = record->xl_info & ~XLR_INFO_MASK;
4773 /* Backup blocks are not used in xact records */
4774 Assert(!(record->xl_info & XLR_BKP_BLOCK_MASK));
4776 if (info == XLOG_XACT_COMMIT_COMPACT)
4778 xl_xact_commit_compact *xlrec = (xl_xact_commit_compact *) XLogRecGetData(record);
4780 xact_redo_commit_compact(xlrec, record->xl_xid, lsn);
4782 else if (info == XLOG_XACT_COMMIT)
4784 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
4786 xact_redo_commit(xlrec, record->xl_xid, lsn);
4788 else if (info == XLOG_XACT_ABORT)
4790 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
4792 xact_redo_abort(xlrec, record->xl_xid);
4794 else if (info == XLOG_XACT_PREPARE)
4796 /* the record contents are exactly the 2PC file */
4797 RecreateTwoPhaseFile(record->xl_xid,
4798 XLogRecGetData(record), record->xl_len);
4800 else if (info == XLOG_XACT_COMMIT_PREPARED)
4802 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
4804 xact_redo_commit(&xlrec->crec, xlrec->xid, lsn);
4805 RemoveTwoPhaseFile(xlrec->xid, false);
4807 else if (info == XLOG_XACT_ABORT_PREPARED)
4809 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
4811 xact_redo_abort(&xlrec->arec, xlrec->xid);
4812 RemoveTwoPhaseFile(xlrec->xid, false);
4814 else if (info == XLOG_XACT_ASSIGNMENT)
4816 xl_xact_assignment *xlrec = (xl_xact_assignment *) XLogRecGetData(record);
4818 if (standbyState >= STANDBY_INITIALIZED)
4819 ProcArrayApplyXidAssignment(xlrec->xtop,
4820 xlrec->nsubxacts, xlrec->xsub);
4823 elog(PANIC, "xact_redo: unknown op code %u", info);
4827 xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
4830 TransactionId *subxacts;
4832 subxacts = (TransactionId *) &xlrec->xnodes[xlrec->nrels];
4834 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4836 if (xlrec->nrels > 0)
4838 appendStringInfo(buf, "; rels:");
4839 for (i = 0; i < xlrec->nrels; i++)
4841 char *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);
4843 appendStringInfo(buf, " %s", path);
4847 if (xlrec->nsubxacts > 0)
4849 appendStringInfo(buf, "; subxacts:");
4850 for (i = 0; i < xlrec->nsubxacts; i++)
4851 appendStringInfo(buf, " %u", subxacts[i]);
4853 if (xlrec->nmsgs > 0)
4855 SharedInvalidationMessage *msgs;
4857 msgs = (SharedInvalidationMessage *) &subxacts[xlrec->nsubxacts];
4859 if (XactCompletionRelcacheInitFileInval(xlrec->xinfo))
4860 appendStringInfo(buf, "; relcache init file inval dbid %u tsid %u",
4861 xlrec->dbId, xlrec->tsId);
4863 appendStringInfo(buf, "; inval msgs:");
4864 for (i = 0; i < xlrec->nmsgs; i++)
4866 SharedInvalidationMessage *msg = &msgs[i];
4869 appendStringInfo(buf, " catcache %d", msg->id);
4870 else if (msg->id == SHAREDINVALCATALOG_ID)
4871 appendStringInfo(buf, " catalog %u", msg->cat.catId);
4872 else if (msg->id == SHAREDINVALRELCACHE_ID)
4873 appendStringInfo(buf, " relcache %u", msg->rc.relId);
4874 /* remaining cases not expected, but print something anyway */
4875 else if (msg->id == SHAREDINVALSMGR_ID)
4876 appendStringInfo(buf, " smgr");
4877 else if (msg->id == SHAREDINVALRELMAP_ID)
4878 appendStringInfo(buf, " relmap");
4880 appendStringInfo(buf, " unknown id %d", msg->id);
4886 xact_desc_commit_compact(StringInfo buf, xl_xact_commit_compact *xlrec)
4890 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4892 if (xlrec->nsubxacts > 0)
4894 appendStringInfo(buf, "; subxacts:");
4895 for (i = 0; i < xlrec->nsubxacts; i++)
4896 appendStringInfo(buf, " %u", xlrec->subxacts[i]);
4901 xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
4905 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4906 if (xlrec->nrels > 0)
4908 appendStringInfo(buf, "; rels:");
4909 for (i = 0; i < xlrec->nrels; i++)
4911 char *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);
4913 appendStringInfo(buf, " %s", path);
4917 if (xlrec->nsubxacts > 0)
4919 TransactionId *xacts = (TransactionId *)
4920 &xlrec->xnodes[xlrec->nrels];
4922 appendStringInfo(buf, "; subxacts:");
4923 for (i = 0; i < xlrec->nsubxacts; i++)
4924 appendStringInfo(buf, " %u", xacts[i]);
4929 xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
4933 appendStringInfo(buf, "subxacts:");
4935 for (i = 0; i < xlrec->nsubxacts; i++)
4936 appendStringInfo(buf, " %u", xlrec->xsub[i]);
4940 xact_desc(StringInfo buf, uint8 xl_info, char *rec)
4942 uint8 info = xl_info & ~XLR_INFO_MASK;
4944 if (info == XLOG_XACT_COMMIT_COMPACT)
4946 xl_xact_commit_compact *xlrec = (xl_xact_commit_compact *) rec;
4948 appendStringInfo(buf, "commit: ");
4949 xact_desc_commit_compact(buf, xlrec);
4951 else if (info == XLOG_XACT_COMMIT)
4953 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
4955 appendStringInfo(buf, "commit: ");
4956 xact_desc_commit(buf, xlrec);
4958 else if (info == XLOG_XACT_ABORT)
4960 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
4962 appendStringInfo(buf, "abort: ");
4963 xact_desc_abort(buf, xlrec);
4965 else if (info == XLOG_XACT_PREPARE)
4967 appendStringInfo(buf, "prepare");
4969 else if (info == XLOG_XACT_COMMIT_PREPARED)
4971 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
4973 appendStringInfo(buf, "commit prepared %u: ", xlrec->xid);
4974 xact_desc_commit(buf, &xlrec->crec);
4976 else if (info == XLOG_XACT_ABORT_PREPARED)
4978 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
4980 appendStringInfo(buf, "abort prepared %u: ", xlrec->xid);
4981 xact_desc_abort(buf, &xlrec->arec);
4983 else if (info == XLOG_XACT_ASSIGNMENT)
4985 xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
4988 * Note that we ignore the WAL record's xid, since we're more
4989 * interested in the top-level xid that issued the record and which
4990 * xids are being reported here.
4992 appendStringInfo(buf, "xid assignment xtop %u: ", xlrec->xtop);
4993 xact_desc_assignment(buf, xlrec);
4996 appendStringInfo(buf, "UNKNOWN");