1 /*-------------------------------------------------------------------------
4 * top level transaction system support routines
6 * See src/backend/access/transam/README for more information.
8 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
13 * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.277 2009/12/09 21:57:50 tgl Exp $
15 *-------------------------------------------------------------------------
23 #include "access/multixact.h"
24 #include "access/subtrans.h"
25 #include "access/transam.h"
26 #include "access/twophase.h"
27 #include "access/xact.h"
28 #include "access/xlogutils.h"
29 #include "catalog/catalog.h"
30 #include "catalog/namespace.h"
31 #include "catalog/storage.h"
32 #include "commands/async.h"
33 #include "commands/tablecmds.h"
34 #include "commands/trigger.h"
35 #include "executor/spi.h"
36 #include "libpq/be-fsstubs.h"
37 #include "miscadmin.h"
39 #include "storage/bufmgr.h"
40 #include "storage/fd.h"
41 #include "storage/lmgr.h"
42 #include "storage/procarray.h"
43 #include "storage/sinvaladt.h"
44 #include "storage/smgr.h"
45 #include "utils/combocid.h"
46 #include "utils/guc.h"
47 #include "utils/inval.h"
48 #include "utils/memutils.h"
49 #include "utils/relcache.h"
50 #include "utils/snapmgr.h"
55 * User-tweakable parameters
57 int DefaultXactIsoLevel = XACT_READ_COMMITTED;
60 bool DefaultXactReadOnly = false;
63 bool XactSyncCommit = true;
65 int CommitDelay = 0; /* precommit delay in microseconds */
66 int CommitSiblings = 5; /* # concurrent xacts needed to sleep */
69 * MyXactAccessedTempRel is set when a temporary relation is accessed.
70 * We don't allow PREPARE TRANSACTION in that case. (This is global
71 * so that it can be set from heapam.c.)
73 bool MyXactAccessedTempRel = false;
77 * transaction states - transaction state from server perspective
79 typedef enum TransState
81 TRANS_DEFAULT, /* idle */
82 TRANS_START, /* transaction starting */
83 TRANS_INPROGRESS, /* inside a valid transaction */
84 TRANS_COMMIT, /* commit in progress */
85 TRANS_ABORT, /* abort in progress */
86 TRANS_PREPARE /* prepare in progress */
90 * transaction block states - transaction state of client queries
92 * Note: the subtransaction states are used only for non-topmost
93 * transactions; the others appear only in the topmost transaction.
95 typedef enum TBlockState
97 /* not-in-transaction-block states */
98 TBLOCK_DEFAULT, /* idle */
99 TBLOCK_STARTED, /* running single-query transaction */
101 /* transaction block states */
102 TBLOCK_BEGIN, /* starting transaction block */
103 TBLOCK_INPROGRESS, /* live transaction */
104 TBLOCK_END, /* COMMIT received */
105 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
106 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
107 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
108 TBLOCK_PREPARE, /* live xact, PREPARE received */
110 /* subtransaction states */
111 TBLOCK_SUBBEGIN, /* starting a subtransaction */
112 TBLOCK_SUBINPROGRESS, /* live subtransaction */
113 TBLOCK_SUBEND, /* RELEASE received */
114 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
115 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
116 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
117 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
118 TBLOCK_SUBABORT_RESTART /* failed subxact, ROLLBACK TO received */
122 * transaction state structure
124 typedef struct TransactionStateData
126 TransactionId transactionId; /* my XID, or Invalid if none */
127 SubTransactionId subTransactionId; /* my subxact ID */
128 char *name; /* savepoint name, if any */
129 int savepointLevel; /* savepoint level */
130 TransState state; /* low-level state */
131 TBlockState blockState; /* high-level state */
132 int nestingLevel; /* transaction nesting depth */
133 int gucNestLevel; /* GUC context nesting depth */
134 MemoryContext curTransactionContext; /* my xact-lifetime context */
135 ResourceOwner curTransactionOwner; /* my query resources */
136 TransactionId *childXids; /* subcommitted child XIDs, in XID order */
137 int nChildXids; /* # of subcommitted child XIDs */
138 int maxChildXids; /* allocated size of childXids[] */
139 Oid prevUser; /* previous CurrentUserId setting */
140 int prevSecContext; /* previous SecurityRestrictionContext */
141 bool prevXactReadOnly; /* entry-time xact r/o state */
142 struct TransactionStateData *parent; /* back link to parent */
143 } TransactionStateData;
145 typedef TransactionStateData *TransactionState;
148 * CurrentTransactionState always points to the current transaction state
149 * block. It will point to TopTransactionStateData when not in a
150 * transaction at all, or when in a top-level transaction.
152 static TransactionStateData TopTransactionStateData = {
153 0, /* transaction id */
154 0, /* subtransaction id */
155 NULL, /* savepoint name */
156 0, /* savepoint level */
157 TRANS_DEFAULT, /* transaction state */
158 TBLOCK_DEFAULT, /* transaction block state from the client
160 0, /* transaction nesting depth */
161 0, /* GUC context nesting depth */
162 NULL, /* cur transaction context */
163 NULL, /* cur transaction resource owner */
164 NULL, /* subcommitted child Xids */
165 0, /* # of subcommitted child Xids */
166 0, /* allocated size of childXids[] */
167 InvalidOid, /* previous CurrentUserId setting */
168 0, /* previous SecurityRestrictionContext */
169 false, /* entry-time xact r/o state */
170 NULL /* link to parent state block */
173 static TransactionState CurrentTransactionState = &TopTransactionStateData;
176 * The subtransaction ID and command ID assignment counters are global
177 * to a whole transaction, so we do not keep them in the state stack.
179 static SubTransactionId currentSubTransactionId;
180 static CommandId currentCommandId;
181 static bool currentCommandIdUsed;
184 * xactStartTimestamp is the value of transaction_timestamp().
185 * stmtStartTimestamp is the value of statement_timestamp().
186 * xactStopTimestamp is the time at which we log a commit or abort WAL record.
187 * These do not change as we enter and exit subtransactions, so we don't
188 * keep them inside the TransactionState stack.
190 static TimestampTz xactStartTimestamp;
191 static TimestampTz stmtStartTimestamp;
192 static TimestampTz xactStopTimestamp;
195 * GID to be used for preparing the current transaction. This is also
196 * global to a whole transaction, so we don't keep it in the state stack.
198 static char *prepareGID;
201 * Some commands want to force synchronous commit.
203 static bool forceSyncCommit = false;
206 * Private context for transaction-abort work --- we reserve space for this
207 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
208 * when we've run out of memory.
210 static MemoryContext TransactionAbortContext = NULL;
213 * List of add-on start- and end-of-xact callbacks
215 typedef struct XactCallbackItem
217 struct XactCallbackItem *next;
218 XactCallback callback;
222 static XactCallbackItem *Xact_callbacks = NULL;
225 * List of add-on start- and end-of-subxact callbacks
227 typedef struct SubXactCallbackItem
229 struct SubXactCallbackItem *next;
230 SubXactCallback callback;
232 } SubXactCallbackItem;
234 static SubXactCallbackItem *SubXact_callbacks = NULL;
237 /* local function prototypes */
238 static void AssignTransactionId(TransactionState s);
239 static void AbortTransaction(void);
240 static void AtAbort_Memory(void);
241 static void AtCleanup_Memory(void);
242 static void AtAbort_ResourceOwner(void);
243 static void AtCommit_LocalCache(void);
244 static void AtCommit_Memory(void);
245 static void AtStart_Cache(void);
246 static void AtStart_Memory(void);
247 static void AtStart_ResourceOwner(void);
248 static void CallXactCallbacks(XactEvent event);
249 static void CallSubXactCallbacks(SubXactEvent event,
250 SubTransactionId mySubid,
251 SubTransactionId parentSubid);
252 static void CleanupTransaction(void);
253 static void CommitTransaction(void);
254 static TransactionId RecordTransactionAbort(bool isSubXact);
255 static void StartTransaction(void);
257 static void StartSubTransaction(void);
258 static void CommitSubTransaction(void);
259 static void AbortSubTransaction(void);
260 static void CleanupSubTransaction(void);
261 static void PushTransaction(void);
262 static void PopTransaction(void);
264 static void AtSubAbort_Memory(void);
265 static void AtSubCleanup_Memory(void);
266 static void AtSubAbort_ResourceOwner(void);
267 static void AtSubCommit_Memory(void);
268 static void AtSubStart_Memory(void);
269 static void AtSubStart_ResourceOwner(void);
271 static void ShowTransactionState(const char *str);
272 static void ShowTransactionStateRec(TransactionState state);
273 static const char *BlockStateAsString(TBlockState blockState);
274 static const char *TransStateAsString(TransState state);
277 /* ----------------------------------------------------------------
278 * transaction state accessors
279 * ----------------------------------------------------------------
285 * This returns true if we are inside a valid transaction; that is,
286 * it is safe to initiate database access, take heavyweight locks, etc.
289 IsTransactionState(void)
291 TransactionState s = CurrentTransactionState;
294 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
295 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
296 * TRANS_PREPARE since it might be too soon or too late within those
297 * transition states to do anything interesting. Hence, the only "valid"
298 * state is TRANS_INPROGRESS.
300 return (s->state == TRANS_INPROGRESS);
304 * IsAbortedTransactionBlockState
306 * This returns true if we are currently running a query
307 * within an aborted transaction block.
310 IsAbortedTransactionBlockState(void)
312 TransactionState s = CurrentTransactionState;
314 if (s->blockState == TBLOCK_ABORT ||
315 s->blockState == TBLOCK_SUBABORT)
323 * GetTopTransactionId
325 * This will return the XID of the main transaction, assigning one if
326 * it's not yet set. Be careful to call this only inside a valid xact.
329 GetTopTransactionId(void)
331 if (!TransactionIdIsValid(TopTransactionStateData.transactionId))
332 AssignTransactionId(&TopTransactionStateData);
333 return TopTransactionStateData.transactionId;
337 * GetTopTransactionIdIfAny
339 * This will return the XID of the main transaction, if one is assigned.
340 * It will return InvalidTransactionId if we are not currently inside a
341 * transaction, or inside a transaction that hasn't yet been assigned an XID.
344 GetTopTransactionIdIfAny(void)
346 return TopTransactionStateData.transactionId;
350 * GetCurrentTransactionId
352 * This will return the XID of the current transaction (main or sub
353 * transaction), assigning one if it's not yet set. Be careful to call this
354 * only inside a valid xact.
357 GetCurrentTransactionId(void)
359 TransactionState s = CurrentTransactionState;
361 if (!TransactionIdIsValid(s->transactionId))
362 AssignTransactionId(s);
363 return s->transactionId;
367 * GetCurrentTransactionIdIfAny
369 * This will return the XID of the current sub xact, if one is assigned.
370 * It will return InvalidTransactionId if we are not currently inside a
371 * transaction, or inside a transaction that hasn't been assigned an XID yet.
374 GetCurrentTransactionIdIfAny(void)
376 return CurrentTransactionState->transactionId;
381 * AssignTransactionId
383 * Assigns a new permanent XID to the given TransactionState.
384 * We do not assign XIDs to transactions until/unless this is called.
385 * Also, any parent TransactionStates that don't yet have XIDs are assigned
386 * one; this maintains the invariant that a child transaction has an XID
387 * following its parent's.
390 AssignTransactionId(TransactionState s)
392 bool isSubXact = (s->parent != NULL);
393 ResourceOwner currentOwner;
395 /* Assert that caller didn't screw up */
396 Assert(!TransactionIdIsValid(s->transactionId));
397 Assert(s->state == TRANS_INPROGRESS);
400 * Ensure parent(s) have XIDs, so that a child always has an XID later
403 if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
404 AssignTransactionId(s->parent);
407 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
409 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
410 * shared storage other than PG_PROC; because if there's no room for it in
411 * PG_PROC, the subtrans entry is needed to ensure that other backends see
412 * the Xid as "running". See GetNewTransactionId.
414 s->transactionId = GetNewTransactionId(isSubXact);
417 SubTransSetParent(s->transactionId, s->parent->transactionId);
420 * Acquire lock on the transaction XID. (We assume this cannot block.) We
421 * have to ensure that the lock is assigned to the transaction's own
424 currentOwner = CurrentResourceOwner;
427 CurrentResourceOwner = s->curTransactionOwner;
428 XactLockTableInsert(s->transactionId);
432 /* Ensure CurrentResourceOwner is restored on error */
433 CurrentResourceOwner = currentOwner;
437 CurrentResourceOwner = currentOwner;
442 * GetCurrentSubTransactionId
445 GetCurrentSubTransactionId(void)
447 TransactionState s = CurrentTransactionState;
449 return s->subTransactionId;
454 * GetCurrentCommandId
456 * "used" must be TRUE if the caller intends to use the command ID to mark
457 * inserted/updated/deleted tuples. FALSE means the ID is being fetched
458 * for read-only purposes (ie, as a snapshot validity cutoff). See
459 * CommandCounterIncrement() for discussion.
462 GetCurrentCommandId(bool used)
464 /* this is global to a transaction, not subtransaction-local */
466 currentCommandIdUsed = true;
467 return currentCommandId;
471 * GetCurrentTransactionStartTimestamp
474 GetCurrentTransactionStartTimestamp(void)
476 return xactStartTimestamp;
480 * GetCurrentStatementStartTimestamp
483 GetCurrentStatementStartTimestamp(void)
485 return stmtStartTimestamp;
489 * GetCurrentTransactionStopTimestamp
491 * We return current time if the transaction stop time hasn't been set
492 * (which can happen if we decide we don't need to log an XLOG record).
495 GetCurrentTransactionStopTimestamp(void)
497 if (xactStopTimestamp != 0)
498 return xactStopTimestamp;
499 return GetCurrentTimestamp();
503 * SetCurrentStatementStartTimestamp
506 SetCurrentStatementStartTimestamp(void)
508 stmtStartTimestamp = GetCurrentTimestamp();
512 * SetCurrentTransactionStopTimestamp
515 SetCurrentTransactionStopTimestamp(void)
517 xactStopTimestamp = GetCurrentTimestamp();
521 * GetCurrentTransactionNestLevel
523 * Note: this will return zero when not inside any transaction, one when
524 * inside a top-level transaction, etc.
527 GetCurrentTransactionNestLevel(void)
529 TransactionState s = CurrentTransactionState;
531 return s->nestingLevel;
536 * TransactionIdIsCurrentTransactionId
539 TransactionIdIsCurrentTransactionId(TransactionId xid)
544 * We always say that BootstrapTransactionId is "not my transaction ID"
545 * even when it is (ie, during bootstrap). Along with the fact that
546 * transam.c always treats BootstrapTransactionId as already committed,
547 * this causes the tqual.c routines to see all tuples as committed, which
548 * is what we need during bootstrap. (Bootstrap mode only inserts tuples,
549 * it never updates or deletes them, so all tuples can be presumed good
552 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
553 * not my transaction ID, so we can just return "false" immediately for
554 * any non-normal XID.
556 if (!TransactionIdIsNormal(xid))
560 * We will return true for the Xid of the current subtransaction, any of
561 * its subcommitted children, any of its parents, or any of their
562 * previously subcommitted children. However, a transaction being aborted
563 * is no longer "current", even though it may still have an entry on the
566 for (s = CurrentTransactionState; s != NULL; s = s->parent)
571 if (s->state == TRANS_ABORT)
573 if (!TransactionIdIsValid(s->transactionId))
574 continue; /* it can't have any child XIDs either */
575 if (TransactionIdEquals(xid, s->transactionId))
577 /* As the childXids array is ordered, we can use binary search */
579 high = s->nChildXids - 1;
585 middle = low + (high - low) / 2;
586 probe = s->childXids[middle];
587 if (TransactionIdEquals(probe, xid))
589 else if (TransactionIdPrecedes(probe, xid))
601 * CommandCounterIncrement
604 CommandCounterIncrement(void)
607 * If the current value of the command counter hasn't been "used" to mark
608 * tuples, we need not increment it, since there's no need to distinguish
609 * a read-only command from others. This helps postpone command counter
610 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
612 if (currentCommandIdUsed)
614 currentCommandId += 1;
615 if (currentCommandId == FirstCommandId) /* check for overflow */
617 currentCommandId -= 1;
619 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
620 errmsg("cannot have more than 2^32-1 commands in a transaction")));
622 currentCommandIdUsed = false;
624 /* Propagate new command ID into static snapshots */
625 SnapshotSetCommandId(currentCommandId);
628 * Make any catalog changes done by the just-completed command visible
629 * in the local syscache. We obviously don't need to do this after a
630 * read-only command. (But see hacks in inval.c to make real sure we
631 * don't think a command that queued inval messages was read-only.)
633 AtCommit_LocalCache();
637 * Make any other backends' catalog changes visible to me.
639 * XXX this is probably in the wrong place: CommandCounterIncrement should
640 * be purely a local operation, most likely. However fooling with this
641 * will affect asynchronous cross-backend interactions, which doesn't seem
642 * like a wise thing to do in late beta, so save improving this for
643 * another day - tgl 2007-11-30
651 * Interface routine to allow commands to force a synchronous commit of the
652 * current top-level transaction
655 ForceSyncCommit(void)
657 forceSyncCommit = true;
661 /* ----------------------------------------------------------------
662 * StartTransaction stuff
663 * ----------------------------------------------------------------
672 AcceptInvalidationMessages();
681 TransactionState s = CurrentTransactionState;
684 * If this is the first time through, create a private context for
685 * AbortTransaction to work in. By reserving some space now, we can
686 * insulate AbortTransaction from out-of-memory scenarios. Like
687 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
688 * size, so that space will be reserved immediately.
690 if (TransactionAbortContext == NULL)
691 TransactionAbortContext =
692 AllocSetContextCreate(TopMemoryContext,
693 "TransactionAbortContext",
699 * We shouldn't have a transaction context already.
701 Assert(TopTransactionContext == NULL);
704 * Create a toplevel context for the transaction.
706 TopTransactionContext =
707 AllocSetContextCreate(TopMemoryContext,
708 "TopTransactionContext",
709 ALLOCSET_DEFAULT_MINSIZE,
710 ALLOCSET_DEFAULT_INITSIZE,
711 ALLOCSET_DEFAULT_MAXSIZE);
714 * In a top-level transaction, CurTransactionContext is the same as
715 * TopTransactionContext.
717 CurTransactionContext = TopTransactionContext;
718 s->curTransactionContext = CurTransactionContext;
720 /* Make the CurTransactionContext active. */
721 MemoryContextSwitchTo(CurTransactionContext);
725 * AtStart_ResourceOwner
728 AtStart_ResourceOwner(void)
730 TransactionState s = CurrentTransactionState;
733 * We shouldn't have a transaction resource owner already.
735 Assert(TopTransactionResourceOwner == NULL);
738 * Create a toplevel resource owner for the transaction.
740 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
742 TopTransactionResourceOwner = s->curTransactionOwner;
743 CurTransactionResourceOwner = s->curTransactionOwner;
744 CurrentResourceOwner = s->curTransactionOwner;
747 /* ----------------------------------------------------------------
748 * StartSubTransaction stuff
749 * ----------------------------------------------------------------
756 AtSubStart_Memory(void)
758 TransactionState s = CurrentTransactionState;
760 Assert(CurTransactionContext != NULL);
763 * Create a CurTransactionContext, which will be used to hold data that
764 * survives subtransaction commit but disappears on subtransaction abort.
765 * We make it a child of the immediate parent's CurTransactionContext.
767 CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
768 "CurTransactionContext",
769 ALLOCSET_DEFAULT_MINSIZE,
770 ALLOCSET_DEFAULT_INITSIZE,
771 ALLOCSET_DEFAULT_MAXSIZE);
772 s->curTransactionContext = CurTransactionContext;
774 /* Make the CurTransactionContext active. */
775 MemoryContextSwitchTo(CurTransactionContext);
779 * AtSubStart_ResourceOwner
782 AtSubStart_ResourceOwner(void)
784 TransactionState s = CurrentTransactionState;
786 Assert(s->parent != NULL);
789 * Create a resource owner for the subtransaction. We make it a child of
790 * the immediate parent's resource owner.
792 s->curTransactionOwner =
793 ResourceOwnerCreate(s->parent->curTransactionOwner,
796 CurTransactionResourceOwner = s->curTransactionOwner;
797 CurrentResourceOwner = s->curTransactionOwner;
800 /* ----------------------------------------------------------------
801 * CommitTransaction stuff
802 * ----------------------------------------------------------------
806 * RecordTransactionCommit
808 * Returns latest XID among xact and its children, or InvalidTransactionId
809 * if the xact has no XID. (We compute that here just because it's easier.)
811 * This is exported only to support an ugly hack in VACUUM FULL.
814 RecordTransactionCommit(void)
816 TransactionId xid = GetTopTransactionIdIfAny();
817 bool markXidCommitted = TransactionIdIsValid(xid);
818 TransactionId latestXid = InvalidTransactionId;
823 TransactionId *children;
825 /* Get data needed for commit record */
826 nrels = smgrGetPendingDeletes(true, &rels, &haveNonTemp);
827 nchildren = xactGetCommittedChildren(&children);
830 * If we haven't been assigned an XID yet, we neither can, nor do we want
831 * to write a COMMIT record.
833 if (!markXidCommitted)
836 * We expect that every smgrscheduleunlink is followed by a catalog
837 * update, and hence XID assignment, so we shouldn't get here with any
838 * pending deletes. Use a real test not just an Assert to check this,
839 * since it's a bit fragile.
842 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
844 /* Can't have child XIDs either; AssignTransactionId enforces this */
845 Assert(nchildren == 0);
848 * If we didn't create XLOG entries, we're done here; otherwise we
849 * should flush those entries the same as a commit record. (An
850 * example of a possible record that wouldn't cause an XID to be
851 * assigned is a sequence advance record due to nextval() --- we want
852 * to flush that to disk before reporting commit.)
854 if (XactLastRecEnd.xrecoff == 0)
860 * Begin commit critical section and insert the commit XLOG record.
862 XLogRecData rdata[3];
864 xl_xact_commit xlrec;
866 /* Tell bufmgr and smgr to prepare for commit */
870 * Mark ourselves as within our "commit critical section". This
871 * forces any concurrent checkpoint to wait until we've updated
872 * pg_clog. Without this, it is possible for the checkpoint to set
873 * REDO after the XLOG record but fail to flush the pg_clog update to
874 * disk, leading to loss of the transaction commit if the system
875 * crashes a little later.
877 * Note: we could, but don't bother to, set this flag in
878 * RecordTransactionAbort. That's because loss of a transaction abort
879 * is noncritical; the presumption would be that it aborted, anyway.
881 * It's safe to change the inCommit flag of our own backend without
882 * holding the ProcArrayLock, since we're the only one modifying it.
883 * This makes checkpoint's determination of which xacts are inCommit a
884 * bit fuzzy, but it doesn't matter.
886 START_CRIT_SECTION();
887 MyProc->inCommit = true;
889 SetCurrentTransactionStopTimestamp();
890 xlrec.xact_time = xactStopTimestamp;
892 xlrec.nsubxacts = nchildren;
893 rdata[0].data = (char *) (&xlrec);
894 rdata[0].len = MinSizeOfXactCommit;
895 rdata[0].buffer = InvalidBuffer;
896 /* dump rels to delete */
899 rdata[0].next = &(rdata[1]);
900 rdata[1].data = (char *) rels;
901 rdata[1].len = nrels * sizeof(RelFileNode);
902 rdata[1].buffer = InvalidBuffer;
905 /* dump committed child Xids */
908 rdata[lastrdata].next = &(rdata[2]);
909 rdata[2].data = (char *) children;
910 rdata[2].len = nchildren * sizeof(TransactionId);
911 rdata[2].buffer = InvalidBuffer;
914 rdata[lastrdata].next = NULL;
916 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
920 * Check if we want to commit asynchronously. If the user has set
921 * synchronous_commit = off, and we're not doing cleanup of any non-temp
922 * rels nor committing any command that wanted to force sync commit, then
923 * we can defer flushing XLOG. (We must not allow asynchronous commit if
924 * there are any non-temp tables to be deleted, because we might delete
925 * the files before the COMMIT record is flushed to disk. We do allow
926 * asynchronous commit if all to-be-deleted tables are temporary though,
927 * since they are lost anyway if we crash.)
929 if (XactSyncCommit || forceSyncCommit || haveNonTemp)
932 * Synchronous commit case.
934 * Sleep before flush! So we can flush more than one commit records
935 * per single fsync. (The idea is some other backend may do the
936 * XLogFlush while we're sleeping. This needs work still, because on
937 * most Unixen, the minimum select() delay is 10msec or more, which is
940 * We do not sleep if enableFsync is not turned on, nor if there are
941 * fewer than CommitSiblings other backends with active transactions.
943 if (CommitDelay > 0 && enableFsync &&
944 CountActiveBackends() >= CommitSiblings)
945 pg_usleep(CommitDelay);
947 XLogFlush(XactLastRecEnd);
950 * Now we may update the CLOG, if we wrote a COMMIT record above
952 if (markXidCommitted)
953 TransactionIdCommitTree(xid, nchildren, children);
958 * Asynchronous commit case.
960 * Report the latest async commit LSN, so that the WAL writer knows to
963 XLogSetAsyncCommitLSN(XactLastRecEnd);
966 * We must not immediately update the CLOG, since we didn't flush the
967 * XLOG. Instead, we store the LSN up to which the XLOG must be
968 * flushed before the CLOG may be updated.
970 if (markXidCommitted)
971 TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
975 * If we entered a commit critical section, leave it now, and let
976 * checkpoints proceed.
978 if (markXidCommitted)
980 MyProc->inCommit = false;
984 /* Compute latestXid while we have the child XIDs handy */
985 latestXid = TransactionIdLatest(xid, nchildren, children);
987 /* Reset XactLastRecEnd until the next transaction writes something */
988 XactLastRecEnd.xrecoff = 0;
991 /* Clean up local data */
1000 * AtCommit_LocalCache
1003 AtCommit_LocalCache(void)
1006 * Make catalog changes visible to me for the next command.
1008 CommandEndInvalidationMessages();
1015 AtCommit_Memory(void)
1018 * Now that we're "out" of a transaction, have the system allocate things
1019 * in the top memory context instead of per-transaction contexts.
1021 MemoryContextSwitchTo(TopMemoryContext);
1024 * Release all transaction-local memory.
1026 Assert(TopTransactionContext != NULL);
1027 MemoryContextDelete(TopTransactionContext);
1028 TopTransactionContext = NULL;
1029 CurTransactionContext = NULL;
1030 CurrentTransactionState->curTransactionContext = NULL;
1033 /* ----------------------------------------------------------------
1034 * CommitSubTransaction stuff
1035 * ----------------------------------------------------------------
1039 * AtSubCommit_Memory
1042 AtSubCommit_Memory(void)
1044 TransactionState s = CurrentTransactionState;
1046 Assert(s->parent != NULL);
1048 /* Return to parent transaction level's memory context. */
1049 CurTransactionContext = s->parent->curTransactionContext;
1050 MemoryContextSwitchTo(CurTransactionContext);
1053 * Ordinarily we cannot throw away the child's CurTransactionContext,
1054 * since the data it contains will be needed at upper commit. However, if
1055 * there isn't actually anything in it, we can throw it away. This avoids
1056 * a small memory leak in the common case of "trivial" subxacts.
1058 if (MemoryContextIsEmpty(s->curTransactionContext))
1060 MemoryContextDelete(s->curTransactionContext);
1061 s->curTransactionContext = NULL;
1066 * AtSubCommit_childXids
1068 * Pass my own XID and my child XIDs up to my parent as committed children.
1071 AtSubCommit_childXids(void)
1073 TransactionState s = CurrentTransactionState;
1076 Assert(s->parent != NULL);
1079 * The parent childXids array will need to hold my XID and all my
1080 * childXids, in addition to the XIDs already there.
1082 new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1084 /* Allocate or enlarge the parent array if necessary */
1085 if (s->parent->maxChildXids < new_nChildXids)
1087 int new_maxChildXids;
1088 TransactionId *new_childXids;
1091 * Make it 2x what's needed right now, to avoid having to enlarge it
1092 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1093 * is what ensures that we don't need to worry about integer overflow
1094 * here or in the calculation of new_nChildXids.)
1096 new_maxChildXids = Min(new_nChildXids * 2,
1097 (int) (MaxAllocSize / sizeof(TransactionId)));
1099 if (new_maxChildXids < new_nChildXids)
1101 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1102 errmsg("maximum number of committed subtransactions (%d) exceeded",
1103 (int) (MaxAllocSize / sizeof(TransactionId)))));
1106 * We keep the child-XID arrays in TopTransactionContext; this avoids
1107 * setting up child-transaction contexts for what might be just a few
1108 * bytes of grandchild XIDs.
1110 if (s->parent->childXids == NULL)
1112 MemoryContextAlloc(TopTransactionContext,
1113 new_maxChildXids * sizeof(TransactionId));
1115 new_childXids = repalloc(s->parent->childXids,
1116 new_maxChildXids * sizeof(TransactionId));
1118 s->parent->childXids = new_childXids;
1119 s->parent->maxChildXids = new_maxChildXids;
1123 * Copy all my XIDs to parent's array.
1125 * Note: We rely on the fact that the XID of a child always follows that
1126 * of its parent. By copying the XID of this subtransaction before the
1127 * XIDs of its children, we ensure that the array stays ordered.
1128 * Likewise, all XIDs already in the array belong to subtransactions
1129 * started and subcommitted before us, so their XIDs must precede ours.
1131 s->parent->childXids[s->parent->nChildXids] = s->transactionId;
1133 if (s->nChildXids > 0)
1134 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1136 s->nChildXids * sizeof(TransactionId));
1138 s->parent->nChildXids = new_nChildXids;
1140 /* Release child's array to avoid leakage */
1141 if (s->childXids != NULL)
1142 pfree(s->childXids);
1143 /* We must reset these to avoid double-free if fail later in commit */
1144 s->childXids = NULL;
1146 s->maxChildXids = 0;
1149 /* ----------------------------------------------------------------
1150 * AbortTransaction stuff
1151 * ----------------------------------------------------------------
1155 * RecordTransactionAbort
1157 * Returns latest XID among xact and its children, or InvalidTransactionId
1158 * if the xact has no XID. (We compute that here just because it's easier.)
1160 static TransactionId
1161 RecordTransactionAbort(bool isSubXact)
1163 TransactionId xid = GetCurrentTransactionIdIfAny();
1164 TransactionId latestXid;
1168 TransactionId *children;
1169 XLogRecData rdata[3];
1171 xl_xact_abort xlrec;
1174 * If we haven't been assigned an XID, nobody will care whether we aborted
1175 * or not. Hence, we're done in that case. It does not matter if we have
1176 * rels to delete (note that this routine is not responsible for actually
1177 * deleting 'em). We cannot have any child XIDs, either.
1179 if (!TransactionIdIsValid(xid))
1181 /* Reset XactLastRecEnd until the next transaction writes something */
1183 XactLastRecEnd.xrecoff = 0;
1184 return InvalidTransactionId;
1188 * We have a valid XID, so we should write an ABORT record for it.
1190 * We do not flush XLOG to disk here, since the default assumption after a
1191 * crash would be that we aborted, anyway. For the same reason, we don't
1192 * need to worry about interlocking against checkpoint start.
1196 * Check that we haven't aborted halfway through RecordTransactionCommit.
1198 if (TransactionIdDidCommit(xid))
1199 elog(PANIC, "cannot abort transaction %u, it was already committed",
1202 /* Fetch the data we need for the abort record */
1203 nrels = smgrGetPendingDeletes(false, &rels, NULL);
1204 nchildren = xactGetCommittedChildren(&children);
1206 /* XXX do we really need a critical section here? */
1207 START_CRIT_SECTION();
1209 /* Write the ABORT record */
1211 xlrec.xact_time = GetCurrentTimestamp();
1214 SetCurrentTransactionStopTimestamp();
1215 xlrec.xact_time = xactStopTimestamp;
1217 xlrec.nrels = nrels;
1218 xlrec.nsubxacts = nchildren;
1219 rdata[0].data = (char *) (&xlrec);
1220 rdata[0].len = MinSizeOfXactAbort;
1221 rdata[0].buffer = InvalidBuffer;
1222 /* dump rels to delete */
1225 rdata[0].next = &(rdata[1]);
1226 rdata[1].data = (char *) rels;
1227 rdata[1].len = nrels * sizeof(RelFileNode);
1228 rdata[1].buffer = InvalidBuffer;
1231 /* dump committed child Xids */
1234 rdata[lastrdata].next = &(rdata[2]);
1235 rdata[2].data = (char *) children;
1236 rdata[2].len = nchildren * sizeof(TransactionId);
1237 rdata[2].buffer = InvalidBuffer;
1240 rdata[lastrdata].next = NULL;
1242 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
1245 * Mark the transaction aborted in clog. This is not absolutely necessary
1246 * but we may as well do it while we are here; also, in the subxact case
1247 * it is helpful because XactLockTableWait makes use of it to avoid
1248 * waiting for already-aborted subtransactions. It is OK to do it without
1249 * having flushed the ABORT record to disk, because in event of a crash
1250 * we'd be assumed to have aborted anyway.
1252 TransactionIdAbortTree(xid, nchildren, children);
1256 /* Compute latestXid while we have the child XIDs handy */
1257 latestXid = TransactionIdLatest(xid, nchildren, children);
1260 * If we're aborting a subtransaction, we can immediately remove failed
1261 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1262 * subxacts, because we already have the child XID array at hand. For
1263 * main xacts, the equivalent happens just after this function returns.
1266 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1268 /* Reset XactLastRecEnd until the next transaction writes something */
1270 XactLastRecEnd.xrecoff = 0;
1272 /* And clean up local data */
1283 AtAbort_Memory(void)
1286 * Switch into TransactionAbortContext, which should have some free space
1287 * even if nothing else does. We'll work in this context until we've
1288 * finished cleaning up.
1290 * It is barely possible to get here when we've not been able to create
1291 * TransactionAbortContext yet; if so use TopMemoryContext.
1293 if (TransactionAbortContext != NULL)
1294 MemoryContextSwitchTo(TransactionAbortContext);
1296 MemoryContextSwitchTo(TopMemoryContext);
1303 AtSubAbort_Memory(void)
1305 Assert(TransactionAbortContext != NULL);
1307 MemoryContextSwitchTo(TransactionAbortContext);
1312 * AtAbort_ResourceOwner
1315 AtAbort_ResourceOwner(void)
1318 * Make sure we have a valid ResourceOwner, if possible (else it will be
1319 * NULL, which is OK)
1321 CurrentResourceOwner = TopTransactionResourceOwner;
1325 * AtSubAbort_ResourceOwner
1328 AtSubAbort_ResourceOwner(void)
1330 TransactionState s = CurrentTransactionState;
1332 /* Make sure we have a valid ResourceOwner */
1333 CurrentResourceOwner = s->curTransactionOwner;
1338 * AtSubAbort_childXids
1341 AtSubAbort_childXids(void)
1343 TransactionState s = CurrentTransactionState;
1346 * We keep the child-XID arrays in TopTransactionContext (see
1347 * AtSubCommit_childXids). This means we'd better free the array
1348 * explicitly at abort to avoid leakage.
1350 if (s->childXids != NULL)
1351 pfree(s->childXids);
1352 s->childXids = NULL;
1354 s->maxChildXids = 0;
1357 /* ----------------------------------------------------------------
1358 * CleanupTransaction stuff
1359 * ----------------------------------------------------------------
1366 AtCleanup_Memory(void)
1368 Assert(CurrentTransactionState->parent == NULL);
1371 * Now that we're "out" of a transaction, have the system allocate things
1372 * in the top memory context instead of per-transaction contexts.
1374 MemoryContextSwitchTo(TopMemoryContext);
1377 * Clear the special abort context for next time.
1379 if (TransactionAbortContext != NULL)
1380 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1383 * Release all transaction-local memory.
1385 if (TopTransactionContext != NULL)
1386 MemoryContextDelete(TopTransactionContext);
1387 TopTransactionContext = NULL;
1388 CurTransactionContext = NULL;
1389 CurrentTransactionState->curTransactionContext = NULL;
1393 /* ----------------------------------------------------------------
1394 * CleanupSubTransaction stuff
1395 * ----------------------------------------------------------------
1399 * AtSubCleanup_Memory
1402 AtSubCleanup_Memory(void)
1404 TransactionState s = CurrentTransactionState;
1406 Assert(s->parent != NULL);
1408 /* Make sure we're not in an about-to-be-deleted context */
1409 MemoryContextSwitchTo(s->parent->curTransactionContext);
1410 CurTransactionContext = s->parent->curTransactionContext;
1413 * Clear the special abort context for next time.
1415 if (TransactionAbortContext != NULL)
1416 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1419 * Delete the subxact local memory contexts. Its CurTransactionContext can
1420 * go too (note this also kills CurTransactionContexts from any children
1423 if (s->curTransactionContext)
1424 MemoryContextDelete(s->curTransactionContext);
1425 s->curTransactionContext = NULL;
1428 /* ----------------------------------------------------------------
1429 * interface routines
1430 * ----------------------------------------------------------------
1437 StartTransaction(void)
1440 VirtualTransactionId vxid;
1443 * Let's just make sure the state stack is empty
1445 s = &TopTransactionStateData;
1446 CurrentTransactionState = s;
1449 * check the current transaction state
1451 if (s->state != TRANS_DEFAULT)
1452 elog(WARNING, "StartTransaction while in %s state",
1453 TransStateAsString(s->state));
1456 * set the current transaction state information appropriately during
1459 s->state = TRANS_START;
1460 s->transactionId = InvalidTransactionId; /* until assigned */
1463 * Make sure we've reset xact state variables
1465 XactIsoLevel = DefaultXactIsoLevel;
1466 XactReadOnly = DefaultXactReadOnly;
1467 forceSyncCommit = false;
1468 MyXactAccessedTempRel = false;
1471 * reinitialize within-transaction counters
1473 s->subTransactionId = TopSubTransactionId;
1474 currentSubTransactionId = TopSubTransactionId;
1475 currentCommandId = FirstCommandId;
1476 currentCommandIdUsed = false;
1479 * must initialize resource-management stuff first
1482 AtStart_ResourceOwner();
1485 * Assign a new LocalTransactionId, and combine it with the backendId to
1486 * form a virtual transaction id.
1488 vxid.backendId = MyBackendId;
1489 vxid.localTransactionId = GetNextLocalTransactionId();
1492 * Lock the virtual transaction id before we announce it in the proc array
1494 VirtualXactLockTableInsert(vxid);
1497 * Advertise it in the proc array. We assume assignment of
1498 * LocalTransactionID is atomic, and the backendId should be set already.
1500 Assert(MyProc->backendId == vxid.backendId);
1501 MyProc->lxid = vxid.localTransactionId;
1503 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
1506 * set transaction_timestamp() (a/k/a now()). We want this to be the same
1507 * as the first command's statement_timestamp(), so don't do a fresh
1508 * GetCurrentTimestamp() call (which'd be expensive anyway). Also, mark
1509 * xactStopTimestamp as unset.
1511 xactStartTimestamp = stmtStartTimestamp;
1512 xactStopTimestamp = 0;
1513 pgstat_report_xact_timestamp(xactStartTimestamp);
1516 * initialize current transaction state fields
1518 * note: prevXactReadOnly is not used at the outermost level
1520 s->nestingLevel = 1;
1521 s->gucNestLevel = 1;
1522 s->childXids = NULL;
1524 s->maxChildXids = 0;
1525 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
1526 /* SecurityRestrictionContext should never be set outside a transaction */
1527 Assert(s->prevSecContext == 0);
1530 * initialize other subsystems for new transaction
1535 AfterTriggerBeginXact();
1538 * done with start processing, set current transaction state to "in
1541 s->state = TRANS_INPROGRESS;
1543 ShowTransactionState("StartTransaction");
1550 * NB: if you change this routine, better look at PrepareTransaction too!
1553 CommitTransaction(void)
1555 TransactionState s = CurrentTransactionState;
1556 TransactionId latestXid;
1558 ShowTransactionState("CommitTransaction");
1561 * check the current transaction state
1563 if (s->state != TRANS_INPROGRESS)
1564 elog(WARNING, "CommitTransaction while in %s state",
1565 TransStateAsString(s->state));
1566 Assert(s->parent == NULL);
1569 * Do pre-commit processing (most of this stuff requires database access,
1570 * and in fact could still cause an error...)
1572 * It is possible for CommitHoldablePortals to invoke functions that queue
1573 * deferred triggers, and it's also possible that triggers create holdable
1574 * cursors. So we have to loop until there's nothing left to do.
1579 * Fire all currently pending deferred triggers.
1581 AfterTriggerFireDeferred();
1584 * Convert any open holdable cursors into static portals. If there
1585 * weren't any, we are done ... otherwise loop back to check if they
1586 * queued deferred triggers. Lather, rinse, repeat.
1588 if (!CommitHoldablePortals())
1592 /* Now we can shut down the deferred-trigger manager */
1593 AfterTriggerEndXact(true);
1595 /* Close any open regular cursors */
1599 * Let ON COMMIT management do its thing (must happen after closing
1600 * cursors, to avoid dangling-reference problems)
1602 PreCommit_on_commit_actions();
1604 /* close large objects before lower-level cleanup */
1605 AtEOXact_LargeObject(true);
1607 /* NOTIFY commit must come before lower-level cleanup */
1610 /* Prevent cancel/die interrupt while cleaning up */
1614 * set the current transaction state information appropriately during
1617 s->state = TRANS_COMMIT;
1620 * Here is where we really truly commit.
1622 latestXid = RecordTransactionCommit();
1624 TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
1627 * Let others know about no transaction in progress by me. Note that this
1628 * must be done _before_ releasing locks we hold and _after_
1629 * RecordTransactionCommit.
1631 ProcArrayEndTransaction(MyProc, latestXid);
1634 * This is all post-commit cleanup. Note that if an error is raised here,
1635 * it's too late to abort the transaction. This should be just
1636 * noncritical resource releasing.
1638 * The ordering of operations is not entirely random. The idea is:
1639 * release resources visible to other backends (eg, files, buffer pins);
1640 * then release locks; then release backend-local resources. We want to
1641 * release locks at the point where any backend waiting for us will see
1642 * our transaction as being fully cleaned up.
1644 * Resources that can be associated with individual queries are handled by
1645 * the ResourceOwner mechanism. The other calls here are for backend-wide
1649 CallXactCallbacks(XACT_EVENT_COMMIT);
1651 ResourceOwnerRelease(TopTransactionResourceOwner,
1652 RESOURCE_RELEASE_BEFORE_LOCKS,
1655 /* Check we've released all buffer pins */
1656 AtEOXact_Buffers(true);
1658 /* Clean up the relation cache */
1659 AtEOXact_RelationCache(true);
1661 /* Clean up the snapshot manager */
1662 AtEarlyCommit_Snapshot();
1665 * Make catalog changes visible to all backends. This has to happen after
1666 * relcache references are dropped (see comments for
1667 * AtEOXact_RelationCache), but before locks are released (if anyone is
1668 * waiting for lock on a relation we've modified, we want them to know
1669 * about the catalog change before they start using the relation).
1671 AtEOXact_Inval(true);
1674 * Likewise, dropping of files deleted during the transaction is best done
1675 * after releasing relcache and buffer pins. (This is not strictly
1676 * necessary during commit, since such pins should have been released
1677 * already, but this ordering is definitely critical during abort.)
1679 smgrDoPendingDeletes(true);
1681 AtEOXact_MultiXact();
1683 ResourceOwnerRelease(TopTransactionResourceOwner,
1684 RESOURCE_RELEASE_LOCKS,
1686 ResourceOwnerRelease(TopTransactionResourceOwner,
1687 RESOURCE_RELEASE_AFTER_LOCKS,
1690 /* Check we've released all catcache entries */
1691 AtEOXact_CatCache(true);
1693 AtEOXact_GUC(true, 1);
1695 AtEOXact_on_commit_actions(true);
1696 AtEOXact_Namespace(true);
1697 /* smgrcommit already done */
1699 AtEOXact_ComboCid();
1700 AtEOXact_HashTables(true);
1701 AtEOXact_PgStat(true);
1702 AtEOXact_Snapshot(true);
1703 pgstat_report_xact_timestamp(0);
1705 CurrentResourceOwner = NULL;
1706 ResourceOwnerDelete(TopTransactionResourceOwner);
1707 s->curTransactionOwner = NULL;
1708 CurTransactionResourceOwner = NULL;
1709 TopTransactionResourceOwner = NULL;
1713 s->transactionId = InvalidTransactionId;
1714 s->subTransactionId = InvalidSubTransactionId;
1715 s->nestingLevel = 0;
1716 s->gucNestLevel = 0;
1717 s->childXids = NULL;
1719 s->maxChildXids = 0;
1722 * done with commit processing, set current transaction state back to
1725 s->state = TRANS_DEFAULT;
1727 RESUME_INTERRUPTS();
1732 * PrepareTransaction
1734 * NB: if you change this routine, better look at CommitTransaction too!
1737 PrepareTransaction(void)
1739 TransactionState s = CurrentTransactionState;
1740 TransactionId xid = GetCurrentTransactionId();
1741 GlobalTransaction gxact;
1742 TimestampTz prepared_at;
1744 ShowTransactionState("PrepareTransaction");
1747 * check the current transaction state
1749 if (s->state != TRANS_INPROGRESS)
1750 elog(WARNING, "PrepareTransaction while in %s state",
1751 TransStateAsString(s->state));
1752 Assert(s->parent == NULL);
1755 * Do pre-commit processing (most of this stuff requires database access,
1756 * and in fact could still cause an error...)
1758 * It is possible for PrepareHoldablePortals to invoke functions that
1759 * queue deferred triggers, and it's also possible that triggers create
1760 * holdable cursors. So we have to loop until there's nothing left to do.
1765 * Fire all currently pending deferred triggers.
1767 AfterTriggerFireDeferred();
1770 * Convert any open holdable cursors into static portals. If there
1771 * weren't any, we are done ... otherwise loop back to check if they
1772 * queued deferred triggers. Lather, rinse, repeat.
1774 if (!PrepareHoldablePortals())
1778 /* Now we can shut down the deferred-trigger manager */
1779 AfterTriggerEndXact(true);
1781 /* Close any open regular cursors */
1785 * Let ON COMMIT management do its thing (must happen after closing
1786 * cursors, to avoid dangling-reference problems)
1788 PreCommit_on_commit_actions();
1790 /* close large objects before lower-level cleanup */
1791 AtEOXact_LargeObject(true);
1793 /* NOTIFY will be handled below */
1796 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
1797 * this transaction. Having the prepared xact hold locks on another
1798 * backend's temp table seems a bad idea --- for instance it would prevent
1799 * the backend from exiting. There are other problems too, such as how to
1800 * clean up the source backend's local buffers and ON COMMIT state if the
1801 * prepared xact includes a DROP of a temp table.
1803 * We must check this after executing any ON COMMIT actions, because they
1804 * might still access a temp relation.
1806 * XXX In principle this could be relaxed to allow some useful special
1807 * cases, such as a temp table created and dropped all within the
1808 * transaction. That seems to require much more bookkeeping though.
1810 if (MyXactAccessedTempRel)
1812 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1813 errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
1815 /* Prevent cancel/die interrupt while cleaning up */
1819 * set the current transaction state information appropriately during
1820 * prepare processing
1822 s->state = TRANS_PREPARE;
1824 prepared_at = GetCurrentTimestamp();
1826 /* Tell bufmgr and smgr to prepare for commit */
1830 * Reserve the GID for this transaction. This could fail if the requested
1831 * GID is invalid or already in use.
1833 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
1834 GetUserId(), MyDatabaseId);
1838 * Collect data for the 2PC state file. Note that in general, no actual
1839 * state change should happen in the called modules during this step,
1840 * since it's still possible to fail before commit, and in that case we
1841 * want transaction abort to be able to clean up. (In particular, the
1842 * AtPrepare routines may error out if they find cases they cannot
1843 * handle.) State cleanup should happen in the PostPrepare routines
1844 * below. However, some modules can go ahead and clear state here because
1845 * they wouldn't do anything with it during abort anyway.
1847 * Note: because the 2PC state file records will be replayed in the same
1848 * order they are made, the order of these calls has to match the order in
1849 * which we want things to happen during COMMIT PREPARED or ROLLBACK
1850 * PREPARED; in particular, pay attention to whether things should happen
1851 * before or after releasing the transaction's locks.
1853 StartPrepare(gxact);
1859 AtPrepare_MultiXact();
1862 * Here is where we really truly prepare.
1864 * We have to record transaction prepares even if we didn't make any
1865 * updates, because the transaction manager might get confused if we lose
1866 * a global transaction.
1871 * Now we clean up backend-internal state and release internal resources.
1874 /* Reset XactLastRecEnd until the next transaction writes something */
1875 XactLastRecEnd.xrecoff = 0;
1878 * Let others know about no transaction in progress by me. This has to be
1879 * done *after* the prepared transaction has been marked valid, else
1880 * someone may think it is unlocked and recyclable.
1882 ProcArrayClearTransaction(MyProc);
1885 * This is all post-transaction cleanup. Note that if an error is raised
1886 * here, it's too late to abort the transaction. This should be just
1887 * noncritical resource releasing. See notes in CommitTransaction.
1890 CallXactCallbacks(XACT_EVENT_PREPARE);
1892 ResourceOwnerRelease(TopTransactionResourceOwner,
1893 RESOURCE_RELEASE_BEFORE_LOCKS,
1896 /* Check we've released all buffer pins */
1897 AtEOXact_Buffers(true);
1899 /* Clean up the relation cache */
1900 AtEOXact_RelationCache(true);
1902 /* Clean up the snapshot manager */
1903 AtEarlyCommit_Snapshot();
1905 /* notify doesn't need a postprepare call */
1907 PostPrepare_PgStat();
1909 PostPrepare_Inval();
1913 PostPrepare_MultiXact(xid);
1915 PostPrepare_Locks(xid);
1917 ResourceOwnerRelease(TopTransactionResourceOwner,
1918 RESOURCE_RELEASE_LOCKS,
1920 ResourceOwnerRelease(TopTransactionResourceOwner,
1921 RESOURCE_RELEASE_AFTER_LOCKS,
1924 /* Check we've released all catcache entries */
1925 AtEOXact_CatCache(true);
1927 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
1928 AtEOXact_GUC(true, 1);
1930 AtEOXact_on_commit_actions(true);
1931 AtEOXact_Namespace(true);
1932 /* smgrcommit already done */
1934 AtEOXact_ComboCid();
1935 AtEOXact_HashTables(true);
1936 /* don't call AtEOXact_PgStat here */
1937 AtEOXact_Snapshot(true);
1939 CurrentResourceOwner = NULL;
1940 ResourceOwnerDelete(TopTransactionResourceOwner);
1941 s->curTransactionOwner = NULL;
1942 CurTransactionResourceOwner = NULL;
1943 TopTransactionResourceOwner = NULL;
1947 s->transactionId = InvalidTransactionId;
1948 s->subTransactionId = InvalidSubTransactionId;
1949 s->nestingLevel = 0;
1950 s->gucNestLevel = 0;
1951 s->childXids = NULL;
1953 s->maxChildXids = 0;
1956 * done with 1st phase commit processing, set current transaction state
1959 s->state = TRANS_DEFAULT;
1961 RESUME_INTERRUPTS();
1969 AbortTransaction(void)
1971 TransactionState s = CurrentTransactionState;
1972 TransactionId latestXid;
1974 /* Prevent cancel/die interrupt while cleaning up */
1977 /* Make sure we have a valid memory context and resource owner */
1979 AtAbort_ResourceOwner();
1982 * Release any LW locks we might be holding as quickly as possible.
1983 * (Regular locks, however, must be held till we finish aborting.)
1984 * Releasing LW locks is critical since we might try to grab them again
1985 * while cleaning up!
1989 /* Clean up buffer I/O and buffer context locks, too */
1994 * Also clean up any open wait for lock, since the lock manager will choke
1995 * if we try to wait for another lock before doing this.
2000 * check the current transaction state
2002 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2003 elog(WARNING, "AbortTransaction while in %s state",
2004 TransStateAsString(s->state));
2005 Assert(s->parent == NULL);
2008 * set the current transaction state information appropriately during the
2011 s->state = TRANS_ABORT;
2014 * Reset user ID which might have been changed transiently. We need this
2015 * to clean up in case control escaped out of a SECURITY DEFINER function
2016 * or other local change of CurrentUserId; therefore, the prior value of
2017 * SecurityRestrictionContext also needs to be restored.
2019 * (Note: it is not necessary to restore session authorization or role
2020 * settings here because those can only be changed via GUC, and GUC will
2021 * take care of rolling them back if need be.)
2023 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
2026 * do abort processing
2028 AfterTriggerEndXact(false);
2030 AtEOXact_LargeObject(false); /* 'false' means it's abort */
2034 * Advertise the fact that we aborted in pg_clog (assuming that we got as
2035 * far as assigning an XID to advertise).
2037 latestXid = RecordTransactionAbort(false);
2039 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
2042 * Let others know about no transaction in progress by me. Note that this
2043 * must be done _before_ releasing locks we hold and _after_
2044 * RecordTransactionAbort.
2046 ProcArrayEndTransaction(MyProc, latestXid);
2049 * Post-abort cleanup. See notes in CommitTransaction() concerning
2053 CallXactCallbacks(XACT_EVENT_ABORT);
2055 ResourceOwnerRelease(TopTransactionResourceOwner,
2056 RESOURCE_RELEASE_BEFORE_LOCKS,
2058 AtEOXact_Buffers(false);
2059 AtEOXact_RelationCache(false);
2060 AtEOXact_Inval(false);
2061 smgrDoPendingDeletes(false);
2062 AtEOXact_MultiXact();
2063 ResourceOwnerRelease(TopTransactionResourceOwner,
2064 RESOURCE_RELEASE_LOCKS,
2066 ResourceOwnerRelease(TopTransactionResourceOwner,
2067 RESOURCE_RELEASE_AFTER_LOCKS,
2069 AtEOXact_CatCache(false);
2071 AtEOXact_GUC(false, 1);
2072 AtEOXact_SPI(false);
2073 AtEOXact_on_commit_actions(false);
2074 AtEOXact_Namespace(false);
2076 AtEOXact_ComboCid();
2077 AtEOXact_HashTables(false);
2078 AtEOXact_PgStat(false);
2079 AtEOXact_Snapshot(false);
2080 pgstat_report_xact_timestamp(0);
2083 * State remains TRANS_ABORT until CleanupTransaction().
2085 RESUME_INTERRUPTS();
2089 * CleanupTransaction
2092 CleanupTransaction(void)
2094 TransactionState s = CurrentTransactionState;
2097 * State should still be TRANS_ABORT from AbortTransaction().
2099 if (s->state != TRANS_ABORT)
2100 elog(FATAL, "CleanupTransaction: unexpected state %s",
2101 TransStateAsString(s->state));
2104 * do abort cleanup processing
2106 AtCleanup_Portals(); /* now safe to release portal memory */
2108 CurrentResourceOwner = NULL; /* and resource owner */
2109 if (TopTransactionResourceOwner)
2110 ResourceOwnerDelete(TopTransactionResourceOwner);
2111 s->curTransactionOwner = NULL;
2112 CurTransactionResourceOwner = NULL;
2113 TopTransactionResourceOwner = NULL;
2115 AtCleanup_Memory(); /* and transaction memory */
2117 s->transactionId = InvalidTransactionId;
2118 s->subTransactionId = InvalidSubTransactionId;
2119 s->nestingLevel = 0;
2120 s->gucNestLevel = 0;
2121 s->childXids = NULL;
2123 s->maxChildXids = 0;
2126 * done with abort processing, set current transaction state back to
2129 s->state = TRANS_DEFAULT;
2133 * StartTransactionCommand
2136 StartTransactionCommand(void)
2138 TransactionState s = CurrentTransactionState;
2140 switch (s->blockState)
2143 * if we aren't in a transaction block, we just do our usual start
2146 case TBLOCK_DEFAULT:
2148 s->blockState = TBLOCK_STARTED;
2152 * We are somewhere in a transaction block or subtransaction and
2153 * about to start a new command. For now we do nothing, but
2154 * someday we may do command-local resource initialization. (Note
2155 * that any needed CommandCounterIncrement was done by the
2156 * previous CommitTransactionCommand.)
2158 case TBLOCK_INPROGRESS:
2159 case TBLOCK_SUBINPROGRESS:
2163 * Here we are in a failed transaction block (one of the commands
2164 * caused an abort) so we do nothing but remain in the abort
2165 * state. Eventually we will get a ROLLBACK command which will
2166 * get us out of this state. (It is up to other code to ensure
2167 * that no commands other than ROLLBACK will be processed in these
2171 case TBLOCK_SUBABORT:
2174 /* These cases are invalid. */
2175 case TBLOCK_STARTED:
2177 case TBLOCK_SUBBEGIN:
2180 case TBLOCK_ABORT_END:
2181 case TBLOCK_SUBABORT_END:
2182 case TBLOCK_ABORT_PENDING:
2183 case TBLOCK_SUBABORT_PENDING:
2184 case TBLOCK_SUBRESTART:
2185 case TBLOCK_SUBABORT_RESTART:
2186 case TBLOCK_PREPARE:
2187 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2188 BlockStateAsString(s->blockState));
2193 * We must switch to CurTransactionContext before returning. This is
2194 * already done if we called StartTransaction, otherwise not.
2196 Assert(CurTransactionContext != NULL);
2197 MemoryContextSwitchTo(CurTransactionContext);
2201 * CommitTransactionCommand
2204 CommitTransactionCommand(void)
2206 TransactionState s = CurrentTransactionState;
2208 switch (s->blockState)
2211 * This shouldn't happen, because it means the previous
2212 * StartTransactionCommand didn't set the STARTED state
2215 case TBLOCK_DEFAULT:
2216 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2217 BlockStateAsString(s->blockState));
2221 * If we aren't in a transaction block, just do our usual
2222 * transaction commit, and return to the idle state.
2224 case TBLOCK_STARTED:
2225 CommitTransaction();
2226 s->blockState = TBLOCK_DEFAULT;
2230 * We are completing a "BEGIN TRANSACTION" command, so we change
2231 * to the "transaction block in progress" state and return. (We
2232 * assume the BEGIN did nothing to the database, so we need no
2233 * CommandCounterIncrement.)
2236 s->blockState = TBLOCK_INPROGRESS;
2240 * This is the case when we have finished executing a command
2241 * someplace within a transaction block. We increment the command
2242 * counter and return.
2244 case TBLOCK_INPROGRESS:
2245 case TBLOCK_SUBINPROGRESS:
2246 CommandCounterIncrement();
2250 * We are completing a "COMMIT" command. Do it and return to the
2254 CommitTransaction();
2255 s->blockState = TBLOCK_DEFAULT;
2259 * Here we are in the middle of a transaction block but one of the
2260 * commands caused an abort so we do nothing but remain in the
2261 * abort state. Eventually we will get a ROLLBACK comand.
2264 case TBLOCK_SUBABORT:
2268 * Here we were in an aborted transaction block and we just got
2269 * the ROLLBACK command from the user, so clean up the
2270 * already-aborted transaction and return to the idle state.
2272 case TBLOCK_ABORT_END:
2273 CleanupTransaction();
2274 s->blockState = TBLOCK_DEFAULT;
2278 * Here we were in a perfectly good transaction block but the user
2279 * told us to ROLLBACK anyway. We have to abort the transaction
2280 * and then clean up.
2282 case TBLOCK_ABORT_PENDING:
2284 CleanupTransaction();
2285 s->blockState = TBLOCK_DEFAULT;
2289 * We are completing a "PREPARE TRANSACTION" command. Do it and
2290 * return to the idle state.
2292 case TBLOCK_PREPARE:
2293 PrepareTransaction();
2294 s->blockState = TBLOCK_DEFAULT;
2298 * We were just issued a SAVEPOINT inside a transaction block.
2299 * Start a subtransaction. (DefineSavepoint already did
2300 * PushTransaction, so as to have someplace to put the SUBBEGIN
2303 case TBLOCK_SUBBEGIN:
2304 StartSubTransaction();
2305 s->blockState = TBLOCK_SUBINPROGRESS;
2309 * We were issued a COMMIT or RELEASE command, so we end the
2310 * current subtransaction and return to the parent transaction.
2311 * The parent might be ended too, so repeat till we are all the
2312 * way out or find an INPROGRESS transaction.
2317 CommitSubTransaction();
2318 s = CurrentTransactionState; /* changed by pop */
2319 } while (s->blockState == TBLOCK_SUBEND);
2320 /* If we had a COMMIT command, finish off the main xact too */
2321 if (s->blockState == TBLOCK_END)
2323 Assert(s->parent == NULL);
2324 CommitTransaction();
2325 s->blockState = TBLOCK_DEFAULT;
2327 else if (s->blockState == TBLOCK_PREPARE)
2329 Assert(s->parent == NULL);
2330 PrepareTransaction();
2331 s->blockState = TBLOCK_DEFAULT;
2335 Assert(s->blockState == TBLOCK_INPROGRESS ||
2336 s->blockState == TBLOCK_SUBINPROGRESS);
2341 * The current already-failed subtransaction is ending due to a
2342 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2343 * examine the parent (which could be in any of several states).
2345 case TBLOCK_SUBABORT_END:
2346 CleanupSubTransaction();
2347 CommitTransactionCommand();
2351 * As above, but it's not dead yet, so abort first.
2353 case TBLOCK_SUBABORT_PENDING:
2354 AbortSubTransaction();
2355 CleanupSubTransaction();
2356 CommitTransactionCommand();
2360 * The current subtransaction is the target of a ROLLBACK TO
2361 * command. Abort and pop it, then start a new subtransaction
2362 * with the same name.
2364 case TBLOCK_SUBRESTART:
2369 /* save name and keep Cleanup from freeing it */
2372 savepointLevel = s->savepointLevel;
2374 AbortSubTransaction();
2375 CleanupSubTransaction();
2377 DefineSavepoint(NULL);
2378 s = CurrentTransactionState; /* changed by push */
2380 s->savepointLevel = savepointLevel;
2382 /* This is the same as TBLOCK_SUBBEGIN case */
2383 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2384 StartSubTransaction();
2385 s->blockState = TBLOCK_SUBINPROGRESS;
2390 * Same as above, but the subtransaction had already failed, so we
2391 * don't need AbortSubTransaction.
2393 case TBLOCK_SUBABORT_RESTART:
2398 /* save name and keep Cleanup from freeing it */
2401 savepointLevel = s->savepointLevel;
2403 CleanupSubTransaction();
2405 DefineSavepoint(NULL);
2406 s = CurrentTransactionState; /* changed by push */
2408 s->savepointLevel = savepointLevel;
2410 /* This is the same as TBLOCK_SUBBEGIN case */
2411 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2412 StartSubTransaction();
2413 s->blockState = TBLOCK_SUBINPROGRESS;
2420 * AbortCurrentTransaction
2423 AbortCurrentTransaction(void)
2425 TransactionState s = CurrentTransactionState;
2427 switch (s->blockState)
2429 case TBLOCK_DEFAULT:
2430 if (s->state == TRANS_DEFAULT)
2432 /* we are idle, so nothing to do */
2437 * We can get here after an error during transaction start
2438 * (state will be TRANS_START). Need to clean up the
2439 * incompletely started transaction. First, adjust the
2440 * low-level state to suppress warning message from
2443 if (s->state == TRANS_START)
2444 s->state = TRANS_INPROGRESS;
2446 CleanupTransaction();
2451 * if we aren't in a transaction block, we just do the basic abort
2452 * & cleanup transaction.
2454 case TBLOCK_STARTED:
2456 CleanupTransaction();
2457 s->blockState = TBLOCK_DEFAULT;
2461 * If we are in TBLOCK_BEGIN it means something screwed up right
2462 * after reading "BEGIN TRANSACTION". We assume that the user
2463 * will interpret the error as meaning the BEGIN failed to get him
2464 * into a transaction block, so we should abort and return to idle
2469 CleanupTransaction();
2470 s->blockState = TBLOCK_DEFAULT;
2474 * We are somewhere in a transaction block and we've gotten a
2475 * failure, so we abort the transaction and set up the persistent
2476 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
2478 case TBLOCK_INPROGRESS:
2480 s->blockState = TBLOCK_ABORT;
2481 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
2485 * Here, we failed while trying to COMMIT. Clean up the
2486 * transaction and return to idle state (we do not want to stay in
2491 CleanupTransaction();
2492 s->blockState = TBLOCK_DEFAULT;
2496 * Here, we are already in an aborted transaction state and are
2497 * waiting for a ROLLBACK, but for some reason we failed again! So
2498 * we just remain in the abort state.
2501 case TBLOCK_SUBABORT:
2505 * We are in a failed transaction and we got the ROLLBACK command.
2506 * We have already aborted, we just need to cleanup and go to idle
2509 case TBLOCK_ABORT_END:
2510 CleanupTransaction();
2511 s->blockState = TBLOCK_DEFAULT;
2515 * We are in a live transaction and we got a ROLLBACK command.
2516 * Abort, cleanup, go to idle state.
2518 case TBLOCK_ABORT_PENDING:
2520 CleanupTransaction();
2521 s->blockState = TBLOCK_DEFAULT;
2525 * Here, we failed while trying to PREPARE. Clean up the
2526 * transaction and return to idle state (we do not want to stay in
2529 case TBLOCK_PREPARE:
2531 CleanupTransaction();
2532 s->blockState = TBLOCK_DEFAULT;
2536 * We got an error inside a subtransaction. Abort just the
2537 * subtransaction, and go to the persistent SUBABORT state until
2540 case TBLOCK_SUBINPROGRESS:
2541 AbortSubTransaction();
2542 s->blockState = TBLOCK_SUBABORT;
2546 * If we failed while trying to create a subtransaction, clean up
2547 * the broken subtransaction and abort the parent. The same
2548 * applies if we get a failure while ending a subtransaction.
2550 case TBLOCK_SUBBEGIN:
2552 case TBLOCK_SUBABORT_PENDING:
2553 case TBLOCK_SUBRESTART:
2554 AbortSubTransaction();
2555 CleanupSubTransaction();
2556 AbortCurrentTransaction();
2560 * Same as above, except the Abort() was already done.
2562 case TBLOCK_SUBABORT_END:
2563 case TBLOCK_SUBABORT_RESTART:
2564 CleanupSubTransaction();
2565 AbortCurrentTransaction();
2571 * PreventTransactionChain
2573 * This routine is to be called by statements that must not run inside
2574 * a transaction block, typically because they have non-rollback-able
2575 * side effects or do internal commits.
2577 * If we have already started a transaction block, issue an error; also issue
2578 * an error if we appear to be running inside a user-defined function (which
2579 * could issue more commands and possibly cause a failure after the statement
2580 * completes). Subtransactions are verboten too.
2582 * isTopLevel: passed down from ProcessUtility to determine whether we are
2583 * inside a function or multi-query querystring. (We will always fail if
2584 * this is false, but it's convenient to centralize the check here instead of
2585 * making callers do it.)
2586 * stmtType: statement type name, for error messages.
2589 PreventTransactionChain(bool isTopLevel, const char *stmtType)
2592 * xact block already started?
2594 if (IsTransactionBlock())
2596 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2597 /* translator: %s represents an SQL statement name */
2598 errmsg("%s cannot run inside a transaction block",
2604 if (IsSubTransaction())
2606 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2607 /* translator: %s represents an SQL statement name */
2608 errmsg("%s cannot run inside a subtransaction",
2612 * inside a function call?
2616 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2617 /* translator: %s represents an SQL statement name */
2618 errmsg("%s cannot be executed from a function or multi-command string",
2621 /* If we got past IsTransactionBlock test, should be in default state */
2622 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2623 CurrentTransactionState->blockState != TBLOCK_STARTED)
2624 elog(FATAL, "cannot prevent transaction chain");
2629 * RequireTransactionChain
2631 * This routine is to be called by statements that must run inside
2632 * a transaction block, because they have no effects that persist past
2633 * transaction end (and so calling them outside a transaction block
2634 * is presumably an error). DECLARE CURSOR is an example.
2636 * If we appear to be running inside a user-defined function, we do not
2637 * issue an error, since the function could issue more commands that make
2638 * use of the current statement's results. Likewise subtransactions.
2639 * Thus this is an inverse for PreventTransactionChain.
2641 * isTopLevel: passed down from ProcessUtility to determine whether we are
2642 * inside a function.
2643 * stmtType: statement type name, for error messages.
2646 RequireTransactionChain(bool isTopLevel, const char *stmtType)
2649 * xact block already started?
2651 if (IsTransactionBlock())
2657 if (IsSubTransaction())
2661 * inside a function call?
2667 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2668 /* translator: %s represents an SQL statement name */
2669 errmsg("%s can only be used in transaction blocks",
2674 * IsInTransactionChain
2676 * This routine is for statements that need to behave differently inside
2677 * a transaction block than when running as single commands. ANALYZE is
2678 * currently the only example.
2680 * isTopLevel: passed down from ProcessUtility to determine whether we are
2681 * inside a function.
2684 IsInTransactionChain(bool isTopLevel)
2687 * Return true on same conditions that would make PreventTransactionChain
2690 if (IsTransactionBlock())
2693 if (IsSubTransaction())
2699 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2700 CurrentTransactionState->blockState != TBLOCK_STARTED)
2708 * Register or deregister callback functions for start- and end-of-xact
2711 * These functions are intended for use by dynamically loaded modules.
2712 * For built-in modules we generally just hardwire the appropriate calls
2713 * (mainly because it's easier to control the order that way, where needed).
2715 * At transaction end, the callback occurs post-commit or post-abort, so the
2716 * callback functions can only do noncritical cleanup.
2719 RegisterXactCallback(XactCallback callback, void *arg)
2721 XactCallbackItem *item;
2723 item = (XactCallbackItem *)
2724 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
2725 item->callback = callback;
2727 item->next = Xact_callbacks;
2728 Xact_callbacks = item;
2732 UnregisterXactCallback(XactCallback callback, void *arg)
2734 XactCallbackItem *item;
2735 XactCallbackItem *prev;
2738 for (item = Xact_callbacks; item; prev = item, item = item->next)
2740 if (item->callback == callback && item->arg == arg)
2743 prev->next = item->next;
2745 Xact_callbacks = item->next;
2753 CallXactCallbacks(XactEvent event)
2755 XactCallbackItem *item;
2757 for (item = Xact_callbacks; item; item = item->next)
2758 (*item->callback) (event, item->arg);
2763 * Register or deregister callback functions for start- and end-of-subxact
2766 * Pretty much same as above, but for subtransaction events.
2768 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
2769 * so the callback functions can only do noncritical cleanup. At
2770 * subtransaction start, the callback is called when the subtransaction has
2771 * finished initializing.
2774 RegisterSubXactCallback(SubXactCallback callback, void *arg)
2776 SubXactCallbackItem *item;
2778 item = (SubXactCallbackItem *)
2779 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
2780 item->callback = callback;
2782 item->next = SubXact_callbacks;
2783 SubXact_callbacks = item;
2787 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
2789 SubXactCallbackItem *item;
2790 SubXactCallbackItem *prev;
2793 for (item = SubXact_callbacks; item; prev = item, item = item->next)
2795 if (item->callback == callback && item->arg == arg)
2798 prev->next = item->next;
2800 SubXact_callbacks = item->next;
2808 CallSubXactCallbacks(SubXactEvent event,
2809 SubTransactionId mySubid,
2810 SubTransactionId parentSubid)
2812 SubXactCallbackItem *item;
2814 for (item = SubXact_callbacks; item; item = item->next)
2815 (*item->callback) (event, mySubid, parentSubid, item->arg);
2819 /* ----------------------------------------------------------------
2820 * transaction block support
2821 * ----------------------------------------------------------------
2825 * BeginTransactionBlock
2826 * This executes a BEGIN command.
2829 BeginTransactionBlock(void)
2831 TransactionState s = CurrentTransactionState;
2833 switch (s->blockState)
2836 * We are not inside a transaction block, so allow one to begin.
2838 case TBLOCK_STARTED:
2839 s->blockState = TBLOCK_BEGIN;
2843 * Already a transaction block in progress.
2845 case TBLOCK_INPROGRESS:
2846 case TBLOCK_SUBINPROGRESS:
2848 case TBLOCK_SUBABORT:
2850 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2851 errmsg("there is already a transaction in progress")));
2854 /* These cases are invalid. */
2855 case TBLOCK_DEFAULT:
2857 case TBLOCK_SUBBEGIN:
2860 case TBLOCK_ABORT_END:
2861 case TBLOCK_SUBABORT_END:
2862 case TBLOCK_ABORT_PENDING:
2863 case TBLOCK_SUBABORT_PENDING:
2864 case TBLOCK_SUBRESTART:
2865 case TBLOCK_SUBABORT_RESTART:
2866 case TBLOCK_PREPARE:
2867 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
2868 BlockStateAsString(s->blockState));
2874 * PrepareTransactionBlock
2875 * This executes a PREPARE command.
2877 * Since PREPARE may actually do a ROLLBACK, the result indicates what
2878 * happened: TRUE for PREPARE, FALSE for ROLLBACK.
2880 * Note that we don't actually do anything here except change blockState.
2881 * The real work will be done in the upcoming PrepareTransaction().
2882 * We do it this way because it's not convenient to change memory context,
2883 * resource owner, etc while executing inside a Portal.
2886 PrepareTransactionBlock(char *gid)
2891 /* Set up to commit the current transaction */
2892 result = EndTransactionBlock();
2894 /* If successful, change outer tblock state to PREPARE */
2897 s = CurrentTransactionState;
2899 while (s->parent != NULL)
2902 if (s->blockState == TBLOCK_END)
2904 /* Save GID where PrepareTransaction can find it again */
2905 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
2907 s->blockState = TBLOCK_PREPARE;
2912 * ignore case where we are not in a transaction;
2913 * EndTransactionBlock already issued a warning.
2915 Assert(s->blockState == TBLOCK_STARTED);
2916 /* Don't send back a PREPARE result tag... */
2925 * EndTransactionBlock
2926 * This executes a COMMIT command.
2928 * Since COMMIT may actually do a ROLLBACK, the result indicates what
2929 * happened: TRUE for COMMIT, FALSE for ROLLBACK.
2931 * Note that we don't actually do anything here except change blockState.
2932 * The real work will be done in the upcoming CommitTransactionCommand().
2933 * We do it this way because it's not convenient to change memory context,
2934 * resource owner, etc while executing inside a Portal.
2937 EndTransactionBlock(void)
2939 TransactionState s = CurrentTransactionState;
2940 bool result = false;
2942 switch (s->blockState)
2945 * We are in a transaction block, so tell CommitTransactionCommand
2948 case TBLOCK_INPROGRESS:
2949 s->blockState = TBLOCK_END;
2954 * We are in a failed transaction block. Tell
2955 * CommitTransactionCommand it's time to exit the block.
2958 s->blockState = TBLOCK_ABORT_END;
2962 * We are in a live subtransaction block. Set up to subcommit all
2963 * open subtransactions and then commit the main transaction.
2965 case TBLOCK_SUBINPROGRESS:
2966 while (s->parent != NULL)
2968 if (s->blockState == TBLOCK_SUBINPROGRESS)
2969 s->blockState = TBLOCK_SUBEND;
2971 elog(FATAL, "EndTransactionBlock: unexpected state %s",
2972 BlockStateAsString(s->blockState));
2975 if (s->blockState == TBLOCK_INPROGRESS)
2976 s->blockState = TBLOCK_END;
2978 elog(FATAL, "EndTransactionBlock: unexpected state %s",
2979 BlockStateAsString(s->blockState));
2984 * Here we are inside an aborted subtransaction. Treat the COMMIT
2985 * as ROLLBACK: set up to abort everything and exit the main
2988 case TBLOCK_SUBABORT:
2989 while (s->parent != NULL)
2991 if (s->blockState == TBLOCK_SUBINPROGRESS)
2992 s->blockState = TBLOCK_SUBABORT_PENDING;
2993 else if (s->blockState == TBLOCK_SUBABORT)
2994 s->blockState = TBLOCK_SUBABORT_END;
2996 elog(FATAL, "EndTransactionBlock: unexpected state %s",
2997 BlockStateAsString(s->blockState));
3000 if (s->blockState == TBLOCK_INPROGRESS)
3001 s->blockState = TBLOCK_ABORT_PENDING;
3002 else if (s->blockState == TBLOCK_ABORT)
3003 s->blockState = TBLOCK_ABORT_END;
3005 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3006 BlockStateAsString(s->blockState));
3010 * The user issued COMMIT when not inside a transaction. Issue a
3011 * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
3012 * CommitTransactionCommand() will then close the transaction and
3013 * put us back into the default state.
3015 case TBLOCK_STARTED:
3017 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3018 errmsg("there is no transaction in progress")));
3022 /* These cases are invalid. */
3023 case TBLOCK_DEFAULT:
3025 case TBLOCK_SUBBEGIN:
3028 case TBLOCK_ABORT_END:
3029 case TBLOCK_SUBABORT_END:
3030 case TBLOCK_ABORT_PENDING:
3031 case TBLOCK_SUBABORT_PENDING:
3032 case TBLOCK_SUBRESTART:
3033 case TBLOCK_SUBABORT_RESTART:
3034 case TBLOCK_PREPARE:
3035 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3036 BlockStateAsString(s->blockState));
3044 * UserAbortTransactionBlock
3045 * This executes a ROLLBACK command.
3047 * As above, we don't actually do anything here except change blockState.
3050 UserAbortTransactionBlock(void)
3052 TransactionState s = CurrentTransactionState;
3054 switch (s->blockState)
3057 * We are inside a transaction block and we got a ROLLBACK command
3058 * from the user, so tell CommitTransactionCommand to abort and
3059 * exit the transaction block.
3061 case TBLOCK_INPROGRESS:
3062 s->blockState = TBLOCK_ABORT_PENDING;
3066 * We are inside a failed transaction block and we got a ROLLBACK
3067 * command from the user. Abort processing is already done, so
3068 * CommitTransactionCommand just has to cleanup and go back to
3072 s->blockState = TBLOCK_ABORT_END;
3076 * We are inside a subtransaction. Mark everything up to top
3077 * level as exitable.
3079 case TBLOCK_SUBINPROGRESS:
3080 case TBLOCK_SUBABORT:
3081 while (s->parent != NULL)
3083 if (s->blockState == TBLOCK_SUBINPROGRESS)
3084 s->blockState = TBLOCK_SUBABORT_PENDING;
3085 else if (s->blockState == TBLOCK_SUBABORT)
3086 s->blockState = TBLOCK_SUBABORT_END;
3088 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3089 BlockStateAsString(s->blockState));
3092 if (s->blockState == TBLOCK_INPROGRESS)
3093 s->blockState = TBLOCK_ABORT_PENDING;
3094 else if (s->blockState == TBLOCK_ABORT)
3095 s->blockState = TBLOCK_ABORT_END;
3097 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3098 BlockStateAsString(s->blockState));
3102 * The user issued ABORT when not inside a transaction. Issue a
3103 * WARNING and go to abort state. The upcoming call to
3104 * CommitTransactionCommand() will then put us back into the
3107 case TBLOCK_STARTED:
3109 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3110 errmsg("there is no transaction in progress")));
3111 s->blockState = TBLOCK_ABORT_PENDING;
3114 /* These cases are invalid. */
3115 case TBLOCK_DEFAULT:
3117 case TBLOCK_SUBBEGIN:
3120 case TBLOCK_ABORT_END:
3121 case TBLOCK_SUBABORT_END:
3122 case TBLOCK_ABORT_PENDING:
3123 case TBLOCK_SUBABORT_PENDING:
3124 case TBLOCK_SUBRESTART:
3125 case TBLOCK_SUBABORT_RESTART:
3126 case TBLOCK_PREPARE:
3127 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3128 BlockStateAsString(s->blockState));
3135 * This executes a SAVEPOINT command.
3138 DefineSavepoint(char *name)
3140 TransactionState s = CurrentTransactionState;
3142 switch (s->blockState)
3144 case TBLOCK_INPROGRESS:
3145 case TBLOCK_SUBINPROGRESS:
3146 /* Normal subtransaction start */
3148 s = CurrentTransactionState; /* changed by push */
3151 * Savepoint names, like the TransactionState block itself, live
3152 * in TopTransactionContext.
3155 s->name = MemoryContextStrdup(TopTransactionContext, name);
3158 /* These cases are invalid. */
3159 case TBLOCK_DEFAULT:
3160 case TBLOCK_STARTED:
3162 case TBLOCK_SUBBEGIN:
3166 case TBLOCK_SUBABORT:
3167 case TBLOCK_ABORT_END:
3168 case TBLOCK_SUBABORT_END:
3169 case TBLOCK_ABORT_PENDING:
3170 case TBLOCK_SUBABORT_PENDING:
3171 case TBLOCK_SUBRESTART:
3172 case TBLOCK_SUBABORT_RESTART:
3173 case TBLOCK_PREPARE:
3174 elog(FATAL, "DefineSavepoint: unexpected state %s",
3175 BlockStateAsString(s->blockState));
3182 * This executes a RELEASE command.
3184 * As above, we don't actually do anything here except change blockState.
3187 ReleaseSavepoint(List *options)
3189 TransactionState s = CurrentTransactionState;
3190 TransactionState target,
3195 switch (s->blockState)
3198 * We can't rollback to a savepoint if there is no savepoint
3201 case TBLOCK_INPROGRESS:
3203 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3204 errmsg("no such savepoint")));
3208 * We are in a non-aborted subtransaction. This is the only valid
3211 case TBLOCK_SUBINPROGRESS:
3214 /* These cases are invalid. */
3215 case TBLOCK_DEFAULT:
3216 case TBLOCK_STARTED:
3218 case TBLOCK_SUBBEGIN:
3222 case TBLOCK_SUBABORT:
3223 case TBLOCK_ABORT_END:
3224 case TBLOCK_SUBABORT_END:
3225 case TBLOCK_ABORT_PENDING:
3226 case TBLOCK_SUBABORT_PENDING:
3227 case TBLOCK_SUBRESTART:
3228 case TBLOCK_SUBABORT_RESTART:
3229 case TBLOCK_PREPARE:
3230 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3231 BlockStateAsString(s->blockState));
3235 foreach(cell, options)
3237 DefElem *elem = lfirst(cell);
3239 if (strcmp(elem->defname, "savepoint_name") == 0)
3240 name = strVal(elem->arg);
3243 Assert(PointerIsValid(name));
3245 for (target = s; PointerIsValid(target); target = target->parent)
3247 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3251 if (!PointerIsValid(target))
3253 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3254 errmsg("no such savepoint")));
3256 /* disallow crossing savepoint level boundaries */
3257 if (target->savepointLevel != s->savepointLevel)
3259 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3260 errmsg("no such savepoint")));
3263 * Mark "commit pending" all subtransactions up to the target
3264 * subtransaction. The actual commits will happen when control gets to
3265 * CommitTransactionCommand.
3267 xact = CurrentTransactionState;
3270 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3271 xact->blockState = TBLOCK_SUBEND;
3274 xact = xact->parent;
3275 Assert(PointerIsValid(xact));
3280 * RollbackToSavepoint
3281 * This executes a ROLLBACK TO <savepoint> command.
3283 * As above, we don't actually do anything here except change blockState.
3286 RollbackToSavepoint(List *options)
3288 TransactionState s = CurrentTransactionState;
3289 TransactionState target,
3294 switch (s->blockState)
3297 * We can't rollback to a savepoint if there is no savepoint
3300 case TBLOCK_INPROGRESS:
3303 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3304 errmsg("no such savepoint")));
3308 * There is at least one savepoint, so proceed.
3310 case TBLOCK_SUBINPROGRESS:
3311 case TBLOCK_SUBABORT:
3314 /* These cases are invalid. */
3315 case TBLOCK_DEFAULT:
3316 case TBLOCK_STARTED:
3318 case TBLOCK_SUBBEGIN:
3321 case TBLOCK_ABORT_END:
3322 case TBLOCK_SUBABORT_END:
3323 case TBLOCK_ABORT_PENDING:
3324 case TBLOCK_SUBABORT_PENDING:
3325 case TBLOCK_SUBRESTART:
3326 case TBLOCK_SUBABORT_RESTART:
3327 case TBLOCK_PREPARE:
3328 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3329 BlockStateAsString(s->blockState));
3333 foreach(cell, options)
3335 DefElem *elem = lfirst(cell);
3337 if (strcmp(elem->defname, "savepoint_name") == 0)
3338 name = strVal(elem->arg);
3341 Assert(PointerIsValid(name));
3343 for (target = s; PointerIsValid(target); target = target->parent)
3345 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3349 if (!PointerIsValid(target))
3351 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3352 errmsg("no such savepoint")));
3354 /* disallow crossing savepoint level boundaries */
3355 if (target->savepointLevel != s->savepointLevel)
3357 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3358 errmsg("no such savepoint")));
3361 * Mark "abort pending" all subtransactions up to the target
3362 * subtransaction. The actual aborts will happen when control gets to
3363 * CommitTransactionCommand.
3365 xact = CurrentTransactionState;
3370 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3371 xact->blockState = TBLOCK_SUBABORT_PENDING;
3372 else if (xact->blockState == TBLOCK_SUBABORT)
3373 xact->blockState = TBLOCK_SUBABORT_END;
3375 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3376 BlockStateAsString(xact->blockState));
3377 xact = xact->parent;
3378 Assert(PointerIsValid(xact));
3381 /* And mark the target as "restart pending" */
3382 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3383 xact->blockState = TBLOCK_SUBRESTART;
3384 else if (xact->blockState == TBLOCK_SUBABORT)
3385 xact->blockState = TBLOCK_SUBABORT_RESTART;
3387 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3388 BlockStateAsString(xact->blockState));
3392 * BeginInternalSubTransaction
3393 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
3394 * TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
3395 * used in functions that might be called when not inside a BEGIN block
3396 * or when running deferred triggers at COMMIT/PREPARE time. Also, it
3397 * automatically does CommitTransactionCommand/StartTransactionCommand
3398 * instead of expecting the caller to do it.
3401 BeginInternalSubTransaction(char *name)
3403 TransactionState s = CurrentTransactionState;
3405 switch (s->blockState)
3407 case TBLOCK_STARTED:
3408 case TBLOCK_INPROGRESS:
3410 case TBLOCK_PREPARE:
3411 case TBLOCK_SUBINPROGRESS:
3412 /* Normal subtransaction start */
3414 s = CurrentTransactionState; /* changed by push */
3417 * Savepoint names, like the TransactionState block itself, live
3418 * in TopTransactionContext.
3421 s->name = MemoryContextStrdup(TopTransactionContext, name);
3424 /* These cases are invalid. */
3425 case TBLOCK_DEFAULT:
3427 case TBLOCK_SUBBEGIN:
3430 case TBLOCK_SUBABORT:
3431 case TBLOCK_ABORT_END:
3432 case TBLOCK_SUBABORT_END:
3433 case TBLOCK_ABORT_PENDING:
3434 case TBLOCK_SUBABORT_PENDING:
3435 case TBLOCK_SUBRESTART:
3436 case TBLOCK_SUBABORT_RESTART:
3437 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
3438 BlockStateAsString(s->blockState));
3442 CommitTransactionCommand();
3443 StartTransactionCommand();
3447 * ReleaseCurrentSubTransaction
3449 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
3450 * savepoint name (if any).
3451 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3454 ReleaseCurrentSubTransaction(void)
3456 TransactionState s = CurrentTransactionState;
3458 if (s->blockState != TBLOCK_SUBINPROGRESS)
3459 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
3460 BlockStateAsString(s->blockState));
3461 Assert(s->state == TRANS_INPROGRESS);
3462 MemoryContextSwitchTo(CurTransactionContext);
3463 CommitSubTransaction();
3464 s = CurrentTransactionState; /* changed by pop */
3465 Assert(s->state == TRANS_INPROGRESS);
3469 * RollbackAndReleaseCurrentSubTransaction
3471 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
3472 * of its savepoint name (if any).
3473 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3476 RollbackAndReleaseCurrentSubTransaction(void)
3478 TransactionState s = CurrentTransactionState;
3480 switch (s->blockState)
3482 /* Must be in a subtransaction */
3483 case TBLOCK_SUBINPROGRESS:
3484 case TBLOCK_SUBABORT:
3487 /* These cases are invalid. */
3488 case TBLOCK_DEFAULT:
3489 case TBLOCK_STARTED:
3491 case TBLOCK_SUBBEGIN:
3492 case TBLOCK_INPROGRESS:
3496 case TBLOCK_ABORT_END:
3497 case TBLOCK_SUBABORT_END:
3498 case TBLOCK_ABORT_PENDING:
3499 case TBLOCK_SUBABORT_PENDING:
3500 case TBLOCK_SUBRESTART:
3501 case TBLOCK_SUBABORT_RESTART:
3502 case TBLOCK_PREPARE:
3503 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
3504 BlockStateAsString(s->blockState));
3509 * Abort the current subtransaction, if needed.
3511 if (s->blockState == TBLOCK_SUBINPROGRESS)
3512 AbortSubTransaction();
3514 /* And clean it up, too */
3515 CleanupSubTransaction();
3517 s = CurrentTransactionState; /* changed by pop */
3518 AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
3519 s->blockState == TBLOCK_INPROGRESS ||
3520 s->blockState == TBLOCK_STARTED);
3524 * AbortOutOfAnyTransaction
3526 * This routine is provided for error recovery purposes. It aborts any
3527 * active transaction or transaction block, leaving the system in a known
3531 AbortOutOfAnyTransaction(void)
3533 TransactionState s = CurrentTransactionState;
3536 * Get out of any transaction or nested transaction
3540 switch (s->blockState)
3542 case TBLOCK_DEFAULT:
3543 /* Not in a transaction, do nothing */
3545 case TBLOCK_STARTED:
3547 case TBLOCK_INPROGRESS:
3549 case TBLOCK_ABORT_PENDING:
3550 case TBLOCK_PREPARE:
3551 /* In a transaction, so clean up */
3553 CleanupTransaction();
3554 s->blockState = TBLOCK_DEFAULT;
3557 case TBLOCK_ABORT_END:
3558 /* AbortTransaction already done, still need Cleanup */
3559 CleanupTransaction();
3560 s->blockState = TBLOCK_DEFAULT;
3564 * In a subtransaction, so clean it up and abort parent too
3566 case TBLOCK_SUBBEGIN:
3567 case TBLOCK_SUBINPROGRESS:
3569 case TBLOCK_SUBABORT_PENDING:
3570 case TBLOCK_SUBRESTART:
3571 AbortSubTransaction();
3572 CleanupSubTransaction();
3573 s = CurrentTransactionState; /* changed by pop */
3576 case TBLOCK_SUBABORT:
3577 case TBLOCK_SUBABORT_END:
3578 case TBLOCK_SUBABORT_RESTART:
3579 /* As above, but AbortSubTransaction already done */
3580 CleanupSubTransaction();
3581 s = CurrentTransactionState; /* changed by pop */
3584 } while (s->blockState != TBLOCK_DEFAULT);
3586 /* Should be out of all subxacts now */
3587 Assert(s->parent == NULL);
3591 * IsTransactionBlock --- are we within a transaction block?
3594 IsTransactionBlock(void)
3596 TransactionState s = CurrentTransactionState;
3598 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
3605 * IsTransactionOrTransactionBlock --- are we within either a transaction
3606 * or a transaction block? (The backend is only really "idle" when this
3609 * This should match up with IsTransactionBlock and IsTransactionState.
3612 IsTransactionOrTransactionBlock(void)
3614 TransactionState s = CurrentTransactionState;
3616 if (s->blockState == TBLOCK_DEFAULT)
3623 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
3626 TransactionBlockStatusCode(void)
3628 TransactionState s = CurrentTransactionState;
3630 switch (s->blockState)
3632 case TBLOCK_DEFAULT:
3633 case TBLOCK_STARTED:
3634 return 'I'; /* idle --- not in transaction */
3636 case TBLOCK_SUBBEGIN:
3637 case TBLOCK_INPROGRESS:
3638 case TBLOCK_SUBINPROGRESS:
3641 case TBLOCK_PREPARE:
3642 return 'T'; /* in transaction */
3644 case TBLOCK_SUBABORT:
3645 case TBLOCK_ABORT_END:
3646 case TBLOCK_SUBABORT_END:
3647 case TBLOCK_ABORT_PENDING:
3648 case TBLOCK_SUBABORT_PENDING:
3649 case TBLOCK_SUBRESTART:
3650 case TBLOCK_SUBABORT_RESTART:
3651 return 'E'; /* in failed transaction */
3654 /* should never get here */
3655 elog(FATAL, "invalid transaction block state: %s",
3656 BlockStateAsString(s->blockState));
3657 return 0; /* keep compiler quiet */
3664 IsSubTransaction(void)
3666 TransactionState s = CurrentTransactionState;
3668 if (s->nestingLevel >= 2)
3675 * StartSubTransaction
3677 * If you're wondering why this is separate from PushTransaction: it's because
3678 * we can't conveniently do this stuff right inside DefineSavepoint. The
3679 * SAVEPOINT utility command will be executed inside a Portal, and if we
3680 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
3681 * the Portal will undo those settings. So we make DefineSavepoint just
3682 * push a dummy transaction block, and when control returns to the main
3683 * idle loop, CommitTransactionCommand will be called, and we'll come here
3684 * to finish starting the subtransaction.
3687 StartSubTransaction(void)
3689 TransactionState s = CurrentTransactionState;
3691 if (s->state != TRANS_DEFAULT)
3692 elog(WARNING, "StartSubTransaction while in %s state",
3693 TransStateAsString(s->state));
3695 s->state = TRANS_START;
3698 * Initialize subsystems for new subtransaction
3700 * must initialize resource-management stuff first
3702 AtSubStart_Memory();
3703 AtSubStart_ResourceOwner();
3705 AtSubStart_Notify();
3706 AfterTriggerBeginSubXact();
3708 s->state = TRANS_INPROGRESS;
3711 * Call start-of-subxact callbacks
3713 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
3714 s->parent->subTransactionId);
3716 ShowTransactionState("StartSubTransaction");
3720 * CommitSubTransaction
3722 * The caller has to make sure to always reassign CurrentTransactionState
3723 * if it has a local pointer to it after calling this function.
3726 CommitSubTransaction(void)
3728 TransactionState s = CurrentTransactionState;
3730 ShowTransactionState("CommitSubTransaction");
3732 if (s->state != TRANS_INPROGRESS)
3733 elog(WARNING, "CommitSubTransaction while in %s state",
3734 TransStateAsString(s->state));
3736 /* Pre-commit processing goes here -- nothing to do at the moment */
3738 s->state = TRANS_COMMIT;
3740 /* Must CCI to ensure commands of subtransaction are seen as done */
3741 CommandCounterIncrement();
3744 * Prior to 8.4 we marked subcommit in clog at this point. We now only
3745 * perform that step, if required, as part of the atomic update of the
3746 * whole transaction tree at top level commit or abort.
3749 /* Post-commit cleanup */
3750 if (TransactionIdIsValid(s->transactionId))
3751 AtSubCommit_childXids();
3752 AfterTriggerEndSubXact(true);
3753 AtSubCommit_Portals(s->subTransactionId,
3754 s->parent->subTransactionId,
3755 s->parent->curTransactionOwner);
3756 AtEOSubXact_LargeObject(true, s->subTransactionId,
3757 s->parent->subTransactionId);
3758 AtSubCommit_Notify();
3760 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
3761 s->parent->subTransactionId);
3763 ResourceOwnerRelease(s->curTransactionOwner,
3764 RESOURCE_RELEASE_BEFORE_LOCKS,
3766 AtEOSubXact_RelationCache(true, s->subTransactionId,
3767 s->parent->subTransactionId);
3768 AtEOSubXact_Inval(true);
3772 * The only lock we actually release here is the subtransaction XID lock.
3773 * The rest just get transferred to the parent resource owner.
3775 CurrentResourceOwner = s->curTransactionOwner;
3776 if (TransactionIdIsValid(s->transactionId))
3777 XactLockTableDelete(s->transactionId);
3779 ResourceOwnerRelease(s->curTransactionOwner,
3780 RESOURCE_RELEASE_LOCKS,
3782 ResourceOwnerRelease(s->curTransactionOwner,
3783 RESOURCE_RELEASE_AFTER_LOCKS,
3786 AtEOXact_GUC(true, s->gucNestLevel);
3787 AtEOSubXact_SPI(true, s->subTransactionId);
3788 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
3789 s->parent->subTransactionId);
3790 AtEOSubXact_Namespace(true, s->subTransactionId,
3791 s->parent->subTransactionId);
3792 AtEOSubXact_Files(true, s->subTransactionId,
3793 s->parent->subTransactionId);
3794 AtEOSubXact_HashTables(true, s->nestingLevel);
3795 AtEOSubXact_PgStat(true, s->nestingLevel);
3796 AtSubCommit_Snapshot(s->nestingLevel);
3799 * We need to restore the upper transaction's read-only state, in case the
3800 * upper is read-write while the child is read-only; GUC will incorrectly
3801 * think it should leave the child state in place.
3803 XactReadOnly = s->prevXactReadOnly;
3805 CurrentResourceOwner = s->parent->curTransactionOwner;
3806 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3807 ResourceOwnerDelete(s->curTransactionOwner);
3808 s->curTransactionOwner = NULL;
3810 AtSubCommit_Memory();
3812 s->state = TRANS_DEFAULT;
3818 * AbortSubTransaction
3821 AbortSubTransaction(void)
3823 TransactionState s = CurrentTransactionState;
3825 /* Prevent cancel/die interrupt while cleaning up */
3828 /* Make sure we have a valid memory context and resource owner */
3829 AtSubAbort_Memory();
3830 AtSubAbort_ResourceOwner();
3833 * Release any LW locks we might be holding as quickly as possible.
3834 * (Regular locks, however, must be held till we finish aborting.)
3835 * Releasing LW locks is critical since we might try to grab them again
3836 * while cleaning up!
3838 * FIXME This may be incorrect --- Are there some locks we should keep?
3839 * Buffer locks, for example? I don't think so but I'm not sure.
3849 * check the current transaction state
3851 ShowTransactionState("AbortSubTransaction");
3853 if (s->state != TRANS_INPROGRESS)
3854 elog(WARNING, "AbortSubTransaction while in %s state",
3855 TransStateAsString(s->state));
3857 s->state = TRANS_ABORT;
3860 * Reset user ID which might have been changed transiently. (See notes in
3861 * AbortTransaction.)
3863 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
3866 * We can skip all this stuff if the subxact failed before creating a
3869 if (s->curTransactionOwner)
3871 AfterTriggerEndSubXact(false);
3872 AtSubAbort_Portals(s->subTransactionId,
3873 s->parent->subTransactionId,
3874 s->parent->curTransactionOwner);
3875 AtEOSubXact_LargeObject(false, s->subTransactionId,
3876 s->parent->subTransactionId);
3877 AtSubAbort_Notify();
3879 /* Advertise the fact that we aborted in pg_clog. */
3880 (void) RecordTransactionAbort(true);
3882 /* Post-abort cleanup */
3883 if (TransactionIdIsValid(s->transactionId))
3884 AtSubAbort_childXids();
3886 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
3887 s->parent->subTransactionId);
3889 ResourceOwnerRelease(s->curTransactionOwner,
3890 RESOURCE_RELEASE_BEFORE_LOCKS,
3892 AtEOSubXact_RelationCache(false, s->subTransactionId,
3893 s->parent->subTransactionId);
3894 AtEOSubXact_Inval(false);
3896 ResourceOwnerRelease(s->curTransactionOwner,
3897 RESOURCE_RELEASE_LOCKS,
3899 ResourceOwnerRelease(s->curTransactionOwner,
3900 RESOURCE_RELEASE_AFTER_LOCKS,
3903 AtEOXact_GUC(false, s->gucNestLevel);
3904 AtEOSubXact_SPI(false, s->subTransactionId);
3905 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
3906 s->parent->subTransactionId);
3907 AtEOSubXact_Namespace(false, s->subTransactionId,
3908 s->parent->subTransactionId);
3909 AtEOSubXact_Files(false, s->subTransactionId,
3910 s->parent->subTransactionId);
3911 AtEOSubXact_HashTables(false, s->nestingLevel);
3912 AtEOSubXact_PgStat(false, s->nestingLevel);
3913 AtSubAbort_Snapshot(s->nestingLevel);
3917 * Restore the upper transaction's read-only state, too. This should be
3918 * redundant with GUC's cleanup but we may as well do it for consistency
3919 * with the commit case.
3921 XactReadOnly = s->prevXactReadOnly;
3923 RESUME_INTERRUPTS();
3927 * CleanupSubTransaction
3929 * The caller has to make sure to always reassign CurrentTransactionState
3930 * if it has a local pointer to it after calling this function.
3933 CleanupSubTransaction(void)
3935 TransactionState s = CurrentTransactionState;
3937 ShowTransactionState("CleanupSubTransaction");
3939 if (s->state != TRANS_ABORT)
3940 elog(WARNING, "CleanupSubTransaction while in %s state",
3941 TransStateAsString(s->state));
3943 AtSubCleanup_Portals(s->subTransactionId);
3945 CurrentResourceOwner = s->parent->curTransactionOwner;
3946 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3947 if (s->curTransactionOwner)
3948 ResourceOwnerDelete(s->curTransactionOwner);
3949 s->curTransactionOwner = NULL;
3951 AtSubCleanup_Memory();
3953 s->state = TRANS_DEFAULT;
3960 * Create transaction state stack entry for a subtransaction
3962 * The caller has to make sure to always reassign CurrentTransactionState
3963 * if it has a local pointer to it after calling this function.
3966 PushTransaction(void)
3968 TransactionState p = CurrentTransactionState;
3972 * We keep subtransaction state nodes in TopTransactionContext.
3974 s = (TransactionState)
3975 MemoryContextAllocZero(TopTransactionContext,
3976 sizeof(TransactionStateData));
3979 * Assign a subtransaction ID, watching out for counter wraparound.
3981 currentSubTransactionId += 1;
3982 if (currentSubTransactionId == InvalidSubTransactionId)
3984 currentSubTransactionId -= 1;
3987 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3988 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
3992 * We can now stack a minimally valid subtransaction without fear of
3995 s->transactionId = InvalidTransactionId; /* until assigned */
3996 s->subTransactionId = currentSubTransactionId;
3998 s->nestingLevel = p->nestingLevel + 1;
3999 s->gucNestLevel = NewGUCNestLevel();
4000 s->savepointLevel = p->savepointLevel;
4001 s->state = TRANS_DEFAULT;
4002 s->blockState = TBLOCK_SUBBEGIN;
4003 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
4004 s->prevXactReadOnly = XactReadOnly;
4006 CurrentTransactionState = s;
4009 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
4010 * with the subtransaction from here on out; in particular they should not
4011 * assume that it necessarily has a transaction context, resource owner,
4018 * Pop back to parent transaction state
4020 * The caller has to make sure to always reassign CurrentTransactionState
4021 * if it has a local pointer to it after calling this function.
4024 PopTransaction(void)
4026 TransactionState s = CurrentTransactionState;
4028 if (s->state != TRANS_DEFAULT)
4029 elog(WARNING, "PopTransaction while in %s state",
4030 TransStateAsString(s->state));
4032 if (s->parent == NULL)
4033 elog(FATAL, "PopTransaction with no parent");
4035 CurrentTransactionState = s->parent;
4037 /* Let's just make sure CurTransactionContext is good */
4038 CurTransactionContext = s->parent->curTransactionContext;
4039 MemoryContextSwitchTo(CurTransactionContext);
4041 /* Ditto for ResourceOwner links */
4042 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4043 CurrentResourceOwner = s->parent->curTransactionOwner;
4045 /* Free the old child structure */
4052 * ShowTransactionState
4056 ShowTransactionState(const char *str)
4058 /* skip work if message will definitely not be printed */
4059 if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
4061 elog(DEBUG3, "%s", str);
4062 ShowTransactionStateRec(CurrentTransactionState);
4067 * ShowTransactionStateRec
4068 * Recursive subroutine for ShowTransactionState
4071 ShowTransactionStateRec(TransactionState s)
4075 initStringInfo(&buf);
4077 if (s->nChildXids > 0)
4081 appendStringInfo(&buf, "%u", s->childXids[0]);
4082 for (i = 1; i < s->nChildXids; i++)
4083 appendStringInfo(&buf, " %u", s->childXids[i]);
4087 ShowTransactionStateRec(s->parent);
4089 /* use ereport to suppress computation if msg will not be printed */
4091 (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u%s, nestlvl: %d, children: %s",
4092 PointerIsValid(s->name) ? s->name : "unnamed",
4093 BlockStateAsString(s->blockState),
4094 TransStateAsString(s->state),
4095 (unsigned int) s->transactionId,
4096 (unsigned int) s->subTransactionId,
4097 (unsigned int) currentCommandId,
4098 currentCommandIdUsed ? " (used)" : "",
4099 s->nestingLevel, buf.data)));
4105 * BlockStateAsString
4109 BlockStateAsString(TBlockState blockState)
4113 case TBLOCK_DEFAULT:
4115 case TBLOCK_STARTED:
4119 case TBLOCK_INPROGRESS:
4120 return "INPROGRESS";
4125 case TBLOCK_ABORT_END:
4127 case TBLOCK_ABORT_PENDING:
4128 return "ABORT PEND";
4129 case TBLOCK_PREPARE:
4131 case TBLOCK_SUBBEGIN:
4133 case TBLOCK_SUBINPROGRESS:
4134 return "SUB INPROGRS";
4137 case TBLOCK_SUBABORT:
4139 case TBLOCK_SUBABORT_END:
4140 return "SUB ABORT END";
4141 case TBLOCK_SUBABORT_PENDING:
4142 return "SUB ABRT PEND";
4143 case TBLOCK_SUBRESTART:
4144 return "SUB RESTART";
4145 case TBLOCK_SUBABORT_RESTART:
4146 return "SUB AB RESTRT";
4148 return "UNRECOGNIZED";
4152 * TransStateAsString
4156 TransStateAsString(TransState state)
4164 case TRANS_INPROGRESS:
4173 return "UNRECOGNIZED";
4177 * xactGetCommittedChildren
4179 * Gets the list of committed children of the current transaction. The return
4180 * value is the number of child transactions. *ptr is set to point to an
4181 * array of TransactionIds. The array is allocated in TopTransactionContext;
4182 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
4183 * If there are no subxacts, *ptr is set to NULL.
4186 xactGetCommittedChildren(TransactionId **ptr)
4188 TransactionState s = CurrentTransactionState;
4190 if (s->nChildXids == 0)
4193 *ptr = s->childXids;
4195 return s->nChildXids;
4199 * XLOG support routines
4203 xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid)
4205 TransactionId *sub_xids;
4206 TransactionId max_xid;
4209 /* Mark the transaction committed in pg_clog */
4210 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4211 TransactionIdCommitTree(xid, xlrec->nsubxacts, sub_xids);
4213 /* Make sure nextXid is beyond any XID mentioned in the record */
4215 for (i = 0; i < xlrec->nsubxacts; i++)
4217 if (TransactionIdPrecedes(max_xid, sub_xids[i]))
4218 max_xid = sub_xids[i];
4220 if (TransactionIdFollowsOrEquals(max_xid,
4221 ShmemVariableCache->nextXid))
4223 ShmemVariableCache->nextXid = max_xid;
4224 TransactionIdAdvance(ShmemVariableCache->nextXid);
4227 /* Make sure files supposed to be dropped are dropped */
4228 for (i = 0; i < xlrec->nrels; i++)
4230 SMgrRelation srel = smgropen(xlrec->xnodes[i]);
4233 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4235 if (smgrexists(srel, fork))
4237 XLogDropRelation(xlrec->xnodes[i], fork);
4238 smgrdounlink(srel, fork, false, true);
4246 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
4248 TransactionId *sub_xids;
4249 TransactionId max_xid;
4252 /* Mark the transaction aborted in pg_clog */
4253 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4254 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4256 /* Make sure nextXid is beyond any XID mentioned in the record */
4258 for (i = 0; i < xlrec->nsubxacts; i++)
4260 if (TransactionIdPrecedes(max_xid, sub_xids[i]))
4261 max_xid = sub_xids[i];
4263 if (TransactionIdFollowsOrEquals(max_xid,
4264 ShmemVariableCache->nextXid))
4266 ShmemVariableCache->nextXid = max_xid;
4267 TransactionIdAdvance(ShmemVariableCache->nextXid);
4270 /* Make sure files supposed to be dropped are dropped */
4271 for (i = 0; i < xlrec->nrels; i++)
4273 SMgrRelation srel = smgropen(xlrec->xnodes[i]);
4276 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4278 if (smgrexists(srel, fork))
4280 XLogDropRelation(xlrec->xnodes[i], fork);
4281 smgrdounlink(srel, fork, false, true);
4289 xact_redo(XLogRecPtr lsn, XLogRecord *record)
4291 uint8 info = record->xl_info & ~XLR_INFO_MASK;
4293 /* Backup blocks are not used in xact records */
4294 Assert(!(record->xl_info & XLR_BKP_BLOCK_MASK));
4296 if (info == XLOG_XACT_COMMIT)
4298 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
4300 xact_redo_commit(xlrec, record->xl_xid);
4302 else if (info == XLOG_XACT_ABORT)
4304 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
4306 xact_redo_abort(xlrec, record->xl_xid);
4308 else if (info == XLOG_XACT_PREPARE)
4310 /* the record contents are exactly the 2PC file */
4311 RecreateTwoPhaseFile(record->xl_xid,
4312 XLogRecGetData(record), record->xl_len);
4314 else if (info == XLOG_XACT_COMMIT_PREPARED)
4316 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
4318 xact_redo_commit(&xlrec->crec, xlrec->xid);
4319 RemoveTwoPhaseFile(xlrec->xid, false);
4321 else if (info == XLOG_XACT_ABORT_PREPARED)
4323 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
4325 xact_redo_abort(&xlrec->arec, xlrec->xid);
4326 RemoveTwoPhaseFile(xlrec->xid, false);
4329 elog(PANIC, "xact_redo: unknown op code %u", info);
4333 xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
4337 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4338 if (xlrec->nrels > 0)
4340 appendStringInfo(buf, "; rels:");
4341 for (i = 0; i < xlrec->nrels; i++)
4343 char *path = relpath(xlrec->xnodes[i], MAIN_FORKNUM);
4345 appendStringInfo(buf, " %s", path);
4349 if (xlrec->nsubxacts > 0)
4351 TransactionId *xacts = (TransactionId *)
4352 &xlrec->xnodes[xlrec->nrels];
4354 appendStringInfo(buf, "; subxacts:");
4355 for (i = 0; i < xlrec->nsubxacts; i++)
4356 appendStringInfo(buf, " %u", xacts[i]);
4361 xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
4365 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4366 if (xlrec->nrels > 0)
4368 appendStringInfo(buf, "; rels:");
4369 for (i = 0; i < xlrec->nrels; i++)
4371 char *path = relpath(xlrec->xnodes[i], MAIN_FORKNUM);
4373 appendStringInfo(buf, " %s", path);
4377 if (xlrec->nsubxacts > 0)
4379 TransactionId *xacts = (TransactionId *)
4380 &xlrec->xnodes[xlrec->nrels];
4382 appendStringInfo(buf, "; subxacts:");
4383 for (i = 0; i < xlrec->nsubxacts; i++)
4384 appendStringInfo(buf, " %u", xacts[i]);
4389 xact_desc(StringInfo buf, uint8 xl_info, char *rec)
4391 uint8 info = xl_info & ~XLR_INFO_MASK;
4393 if (info == XLOG_XACT_COMMIT)
4395 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
4397 appendStringInfo(buf, "commit: ");
4398 xact_desc_commit(buf, xlrec);
4400 else if (info == XLOG_XACT_ABORT)
4402 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
4404 appendStringInfo(buf, "abort: ");
4405 xact_desc_abort(buf, xlrec);
4407 else if (info == XLOG_XACT_PREPARE)
4409 appendStringInfo(buf, "prepare");
4411 else if (info == XLOG_XACT_COMMIT_PREPARED)
4413 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
4415 appendStringInfo(buf, "commit %u: ", xlrec->xid);
4416 xact_desc_commit(buf, &xlrec->crec);
4418 else if (info == XLOG_XACT_ABORT_PREPARED)
4420 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
4422 appendStringInfo(buf, "abort %u: ", xlrec->xid);
4423 xact_desc_abort(buf, &xlrec->arec);
4426 appendStringInfo(buf, "UNKNOWN");