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.251 2007/09/11 03:28:05 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/sinvaladt.h"
41 #include "storage/smgr.h"
42 #include "utils/combocid.h"
43 #include "utils/flatfiles.h"
44 #include "utils/guc.h"
45 #include "utils/inval.h"
46 #include "utils/memutils.h"
47 #include "utils/relcache.h"
51 * User-tweakable parameters
53 int DefaultXactIsoLevel = XACT_READ_COMMITTED;
56 bool DefaultXactReadOnly = false;
59 bool XactSyncCommit = true;
61 int CommitDelay = 0; /* precommit delay in microseconds */
62 int CommitSiblings = 5; /* # concurrent xacts needed to sleep */
66 * transaction states - transaction state from server perspective
68 typedef enum TransState
70 TRANS_DEFAULT, /* idle */
71 TRANS_START, /* transaction starting */
72 TRANS_INPROGRESS, /* inside a valid transaction */
73 TRANS_COMMIT, /* commit in progress */
74 TRANS_ABORT, /* abort in progress */
75 TRANS_PREPARE /* prepare in progress */
79 * transaction block states - transaction state of client queries
81 * Note: the subtransaction states are used only for non-topmost
82 * transactions; the others appear only in the topmost transaction.
84 typedef enum TBlockState
86 /* not-in-transaction-block states */
87 TBLOCK_DEFAULT, /* idle */
88 TBLOCK_STARTED, /* running single-query transaction */
90 /* transaction block states */
91 TBLOCK_BEGIN, /* starting transaction block */
92 TBLOCK_INPROGRESS, /* live transaction */
93 TBLOCK_END, /* COMMIT received */
94 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
95 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
96 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
97 TBLOCK_PREPARE, /* live xact, PREPARE received */
99 /* subtransaction states */
100 TBLOCK_SUBBEGIN, /* starting a subtransaction */
101 TBLOCK_SUBINPROGRESS, /* live subtransaction */
102 TBLOCK_SUBEND, /* RELEASE received */
103 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
104 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
105 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
106 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
107 TBLOCK_SUBABORT_RESTART /* failed subxact, ROLLBACK TO received */
111 * transaction state structure
113 typedef struct TransactionStateData
115 TransactionId transactionId; /* my XID, or Invalid if none */
116 SubTransactionId subTransactionId; /* my subxact ID */
117 char *name; /* savepoint name, if any */
118 int savepointLevel; /* savepoint level */
119 TransState state; /* low-level state */
120 TBlockState blockState; /* high-level state */
121 int nestingLevel; /* transaction nesting depth */
122 int gucNestLevel; /* GUC context nesting depth */
123 MemoryContext curTransactionContext; /* my xact-lifetime context */
124 ResourceOwner curTransactionOwner; /* my query resources */
125 List *childXids; /* subcommitted child XIDs */
126 Oid currentUser; /* subxact start current_user */
127 bool prevXactReadOnly; /* entry-time xact r/o state */
128 struct TransactionStateData *parent; /* back link to parent */
129 } TransactionStateData;
131 typedef TransactionStateData *TransactionState;
134 * CurrentTransactionState always points to the current transaction state
135 * block. It will point to TopTransactionStateData when not in a
136 * transaction at all, or when in a top-level transaction.
138 static TransactionStateData TopTransactionStateData = {
139 0, /* transaction id */
140 0, /* subtransaction id */
141 NULL, /* savepoint name */
142 0, /* savepoint level */
143 TRANS_DEFAULT, /* transaction state */
144 TBLOCK_DEFAULT, /* transaction block state from the client
146 0, /* transaction nesting depth */
147 0, /* GUC context nesting depth */
148 NULL, /* cur transaction context */
149 NULL, /* cur transaction resource owner */
150 NIL, /* subcommitted child Xids */
151 0, /* entry-time current userid */
152 false, /* entry-time xact r/o state */
153 NULL /* link to parent state block */
156 static TransactionState CurrentTransactionState = &TopTransactionStateData;
159 * The subtransaction ID and command ID assignment counters are global
160 * to a whole transaction, so we do not keep them in the state stack.
162 static SubTransactionId currentSubTransactionId;
163 static CommandId currentCommandId;
166 * xactStartTimestamp is the value of transaction_timestamp().
167 * stmtStartTimestamp is the value of statement_timestamp().
168 * xactStopTimestamp is the time at which we log a commit or abort WAL record.
169 * These do not change as we enter and exit subtransactions, so we don't
170 * keep them inside the TransactionState stack.
172 static TimestampTz xactStartTimestamp;
173 static TimestampTz stmtStartTimestamp;
174 static TimestampTz xactStopTimestamp;
177 * GID to be used for preparing the current transaction. This is also
178 * global to a whole transaction, so we don't keep it in the state stack.
180 static char *prepareGID;
183 * Some commands want to force synchronous commit.
185 static bool forceSyncCommit = false;
188 * Private context for transaction-abort work --- we reserve space for this
189 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
190 * when we've run out of memory.
192 static MemoryContext TransactionAbortContext = NULL;
195 * List of add-on start- and end-of-xact callbacks
197 typedef struct XactCallbackItem
199 struct XactCallbackItem *next;
200 XactCallback callback;
204 static XactCallbackItem *Xact_callbacks = NULL;
207 * List of add-on start- and end-of-subxact callbacks
209 typedef struct SubXactCallbackItem
211 struct SubXactCallbackItem *next;
212 SubXactCallback callback;
214 } SubXactCallbackItem;
216 static SubXactCallbackItem *SubXact_callbacks = NULL;
219 /* local function prototypes */
220 static void AssignTransactionId(TransactionState s);
221 static void AbortTransaction(void);
222 static void AtAbort_Memory(void);
223 static void AtCleanup_Memory(void);
224 static void AtAbort_ResourceOwner(void);
225 static void AtCommit_LocalCache(void);
226 static void AtCommit_Memory(void);
227 static void AtStart_Cache(void);
228 static void AtStart_Memory(void);
229 static void AtStart_ResourceOwner(void);
230 static void CallXactCallbacks(XactEvent event);
231 static void CallSubXactCallbacks(SubXactEvent event,
232 SubTransactionId mySubid,
233 SubTransactionId parentSubid);
234 static void CleanupTransaction(void);
235 static void CommitTransaction(void);
236 static TransactionId RecordTransactionAbort(bool isSubXact);
237 static void StartTransaction(void);
239 static void RecordSubTransactionCommit(void);
240 static void StartSubTransaction(void);
241 static void CommitSubTransaction(void);
242 static void AbortSubTransaction(void);
243 static void CleanupSubTransaction(void);
244 static void PushTransaction(void);
245 static void PopTransaction(void);
247 static void AtSubAbort_Memory(void);
248 static void AtSubCleanup_Memory(void);
249 static void AtSubAbort_ResourceOwner(void);
250 static void AtSubCommit_Memory(void);
251 static void AtSubStart_Memory(void);
252 static void AtSubStart_ResourceOwner(void);
254 static void ShowTransactionState(const char *str);
255 static void ShowTransactionStateRec(TransactionState state);
256 static const char *BlockStateAsString(TBlockState blockState);
257 static const char *TransStateAsString(TransState state);
260 /* ----------------------------------------------------------------
261 * transaction state accessors
262 * ----------------------------------------------------------------
268 * This returns true if we are inside a valid transaction; that is,
269 * it is safe to initiate database access, take heavyweight locks, etc.
272 IsTransactionState(void)
274 TransactionState s = CurrentTransactionState;
277 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However,
278 * we also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
279 * TRANS_PREPARE since it might be too soon or too late within those
280 * transition states to do anything interesting. Hence, the only "valid"
281 * state is TRANS_INPROGRESS.
283 return (s->state == TRANS_INPROGRESS);
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 * This will return the XID of the main transaction, assigning one if
309 * it's not yet set. Be careful to call this only inside a valid xact.
312 GetTopTransactionId(void)
314 if (!TransactionIdIsValid(TopTransactionStateData.transactionId))
315 AssignTransactionId(&TopTransactionStateData);
316 return TopTransactionStateData.transactionId;
320 * GetTopTransactionIdIfAny
322 * This will return the XID of the main transaction, if one is assigned.
323 * It will return InvalidTransactionId if we are not currently inside a
324 * transaction, or inside a transaction that hasn't yet been assigned an XID.
327 GetTopTransactionIdIfAny(void)
329 return TopTransactionStateData.transactionId;
333 * GetCurrentTransactionId
335 * This will return the XID of the current transaction (main or sub
336 * transaction), assigning one if it's not yet set. Be careful to call this
337 * only inside a valid xact.
340 GetCurrentTransactionId(void)
342 TransactionState s = CurrentTransactionState;
344 if (!TransactionIdIsValid(s->transactionId))
345 AssignTransactionId(s);
346 return s->transactionId;
350 * GetCurrentTransactionIdIfAny
352 * This will return the XID of the current sub xact, if one is assigned.
353 * It will return InvalidTransactionId if we are not currently inside a
354 * transaction, or inside a transaction that hasn't been assigned an XID yet.
357 GetCurrentTransactionIdIfAny(void)
359 return CurrentTransactionState->transactionId;
364 * AssignTransactionId
366 * Assigns a new permanent XID to the given TransactionState.
367 * We do not assign XIDs to transactions until/unless this is called.
368 * Also, any parent TransactionStates that don't yet have XIDs are assigned
369 * one; this maintains the invariant that a child transaction has an XID
370 * following its parent's.
373 AssignTransactionId(TransactionState s)
375 bool isSubXact = (s->parent != NULL);
376 ResourceOwner currentOwner;
378 /* Assert that caller didn't screw up */
379 Assert(!TransactionIdIsValid(s->transactionId));
380 Assert(s->state == TRANS_INPROGRESS);
383 * Ensure parent(s) have XIDs, so that a child always has an XID later
386 if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
387 AssignTransactionId(s->parent);
390 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
392 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
393 * shared storage other than PG_PROC; because if there's no room for it in
394 * PG_PROC, the subtrans entry is needed to ensure that other backends see
395 * the Xid as "running". See GetNewTransactionId.
397 s->transactionId = GetNewTransactionId(isSubXact);
400 SubTransSetParent(s->transactionId, s->parent->transactionId);
403 * Acquire lock on the transaction XID. (We assume this cannot block.)
404 * We have to ensure that the lock is assigned to the transaction's
407 currentOwner = CurrentResourceOwner;
410 CurrentResourceOwner = s->curTransactionOwner;
411 XactLockTableInsert(s->transactionId);
415 /* Ensure CurrentResourceOwner is restored on error */
416 CurrentResourceOwner = currentOwner;
420 CurrentResourceOwner = currentOwner;
425 * GetCurrentSubTransactionId
428 GetCurrentSubTransactionId(void)
430 TransactionState s = CurrentTransactionState;
432 return s->subTransactionId;
437 * GetCurrentCommandId
440 GetCurrentCommandId(void)
442 /* this is global to a transaction, not subtransaction-local */
443 return currentCommandId;
447 * GetCurrentTransactionStartTimestamp
450 GetCurrentTransactionStartTimestamp(void)
452 return xactStartTimestamp;
456 * GetCurrentStatementStartTimestamp
459 GetCurrentStatementStartTimestamp(void)
461 return stmtStartTimestamp;
465 * GetCurrentTransactionStopTimestamp
467 * We return current time if the transaction stop time hasn't been set
468 * (which can happen if we decide we don't need to log an XLOG record).
471 GetCurrentTransactionStopTimestamp(void)
473 if (xactStopTimestamp != 0)
474 return xactStopTimestamp;
475 return GetCurrentTimestamp();
479 * SetCurrentStatementStartTimestamp
482 SetCurrentStatementStartTimestamp(void)
484 stmtStartTimestamp = GetCurrentTimestamp();
488 * SetCurrentTransactionStopTimestamp
491 SetCurrentTransactionStopTimestamp(void)
493 xactStopTimestamp = GetCurrentTimestamp();
497 * GetCurrentTransactionNestLevel
499 * Note: this will return zero when not inside any transaction, one when
500 * inside a top-level transaction, etc.
503 GetCurrentTransactionNestLevel(void)
505 TransactionState s = CurrentTransactionState;
507 return s->nestingLevel;
512 * TransactionIdIsCurrentTransactionId
515 TransactionIdIsCurrentTransactionId(TransactionId xid)
520 * We always say that BootstrapTransactionId is "not my transaction ID"
521 * even when it is (ie, during bootstrap). Along with the fact that
522 * transam.c always treats BootstrapTransactionId as already committed,
523 * this causes the tqual.c routines to see all tuples as committed, which
524 * is what we need during bootstrap. (Bootstrap mode only inserts tuples,
525 * it never updates or deletes them, so all tuples can be presumed good
528 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
529 * not my transaction ID, so we can just return "false" immediately for
530 * any non-normal XID.
532 if (!TransactionIdIsNormal(xid))
536 * We will return true for the Xid of the current subtransaction, any of
537 * its subcommitted children, any of its parents, or any of their
538 * previously subcommitted children. However, a transaction being aborted
539 * is no longer "current", even though it may still have an entry on the
542 for (s = CurrentTransactionState; s != NULL; s = s->parent)
546 if (s->state == TRANS_ABORT)
548 if (!TransactionIdIsValid(s->transactionId))
549 continue; /* it can't have any child XIDs either */
550 if (TransactionIdEquals(xid, s->transactionId))
552 foreach(cell, s->childXids)
554 if (TransactionIdEquals(xid, lfirst_xid(cell)))
564 * CommandCounterIncrement
567 CommandCounterIncrement(void)
569 currentCommandId += 1;
570 if (currentCommandId == FirstCommandId) /* check for overflow */
572 currentCommandId -= 1;
574 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
575 errmsg("cannot have more than 2^32-1 commands in a transaction")));
578 /* Propagate new command ID into static snapshots, if set */
579 if (SerializableSnapshot)
580 SerializableSnapshot->curcid = currentCommandId;
582 LatestSnapshot->curcid = currentCommandId;
585 * make cache changes visible to me.
587 AtCommit_LocalCache();
594 * Interface routine to allow commands to force a synchronous commit of the
595 * current top-level transaction
598 ForceSyncCommit(void)
600 forceSyncCommit = true;
604 /* ----------------------------------------------------------------
605 * StartTransaction stuff
606 * ----------------------------------------------------------------
615 AcceptInvalidationMessages();
624 TransactionState s = CurrentTransactionState;
627 * If this is the first time through, create a private context for
628 * AbortTransaction to work in. By reserving some space now, we can
629 * insulate AbortTransaction from out-of-memory scenarios. Like
630 * ErrorContext, we set it up with slow growth rate and a nonzero
631 * minimum size, so that space will be reserved immediately.
633 if (TransactionAbortContext == NULL)
634 TransactionAbortContext =
635 AllocSetContextCreate(TopMemoryContext,
636 "TransactionAbortContext",
642 * We shouldn't have a transaction context already.
644 Assert(TopTransactionContext == NULL);
647 * Create a toplevel context for the transaction.
649 TopTransactionContext =
650 AllocSetContextCreate(TopMemoryContext,
651 "TopTransactionContext",
652 ALLOCSET_DEFAULT_MINSIZE,
653 ALLOCSET_DEFAULT_INITSIZE,
654 ALLOCSET_DEFAULT_MAXSIZE);
657 * In a top-level transaction, CurTransactionContext is the same as
658 * TopTransactionContext.
660 CurTransactionContext = TopTransactionContext;
661 s->curTransactionContext = CurTransactionContext;
663 /* Make the CurTransactionContext active. */
664 MemoryContextSwitchTo(CurTransactionContext);
668 * AtStart_ResourceOwner
671 AtStart_ResourceOwner(void)
673 TransactionState s = CurrentTransactionState;
676 * We shouldn't have a transaction resource owner already.
678 Assert(TopTransactionResourceOwner == NULL);
681 * Create a toplevel resource owner for the transaction.
683 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
685 TopTransactionResourceOwner = s->curTransactionOwner;
686 CurTransactionResourceOwner = s->curTransactionOwner;
687 CurrentResourceOwner = s->curTransactionOwner;
690 /* ----------------------------------------------------------------
691 * StartSubTransaction stuff
692 * ----------------------------------------------------------------
699 AtSubStart_Memory(void)
701 TransactionState s = CurrentTransactionState;
703 Assert(CurTransactionContext != NULL);
706 * Create a CurTransactionContext, which will be used to hold data that
707 * survives subtransaction commit but disappears on subtransaction abort.
708 * We make it a child of the immediate parent's CurTransactionContext.
710 CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
711 "CurTransactionContext",
712 ALLOCSET_DEFAULT_MINSIZE,
713 ALLOCSET_DEFAULT_INITSIZE,
714 ALLOCSET_DEFAULT_MAXSIZE);
715 s->curTransactionContext = CurTransactionContext;
717 /* Make the CurTransactionContext active. */
718 MemoryContextSwitchTo(CurTransactionContext);
722 * AtSubStart_ResourceOwner
725 AtSubStart_ResourceOwner(void)
727 TransactionState s = CurrentTransactionState;
729 Assert(s->parent != NULL);
732 * Create a resource owner for the subtransaction. We make it a child of
733 * the immediate parent's resource owner.
735 s->curTransactionOwner =
736 ResourceOwnerCreate(s->parent->curTransactionOwner,
739 CurTransactionResourceOwner = s->curTransactionOwner;
740 CurrentResourceOwner = s->curTransactionOwner;
743 /* ----------------------------------------------------------------
744 * CommitTransaction stuff
745 * ----------------------------------------------------------------
749 * RecordTransactionCommit
751 * Returns latest XID among xact and its children, or InvalidTransactionId
752 * if the xact has no XID. (We compute that here just because it's easier.)
754 * This is exported only to support an ugly hack in VACUUM FULL.
757 RecordTransactionCommit(void)
759 TransactionId xid = GetTopTransactionIdIfAny();
760 bool markXidCommitted = TransactionIdIsValid(xid);
761 TransactionId latestXid = InvalidTransactionId;
766 TransactionId *children;
768 /* Get data needed for commit record */
769 nrels = smgrGetPendingDeletes(true, &rels, &haveNonTemp);
770 nchildren = xactGetCommittedChildren(&children);
773 * If we haven't been assigned an XID yet, we neither can, nor do we
774 * want to write a COMMIT record.
776 if (!markXidCommitted)
779 * We expect that every smgrscheduleunlink is followed by a catalog
780 * update, and hence XID assignment, so we shouldn't get here with
781 * any pending deletes. Use a real test not just an Assert to check
782 * this, since it's a bit fragile.
785 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
787 /* Can't have child XIDs either; AssignTransactionId enforces this */
788 Assert(nchildren == 0);
791 * If we didn't create XLOG entries, we're done here; otherwise we
792 * should flush those entries the same as a commit record. (An
793 * example of a possible record that wouldn't cause an XID to be
794 * assigned is a sequence advance record due to nextval() --- we
795 * want to flush that to disk before reporting commit.)
797 if (XactLastRecEnd.xrecoff == 0)
803 * Begin commit critical section and insert the commit XLOG record.
805 XLogRecData rdata[3];
807 xl_xact_commit xlrec;
809 /* Tell bufmgr and smgr to prepare for commit */
813 * Mark ourselves as within our "commit critical section". This
814 * forces any concurrent checkpoint to wait until we've updated
815 * pg_clog. Without this, it is possible for the checkpoint to
816 * set REDO after the XLOG record but fail to flush the pg_clog
817 * update to disk, leading to loss of the transaction commit if
818 * the system crashes a little later.
820 * Note: we could, but don't bother to, set this flag in
821 * RecordTransactionAbort. That's because loss of a transaction
822 * abort is noncritical; the presumption would be that it aborted,
825 * It's safe to change the inCommit flag of our own backend
826 * without holding the ProcArrayLock, since we're the only one
827 * modifying it. This makes checkpoint's determination of which
828 * xacts are inCommit a bit fuzzy, but it doesn't matter.
830 START_CRIT_SECTION();
831 MyProc->inCommit = true;
833 SetCurrentTransactionStopTimestamp();
834 xlrec.xact_time = xactStopTimestamp;
836 xlrec.nsubxacts = nchildren;
837 rdata[0].data = (char *) (&xlrec);
838 rdata[0].len = MinSizeOfXactCommit;
839 rdata[0].buffer = InvalidBuffer;
840 /* dump rels to delete */
843 rdata[0].next = &(rdata[1]);
844 rdata[1].data = (char *) rels;
845 rdata[1].len = nrels * sizeof(RelFileNode);
846 rdata[1].buffer = InvalidBuffer;
849 /* dump committed child Xids */
852 rdata[lastrdata].next = &(rdata[2]);
853 rdata[2].data = (char *) children;
854 rdata[2].len = nchildren * sizeof(TransactionId);
855 rdata[2].buffer = InvalidBuffer;
858 rdata[lastrdata].next = NULL;
860 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
864 * Check if we want to commit asynchronously. If the user has set
865 * synchronous_commit = off, and we're not doing cleanup of any non-temp
866 * rels nor committing any command that wanted to force sync commit, then
867 * we can defer flushing XLOG. (We must not allow asynchronous commit if
868 * there are any non-temp tables to be deleted, because we might delete
869 * the files before the COMMIT record is flushed to disk. We do allow
870 * asynchronous commit if all to-be-deleted tables are temporary though,
871 * since they are lost anyway if we crash.)
873 if (XactSyncCommit || forceSyncCommit || haveNonTemp)
876 * Synchronous commit case.
878 * Sleep before flush! So we can flush more than one commit
879 * records per single fsync. (The idea is some other backend
880 * may do the XLogFlush while we're sleeping. This needs work
881 * still, because on most Unixen, the minimum select() delay
882 * is 10msec or more, which is way too long.)
884 * We do not sleep if enableFsync is not turned on, nor if
885 * there are fewer than CommitSiblings other backends with
886 * active transactions.
888 if (CommitDelay > 0 && enableFsync &&
889 CountActiveBackends() >= CommitSiblings)
890 pg_usleep(CommitDelay);
892 XLogFlush(XactLastRecEnd);
895 * Now we may update the CLOG, if we wrote a COMMIT record above
897 if (markXidCommitted)
899 TransactionIdCommit(xid);
900 /* to avoid race conditions, the parent must commit first */
901 TransactionIdCommitTree(nchildren, children);
907 * Asynchronous commit case.
909 * Report the latest async commit LSN, so that
910 * the WAL writer knows to flush this commit.
912 XLogSetAsyncCommitLSN(XactLastRecEnd);
915 * We must not immediately update the CLOG, since we didn't
916 * flush the XLOG. Instead, we store the LSN up to which
917 * the XLOG must be flushed before the CLOG may be updated.
919 if (markXidCommitted)
921 TransactionIdAsyncCommit(xid, XactLastRecEnd);
922 /* to avoid race conditions, the parent must commit first */
923 TransactionIdAsyncCommitTree(nchildren, children, XactLastRecEnd);
928 * If we entered a commit critical section, leave it now, and
929 * let checkpoints proceed.
931 if (markXidCommitted)
933 MyProc->inCommit = false;
937 /* Compute latestXid while we have the child XIDs handy */
938 latestXid = TransactionIdLatest(xid, nchildren, children);
940 /* Reset XactLastRecEnd until the next transaction writes something */
941 XactLastRecEnd.xrecoff = 0;
944 /* Clean up local data */
955 * AtCommit_LocalCache
958 AtCommit_LocalCache(void)
961 * Make catalog changes visible to me for the next command.
963 CommandEndInvalidationMessages();
970 AtCommit_Memory(void)
973 * Now that we're "out" of a transaction, have the system allocate things
974 * in the top memory context instead of per-transaction contexts.
976 MemoryContextSwitchTo(TopMemoryContext);
979 * Release all transaction-local memory.
981 Assert(TopTransactionContext != NULL);
982 MemoryContextDelete(TopTransactionContext);
983 TopTransactionContext = NULL;
984 CurTransactionContext = NULL;
985 CurrentTransactionState->curTransactionContext = NULL;
988 /* ----------------------------------------------------------------
989 * CommitSubTransaction stuff
990 * ----------------------------------------------------------------
997 AtSubCommit_Memory(void)
999 TransactionState s = CurrentTransactionState;
1001 Assert(s->parent != NULL);
1003 /* Return to parent transaction level's memory context. */
1004 CurTransactionContext = s->parent->curTransactionContext;
1005 MemoryContextSwitchTo(CurTransactionContext);
1008 * Ordinarily we cannot throw away the child's CurTransactionContext,
1009 * since the data it contains will be needed at upper commit. However, if
1010 * there isn't actually anything in it, we can throw it away. This avoids
1011 * a small memory leak in the common case of "trivial" subxacts.
1013 if (MemoryContextIsEmpty(s->curTransactionContext))
1015 MemoryContextDelete(s->curTransactionContext);
1016 s->curTransactionContext = NULL;
1021 * AtSubCommit_childXids
1023 * Pass my own XID and my child XIDs up to my parent as committed children.
1026 AtSubCommit_childXids(void)
1028 TransactionState s = CurrentTransactionState;
1029 MemoryContext old_cxt;
1031 Assert(s->parent != NULL);
1034 * We keep the child-XID lists in TopTransactionContext; this avoids
1035 * setting up child-transaction contexts for what might be just a few
1036 * bytes of grandchild XIDs.
1038 old_cxt = MemoryContextSwitchTo(TopTransactionContext);
1040 s->parent->childXids = lappend_xid(s->parent->childXids,
1043 if (s->childXids != NIL)
1045 s->parent->childXids = list_concat(s->parent->childXids,
1049 * list_concat doesn't free the list header for the second list; do so
1050 * here to avoid memory leakage (kluge)
1052 pfree(s->childXids);
1056 MemoryContextSwitchTo(old_cxt);
1060 * RecordSubTransactionCommit
1063 RecordSubTransactionCommit(void)
1065 TransactionId xid = GetCurrentTransactionIdIfAny();
1068 * We do not log the subcommit in XLOG; it doesn't matter until the
1069 * top-level transaction commits.
1071 * We must mark the subtransaction subcommitted in the CLOG if
1072 * it had a valid XID assigned. If it did not, nobody else will
1073 * ever know about the existence of this subxact. We don't
1074 * have to deal with deletions scheduled for on-commit here, since
1075 * they'll be reassigned to our parent (who might still abort).
1077 if (TransactionIdIsValid(xid))
1079 /* XXX does this really need to be a critical section? */
1080 START_CRIT_SECTION();
1082 /* Record subtransaction subcommit */
1083 TransactionIdSubCommit(xid);
1089 /* ----------------------------------------------------------------
1090 * AbortTransaction stuff
1091 * ----------------------------------------------------------------
1095 * RecordTransactionAbort
1097 * Returns latest XID among xact and its children, or InvalidTransactionId
1098 * if the xact has no XID. (We compute that here just because it's easier.)
1100 static TransactionId
1101 RecordTransactionAbort(bool isSubXact)
1103 TransactionId xid = GetCurrentTransactionIdIfAny();
1104 TransactionId latestXid;
1108 TransactionId *children;
1109 XLogRecData rdata[3];
1111 xl_xact_abort xlrec;
1114 * If we haven't been assigned an XID, nobody will care whether we
1115 * aborted or not. Hence, we're done in that case. It does not matter
1116 * if we have rels to delete (note that this routine is not responsible
1117 * for actually deleting 'em). We cannot have any child XIDs, either.
1119 if (!TransactionIdIsValid(xid))
1121 /* Reset XactLastRecEnd until the next transaction writes something */
1123 XactLastRecEnd.xrecoff = 0;
1124 return InvalidTransactionId;
1128 * We have a valid XID, so we should write an ABORT record for it.
1130 * We do not flush XLOG to disk here, since the default assumption after a
1131 * crash would be that we aborted, anyway. For the same reason, we don't
1132 * need to worry about interlocking against checkpoint start.
1136 * Check that we haven't aborted halfway through RecordTransactionCommit.
1138 if (TransactionIdDidCommit(xid))
1139 elog(PANIC, "cannot abort transaction %u, it was already committed",
1142 /* Fetch the data we need for the abort record */
1143 nrels = smgrGetPendingDeletes(false, &rels, NULL);
1144 nchildren = xactGetCommittedChildren(&children);
1146 /* XXX do we really need a critical section here? */
1147 START_CRIT_SECTION();
1149 /* Write the ABORT record */
1151 xlrec.xact_time = GetCurrentTimestamp();
1154 SetCurrentTransactionStopTimestamp();
1155 xlrec.xact_time = xactStopTimestamp;
1157 xlrec.nrels = nrels;
1158 xlrec.nsubxacts = nchildren;
1159 rdata[0].data = (char *) (&xlrec);
1160 rdata[0].len = MinSizeOfXactAbort;
1161 rdata[0].buffer = InvalidBuffer;
1162 /* dump rels to delete */
1165 rdata[0].next = &(rdata[1]);
1166 rdata[1].data = (char *) rels;
1167 rdata[1].len = nrels * sizeof(RelFileNode);
1168 rdata[1].buffer = InvalidBuffer;
1171 /* dump committed child Xids */
1174 rdata[lastrdata].next = &(rdata[2]);
1175 rdata[2].data = (char *) children;
1176 rdata[2].len = nchildren * sizeof(TransactionId);
1177 rdata[2].buffer = InvalidBuffer;
1180 rdata[lastrdata].next = NULL;
1182 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
1185 * Mark the transaction aborted in clog. This is not absolutely necessary
1186 * but we may as well do it while we are here; also, in the subxact case
1187 * it is helpful because XactLockTableWait makes use of it to avoid
1188 * waiting for already-aborted subtransactions. It is OK to do it without
1189 * having flushed the ABORT record to disk, because in event of a crash
1190 * we'd be assumed to have aborted anyway.
1192 * The ordering here isn't critical but it seems best to mark the
1193 * parent first. This assures an atomic transition of all the
1194 * subtransactions to aborted state from the point of view of
1195 * concurrent TransactionIdDidAbort calls.
1197 TransactionIdAbort(xid);
1198 TransactionIdAbortTree(nchildren, children);
1202 /* Compute latestXid while we have the child XIDs handy */
1203 latestXid = TransactionIdLatest(xid, nchildren, children);
1206 * If we're aborting a subtransaction, we can immediately remove failed
1207 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1208 * subxacts, because we already have the child XID array at hand. For
1209 * main xacts, the equivalent happens just after this function returns.
1212 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1214 /* Reset XactLastRecEnd until the next transaction writes something */
1216 XactLastRecEnd.xrecoff = 0;
1218 /* And clean up local data */
1231 AtAbort_Memory(void)
1234 * Switch into TransactionAbortContext, which should have some free
1235 * space even if nothing else does. We'll work in this context until
1236 * we've finished cleaning up.
1238 * It is barely possible to get here when we've not been able to create
1239 * TransactionAbortContext yet; if so use TopMemoryContext.
1241 if (TransactionAbortContext != NULL)
1242 MemoryContextSwitchTo(TransactionAbortContext);
1244 MemoryContextSwitchTo(TopMemoryContext);
1251 AtSubAbort_Memory(void)
1253 Assert(TransactionAbortContext != NULL);
1255 MemoryContextSwitchTo(TransactionAbortContext);
1260 * AtAbort_ResourceOwner
1263 AtAbort_ResourceOwner(void)
1266 * Make sure we have a valid ResourceOwner, if possible (else it will be
1267 * NULL, which is OK)
1269 CurrentResourceOwner = TopTransactionResourceOwner;
1273 * AtSubAbort_ResourceOwner
1276 AtSubAbort_ResourceOwner(void)
1278 TransactionState s = CurrentTransactionState;
1280 /* Make sure we have a valid ResourceOwner */
1281 CurrentResourceOwner = s->curTransactionOwner;
1286 * AtSubAbort_childXids
1289 AtSubAbort_childXids(void)
1291 TransactionState s = CurrentTransactionState;
1294 * We keep the child-XID lists in TopTransactionContext (see
1295 * AtSubCommit_childXids). This means we'd better free the list
1296 * explicitly at abort to avoid leakage.
1298 list_free(s->childXids);
1302 /* ----------------------------------------------------------------
1303 * CleanupTransaction stuff
1304 * ----------------------------------------------------------------
1311 AtCleanup_Memory(void)
1313 Assert(CurrentTransactionState->parent == NULL);
1316 * Now that we're "out" of a transaction, have the system allocate things
1317 * in the top memory context instead of per-transaction contexts.
1319 MemoryContextSwitchTo(TopMemoryContext);
1322 * Clear the special abort context for next time.
1324 if (TransactionAbortContext != NULL)
1325 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1328 * Release all transaction-local memory.
1330 if (TopTransactionContext != NULL)
1331 MemoryContextDelete(TopTransactionContext);
1332 TopTransactionContext = NULL;
1333 CurTransactionContext = NULL;
1334 CurrentTransactionState->curTransactionContext = NULL;
1338 /* ----------------------------------------------------------------
1339 * CleanupSubTransaction stuff
1340 * ----------------------------------------------------------------
1344 * AtSubCleanup_Memory
1347 AtSubCleanup_Memory(void)
1349 TransactionState s = CurrentTransactionState;
1351 Assert(s->parent != NULL);
1353 /* Make sure we're not in an about-to-be-deleted context */
1354 MemoryContextSwitchTo(s->parent->curTransactionContext);
1355 CurTransactionContext = s->parent->curTransactionContext;
1358 * Clear the special abort context for next time.
1360 if (TransactionAbortContext != NULL)
1361 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1364 * Delete the subxact local memory contexts. Its CurTransactionContext can
1365 * go too (note this also kills CurTransactionContexts from any children
1368 if (s->curTransactionContext)
1369 MemoryContextDelete(s->curTransactionContext);
1370 s->curTransactionContext = NULL;
1373 /* ----------------------------------------------------------------
1374 * interface routines
1375 * ----------------------------------------------------------------
1382 StartTransaction(void)
1385 VirtualTransactionId vxid;
1388 * Let's just make sure the state stack is empty
1390 s = &TopTransactionStateData;
1391 CurrentTransactionState = s;
1394 * check the current transaction state
1396 if (s->state != TRANS_DEFAULT)
1397 elog(WARNING, "StartTransaction while in %s state",
1398 TransStateAsString(s->state));
1401 * set the current transaction state information appropriately during
1404 s->state = TRANS_START;
1405 s->transactionId = InvalidTransactionId; /* until assigned */
1408 * Make sure we've freed any old snapshot, and reset xact state variables
1411 XactIsoLevel = DefaultXactIsoLevel;
1412 XactReadOnly = DefaultXactReadOnly;
1413 forceSyncCommit = false;
1416 * reinitialize within-transaction counters
1418 s->subTransactionId = TopSubTransactionId;
1419 currentSubTransactionId = TopSubTransactionId;
1420 currentCommandId = FirstCommandId;
1423 * must initialize resource-management stuff first
1426 AtStart_ResourceOwner();
1429 * Assign a new LocalTransactionId, and combine it with the backendId to
1430 * form a virtual transaction id.
1432 vxid.backendId = MyBackendId;
1433 vxid.localTransactionId = GetNextLocalTransactionId();
1436 * Lock the virtual transaction id before we announce it in the proc array
1438 VirtualXactLockTableInsert(vxid);
1441 * Advertise it in the proc array. We assume assignment of
1442 * LocalTransactionID is atomic, and the backendId should be set already.
1444 Assert(MyProc->backendId == vxid.backendId);
1445 MyProc->lxid = vxid.localTransactionId;
1447 PG_TRACE1(transaction__start, vxid.localTransactionId);
1450 * set transaction_timestamp() (a/k/a now()). We want this to be the same
1451 * as the first command's statement_timestamp(), so don't do a fresh
1452 * GetCurrentTimestamp() call (which'd be expensive anyway). Also,
1453 * mark xactStopTimestamp as unset.
1455 xactStartTimestamp = stmtStartTimestamp;
1456 xactStopTimestamp = 0;
1457 pgstat_report_xact_timestamp(xactStartTimestamp);
1460 * initialize current transaction state fields
1462 s->nestingLevel = 1;
1463 s->gucNestLevel = 1;
1467 * You might expect to see "s->currentUser = GetUserId();" here, but you
1468 * won't because it doesn't work during startup; the userid isn't set yet
1469 * during a backend's first transaction start. We only use the
1470 * currentUser field in sub-transaction state structs.
1472 * prevXactReadOnly is also valid only in sub-transactions.
1476 * initialize other subsystems for new transaction
1481 AfterTriggerBeginXact();
1484 * done with start processing, set current transaction state to "in
1487 s->state = TRANS_INPROGRESS;
1489 ShowTransactionState("StartTransaction");
1496 * NB: if you change this routine, better look at PrepareTransaction too!
1499 CommitTransaction(void)
1501 TransactionState s = CurrentTransactionState;
1502 TransactionId latestXid;
1504 ShowTransactionState("CommitTransaction");
1507 * check the current transaction state
1509 if (s->state != TRANS_INPROGRESS)
1510 elog(WARNING, "CommitTransaction while in %s state",
1511 TransStateAsString(s->state));
1512 Assert(s->parent == NULL);
1515 * Do pre-commit processing (most of this stuff requires database access,
1516 * and in fact could still cause an error...)
1518 * It is possible for CommitHoldablePortals to invoke functions that queue
1519 * deferred triggers, and it's also possible that triggers create holdable
1520 * cursors. So we have to loop until there's nothing left to do.
1525 * Fire all currently pending deferred triggers.
1527 AfterTriggerFireDeferred();
1530 * Convert any open holdable cursors into static portals. If there
1531 * weren't any, we are done ... otherwise loop back to check if they
1532 * queued deferred triggers. Lather, rinse, repeat.
1534 if (!CommitHoldablePortals())
1538 /* Now we can shut down the deferred-trigger manager */
1539 AfterTriggerEndXact(true);
1541 /* Close any open regular cursors */
1545 * Let ON COMMIT management do its thing (must happen after closing
1546 * cursors, to avoid dangling-reference problems)
1548 PreCommit_on_commit_actions();
1550 /* close large objects before lower-level cleanup */
1551 AtEOXact_LargeObject(true);
1553 /* NOTIFY commit must come before lower-level cleanup */
1557 * Update flat files if we changed pg_database, pg_authid or
1558 * pg_auth_members. This should be the last step before commit.
1560 AtEOXact_UpdateFlatFiles(true);
1562 /* Prevent cancel/die interrupt while cleaning up */
1566 * set the current transaction state information appropriately during
1569 s->state = TRANS_COMMIT;
1572 * Here is where we really truly commit.
1574 latestXid = RecordTransactionCommit();
1576 PG_TRACE1(transaction__commit, MyProc->lxid);
1579 * Let others know about no transaction in progress by me. Note that
1580 * this must be done _before_ releasing locks we hold and _after_
1581 * RecordTransactionCommit.
1583 ProcArrayEndTransaction(MyProc, latestXid);
1586 * This is all post-commit cleanup. Note that if an error is raised here,
1587 * it's too late to abort the transaction. This should be just
1588 * noncritical resource releasing.
1590 * The ordering of operations is not entirely random. The idea is:
1591 * release resources visible to other backends (eg, files, buffer pins);
1592 * then release locks; then release backend-local resources. We want to
1593 * release locks at the point where any backend waiting for us will see
1594 * our transaction as being fully cleaned up.
1596 * Resources that can be associated with individual queries are handled by
1597 * the ResourceOwner mechanism. The other calls here are for backend-wide
1601 CallXactCallbacks(XACT_EVENT_COMMIT);
1603 ResourceOwnerRelease(TopTransactionResourceOwner,
1604 RESOURCE_RELEASE_BEFORE_LOCKS,
1607 /* Check we've released all buffer pins */
1608 AtEOXact_Buffers(true);
1610 /* Clean up the relation cache */
1611 AtEOXact_RelationCache(true);
1614 * Make catalog changes visible to all backends. This has to happen after
1615 * relcache references are dropped (see comments for
1616 * AtEOXact_RelationCache), but before locks are released (if anyone is
1617 * waiting for lock on a relation we've modified, we want them to know
1618 * about the catalog change before they start using the relation).
1620 AtEOXact_Inval(true);
1623 * Likewise, dropping of files deleted during the transaction is best done
1624 * after releasing relcache and buffer pins. (This is not strictly
1625 * necessary during commit, since such pins should have been released
1626 * already, but this ordering is definitely critical during abort.)
1628 smgrDoPendingDeletes(true);
1630 AtEOXact_MultiXact();
1632 ResourceOwnerRelease(TopTransactionResourceOwner,
1633 RESOURCE_RELEASE_LOCKS,
1635 ResourceOwnerRelease(TopTransactionResourceOwner,
1636 RESOURCE_RELEASE_AFTER_LOCKS,
1639 /* Check we've released all catcache entries */
1640 AtEOXact_CatCache(true);
1642 AtEOXact_GUC(true, 1);
1644 AtEOXact_on_commit_actions(true);
1645 AtEOXact_Namespace(true);
1646 /* smgrcommit already done */
1648 AtEOXact_ComboCid();
1649 AtEOXact_HashTables(true);
1650 AtEOXact_PgStat(true);
1651 pgstat_report_xact_timestamp(0);
1653 CurrentResourceOwner = NULL;
1654 ResourceOwnerDelete(TopTransactionResourceOwner);
1655 s->curTransactionOwner = NULL;
1656 CurTransactionResourceOwner = NULL;
1657 TopTransactionResourceOwner = NULL;
1661 s->transactionId = InvalidTransactionId;
1662 s->subTransactionId = InvalidSubTransactionId;
1663 s->nestingLevel = 0;
1664 s->gucNestLevel = 0;
1668 * done with commit processing, set current transaction state back to
1671 s->state = TRANS_DEFAULT;
1673 RESUME_INTERRUPTS();
1678 * PrepareTransaction
1680 * NB: if you change this routine, better look at CommitTransaction too!
1683 PrepareTransaction(void)
1685 TransactionState s = CurrentTransactionState;
1686 TransactionId xid = GetCurrentTransactionId();
1687 GlobalTransaction gxact;
1688 TimestampTz prepared_at;
1690 ShowTransactionState("PrepareTransaction");
1693 * check the current transaction state
1695 if (s->state != TRANS_INPROGRESS)
1696 elog(WARNING, "PrepareTransaction while in %s state",
1697 TransStateAsString(s->state));
1698 Assert(s->parent == NULL);
1701 * Do pre-commit processing (most of this stuff requires database access,
1702 * and in fact could still cause an error...)
1704 * It is possible for PrepareHoldablePortals to invoke functions that
1705 * queue deferred triggers, and it's also possible that triggers create
1706 * holdable cursors. So we have to loop until there's nothing left to do.
1711 * Fire all currently pending deferred triggers.
1713 AfterTriggerFireDeferred();
1716 * Convert any open holdable cursors into static portals. If there
1717 * weren't any, we are done ... otherwise loop back to check if they
1718 * queued deferred triggers. Lather, rinse, repeat.
1720 if (!PrepareHoldablePortals())
1724 /* Now we can shut down the deferred-trigger manager */
1725 AfterTriggerEndXact(true);
1727 /* Close any open regular cursors */
1731 * Let ON COMMIT management do its thing (must happen after closing
1732 * cursors, to avoid dangling-reference problems)
1734 PreCommit_on_commit_actions();
1736 /* close large objects before lower-level cleanup */
1737 AtEOXact_LargeObject(true);
1739 /* NOTIFY and flatfiles will be handled below */
1741 /* Prevent cancel/die interrupt while cleaning up */
1745 * set the current transaction state information appropriately during
1746 * prepare processing
1748 s->state = TRANS_PREPARE;
1750 prepared_at = GetCurrentTimestamp();
1752 /* Tell bufmgr and smgr to prepare for commit */
1756 * Reserve the GID for this transaction. This could fail if the requested
1757 * GID is invalid or already in use.
1759 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
1760 GetUserId(), MyDatabaseId);
1764 * Collect data for the 2PC state file. Note that in general, no actual
1765 * state change should happen in the called modules during this step,
1766 * since it's still possible to fail before commit, and in that case we
1767 * want transaction abort to be able to clean up. (In particular, the
1768 * AtPrepare routines may error out if they find cases they cannot
1769 * handle.) State cleanup should happen in the PostPrepare routines
1770 * below. However, some modules can go ahead and clear state here because
1771 * they wouldn't do anything with it during abort anyway.
1773 * Note: because the 2PC state file records will be replayed in the same
1774 * order they are made, the order of these calls has to match the order in
1775 * which we want things to happen during COMMIT PREPARED or ROLLBACK
1776 * PREPARED; in particular, pay attention to whether things should happen
1777 * before or after releasing the transaction's locks.
1779 StartPrepare(gxact);
1782 AtPrepare_UpdateFlatFiles();
1788 * Here is where we really truly prepare.
1790 * We have to record transaction prepares even if we didn't make any
1791 * updates, because the transaction manager might get confused if we lose
1792 * a global transaction.
1797 * Now we clean up backend-internal state and release internal resources.
1800 /* Reset XactLastRecEnd until the next transaction writes something */
1801 XactLastRecEnd.xrecoff = 0;
1804 * Let others know about no transaction in progress by me. This has to be
1805 * done *after* the prepared transaction has been marked valid, else
1806 * someone may think it is unlocked and recyclable.
1808 ProcArrayClearTransaction(MyProc);
1811 * This is all post-transaction cleanup. Note that if an error is raised
1812 * here, it's too late to abort the transaction. This should be just
1813 * noncritical resource releasing. See notes in CommitTransaction.
1816 CallXactCallbacks(XACT_EVENT_PREPARE);
1818 ResourceOwnerRelease(TopTransactionResourceOwner,
1819 RESOURCE_RELEASE_BEFORE_LOCKS,
1822 /* Check we've released all buffer pins */
1823 AtEOXact_Buffers(true);
1825 /* Clean up the relation cache */
1826 AtEOXact_RelationCache(true);
1828 /* notify and flatfiles don't need a postprepare call */
1830 PostPrepare_PgStat();
1832 PostPrepare_Inval();
1836 AtEOXact_MultiXact();
1838 PostPrepare_Locks(xid);
1840 ResourceOwnerRelease(TopTransactionResourceOwner,
1841 RESOURCE_RELEASE_LOCKS,
1843 ResourceOwnerRelease(TopTransactionResourceOwner,
1844 RESOURCE_RELEASE_AFTER_LOCKS,
1847 /* Check we've released all catcache entries */
1848 AtEOXact_CatCache(true);
1850 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
1851 AtEOXact_GUC(true, 1);
1853 AtEOXact_on_commit_actions(true);
1854 AtEOXact_Namespace(true);
1855 /* smgrcommit already done */
1857 AtEOXact_ComboCid();
1858 AtEOXact_HashTables(true);
1859 /* don't call AtEOXact_PgStat here */
1861 CurrentResourceOwner = NULL;
1862 ResourceOwnerDelete(TopTransactionResourceOwner);
1863 s->curTransactionOwner = NULL;
1864 CurTransactionResourceOwner = NULL;
1865 TopTransactionResourceOwner = NULL;
1869 s->transactionId = InvalidTransactionId;
1870 s->subTransactionId = InvalidSubTransactionId;
1871 s->nestingLevel = 0;
1872 s->gucNestLevel = 0;
1876 * done with 1st phase commit processing, set current transaction state
1879 s->state = TRANS_DEFAULT;
1881 RESUME_INTERRUPTS();
1889 AbortTransaction(void)
1891 TransactionState s = CurrentTransactionState;
1892 TransactionId latestXid;
1894 /* Prevent cancel/die interrupt while cleaning up */
1897 /* Make sure we have a valid memory context and resource owner */
1899 AtAbort_ResourceOwner();
1902 * Release any LW locks we might be holding as quickly as possible.
1903 * (Regular locks, however, must be held till we finish aborting.)
1904 * Releasing LW locks is critical since we might try to grab them again
1905 * while cleaning up!
1909 /* Clean up buffer I/O and buffer context locks, too */
1914 * Also clean up any open wait for lock, since the lock manager will choke
1915 * if we try to wait for another lock before doing this.
1920 * check the current transaction state
1922 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
1923 elog(WARNING, "AbortTransaction while in %s state",
1924 TransStateAsString(s->state));
1925 Assert(s->parent == NULL);
1928 * set the current transaction state information appropriately during the
1931 s->state = TRANS_ABORT;
1934 * Reset user id which might have been changed transiently. We cannot use
1935 * s->currentUser, since it may not be set yet; instead rely on internal
1936 * state of miscinit.c.
1938 * (Note: it is not necessary to restore session authorization here
1939 * because that can only be changed via GUC, and GUC will take care of
1940 * rolling it back if need be. However, an error within a SECURITY
1941 * DEFINER function could send control here with the wrong current
1947 * do abort processing
1949 AfterTriggerEndXact(false);
1951 AtEOXact_LargeObject(false); /* 'false' means it's abort */
1953 AtEOXact_UpdateFlatFiles(false);
1956 * Advertise the fact that we aborted in pg_clog (assuming that we got as
1957 * far as assigning an XID to advertise).
1959 latestXid = RecordTransactionAbort(false);
1961 PG_TRACE1(transaction__abort, MyProc->lxid);
1964 * Let others know about no transaction in progress by me. Note that this
1965 * must be done _before_ releasing locks we hold and _after_
1966 * RecordTransactionAbort.
1968 ProcArrayEndTransaction(MyProc, latestXid);
1971 * Post-abort cleanup. See notes in CommitTransaction() concerning
1975 CallXactCallbacks(XACT_EVENT_ABORT);
1977 ResourceOwnerRelease(TopTransactionResourceOwner,
1978 RESOURCE_RELEASE_BEFORE_LOCKS,
1980 AtEOXact_Buffers(false);
1981 AtEOXact_RelationCache(false);
1982 AtEOXact_Inval(false);
1983 smgrDoPendingDeletes(false);
1984 AtEOXact_MultiXact();
1985 ResourceOwnerRelease(TopTransactionResourceOwner,
1986 RESOURCE_RELEASE_LOCKS,
1988 ResourceOwnerRelease(TopTransactionResourceOwner,
1989 RESOURCE_RELEASE_AFTER_LOCKS,
1991 AtEOXact_CatCache(false);
1993 AtEOXact_GUC(false, 1);
1994 AtEOXact_SPI(false);
1995 AtEOXact_on_commit_actions(false);
1996 AtEOXact_Namespace(false);
1999 AtEOXact_ComboCid();
2000 AtEOXact_HashTables(false);
2001 AtEOXact_PgStat(false);
2002 pgstat_report_xact_timestamp(0);
2005 * State remains TRANS_ABORT until CleanupTransaction().
2007 RESUME_INTERRUPTS();
2011 * CleanupTransaction
2014 CleanupTransaction(void)
2016 TransactionState s = CurrentTransactionState;
2019 * State should still be TRANS_ABORT from AbortTransaction().
2021 if (s->state != TRANS_ABORT)
2022 elog(FATAL, "CleanupTransaction: unexpected state %s",
2023 TransStateAsString(s->state));
2026 * do abort cleanup processing
2028 AtCleanup_Portals(); /* now safe to release portal memory */
2030 CurrentResourceOwner = NULL; /* and resource owner */
2031 if (TopTransactionResourceOwner)
2032 ResourceOwnerDelete(TopTransactionResourceOwner);
2033 s->curTransactionOwner = NULL;
2034 CurTransactionResourceOwner = NULL;
2035 TopTransactionResourceOwner = NULL;
2037 AtCleanup_Memory(); /* and transaction memory */
2039 s->transactionId = InvalidTransactionId;
2040 s->subTransactionId = InvalidSubTransactionId;
2041 s->nestingLevel = 0;
2042 s->gucNestLevel = 0;
2046 * done with abort processing, set current transaction state back to
2049 s->state = TRANS_DEFAULT;
2053 * StartTransactionCommand
2056 StartTransactionCommand(void)
2058 TransactionState s = CurrentTransactionState;
2060 switch (s->blockState)
2063 * if we aren't in a transaction block, we just do our usual start
2066 case TBLOCK_DEFAULT:
2068 s->blockState = TBLOCK_STARTED;
2072 * We are somewhere in a transaction block or subtransaction and
2073 * about to start a new command. For now we do nothing, but
2074 * someday we may do command-local resource initialization. (Note
2075 * that any needed CommandCounterIncrement was done by the
2076 * previous CommitTransactionCommand.)
2078 case TBLOCK_INPROGRESS:
2079 case TBLOCK_SUBINPROGRESS:
2083 * Here we are in a failed transaction block (one of the commands
2084 * caused an abort) so we do nothing but remain in the abort
2085 * state. Eventually we will get a ROLLBACK command which will
2086 * get us out of this state. (It is up to other code to ensure
2087 * that no commands other than ROLLBACK will be processed in these
2091 case TBLOCK_SUBABORT:
2094 /* These cases are invalid. */
2095 case TBLOCK_STARTED:
2097 case TBLOCK_SUBBEGIN:
2100 case TBLOCK_ABORT_END:
2101 case TBLOCK_SUBABORT_END:
2102 case TBLOCK_ABORT_PENDING:
2103 case TBLOCK_SUBABORT_PENDING:
2104 case TBLOCK_SUBRESTART:
2105 case TBLOCK_SUBABORT_RESTART:
2106 case TBLOCK_PREPARE:
2107 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2108 BlockStateAsString(s->blockState));
2113 * We must switch to CurTransactionContext before returning. This is
2114 * already done if we called StartTransaction, otherwise not.
2116 Assert(CurTransactionContext != NULL);
2117 MemoryContextSwitchTo(CurTransactionContext);
2121 * CommitTransactionCommand
2124 CommitTransactionCommand(void)
2126 TransactionState s = CurrentTransactionState;
2128 switch (s->blockState)
2131 * This shouldn't happen, because it means the previous
2132 * StartTransactionCommand didn't set the STARTED state
2135 case TBLOCK_DEFAULT:
2136 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2137 BlockStateAsString(s->blockState));
2141 * If we aren't in a transaction block, just do our usual
2142 * transaction commit, and return to the idle state.
2144 case TBLOCK_STARTED:
2145 CommitTransaction();
2146 s->blockState = TBLOCK_DEFAULT;
2150 * We are completing a "BEGIN TRANSACTION" command, so we change
2151 * to the "transaction block in progress" state and return. (We
2152 * assume the BEGIN did nothing to the database, so we need no
2153 * CommandCounterIncrement.)
2156 s->blockState = TBLOCK_INPROGRESS;
2160 * This is the case when we have finished executing a command
2161 * someplace within a transaction block. We increment the command
2162 * counter and return.
2164 case TBLOCK_INPROGRESS:
2165 case TBLOCK_SUBINPROGRESS:
2166 CommandCounterIncrement();
2170 * We are completing a "COMMIT" command. Do it and return to the
2174 CommitTransaction();
2175 s->blockState = TBLOCK_DEFAULT;
2179 * Here we are in the middle of a transaction block but one of the
2180 * commands caused an abort so we do nothing but remain in the
2181 * abort state. Eventually we will get a ROLLBACK comand.
2184 case TBLOCK_SUBABORT:
2188 * Here we were in an aborted transaction block and we just got
2189 * the ROLLBACK command from the user, so clean up the
2190 * already-aborted transaction and return to the idle state.
2192 case TBLOCK_ABORT_END:
2193 CleanupTransaction();
2194 s->blockState = TBLOCK_DEFAULT;
2198 * Here we were in a perfectly good transaction block but the user
2199 * told us to ROLLBACK anyway. We have to abort the transaction
2200 * and then clean up.
2202 case TBLOCK_ABORT_PENDING:
2204 CleanupTransaction();
2205 s->blockState = TBLOCK_DEFAULT;
2209 * We are completing a "PREPARE TRANSACTION" command. Do it and
2210 * return to the idle state.
2212 case TBLOCK_PREPARE:
2213 PrepareTransaction();
2214 s->blockState = TBLOCK_DEFAULT;
2218 * We were just issued a SAVEPOINT inside a transaction block.
2219 * Start a subtransaction. (DefineSavepoint already did
2220 * PushTransaction, so as to have someplace to put the SUBBEGIN
2223 case TBLOCK_SUBBEGIN:
2224 StartSubTransaction();
2225 s->blockState = TBLOCK_SUBINPROGRESS;
2229 * We were issued a COMMIT or RELEASE command, so we end the
2230 * current subtransaction and return to the parent transaction.
2231 * The parent might be ended too, so repeat till we are all the
2232 * way out or find an INPROGRESS transaction.
2237 CommitSubTransaction();
2238 s = CurrentTransactionState; /* changed by pop */
2239 } while (s->blockState == TBLOCK_SUBEND);
2240 /* If we had a COMMIT command, finish off the main xact too */
2241 if (s->blockState == TBLOCK_END)
2243 Assert(s->parent == NULL);
2244 CommitTransaction();
2245 s->blockState = TBLOCK_DEFAULT;
2247 else if (s->blockState == TBLOCK_PREPARE)
2249 Assert(s->parent == NULL);
2250 PrepareTransaction();
2251 s->blockState = TBLOCK_DEFAULT;
2255 Assert(s->blockState == TBLOCK_INPROGRESS ||
2256 s->blockState == TBLOCK_SUBINPROGRESS);
2261 * The current already-failed subtransaction is ending due to a
2262 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2263 * examine the parent (which could be in any of several states).
2265 case TBLOCK_SUBABORT_END:
2266 CleanupSubTransaction();
2267 CommitTransactionCommand();
2271 * As above, but it's not dead yet, so abort first.
2273 case TBLOCK_SUBABORT_PENDING:
2274 AbortSubTransaction();
2275 CleanupSubTransaction();
2276 CommitTransactionCommand();
2280 * The current subtransaction is the target of a ROLLBACK TO
2281 * command. Abort and pop it, then start a new subtransaction
2282 * with the same name.
2284 case TBLOCK_SUBRESTART:
2289 /* save name and keep Cleanup from freeing it */
2292 savepointLevel = s->savepointLevel;
2294 AbortSubTransaction();
2295 CleanupSubTransaction();
2297 DefineSavepoint(NULL);
2298 s = CurrentTransactionState; /* changed by push */
2300 s->savepointLevel = savepointLevel;
2302 /* This is the same as TBLOCK_SUBBEGIN case */
2303 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2304 StartSubTransaction();
2305 s->blockState = TBLOCK_SUBINPROGRESS;
2310 * Same as above, but the subtransaction had already failed, so we
2311 * don't need AbortSubTransaction.
2313 case TBLOCK_SUBABORT_RESTART:
2318 /* save name and keep Cleanup from freeing it */
2321 savepointLevel = s->savepointLevel;
2323 CleanupSubTransaction();
2325 DefineSavepoint(NULL);
2326 s = CurrentTransactionState; /* changed by push */
2328 s->savepointLevel = savepointLevel;
2330 /* This is the same as TBLOCK_SUBBEGIN case */
2331 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2332 StartSubTransaction();
2333 s->blockState = TBLOCK_SUBINPROGRESS;
2340 * AbortCurrentTransaction
2343 AbortCurrentTransaction(void)
2345 TransactionState s = CurrentTransactionState;
2347 switch (s->blockState)
2349 case TBLOCK_DEFAULT:
2350 if (s->state == TRANS_DEFAULT)
2352 /* we are idle, so nothing to do */
2357 * We can get here after an error during transaction start
2358 * (state will be TRANS_START). Need to clean up the
2359 * incompletely started transaction. First, adjust the
2360 * low-level state to suppress warning message from
2363 if (s->state == TRANS_START)
2364 s->state = TRANS_INPROGRESS;
2366 CleanupTransaction();
2371 * if we aren't in a transaction block, we just do the basic abort
2372 * & cleanup transaction.
2374 case TBLOCK_STARTED:
2376 CleanupTransaction();
2377 s->blockState = TBLOCK_DEFAULT;
2381 * If we are in TBLOCK_BEGIN it means something screwed up right
2382 * after reading "BEGIN TRANSACTION". We assume that the user
2383 * will interpret the error as meaning the BEGIN failed to get him
2384 * into a transaction block, so we should abort and return to idle
2389 CleanupTransaction();
2390 s->blockState = TBLOCK_DEFAULT;
2394 * We are somewhere in a transaction block and we've gotten a
2395 * failure, so we abort the transaction and set up the persistent
2396 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
2398 case TBLOCK_INPROGRESS:
2400 s->blockState = TBLOCK_ABORT;
2401 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
2405 * Here, we failed while trying to COMMIT. Clean up the
2406 * transaction and return to idle state (we do not want to stay in
2411 CleanupTransaction();
2412 s->blockState = TBLOCK_DEFAULT;
2416 * Here, we are already in an aborted transaction state and are
2417 * waiting for a ROLLBACK, but for some reason we failed again! So
2418 * we just remain in the abort state.
2421 case TBLOCK_SUBABORT:
2425 * We are in a failed transaction and we got the ROLLBACK command.
2426 * We have already aborted, we just need to cleanup and go to idle
2429 case TBLOCK_ABORT_END:
2430 CleanupTransaction();
2431 s->blockState = TBLOCK_DEFAULT;
2435 * We are in a live transaction and we got a ROLLBACK command.
2436 * Abort, cleanup, go to idle state.
2438 case TBLOCK_ABORT_PENDING:
2440 CleanupTransaction();
2441 s->blockState = TBLOCK_DEFAULT;
2445 * Here, we failed while trying to PREPARE. Clean up the
2446 * transaction and return to idle state (we do not want to stay in
2449 case TBLOCK_PREPARE:
2451 CleanupTransaction();
2452 s->blockState = TBLOCK_DEFAULT;
2456 * We got an error inside a subtransaction. Abort just the
2457 * subtransaction, and go to the persistent SUBABORT state until
2460 case TBLOCK_SUBINPROGRESS:
2461 AbortSubTransaction();
2462 s->blockState = TBLOCK_SUBABORT;
2466 * If we failed while trying to create a subtransaction, clean up
2467 * the broken subtransaction and abort the parent. The same
2468 * applies if we get a failure while ending a subtransaction.
2470 case TBLOCK_SUBBEGIN:
2472 case TBLOCK_SUBABORT_PENDING:
2473 case TBLOCK_SUBRESTART:
2474 AbortSubTransaction();
2475 CleanupSubTransaction();
2476 AbortCurrentTransaction();
2480 * Same as above, except the Abort() was already done.
2482 case TBLOCK_SUBABORT_END:
2483 case TBLOCK_SUBABORT_RESTART:
2484 CleanupSubTransaction();
2485 AbortCurrentTransaction();
2491 * PreventTransactionChain
2493 * This routine is to be called by statements that must not run inside
2494 * a transaction block, typically because they have non-rollback-able
2495 * side effects or do internal commits.
2497 * If we have already started a transaction block, issue an error; also issue
2498 * an error if we appear to be running inside a user-defined function (which
2499 * could issue more commands and possibly cause a failure after the statement
2500 * completes). Subtransactions are verboten too.
2502 * isTopLevel: passed down from ProcessUtility to determine whether we are
2503 * inside a function or multi-query querystring. (We will always fail if
2504 * this is false, but it's convenient to centralize the check here instead of
2505 * making callers do it.)
2506 * stmtType: statement type name, for error messages.
2509 PreventTransactionChain(bool isTopLevel, const char *stmtType)
2512 * xact block already started?
2514 if (IsTransactionBlock())
2516 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2517 /* translator: %s represents an SQL statement name */
2518 errmsg("%s cannot run inside a transaction block",
2524 if (IsSubTransaction())
2526 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2527 /* translator: %s represents an SQL statement name */
2528 errmsg("%s cannot run inside a subtransaction",
2532 * inside a function call?
2536 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2537 /* translator: %s represents an SQL statement name */
2538 errmsg("%s cannot be executed from a function or multi-command string",
2541 /* If we got past IsTransactionBlock test, should be in default state */
2542 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2543 CurrentTransactionState->blockState != TBLOCK_STARTED)
2544 elog(FATAL, "cannot prevent transaction chain");
2549 * RequireTransactionChain
2551 * This routine is to be called by statements that must run inside
2552 * a transaction block, because they have no effects that persist past
2553 * transaction end (and so calling them outside a transaction block
2554 * is presumably an error). DECLARE CURSOR is an example.
2556 * If we appear to be running inside a user-defined function, we do not
2557 * issue an error, since the function could issue more commands that make
2558 * use of the current statement's results. Likewise subtransactions.
2559 * Thus this is an inverse for PreventTransactionChain.
2561 * isTopLevel: passed down from ProcessUtility to determine whether we are
2562 * inside a function.
2563 * stmtType: statement type name, for error messages.
2566 RequireTransactionChain(bool isTopLevel, const char *stmtType)
2569 * xact block already started?
2571 if (IsTransactionBlock())
2577 if (IsSubTransaction())
2581 * inside a function call?
2587 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2588 /* translator: %s represents an SQL statement name */
2589 errmsg("%s can only be used in transaction blocks",
2594 * IsInTransactionChain
2596 * This routine is for statements that need to behave differently inside
2597 * a transaction block than when running as single commands. ANALYZE is
2598 * currently the only example.
2600 * isTopLevel: passed down from ProcessUtility to determine whether we are
2601 * inside a function.
2604 IsInTransactionChain(bool isTopLevel)
2607 * Return true on same conditions that would make PreventTransactionChain
2610 if (IsTransactionBlock())
2613 if (IsSubTransaction())
2619 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2620 CurrentTransactionState->blockState != TBLOCK_STARTED)
2628 * Register or deregister callback functions for start- and end-of-xact
2631 * These functions are intended for use by dynamically loaded modules.
2632 * For built-in modules we generally just hardwire the appropriate calls
2633 * (mainly because it's easier to control the order that way, where needed).
2635 * At transaction end, the callback occurs post-commit or post-abort, so the
2636 * callback functions can only do noncritical cleanup.
2639 RegisterXactCallback(XactCallback callback, void *arg)
2641 XactCallbackItem *item;
2643 item = (XactCallbackItem *)
2644 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
2645 item->callback = callback;
2647 item->next = Xact_callbacks;
2648 Xact_callbacks = item;
2652 UnregisterXactCallback(XactCallback callback, void *arg)
2654 XactCallbackItem *item;
2655 XactCallbackItem *prev;
2658 for (item = Xact_callbacks; item; prev = item, item = item->next)
2660 if (item->callback == callback && item->arg == arg)
2663 prev->next = item->next;
2665 Xact_callbacks = item->next;
2673 CallXactCallbacks(XactEvent event)
2675 XactCallbackItem *item;
2677 for (item = Xact_callbacks; item; item = item->next)
2678 (*item->callback) (event, item->arg);
2683 * Register or deregister callback functions for start- and end-of-subxact
2686 * Pretty much same as above, but for subtransaction events.
2688 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
2689 * so the callback functions can only do noncritical cleanup. At
2690 * subtransaction start, the callback is called when the subtransaction has
2691 * finished initializing.
2694 RegisterSubXactCallback(SubXactCallback callback, void *arg)
2696 SubXactCallbackItem *item;
2698 item = (SubXactCallbackItem *)
2699 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
2700 item->callback = callback;
2702 item->next = SubXact_callbacks;
2703 SubXact_callbacks = item;
2707 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
2709 SubXactCallbackItem *item;
2710 SubXactCallbackItem *prev;
2713 for (item = SubXact_callbacks; item; prev = item, item = item->next)
2715 if (item->callback == callback && item->arg == arg)
2718 prev->next = item->next;
2720 SubXact_callbacks = item->next;
2728 CallSubXactCallbacks(SubXactEvent event,
2729 SubTransactionId mySubid,
2730 SubTransactionId parentSubid)
2732 SubXactCallbackItem *item;
2734 for (item = SubXact_callbacks; item; item = item->next)
2735 (*item->callback) (event, mySubid, parentSubid, item->arg);
2739 /* ----------------------------------------------------------------
2740 * transaction block support
2741 * ----------------------------------------------------------------
2745 * BeginTransactionBlock
2746 * This executes a BEGIN command.
2749 BeginTransactionBlock(void)
2751 TransactionState s = CurrentTransactionState;
2753 switch (s->blockState)
2756 * We are not inside a transaction block, so allow one to begin.
2758 case TBLOCK_STARTED:
2759 s->blockState = TBLOCK_BEGIN;
2763 * Already a transaction block in progress.
2765 case TBLOCK_INPROGRESS:
2766 case TBLOCK_SUBINPROGRESS:
2768 case TBLOCK_SUBABORT:
2770 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2771 errmsg("there is already a transaction in progress")));
2774 /* These cases are invalid. */
2775 case TBLOCK_DEFAULT:
2777 case TBLOCK_SUBBEGIN:
2780 case TBLOCK_ABORT_END:
2781 case TBLOCK_SUBABORT_END:
2782 case TBLOCK_ABORT_PENDING:
2783 case TBLOCK_SUBABORT_PENDING:
2784 case TBLOCK_SUBRESTART:
2785 case TBLOCK_SUBABORT_RESTART:
2786 case TBLOCK_PREPARE:
2787 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
2788 BlockStateAsString(s->blockState));
2794 * PrepareTransactionBlock
2795 * This executes a PREPARE command.
2797 * Since PREPARE may actually do a ROLLBACK, the result indicates what
2798 * happened: TRUE for PREPARE, FALSE for ROLLBACK.
2800 * Note that we don't actually do anything here except change blockState.
2801 * The real work will be done in the upcoming PrepareTransaction().
2802 * We do it this way because it's not convenient to change memory context,
2803 * resource owner, etc while executing inside a Portal.
2806 PrepareTransactionBlock(char *gid)
2811 /* Set up to commit the current transaction */
2812 result = EndTransactionBlock();
2814 /* If successful, change outer tblock state to PREPARE */
2817 s = CurrentTransactionState;
2819 while (s->parent != NULL)
2822 if (s->blockState == TBLOCK_END)
2824 /* Save GID where PrepareTransaction can find it again */
2825 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
2827 s->blockState = TBLOCK_PREPARE;
2832 * ignore case where we are not in a transaction;
2833 * EndTransactionBlock already issued a warning.
2835 Assert(s->blockState == TBLOCK_STARTED);
2836 /* Don't send back a PREPARE result tag... */
2845 * EndTransactionBlock
2846 * This executes a COMMIT command.
2848 * Since COMMIT may actually do a ROLLBACK, the result indicates what
2849 * happened: TRUE for COMMIT, FALSE for ROLLBACK.
2851 * Note that we don't actually do anything here except change blockState.
2852 * The real work will be done in the upcoming CommitTransactionCommand().
2853 * We do it this way because it's not convenient to change memory context,
2854 * resource owner, etc while executing inside a Portal.
2857 EndTransactionBlock(void)
2859 TransactionState s = CurrentTransactionState;
2860 bool result = false;
2862 switch (s->blockState)
2865 * We are in a transaction block, so tell CommitTransactionCommand
2868 case TBLOCK_INPROGRESS:
2869 s->blockState = TBLOCK_END;
2874 * We are in a failed transaction block. Tell
2875 * CommitTransactionCommand it's time to exit the block.
2878 s->blockState = TBLOCK_ABORT_END;
2882 * We are in a live subtransaction block. Set up to subcommit all
2883 * open subtransactions and then commit the main transaction.
2885 case TBLOCK_SUBINPROGRESS:
2886 while (s->parent != NULL)
2888 if (s->blockState == TBLOCK_SUBINPROGRESS)
2889 s->blockState = TBLOCK_SUBEND;
2891 elog(FATAL, "EndTransactionBlock: unexpected state %s",
2892 BlockStateAsString(s->blockState));
2895 if (s->blockState == TBLOCK_INPROGRESS)
2896 s->blockState = TBLOCK_END;
2898 elog(FATAL, "EndTransactionBlock: unexpected state %s",
2899 BlockStateAsString(s->blockState));
2904 * Here we are inside an aborted subtransaction. Treat the COMMIT
2905 * as ROLLBACK: set up to abort everything and exit the main
2908 case TBLOCK_SUBABORT:
2909 while (s->parent != NULL)
2911 if (s->blockState == TBLOCK_SUBINPROGRESS)
2912 s->blockState = TBLOCK_SUBABORT_PENDING;
2913 else if (s->blockState == TBLOCK_SUBABORT)
2914 s->blockState = TBLOCK_SUBABORT_END;
2916 elog(FATAL, "EndTransactionBlock: unexpected state %s",
2917 BlockStateAsString(s->blockState));
2920 if (s->blockState == TBLOCK_INPROGRESS)
2921 s->blockState = TBLOCK_ABORT_PENDING;
2922 else if (s->blockState == TBLOCK_ABORT)
2923 s->blockState = TBLOCK_ABORT_END;
2925 elog(FATAL, "EndTransactionBlock: unexpected state %s",
2926 BlockStateAsString(s->blockState));
2930 * The user issued COMMIT when not inside a transaction. Issue a
2931 * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
2932 * CommitTransactionCommand() will then close the transaction and
2933 * put us back into the default state.
2935 case TBLOCK_STARTED:
2937 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2938 errmsg("there is no transaction in progress")));
2942 /* These cases are invalid. */
2943 case TBLOCK_DEFAULT:
2945 case TBLOCK_SUBBEGIN:
2948 case TBLOCK_ABORT_END:
2949 case TBLOCK_SUBABORT_END:
2950 case TBLOCK_ABORT_PENDING:
2951 case TBLOCK_SUBABORT_PENDING:
2952 case TBLOCK_SUBRESTART:
2953 case TBLOCK_SUBABORT_RESTART:
2954 case TBLOCK_PREPARE:
2955 elog(FATAL, "EndTransactionBlock: unexpected state %s",
2956 BlockStateAsString(s->blockState));
2964 * UserAbortTransactionBlock
2965 * This executes a ROLLBACK command.
2967 * As above, we don't actually do anything here except change blockState.
2970 UserAbortTransactionBlock(void)
2972 TransactionState s = CurrentTransactionState;
2974 switch (s->blockState)
2977 * We are inside a transaction block and we got a ROLLBACK command
2978 * from the user, so tell CommitTransactionCommand to abort and
2979 * exit the transaction block.
2981 case TBLOCK_INPROGRESS:
2982 s->blockState = TBLOCK_ABORT_PENDING;
2986 * We are inside a failed transaction block and we got a ROLLBACK
2987 * command from the user. Abort processing is already done, so
2988 * CommitTransactionCommand just has to cleanup and go back to
2992 s->blockState = TBLOCK_ABORT_END;
2996 * We are inside a subtransaction. Mark everything up to top
2997 * level as exitable.
2999 case TBLOCK_SUBINPROGRESS:
3000 case TBLOCK_SUBABORT:
3001 while (s->parent != NULL)
3003 if (s->blockState == TBLOCK_SUBINPROGRESS)
3004 s->blockState = TBLOCK_SUBABORT_PENDING;
3005 else if (s->blockState == TBLOCK_SUBABORT)
3006 s->blockState = TBLOCK_SUBABORT_END;
3008 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3009 BlockStateAsString(s->blockState));
3012 if (s->blockState == TBLOCK_INPROGRESS)
3013 s->blockState = TBLOCK_ABORT_PENDING;
3014 else if (s->blockState == TBLOCK_ABORT)
3015 s->blockState = TBLOCK_ABORT_END;
3017 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3018 BlockStateAsString(s->blockState));
3022 * The user issued ABORT when not inside a transaction. Issue a
3023 * WARNING and go to abort state. The upcoming call to
3024 * CommitTransactionCommand() will then put us back into the
3027 case TBLOCK_STARTED:
3029 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3030 errmsg("there is no transaction in progress")));
3031 s->blockState = TBLOCK_ABORT_PENDING;
3034 /* These cases are invalid. */
3035 case TBLOCK_DEFAULT:
3037 case TBLOCK_SUBBEGIN:
3040 case TBLOCK_ABORT_END:
3041 case TBLOCK_SUBABORT_END:
3042 case TBLOCK_ABORT_PENDING:
3043 case TBLOCK_SUBABORT_PENDING:
3044 case TBLOCK_SUBRESTART:
3045 case TBLOCK_SUBABORT_RESTART:
3046 case TBLOCK_PREPARE:
3047 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3048 BlockStateAsString(s->blockState));
3055 * This executes a SAVEPOINT command.
3058 DefineSavepoint(char *name)
3060 TransactionState s = CurrentTransactionState;
3062 switch (s->blockState)
3064 case TBLOCK_INPROGRESS:
3065 case TBLOCK_SUBINPROGRESS:
3066 /* Normal subtransaction start */
3068 s = CurrentTransactionState; /* changed by push */
3071 * Savepoint names, like the TransactionState block itself, live
3072 * in TopTransactionContext.
3075 s->name = MemoryContextStrdup(TopTransactionContext, name);
3078 /* These cases are invalid. */
3079 case TBLOCK_DEFAULT:
3080 case TBLOCK_STARTED:
3082 case TBLOCK_SUBBEGIN:
3086 case TBLOCK_SUBABORT:
3087 case TBLOCK_ABORT_END:
3088 case TBLOCK_SUBABORT_END:
3089 case TBLOCK_ABORT_PENDING:
3090 case TBLOCK_SUBABORT_PENDING:
3091 case TBLOCK_SUBRESTART:
3092 case TBLOCK_SUBABORT_RESTART:
3093 case TBLOCK_PREPARE:
3094 elog(FATAL, "DefineSavepoint: unexpected state %s",
3095 BlockStateAsString(s->blockState));
3102 * This executes a RELEASE command.
3104 * As above, we don't actually do anything here except change blockState.
3107 ReleaseSavepoint(List *options)
3109 TransactionState s = CurrentTransactionState;
3110 TransactionState target,
3115 switch (s->blockState)
3118 * We can't rollback to a savepoint if there is no savepoint
3121 case TBLOCK_INPROGRESS:
3123 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3124 errmsg("no such savepoint")));
3128 * We are in a non-aborted subtransaction. This is the only valid
3131 case TBLOCK_SUBINPROGRESS:
3134 /* These cases are invalid. */
3135 case TBLOCK_DEFAULT:
3136 case TBLOCK_STARTED:
3138 case TBLOCK_SUBBEGIN:
3142 case TBLOCK_SUBABORT:
3143 case TBLOCK_ABORT_END:
3144 case TBLOCK_SUBABORT_END:
3145 case TBLOCK_ABORT_PENDING:
3146 case TBLOCK_SUBABORT_PENDING:
3147 case TBLOCK_SUBRESTART:
3148 case TBLOCK_SUBABORT_RESTART:
3149 case TBLOCK_PREPARE:
3150 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3151 BlockStateAsString(s->blockState));
3155 foreach(cell, options)
3157 DefElem *elem = lfirst(cell);
3159 if (strcmp(elem->defname, "savepoint_name") == 0)
3160 name = strVal(elem->arg);
3163 Assert(PointerIsValid(name));
3165 for (target = s; PointerIsValid(target); target = target->parent)
3167 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3171 if (!PointerIsValid(target))
3173 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3174 errmsg("no such savepoint")));
3176 /* disallow crossing savepoint level boundaries */
3177 if (target->savepointLevel != s->savepointLevel)
3179 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3180 errmsg("no such savepoint")));
3183 * Mark "commit pending" all subtransactions up to the target
3184 * subtransaction. The actual commits will happen when control gets to
3185 * CommitTransactionCommand.
3187 xact = CurrentTransactionState;
3190 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3191 xact->blockState = TBLOCK_SUBEND;
3194 xact = xact->parent;
3195 Assert(PointerIsValid(xact));
3200 * RollbackToSavepoint
3201 * This executes a ROLLBACK TO <savepoint> command.
3203 * As above, we don't actually do anything here except change blockState.
3206 RollbackToSavepoint(List *options)
3208 TransactionState s = CurrentTransactionState;
3209 TransactionState target,
3214 switch (s->blockState)
3217 * We can't rollback to a savepoint if there is no savepoint
3220 case TBLOCK_INPROGRESS:
3223 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3224 errmsg("no such savepoint")));
3228 * There is at least one savepoint, so proceed.
3230 case TBLOCK_SUBINPROGRESS:
3231 case TBLOCK_SUBABORT:
3234 /* These cases are invalid. */
3235 case TBLOCK_DEFAULT:
3236 case TBLOCK_STARTED:
3238 case TBLOCK_SUBBEGIN:
3241 case TBLOCK_ABORT_END:
3242 case TBLOCK_SUBABORT_END:
3243 case TBLOCK_ABORT_PENDING:
3244 case TBLOCK_SUBABORT_PENDING:
3245 case TBLOCK_SUBRESTART:
3246 case TBLOCK_SUBABORT_RESTART:
3247 case TBLOCK_PREPARE:
3248 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3249 BlockStateAsString(s->blockState));
3253 foreach(cell, options)
3255 DefElem *elem = lfirst(cell);
3257 if (strcmp(elem->defname, "savepoint_name") == 0)
3258 name = strVal(elem->arg);
3261 Assert(PointerIsValid(name));
3263 for (target = s; PointerIsValid(target); target = target->parent)
3265 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3269 if (!PointerIsValid(target))
3271 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3272 errmsg("no such savepoint")));
3274 /* disallow crossing savepoint level boundaries */
3275 if (target->savepointLevel != s->savepointLevel)
3277 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3278 errmsg("no such savepoint")));
3281 * Mark "abort pending" all subtransactions up to the target
3282 * subtransaction. The actual aborts will happen when control gets to
3283 * CommitTransactionCommand.
3285 xact = CurrentTransactionState;
3290 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3291 xact->blockState = TBLOCK_SUBABORT_PENDING;
3292 else if (xact->blockState == TBLOCK_SUBABORT)
3293 xact->blockState = TBLOCK_SUBABORT_END;
3295 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3296 BlockStateAsString(xact->blockState));
3297 xact = xact->parent;
3298 Assert(PointerIsValid(xact));
3301 /* And mark the target as "restart pending" */
3302 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3303 xact->blockState = TBLOCK_SUBRESTART;
3304 else if (xact->blockState == TBLOCK_SUBABORT)
3305 xact->blockState = TBLOCK_SUBABORT_RESTART;
3307 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3308 BlockStateAsString(xact->blockState));
3312 * BeginInternalSubTransaction
3313 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
3314 * TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
3315 * used in functions that might be called when not inside a BEGIN block
3316 * or when running deferred triggers at COMMIT/PREPARE time. Also, it
3317 * automatically does CommitTransactionCommand/StartTransactionCommand
3318 * instead of expecting the caller to do it.
3321 BeginInternalSubTransaction(char *name)
3323 TransactionState s = CurrentTransactionState;
3325 switch (s->blockState)
3327 case TBLOCK_STARTED:
3328 case TBLOCK_INPROGRESS:
3330 case TBLOCK_PREPARE:
3331 case TBLOCK_SUBINPROGRESS:
3332 /* Normal subtransaction start */
3334 s = CurrentTransactionState; /* changed by push */
3337 * Savepoint names, like the TransactionState block itself, live
3338 * in TopTransactionContext.
3341 s->name = MemoryContextStrdup(TopTransactionContext, name);
3344 /* These cases are invalid. */
3345 case TBLOCK_DEFAULT:
3347 case TBLOCK_SUBBEGIN:
3350 case TBLOCK_SUBABORT:
3351 case TBLOCK_ABORT_END:
3352 case TBLOCK_SUBABORT_END:
3353 case TBLOCK_ABORT_PENDING:
3354 case TBLOCK_SUBABORT_PENDING:
3355 case TBLOCK_SUBRESTART:
3356 case TBLOCK_SUBABORT_RESTART:
3357 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
3358 BlockStateAsString(s->blockState));
3362 CommitTransactionCommand();
3363 StartTransactionCommand();
3367 * ReleaseCurrentSubTransaction
3369 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
3370 * savepoint name (if any).
3371 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3374 ReleaseCurrentSubTransaction(void)
3376 TransactionState s = CurrentTransactionState;
3378 if (s->blockState != TBLOCK_SUBINPROGRESS)
3379 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
3380 BlockStateAsString(s->blockState));
3381 Assert(s->state == TRANS_INPROGRESS);
3382 MemoryContextSwitchTo(CurTransactionContext);
3383 CommitSubTransaction();
3384 s = CurrentTransactionState; /* changed by pop */
3385 Assert(s->state == TRANS_INPROGRESS);
3389 * RollbackAndReleaseCurrentSubTransaction
3391 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
3392 * of its savepoint name (if any).
3393 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3396 RollbackAndReleaseCurrentSubTransaction(void)
3398 TransactionState s = CurrentTransactionState;
3400 switch (s->blockState)
3402 /* Must be in a subtransaction */
3403 case TBLOCK_SUBINPROGRESS:
3404 case TBLOCK_SUBABORT:
3407 /* These cases are invalid. */
3408 case TBLOCK_DEFAULT:
3409 case TBLOCK_STARTED:
3411 case TBLOCK_SUBBEGIN:
3412 case TBLOCK_INPROGRESS:
3416 case TBLOCK_ABORT_END:
3417 case TBLOCK_SUBABORT_END:
3418 case TBLOCK_ABORT_PENDING:
3419 case TBLOCK_SUBABORT_PENDING:
3420 case TBLOCK_SUBRESTART:
3421 case TBLOCK_SUBABORT_RESTART:
3422 case TBLOCK_PREPARE:
3423 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
3424 BlockStateAsString(s->blockState));
3429 * Abort the current subtransaction, if needed.
3431 if (s->blockState == TBLOCK_SUBINPROGRESS)
3432 AbortSubTransaction();
3434 /* And clean it up, too */
3435 CleanupSubTransaction();
3437 s = CurrentTransactionState; /* changed by pop */
3438 AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
3439 s->blockState == TBLOCK_INPROGRESS ||
3440 s->blockState == TBLOCK_STARTED);
3444 * AbortOutOfAnyTransaction
3446 * This routine is provided for error recovery purposes. It aborts any
3447 * active transaction or transaction block, leaving the system in a known
3451 AbortOutOfAnyTransaction(void)
3453 TransactionState s = CurrentTransactionState;
3456 * Get out of any transaction or nested transaction
3460 switch (s->blockState)
3462 case TBLOCK_DEFAULT:
3463 /* Not in a transaction, do nothing */
3465 case TBLOCK_STARTED:
3467 case TBLOCK_INPROGRESS:
3469 case TBLOCK_ABORT_PENDING:
3470 case TBLOCK_PREPARE:
3471 /* In a transaction, so clean up */
3473 CleanupTransaction();
3474 s->blockState = TBLOCK_DEFAULT;
3477 case TBLOCK_ABORT_END:
3478 /* AbortTransaction already done, still need Cleanup */
3479 CleanupTransaction();
3480 s->blockState = TBLOCK_DEFAULT;
3484 * In a subtransaction, so clean it up and abort parent too
3486 case TBLOCK_SUBBEGIN:
3487 case TBLOCK_SUBINPROGRESS:
3489 case TBLOCK_SUBABORT_PENDING:
3490 case TBLOCK_SUBRESTART:
3491 AbortSubTransaction();
3492 CleanupSubTransaction();
3493 s = CurrentTransactionState; /* changed by pop */
3496 case TBLOCK_SUBABORT:
3497 case TBLOCK_SUBABORT_END:
3498 case TBLOCK_SUBABORT_RESTART:
3499 /* As above, but AbortSubTransaction already done */
3500 CleanupSubTransaction();
3501 s = CurrentTransactionState; /* changed by pop */
3504 } while (s->blockState != TBLOCK_DEFAULT);
3506 /* Should be out of all subxacts now */
3507 Assert(s->parent == NULL);
3511 * IsTransactionBlock --- are we within a transaction block?
3514 IsTransactionBlock(void)
3516 TransactionState s = CurrentTransactionState;
3518 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
3525 * IsTransactionOrTransactionBlock --- are we within either a transaction
3526 * or a transaction block? (The backend is only really "idle" when this
3529 * This should match up with IsTransactionBlock and IsTransactionState.
3532 IsTransactionOrTransactionBlock(void)
3534 TransactionState s = CurrentTransactionState;
3536 if (s->blockState == TBLOCK_DEFAULT)
3543 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
3546 TransactionBlockStatusCode(void)
3548 TransactionState s = CurrentTransactionState;
3550 switch (s->blockState)
3552 case TBLOCK_DEFAULT:
3553 case TBLOCK_STARTED:
3554 return 'I'; /* idle --- not in transaction */
3556 case TBLOCK_SUBBEGIN:
3557 case TBLOCK_INPROGRESS:
3558 case TBLOCK_SUBINPROGRESS:
3561 case TBLOCK_PREPARE:
3562 return 'T'; /* in transaction */
3564 case TBLOCK_SUBABORT:
3565 case TBLOCK_ABORT_END:
3566 case TBLOCK_SUBABORT_END:
3567 case TBLOCK_ABORT_PENDING:
3568 case TBLOCK_SUBABORT_PENDING:
3569 case TBLOCK_SUBRESTART:
3570 case TBLOCK_SUBABORT_RESTART:
3571 return 'E'; /* in failed transaction */
3574 /* should never get here */
3575 elog(FATAL, "invalid transaction block state: %s",
3576 BlockStateAsString(s->blockState));
3577 return 0; /* keep compiler quiet */
3584 IsSubTransaction(void)
3586 TransactionState s = CurrentTransactionState;
3588 if (s->nestingLevel >= 2)
3595 * StartSubTransaction
3597 * If you're wondering why this is separate from PushTransaction: it's because
3598 * we can't conveniently do this stuff right inside DefineSavepoint. The
3599 * SAVEPOINT utility command will be executed inside a Portal, and if we
3600 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
3601 * the Portal will undo those settings. So we make DefineSavepoint just
3602 * push a dummy transaction block, and when control returns to the main
3603 * idle loop, CommitTransactionCommand will be called, and we'll come here
3604 * to finish starting the subtransaction.
3607 StartSubTransaction(void)
3609 TransactionState s = CurrentTransactionState;
3611 if (s->state != TRANS_DEFAULT)
3612 elog(WARNING, "StartSubTransaction while in %s state",
3613 TransStateAsString(s->state));
3615 s->state = TRANS_START;
3618 * Initialize subsystems for new subtransaction
3620 * must initialize resource-management stuff first
3622 AtSubStart_Memory();
3623 AtSubStart_ResourceOwner();
3625 AtSubStart_Notify();
3626 AfterTriggerBeginSubXact();
3628 s->state = TRANS_INPROGRESS;
3631 * Call start-of-subxact callbacks
3633 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
3634 s->parent->subTransactionId);
3636 ShowTransactionState("StartSubTransaction");
3640 * CommitSubTransaction
3642 * The caller has to make sure to always reassign CurrentTransactionState
3643 * if it has a local pointer to it after calling this function.
3646 CommitSubTransaction(void)
3648 TransactionState s = CurrentTransactionState;
3650 ShowTransactionState("CommitSubTransaction");
3652 if (s->state != TRANS_INPROGRESS)
3653 elog(WARNING, "CommitSubTransaction while in %s state",
3654 TransStateAsString(s->state));
3656 /* Pre-commit processing goes here -- nothing to do at the moment */
3658 s->state = TRANS_COMMIT;
3660 /* Must CCI to ensure commands of subtransaction are seen as done */
3661 CommandCounterIncrement();
3663 /* Mark subtransaction as subcommitted */
3664 RecordSubTransactionCommit();
3666 /* Post-commit cleanup */
3667 if (TransactionIdIsValid(s->transactionId))
3668 AtSubCommit_childXids();
3669 AfterTriggerEndSubXact(true);
3670 AtSubCommit_Portals(s->subTransactionId,
3671 s->parent->subTransactionId,
3672 s->parent->curTransactionOwner);
3673 AtEOSubXact_LargeObject(true, s->subTransactionId,
3674 s->parent->subTransactionId);
3675 AtSubCommit_Notify();
3676 AtEOSubXact_UpdateFlatFiles(true, s->subTransactionId,
3677 s->parent->subTransactionId);
3679 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
3680 s->parent->subTransactionId);
3682 ResourceOwnerRelease(s->curTransactionOwner,
3683 RESOURCE_RELEASE_BEFORE_LOCKS,
3685 AtEOSubXact_RelationCache(true, s->subTransactionId,
3686 s->parent->subTransactionId);
3687 AtEOSubXact_Inval(true);
3691 * The only lock we actually release here is the subtransaction XID lock.
3692 * The rest just get transferred to the parent resource owner.
3694 CurrentResourceOwner = s->curTransactionOwner;
3695 if (TransactionIdIsValid(s->transactionId))
3696 XactLockTableDelete(s->transactionId);
3698 ResourceOwnerRelease(s->curTransactionOwner,
3699 RESOURCE_RELEASE_LOCKS,
3701 ResourceOwnerRelease(s->curTransactionOwner,
3702 RESOURCE_RELEASE_AFTER_LOCKS,
3705 AtEOXact_GUC(true, s->gucNestLevel);
3706 AtEOSubXact_SPI(true, s->subTransactionId);
3707 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
3708 s->parent->subTransactionId);
3709 AtEOSubXact_Namespace(true, s->subTransactionId,
3710 s->parent->subTransactionId);
3711 AtEOSubXact_Files(true, s->subTransactionId,
3712 s->parent->subTransactionId);
3713 AtEOSubXact_HashTables(true, s->nestingLevel);
3714 AtEOSubXact_PgStat(true, s->nestingLevel);
3717 * We need to restore the upper transaction's read-only state, in case the
3718 * upper is read-write while the child is read-only; GUC will incorrectly
3719 * think it should leave the child state in place.
3721 XactReadOnly = s->prevXactReadOnly;
3723 CurrentResourceOwner = s->parent->curTransactionOwner;
3724 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3725 ResourceOwnerDelete(s->curTransactionOwner);
3726 s->curTransactionOwner = NULL;
3728 AtSubCommit_Memory();
3730 s->state = TRANS_DEFAULT;
3736 * AbortSubTransaction
3739 AbortSubTransaction(void)
3741 TransactionState s = CurrentTransactionState;
3743 /* Prevent cancel/die interrupt while cleaning up */
3746 /* Make sure we have a valid memory context and resource owner */
3747 AtSubAbort_Memory();
3748 AtSubAbort_ResourceOwner();
3751 * Release any LW locks we might be holding as quickly as possible.
3752 * (Regular locks, however, must be held till we finish aborting.)
3753 * Releasing LW locks is critical since we might try to grab them again
3754 * while cleaning up!
3756 * FIXME This may be incorrect --- Are there some locks we should keep?
3757 * Buffer locks, for example? I don't think so but I'm not sure.
3767 * check the current transaction state
3769 ShowTransactionState("AbortSubTransaction");
3771 if (s->state != TRANS_INPROGRESS)
3772 elog(WARNING, "AbortSubTransaction while in %s state",
3773 TransStateAsString(s->state));
3775 s->state = TRANS_ABORT;
3778 * We can skip all this stuff if the subxact failed before creating a
3781 if (s->curTransactionOwner)
3783 AfterTriggerEndSubXact(false);
3784 AtSubAbort_Portals(s->subTransactionId,
3785 s->parent->subTransactionId,
3786 s->parent->curTransactionOwner);
3787 AtEOSubXact_LargeObject(false, s->subTransactionId,
3788 s->parent->subTransactionId);
3789 AtSubAbort_Notify();
3790 AtEOSubXact_UpdateFlatFiles(false, s->subTransactionId,
3791 s->parent->subTransactionId);
3793 /* Advertise the fact that we aborted in pg_clog. */
3794 (void) RecordTransactionAbort(true);
3796 /* Post-abort cleanup */
3797 if (TransactionIdIsValid(s->transactionId))
3798 AtSubAbort_childXids();
3800 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
3801 s->parent->subTransactionId);
3803 ResourceOwnerRelease(s->curTransactionOwner,
3804 RESOURCE_RELEASE_BEFORE_LOCKS,
3806 AtEOSubXact_RelationCache(false, s->subTransactionId,
3807 s->parent->subTransactionId);
3808 AtEOSubXact_Inval(false);
3810 ResourceOwnerRelease(s->curTransactionOwner,
3811 RESOURCE_RELEASE_LOCKS,
3813 ResourceOwnerRelease(s->curTransactionOwner,
3814 RESOURCE_RELEASE_AFTER_LOCKS,
3817 AtEOXact_GUC(false, s->gucNestLevel);
3818 AtEOSubXact_SPI(false, s->subTransactionId);
3819 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
3820 s->parent->subTransactionId);
3821 AtEOSubXact_Namespace(false, s->subTransactionId,
3822 s->parent->subTransactionId);
3823 AtEOSubXact_Files(false, s->subTransactionId,
3824 s->parent->subTransactionId);
3825 AtEOSubXact_HashTables(false, s->nestingLevel);
3826 AtEOSubXact_PgStat(false, s->nestingLevel);
3830 * Reset user id which might have been changed transiently. Here we want
3831 * to restore to the userid that was current at subxact entry. (As in
3832 * AbortTransaction, we need not worry about the session userid.)
3834 * Must do this after AtEOXact_GUC to handle the case where we entered the
3835 * subxact inside a SECURITY DEFINER function (hence current and session
3836 * userids were different) and then session auth was changed inside the
3837 * subxact. GUC will reset both current and session userids to the
3838 * entry-time session userid. This is right in every other scenario so it
3839 * seems simplest to let GUC do that and fix it here.
3841 SetUserId(s->currentUser);
3844 * Restore the upper transaction's read-only state, too. This should be
3845 * redundant with GUC's cleanup but we may as well do it for consistency
3846 * with the commit case.
3848 XactReadOnly = s->prevXactReadOnly;
3850 RESUME_INTERRUPTS();
3854 * CleanupSubTransaction
3856 * The caller has to make sure to always reassign CurrentTransactionState
3857 * if it has a local pointer to it after calling this function.
3860 CleanupSubTransaction(void)
3862 TransactionState s = CurrentTransactionState;
3864 ShowTransactionState("CleanupSubTransaction");
3866 if (s->state != TRANS_ABORT)
3867 elog(WARNING, "CleanupSubTransaction while in %s state",
3868 TransStateAsString(s->state));
3870 AtSubCleanup_Portals(s->subTransactionId);
3872 CurrentResourceOwner = s->parent->curTransactionOwner;
3873 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3874 if (s->curTransactionOwner)
3875 ResourceOwnerDelete(s->curTransactionOwner);
3876 s->curTransactionOwner = NULL;
3878 AtSubCleanup_Memory();
3880 s->state = TRANS_DEFAULT;
3887 * Create transaction state stack entry for a subtransaction
3889 * The caller has to make sure to always reassign CurrentTransactionState
3890 * if it has a local pointer to it after calling this function.
3893 PushTransaction(void)
3895 TransactionState p = CurrentTransactionState;
3900 * At present, GetUserId cannot fail, but let's not assume that. Get the
3901 * ID before entering the critical code sequence.
3903 currentUser = GetUserId();
3906 * We keep subtransaction state nodes in TopTransactionContext.
3908 s = (TransactionState)
3909 MemoryContextAllocZero(TopTransactionContext,
3910 sizeof(TransactionStateData));
3913 * Assign a subtransaction ID, watching out for counter wraparound.
3915 currentSubTransactionId += 1;
3916 if (currentSubTransactionId == InvalidSubTransactionId)
3918 currentSubTransactionId -= 1;
3921 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3922 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
3926 * We can now stack a minimally valid subtransaction without fear of
3929 s->transactionId = InvalidTransactionId; /* until assigned */
3930 s->subTransactionId = currentSubTransactionId;
3932 s->nestingLevel = p->nestingLevel + 1;
3933 s->gucNestLevel = NewGUCNestLevel();
3934 s->savepointLevel = p->savepointLevel;
3935 s->state = TRANS_DEFAULT;
3936 s->blockState = TBLOCK_SUBBEGIN;
3937 s->currentUser = currentUser;
3938 s->prevXactReadOnly = XactReadOnly;
3940 CurrentTransactionState = s;
3943 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
3944 * with the subtransaction from here on out; in particular they should not
3945 * assume that it necessarily has a transaction context, resource owner,
3952 * Pop back to parent transaction state
3954 * The caller has to make sure to always reassign CurrentTransactionState
3955 * if it has a local pointer to it after calling this function.
3958 PopTransaction(void)
3960 TransactionState s = CurrentTransactionState;
3962 if (s->state != TRANS_DEFAULT)
3963 elog(WARNING, "PopTransaction while in %s state",
3964 TransStateAsString(s->state));
3966 if (s->parent == NULL)
3967 elog(FATAL, "PopTransaction with no parent");
3969 CurrentTransactionState = s->parent;
3971 /* Let's just make sure CurTransactionContext is good */
3972 CurTransactionContext = s->parent->curTransactionContext;
3973 MemoryContextSwitchTo(CurTransactionContext);
3975 /* Ditto for ResourceOwner links */
3976 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3977 CurrentResourceOwner = s->parent->curTransactionOwner;
3979 /* Free the old child structure */
3986 * ShowTransactionState
3990 ShowTransactionState(const char *str)
3992 /* skip work if message will definitely not be printed */
3993 if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
3995 elog(DEBUG3, "%s", str);
3996 ShowTransactionStateRec(CurrentTransactionState);
4001 * ShowTransactionStateRec
4002 * Recursive subroutine for ShowTransactionState
4005 ShowTransactionStateRec(TransactionState s)
4008 ShowTransactionStateRec(s->parent);
4010 /* use ereport to suppress computation if msg will not be printed */
4012 (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u, nestlvl: %d, children: %s",
4013 PointerIsValid(s->name) ? s->name : "unnamed",
4014 BlockStateAsString(s->blockState),
4015 TransStateAsString(s->state),
4016 (unsigned int) s->transactionId,
4017 (unsigned int) s->subTransactionId,
4018 (unsigned int) currentCommandId,
4020 nodeToString(s->childXids))));
4024 * BlockStateAsString
4028 BlockStateAsString(TBlockState blockState)
4032 case TBLOCK_DEFAULT:
4034 case TBLOCK_STARTED:
4038 case TBLOCK_INPROGRESS:
4039 return "INPROGRESS";
4044 case TBLOCK_ABORT_END:
4046 case TBLOCK_ABORT_PENDING:
4047 return "ABORT PEND";
4048 case TBLOCK_PREPARE:
4050 case TBLOCK_SUBBEGIN:
4052 case TBLOCK_SUBINPROGRESS:
4053 return "SUB INPROGRS";
4056 case TBLOCK_SUBABORT:
4058 case TBLOCK_SUBABORT_END:
4059 return "SUB ABORT END";
4060 case TBLOCK_SUBABORT_PENDING:
4061 return "SUB ABRT PEND";
4062 case TBLOCK_SUBRESTART:
4063 return "SUB RESTART";
4064 case TBLOCK_SUBABORT_RESTART:
4065 return "SUB AB RESTRT";
4067 return "UNRECOGNIZED";
4071 * TransStateAsString
4075 TransStateAsString(TransState state)
4083 case TRANS_INPROGRESS:
4092 return "UNRECOGNIZED";
4096 * xactGetCommittedChildren
4098 * Gets the list of committed children of the current transaction. The return
4099 * value is the number of child transactions. *children is set to point to a
4100 * palloc'd array of TransactionIds. If there are no subxacts, *children is
4104 xactGetCommittedChildren(TransactionId **ptr)
4106 TransactionState s = CurrentTransactionState;
4108 TransactionId *children;
4111 nchildren = list_length(s->childXids);
4118 children = (TransactionId *) palloc(nchildren * sizeof(TransactionId));
4121 foreach(p, s->childXids)
4123 TransactionId child = lfirst_xid(p);
4125 *children++ = child;
4132 * XLOG support routines
4136 xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid)
4138 TransactionId *sub_xids;
4139 TransactionId max_xid;
4142 TransactionIdCommit(xid);
4144 /* Mark committed subtransactions as committed */
4145 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4146 TransactionIdCommitTree(xlrec->nsubxacts, sub_xids);
4148 /* Make sure nextXid is beyond any XID mentioned in the record */
4150 for (i = 0; i < xlrec->nsubxacts; i++)
4152 if (TransactionIdPrecedes(max_xid, sub_xids[i]))
4153 max_xid = sub_xids[i];
4155 if (TransactionIdFollowsOrEquals(max_xid,
4156 ShmemVariableCache->nextXid))
4158 ShmemVariableCache->nextXid = max_xid;
4159 TransactionIdAdvance(ShmemVariableCache->nextXid);
4162 /* Make sure files supposed to be dropped are dropped */
4163 for (i = 0; i < xlrec->nrels; i++)
4165 XLogDropRelation(xlrec->xnodes[i]);
4166 smgrdounlink(smgropen(xlrec->xnodes[i]), false, true);
4171 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
4173 TransactionId *sub_xids;
4174 TransactionId max_xid;
4177 TransactionIdAbort(xid);
4179 /* Mark subtransactions as aborted */
4180 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4181 TransactionIdAbortTree(xlrec->nsubxacts, sub_xids);
4183 /* Make sure nextXid is beyond any XID mentioned in the record */
4185 for (i = 0; i < xlrec->nsubxacts; i++)
4187 if (TransactionIdPrecedes(max_xid, sub_xids[i]))
4188 max_xid = sub_xids[i];
4190 if (TransactionIdFollowsOrEquals(max_xid,
4191 ShmemVariableCache->nextXid))
4193 ShmemVariableCache->nextXid = max_xid;
4194 TransactionIdAdvance(ShmemVariableCache->nextXid);
4197 /* Make sure files supposed to be dropped are dropped */
4198 for (i = 0; i < xlrec->nrels; i++)
4200 XLogDropRelation(xlrec->xnodes[i]);
4201 smgrdounlink(smgropen(xlrec->xnodes[i]), false, true);
4206 xact_redo(XLogRecPtr lsn, XLogRecord *record)
4208 uint8 info = record->xl_info & ~XLR_INFO_MASK;
4210 if (info == XLOG_XACT_COMMIT)
4212 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
4214 xact_redo_commit(xlrec, record->xl_xid);
4216 else if (info == XLOG_XACT_ABORT)
4218 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
4220 xact_redo_abort(xlrec, record->xl_xid);
4222 else if (info == XLOG_XACT_PREPARE)
4224 /* the record contents are exactly the 2PC file */
4225 RecreateTwoPhaseFile(record->xl_xid,
4226 XLogRecGetData(record), record->xl_len);
4228 else if (info == XLOG_XACT_COMMIT_PREPARED)
4230 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
4232 xact_redo_commit(&xlrec->crec, xlrec->xid);
4233 RemoveTwoPhaseFile(xlrec->xid, false);
4235 else if (info == XLOG_XACT_ABORT_PREPARED)
4237 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
4239 xact_redo_abort(&xlrec->arec, xlrec->xid);
4240 RemoveTwoPhaseFile(xlrec->xid, false);
4243 elog(PANIC, "xact_redo: unknown op code %u", info);
4247 xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
4251 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4252 if (xlrec->nrels > 0)
4254 appendStringInfo(buf, "; rels:");
4255 for (i = 0; i < xlrec->nrels; i++)
4257 RelFileNode rnode = xlrec->xnodes[i];
4259 appendStringInfo(buf, " %u/%u/%u",
4260 rnode.spcNode, rnode.dbNode, rnode.relNode);
4263 if (xlrec->nsubxacts > 0)
4265 TransactionId *xacts = (TransactionId *)
4266 &xlrec->xnodes[xlrec->nrels];
4268 appendStringInfo(buf, "; subxacts:");
4269 for (i = 0; i < xlrec->nsubxacts; i++)
4270 appendStringInfo(buf, " %u", xacts[i]);
4275 xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
4279 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4280 if (xlrec->nrels > 0)
4282 appendStringInfo(buf, "; rels:");
4283 for (i = 0; i < xlrec->nrels; i++)
4285 RelFileNode rnode = xlrec->xnodes[i];
4287 appendStringInfo(buf, " %u/%u/%u",
4288 rnode.spcNode, rnode.dbNode, rnode.relNode);
4291 if (xlrec->nsubxacts > 0)
4293 TransactionId *xacts = (TransactionId *)
4294 &xlrec->xnodes[xlrec->nrels];
4296 appendStringInfo(buf, "; subxacts:");
4297 for (i = 0; i < xlrec->nsubxacts; i++)
4298 appendStringInfo(buf, " %u", xacts[i]);
4303 xact_desc(StringInfo buf, uint8 xl_info, char *rec)
4305 uint8 info = xl_info & ~XLR_INFO_MASK;
4307 if (info == XLOG_XACT_COMMIT)
4309 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
4311 appendStringInfo(buf, "commit: ");
4312 xact_desc_commit(buf, xlrec);
4314 else if (info == XLOG_XACT_ABORT)
4316 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
4318 appendStringInfo(buf, "abort: ");
4319 xact_desc_abort(buf, xlrec);
4321 else if (info == XLOG_XACT_PREPARE)
4323 appendStringInfo(buf, "prepare");
4325 else if (info == XLOG_XACT_COMMIT_PREPARED)
4327 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
4329 appendStringInfo(buf, "commit %u: ", xlrec->xid);
4330 xact_desc_commit(buf, &xlrec->crec);
4332 else if (info == XLOG_XACT_ABORT_PREPARED)
4334 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
4336 appendStringInfo(buf, "abort %u: ", xlrec->xid);
4337 xact_desc_abort(buf, &xlrec->arec);
4340 appendStringInfo(buf, "UNKNOWN");