1 /*-------------------------------------------------------------------------
4 * top level transaction system support routines
6 * See src/backend/access/transam/README for more information.
8 * Portions Copyright (c) 1996-2007, 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.240 2007/04/26 23:24:44 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/namespace.h"
30 #include "commands/async.h"
31 #include "commands/tablecmds.h"
32 #include "commands/trigger.h"
33 #include "executor/spi.h"
34 #include "libpq/be-fsstubs.h"
35 #include "miscadmin.h"
37 #include "storage/fd.h"
38 #include "storage/lmgr.h"
39 #include "storage/procarray.h"
40 #include "storage/smgr.h"
41 #include "utils/combocid.h"
42 #include "utils/flatfiles.h"
43 #include "utils/guc.h"
44 #include "utils/inval.h"
45 #include "utils/memutils.h"
46 #include "utils/relcache.h"
50 * User-tweakable parameters
52 int DefaultXactIsoLevel = XACT_READ_COMMITTED;
55 bool DefaultXactReadOnly = false;
58 int CommitDelay = 0; /* precommit delay in microseconds */
59 int CommitSiblings = 5; /* # concurrent xacts needed to sleep */
63 * transaction states - transaction state from server perspective
65 typedef enum TransState
76 * transaction block states - transaction state of client queries
78 * Note: the subtransaction states are used only for non-topmost
79 * transactions; the others appear only in the topmost transaction.
81 typedef enum TBlockState
83 /* not-in-transaction-block states */
84 TBLOCK_DEFAULT, /* idle */
85 TBLOCK_STARTED, /* running single-query transaction */
87 /* transaction block states */
88 TBLOCK_BEGIN, /* starting transaction block */
89 TBLOCK_INPROGRESS, /* live transaction */
90 TBLOCK_END, /* COMMIT received */
91 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
92 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
93 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
94 TBLOCK_PREPARE, /* live xact, PREPARE received */
96 /* subtransaction states */
97 TBLOCK_SUBBEGIN, /* starting a subtransaction */
98 TBLOCK_SUBINPROGRESS, /* live subtransaction */
99 TBLOCK_SUBEND, /* RELEASE received */
100 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
101 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
102 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
103 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
104 TBLOCK_SUBABORT_RESTART /* failed subxact, ROLLBACK TO received */
108 * transaction state structure
110 typedef struct TransactionStateData
112 TransactionId transactionId; /* my XID, or Invalid if none */
113 SubTransactionId subTransactionId; /* my subxact ID */
114 char *name; /* savepoint name, if any */
115 int savepointLevel; /* savepoint level */
116 TransState state; /* low-level state */
117 TBlockState blockState; /* high-level state */
118 int nestingLevel; /* nest depth */
119 MemoryContext curTransactionContext; /* my xact-lifetime context */
120 ResourceOwner curTransactionOwner; /* my query resources */
121 List *childXids; /* subcommitted child XIDs */
122 Oid currentUser; /* subxact start current_user */
123 bool prevXactReadOnly; /* entry-time xact r/o state */
124 struct TransactionStateData *parent; /* back link to parent */
125 } TransactionStateData;
127 typedef TransactionStateData *TransactionState;
130 * CurrentTransactionState always points to the current transaction state
131 * block. It will point to TopTransactionStateData when not in a
132 * transaction at all, or when in a top-level transaction.
134 static TransactionStateData TopTransactionStateData = {
135 0, /* transaction id */
136 0, /* subtransaction id */
137 NULL, /* savepoint name */
138 0, /* savepoint level */
139 TRANS_DEFAULT, /* transaction state */
140 TBLOCK_DEFAULT, /* transaction block state from the client
142 0, /* nesting level */
143 NULL, /* cur transaction context */
144 NULL, /* cur transaction resource owner */
145 NIL, /* subcommitted child Xids */
146 0, /* entry-time current userid */
147 false, /* entry-time xact r/o state */
148 NULL /* link to parent state block */
151 static TransactionState CurrentTransactionState = &TopTransactionStateData;
154 * The subtransaction ID and command ID assignment counters are global
155 * to a whole transaction, so we do not keep them in the state stack.
157 static SubTransactionId currentSubTransactionId;
158 static CommandId currentCommandId;
161 * xactStartTimestamp is the value of transaction_timestamp().
162 * stmtStartTimestamp is the value of statement_timestamp().
163 * These do not change as we enter and exit subtransactions, so we don't
164 * keep them inside the TransactionState stack.
166 static TimestampTz xactStartTimestamp;
167 static TimestampTz stmtStartTimestamp;
170 * GID to be used for preparing the current transaction. This is also
171 * global to a whole transaction, so we don't keep it in the state stack.
173 static char *prepareGID;
176 * Private context for transaction-abort work --- we reserve space for this
177 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
178 * when we've run out of memory.
180 static MemoryContext TransactionAbortContext = NULL;
183 * List of add-on start- and end-of-xact callbacks
185 typedef struct XactCallbackItem
187 struct XactCallbackItem *next;
188 XactCallback callback;
192 static XactCallbackItem *Xact_callbacks = NULL;
195 * List of add-on start- and end-of-subxact callbacks
197 typedef struct SubXactCallbackItem
199 struct SubXactCallbackItem *next;
200 SubXactCallback callback;
202 } SubXactCallbackItem;
204 static SubXactCallbackItem *SubXact_callbacks = NULL;
207 /* local function prototypes */
208 static void AssignSubTransactionId(TransactionState s);
209 static void AbortTransaction(void);
210 static void AtAbort_Memory(void);
211 static void AtCleanup_Memory(void);
212 static void AtAbort_ResourceOwner(void);
213 static void AtCommit_LocalCache(void);
214 static void AtCommit_Memory(void);
215 static void AtStart_Cache(void);
216 static void AtStart_Memory(void);
217 static void AtStart_ResourceOwner(void);
218 static void CallXactCallbacks(XactEvent event);
219 static void CallSubXactCallbacks(SubXactEvent event,
220 SubTransactionId mySubid,
221 SubTransactionId parentSubid);
222 static void CleanupTransaction(void);
223 static void CommitTransaction(void);
224 static void RecordTransactionAbort(void);
225 static void StartTransaction(void);
227 static void RecordSubTransactionCommit(void);
228 static void StartSubTransaction(void);
229 static void CommitSubTransaction(void);
230 static void AbortSubTransaction(void);
231 static void CleanupSubTransaction(void);
232 static void PushTransaction(void);
233 static void PopTransaction(void);
235 static void AtSubAbort_Memory(void);
236 static void AtSubCleanup_Memory(void);
237 static void AtSubAbort_ResourceOwner(void);
238 static void AtSubCommit_Memory(void);
239 static void AtSubStart_Memory(void);
240 static void AtSubStart_ResourceOwner(void);
242 static void ShowTransactionState(const char *str);
243 static void ShowTransactionStateRec(TransactionState state);
244 static const char *BlockStateAsString(TBlockState blockState);
245 static const char *TransStateAsString(TransState state);
248 /* ----------------------------------------------------------------
249 * transaction state accessors
250 * ----------------------------------------------------------------
256 * This returns true if we are currently running a query
257 * within an executing transaction.
260 IsTransactionState(void)
262 TransactionState s = CurrentTransactionState;
270 case TRANS_INPROGRESS:
281 * Shouldn't get here, but lint is not happy without this...
287 * IsAbortedTransactionBlockState
289 * This returns true if we are currently running a query
290 * within an aborted transaction block.
293 IsAbortedTransactionBlockState(void)
295 TransactionState s = CurrentTransactionState;
297 if (s->blockState == TBLOCK_ABORT ||
298 s->blockState == TBLOCK_SUBABORT)
306 * GetTopTransactionId
308 * Get the ID of the main transaction, even if we are currently inside
312 GetTopTransactionId(void)
314 return TopTransactionStateData.transactionId;
319 * GetCurrentTransactionId
321 * We do not assign XIDs to subtransactions until/unless this is called.
322 * When we do assign an XID to a subtransaction, recursively make sure
323 * its parent has one as well (this maintains the invariant that a child
324 * transaction has an XID following its parent's).
327 GetCurrentTransactionId(void)
329 TransactionState s = CurrentTransactionState;
331 if (!TransactionIdIsValid(s->transactionId))
332 AssignSubTransactionId(s);
334 return s->transactionId;
338 AssignSubTransactionId(TransactionState s)
340 ResourceOwner currentOwner;
342 Assert(s->parent != NULL);
343 Assert(s->state == TRANS_INPROGRESS);
344 if (!TransactionIdIsValid(s->parent->transactionId))
345 AssignSubTransactionId(s->parent);
348 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
350 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
351 * shared storage other than PG_PROC; because if there's no room for it in
352 * PG_PROC, the subtrans entry is needed to ensure that other backends see
353 * the Xid as "running". See GetNewTransactionId.
355 s->transactionId = GetNewTransactionId(true);
357 SubTransSetParent(s->transactionId, s->parent->transactionId);
360 * Acquire lock on the transaction XID. (We assume this cannot block.) We
361 * have to be sure that the lock is assigned to the transaction's
364 currentOwner = CurrentResourceOwner;
367 CurrentResourceOwner = s->curTransactionOwner;
369 XactLockTableInsert(s->transactionId);
373 /* Ensure CurrentResourceOwner is restored on error */
374 CurrentResourceOwner = currentOwner;
378 CurrentResourceOwner = currentOwner;
383 * GetCurrentTransactionIdIfAny
385 * Unlike GetCurrentTransactionId, this will return InvalidTransactionId
386 * if we are currently not in a transaction, or in a transaction or
387 * subtransaction that has not yet assigned itself an XID.
390 GetCurrentTransactionIdIfAny(void)
392 TransactionState s = CurrentTransactionState;
394 return s->transactionId;
399 * GetCurrentSubTransactionId
402 GetCurrentSubTransactionId(void)
404 TransactionState s = CurrentTransactionState;
406 return s->subTransactionId;
411 * GetCurrentCommandId
414 GetCurrentCommandId(void)
416 /* this is global to a transaction, not subtransaction-local */
417 return currentCommandId;
421 * GetCurrentTransactionStartTimestamp
424 GetCurrentTransactionStartTimestamp(void)
426 return xactStartTimestamp;
430 * GetCurrentStatementStartTimestamp
433 GetCurrentStatementStartTimestamp(void)
435 return stmtStartTimestamp;
439 * SetCurrentStatementStartTimestamp
442 SetCurrentStatementStartTimestamp(void)
444 stmtStartTimestamp = GetCurrentTimestamp();
448 * GetCurrentTransactionNestLevel
450 * Note: this will return zero when not inside any transaction, one when
451 * inside a top-level transaction, etc.
454 GetCurrentTransactionNestLevel(void)
456 TransactionState s = CurrentTransactionState;
458 return s->nestingLevel;
463 * TransactionIdIsCurrentTransactionId
466 TransactionIdIsCurrentTransactionId(TransactionId xid)
471 * We always say that BootstrapTransactionId is "not my transaction ID"
472 * even when it is (ie, during bootstrap). Along with the fact that
473 * transam.c always treats BootstrapTransactionId as already committed,
474 * this causes the tqual.c routines to see all tuples as committed, which
475 * is what we need during bootstrap. (Bootstrap mode only inserts tuples,
476 * it never updates or deletes them, so all tuples can be presumed good
479 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
480 * not my transaction ID, so we can just return "false" immediately for
481 * any non-normal XID.
483 if (!TransactionIdIsNormal(xid))
487 * We will return true for the Xid of the current subtransaction, any of
488 * its subcommitted children, any of its parents, or any of their
489 * previously subcommitted children. However, a transaction being aborted
490 * is no longer "current", even though it may still have an entry on the
493 for (s = CurrentTransactionState; s != NULL; s = s->parent)
497 if (s->state == TRANS_ABORT)
499 if (!TransactionIdIsValid(s->transactionId))
500 continue; /* it can't have any child XIDs either */
501 if (TransactionIdEquals(xid, s->transactionId))
503 foreach(cell, s->childXids)
505 if (TransactionIdEquals(xid, lfirst_xid(cell)))
515 * CommandCounterIncrement
518 CommandCounterIncrement(void)
520 currentCommandId += 1;
521 if (currentCommandId == FirstCommandId) /* check for overflow */
523 currentCommandId -= 1;
525 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
526 errmsg("cannot have more than 2^32-1 commands in a transaction")));
529 /* Propagate new command ID into static snapshots, if set */
530 if (SerializableSnapshot)
531 SerializableSnapshot->curcid = currentCommandId;
533 LatestSnapshot->curcid = currentCommandId;
536 * make cache changes visible to me.
538 AtCommit_LocalCache();
543 /* ----------------------------------------------------------------
544 * StartTransaction stuff
545 * ----------------------------------------------------------------
554 AcceptInvalidationMessages();
563 TransactionState s = CurrentTransactionState;
566 * If this is the first time through, create a private context for
567 * AbortTransaction to work in. By reserving some space now, we can
568 * insulate AbortTransaction from out-of-memory scenarios. Like
569 * ErrorContext, we set it up with slow growth rate and a nonzero
570 * minimum size, so that space will be reserved immediately.
572 if (TransactionAbortContext == NULL)
573 TransactionAbortContext =
574 AllocSetContextCreate(TopMemoryContext,
575 "TransactionAbortContext",
581 * We shouldn't have a transaction context already.
583 Assert(TopTransactionContext == NULL);
586 * Create a toplevel context for the transaction.
588 TopTransactionContext =
589 AllocSetContextCreate(TopMemoryContext,
590 "TopTransactionContext",
591 ALLOCSET_DEFAULT_MINSIZE,
592 ALLOCSET_DEFAULT_INITSIZE,
593 ALLOCSET_DEFAULT_MAXSIZE);
596 * In a top-level transaction, CurTransactionContext is the same as
597 * TopTransactionContext.
599 CurTransactionContext = TopTransactionContext;
600 s->curTransactionContext = CurTransactionContext;
602 /* Make the CurTransactionContext active. */
603 MemoryContextSwitchTo(CurTransactionContext);
607 * AtStart_ResourceOwner
610 AtStart_ResourceOwner(void)
612 TransactionState s = CurrentTransactionState;
615 * We shouldn't have a transaction resource owner already.
617 Assert(TopTransactionResourceOwner == NULL);
620 * Create a toplevel resource owner for the transaction.
622 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
624 TopTransactionResourceOwner = s->curTransactionOwner;
625 CurTransactionResourceOwner = s->curTransactionOwner;
626 CurrentResourceOwner = s->curTransactionOwner;
629 /* ----------------------------------------------------------------
630 * StartSubTransaction stuff
631 * ----------------------------------------------------------------
638 AtSubStart_Memory(void)
640 TransactionState s = CurrentTransactionState;
642 Assert(CurTransactionContext != NULL);
645 * Create a CurTransactionContext, which will be used to hold data that
646 * survives subtransaction commit but disappears on subtransaction abort.
647 * We make it a child of the immediate parent's CurTransactionContext.
649 CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
650 "CurTransactionContext",
651 ALLOCSET_DEFAULT_MINSIZE,
652 ALLOCSET_DEFAULT_INITSIZE,
653 ALLOCSET_DEFAULT_MAXSIZE);
654 s->curTransactionContext = CurTransactionContext;
656 /* Make the CurTransactionContext active. */
657 MemoryContextSwitchTo(CurTransactionContext);
661 * AtSubStart_ResourceOwner
664 AtSubStart_ResourceOwner(void)
666 TransactionState s = CurrentTransactionState;
668 Assert(s->parent != NULL);
671 * Create a resource owner for the subtransaction. We make it a child of
672 * the immediate parent's resource owner.
674 s->curTransactionOwner =
675 ResourceOwnerCreate(s->parent->curTransactionOwner,
678 CurTransactionResourceOwner = s->curTransactionOwner;
679 CurrentResourceOwner = s->curTransactionOwner;
682 /* ----------------------------------------------------------------
683 * CommitTransaction stuff
684 * ----------------------------------------------------------------
688 * RecordTransactionCommit
691 RecordTransactionCommit(void)
696 TransactionId *children;
698 /* Get data needed for commit record */
699 nrels = smgrGetPendingDeletes(true, &rels);
700 nchildren = xactGetCommittedChildren(&children);
703 * If we made neither any XLOG entries nor any temp-rel updates, and have
704 * no files to be deleted, we can omit recording the transaction commit at
705 * all. (This test includes the effects of subtransactions, so the
706 * presence of committed subxacts need not alone force a write.)
708 if (MyXactMadeXLogEntry || MyXactMadeTempRelUpdate || nrels > 0)
710 TransactionId xid = GetCurrentTransactionId();
714 /* Tell bufmgr and smgr to prepare for commit */
717 START_CRIT_SECTION();
720 * We only need to log the commit in XLOG if the transaction made any
721 * transaction-controlled XLOG entries or will delete files.
723 madeTCentries = (MyLastRecPtr.xrecoff != 0);
724 if (madeTCentries || nrels > 0)
726 XLogRecData rdata[3];
728 xl_xact_commit xlrec;
731 * Mark ourselves as within our "commit critical section". This
732 * forces any concurrent checkpoint to wait until we've updated
733 * pg_clog. Without this, it is possible for the checkpoint to
734 * set REDO after the XLOG record but fail to flush the pg_clog
735 * update to disk, leading to loss of the transaction commit if
736 * the system crashes a little later.
738 * Note: we could, but don't bother to, set this flag in
739 * RecordTransactionAbort. That's because loss of a transaction
740 * abort is noncritical; the presumption would be that it aborted,
743 * It's safe to change the inCommit flag of our own backend
744 * without holding the ProcArrayLock, since we're the only one
745 * modifying it. This makes checkpoint's determination of which
746 * xacts are inCommit a bit fuzzy, but it doesn't matter.
748 MyProc->inCommit = true;
750 xlrec.xtime = time(NULL);
752 xlrec.nsubxacts = nchildren;
753 rdata[0].data = (char *) (&xlrec);
754 rdata[0].len = MinSizeOfXactCommit;
755 rdata[0].buffer = InvalidBuffer;
756 /* dump rels to delete */
759 rdata[0].next = &(rdata[1]);
760 rdata[1].data = (char *) rels;
761 rdata[1].len = nrels * sizeof(RelFileNode);
762 rdata[1].buffer = InvalidBuffer;
765 /* dump committed child Xids */
768 rdata[lastrdata].next = &(rdata[2]);
769 rdata[2].data = (char *) children;
770 rdata[2].len = nchildren * sizeof(TransactionId);
771 rdata[2].buffer = InvalidBuffer;
774 rdata[lastrdata].next = NULL;
776 recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
780 /* Just flush through last record written by me */
781 recptr = ProcLastRecEnd;
785 * We must flush our XLOG entries to disk if we made any XLOG entries,
786 * whether in or out of transaction control. For example, if we
787 * reported a nextval() result to the client, this ensures that any
788 * XLOG record generated by nextval will hit the disk before we report
789 * the transaction committed.
791 * Note: if we generated a commit record above, MyXactMadeXLogEntry
792 * will certainly be set now.
794 if (MyXactMadeXLogEntry)
797 * Sleep before flush! So we can flush more than one commit
798 * records per single fsync. (The idea is some other backend may
799 * do the XLogFlush while we're sleeping. This needs work still,
800 * because on most Unixen, the minimum select() delay is 10msec or
801 * more, which is way too long.)
803 * We do not sleep if enableFsync is not turned on, nor if there
804 * are fewer than CommitSiblings other backends with active
807 if (CommitDelay > 0 && enableFsync &&
808 CountActiveBackends() >= CommitSiblings)
809 pg_usleep(CommitDelay);
815 * We must mark the transaction committed in clog if its XID appears
816 * either in permanent rels or in local temporary rels. We test this
817 * by seeing if we made transaction-controlled entries *OR* local-rel
818 * tuple updates. Note that if we made only the latter, we have not
819 * emitted an XLOG record for our commit, and so in the event of a
820 * crash the clog update might be lost. This is okay because no one
821 * else will ever care whether we committed.
823 if (madeTCentries || MyXactMadeTempRelUpdate)
825 TransactionIdCommit(xid);
826 /* to avoid race conditions, the parent must commit first */
827 TransactionIdCommitTree(nchildren, children);
830 /* Checkpoint can proceed now */
831 MyProc->inCommit = false;
836 /* Break the chain of back-links in the XLOG records I output */
837 MyLastRecPtr.xrecoff = 0;
838 MyXactMadeXLogEntry = false;
839 MyXactMadeTempRelUpdate = false;
841 /* And clean up local data */
850 * AtCommit_LocalCache
853 AtCommit_LocalCache(void)
856 * Make catalog changes visible to me for the next command.
858 CommandEndInvalidationMessages();
865 AtCommit_Memory(void)
868 * Now that we're "out" of a transaction, have the system allocate things
869 * in the top memory context instead of per-transaction contexts.
871 MemoryContextSwitchTo(TopMemoryContext);
874 * Release all transaction-local memory.
876 Assert(TopTransactionContext != NULL);
877 MemoryContextDelete(TopTransactionContext);
878 TopTransactionContext = NULL;
879 CurTransactionContext = NULL;
880 CurrentTransactionState->curTransactionContext = NULL;
883 /* ----------------------------------------------------------------
884 * CommitSubTransaction stuff
885 * ----------------------------------------------------------------
892 AtSubCommit_Memory(void)
894 TransactionState s = CurrentTransactionState;
896 Assert(s->parent != NULL);
898 /* Return to parent transaction level's memory context. */
899 CurTransactionContext = s->parent->curTransactionContext;
900 MemoryContextSwitchTo(CurTransactionContext);
903 * Ordinarily we cannot throw away the child's CurTransactionContext,
904 * since the data it contains will be needed at upper commit. However, if
905 * there isn't actually anything in it, we can throw it away. This avoids
906 * a small memory leak in the common case of "trivial" subxacts.
908 if (MemoryContextIsEmpty(s->curTransactionContext))
910 MemoryContextDelete(s->curTransactionContext);
911 s->curTransactionContext = NULL;
916 * AtSubCommit_childXids
918 * Pass my own XID and my child XIDs up to my parent as committed children.
921 AtSubCommit_childXids(void)
923 TransactionState s = CurrentTransactionState;
924 MemoryContext old_cxt;
926 Assert(s->parent != NULL);
929 * We keep the child-XID lists in TopTransactionContext; this avoids
930 * setting up child-transaction contexts for what might be just a few
931 * bytes of grandchild XIDs.
933 old_cxt = MemoryContextSwitchTo(TopTransactionContext);
935 s->parent->childXids = lappend_xid(s->parent->childXids,
938 if (s->childXids != NIL)
940 s->parent->childXids = list_concat(s->parent->childXids,
944 * list_concat doesn't free the list header for the second list; do so
945 * here to avoid memory leakage (kluge)
951 MemoryContextSwitchTo(old_cxt);
955 * RecordSubTransactionCommit
958 RecordSubTransactionCommit(void)
961 * We do not log the subcommit in XLOG; it doesn't matter until the
962 * top-level transaction commits.
964 * We must mark the subtransaction subcommitted in clog if its XID appears
965 * either in permanent rels or in local temporary rels. We test this by
966 * seeing if we made transaction-controlled entries *OR* local-rel tuple
967 * updates. (The test here actually covers the entire transaction tree so
968 * far, so it may mark subtransactions that don't really need it, but it's
969 * probably not worth being tenser. Note that if a prior subtransaction
970 * dirtied these variables, then RecordTransactionCommit will have to do
971 * the full pushup anyway...)
973 if (MyLastRecPtr.xrecoff != 0 || MyXactMadeTempRelUpdate)
975 TransactionId xid = GetCurrentTransactionId();
977 /* XXX does this really need to be a critical section? */
978 START_CRIT_SECTION();
980 /* Record subtransaction subcommit */
981 TransactionIdSubCommit(xid);
987 /* ----------------------------------------------------------------
988 * AbortTransaction stuff
989 * ----------------------------------------------------------------
993 * RecordTransactionAbort
996 RecordTransactionAbort(void)
1001 TransactionId *children;
1003 /* Get data needed for abort record */
1004 nrels = smgrGetPendingDeletes(false, &rels);
1005 nchildren = xactGetCommittedChildren(&children);
1008 * If we made neither any transaction-controlled XLOG entries nor any
1009 * temp-rel updates, and are not going to delete any files, we can omit
1010 * recording the transaction abort at all. No one will ever care that it
1011 * aborted. (These tests cover our whole transaction tree.)
1013 if (MyLastRecPtr.xrecoff != 0 || MyXactMadeTempRelUpdate || nrels > 0)
1015 TransactionId xid = GetCurrentTransactionId();
1018 * Catch the scenario where we aborted partway through
1019 * RecordTransactionCommit ...
1021 if (TransactionIdDidCommit(xid))
1022 elog(PANIC, "cannot abort transaction %u, it was already committed", xid);
1024 START_CRIT_SECTION();
1027 * We only need to log the abort in XLOG if the transaction made any
1028 * transaction-controlled XLOG entries or will delete files. (If it
1029 * made no transaction-controlled XLOG entries, its XID appears
1030 * nowhere in permanent storage, so no one else will ever care if it
1033 * We do not flush XLOG to disk unless deleting files, since the
1034 * default assumption after a crash would be that we aborted, anyway.
1035 * For the same reason, we don't need to worry about interlocking
1036 * against checkpoint start.
1038 if (MyLastRecPtr.xrecoff != 0 || nrels > 0)
1040 XLogRecData rdata[3];
1042 xl_xact_abort xlrec;
1045 xlrec.xtime = time(NULL);
1046 xlrec.nrels = nrels;
1047 xlrec.nsubxacts = nchildren;
1048 rdata[0].data = (char *) (&xlrec);
1049 rdata[0].len = MinSizeOfXactAbort;
1050 rdata[0].buffer = InvalidBuffer;
1051 /* dump rels to delete */
1054 rdata[0].next = &(rdata[1]);
1055 rdata[1].data = (char *) rels;
1056 rdata[1].len = nrels * sizeof(RelFileNode);
1057 rdata[1].buffer = InvalidBuffer;
1060 /* dump committed child Xids */
1063 rdata[lastrdata].next = &(rdata[2]);
1064 rdata[2].data = (char *) children;
1065 rdata[2].len = nchildren * sizeof(TransactionId);
1066 rdata[2].buffer = InvalidBuffer;
1069 rdata[lastrdata].next = NULL;
1071 recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
1073 /* Must flush if we are deleting files... */
1079 * Mark the transaction aborted in clog. This is not absolutely
1080 * necessary but we may as well do it while we are here.
1082 * The ordering here isn't critical but it seems best to mark the
1083 * parent first. This assures an atomic transition of all the
1084 * subtransactions to aborted state from the point of view of
1085 * concurrent TransactionIdDidAbort calls.
1087 TransactionIdAbort(xid);
1088 TransactionIdAbortTree(nchildren, children);
1093 /* Break the chain of back-links in the XLOG records I output */
1094 MyLastRecPtr.xrecoff = 0;
1095 MyXactMadeXLogEntry = false;
1096 MyXactMadeTempRelUpdate = false;
1098 /* And clean up local data */
1109 AtAbort_Memory(void)
1112 * Switch into TransactionAbortContext, which should have some free
1113 * space even if nothing else does. We'll work in this context until
1114 * we've finished cleaning up.
1116 * It is barely possible to get here when we've not been able to create
1117 * TransactionAbortContext yet; if so use TopMemoryContext.
1119 if (TransactionAbortContext != NULL)
1120 MemoryContextSwitchTo(TransactionAbortContext);
1122 MemoryContextSwitchTo(TopMemoryContext);
1129 AtSubAbort_Memory(void)
1131 Assert(TransactionAbortContext != NULL);
1133 MemoryContextSwitchTo(TransactionAbortContext);
1138 * AtAbort_ResourceOwner
1141 AtAbort_ResourceOwner(void)
1144 * Make sure we have a valid ResourceOwner, if possible (else it will be
1145 * NULL, which is OK)
1147 CurrentResourceOwner = TopTransactionResourceOwner;
1151 * AtSubAbort_ResourceOwner
1154 AtSubAbort_ResourceOwner(void)
1156 TransactionState s = CurrentTransactionState;
1158 /* Make sure we have a valid ResourceOwner */
1159 CurrentResourceOwner = s->curTransactionOwner;
1164 * AtSubAbort_childXids
1167 AtSubAbort_childXids(void)
1169 TransactionState s = CurrentTransactionState;
1172 * We keep the child-XID lists in TopTransactionContext (see
1173 * AtSubCommit_childXids). This means we'd better free the list
1174 * explicitly at abort to avoid leakage.
1176 list_free(s->childXids);
1181 * RecordSubTransactionAbort
1184 RecordSubTransactionAbort(void)
1188 TransactionId xid = GetCurrentTransactionId();
1190 TransactionId *children;
1192 /* Get data needed for abort record */
1193 nrels = smgrGetPendingDeletes(false, &rels);
1194 nchildren = xactGetCommittedChildren(&children);
1197 * If we made neither any transaction-controlled XLOG entries nor any
1198 * temp-rel updates, and are not going to delete any files, we can omit
1199 * recording the transaction abort at all. No one will ever care that it
1200 * aborted. (These tests cover our whole transaction tree, and therefore
1201 * may mark subxacts that don't really need it, but it's probably not
1202 * worth being tenser.)
1204 * In this case we needn't worry about marking subcommitted children as
1205 * aborted, because they didn't mark themselves as subcommitted in the
1206 * first place; see the optimization in RecordSubTransactionCommit.
1208 if (MyLastRecPtr.xrecoff != 0 || MyXactMadeTempRelUpdate || nrels > 0)
1210 START_CRIT_SECTION();
1213 * We only need to log the abort in XLOG if the transaction made any
1214 * transaction-controlled XLOG entries or will delete files.
1216 if (MyLastRecPtr.xrecoff != 0 || nrels > 0)
1218 XLogRecData rdata[3];
1220 xl_xact_abort xlrec;
1223 xlrec.xtime = time(NULL);
1224 xlrec.nrels = nrels;
1225 xlrec.nsubxacts = nchildren;
1226 rdata[0].data = (char *) (&xlrec);
1227 rdata[0].len = MinSizeOfXactAbort;
1228 rdata[0].buffer = InvalidBuffer;
1229 /* dump rels to delete */
1232 rdata[0].next = &(rdata[1]);
1233 rdata[1].data = (char *) rels;
1234 rdata[1].len = nrels * sizeof(RelFileNode);
1235 rdata[1].buffer = InvalidBuffer;
1238 /* dump committed child Xids */
1241 rdata[lastrdata].next = &(rdata[2]);
1242 rdata[2].data = (char *) children;
1243 rdata[2].len = nchildren * sizeof(TransactionId);
1244 rdata[2].buffer = InvalidBuffer;
1247 rdata[lastrdata].next = NULL;
1249 recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
1251 /* Must flush if we are deleting files... */
1257 * Mark the transaction aborted in clog. This is not absolutely
1258 * necessary but XactLockTableWait makes use of it to avoid waiting
1259 * for already-aborted subtransactions.
1261 TransactionIdAbort(xid);
1262 TransactionIdAbortTree(nchildren, children);
1268 * We can immediately remove failed XIDs from PGPROC's cache of running
1269 * child XIDs. It's easiest to do it here while we have the child XID
1270 * array at hand, even though in the main-transaction case the equivalent
1271 * work happens just after return from RecordTransactionAbort.
1273 XidCacheRemoveRunningXids(xid, nchildren, children);
1275 /* And clean up local data */
1282 /* ----------------------------------------------------------------
1283 * CleanupTransaction stuff
1284 * ----------------------------------------------------------------
1291 AtCleanup_Memory(void)
1293 Assert(CurrentTransactionState->parent == NULL);
1296 * Now that we're "out" of a transaction, have the system allocate things
1297 * in the top memory context instead of per-transaction contexts.
1299 MemoryContextSwitchTo(TopMemoryContext);
1302 * Clear the special abort context for next time.
1304 if (TransactionAbortContext != NULL)
1305 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1308 * Release all transaction-local memory.
1310 if (TopTransactionContext != NULL)
1311 MemoryContextDelete(TopTransactionContext);
1312 TopTransactionContext = NULL;
1313 CurTransactionContext = NULL;
1314 CurrentTransactionState->curTransactionContext = NULL;
1318 /* ----------------------------------------------------------------
1319 * CleanupSubTransaction stuff
1320 * ----------------------------------------------------------------
1324 * AtSubCleanup_Memory
1327 AtSubCleanup_Memory(void)
1329 TransactionState s = CurrentTransactionState;
1331 Assert(s->parent != NULL);
1333 /* Make sure we're not in an about-to-be-deleted context */
1334 MemoryContextSwitchTo(s->parent->curTransactionContext);
1335 CurTransactionContext = s->parent->curTransactionContext;
1338 * Clear the special abort context for next time.
1340 if (TransactionAbortContext != NULL)
1341 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1344 * Delete the subxact local memory contexts. Its CurTransactionContext can
1345 * go too (note this also kills CurTransactionContexts from any children
1348 if (s->curTransactionContext)
1349 MemoryContextDelete(s->curTransactionContext);
1350 s->curTransactionContext = NULL;
1353 /* ----------------------------------------------------------------
1354 * interface routines
1355 * ----------------------------------------------------------------
1362 StartTransaction(void)
1367 * Let's just make sure the state stack is empty
1369 s = &TopTransactionStateData;
1370 CurrentTransactionState = s;
1373 * check the current transaction state
1375 if (s->state != TRANS_DEFAULT)
1376 elog(WARNING, "StartTransaction while in %s state",
1377 TransStateAsString(s->state));
1380 * set the current transaction state information appropriately during
1383 s->state = TRANS_START;
1384 s->transactionId = InvalidTransactionId; /* until assigned */
1387 * Make sure we've freed any old snapshot, and reset xact state variables
1390 XactIsoLevel = DefaultXactIsoLevel;
1391 XactReadOnly = DefaultXactReadOnly;
1394 * reinitialize within-transaction counters
1396 s->subTransactionId = TopSubTransactionId;
1397 currentSubTransactionId = TopSubTransactionId;
1398 currentCommandId = FirstCommandId;
1401 * must initialize resource-management stuff first
1404 AtStart_ResourceOwner();
1407 * generate a new transaction id
1409 s->transactionId = GetNewTransactionId(false);
1411 XactLockTableInsert(s->transactionId);
1413 PG_TRACE1(transaction__start, s->transactionId);
1416 * set transaction_timestamp() (a/k/a now()). We want this to be the same
1417 * as the first command's statement_timestamp(), so don't do a fresh
1418 * GetCurrentTimestamp() call (which'd be expensive anyway).
1420 xactStartTimestamp = stmtStartTimestamp;
1421 pgstat_report_txn_timestamp(xactStartTimestamp);
1424 * initialize current transaction state fields
1426 s->nestingLevel = 1;
1430 * You might expect to see "s->currentUser = GetUserId();" here, but you
1431 * won't because it doesn't work during startup; the userid isn't set yet
1432 * during a backend's first transaction start. We only use the
1433 * currentUser field in sub-transaction state structs.
1435 * prevXactReadOnly is also valid only in sub-transactions.
1439 * initialize other subsystems for new transaction
1443 AfterTriggerBeginXact();
1446 * done with start processing, set current transaction state to "in
1449 s->state = TRANS_INPROGRESS;
1451 ShowTransactionState("StartTransaction");
1458 * NB: if you change this routine, better look at PrepareTransaction too!
1461 CommitTransaction(void)
1463 TransactionState s = CurrentTransactionState;
1465 ShowTransactionState("CommitTransaction");
1468 * check the current transaction state
1470 if (s->state != TRANS_INPROGRESS)
1471 elog(WARNING, "CommitTransaction while in %s state",
1472 TransStateAsString(s->state));
1473 Assert(s->parent == NULL);
1476 * Do pre-commit processing (most of this stuff requires database access,
1477 * and in fact could still cause an error...)
1479 * It is possible for CommitHoldablePortals to invoke functions that queue
1480 * deferred triggers, and it's also possible that triggers create holdable
1481 * cursors. So we have to loop until there's nothing left to do.
1486 * Fire all currently pending deferred triggers.
1488 AfterTriggerFireDeferred();
1491 * Convert any open holdable cursors into static portals. If there
1492 * weren't any, we are done ... otherwise loop back to check if they
1493 * queued deferred triggers. Lather, rinse, repeat.
1495 if (!CommitHoldablePortals())
1499 /* Now we can shut down the deferred-trigger manager */
1500 AfterTriggerEndXact(true);
1502 /* Close any open regular cursors */
1506 * Let ON COMMIT management do its thing (must happen after closing
1507 * cursors, to avoid dangling-reference problems)
1509 PreCommit_on_commit_actions();
1511 /* close large objects before lower-level cleanup */
1512 AtEOXact_LargeObject(true);
1514 /* NOTIFY commit must come before lower-level cleanup */
1518 * Update flat files if we changed pg_database, pg_authid or
1519 * pg_auth_members. This should be the last step before commit.
1521 AtEOXact_UpdateFlatFiles(true);
1523 /* Prevent cancel/die interrupt while cleaning up */
1527 * set the current transaction state information appropriately during
1530 s->state = TRANS_COMMIT;
1533 * Here is where we really truly commit.
1535 RecordTransactionCommit();
1538 * Let others know about no transaction in progress by me. Note that
1539 * this must be done _before_ releasing locks we hold and _after_
1540 * RecordTransactionCommit.
1542 * LWLockAcquire(ProcArrayLock) is required; consider this example:
1543 * UPDATE with xid 0 is blocked by xid 1's UPDATE.
1544 * xid 1 is doing commit while xid 2 gets snapshot.
1545 * If xid 2's GetSnapshotData sees xid 1 as running then it must see
1546 * xid 0 as running as well, or it will be able to see two tuple versions
1547 * - one deleted by xid 1 and one inserted by xid 0. See notes in
1550 * Note: MyProc may be null during bootstrap.
1555 /* Lock ProcArrayLock because that's what GetSnapshotData uses. */
1556 LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
1557 MyProc->xid = InvalidTransactionId;
1558 MyProc->xmin = InvalidTransactionId;
1559 MyProc->inVacuum = false; /* must be cleared with xid/xmin */
1561 /* Clear the subtransaction-XID cache too while holding the lock */
1562 MyProc->subxids.nxids = 0;
1563 MyProc->subxids.overflowed = false;
1565 LWLockRelease(ProcArrayLock);
1568 PG_TRACE1(transaction__commit, s->transactionId);
1571 * This is all post-commit cleanup. Note that if an error is raised here,
1572 * it's too late to abort the transaction. This should be just
1573 * noncritical resource releasing.
1575 * The ordering of operations is not entirely random. The idea is:
1576 * release resources visible to other backends (eg, files, buffer pins);
1577 * then release locks; then release backend-local resources. We want to
1578 * release locks at the point where any backend waiting for us will see
1579 * our transaction as being fully cleaned up.
1581 * Resources that can be associated with individual queries are handled by
1582 * the ResourceOwner mechanism. The other calls here are for backend-wide
1586 CallXactCallbacks(XACT_EVENT_COMMIT);
1588 ResourceOwnerRelease(TopTransactionResourceOwner,
1589 RESOURCE_RELEASE_BEFORE_LOCKS,
1592 /* Check we've released all buffer pins */
1593 AtEOXact_Buffers(true);
1595 /* Clean up the relation cache */
1596 AtEOXact_RelationCache(true);
1599 * Make catalog changes visible to all backends. This has to happen after
1600 * relcache references are dropped (see comments for
1601 * AtEOXact_RelationCache), but before locks are released (if anyone is
1602 * waiting for lock on a relation we've modified, we want them to know
1603 * about the catalog change before they start using the relation).
1605 AtEOXact_Inval(true);
1608 * Likewise, dropping of files deleted during the transaction is best done
1609 * after releasing relcache and buffer pins. (This is not strictly
1610 * necessary during commit, since such pins should have been released
1611 * already, but this ordering is definitely critical during abort.)
1613 smgrDoPendingDeletes(true);
1615 AtEOXact_MultiXact();
1617 ResourceOwnerRelease(TopTransactionResourceOwner,
1618 RESOURCE_RELEASE_LOCKS,
1620 ResourceOwnerRelease(TopTransactionResourceOwner,
1621 RESOURCE_RELEASE_AFTER_LOCKS,
1624 /* Check we've released all catcache entries */
1625 AtEOXact_CatCache(true);
1627 AtEOXact_GUC(true, false);
1629 AtEOXact_on_commit_actions(true);
1630 AtEOXact_Namespace(true);
1631 /* smgrcommit already done */
1633 AtEOXact_ComboCid();
1634 AtEOXact_HashTables(true);
1635 pgstat_clear_snapshot();
1636 pgstat_count_xact_commit();
1637 pgstat_report_txn_timestamp(0);
1639 CurrentResourceOwner = NULL;
1640 ResourceOwnerDelete(TopTransactionResourceOwner);
1641 s->curTransactionOwner = NULL;
1642 CurTransactionResourceOwner = NULL;
1643 TopTransactionResourceOwner = NULL;
1647 s->transactionId = InvalidTransactionId;
1648 s->subTransactionId = InvalidSubTransactionId;
1649 s->nestingLevel = 0;
1653 * done with commit processing, set current transaction state back to
1656 s->state = TRANS_DEFAULT;
1658 RESUME_INTERRUPTS();
1663 * PrepareTransaction
1665 * NB: if you change this routine, better look at CommitTransaction too!
1668 PrepareTransaction(void)
1670 TransactionState s = CurrentTransactionState;
1671 TransactionId xid = GetCurrentTransactionId();
1672 GlobalTransaction gxact;
1673 TimestampTz prepared_at;
1675 ShowTransactionState("PrepareTransaction");
1678 * check the current transaction state
1680 if (s->state != TRANS_INPROGRESS)
1681 elog(WARNING, "PrepareTransaction while in %s state",
1682 TransStateAsString(s->state));
1683 Assert(s->parent == NULL);
1686 * Do pre-commit processing (most of this stuff requires database access,
1687 * and in fact could still cause an error...)
1689 * It is possible for PrepareHoldablePortals to invoke functions that
1690 * queue deferred triggers, and it's also possible that triggers create
1691 * holdable cursors. So we have to loop until there's nothing left to do.
1696 * Fire all currently pending deferred triggers.
1698 AfterTriggerFireDeferred();
1701 * Convert any open holdable cursors into static portals. If there
1702 * weren't any, we are done ... otherwise loop back to check if they
1703 * queued deferred triggers. Lather, rinse, repeat.
1705 if (!PrepareHoldablePortals())
1709 /* Now we can shut down the deferred-trigger manager */
1710 AfterTriggerEndXact(true);
1712 /* Close any open regular cursors */
1716 * Let ON COMMIT management do its thing (must happen after closing
1717 * cursors, to avoid dangling-reference problems)
1719 PreCommit_on_commit_actions();
1721 /* close large objects before lower-level cleanup */
1722 AtEOXact_LargeObject(true);
1724 /* NOTIFY and flatfiles will be handled below */
1726 /* Prevent cancel/die interrupt while cleaning up */
1730 * set the current transaction state information appropriately during
1731 * prepare processing
1733 s->state = TRANS_PREPARE;
1735 prepared_at = GetCurrentTimestamp();
1737 /* Tell bufmgr and smgr to prepare for commit */
1741 * Reserve the GID for this transaction. This could fail if the requested
1742 * GID is invalid or already in use.
1744 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
1745 GetUserId(), MyDatabaseId);
1749 * Collect data for the 2PC state file. Note that in general, no actual
1750 * state change should happen in the called modules during this step,
1751 * since it's still possible to fail before commit, and in that case we
1752 * want transaction abort to be able to clean up. (In particular, the
1753 * AtPrepare routines may error out if they find cases they cannot
1754 * handle.) State cleanup should happen in the PostPrepare routines
1755 * below. However, some modules can go ahead and clear state here because
1756 * they wouldn't do anything with it during abort anyway.
1758 * Note: because the 2PC state file records will be replayed in the same
1759 * order they are made, the order of these calls has to match the order in
1760 * which we want things to happen during COMMIT PREPARED or ROLLBACK
1761 * PREPARED; in particular, pay attention to whether things should happen
1762 * before or after releasing the transaction's locks.
1764 StartPrepare(gxact);
1767 AtPrepare_UpdateFlatFiles();
1772 * Here is where we really truly prepare.
1774 * We have to record transaction prepares even if we didn't make any
1775 * updates, because the transaction manager might get confused if we lose
1776 * a global transaction.
1781 * Now we clean up backend-internal state and release internal resources.
1784 /* Break the chain of back-links in the XLOG records I output */
1785 MyLastRecPtr.xrecoff = 0;
1786 MyXactMadeXLogEntry = false;
1787 MyXactMadeTempRelUpdate = false;
1790 * Let others know about no transaction in progress by me. This has to be
1791 * done *after* the prepared transaction has been marked valid, else
1792 * someone may think it is unlocked and recyclable.
1795 /* Lock ProcArrayLock because that's what GetSnapshotData uses. */
1796 LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
1797 MyProc->xid = InvalidTransactionId;
1798 MyProc->xmin = InvalidTransactionId;
1799 MyProc->inVacuum = false; /* must be cleared with xid/xmin */
1801 /* Clear the subtransaction-XID cache too while holding the lock */
1802 MyProc->subxids.nxids = 0;
1803 MyProc->subxids.overflowed = false;
1805 LWLockRelease(ProcArrayLock);
1808 * This is all post-transaction cleanup. Note that if an error is raised
1809 * here, it's too late to abort the transaction. This should be just
1810 * noncritical resource releasing. See notes in CommitTransaction.
1813 CallXactCallbacks(XACT_EVENT_PREPARE);
1815 ResourceOwnerRelease(TopTransactionResourceOwner,
1816 RESOURCE_RELEASE_BEFORE_LOCKS,
1819 /* Check we've released all buffer pins */
1820 AtEOXact_Buffers(true);
1822 /* Clean up the relation cache */
1823 AtEOXact_RelationCache(true);
1825 /* notify and flatfiles don't need a postprepare call */
1827 PostPrepare_Inval();
1831 AtEOXact_MultiXact();
1833 PostPrepare_Locks(xid);
1835 ResourceOwnerRelease(TopTransactionResourceOwner,
1836 RESOURCE_RELEASE_LOCKS,
1838 ResourceOwnerRelease(TopTransactionResourceOwner,
1839 RESOURCE_RELEASE_AFTER_LOCKS,
1842 /* Check we've released all catcache entries */
1843 AtEOXact_CatCache(true);
1845 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
1846 AtEOXact_GUC(true, false);
1848 AtEOXact_on_commit_actions(true);
1849 AtEOXact_Namespace(true);
1850 /* smgrcommit already done */
1852 AtEOXact_ComboCid();
1853 AtEOXact_HashTables(true);
1854 pgstat_clear_snapshot();
1856 CurrentResourceOwner = NULL;
1857 ResourceOwnerDelete(TopTransactionResourceOwner);
1858 s->curTransactionOwner = NULL;
1859 CurTransactionResourceOwner = NULL;
1860 TopTransactionResourceOwner = NULL;
1864 s->transactionId = InvalidTransactionId;
1865 s->subTransactionId = InvalidSubTransactionId;
1866 s->nestingLevel = 0;
1870 * done with 1st phase commit processing, set current transaction state
1873 s->state = TRANS_DEFAULT;
1875 RESUME_INTERRUPTS();
1883 AbortTransaction(void)
1885 TransactionState s = CurrentTransactionState;
1887 /* Prevent cancel/die interrupt while cleaning up */
1890 /* Make sure we have a valid memory context and resource owner */
1892 AtAbort_ResourceOwner();
1895 * Release any LW locks we might be holding as quickly as possible.
1896 * (Regular locks, however, must be held till we finish aborting.)
1897 * Releasing LW locks is critical since we might try to grab them again
1898 * while cleaning up!
1902 /* Clean up buffer I/O and buffer context locks, too */
1907 * Also clean up any open wait for lock, since the lock manager will choke
1908 * if we try to wait for another lock before doing this.
1913 * check the current transaction state
1915 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
1916 elog(WARNING, "AbortTransaction while in %s state",
1917 TransStateAsString(s->state));
1918 Assert(s->parent == NULL);
1921 * set the current transaction state information appropriately during the
1924 s->state = TRANS_ABORT;
1927 * Reset user id which might have been changed transiently. We cannot use
1928 * s->currentUser, since it may not be set yet; instead rely on internal
1929 * state of miscinit.c.
1931 * (Note: it is not necessary to restore session authorization here
1932 * because that can only be changed via GUC, and GUC will take care of
1933 * rolling it back if need be. However, an error within a SECURITY
1934 * DEFINER function could send control here with the wrong current
1940 * do abort processing
1942 AfterTriggerEndXact(false);
1944 AtEOXact_LargeObject(false); /* 'false' means it's abort */
1946 AtEOXact_UpdateFlatFiles(false);
1949 * Advertise the fact that we aborted in pg_clog (assuming that we got as
1950 * far as assigning an XID to advertise).
1952 if (TransactionIdIsValid(s->transactionId))
1953 RecordTransactionAbort();
1956 * Let others know about no transaction in progress by me. Note that this
1957 * must be done _before_ releasing locks we hold and _after_
1958 * RecordTransactionAbort.
1962 /* Lock ProcArrayLock because that's what GetSnapshotData uses. */
1963 LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
1964 MyProc->xid = InvalidTransactionId;
1965 MyProc->xmin = InvalidTransactionId;
1966 MyProc->inVacuum = false; /* must be cleared with xid/xmin */
1967 MyProc->inCommit = false; /* be sure this gets cleared */
1969 /* Clear the subtransaction-XID cache too while holding the lock */
1970 MyProc->subxids.nxids = 0;
1971 MyProc->subxids.overflowed = false;
1973 LWLockRelease(ProcArrayLock);
1976 PG_TRACE1(transaction__abort, s->transactionId);
1979 * Post-abort cleanup. See notes in CommitTransaction() concerning
1983 CallXactCallbacks(XACT_EVENT_ABORT);
1985 ResourceOwnerRelease(TopTransactionResourceOwner,
1986 RESOURCE_RELEASE_BEFORE_LOCKS,
1988 AtEOXact_Buffers(false);
1989 AtEOXact_RelationCache(false);
1990 AtEOXact_Inval(false);
1991 smgrDoPendingDeletes(false);
1992 AtEOXact_MultiXact();
1993 ResourceOwnerRelease(TopTransactionResourceOwner,
1994 RESOURCE_RELEASE_LOCKS,
1996 ResourceOwnerRelease(TopTransactionResourceOwner,
1997 RESOURCE_RELEASE_AFTER_LOCKS,
1999 AtEOXact_CatCache(false);
2001 AtEOXact_GUC(false, false);
2002 AtEOXact_SPI(false);
2003 AtEOXact_on_commit_actions(false);
2004 AtEOXact_Namespace(false);
2007 AtEOXact_ComboCid();
2008 AtEOXact_HashTables(false);
2009 pgstat_clear_snapshot();
2010 pgstat_count_xact_rollback();
2011 pgstat_report_txn_timestamp(0);
2014 * State remains TRANS_ABORT until CleanupTransaction().
2016 RESUME_INTERRUPTS();
2020 * CleanupTransaction
2023 CleanupTransaction(void)
2025 TransactionState s = CurrentTransactionState;
2028 * State should still be TRANS_ABORT from AbortTransaction().
2030 if (s->state != TRANS_ABORT)
2031 elog(FATAL, "CleanupTransaction: unexpected state %s",
2032 TransStateAsString(s->state));
2035 * do abort cleanup processing
2037 AtCleanup_Portals(); /* now safe to release portal memory */
2039 CurrentResourceOwner = NULL; /* and resource owner */
2040 if (TopTransactionResourceOwner)
2041 ResourceOwnerDelete(TopTransactionResourceOwner);
2042 s->curTransactionOwner = NULL;
2043 CurTransactionResourceOwner = NULL;
2044 TopTransactionResourceOwner = NULL;
2046 AtCleanup_Memory(); /* and transaction memory */
2048 s->transactionId = InvalidTransactionId;
2049 s->subTransactionId = InvalidSubTransactionId;
2050 s->nestingLevel = 0;
2054 * done with abort processing, set current transaction state back to
2057 s->state = TRANS_DEFAULT;
2061 * StartTransactionCommand
2064 StartTransactionCommand(void)
2066 TransactionState s = CurrentTransactionState;
2068 switch (s->blockState)
2071 * if we aren't in a transaction block, we just do our usual start
2074 case TBLOCK_DEFAULT:
2076 s->blockState = TBLOCK_STARTED;
2080 * We are somewhere in a transaction block or subtransaction and
2081 * about to start a new command. For now we do nothing, but
2082 * someday we may do command-local resource initialization. (Note
2083 * that any needed CommandCounterIncrement was done by the
2084 * previous CommitTransactionCommand.)
2086 case TBLOCK_INPROGRESS:
2087 case TBLOCK_SUBINPROGRESS:
2091 * Here we are in a failed transaction block (one of the commands
2092 * caused an abort) so we do nothing but remain in the abort
2093 * state. Eventually we will get a ROLLBACK command which will
2094 * get us out of this state. (It is up to other code to ensure
2095 * that no commands other than ROLLBACK will be processed in these
2099 case TBLOCK_SUBABORT:
2102 /* These cases are invalid. */
2103 case TBLOCK_STARTED:
2105 case TBLOCK_SUBBEGIN:
2108 case TBLOCK_ABORT_END:
2109 case TBLOCK_SUBABORT_END:
2110 case TBLOCK_ABORT_PENDING:
2111 case TBLOCK_SUBABORT_PENDING:
2112 case TBLOCK_SUBRESTART:
2113 case TBLOCK_SUBABORT_RESTART:
2114 case TBLOCK_PREPARE:
2115 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2116 BlockStateAsString(s->blockState));
2121 * We must switch to CurTransactionContext before returning. This is
2122 * already done if we called StartTransaction, otherwise not.
2124 Assert(CurTransactionContext != NULL);
2125 MemoryContextSwitchTo(CurTransactionContext);
2129 * CommitTransactionCommand
2132 CommitTransactionCommand(void)
2134 TransactionState s = CurrentTransactionState;
2136 switch (s->blockState)
2139 * This shouldn't happen, because it means the previous
2140 * StartTransactionCommand didn't set the STARTED state
2143 case TBLOCK_DEFAULT:
2144 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2145 BlockStateAsString(s->blockState));
2149 * If we aren't in a transaction block, just do our usual
2150 * transaction commit, and return to the idle state.
2152 case TBLOCK_STARTED:
2153 CommitTransaction();
2154 s->blockState = TBLOCK_DEFAULT;
2158 * We are completing a "BEGIN TRANSACTION" command, so we change
2159 * to the "transaction block in progress" state and return. (We
2160 * assume the BEGIN did nothing to the database, so we need no
2161 * CommandCounterIncrement.)
2164 s->blockState = TBLOCK_INPROGRESS;
2168 * This is the case when we have finished executing a command
2169 * someplace within a transaction block. We increment the command
2170 * counter and return.
2172 case TBLOCK_INPROGRESS:
2173 case TBLOCK_SUBINPROGRESS:
2174 CommandCounterIncrement();
2178 * We are completing a "COMMIT" command. Do it and return to the
2182 CommitTransaction();
2183 s->blockState = TBLOCK_DEFAULT;
2187 * Here we are in the middle of a transaction block but one of the
2188 * commands caused an abort so we do nothing but remain in the
2189 * abort state. Eventually we will get a ROLLBACK comand.
2192 case TBLOCK_SUBABORT:
2196 * Here we were in an aborted transaction block and we just got
2197 * the ROLLBACK command from the user, so clean up the
2198 * already-aborted transaction and return to the idle state.
2200 case TBLOCK_ABORT_END:
2201 CleanupTransaction();
2202 s->blockState = TBLOCK_DEFAULT;
2206 * Here we were in a perfectly good transaction block but the user
2207 * told us to ROLLBACK anyway. We have to abort the transaction
2208 * and then clean up.
2210 case TBLOCK_ABORT_PENDING:
2212 CleanupTransaction();
2213 s->blockState = TBLOCK_DEFAULT;
2217 * We are completing a "PREPARE TRANSACTION" command. Do it and
2218 * return to the idle state.
2220 case TBLOCK_PREPARE:
2221 PrepareTransaction();
2222 s->blockState = TBLOCK_DEFAULT;
2226 * We were just issued a SAVEPOINT inside a transaction block.
2227 * Start a subtransaction. (DefineSavepoint already did
2228 * PushTransaction, so as to have someplace to put the SUBBEGIN
2231 case TBLOCK_SUBBEGIN:
2232 StartSubTransaction();
2233 s->blockState = TBLOCK_SUBINPROGRESS;
2237 * We were issued a COMMIT or RELEASE command, so we end the
2238 * current subtransaction and return to the parent transaction.
2239 * The parent might be ended too, so repeat till we are all the
2240 * way out or find an INPROGRESS transaction.
2245 CommitSubTransaction();
2246 s = CurrentTransactionState; /* changed by pop */
2247 } while (s->blockState == TBLOCK_SUBEND);
2248 /* If we had a COMMIT command, finish off the main xact too */
2249 if (s->blockState == TBLOCK_END)
2251 Assert(s->parent == NULL);
2252 CommitTransaction();
2253 s->blockState = TBLOCK_DEFAULT;
2255 else if (s->blockState == TBLOCK_PREPARE)
2257 Assert(s->parent == NULL);
2258 PrepareTransaction();
2259 s->blockState = TBLOCK_DEFAULT;
2263 Assert(s->blockState == TBLOCK_INPROGRESS ||
2264 s->blockState == TBLOCK_SUBINPROGRESS);
2269 * The current already-failed subtransaction is ending due to a
2270 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2271 * examine the parent (which could be in any of several states).
2273 case TBLOCK_SUBABORT_END:
2274 CleanupSubTransaction();
2275 CommitTransactionCommand();
2279 * As above, but it's not dead yet, so abort first.
2281 case TBLOCK_SUBABORT_PENDING:
2282 AbortSubTransaction();
2283 CleanupSubTransaction();
2284 CommitTransactionCommand();
2288 * The current subtransaction is the target of a ROLLBACK TO
2289 * command. Abort and pop it, then start a new subtransaction
2290 * with the same name.
2292 case TBLOCK_SUBRESTART:
2297 /* save name and keep Cleanup from freeing it */
2300 savepointLevel = s->savepointLevel;
2302 AbortSubTransaction();
2303 CleanupSubTransaction();
2305 DefineSavepoint(NULL);
2306 s = CurrentTransactionState; /* changed by push */
2308 s->savepointLevel = savepointLevel;
2310 /* This is the same as TBLOCK_SUBBEGIN case */
2311 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2312 StartSubTransaction();
2313 s->blockState = TBLOCK_SUBINPROGRESS;
2318 * Same as above, but the subtransaction had already failed, so we
2319 * don't need AbortSubTransaction.
2321 case TBLOCK_SUBABORT_RESTART:
2326 /* save name and keep Cleanup from freeing it */
2329 savepointLevel = s->savepointLevel;
2331 CleanupSubTransaction();
2333 DefineSavepoint(NULL);
2334 s = CurrentTransactionState; /* changed by push */
2336 s->savepointLevel = savepointLevel;
2338 /* This is the same as TBLOCK_SUBBEGIN case */
2339 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2340 StartSubTransaction();
2341 s->blockState = TBLOCK_SUBINPROGRESS;
2348 * AbortCurrentTransaction
2351 AbortCurrentTransaction(void)
2353 TransactionState s = CurrentTransactionState;
2355 switch (s->blockState)
2357 case TBLOCK_DEFAULT:
2358 if (s->state == TRANS_DEFAULT)
2360 /* we are idle, so nothing to do */
2365 * We can get here after an error during transaction start
2366 * (state will be TRANS_START). Need to clean up the
2367 * incompletely started transaction. First, adjust the
2368 * low-level state to suppress warning message from
2371 if (s->state == TRANS_START)
2372 s->state = TRANS_INPROGRESS;
2374 CleanupTransaction();
2379 * if we aren't in a transaction block, we just do the basic abort
2380 * & cleanup transaction.
2382 case TBLOCK_STARTED:
2384 CleanupTransaction();
2385 s->blockState = TBLOCK_DEFAULT;
2389 * If we are in TBLOCK_BEGIN it means something screwed up right
2390 * after reading "BEGIN TRANSACTION". We assume that the user
2391 * will interpret the error as meaning the BEGIN failed to get him
2392 * into a transaction block, so we should abort and return to idle
2397 CleanupTransaction();
2398 s->blockState = TBLOCK_DEFAULT;
2402 * We are somewhere in a transaction block and we've gotten a
2403 * failure, so we abort the transaction and set up the persistent
2404 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
2406 case TBLOCK_INPROGRESS:
2408 s->blockState = TBLOCK_ABORT;
2409 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
2413 * Here, we failed while trying to COMMIT. Clean up the
2414 * transaction and return to idle state (we do not want to stay in
2419 CleanupTransaction();
2420 s->blockState = TBLOCK_DEFAULT;
2424 * Here, we are already in an aborted transaction state and are
2425 * waiting for a ROLLBACK, but for some reason we failed again! So
2426 * we just remain in the abort state.
2429 case TBLOCK_SUBABORT:
2433 * We are in a failed transaction and we got the ROLLBACK command.
2434 * We have already aborted, we just need to cleanup and go to idle
2437 case TBLOCK_ABORT_END:
2438 CleanupTransaction();
2439 s->blockState = TBLOCK_DEFAULT;
2443 * We are in a live transaction and we got a ROLLBACK command.
2444 * Abort, cleanup, go to idle state.
2446 case TBLOCK_ABORT_PENDING:
2448 CleanupTransaction();
2449 s->blockState = TBLOCK_DEFAULT;
2453 * Here, we failed while trying to PREPARE. Clean up the
2454 * transaction and return to idle state (we do not want to stay in
2457 case TBLOCK_PREPARE:
2459 CleanupTransaction();
2460 s->blockState = TBLOCK_DEFAULT;
2464 * We got an error inside a subtransaction. Abort just the
2465 * subtransaction, and go to the persistent SUBABORT state until
2468 case TBLOCK_SUBINPROGRESS:
2469 AbortSubTransaction();
2470 s->blockState = TBLOCK_SUBABORT;
2474 * If we failed while trying to create a subtransaction, clean up
2475 * the broken subtransaction and abort the parent. The same
2476 * applies if we get a failure while ending a subtransaction.
2478 case TBLOCK_SUBBEGIN:
2480 case TBLOCK_SUBABORT_PENDING:
2481 case TBLOCK_SUBRESTART:
2482 AbortSubTransaction();
2483 CleanupSubTransaction();
2484 AbortCurrentTransaction();
2488 * Same as above, except the Abort() was already done.
2490 case TBLOCK_SUBABORT_END:
2491 case TBLOCK_SUBABORT_RESTART:
2492 CleanupSubTransaction();
2493 AbortCurrentTransaction();
2499 * PreventTransactionChain
2501 * This routine is to be called by statements that must not run inside
2502 * a transaction block, typically because they have non-rollback-able
2503 * side effects or do internal commits.
2505 * If we have already started a transaction block, issue an error; also issue
2506 * an error if we appear to be running inside a user-defined function (which
2507 * could issue more commands and possibly cause a failure after the statement
2508 * completes). Subtransactions are verboten too.
2510 * isTopLevel: passed down from ProcessUtility to determine whether we are
2511 * inside a function or multi-query querystring. (We will always fail if
2512 * this is false, but it's convenient to centralize the check here instead of
2513 * making callers do it.)
2514 * stmtType: statement type name, for error messages.
2517 PreventTransactionChain(bool isTopLevel, const char *stmtType)
2520 * xact block already started?
2522 if (IsTransactionBlock())
2524 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2525 /* translator: %s represents an SQL statement name */
2526 errmsg("%s cannot run inside a transaction block",
2532 if (IsSubTransaction())
2534 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2535 /* translator: %s represents an SQL statement name */
2536 errmsg("%s cannot run inside a subtransaction",
2540 * inside a function call?
2544 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2545 /* translator: %s represents an SQL statement name */
2546 errmsg("%s cannot be executed from a function or multi-command string",
2549 /* If we got past IsTransactionBlock test, should be in default state */
2550 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2551 CurrentTransactionState->blockState != TBLOCK_STARTED)
2552 elog(FATAL, "cannot prevent transaction chain");
2557 * RequireTransactionChain
2559 * This routine is to be called by statements that must run inside
2560 * a transaction block, because they have no effects that persist past
2561 * transaction end (and so calling them outside a transaction block
2562 * is presumably an error). DECLARE CURSOR is an example.
2564 * If we appear to be running inside a user-defined function, we do not
2565 * issue an error, since the function could issue more commands that make
2566 * use of the current statement's results. Likewise subtransactions.
2567 * Thus this is an inverse for PreventTransactionChain.
2569 * isTopLevel: passed down from ProcessUtility to determine whether we are
2570 * inside a function.
2571 * stmtType: statement type name, for error messages.
2574 RequireTransactionChain(bool isTopLevel, const char *stmtType)
2577 * xact block already started?
2579 if (IsTransactionBlock())
2585 if (IsSubTransaction())
2589 * inside a function call?
2595 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2596 /* translator: %s represents an SQL statement name */
2597 errmsg("%s can only be used in transaction blocks",
2602 * IsInTransactionChain
2604 * This routine is for statements that need to behave differently inside
2605 * a transaction block than when running as single commands. ANALYZE is
2606 * currently the only example.
2608 * isTopLevel: passed down from ProcessUtility to determine whether we are
2609 * inside a function.
2612 IsInTransactionChain(bool isTopLevel)
2615 * Return true on same conditions that would make PreventTransactionChain
2618 if (IsTransactionBlock())
2621 if (IsSubTransaction())
2627 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2628 CurrentTransactionState->blockState != TBLOCK_STARTED)
2636 * Register or deregister callback functions for start- and end-of-xact
2639 * These functions are intended for use by dynamically loaded modules.
2640 * For built-in modules we generally just hardwire the appropriate calls
2641 * (mainly because it's easier to control the order that way, where needed).
2643 * At transaction end, the callback occurs post-commit or post-abort, so the
2644 * callback functions can only do noncritical cleanup.
2647 RegisterXactCallback(XactCallback callback, void *arg)
2649 XactCallbackItem *item;
2651 item = (XactCallbackItem *)
2652 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
2653 item->callback = callback;
2655 item->next = Xact_callbacks;
2656 Xact_callbacks = item;
2660 UnregisterXactCallback(XactCallback callback, void *arg)
2662 XactCallbackItem *item;
2663 XactCallbackItem *prev;
2666 for (item = Xact_callbacks; item; prev = item, item = item->next)
2668 if (item->callback == callback && item->arg == arg)
2671 prev->next = item->next;
2673 Xact_callbacks = item->next;
2681 CallXactCallbacks(XactEvent event)
2683 XactCallbackItem *item;
2685 for (item = Xact_callbacks; item; item = item->next)
2686 (*item->callback) (event, item->arg);
2691 * Register or deregister callback functions for start- and end-of-subxact
2694 * Pretty much same as above, but for subtransaction events.
2696 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
2697 * so the callback functions can only do noncritical cleanup. At
2698 * subtransaction start, the callback is called when the subtransaction has
2699 * finished initializing.
2702 RegisterSubXactCallback(SubXactCallback callback, void *arg)
2704 SubXactCallbackItem *item;
2706 item = (SubXactCallbackItem *)
2707 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
2708 item->callback = callback;
2710 item->next = SubXact_callbacks;
2711 SubXact_callbacks = item;
2715 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
2717 SubXactCallbackItem *item;
2718 SubXactCallbackItem *prev;
2721 for (item = SubXact_callbacks; item; prev = item, item = item->next)
2723 if (item->callback == callback && item->arg == arg)
2726 prev->next = item->next;
2728 SubXact_callbacks = item->next;
2736 CallSubXactCallbacks(SubXactEvent event,
2737 SubTransactionId mySubid,
2738 SubTransactionId parentSubid)
2740 SubXactCallbackItem *item;
2742 for (item = SubXact_callbacks; item; item = item->next)
2743 (*item->callback) (event, mySubid, parentSubid, item->arg);
2747 /* ----------------------------------------------------------------
2748 * transaction block support
2749 * ----------------------------------------------------------------
2753 * BeginTransactionBlock
2754 * This executes a BEGIN command.
2757 BeginTransactionBlock(void)
2759 TransactionState s = CurrentTransactionState;
2761 switch (s->blockState)
2764 * We are not inside a transaction block, so allow one to begin.
2766 case TBLOCK_STARTED:
2767 s->blockState = TBLOCK_BEGIN;
2771 * Already a transaction block in progress.
2773 case TBLOCK_INPROGRESS:
2774 case TBLOCK_SUBINPROGRESS:
2776 case TBLOCK_SUBABORT:
2778 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2779 errmsg("there is already a transaction in progress")));
2782 /* These cases are invalid. */
2783 case TBLOCK_DEFAULT:
2785 case TBLOCK_SUBBEGIN:
2788 case TBLOCK_ABORT_END:
2789 case TBLOCK_SUBABORT_END:
2790 case TBLOCK_ABORT_PENDING:
2791 case TBLOCK_SUBABORT_PENDING:
2792 case TBLOCK_SUBRESTART:
2793 case TBLOCK_SUBABORT_RESTART:
2794 case TBLOCK_PREPARE:
2795 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
2796 BlockStateAsString(s->blockState));
2802 * PrepareTransactionBlock
2803 * This executes a PREPARE command.
2805 * Since PREPARE may actually do a ROLLBACK, the result indicates what
2806 * happened: TRUE for PREPARE, FALSE for ROLLBACK.
2808 * Note that we don't actually do anything here except change blockState.
2809 * The real work will be done in the upcoming PrepareTransaction().
2810 * We do it this way because it's not convenient to change memory context,
2811 * resource owner, etc while executing inside a Portal.
2814 PrepareTransactionBlock(char *gid)
2819 /* Set up to commit the current transaction */
2820 result = EndTransactionBlock();
2822 /* If successful, change outer tblock state to PREPARE */
2825 s = CurrentTransactionState;
2827 while (s->parent != NULL)
2830 if (s->blockState == TBLOCK_END)
2832 /* Save GID where PrepareTransaction can find it again */
2833 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
2835 s->blockState = TBLOCK_PREPARE;
2840 * ignore case where we are not in a transaction;
2841 * EndTransactionBlock already issued a warning.
2843 Assert(s->blockState == TBLOCK_STARTED);
2844 /* Don't send back a PREPARE result tag... */
2853 * EndTransactionBlock
2854 * This executes a COMMIT command.
2856 * Since COMMIT may actually do a ROLLBACK, the result indicates what
2857 * happened: TRUE for COMMIT, FALSE for ROLLBACK.
2859 * Note that we don't actually do anything here except change blockState.
2860 * The real work will be done in the upcoming CommitTransactionCommand().
2861 * We do it this way because it's not convenient to change memory context,
2862 * resource owner, etc while executing inside a Portal.
2865 EndTransactionBlock(void)
2867 TransactionState s = CurrentTransactionState;
2868 bool result = false;
2870 switch (s->blockState)
2873 * We are in a transaction block, so tell CommitTransactionCommand
2876 case TBLOCK_INPROGRESS:
2877 s->blockState = TBLOCK_END;
2882 * We are in a failed transaction block. Tell
2883 * CommitTransactionCommand it's time to exit the block.
2886 s->blockState = TBLOCK_ABORT_END;
2890 * We are in a live subtransaction block. Set up to subcommit all
2891 * open subtransactions and then commit the main transaction.
2893 case TBLOCK_SUBINPROGRESS:
2894 while (s->parent != NULL)
2896 if (s->blockState == TBLOCK_SUBINPROGRESS)
2897 s->blockState = TBLOCK_SUBEND;
2899 elog(FATAL, "EndTransactionBlock: unexpected state %s",
2900 BlockStateAsString(s->blockState));
2903 if (s->blockState == TBLOCK_INPROGRESS)
2904 s->blockState = TBLOCK_END;
2906 elog(FATAL, "EndTransactionBlock: unexpected state %s",
2907 BlockStateAsString(s->blockState));
2912 * Here we are inside an aborted subtransaction. Treat the COMMIT
2913 * as ROLLBACK: set up to abort everything and exit the main
2916 case TBLOCK_SUBABORT:
2917 while (s->parent != NULL)
2919 if (s->blockState == TBLOCK_SUBINPROGRESS)
2920 s->blockState = TBLOCK_SUBABORT_PENDING;
2921 else if (s->blockState == TBLOCK_SUBABORT)
2922 s->blockState = TBLOCK_SUBABORT_END;
2924 elog(FATAL, "EndTransactionBlock: unexpected state %s",
2925 BlockStateAsString(s->blockState));
2928 if (s->blockState == TBLOCK_INPROGRESS)
2929 s->blockState = TBLOCK_ABORT_PENDING;
2930 else if (s->blockState == TBLOCK_ABORT)
2931 s->blockState = TBLOCK_ABORT_END;
2933 elog(FATAL, "EndTransactionBlock: unexpected state %s",
2934 BlockStateAsString(s->blockState));
2938 * The user issued COMMIT when not inside a transaction. Issue a
2939 * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
2940 * CommitTransactionCommand() will then close the transaction and
2941 * put us back into the default state.
2943 case TBLOCK_STARTED:
2945 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2946 errmsg("there is no transaction in progress")));
2950 /* These cases are invalid. */
2951 case TBLOCK_DEFAULT:
2953 case TBLOCK_SUBBEGIN:
2956 case TBLOCK_ABORT_END:
2957 case TBLOCK_SUBABORT_END:
2958 case TBLOCK_ABORT_PENDING:
2959 case TBLOCK_SUBABORT_PENDING:
2960 case TBLOCK_SUBRESTART:
2961 case TBLOCK_SUBABORT_RESTART:
2962 case TBLOCK_PREPARE:
2963 elog(FATAL, "EndTransactionBlock: unexpected state %s",
2964 BlockStateAsString(s->blockState));
2972 * UserAbortTransactionBlock
2973 * This executes a ROLLBACK command.
2975 * As above, we don't actually do anything here except change blockState.
2978 UserAbortTransactionBlock(void)
2980 TransactionState s = CurrentTransactionState;
2982 switch (s->blockState)
2985 * We are inside a transaction block and we got a ROLLBACK command
2986 * from the user, so tell CommitTransactionCommand to abort and
2987 * exit the transaction block.
2989 case TBLOCK_INPROGRESS:
2990 s->blockState = TBLOCK_ABORT_PENDING;
2994 * We are inside a failed transaction block and we got a ROLLBACK
2995 * command from the user. Abort processing is already done, so
2996 * CommitTransactionCommand just has to cleanup and go back to
3000 s->blockState = TBLOCK_ABORT_END;
3004 * We are inside a subtransaction. Mark everything up to top
3005 * level as exitable.
3007 case TBLOCK_SUBINPROGRESS:
3008 case TBLOCK_SUBABORT:
3009 while (s->parent != NULL)
3011 if (s->blockState == TBLOCK_SUBINPROGRESS)
3012 s->blockState = TBLOCK_SUBABORT_PENDING;
3013 else if (s->blockState == TBLOCK_SUBABORT)
3014 s->blockState = TBLOCK_SUBABORT_END;
3016 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3017 BlockStateAsString(s->blockState));
3020 if (s->blockState == TBLOCK_INPROGRESS)
3021 s->blockState = TBLOCK_ABORT_PENDING;
3022 else if (s->blockState == TBLOCK_ABORT)
3023 s->blockState = TBLOCK_ABORT_END;
3025 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3026 BlockStateAsString(s->blockState));
3030 * The user issued ABORT when not inside a transaction. Issue a
3031 * WARNING and go to abort state. The upcoming call to
3032 * CommitTransactionCommand() will then put us back into the
3035 case TBLOCK_STARTED:
3037 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3038 errmsg("there is no transaction in progress")));
3039 s->blockState = TBLOCK_ABORT_PENDING;
3042 /* These cases are invalid. */
3043 case TBLOCK_DEFAULT:
3045 case TBLOCK_SUBBEGIN:
3048 case TBLOCK_ABORT_END:
3049 case TBLOCK_SUBABORT_END:
3050 case TBLOCK_ABORT_PENDING:
3051 case TBLOCK_SUBABORT_PENDING:
3052 case TBLOCK_SUBRESTART:
3053 case TBLOCK_SUBABORT_RESTART:
3054 case TBLOCK_PREPARE:
3055 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3056 BlockStateAsString(s->blockState));
3063 * This executes a SAVEPOINT command.
3066 DefineSavepoint(char *name)
3068 TransactionState s = CurrentTransactionState;
3070 switch (s->blockState)
3072 case TBLOCK_INPROGRESS:
3073 case TBLOCK_SUBINPROGRESS:
3074 /* Normal subtransaction start */
3076 s = CurrentTransactionState; /* changed by push */
3079 * Savepoint names, like the TransactionState block itself, live
3080 * in TopTransactionContext.
3083 s->name = MemoryContextStrdup(TopTransactionContext, name);
3086 /* These cases are invalid. */
3087 case TBLOCK_DEFAULT:
3088 case TBLOCK_STARTED:
3090 case TBLOCK_SUBBEGIN:
3094 case TBLOCK_SUBABORT:
3095 case TBLOCK_ABORT_END:
3096 case TBLOCK_SUBABORT_END:
3097 case TBLOCK_ABORT_PENDING:
3098 case TBLOCK_SUBABORT_PENDING:
3099 case TBLOCK_SUBRESTART:
3100 case TBLOCK_SUBABORT_RESTART:
3101 case TBLOCK_PREPARE:
3102 elog(FATAL, "DefineSavepoint: unexpected state %s",
3103 BlockStateAsString(s->blockState));
3110 * This executes a RELEASE command.
3112 * As above, we don't actually do anything here except change blockState.
3115 ReleaseSavepoint(List *options)
3117 TransactionState s = CurrentTransactionState;
3118 TransactionState target,
3123 switch (s->blockState)
3126 * We can't rollback to a savepoint if there is no savepoint
3129 case TBLOCK_INPROGRESS:
3131 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3132 errmsg("no such savepoint")));
3136 * We are in a non-aborted subtransaction. This is the only valid
3139 case TBLOCK_SUBINPROGRESS:
3142 /* These cases are invalid. */
3143 case TBLOCK_DEFAULT:
3144 case TBLOCK_STARTED:
3146 case TBLOCK_SUBBEGIN:
3150 case TBLOCK_SUBABORT:
3151 case TBLOCK_ABORT_END:
3152 case TBLOCK_SUBABORT_END:
3153 case TBLOCK_ABORT_PENDING:
3154 case TBLOCK_SUBABORT_PENDING:
3155 case TBLOCK_SUBRESTART:
3156 case TBLOCK_SUBABORT_RESTART:
3157 case TBLOCK_PREPARE:
3158 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3159 BlockStateAsString(s->blockState));
3163 foreach(cell, options)
3165 DefElem *elem = lfirst(cell);
3167 if (strcmp(elem->defname, "savepoint_name") == 0)
3168 name = strVal(elem->arg);
3171 Assert(PointerIsValid(name));
3173 for (target = s; PointerIsValid(target); target = target->parent)
3175 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3179 if (!PointerIsValid(target))
3181 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3182 errmsg("no such savepoint")));
3184 /* disallow crossing savepoint level boundaries */
3185 if (target->savepointLevel != s->savepointLevel)
3187 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3188 errmsg("no such savepoint")));
3191 * Mark "commit pending" all subtransactions up to the target
3192 * subtransaction. The actual commits will happen when control gets to
3193 * CommitTransactionCommand.
3195 xact = CurrentTransactionState;
3198 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3199 xact->blockState = TBLOCK_SUBEND;
3202 xact = xact->parent;
3203 Assert(PointerIsValid(xact));
3208 * RollbackToSavepoint
3209 * This executes a ROLLBACK TO <savepoint> command.
3211 * As above, we don't actually do anything here except change blockState.
3214 RollbackToSavepoint(List *options)
3216 TransactionState s = CurrentTransactionState;
3217 TransactionState target,
3222 switch (s->blockState)
3225 * We can't rollback to a savepoint if there is no savepoint
3228 case TBLOCK_INPROGRESS:
3231 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3232 errmsg("no such savepoint")));
3236 * There is at least one savepoint, so proceed.
3238 case TBLOCK_SUBINPROGRESS:
3239 case TBLOCK_SUBABORT:
3242 /* These cases are invalid. */
3243 case TBLOCK_DEFAULT:
3244 case TBLOCK_STARTED:
3246 case TBLOCK_SUBBEGIN:
3249 case TBLOCK_ABORT_END:
3250 case TBLOCK_SUBABORT_END:
3251 case TBLOCK_ABORT_PENDING:
3252 case TBLOCK_SUBABORT_PENDING:
3253 case TBLOCK_SUBRESTART:
3254 case TBLOCK_SUBABORT_RESTART:
3255 case TBLOCK_PREPARE:
3256 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3257 BlockStateAsString(s->blockState));
3261 foreach(cell, options)
3263 DefElem *elem = lfirst(cell);
3265 if (strcmp(elem->defname, "savepoint_name") == 0)
3266 name = strVal(elem->arg);
3269 Assert(PointerIsValid(name));
3271 for (target = s; PointerIsValid(target); target = target->parent)
3273 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3277 if (!PointerIsValid(target))
3279 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3280 errmsg("no such savepoint")));
3282 /* disallow crossing savepoint level boundaries */
3283 if (target->savepointLevel != s->savepointLevel)
3285 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3286 errmsg("no such savepoint")));
3289 * Mark "abort pending" all subtransactions up to the target
3290 * subtransaction. The actual aborts will happen when control gets to
3291 * CommitTransactionCommand.
3293 xact = CurrentTransactionState;
3298 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3299 xact->blockState = TBLOCK_SUBABORT_PENDING;
3300 else if (xact->blockState == TBLOCK_SUBABORT)
3301 xact->blockState = TBLOCK_SUBABORT_END;
3303 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3304 BlockStateAsString(xact->blockState));
3305 xact = xact->parent;
3306 Assert(PointerIsValid(xact));
3309 /* And mark the target as "restart pending" */
3310 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3311 xact->blockState = TBLOCK_SUBRESTART;
3312 else if (xact->blockState == TBLOCK_SUBABORT)
3313 xact->blockState = TBLOCK_SUBABORT_RESTART;
3315 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3316 BlockStateAsString(xact->blockState));
3320 * BeginInternalSubTransaction
3321 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED
3322 * state, and therefore it can safely be used in a function that might
3323 * be called when not inside a BEGIN block. Also, we automatically
3324 * cycle through CommitTransactionCommand/StartTransactionCommand
3325 * instead of expecting the caller to do it.
3328 BeginInternalSubTransaction(char *name)
3330 TransactionState s = CurrentTransactionState;
3332 switch (s->blockState)
3334 case TBLOCK_STARTED:
3335 case TBLOCK_INPROGRESS:
3336 case TBLOCK_SUBINPROGRESS:
3337 /* Normal subtransaction start */
3339 s = CurrentTransactionState; /* changed by push */
3342 * Savepoint names, like the TransactionState block itself, live
3343 * in TopTransactionContext.
3346 s->name = MemoryContextStrdup(TopTransactionContext, name);
3349 /* These cases are invalid. */
3350 case TBLOCK_DEFAULT:
3352 case TBLOCK_SUBBEGIN:
3356 case TBLOCK_SUBABORT:
3357 case TBLOCK_ABORT_END:
3358 case TBLOCK_SUBABORT_END:
3359 case TBLOCK_ABORT_PENDING:
3360 case TBLOCK_SUBABORT_PENDING:
3361 case TBLOCK_SUBRESTART:
3362 case TBLOCK_SUBABORT_RESTART:
3363 case TBLOCK_PREPARE:
3364 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
3365 BlockStateAsString(s->blockState));
3369 CommitTransactionCommand();
3370 StartTransactionCommand();
3374 * ReleaseCurrentSubTransaction
3376 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
3377 * savepoint name (if any).
3378 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3381 ReleaseCurrentSubTransaction(void)
3383 TransactionState s = CurrentTransactionState;
3385 if (s->blockState != TBLOCK_SUBINPROGRESS)
3386 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
3387 BlockStateAsString(s->blockState));
3388 Assert(s->state == TRANS_INPROGRESS);
3389 MemoryContextSwitchTo(CurTransactionContext);
3390 CommitSubTransaction();
3391 s = CurrentTransactionState; /* changed by pop */
3392 Assert(s->state == TRANS_INPROGRESS);
3396 * RollbackAndReleaseCurrentSubTransaction
3398 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
3399 * of its savepoint name (if any).
3400 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3403 RollbackAndReleaseCurrentSubTransaction(void)
3405 TransactionState s = CurrentTransactionState;
3407 switch (s->blockState)
3409 /* Must be in a subtransaction */
3410 case TBLOCK_SUBINPROGRESS:
3411 case TBLOCK_SUBABORT:
3414 /* These cases are invalid. */
3415 case TBLOCK_DEFAULT:
3416 case TBLOCK_STARTED:
3418 case TBLOCK_SUBBEGIN:
3419 case TBLOCK_INPROGRESS:
3423 case TBLOCK_ABORT_END:
3424 case TBLOCK_SUBABORT_END:
3425 case TBLOCK_ABORT_PENDING:
3426 case TBLOCK_SUBABORT_PENDING:
3427 case TBLOCK_SUBRESTART:
3428 case TBLOCK_SUBABORT_RESTART:
3429 case TBLOCK_PREPARE:
3430 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
3431 BlockStateAsString(s->blockState));
3436 * Abort the current subtransaction, if needed.
3438 if (s->blockState == TBLOCK_SUBINPROGRESS)
3439 AbortSubTransaction();
3441 /* And clean it up, too */
3442 CleanupSubTransaction();
3444 s = CurrentTransactionState; /* changed by pop */
3445 AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
3446 s->blockState == TBLOCK_INPROGRESS ||
3447 s->blockState == TBLOCK_STARTED);
3451 * AbortOutOfAnyTransaction
3453 * This routine is provided for error recovery purposes. It aborts any
3454 * active transaction or transaction block, leaving the system in a known
3458 AbortOutOfAnyTransaction(void)
3460 TransactionState s = CurrentTransactionState;
3463 * Get out of any transaction or nested transaction
3467 switch (s->blockState)
3469 case TBLOCK_DEFAULT:
3470 /* Not in a transaction, do nothing */
3472 case TBLOCK_STARTED:
3474 case TBLOCK_INPROGRESS:
3476 case TBLOCK_ABORT_PENDING:
3477 case TBLOCK_PREPARE:
3478 /* In a transaction, so clean up */
3480 CleanupTransaction();
3481 s->blockState = TBLOCK_DEFAULT;
3484 case TBLOCK_ABORT_END:
3485 /* AbortTransaction already done, still need Cleanup */
3486 CleanupTransaction();
3487 s->blockState = TBLOCK_DEFAULT;
3491 * In a subtransaction, so clean it up and abort parent too
3493 case TBLOCK_SUBBEGIN:
3494 case TBLOCK_SUBINPROGRESS:
3496 case TBLOCK_SUBABORT_PENDING:
3497 case TBLOCK_SUBRESTART:
3498 AbortSubTransaction();
3499 CleanupSubTransaction();
3500 s = CurrentTransactionState; /* changed by pop */
3503 case TBLOCK_SUBABORT:
3504 case TBLOCK_SUBABORT_END:
3505 case TBLOCK_SUBABORT_RESTART:
3506 /* As above, but AbortSubTransaction already done */
3507 CleanupSubTransaction();
3508 s = CurrentTransactionState; /* changed by pop */
3511 } while (s->blockState != TBLOCK_DEFAULT);
3513 /* Should be out of all subxacts now */
3514 Assert(s->parent == NULL);
3518 * IsTransactionBlock --- are we within a transaction block?
3521 IsTransactionBlock(void)
3523 TransactionState s = CurrentTransactionState;
3525 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
3532 * IsTransactionOrTransactionBlock --- are we within either a transaction
3533 * or a transaction block? (The backend is only really "idle" when this
3536 * This should match up with IsTransactionBlock and IsTransactionState.
3539 IsTransactionOrTransactionBlock(void)
3541 TransactionState s = CurrentTransactionState;
3543 if (s->blockState == TBLOCK_DEFAULT)
3550 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
3553 TransactionBlockStatusCode(void)
3555 TransactionState s = CurrentTransactionState;
3557 switch (s->blockState)
3559 case TBLOCK_DEFAULT:
3560 case TBLOCK_STARTED:
3561 return 'I'; /* idle --- not in transaction */
3563 case TBLOCK_SUBBEGIN:
3564 case TBLOCK_INPROGRESS:
3565 case TBLOCK_SUBINPROGRESS:
3568 case TBLOCK_PREPARE:
3569 return 'T'; /* in transaction */
3571 case TBLOCK_SUBABORT:
3572 case TBLOCK_ABORT_END:
3573 case TBLOCK_SUBABORT_END:
3574 case TBLOCK_ABORT_PENDING:
3575 case TBLOCK_SUBABORT_PENDING:
3576 case TBLOCK_SUBRESTART:
3577 case TBLOCK_SUBABORT_RESTART:
3578 return 'E'; /* in failed transaction */
3581 /* should never get here */
3582 elog(FATAL, "invalid transaction block state: %s",
3583 BlockStateAsString(s->blockState));
3584 return 0; /* keep compiler quiet */
3591 IsSubTransaction(void)
3593 TransactionState s = CurrentTransactionState;
3595 if (s->nestingLevel >= 2)
3602 * StartSubTransaction
3604 * If you're wondering why this is separate from PushTransaction: it's because
3605 * we can't conveniently do this stuff right inside DefineSavepoint. The
3606 * SAVEPOINT utility command will be executed inside a Portal, and if we
3607 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
3608 * the Portal will undo those settings. So we make DefineSavepoint just
3609 * push a dummy transaction block, and when control returns to the main
3610 * idle loop, CommitTransactionCommand will be called, and we'll come here
3611 * to finish starting the subtransaction.
3614 StartSubTransaction(void)
3616 TransactionState s = CurrentTransactionState;
3618 if (s->state != TRANS_DEFAULT)
3619 elog(WARNING, "StartSubTransaction while in %s state",
3620 TransStateAsString(s->state));
3622 s->state = TRANS_START;
3625 * Initialize subsystems for new subtransaction
3627 * must initialize resource-management stuff first
3629 AtSubStart_Memory();
3630 AtSubStart_ResourceOwner();
3632 AtSubStart_Notify();
3633 AfterTriggerBeginSubXact();
3635 s->state = TRANS_INPROGRESS;
3638 * Call start-of-subxact callbacks
3640 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
3641 s->parent->subTransactionId);
3643 ShowTransactionState("StartSubTransaction");
3647 * CommitSubTransaction
3649 * The caller has to make sure to always reassign CurrentTransactionState
3650 * if it has a local pointer to it after calling this function.
3653 CommitSubTransaction(void)
3655 TransactionState s = CurrentTransactionState;
3657 ShowTransactionState("CommitSubTransaction");
3659 if (s->state != TRANS_INPROGRESS)
3660 elog(WARNING, "CommitSubTransaction while in %s state",
3661 TransStateAsString(s->state));
3663 /* Pre-commit processing goes here -- nothing to do at the moment */
3665 s->state = TRANS_COMMIT;
3667 /* Must CCI to ensure commands of subtransaction are seen as done */
3668 CommandCounterIncrement();
3670 /* Mark subtransaction as subcommitted */
3671 if (TransactionIdIsValid(s->transactionId))
3673 RecordSubTransactionCommit();
3674 AtSubCommit_childXids();
3677 /* Post-commit cleanup */
3678 AfterTriggerEndSubXact(true);
3679 AtSubCommit_Portals(s->subTransactionId,
3680 s->parent->subTransactionId,
3681 s->parent->curTransactionOwner);
3682 AtEOSubXact_LargeObject(true, s->subTransactionId,
3683 s->parent->subTransactionId);
3684 AtSubCommit_Notify();
3685 AtEOSubXact_UpdateFlatFiles(true, s->subTransactionId,
3686 s->parent->subTransactionId);
3688 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
3689 s->parent->subTransactionId);
3691 ResourceOwnerRelease(s->curTransactionOwner,
3692 RESOURCE_RELEASE_BEFORE_LOCKS,
3694 AtEOSubXact_RelationCache(true, s->subTransactionId,
3695 s->parent->subTransactionId);
3696 AtEOSubXact_Inval(true);
3700 * The only lock we actually release here is the subtransaction XID lock.
3701 * The rest just get transferred to the parent resource owner.
3703 CurrentResourceOwner = s->curTransactionOwner;
3704 if (TransactionIdIsValid(s->transactionId))
3705 XactLockTableDelete(s->transactionId);
3707 ResourceOwnerRelease(s->curTransactionOwner,
3708 RESOURCE_RELEASE_LOCKS,
3710 ResourceOwnerRelease(s->curTransactionOwner,
3711 RESOURCE_RELEASE_AFTER_LOCKS,
3714 AtEOXact_GUC(true, true);
3715 AtEOSubXact_SPI(true, s->subTransactionId);
3716 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
3717 s->parent->subTransactionId);
3718 AtEOSubXact_Namespace(true, s->subTransactionId,
3719 s->parent->subTransactionId);
3720 AtEOSubXact_Files(true, s->subTransactionId,
3721 s->parent->subTransactionId);
3722 AtEOSubXact_HashTables(true, s->nestingLevel);
3725 * We need to restore the upper transaction's read-only state, in case the
3726 * upper is read-write while the child is read-only; GUC will incorrectly
3727 * think it should leave the child state in place.
3729 XactReadOnly = s->prevXactReadOnly;
3731 CurrentResourceOwner = s->parent->curTransactionOwner;
3732 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3733 ResourceOwnerDelete(s->curTransactionOwner);
3734 s->curTransactionOwner = NULL;
3736 AtSubCommit_Memory();
3738 s->state = TRANS_DEFAULT;
3744 * AbortSubTransaction
3747 AbortSubTransaction(void)
3749 TransactionState s = CurrentTransactionState;
3751 /* Prevent cancel/die interrupt while cleaning up */
3754 /* Make sure we have a valid memory context and resource owner */
3755 AtSubAbort_Memory();
3756 AtSubAbort_ResourceOwner();
3759 * Release any LW locks we might be holding as quickly as possible.
3760 * (Regular locks, however, must be held till we finish aborting.)
3761 * Releasing LW locks is critical since we might try to grab them again
3762 * while cleaning up!
3764 * FIXME This may be incorrect --- Are there some locks we should keep?
3765 * Buffer locks, for example? I don't think so but I'm not sure.
3775 * check the current transaction state
3777 ShowTransactionState("AbortSubTransaction");
3779 if (s->state != TRANS_INPROGRESS)
3780 elog(WARNING, "AbortSubTransaction while in %s state",
3781 TransStateAsString(s->state));
3783 s->state = TRANS_ABORT;
3786 * We can skip all this stuff if the subxact failed before creating a
3789 if (s->curTransactionOwner)
3791 AfterTriggerEndSubXact(false);
3792 AtSubAbort_Portals(s->subTransactionId,
3793 s->parent->subTransactionId,
3794 s->parent->curTransactionOwner);
3795 AtEOSubXact_LargeObject(false, s->subTransactionId,
3796 s->parent->subTransactionId);
3797 AtSubAbort_Notify();
3798 AtEOSubXact_UpdateFlatFiles(false, s->subTransactionId,
3799 s->parent->subTransactionId);
3801 /* Advertise the fact that we aborted in pg_clog. */
3802 if (TransactionIdIsValid(s->transactionId))
3804 RecordSubTransactionAbort();
3805 AtSubAbort_childXids();
3808 /* Post-abort cleanup */
3809 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
3810 s->parent->subTransactionId);
3812 ResourceOwnerRelease(s->curTransactionOwner,
3813 RESOURCE_RELEASE_BEFORE_LOCKS,
3815 AtEOSubXact_RelationCache(false, s->subTransactionId,
3816 s->parent->subTransactionId);
3817 AtEOSubXact_Inval(false);
3819 ResourceOwnerRelease(s->curTransactionOwner,
3820 RESOURCE_RELEASE_LOCKS,
3822 ResourceOwnerRelease(s->curTransactionOwner,
3823 RESOURCE_RELEASE_AFTER_LOCKS,
3826 AtEOXact_GUC(false, true);
3827 AtEOSubXact_SPI(false, s->subTransactionId);
3828 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
3829 s->parent->subTransactionId);
3830 AtEOSubXact_Namespace(false, s->subTransactionId,
3831 s->parent->subTransactionId);
3832 AtEOSubXact_Files(false, s->subTransactionId,
3833 s->parent->subTransactionId);
3834 AtEOSubXact_HashTables(false, s->nestingLevel);
3838 * Reset user id which might have been changed transiently. Here we want
3839 * to restore to the userid that was current at subxact entry. (As in
3840 * AbortTransaction, we need not worry about the session userid.)
3842 * Must do this after AtEOXact_GUC to handle the case where we entered the
3843 * subxact inside a SECURITY DEFINER function (hence current and session
3844 * userids were different) and then session auth was changed inside the
3845 * subxact. GUC will reset both current and session userids to the
3846 * entry-time session userid. This is right in every other scenario so it
3847 * seems simplest to let GUC do that and fix it here.
3849 SetUserId(s->currentUser);
3852 * Restore the upper transaction's read-only state, too. This should be
3853 * redundant with GUC's cleanup but we may as well do it for consistency
3854 * with the commit case.
3856 XactReadOnly = s->prevXactReadOnly;
3858 RESUME_INTERRUPTS();
3862 * CleanupSubTransaction
3864 * The caller has to make sure to always reassign CurrentTransactionState
3865 * if it has a local pointer to it after calling this function.
3868 CleanupSubTransaction(void)
3870 TransactionState s = CurrentTransactionState;
3872 ShowTransactionState("CleanupSubTransaction");
3874 if (s->state != TRANS_ABORT)
3875 elog(WARNING, "CleanupSubTransaction while in %s state",
3876 TransStateAsString(s->state));
3878 AtSubCleanup_Portals(s->subTransactionId);
3880 CurrentResourceOwner = s->parent->curTransactionOwner;
3881 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3882 if (s->curTransactionOwner)
3883 ResourceOwnerDelete(s->curTransactionOwner);
3884 s->curTransactionOwner = NULL;
3886 AtSubCleanup_Memory();
3888 s->state = TRANS_DEFAULT;
3895 * Create transaction state stack entry for a subtransaction
3897 * The caller has to make sure to always reassign CurrentTransactionState
3898 * if it has a local pointer to it after calling this function.
3901 PushTransaction(void)
3903 TransactionState p = CurrentTransactionState;
3908 * At present, GetUserId cannot fail, but let's not assume that. Get the
3909 * ID before entering the critical code sequence.
3911 currentUser = GetUserId();
3914 * We keep subtransaction state nodes in TopTransactionContext.
3916 s = (TransactionState)
3917 MemoryContextAllocZero(TopTransactionContext,
3918 sizeof(TransactionStateData));
3921 * Assign a subtransaction ID, watching out for counter wraparound.
3923 currentSubTransactionId += 1;
3924 if (currentSubTransactionId == InvalidSubTransactionId)
3926 currentSubTransactionId -= 1;
3929 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3930 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
3934 * We can now stack a minimally valid subtransaction without fear of
3937 s->transactionId = InvalidTransactionId; /* until assigned */
3938 s->subTransactionId = currentSubTransactionId;
3940 s->nestingLevel = p->nestingLevel + 1;
3941 s->savepointLevel = p->savepointLevel;
3942 s->state = TRANS_DEFAULT;
3943 s->blockState = TBLOCK_SUBBEGIN;
3944 s->currentUser = currentUser;
3945 s->prevXactReadOnly = XactReadOnly;
3947 CurrentTransactionState = s;
3950 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
3951 * with the subtransaction from here on out; in particular they should not
3952 * assume that it necessarily has a transaction context, resource owner,
3959 * Pop back to parent transaction state
3961 * The caller has to make sure to always reassign CurrentTransactionState
3962 * if it has a local pointer to it after calling this function.
3965 PopTransaction(void)
3967 TransactionState s = CurrentTransactionState;
3969 if (s->state != TRANS_DEFAULT)
3970 elog(WARNING, "PopTransaction while in %s state",
3971 TransStateAsString(s->state));
3973 if (s->parent == NULL)
3974 elog(FATAL, "PopTransaction with no parent");
3976 CurrentTransactionState = s->parent;
3978 /* Let's just make sure CurTransactionContext is good */
3979 CurTransactionContext = s->parent->curTransactionContext;
3980 MemoryContextSwitchTo(CurTransactionContext);
3982 /* Ditto for ResourceOwner links */
3983 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3984 CurrentResourceOwner = s->parent->curTransactionOwner;
3986 /* Free the old child structure */
3993 * ShowTransactionState
3997 ShowTransactionState(const char *str)
3999 /* skip work if message will definitely not be printed */
4000 if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
4002 elog(DEBUG3, "%s", str);
4003 ShowTransactionStateRec(CurrentTransactionState);
4008 * ShowTransactionStateRec
4009 * Recursive subroutine for ShowTransactionState
4012 ShowTransactionStateRec(TransactionState s)
4015 ShowTransactionStateRec(s->parent);
4017 /* use ereport to suppress computation if msg will not be printed */
4019 (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u, nestlvl: %d, children: %s",
4020 PointerIsValid(s->name) ? s->name : "unnamed",
4021 BlockStateAsString(s->blockState),
4022 TransStateAsString(s->state),
4023 (unsigned int) s->transactionId,
4024 (unsigned int) s->subTransactionId,
4025 (unsigned int) currentCommandId,
4027 nodeToString(s->childXids))));
4031 * BlockStateAsString
4035 BlockStateAsString(TBlockState blockState)
4039 case TBLOCK_DEFAULT:
4041 case TBLOCK_STARTED:
4045 case TBLOCK_INPROGRESS:
4046 return "INPROGRESS";
4051 case TBLOCK_ABORT_END:
4053 case TBLOCK_ABORT_PENDING:
4054 return "ABORT PEND";
4055 case TBLOCK_PREPARE:
4057 case TBLOCK_SUBBEGIN:
4059 case TBLOCK_SUBINPROGRESS:
4060 return "SUB INPROGRS";
4063 case TBLOCK_SUBABORT:
4065 case TBLOCK_SUBABORT_END:
4066 return "SUB ABORT END";
4067 case TBLOCK_SUBABORT_PENDING:
4068 return "SUB ABRT PEND";
4069 case TBLOCK_SUBRESTART:
4070 return "SUB RESTART";
4071 case TBLOCK_SUBABORT_RESTART:
4072 return "SUB AB RESTRT";
4074 return "UNRECOGNIZED";
4078 * TransStateAsString
4082 TransStateAsString(TransState state)
4090 case TRANS_INPROGRESS:
4099 return "UNRECOGNIZED";
4103 * xactGetCommittedChildren
4105 * Gets the list of committed children of the current transaction. The return
4106 * value is the number of child transactions. *children is set to point to a
4107 * palloc'd array of TransactionIds. If there are no subxacts, *children is
4111 xactGetCommittedChildren(TransactionId **ptr)
4113 TransactionState s = CurrentTransactionState;
4115 TransactionId *children;
4118 nchildren = list_length(s->childXids);
4125 children = (TransactionId *) palloc(nchildren * sizeof(TransactionId));
4128 foreach(p, s->childXids)
4130 TransactionId child = lfirst_xid(p);
4132 *children++ = child;
4139 * XLOG support routines
4143 xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid)
4145 TransactionId *sub_xids;
4146 TransactionId max_xid;
4149 TransactionIdCommit(xid);
4151 /* Mark committed subtransactions as committed */
4152 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4153 TransactionIdCommitTree(xlrec->nsubxacts, sub_xids);
4155 /* Make sure nextXid is beyond any XID mentioned in the record */
4157 for (i = 0; i < xlrec->nsubxacts; i++)
4159 if (TransactionIdPrecedes(max_xid, sub_xids[i]))
4160 max_xid = sub_xids[i];
4162 if (TransactionIdFollowsOrEquals(max_xid,
4163 ShmemVariableCache->nextXid))
4165 ShmemVariableCache->nextXid = max_xid;
4166 TransactionIdAdvance(ShmemVariableCache->nextXid);
4169 /* Make sure files supposed to be dropped are dropped */
4170 for (i = 0; i < xlrec->nrels; i++)
4172 XLogDropRelation(xlrec->xnodes[i]);
4173 smgrdounlink(smgropen(xlrec->xnodes[i]), false, true);
4178 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
4180 TransactionId *sub_xids;
4181 TransactionId max_xid;
4184 TransactionIdAbort(xid);
4186 /* Mark subtransactions as aborted */
4187 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4188 TransactionIdAbortTree(xlrec->nsubxacts, sub_xids);
4190 /* Make sure nextXid is beyond any XID mentioned in the record */
4192 for (i = 0; i < xlrec->nsubxacts; i++)
4194 if (TransactionIdPrecedes(max_xid, sub_xids[i]))
4195 max_xid = sub_xids[i];
4197 if (TransactionIdFollowsOrEquals(max_xid,
4198 ShmemVariableCache->nextXid))
4200 ShmemVariableCache->nextXid = max_xid;
4201 TransactionIdAdvance(ShmemVariableCache->nextXid);
4204 /* Make sure files supposed to be dropped are dropped */
4205 for (i = 0; i < xlrec->nrels; i++)
4207 XLogDropRelation(xlrec->xnodes[i]);
4208 smgrdounlink(smgropen(xlrec->xnodes[i]), false, true);
4213 xact_redo(XLogRecPtr lsn, XLogRecord *record)
4215 uint8 info = record->xl_info & ~XLR_INFO_MASK;
4217 if (info == XLOG_XACT_COMMIT)
4219 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
4221 xact_redo_commit(xlrec, record->xl_xid);
4223 else if (info == XLOG_XACT_ABORT)
4225 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
4227 xact_redo_abort(xlrec, record->xl_xid);
4229 else if (info == XLOG_XACT_PREPARE)
4231 /* the record contents are exactly the 2PC file */
4232 RecreateTwoPhaseFile(record->xl_xid,
4233 XLogRecGetData(record), record->xl_len);
4235 else if (info == XLOG_XACT_COMMIT_PREPARED)
4237 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
4239 xact_redo_commit(&xlrec->crec, xlrec->xid);
4240 RemoveTwoPhaseFile(xlrec->xid, false);
4242 else if (info == XLOG_XACT_ABORT_PREPARED)
4244 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
4246 xact_redo_abort(&xlrec->arec, xlrec->xid);
4247 RemoveTwoPhaseFile(xlrec->xid, false);
4250 elog(PANIC, "xact_redo: unknown op code %u", info);
4254 xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
4256 struct tm *tm = localtime(&xlrec->xtime);
4259 appendStringInfo(buf, "%04u-%02u-%02u %02u:%02u:%02u",
4260 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
4261 tm->tm_hour, tm->tm_min, tm->tm_sec);
4262 if (xlrec->nrels > 0)
4264 appendStringInfo(buf, "; rels:");
4265 for (i = 0; i < xlrec->nrels; i++)
4267 RelFileNode rnode = xlrec->xnodes[i];
4269 appendStringInfo(buf, " %u/%u/%u",
4270 rnode.spcNode, rnode.dbNode, rnode.relNode);
4273 if (xlrec->nsubxacts > 0)
4275 TransactionId *xacts = (TransactionId *)
4276 &xlrec->xnodes[xlrec->nrels];
4278 appendStringInfo(buf, "; subxacts:");
4279 for (i = 0; i < xlrec->nsubxacts; i++)
4280 appendStringInfo(buf, " %u", xacts[i]);
4285 xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
4287 struct tm *tm = localtime(&xlrec->xtime);
4290 appendStringInfo(buf, "%04u-%02u-%02u %02u:%02u:%02u",
4291 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
4292 tm->tm_hour, tm->tm_min, tm->tm_sec);
4293 if (xlrec->nrels > 0)
4295 appendStringInfo(buf, "; rels:");
4296 for (i = 0; i < xlrec->nrels; i++)
4298 RelFileNode rnode = xlrec->xnodes[i];
4300 appendStringInfo(buf, " %u/%u/%u",
4301 rnode.spcNode, rnode.dbNode, rnode.relNode);
4304 if (xlrec->nsubxacts > 0)
4306 TransactionId *xacts = (TransactionId *)
4307 &xlrec->xnodes[xlrec->nrels];
4309 appendStringInfo(buf, "; subxacts:");
4310 for (i = 0; i < xlrec->nsubxacts; i++)
4311 appendStringInfo(buf, " %u", xacts[i]);
4316 xact_desc(StringInfo buf, uint8 xl_info, char *rec)
4318 uint8 info = xl_info & ~XLR_INFO_MASK;
4320 if (info == XLOG_XACT_COMMIT)
4322 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
4324 appendStringInfo(buf, "commit: ");
4325 xact_desc_commit(buf, xlrec);
4327 else if (info == XLOG_XACT_ABORT)
4329 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
4331 appendStringInfo(buf, "abort: ");
4332 xact_desc_abort(buf, xlrec);
4334 else if (info == XLOG_XACT_PREPARE)
4336 appendStringInfo(buf, "prepare");
4338 else if (info == XLOG_XACT_COMMIT_PREPARED)
4340 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
4342 appendStringInfo(buf, "commit %u: ", xlrec->xid);
4343 xact_desc_commit(buf, &xlrec->crec);
4345 else if (info == XLOG_XACT_ABORT_PREPARED)
4347 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
4349 appendStringInfo(buf, "abort %u: ", xlrec->xid);
4350 xact_desc_abort(buf, &xlrec->arec);
4353 appendStringInfo(buf, "UNKNOWN");