1 /*-------------------------------------------------------------------------
4 * top level transaction system support routines
6 * See src/backend/access/transam/README for more information.
8 * Portions Copyright (c) 1996-2008, 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.259 2008/03/17 02:18:55 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"
48 #include "utils/xml.h"
52 * User-tweakable parameters
54 int DefaultXactIsoLevel = XACT_READ_COMMITTED;
57 bool DefaultXactReadOnly = false;
60 bool XactSyncCommit = true;
62 int CommitDelay = 0; /* precommit delay in microseconds */
63 int CommitSiblings = 5; /* # concurrent xacts needed to sleep */
66 * MyXactAccessedTempRel is set when a temporary relation is accessed.
67 * We don't allow PREPARE TRANSACTION in that case. (This is global
68 * so that it can be set from heapam.c.)
70 bool MyXactAccessedTempRel = false;
74 * transaction states - transaction state from server perspective
76 typedef enum TransState
78 TRANS_DEFAULT, /* idle */
79 TRANS_START, /* transaction starting */
80 TRANS_INPROGRESS, /* inside a valid transaction */
81 TRANS_COMMIT, /* commit in progress */
82 TRANS_ABORT, /* abort in progress */
83 TRANS_PREPARE /* prepare in progress */
87 * transaction block states - transaction state of client queries
89 * Note: the subtransaction states are used only for non-topmost
90 * transactions; the others appear only in the topmost transaction.
92 typedef enum TBlockState
94 /* not-in-transaction-block states */
95 TBLOCK_DEFAULT, /* idle */
96 TBLOCK_STARTED, /* running single-query transaction */
98 /* transaction block states */
99 TBLOCK_BEGIN, /* starting transaction block */
100 TBLOCK_INPROGRESS, /* live transaction */
101 TBLOCK_END, /* COMMIT received */
102 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
103 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
104 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
105 TBLOCK_PREPARE, /* live xact, PREPARE received */
107 /* subtransaction states */
108 TBLOCK_SUBBEGIN, /* starting a subtransaction */
109 TBLOCK_SUBINPROGRESS, /* live subtransaction */
110 TBLOCK_SUBEND, /* RELEASE received */
111 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
112 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
113 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
114 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
115 TBLOCK_SUBABORT_RESTART /* failed subxact, ROLLBACK TO received */
119 * transaction state structure
121 typedef struct TransactionStateData
123 TransactionId transactionId; /* my XID, or Invalid if none */
124 SubTransactionId subTransactionId; /* my subxact ID */
125 char *name; /* savepoint name, if any */
126 int savepointLevel; /* savepoint level */
127 TransState state; /* low-level state */
128 TBlockState blockState; /* high-level state */
129 int nestingLevel; /* transaction nesting depth */
130 int gucNestLevel; /* GUC context nesting depth */
131 MemoryContext curTransactionContext; /* my xact-lifetime context */
132 ResourceOwner curTransactionOwner; /* my query resources */
133 TransactionId *childXids; /* subcommitted child XIDs, in XID order */
134 int nChildXids; /* # of subcommitted child XIDs */
135 int maxChildXids; /* allocated size of childXids[] */
136 Oid prevUser; /* previous CurrentUserId setting */
137 bool prevSecDefCxt; /* previous SecurityDefinerContext setting */
138 bool prevXactReadOnly; /* entry-time xact r/o state */
139 struct TransactionStateData *parent; /* back link to parent */
140 } TransactionStateData;
142 typedef TransactionStateData *TransactionState;
145 * CurrentTransactionState always points to the current transaction state
146 * block. It will point to TopTransactionStateData when not in a
147 * transaction at all, or when in a top-level transaction.
149 static TransactionStateData TopTransactionStateData = {
150 0, /* transaction id */
151 0, /* subtransaction id */
152 NULL, /* savepoint name */
153 0, /* savepoint level */
154 TRANS_DEFAULT, /* transaction state */
155 TBLOCK_DEFAULT, /* transaction block state from the client
157 0, /* transaction nesting depth */
158 0, /* GUC context nesting depth */
159 NULL, /* cur transaction context */
160 NULL, /* cur transaction resource owner */
161 NULL, /* subcommitted child Xids */
162 0, /* # of subcommitted child Xids */
163 0, /* allocated size of childXids[] */
164 InvalidOid, /* previous CurrentUserId setting */
165 false, /* previous SecurityDefinerContext setting */
166 false, /* entry-time xact r/o state */
167 NULL /* link to parent state block */
170 static TransactionState CurrentTransactionState = &TopTransactionStateData;
173 * The subtransaction ID and command ID assignment counters are global
174 * to a whole transaction, so we do not keep them in the state stack.
176 static SubTransactionId currentSubTransactionId;
177 static CommandId currentCommandId;
178 static bool currentCommandIdUsed;
181 * xactStartTimestamp is the value of transaction_timestamp().
182 * stmtStartTimestamp is the value of statement_timestamp().
183 * xactStopTimestamp is the time at which we log a commit or abort WAL record.
184 * These do not change as we enter and exit subtransactions, so we don't
185 * keep them inside the TransactionState stack.
187 static TimestampTz xactStartTimestamp;
188 static TimestampTz stmtStartTimestamp;
189 static TimestampTz xactStopTimestamp;
192 * GID to be used for preparing the current transaction. This is also
193 * global to a whole transaction, so we don't keep it in the state stack.
195 static char *prepareGID;
198 * Some commands want to force synchronous commit.
200 static bool forceSyncCommit = false;
203 * Private context for transaction-abort work --- we reserve space for this
204 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
205 * when we've run out of memory.
207 static MemoryContext TransactionAbortContext = NULL;
210 * List of add-on start- and end-of-xact callbacks
212 typedef struct XactCallbackItem
214 struct XactCallbackItem *next;
215 XactCallback callback;
219 static XactCallbackItem *Xact_callbacks = NULL;
222 * List of add-on start- and end-of-subxact callbacks
224 typedef struct SubXactCallbackItem
226 struct SubXactCallbackItem *next;
227 SubXactCallback callback;
229 } SubXactCallbackItem;
231 static SubXactCallbackItem *SubXact_callbacks = NULL;
234 /* local function prototypes */
235 static void AssignTransactionId(TransactionState s);
236 static void AbortTransaction(void);
237 static void AtAbort_Memory(void);
238 static void AtCleanup_Memory(void);
239 static void AtAbort_ResourceOwner(void);
240 static void AtCommit_LocalCache(void);
241 static void AtCommit_Memory(void);
242 static void AtStart_Cache(void);
243 static void AtStart_Memory(void);
244 static void AtStart_ResourceOwner(void);
245 static void CallXactCallbacks(XactEvent event);
246 static void CallSubXactCallbacks(SubXactEvent event,
247 SubTransactionId mySubid,
248 SubTransactionId parentSubid);
249 static void CleanupTransaction(void);
250 static void CommitTransaction(void);
251 static TransactionId RecordTransactionAbort(bool isSubXact);
252 static void StartTransaction(void);
254 static void RecordSubTransactionCommit(void);
255 static void StartSubTransaction(void);
256 static void CommitSubTransaction(void);
257 static void AbortSubTransaction(void);
258 static void CleanupSubTransaction(void);
259 static void PushTransaction(void);
260 static void PopTransaction(void);
262 static void AtSubAbort_Memory(void);
263 static void AtSubCleanup_Memory(void);
264 static void AtSubAbort_ResourceOwner(void);
265 static void AtSubCommit_Memory(void);
266 static void AtSubStart_Memory(void);
267 static void AtSubStart_ResourceOwner(void);
269 static void ShowTransactionState(const char *str);
270 static void ShowTransactionStateRec(TransactionState state);
271 static const char *BlockStateAsString(TBlockState blockState);
272 static const char *TransStateAsString(TransState state);
275 /* ----------------------------------------------------------------
276 * transaction state accessors
277 * ----------------------------------------------------------------
283 * This returns true if we are inside a valid transaction; that is,
284 * it is safe to initiate database access, take heavyweight locks, etc.
287 IsTransactionState(void)
289 TransactionState s = CurrentTransactionState;
292 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
293 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
294 * TRANS_PREPARE since it might be too soon or too late within those
295 * transition states to do anything interesting. Hence, the only "valid"
296 * state is TRANS_INPROGRESS.
298 return (s->state == TRANS_INPROGRESS);
302 * IsAbortedTransactionBlockState
304 * This returns true if we are currently running a query
305 * within an aborted transaction block.
308 IsAbortedTransactionBlockState(void)
310 TransactionState s = CurrentTransactionState;
312 if (s->blockState == TBLOCK_ABORT ||
313 s->blockState == TBLOCK_SUBABORT)
321 * GetTopTransactionId
323 * This will return the XID of the main transaction, assigning one if
324 * it's not yet set. Be careful to call this only inside a valid xact.
327 GetTopTransactionId(void)
329 if (!TransactionIdIsValid(TopTransactionStateData.transactionId))
330 AssignTransactionId(&TopTransactionStateData);
331 return TopTransactionStateData.transactionId;
335 * GetTopTransactionIdIfAny
337 * This will return the XID of the main transaction, if one is assigned.
338 * It will return InvalidTransactionId if we are not currently inside a
339 * transaction, or inside a transaction that hasn't yet been assigned an XID.
342 GetTopTransactionIdIfAny(void)
344 return TopTransactionStateData.transactionId;
348 * GetCurrentTransactionId
350 * This will return the XID of the current transaction (main or sub
351 * transaction), assigning one if it's not yet set. Be careful to call this
352 * only inside a valid xact.
355 GetCurrentTransactionId(void)
357 TransactionState s = CurrentTransactionState;
359 if (!TransactionIdIsValid(s->transactionId))
360 AssignTransactionId(s);
361 return s->transactionId;
365 * GetCurrentTransactionIdIfAny
367 * This will return the XID of the current sub xact, if one is assigned.
368 * It will return InvalidTransactionId if we are not currently inside a
369 * transaction, or inside a transaction that hasn't been assigned an XID yet.
372 GetCurrentTransactionIdIfAny(void)
374 return CurrentTransactionState->transactionId;
379 * AssignTransactionId
381 * Assigns a new permanent XID to the given TransactionState.
382 * We do not assign XIDs to transactions until/unless this is called.
383 * Also, any parent TransactionStates that don't yet have XIDs are assigned
384 * one; this maintains the invariant that a child transaction has an XID
385 * following its parent's.
388 AssignTransactionId(TransactionState s)
390 bool isSubXact = (s->parent != NULL);
391 ResourceOwner currentOwner;
393 /* Assert that caller didn't screw up */
394 Assert(!TransactionIdIsValid(s->transactionId));
395 Assert(s->state == TRANS_INPROGRESS);
398 * Ensure parent(s) have XIDs, so that a child always has an XID later
401 if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
402 AssignTransactionId(s->parent);
405 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
407 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
408 * shared storage other than PG_PROC; because if there's no room for it in
409 * PG_PROC, the subtrans entry is needed to ensure that other backends see
410 * the Xid as "running". See GetNewTransactionId.
412 s->transactionId = GetNewTransactionId(isSubXact);
415 SubTransSetParent(s->transactionId, s->parent->transactionId);
418 * Acquire lock on the transaction XID. (We assume this cannot block.) We
419 * have to ensure that the lock is assigned to the transaction's own
422 currentOwner = CurrentResourceOwner;
425 CurrentResourceOwner = s->curTransactionOwner;
426 XactLockTableInsert(s->transactionId);
430 /* Ensure CurrentResourceOwner is restored on error */
431 CurrentResourceOwner = currentOwner;
435 CurrentResourceOwner = currentOwner;
440 * GetCurrentSubTransactionId
443 GetCurrentSubTransactionId(void)
445 TransactionState s = CurrentTransactionState;
447 return s->subTransactionId;
452 * GetCurrentCommandId
454 * "used" must be TRUE if the caller intends to use the command ID to mark
455 * inserted/updated/deleted tuples. FALSE means the ID is being fetched
456 * for read-only purposes (ie, as a snapshot validity cutoff). See
457 * CommandCounterIncrement() for discussion.
460 GetCurrentCommandId(bool used)
462 /* this is global to a transaction, not subtransaction-local */
464 currentCommandIdUsed = true;
465 return currentCommandId;
469 * GetCurrentTransactionStartTimestamp
472 GetCurrentTransactionStartTimestamp(void)
474 return xactStartTimestamp;
478 * GetCurrentStatementStartTimestamp
481 GetCurrentStatementStartTimestamp(void)
483 return stmtStartTimestamp;
487 * GetCurrentTransactionStopTimestamp
489 * We return current time if the transaction stop time hasn't been set
490 * (which can happen if we decide we don't need to log an XLOG record).
493 GetCurrentTransactionStopTimestamp(void)
495 if (xactStopTimestamp != 0)
496 return xactStopTimestamp;
497 return GetCurrentTimestamp();
501 * SetCurrentStatementStartTimestamp
504 SetCurrentStatementStartTimestamp(void)
506 stmtStartTimestamp = GetCurrentTimestamp();
510 * SetCurrentTransactionStopTimestamp
513 SetCurrentTransactionStopTimestamp(void)
515 xactStopTimestamp = GetCurrentTimestamp();
519 * GetCurrentTransactionNestLevel
521 * Note: this will return zero when not inside any transaction, one when
522 * inside a top-level transaction, etc.
525 GetCurrentTransactionNestLevel(void)
527 TransactionState s = CurrentTransactionState;
529 return s->nestingLevel;
534 * TransactionIdIsCurrentTransactionId
537 TransactionIdIsCurrentTransactionId(TransactionId xid)
542 * We always say that BootstrapTransactionId is "not my transaction ID"
543 * even when it is (ie, during bootstrap). Along with the fact that
544 * transam.c always treats BootstrapTransactionId as already committed,
545 * this causes the tqual.c routines to see all tuples as committed, which
546 * is what we need during bootstrap. (Bootstrap mode only inserts tuples,
547 * it never updates or deletes them, so all tuples can be presumed good
550 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
551 * not my transaction ID, so we can just return "false" immediately for
552 * any non-normal XID.
554 if (!TransactionIdIsNormal(xid))
558 * We will return true for the Xid of the current subtransaction, any of
559 * its subcommitted children, any of its parents, or any of their
560 * previously subcommitted children. However, a transaction being aborted
561 * is no longer "current", even though it may still have an entry on the
564 for (s = CurrentTransactionState; s != NULL; s = s->parent)
568 if (s->state == TRANS_ABORT)
570 if (!TransactionIdIsValid(s->transactionId))
571 continue; /* it can't have any child XIDs either */
572 if (TransactionIdEquals(xid, s->transactionId))
574 /* As the childXids array is ordered, we can use binary search */
576 high = s->nChildXids - 1;
582 middle = low + (high - low) / 2;
583 probe = s->childXids[middle];
584 if (TransactionIdEquals(probe, xid))
586 else if (TransactionIdPrecedes(probe, xid))
598 * CommandCounterIncrement
601 CommandCounterIncrement(void)
604 * If the current value of the command counter hasn't been "used" to
605 * mark tuples, we need not increment it, since there's no need to
606 * distinguish a read-only command from others. This helps postpone
607 * command counter overflow, and keeps no-op CommandCounterIncrement
610 if (currentCommandIdUsed)
612 currentCommandId += 1;
613 if (currentCommandId == FirstCommandId) /* check for overflow */
615 currentCommandId -= 1;
617 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
618 errmsg("cannot have more than 2^32-1 commands in a transaction")));
620 currentCommandIdUsed = false;
622 /* Propagate new command ID into static snapshots, if set */
623 if (SerializableSnapshot)
624 SerializableSnapshot->curcid = currentCommandId;
626 LatestSnapshot->curcid = currentCommandId;
629 * Make any catalog changes done by the just-completed command
630 * visible in the local syscache. We obviously don't need to do
631 * this after a read-only command. (But see hacks in inval.c
632 * to make real sure we don't think a command that queued inval
633 * messages was read-only.)
635 AtCommit_LocalCache();
639 * Make any other backends' catalog changes visible to me.
641 * XXX this is probably in the wrong place: CommandCounterIncrement
642 * should be purely a local operation, most likely. However fooling
643 * with this will affect asynchronous cross-backend interactions,
644 * which doesn't seem like a wise thing to do in late beta, so save
645 * improving this for another day - tgl 2007-11-30
653 * Interface routine to allow commands to force a synchronous commit of the
654 * current top-level transaction
657 ForceSyncCommit(void)
659 forceSyncCommit = true;
663 /* ----------------------------------------------------------------
664 * StartTransaction stuff
665 * ----------------------------------------------------------------
674 AcceptInvalidationMessages();
683 TransactionState s = CurrentTransactionState;
686 * If this is the first time through, create a private context for
687 * AbortTransaction to work in. By reserving some space now, we can
688 * insulate AbortTransaction from out-of-memory scenarios. Like
689 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
690 * size, so that space will be reserved immediately.
692 if (TransactionAbortContext == NULL)
693 TransactionAbortContext =
694 AllocSetContextCreate(TopMemoryContext,
695 "TransactionAbortContext",
701 * We shouldn't have a transaction context already.
703 Assert(TopTransactionContext == NULL);
706 * Create a toplevel context for the transaction.
708 TopTransactionContext =
709 AllocSetContextCreate(TopMemoryContext,
710 "TopTransactionContext",
711 ALLOCSET_DEFAULT_MINSIZE,
712 ALLOCSET_DEFAULT_INITSIZE,
713 ALLOCSET_DEFAULT_MAXSIZE);
716 * In a top-level transaction, CurTransactionContext is the same as
717 * TopTransactionContext.
719 CurTransactionContext = TopTransactionContext;
720 s->curTransactionContext = CurTransactionContext;
722 /* Make the CurTransactionContext active. */
723 MemoryContextSwitchTo(CurTransactionContext);
727 * AtStart_ResourceOwner
730 AtStart_ResourceOwner(void)
732 TransactionState s = CurrentTransactionState;
735 * We shouldn't have a transaction resource owner already.
737 Assert(TopTransactionResourceOwner == NULL);
740 * Create a toplevel resource owner for the transaction.
742 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
744 TopTransactionResourceOwner = s->curTransactionOwner;
745 CurTransactionResourceOwner = s->curTransactionOwner;
746 CurrentResourceOwner = s->curTransactionOwner;
749 /* ----------------------------------------------------------------
750 * StartSubTransaction stuff
751 * ----------------------------------------------------------------
758 AtSubStart_Memory(void)
760 TransactionState s = CurrentTransactionState;
762 Assert(CurTransactionContext != NULL);
765 * Create a CurTransactionContext, which will be used to hold data that
766 * survives subtransaction commit but disappears on subtransaction abort.
767 * We make it a child of the immediate parent's CurTransactionContext.
769 CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
770 "CurTransactionContext",
771 ALLOCSET_DEFAULT_MINSIZE,
772 ALLOCSET_DEFAULT_INITSIZE,
773 ALLOCSET_DEFAULT_MAXSIZE);
774 s->curTransactionContext = CurTransactionContext;
776 /* Make the CurTransactionContext active. */
777 MemoryContextSwitchTo(CurTransactionContext);
781 * AtSubStart_ResourceOwner
784 AtSubStart_ResourceOwner(void)
786 TransactionState s = CurrentTransactionState;
788 Assert(s->parent != NULL);
791 * Create a resource owner for the subtransaction. We make it a child of
792 * the immediate parent's resource owner.
794 s->curTransactionOwner =
795 ResourceOwnerCreate(s->parent->curTransactionOwner,
798 CurTransactionResourceOwner = s->curTransactionOwner;
799 CurrentResourceOwner = s->curTransactionOwner;
802 /* ----------------------------------------------------------------
803 * CommitTransaction stuff
804 * ----------------------------------------------------------------
808 * RecordTransactionCommit
810 * Returns latest XID among xact and its children, or InvalidTransactionId
811 * if the xact has no XID. (We compute that here just because it's easier.)
813 * This is exported only to support an ugly hack in VACUUM FULL.
816 RecordTransactionCommit(void)
818 TransactionId xid = GetTopTransactionIdIfAny();
819 bool markXidCommitted = TransactionIdIsValid(xid);
820 TransactionId latestXid = InvalidTransactionId;
825 TransactionId *children;
827 /* Get data needed for commit record */
828 nrels = smgrGetPendingDeletes(true, &rels, &haveNonTemp);
829 nchildren = xactGetCommittedChildren(&children);
832 * If we haven't been assigned an XID yet, we neither can, nor do we want
833 * to write a COMMIT record.
835 if (!markXidCommitted)
838 * We expect that every smgrscheduleunlink is followed by a catalog
839 * update, and hence XID assignment, so we shouldn't get here with any
840 * pending deletes. Use a real test not just an Assert to check this,
841 * since it's a bit fragile.
844 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
846 /* Can't have child XIDs either; AssignTransactionId enforces this */
847 Assert(nchildren == 0);
850 * If we didn't create XLOG entries, we're done here; otherwise we
851 * should flush those entries the same as a commit record. (An
852 * example of a possible record that wouldn't cause an XID to be
853 * assigned is a sequence advance record due to nextval() --- we want
854 * to flush that to disk before reporting commit.)
856 if (XactLastRecEnd.xrecoff == 0)
862 * Begin commit critical section and insert the commit XLOG record.
864 XLogRecData rdata[3];
866 xl_xact_commit xlrec;
868 /* Tell bufmgr and smgr to prepare for commit */
872 * Mark ourselves as within our "commit critical section". This
873 * forces any concurrent checkpoint to wait until we've updated
874 * pg_clog. Without this, it is possible for the checkpoint to set
875 * REDO after the XLOG record but fail to flush the pg_clog update to
876 * disk, leading to loss of the transaction commit if the system
877 * crashes a little later.
879 * Note: we could, but don't bother to, set this flag in
880 * RecordTransactionAbort. That's because loss of a transaction abort
881 * is noncritical; the presumption would be that it aborted, anyway.
883 * It's safe to change the inCommit flag of our own backend without
884 * holding the ProcArrayLock, since we're the only one modifying it.
885 * This makes checkpoint's determination of which xacts are inCommit a
886 * bit fuzzy, but it doesn't matter.
888 START_CRIT_SECTION();
889 MyProc->inCommit = true;
891 SetCurrentTransactionStopTimestamp();
892 xlrec.xact_time = xactStopTimestamp;
894 xlrec.nsubxacts = nchildren;
895 rdata[0].data = (char *) (&xlrec);
896 rdata[0].len = MinSizeOfXactCommit;
897 rdata[0].buffer = InvalidBuffer;
898 /* dump rels to delete */
901 rdata[0].next = &(rdata[1]);
902 rdata[1].data = (char *) rels;
903 rdata[1].len = nrels * sizeof(RelFileNode);
904 rdata[1].buffer = InvalidBuffer;
907 /* dump committed child Xids */
910 rdata[lastrdata].next = &(rdata[2]);
911 rdata[2].data = (char *) children;
912 rdata[2].len = nchildren * sizeof(TransactionId);
913 rdata[2].buffer = InvalidBuffer;
916 rdata[lastrdata].next = NULL;
918 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
922 * Check if we want to commit asynchronously. If the user has set
923 * synchronous_commit = off, and we're not doing cleanup of any non-temp
924 * rels nor committing any command that wanted to force sync commit, then
925 * we can defer flushing XLOG. (We must not allow asynchronous commit if
926 * there are any non-temp tables to be deleted, because we might delete
927 * the files before the COMMIT record is flushed to disk. We do allow
928 * asynchronous commit if all to-be-deleted tables are temporary though,
929 * since they are lost anyway if we crash.)
931 if (XactSyncCommit || forceSyncCommit || haveNonTemp)
934 * Synchronous commit case.
936 * Sleep before flush! So we can flush more than one commit records
937 * per single fsync. (The idea is some other backend may do the
938 * XLogFlush while we're sleeping. This needs work still, because on
939 * most Unixen, the minimum select() delay is 10msec or more, which is
942 * We do not sleep if enableFsync is not turned on, nor if there are
943 * fewer than CommitSiblings other backends with active transactions.
945 if (CommitDelay > 0 && enableFsync &&
946 CountActiveBackends() >= CommitSiblings)
947 pg_usleep(CommitDelay);
949 XLogFlush(XactLastRecEnd);
952 * Now we may update the CLOG, if we wrote a COMMIT record above
954 if (markXidCommitted)
956 TransactionIdCommit(xid);
957 /* to avoid race conditions, the parent must commit first */
958 TransactionIdCommitTree(nchildren, children);
964 * Asynchronous commit case.
966 * Report the latest async commit LSN, so that the WAL writer knows to
969 XLogSetAsyncCommitLSN(XactLastRecEnd);
972 * We must not immediately update the CLOG, since we didn't flush the
973 * XLOG. Instead, we store the LSN up to which the XLOG must be
974 * flushed before the CLOG may be updated.
976 if (markXidCommitted)
978 TransactionIdAsyncCommit(xid, XactLastRecEnd);
979 /* to avoid race conditions, the parent must commit first */
980 TransactionIdAsyncCommitTree(nchildren, children, XactLastRecEnd);
985 * If we entered a commit critical section, leave it now, and let
986 * checkpoints proceed.
988 if (markXidCommitted)
990 MyProc->inCommit = false;
994 /* Compute latestXid while we have the child XIDs handy */
995 latestXid = TransactionIdLatest(xid, nchildren, children);
997 /* Reset XactLastRecEnd until the next transaction writes something */
998 XactLastRecEnd.xrecoff = 0;
1001 /* Clean up local data */
1010 * AtCommit_LocalCache
1013 AtCommit_LocalCache(void)
1016 * Make catalog changes visible to me for the next command.
1018 CommandEndInvalidationMessages();
1025 AtCommit_Memory(void)
1028 * Now that we're "out" of a transaction, have the system allocate things
1029 * in the top memory context instead of per-transaction contexts.
1031 MemoryContextSwitchTo(TopMemoryContext);
1034 * Release all transaction-local memory.
1036 Assert(TopTransactionContext != NULL);
1037 MemoryContextDelete(TopTransactionContext);
1038 TopTransactionContext = NULL;
1039 CurTransactionContext = NULL;
1040 CurrentTransactionState->curTransactionContext = NULL;
1043 /* ----------------------------------------------------------------
1044 * CommitSubTransaction stuff
1045 * ----------------------------------------------------------------
1049 * AtSubCommit_Memory
1052 AtSubCommit_Memory(void)
1054 TransactionState s = CurrentTransactionState;
1056 Assert(s->parent != NULL);
1058 /* Return to parent transaction level's memory context. */
1059 CurTransactionContext = s->parent->curTransactionContext;
1060 MemoryContextSwitchTo(CurTransactionContext);
1063 * Ordinarily we cannot throw away the child's CurTransactionContext,
1064 * since the data it contains will be needed at upper commit. However, if
1065 * there isn't actually anything in it, we can throw it away. This avoids
1066 * a small memory leak in the common case of "trivial" subxacts.
1068 if (MemoryContextIsEmpty(s->curTransactionContext))
1070 MemoryContextDelete(s->curTransactionContext);
1071 s->curTransactionContext = NULL;
1076 * AtSubCommit_childXids
1078 * Pass my own XID and my child XIDs up to my parent as committed children.
1081 AtSubCommit_childXids(void)
1083 TransactionState s = CurrentTransactionState;
1086 Assert(s->parent != NULL);
1089 * The parent childXids array will need to hold my XID and all my
1090 * childXids, in addition to the XIDs already there.
1092 new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1094 /* Allocate or enlarge the parent array if necessary */
1095 if (s->parent->maxChildXids < new_nChildXids)
1097 int new_maxChildXids;
1098 TransactionId *new_childXids;
1101 * Make it 2x what's needed right now, to avoid having to enlarge it
1102 * repeatedly. But we can't go above MaxAllocSize. (The latter
1103 * limit is what ensures that we don't need to worry about integer
1104 * overflow here or in the calculation of new_nChildXids.)
1106 new_maxChildXids = Min(new_nChildXids * 2,
1107 (int) (MaxAllocSize / sizeof(TransactionId)));
1109 if (new_maxChildXids < new_nChildXids)
1111 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1112 errmsg("maximum number of committed subtransactions (%d) exceeded",
1113 (int) (MaxAllocSize / sizeof(TransactionId)))));
1116 * We keep the child-XID arrays in TopTransactionContext; this avoids
1117 * setting up child-transaction contexts for what might be just a few
1118 * bytes of grandchild XIDs.
1120 if (s->parent->childXids == NULL)
1122 MemoryContextAlloc(TopTransactionContext,
1123 new_maxChildXids * sizeof(TransactionId));
1125 new_childXids = repalloc(s->parent->childXids,
1126 new_maxChildXids * sizeof(TransactionId));
1128 s->parent->childXids = new_childXids;
1129 s->parent->maxChildXids = new_maxChildXids;
1133 * Copy all my XIDs to parent's array.
1135 * Note: We rely on the fact that the XID of a child always follows that
1136 * of its parent. By copying the XID of this subtransaction before the
1137 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1138 * all XIDs already in the array belong to subtransactions started and
1139 * subcommitted before us, so their XIDs must precede ours.
1141 s->parent->childXids[s->parent->nChildXids] = s->transactionId;
1143 if (s->nChildXids > 0)
1144 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1146 s->nChildXids * sizeof(TransactionId));
1148 s->parent->nChildXids = new_nChildXids;
1150 /* Release child's array to avoid leakage */
1151 if (s->childXids != NULL)
1152 pfree(s->childXids);
1153 /* We must reset these to avoid double-free if fail later in commit */
1154 s->childXids = NULL;
1156 s->maxChildXids = 0;
1160 * RecordSubTransactionCommit
1163 RecordSubTransactionCommit(void)
1165 TransactionId xid = GetCurrentTransactionIdIfAny();
1168 * We do not log the subcommit in XLOG; it doesn't matter until the
1169 * top-level transaction commits.
1171 * We must mark the subtransaction subcommitted in the CLOG if it had a
1172 * valid XID assigned. If it did not, nobody else will ever know about
1173 * the existence of this subxact. We don't have to deal with deletions
1174 * scheduled for on-commit here, since they'll be reassigned to our parent
1175 * (who might still abort).
1177 if (TransactionIdIsValid(xid))
1179 /* XXX does this really need to be a critical section? */
1180 START_CRIT_SECTION();
1182 /* Record subtransaction subcommit */
1183 TransactionIdSubCommit(xid);
1189 /* ----------------------------------------------------------------
1190 * AbortTransaction stuff
1191 * ----------------------------------------------------------------
1195 * RecordTransactionAbort
1197 * Returns latest XID among xact and its children, or InvalidTransactionId
1198 * if the xact has no XID. (We compute that here just because it's easier.)
1200 static TransactionId
1201 RecordTransactionAbort(bool isSubXact)
1203 TransactionId xid = GetCurrentTransactionIdIfAny();
1204 TransactionId latestXid;
1208 TransactionId *children;
1209 XLogRecData rdata[3];
1211 xl_xact_abort xlrec;
1214 * If we haven't been assigned an XID, nobody will care whether we aborted
1215 * or not. Hence, we're done in that case. It does not matter if we have
1216 * rels to delete (note that this routine is not responsible for actually
1217 * deleting 'em). We cannot have any child XIDs, either.
1219 if (!TransactionIdIsValid(xid))
1221 /* Reset XactLastRecEnd until the next transaction writes something */
1223 XactLastRecEnd.xrecoff = 0;
1224 return InvalidTransactionId;
1228 * We have a valid XID, so we should write an ABORT record for it.
1230 * We do not flush XLOG to disk here, since the default assumption after a
1231 * crash would be that we aborted, anyway. For the same reason, we don't
1232 * need to worry about interlocking against checkpoint start.
1236 * Check that we haven't aborted halfway through RecordTransactionCommit.
1238 if (TransactionIdDidCommit(xid))
1239 elog(PANIC, "cannot abort transaction %u, it was already committed",
1242 /* Fetch the data we need for the abort record */
1243 nrels = smgrGetPendingDeletes(false, &rels, NULL);
1244 nchildren = xactGetCommittedChildren(&children);
1246 /* XXX do we really need a critical section here? */
1247 START_CRIT_SECTION();
1249 /* Write the ABORT record */
1251 xlrec.xact_time = GetCurrentTimestamp();
1254 SetCurrentTransactionStopTimestamp();
1255 xlrec.xact_time = xactStopTimestamp;
1257 xlrec.nrels = nrels;
1258 xlrec.nsubxacts = nchildren;
1259 rdata[0].data = (char *) (&xlrec);
1260 rdata[0].len = MinSizeOfXactAbort;
1261 rdata[0].buffer = InvalidBuffer;
1262 /* dump rels to delete */
1265 rdata[0].next = &(rdata[1]);
1266 rdata[1].data = (char *) rels;
1267 rdata[1].len = nrels * sizeof(RelFileNode);
1268 rdata[1].buffer = InvalidBuffer;
1271 /* dump committed child Xids */
1274 rdata[lastrdata].next = &(rdata[2]);
1275 rdata[2].data = (char *) children;
1276 rdata[2].len = nchildren * sizeof(TransactionId);
1277 rdata[2].buffer = InvalidBuffer;
1280 rdata[lastrdata].next = NULL;
1282 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
1285 * Mark the transaction aborted in clog. This is not absolutely necessary
1286 * but we may as well do it while we are here; also, in the subxact case
1287 * it is helpful because XactLockTableWait makes use of it to avoid
1288 * waiting for already-aborted subtransactions. It is OK to do it without
1289 * having flushed the ABORT record to disk, because in event of a crash
1290 * we'd be assumed to have aborted anyway.
1292 * The ordering here isn't critical but it seems best to mark the parent
1293 * first. This assures an atomic transition of all the subtransactions to
1294 * aborted state from the point of view of concurrent
1295 * TransactionIdDidAbort calls.
1297 TransactionIdAbort(xid);
1298 TransactionIdAbortTree(nchildren, children);
1302 /* Compute latestXid while we have the child XIDs handy */
1303 latestXid = TransactionIdLatest(xid, nchildren, children);
1306 * If we're aborting a subtransaction, we can immediately remove failed
1307 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1308 * subxacts, because we already have the child XID array at hand. For
1309 * main xacts, the equivalent happens just after this function returns.
1312 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1314 /* Reset XactLastRecEnd until the next transaction writes something */
1316 XactLastRecEnd.xrecoff = 0;
1318 /* And clean up local data */
1329 AtAbort_Memory(void)
1332 * Switch into TransactionAbortContext, which should have some free space
1333 * even if nothing else does. We'll work in this context until we've
1334 * finished cleaning up.
1336 * It is barely possible to get here when we've not been able to create
1337 * TransactionAbortContext yet; if so use TopMemoryContext.
1339 if (TransactionAbortContext != NULL)
1340 MemoryContextSwitchTo(TransactionAbortContext);
1342 MemoryContextSwitchTo(TopMemoryContext);
1349 AtSubAbort_Memory(void)
1351 Assert(TransactionAbortContext != NULL);
1353 MemoryContextSwitchTo(TransactionAbortContext);
1358 * AtAbort_ResourceOwner
1361 AtAbort_ResourceOwner(void)
1364 * Make sure we have a valid ResourceOwner, if possible (else it will be
1365 * NULL, which is OK)
1367 CurrentResourceOwner = TopTransactionResourceOwner;
1371 * AtSubAbort_ResourceOwner
1374 AtSubAbort_ResourceOwner(void)
1376 TransactionState s = CurrentTransactionState;
1378 /* Make sure we have a valid ResourceOwner */
1379 CurrentResourceOwner = s->curTransactionOwner;
1384 * AtSubAbort_childXids
1387 AtSubAbort_childXids(void)
1389 TransactionState s = CurrentTransactionState;
1392 * We keep the child-XID arrays in TopTransactionContext (see
1393 * AtSubCommit_childXids). This means we'd better free the array
1394 * explicitly at abort to avoid leakage.
1396 if (s->childXids != NULL)
1397 pfree(s->childXids);
1398 s->childXids = NULL;
1400 s->maxChildXids = 0;
1403 /* ----------------------------------------------------------------
1404 * CleanupTransaction stuff
1405 * ----------------------------------------------------------------
1412 AtCleanup_Memory(void)
1414 Assert(CurrentTransactionState->parent == NULL);
1417 * Now that we're "out" of a transaction, have the system allocate things
1418 * in the top memory context instead of per-transaction contexts.
1420 MemoryContextSwitchTo(TopMemoryContext);
1423 * Clear the special abort context for next time.
1425 if (TransactionAbortContext != NULL)
1426 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1429 * Release all transaction-local memory.
1431 if (TopTransactionContext != NULL)
1432 MemoryContextDelete(TopTransactionContext);
1433 TopTransactionContext = NULL;
1434 CurTransactionContext = NULL;
1435 CurrentTransactionState->curTransactionContext = NULL;
1439 /* ----------------------------------------------------------------
1440 * CleanupSubTransaction stuff
1441 * ----------------------------------------------------------------
1445 * AtSubCleanup_Memory
1448 AtSubCleanup_Memory(void)
1450 TransactionState s = CurrentTransactionState;
1452 Assert(s->parent != NULL);
1454 /* Make sure we're not in an about-to-be-deleted context */
1455 MemoryContextSwitchTo(s->parent->curTransactionContext);
1456 CurTransactionContext = s->parent->curTransactionContext;
1459 * Clear the special abort context for next time.
1461 if (TransactionAbortContext != NULL)
1462 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1465 * Delete the subxact local memory contexts. Its CurTransactionContext can
1466 * go too (note this also kills CurTransactionContexts from any children
1469 if (s->curTransactionContext)
1470 MemoryContextDelete(s->curTransactionContext);
1471 s->curTransactionContext = NULL;
1474 /* ----------------------------------------------------------------
1475 * interface routines
1476 * ----------------------------------------------------------------
1483 StartTransaction(void)
1486 VirtualTransactionId vxid;
1489 * Let's just make sure the state stack is empty
1491 s = &TopTransactionStateData;
1492 CurrentTransactionState = s;
1495 * check the current transaction state
1497 if (s->state != TRANS_DEFAULT)
1498 elog(WARNING, "StartTransaction while in %s state",
1499 TransStateAsString(s->state));
1502 * set the current transaction state information appropriately during
1505 s->state = TRANS_START;
1506 s->transactionId = InvalidTransactionId; /* until assigned */
1509 * Make sure we've freed any old snapshot, and reset xact state variables
1512 XactIsoLevel = DefaultXactIsoLevel;
1513 XactReadOnly = DefaultXactReadOnly;
1514 forceSyncCommit = false;
1515 MyXactAccessedTempRel = false;
1518 * reinitialize within-transaction counters
1520 s->subTransactionId = TopSubTransactionId;
1521 currentSubTransactionId = TopSubTransactionId;
1522 currentCommandId = FirstCommandId;
1523 currentCommandIdUsed = false;
1526 * must initialize resource-management stuff first
1529 AtStart_ResourceOwner();
1532 * Assign a new LocalTransactionId, and combine it with the backendId to
1533 * form a virtual transaction id.
1535 vxid.backendId = MyBackendId;
1536 vxid.localTransactionId = GetNextLocalTransactionId();
1539 * Lock the virtual transaction id before we announce it in the proc array
1541 VirtualXactLockTableInsert(vxid);
1544 * Advertise it in the proc array. We assume assignment of
1545 * LocalTransactionID is atomic, and the backendId should be set already.
1547 Assert(MyProc->backendId == vxid.backendId);
1548 MyProc->lxid = vxid.localTransactionId;
1550 PG_TRACE1(transaction__start, vxid.localTransactionId);
1553 * set transaction_timestamp() (a/k/a now()). We want this to be the same
1554 * as the first command's statement_timestamp(), so don't do a fresh
1555 * GetCurrentTimestamp() call (which'd be expensive anyway). Also, mark
1556 * xactStopTimestamp as unset.
1558 xactStartTimestamp = stmtStartTimestamp;
1559 xactStopTimestamp = 0;
1560 pgstat_report_xact_timestamp(xactStartTimestamp);
1563 * initialize current transaction state fields
1565 * note: prevXactReadOnly is not used at the outermost level
1567 s->nestingLevel = 1;
1568 s->gucNestLevel = 1;
1569 s->childXids = NULL;
1571 s->maxChildXids = 0;
1572 GetUserIdAndContext(&s->prevUser, &s->prevSecDefCxt);
1573 /* SecurityDefinerContext should never be set outside a transaction */
1574 Assert(!s->prevSecDefCxt);
1577 * initialize other subsystems for new transaction
1582 AfterTriggerBeginXact();
1585 * done with start processing, set current transaction state to "in
1588 s->state = TRANS_INPROGRESS;
1590 ShowTransactionState("StartTransaction");
1597 * NB: if you change this routine, better look at PrepareTransaction too!
1600 CommitTransaction(void)
1602 TransactionState s = CurrentTransactionState;
1603 TransactionId latestXid;
1605 ShowTransactionState("CommitTransaction");
1608 * check the current transaction state
1610 if (s->state != TRANS_INPROGRESS)
1611 elog(WARNING, "CommitTransaction while in %s state",
1612 TransStateAsString(s->state));
1613 Assert(s->parent == NULL);
1616 * Do pre-commit processing (most of this stuff requires database access,
1617 * and in fact could still cause an error...)
1619 * It is possible for CommitHoldablePortals to invoke functions that queue
1620 * deferred triggers, and it's also possible that triggers create holdable
1621 * cursors. So we have to loop until there's nothing left to do.
1626 * Fire all currently pending deferred triggers.
1628 AfterTriggerFireDeferred();
1631 * Convert any open holdable cursors into static portals. If there
1632 * weren't any, we are done ... otherwise loop back to check if they
1633 * queued deferred triggers. Lather, rinse, repeat.
1635 if (!CommitHoldablePortals())
1639 /* Now we can shut down the deferred-trigger manager */
1640 AfterTriggerEndXact(true);
1642 /* Close any open regular cursors */
1646 * Let ON COMMIT management do its thing (must happen after closing
1647 * cursors, to avoid dangling-reference problems)
1649 PreCommit_on_commit_actions();
1651 /* close large objects before lower-level cleanup */
1652 AtEOXact_LargeObject(true);
1654 /* NOTIFY commit must come before lower-level cleanup */
1658 * Update flat files if we changed pg_database, pg_authid or
1659 * pg_auth_members. This should be the last step before commit.
1661 AtEOXact_UpdateFlatFiles(true);
1663 /* Prevent cancel/die interrupt while cleaning up */
1667 * set the current transaction state information appropriately during
1670 s->state = TRANS_COMMIT;
1673 * Here is where we really truly commit.
1675 latestXid = RecordTransactionCommit();
1677 PG_TRACE1(transaction__commit, MyProc->lxid);
1680 * Let others know about no transaction in progress by me. Note that this
1681 * must be done _before_ releasing locks we hold and _after_
1682 * RecordTransactionCommit.
1684 ProcArrayEndTransaction(MyProc, latestXid);
1687 * This is all post-commit cleanup. Note that if an error is raised here,
1688 * it's too late to abort the transaction. This should be just
1689 * noncritical resource releasing.
1691 * The ordering of operations is not entirely random. The idea is:
1692 * release resources visible to other backends (eg, files, buffer pins);
1693 * then release locks; then release backend-local resources. We want to
1694 * release locks at the point where any backend waiting for us will see
1695 * our transaction as being fully cleaned up.
1697 * Resources that can be associated with individual queries are handled by
1698 * the ResourceOwner mechanism. The other calls here are for backend-wide
1702 CallXactCallbacks(XACT_EVENT_COMMIT);
1704 ResourceOwnerRelease(TopTransactionResourceOwner,
1705 RESOURCE_RELEASE_BEFORE_LOCKS,
1708 /* Check we've released all buffer pins */
1709 AtEOXact_Buffers(true);
1711 /* Clean up the relation cache */
1712 AtEOXact_RelationCache(true);
1715 * Make catalog changes visible to all backends. This has to happen after
1716 * relcache references are dropped (see comments for
1717 * AtEOXact_RelationCache), but before locks are released (if anyone is
1718 * waiting for lock on a relation we've modified, we want them to know
1719 * about the catalog change before they start using the relation).
1721 AtEOXact_Inval(true);
1724 * Likewise, dropping of files deleted during the transaction is best done
1725 * after releasing relcache and buffer pins. (This is not strictly
1726 * necessary during commit, since such pins should have been released
1727 * already, but this ordering is definitely critical during abort.)
1729 smgrDoPendingDeletes(true);
1731 AtEOXact_MultiXact();
1733 ResourceOwnerRelease(TopTransactionResourceOwner,
1734 RESOURCE_RELEASE_LOCKS,
1736 ResourceOwnerRelease(TopTransactionResourceOwner,
1737 RESOURCE_RELEASE_AFTER_LOCKS,
1740 /* Check we've released all catcache entries */
1741 AtEOXact_CatCache(true);
1743 AtEOXact_GUC(true, 1);
1746 AtEOXact_on_commit_actions(true);
1747 AtEOXact_Namespace(true);
1748 /* smgrcommit already done */
1750 AtEOXact_ComboCid();
1751 AtEOXact_HashTables(true);
1752 AtEOXact_PgStat(true);
1753 pgstat_report_xact_timestamp(0);
1755 CurrentResourceOwner = NULL;
1756 ResourceOwnerDelete(TopTransactionResourceOwner);
1757 s->curTransactionOwner = NULL;
1758 CurTransactionResourceOwner = NULL;
1759 TopTransactionResourceOwner = NULL;
1763 s->transactionId = InvalidTransactionId;
1764 s->subTransactionId = InvalidSubTransactionId;
1765 s->nestingLevel = 0;
1766 s->gucNestLevel = 0;
1767 s->childXids = NULL;
1769 s->maxChildXids = 0;
1772 * done with commit processing, set current transaction state back to
1775 s->state = TRANS_DEFAULT;
1777 RESUME_INTERRUPTS();
1782 * PrepareTransaction
1784 * NB: if you change this routine, better look at CommitTransaction too!
1787 PrepareTransaction(void)
1789 TransactionState s = CurrentTransactionState;
1790 TransactionId xid = GetCurrentTransactionId();
1791 GlobalTransaction gxact;
1792 TimestampTz prepared_at;
1794 ShowTransactionState("PrepareTransaction");
1797 * check the current transaction state
1799 if (s->state != TRANS_INPROGRESS)
1800 elog(WARNING, "PrepareTransaction while in %s state",
1801 TransStateAsString(s->state));
1802 Assert(s->parent == NULL);
1805 * Do pre-commit processing (most of this stuff requires database access,
1806 * and in fact could still cause an error...)
1808 * It is possible for PrepareHoldablePortals to invoke functions that
1809 * queue deferred triggers, and it's also possible that triggers create
1810 * holdable cursors. So we have to loop until there's nothing left to do.
1815 * Fire all currently pending deferred triggers.
1817 AfterTriggerFireDeferred();
1820 * Convert any open holdable cursors into static portals. If there
1821 * weren't any, we are done ... otherwise loop back to check if they
1822 * queued deferred triggers. Lather, rinse, repeat.
1824 if (!PrepareHoldablePortals())
1828 /* Now we can shut down the deferred-trigger manager */
1829 AfterTriggerEndXact(true);
1831 /* Close any open regular cursors */
1835 * Let ON COMMIT management do its thing (must happen after closing
1836 * cursors, to avoid dangling-reference problems)
1838 PreCommit_on_commit_actions();
1840 /* close large objects before lower-level cleanup */
1841 AtEOXact_LargeObject(true);
1843 /* NOTIFY and flatfiles will be handled below */
1846 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table
1847 * in this transaction. Having the prepared xact hold locks on another
1848 * backend's temp table seems a bad idea --- for instance it would prevent
1849 * the backend from exiting. There are other problems too, such as how
1850 * to clean up the source backend's local buffers and ON COMMIT state
1851 * if the prepared xact includes a DROP of a temp table.
1853 * We must check this after executing any ON COMMIT actions, because
1854 * they might still access a temp relation.
1856 * XXX In principle this could be relaxed to allow some useful special
1857 * cases, such as a temp table created and dropped all within the
1858 * transaction. That seems to require much more bookkeeping though.
1860 if (MyXactAccessedTempRel)
1862 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1863 errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
1865 /* Prevent cancel/die interrupt while cleaning up */
1869 * set the current transaction state information appropriately during
1870 * prepare processing
1872 s->state = TRANS_PREPARE;
1874 prepared_at = GetCurrentTimestamp();
1876 /* Tell bufmgr and smgr to prepare for commit */
1880 * Reserve the GID for this transaction. This could fail if the requested
1881 * GID is invalid or already in use.
1883 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
1884 GetUserId(), MyDatabaseId);
1888 * Collect data for the 2PC state file. Note that in general, no actual
1889 * state change should happen in the called modules during this step,
1890 * since it's still possible to fail before commit, and in that case we
1891 * want transaction abort to be able to clean up. (In particular, the
1892 * AtPrepare routines may error out if they find cases they cannot
1893 * handle.) State cleanup should happen in the PostPrepare routines
1894 * below. However, some modules can go ahead and clear state here because
1895 * they wouldn't do anything with it during abort anyway.
1897 * Note: because the 2PC state file records will be replayed in the same
1898 * order they are made, the order of these calls has to match the order in
1899 * which we want things to happen during COMMIT PREPARED or ROLLBACK
1900 * PREPARED; in particular, pay attention to whether things should happen
1901 * before or after releasing the transaction's locks.
1903 StartPrepare(gxact);
1906 AtPrepare_UpdateFlatFiles();
1912 * Here is where we really truly prepare.
1914 * We have to record transaction prepares even if we didn't make any
1915 * updates, because the transaction manager might get confused if we lose
1916 * a global transaction.
1921 * Now we clean up backend-internal state and release internal resources.
1924 /* Reset XactLastRecEnd until the next transaction writes something */
1925 XactLastRecEnd.xrecoff = 0;
1928 * Let others know about no transaction in progress by me. This has to be
1929 * done *after* the prepared transaction has been marked valid, else
1930 * someone may think it is unlocked and recyclable.
1932 ProcArrayClearTransaction(MyProc);
1935 * This is all post-transaction cleanup. Note that if an error is raised
1936 * here, it's too late to abort the transaction. This should be just
1937 * noncritical resource releasing. See notes in CommitTransaction.
1940 CallXactCallbacks(XACT_EVENT_PREPARE);
1942 ResourceOwnerRelease(TopTransactionResourceOwner,
1943 RESOURCE_RELEASE_BEFORE_LOCKS,
1946 /* Check we've released all buffer pins */
1947 AtEOXact_Buffers(true);
1949 /* Clean up the relation cache */
1950 AtEOXact_RelationCache(true);
1952 /* notify and flatfiles don't need a postprepare call */
1954 PostPrepare_PgStat();
1956 PostPrepare_Inval();
1960 AtEOXact_MultiXact();
1962 PostPrepare_Locks(xid);
1964 ResourceOwnerRelease(TopTransactionResourceOwner,
1965 RESOURCE_RELEASE_LOCKS,
1967 ResourceOwnerRelease(TopTransactionResourceOwner,
1968 RESOURCE_RELEASE_AFTER_LOCKS,
1971 /* Check we've released all catcache entries */
1972 AtEOXact_CatCache(true);
1974 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
1975 AtEOXact_GUC(true, 1);
1978 AtEOXact_on_commit_actions(true);
1979 AtEOXact_Namespace(true);
1980 /* smgrcommit already done */
1982 AtEOXact_ComboCid();
1983 AtEOXact_HashTables(true);
1984 /* don't call AtEOXact_PgStat here */
1986 CurrentResourceOwner = NULL;
1987 ResourceOwnerDelete(TopTransactionResourceOwner);
1988 s->curTransactionOwner = NULL;
1989 CurTransactionResourceOwner = NULL;
1990 TopTransactionResourceOwner = NULL;
1994 s->transactionId = InvalidTransactionId;
1995 s->subTransactionId = InvalidSubTransactionId;
1996 s->nestingLevel = 0;
1997 s->gucNestLevel = 0;
1998 s->childXids = NULL;
2000 s->maxChildXids = 0;
2003 * done with 1st phase commit processing, set current transaction state
2006 s->state = TRANS_DEFAULT;
2008 RESUME_INTERRUPTS();
2016 AbortTransaction(void)
2018 TransactionState s = CurrentTransactionState;
2019 TransactionId latestXid;
2021 /* Prevent cancel/die interrupt while cleaning up */
2024 /* Make sure we have a valid memory context and resource owner */
2026 AtAbort_ResourceOwner();
2029 * Release any LW locks we might be holding as quickly as possible.
2030 * (Regular locks, however, must be held till we finish aborting.)
2031 * Releasing LW locks is critical since we might try to grab them again
2032 * while cleaning up!
2036 /* Clean up buffer I/O and buffer context locks, too */
2041 * Also clean up any open wait for lock, since the lock manager will choke
2042 * if we try to wait for another lock before doing this.
2047 * check the current transaction state
2049 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2050 elog(WARNING, "AbortTransaction while in %s state",
2051 TransStateAsString(s->state));
2052 Assert(s->parent == NULL);
2055 * set the current transaction state information appropriately during the
2058 s->state = TRANS_ABORT;
2061 * Reset user ID which might have been changed transiently. We need this
2062 * to clean up in case control escaped out of a SECURITY DEFINER function
2063 * or other local change of CurrentUserId; therefore, the prior value
2064 * of SecurityDefinerContext also needs to be restored.
2066 * (Note: it is not necessary to restore session authorization or role
2067 * settings here because those can only be changed via GUC, and GUC will
2068 * take care of rolling them back if need be.)
2070 SetUserIdAndContext(s->prevUser, s->prevSecDefCxt);
2073 * do abort processing
2075 AfterTriggerEndXact(false);
2077 AtEOXact_LargeObject(false); /* 'false' means it's abort */
2079 AtEOXact_UpdateFlatFiles(false);
2082 * Advertise the fact that we aborted in pg_clog (assuming that we got as
2083 * far as assigning an XID to advertise).
2085 latestXid = RecordTransactionAbort(false);
2087 PG_TRACE1(transaction__abort, MyProc->lxid);
2090 * Let others know about no transaction in progress by me. Note that this
2091 * must be done _before_ releasing locks we hold and _after_
2092 * RecordTransactionAbort.
2094 ProcArrayEndTransaction(MyProc, latestXid);
2097 * Post-abort cleanup. See notes in CommitTransaction() concerning
2101 CallXactCallbacks(XACT_EVENT_ABORT);
2103 ResourceOwnerRelease(TopTransactionResourceOwner,
2104 RESOURCE_RELEASE_BEFORE_LOCKS,
2106 AtEOXact_Buffers(false);
2107 AtEOXact_RelationCache(false);
2108 AtEOXact_Inval(false);
2109 smgrDoPendingDeletes(false);
2110 AtEOXact_MultiXact();
2111 ResourceOwnerRelease(TopTransactionResourceOwner,
2112 RESOURCE_RELEASE_LOCKS,
2114 ResourceOwnerRelease(TopTransactionResourceOwner,
2115 RESOURCE_RELEASE_AFTER_LOCKS,
2117 AtEOXact_CatCache(false);
2119 AtEOXact_GUC(false, 1);
2120 AtEOXact_SPI(false);
2122 AtEOXact_on_commit_actions(false);
2123 AtEOXact_Namespace(false);
2126 AtEOXact_ComboCid();
2127 AtEOXact_HashTables(false);
2128 AtEOXact_PgStat(false);
2129 pgstat_report_xact_timestamp(0);
2132 * State remains TRANS_ABORT until CleanupTransaction().
2134 RESUME_INTERRUPTS();
2138 * CleanupTransaction
2141 CleanupTransaction(void)
2143 TransactionState s = CurrentTransactionState;
2146 * State should still be TRANS_ABORT from AbortTransaction().
2148 if (s->state != TRANS_ABORT)
2149 elog(FATAL, "CleanupTransaction: unexpected state %s",
2150 TransStateAsString(s->state));
2153 * do abort cleanup processing
2155 AtCleanup_Portals(); /* now safe to release portal memory */
2157 CurrentResourceOwner = NULL; /* and resource owner */
2158 if (TopTransactionResourceOwner)
2159 ResourceOwnerDelete(TopTransactionResourceOwner);
2160 s->curTransactionOwner = NULL;
2161 CurTransactionResourceOwner = NULL;
2162 TopTransactionResourceOwner = NULL;
2164 AtCleanup_Memory(); /* and transaction memory */
2166 s->transactionId = InvalidTransactionId;
2167 s->subTransactionId = InvalidSubTransactionId;
2168 s->nestingLevel = 0;
2169 s->gucNestLevel = 0;
2170 s->childXids = NULL;
2172 s->maxChildXids = 0;
2175 * done with abort processing, set current transaction state back to
2178 s->state = TRANS_DEFAULT;
2182 * StartTransactionCommand
2185 StartTransactionCommand(void)
2187 TransactionState s = CurrentTransactionState;
2189 switch (s->blockState)
2192 * if we aren't in a transaction block, we just do our usual start
2195 case TBLOCK_DEFAULT:
2197 s->blockState = TBLOCK_STARTED;
2201 * We are somewhere in a transaction block or subtransaction and
2202 * about to start a new command. For now we do nothing, but
2203 * someday we may do command-local resource initialization. (Note
2204 * that any needed CommandCounterIncrement was done by the
2205 * previous CommitTransactionCommand.)
2207 case TBLOCK_INPROGRESS:
2208 case TBLOCK_SUBINPROGRESS:
2212 * Here we are in a failed transaction block (one of the commands
2213 * caused an abort) so we do nothing but remain in the abort
2214 * state. Eventually we will get a ROLLBACK command which will
2215 * get us out of this state. (It is up to other code to ensure
2216 * that no commands other than ROLLBACK will be processed in these
2220 case TBLOCK_SUBABORT:
2223 /* These cases are invalid. */
2224 case TBLOCK_STARTED:
2226 case TBLOCK_SUBBEGIN:
2229 case TBLOCK_ABORT_END:
2230 case TBLOCK_SUBABORT_END:
2231 case TBLOCK_ABORT_PENDING:
2232 case TBLOCK_SUBABORT_PENDING:
2233 case TBLOCK_SUBRESTART:
2234 case TBLOCK_SUBABORT_RESTART:
2235 case TBLOCK_PREPARE:
2236 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2237 BlockStateAsString(s->blockState));
2242 * We must switch to CurTransactionContext before returning. This is
2243 * already done if we called StartTransaction, otherwise not.
2245 Assert(CurTransactionContext != NULL);
2246 MemoryContextSwitchTo(CurTransactionContext);
2250 * CommitTransactionCommand
2253 CommitTransactionCommand(void)
2255 TransactionState s = CurrentTransactionState;
2257 switch (s->blockState)
2260 * This shouldn't happen, because it means the previous
2261 * StartTransactionCommand didn't set the STARTED state
2264 case TBLOCK_DEFAULT:
2265 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2266 BlockStateAsString(s->blockState));
2270 * If we aren't in a transaction block, just do our usual
2271 * transaction commit, and return to the idle state.
2273 case TBLOCK_STARTED:
2274 CommitTransaction();
2275 s->blockState = TBLOCK_DEFAULT;
2279 * We are completing a "BEGIN TRANSACTION" command, so we change
2280 * to the "transaction block in progress" state and return. (We
2281 * assume the BEGIN did nothing to the database, so we need no
2282 * CommandCounterIncrement.)
2285 s->blockState = TBLOCK_INPROGRESS;
2289 * This is the case when we have finished executing a command
2290 * someplace within a transaction block. We increment the command
2291 * counter and return.
2293 case TBLOCK_INPROGRESS:
2294 case TBLOCK_SUBINPROGRESS:
2295 CommandCounterIncrement();
2299 * We are completing a "COMMIT" command. Do it and return to the
2303 CommitTransaction();
2304 s->blockState = TBLOCK_DEFAULT;
2308 * Here we are in the middle of a transaction block but one of the
2309 * commands caused an abort so we do nothing but remain in the
2310 * abort state. Eventually we will get a ROLLBACK comand.
2313 case TBLOCK_SUBABORT:
2317 * Here we were in an aborted transaction block and we just got
2318 * the ROLLBACK command from the user, so clean up the
2319 * already-aborted transaction and return to the idle state.
2321 case TBLOCK_ABORT_END:
2322 CleanupTransaction();
2323 s->blockState = TBLOCK_DEFAULT;
2327 * Here we were in a perfectly good transaction block but the user
2328 * told us to ROLLBACK anyway. We have to abort the transaction
2329 * and then clean up.
2331 case TBLOCK_ABORT_PENDING:
2333 CleanupTransaction();
2334 s->blockState = TBLOCK_DEFAULT;
2338 * We are completing a "PREPARE TRANSACTION" command. Do it and
2339 * return to the idle state.
2341 case TBLOCK_PREPARE:
2342 PrepareTransaction();
2343 s->blockState = TBLOCK_DEFAULT;
2347 * We were just issued a SAVEPOINT inside a transaction block.
2348 * Start a subtransaction. (DefineSavepoint already did
2349 * PushTransaction, so as to have someplace to put the SUBBEGIN
2352 case TBLOCK_SUBBEGIN:
2353 StartSubTransaction();
2354 s->blockState = TBLOCK_SUBINPROGRESS;
2358 * We were issued a COMMIT or RELEASE command, so we end the
2359 * current subtransaction and return to the parent transaction.
2360 * The parent might be ended too, so repeat till we are all the
2361 * way out or find an INPROGRESS transaction.
2366 CommitSubTransaction();
2367 s = CurrentTransactionState; /* changed by pop */
2368 } while (s->blockState == TBLOCK_SUBEND);
2369 /* If we had a COMMIT command, finish off the main xact too */
2370 if (s->blockState == TBLOCK_END)
2372 Assert(s->parent == NULL);
2373 CommitTransaction();
2374 s->blockState = TBLOCK_DEFAULT;
2376 else if (s->blockState == TBLOCK_PREPARE)
2378 Assert(s->parent == NULL);
2379 PrepareTransaction();
2380 s->blockState = TBLOCK_DEFAULT;
2384 Assert(s->blockState == TBLOCK_INPROGRESS ||
2385 s->blockState == TBLOCK_SUBINPROGRESS);
2390 * The current already-failed subtransaction is ending due to a
2391 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2392 * examine the parent (which could be in any of several states).
2394 case TBLOCK_SUBABORT_END:
2395 CleanupSubTransaction();
2396 CommitTransactionCommand();
2400 * As above, but it's not dead yet, so abort first.
2402 case TBLOCK_SUBABORT_PENDING:
2403 AbortSubTransaction();
2404 CleanupSubTransaction();
2405 CommitTransactionCommand();
2409 * The current subtransaction is the target of a ROLLBACK TO
2410 * command. Abort and pop it, then start a new subtransaction
2411 * with the same name.
2413 case TBLOCK_SUBRESTART:
2418 /* save name and keep Cleanup from freeing it */
2421 savepointLevel = s->savepointLevel;
2423 AbortSubTransaction();
2424 CleanupSubTransaction();
2426 DefineSavepoint(NULL);
2427 s = CurrentTransactionState; /* changed by push */
2429 s->savepointLevel = savepointLevel;
2431 /* This is the same as TBLOCK_SUBBEGIN case */
2432 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2433 StartSubTransaction();
2434 s->blockState = TBLOCK_SUBINPROGRESS;
2439 * Same as above, but the subtransaction had already failed, so we
2440 * don't need AbortSubTransaction.
2442 case TBLOCK_SUBABORT_RESTART:
2447 /* save name and keep Cleanup from freeing it */
2450 savepointLevel = s->savepointLevel;
2452 CleanupSubTransaction();
2454 DefineSavepoint(NULL);
2455 s = CurrentTransactionState; /* changed by push */
2457 s->savepointLevel = savepointLevel;
2459 /* This is the same as TBLOCK_SUBBEGIN case */
2460 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2461 StartSubTransaction();
2462 s->blockState = TBLOCK_SUBINPROGRESS;
2469 * AbortCurrentTransaction
2472 AbortCurrentTransaction(void)
2474 TransactionState s = CurrentTransactionState;
2476 switch (s->blockState)
2478 case TBLOCK_DEFAULT:
2479 if (s->state == TRANS_DEFAULT)
2481 /* we are idle, so nothing to do */
2486 * We can get here after an error during transaction start
2487 * (state will be TRANS_START). Need to clean up the
2488 * incompletely started transaction. First, adjust the
2489 * low-level state to suppress warning message from
2492 if (s->state == TRANS_START)
2493 s->state = TRANS_INPROGRESS;
2495 CleanupTransaction();
2500 * if we aren't in a transaction block, we just do the basic abort
2501 * & cleanup transaction.
2503 case TBLOCK_STARTED:
2505 CleanupTransaction();
2506 s->blockState = TBLOCK_DEFAULT;
2510 * If we are in TBLOCK_BEGIN it means something screwed up right
2511 * after reading "BEGIN TRANSACTION". We assume that the user
2512 * will interpret the error as meaning the BEGIN failed to get him
2513 * into a transaction block, so we should abort and return to idle
2518 CleanupTransaction();
2519 s->blockState = TBLOCK_DEFAULT;
2523 * We are somewhere in a transaction block and we've gotten a
2524 * failure, so we abort the transaction and set up the persistent
2525 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
2527 case TBLOCK_INPROGRESS:
2529 s->blockState = TBLOCK_ABORT;
2530 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
2534 * Here, we failed while trying to COMMIT. Clean up the
2535 * transaction and return to idle state (we do not want to stay in
2540 CleanupTransaction();
2541 s->blockState = TBLOCK_DEFAULT;
2545 * Here, we are already in an aborted transaction state and are
2546 * waiting for a ROLLBACK, but for some reason we failed again! So
2547 * we just remain in the abort state.
2550 case TBLOCK_SUBABORT:
2554 * We are in a failed transaction and we got the ROLLBACK command.
2555 * We have already aborted, we just need to cleanup and go to idle
2558 case TBLOCK_ABORT_END:
2559 CleanupTransaction();
2560 s->blockState = TBLOCK_DEFAULT;
2564 * We are in a live transaction and we got a ROLLBACK command.
2565 * Abort, cleanup, go to idle state.
2567 case TBLOCK_ABORT_PENDING:
2569 CleanupTransaction();
2570 s->blockState = TBLOCK_DEFAULT;
2574 * Here, we failed while trying to PREPARE. Clean up the
2575 * transaction and return to idle state (we do not want to stay in
2578 case TBLOCK_PREPARE:
2580 CleanupTransaction();
2581 s->blockState = TBLOCK_DEFAULT;
2585 * We got an error inside a subtransaction. Abort just the
2586 * subtransaction, and go to the persistent SUBABORT state until
2589 case TBLOCK_SUBINPROGRESS:
2590 AbortSubTransaction();
2591 s->blockState = TBLOCK_SUBABORT;
2595 * If we failed while trying to create a subtransaction, clean up
2596 * the broken subtransaction and abort the parent. The same
2597 * applies if we get a failure while ending a subtransaction.
2599 case TBLOCK_SUBBEGIN:
2601 case TBLOCK_SUBABORT_PENDING:
2602 case TBLOCK_SUBRESTART:
2603 AbortSubTransaction();
2604 CleanupSubTransaction();
2605 AbortCurrentTransaction();
2609 * Same as above, except the Abort() was already done.
2611 case TBLOCK_SUBABORT_END:
2612 case TBLOCK_SUBABORT_RESTART:
2613 CleanupSubTransaction();
2614 AbortCurrentTransaction();
2620 * PreventTransactionChain
2622 * This routine is to be called by statements that must not run inside
2623 * a transaction block, typically because they have non-rollback-able
2624 * side effects or do internal commits.
2626 * If we have already started a transaction block, issue an error; also issue
2627 * an error if we appear to be running inside a user-defined function (which
2628 * could issue more commands and possibly cause a failure after the statement
2629 * completes). Subtransactions are verboten too.
2631 * isTopLevel: passed down from ProcessUtility to determine whether we are
2632 * inside a function or multi-query querystring. (We will always fail if
2633 * this is false, but it's convenient to centralize the check here instead of
2634 * making callers do it.)
2635 * stmtType: statement type name, for error messages.
2638 PreventTransactionChain(bool isTopLevel, const char *stmtType)
2641 * xact block already started?
2643 if (IsTransactionBlock())
2645 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2646 /* translator: %s represents an SQL statement name */
2647 errmsg("%s cannot run inside a transaction block",
2653 if (IsSubTransaction())
2655 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2656 /* translator: %s represents an SQL statement name */
2657 errmsg("%s cannot run inside a subtransaction",
2661 * inside a function call?
2665 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2666 /* translator: %s represents an SQL statement name */
2667 errmsg("%s cannot be executed from a function or multi-command string",
2670 /* If we got past IsTransactionBlock test, should be in default state */
2671 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2672 CurrentTransactionState->blockState != TBLOCK_STARTED)
2673 elog(FATAL, "cannot prevent transaction chain");
2678 * RequireTransactionChain
2680 * This routine is to be called by statements that must run inside
2681 * a transaction block, because they have no effects that persist past
2682 * transaction end (and so calling them outside a transaction block
2683 * is presumably an error). DECLARE CURSOR is an example.
2685 * If we appear to be running inside a user-defined function, we do not
2686 * issue an error, since the function could issue more commands that make
2687 * use of the current statement's results. Likewise subtransactions.
2688 * Thus this is an inverse for PreventTransactionChain.
2690 * isTopLevel: passed down from ProcessUtility to determine whether we are
2691 * inside a function.
2692 * stmtType: statement type name, for error messages.
2695 RequireTransactionChain(bool isTopLevel, const char *stmtType)
2698 * xact block already started?
2700 if (IsTransactionBlock())
2706 if (IsSubTransaction())
2710 * inside a function call?
2716 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2717 /* translator: %s represents an SQL statement name */
2718 errmsg("%s can only be used in transaction blocks",
2723 * IsInTransactionChain
2725 * This routine is for statements that need to behave differently inside
2726 * a transaction block than when running as single commands. ANALYZE is
2727 * currently the only example.
2729 * isTopLevel: passed down from ProcessUtility to determine whether we are
2730 * inside a function.
2733 IsInTransactionChain(bool isTopLevel)
2736 * Return true on same conditions that would make PreventTransactionChain
2739 if (IsTransactionBlock())
2742 if (IsSubTransaction())
2748 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2749 CurrentTransactionState->blockState != TBLOCK_STARTED)
2757 * Register or deregister callback functions for start- and end-of-xact
2760 * These functions are intended for use by dynamically loaded modules.
2761 * For built-in modules we generally just hardwire the appropriate calls
2762 * (mainly because it's easier to control the order that way, where needed).
2764 * At transaction end, the callback occurs post-commit or post-abort, so the
2765 * callback functions can only do noncritical cleanup.
2768 RegisterXactCallback(XactCallback callback, void *arg)
2770 XactCallbackItem *item;
2772 item = (XactCallbackItem *)
2773 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
2774 item->callback = callback;
2776 item->next = Xact_callbacks;
2777 Xact_callbacks = item;
2781 UnregisterXactCallback(XactCallback callback, void *arg)
2783 XactCallbackItem *item;
2784 XactCallbackItem *prev;
2787 for (item = Xact_callbacks; item; prev = item, item = item->next)
2789 if (item->callback == callback && item->arg == arg)
2792 prev->next = item->next;
2794 Xact_callbacks = item->next;
2802 CallXactCallbacks(XactEvent event)
2804 XactCallbackItem *item;
2806 for (item = Xact_callbacks; item; item = item->next)
2807 (*item->callback) (event, item->arg);
2812 * Register or deregister callback functions for start- and end-of-subxact
2815 * Pretty much same as above, but for subtransaction events.
2817 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
2818 * so the callback functions can only do noncritical cleanup. At
2819 * subtransaction start, the callback is called when the subtransaction has
2820 * finished initializing.
2823 RegisterSubXactCallback(SubXactCallback callback, void *arg)
2825 SubXactCallbackItem *item;
2827 item = (SubXactCallbackItem *)
2828 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
2829 item->callback = callback;
2831 item->next = SubXact_callbacks;
2832 SubXact_callbacks = item;
2836 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
2838 SubXactCallbackItem *item;
2839 SubXactCallbackItem *prev;
2842 for (item = SubXact_callbacks; item; prev = item, item = item->next)
2844 if (item->callback == callback && item->arg == arg)
2847 prev->next = item->next;
2849 SubXact_callbacks = item->next;
2857 CallSubXactCallbacks(SubXactEvent event,
2858 SubTransactionId mySubid,
2859 SubTransactionId parentSubid)
2861 SubXactCallbackItem *item;
2863 for (item = SubXact_callbacks; item; item = item->next)
2864 (*item->callback) (event, mySubid, parentSubid, item->arg);
2868 /* ----------------------------------------------------------------
2869 * transaction block support
2870 * ----------------------------------------------------------------
2874 * BeginTransactionBlock
2875 * This executes a BEGIN command.
2878 BeginTransactionBlock(void)
2880 TransactionState s = CurrentTransactionState;
2882 switch (s->blockState)
2885 * We are not inside a transaction block, so allow one to begin.
2887 case TBLOCK_STARTED:
2888 s->blockState = TBLOCK_BEGIN;
2892 * Already a transaction block in progress.
2894 case TBLOCK_INPROGRESS:
2895 case TBLOCK_SUBINPROGRESS:
2897 case TBLOCK_SUBABORT:
2899 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2900 errmsg("there is already a transaction in progress")));
2903 /* These cases are invalid. */
2904 case TBLOCK_DEFAULT:
2906 case TBLOCK_SUBBEGIN:
2909 case TBLOCK_ABORT_END:
2910 case TBLOCK_SUBABORT_END:
2911 case TBLOCK_ABORT_PENDING:
2912 case TBLOCK_SUBABORT_PENDING:
2913 case TBLOCK_SUBRESTART:
2914 case TBLOCK_SUBABORT_RESTART:
2915 case TBLOCK_PREPARE:
2916 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
2917 BlockStateAsString(s->blockState));
2923 * PrepareTransactionBlock
2924 * This executes a PREPARE command.
2926 * Since PREPARE may actually do a ROLLBACK, the result indicates what
2927 * happened: TRUE for PREPARE, FALSE for ROLLBACK.
2929 * Note that we don't actually do anything here except change blockState.
2930 * The real work will be done in the upcoming PrepareTransaction().
2931 * We do it this way because it's not convenient to change memory context,
2932 * resource owner, etc while executing inside a Portal.
2935 PrepareTransactionBlock(char *gid)
2940 /* Set up to commit the current transaction */
2941 result = EndTransactionBlock();
2943 /* If successful, change outer tblock state to PREPARE */
2946 s = CurrentTransactionState;
2948 while (s->parent != NULL)
2951 if (s->blockState == TBLOCK_END)
2953 /* Save GID where PrepareTransaction can find it again */
2954 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
2956 s->blockState = TBLOCK_PREPARE;
2961 * ignore case where we are not in a transaction;
2962 * EndTransactionBlock already issued a warning.
2964 Assert(s->blockState == TBLOCK_STARTED);
2965 /* Don't send back a PREPARE result tag... */
2974 * EndTransactionBlock
2975 * This executes a COMMIT command.
2977 * Since COMMIT may actually do a ROLLBACK, the result indicates what
2978 * happened: TRUE for COMMIT, FALSE for ROLLBACK.
2980 * Note that we don't actually do anything here except change blockState.
2981 * The real work will be done in the upcoming CommitTransactionCommand().
2982 * We do it this way because it's not convenient to change memory context,
2983 * resource owner, etc while executing inside a Portal.
2986 EndTransactionBlock(void)
2988 TransactionState s = CurrentTransactionState;
2989 bool result = false;
2991 switch (s->blockState)
2994 * We are in a transaction block, so tell CommitTransactionCommand
2997 case TBLOCK_INPROGRESS:
2998 s->blockState = TBLOCK_END;
3003 * We are in a failed transaction block. Tell
3004 * CommitTransactionCommand it's time to exit the block.
3007 s->blockState = TBLOCK_ABORT_END;
3011 * We are in a live subtransaction block. Set up to subcommit all
3012 * open subtransactions and then commit the main transaction.
3014 case TBLOCK_SUBINPROGRESS:
3015 while (s->parent != NULL)
3017 if (s->blockState == TBLOCK_SUBINPROGRESS)
3018 s->blockState = TBLOCK_SUBEND;
3020 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3021 BlockStateAsString(s->blockState));
3024 if (s->blockState == TBLOCK_INPROGRESS)
3025 s->blockState = TBLOCK_END;
3027 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3028 BlockStateAsString(s->blockState));
3033 * Here we are inside an aborted subtransaction. Treat the COMMIT
3034 * as ROLLBACK: set up to abort everything and exit the main
3037 case TBLOCK_SUBABORT:
3038 while (s->parent != NULL)
3040 if (s->blockState == TBLOCK_SUBINPROGRESS)
3041 s->blockState = TBLOCK_SUBABORT_PENDING;
3042 else if (s->blockState == TBLOCK_SUBABORT)
3043 s->blockState = TBLOCK_SUBABORT_END;
3045 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3046 BlockStateAsString(s->blockState));
3049 if (s->blockState == TBLOCK_INPROGRESS)
3050 s->blockState = TBLOCK_ABORT_PENDING;
3051 else if (s->blockState == TBLOCK_ABORT)
3052 s->blockState = TBLOCK_ABORT_END;
3054 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3055 BlockStateAsString(s->blockState));
3059 * The user issued COMMIT when not inside a transaction. Issue a
3060 * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
3061 * CommitTransactionCommand() will then close the transaction and
3062 * put us back into the default state.
3064 case TBLOCK_STARTED:
3066 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3067 errmsg("there is no transaction in progress")));
3071 /* These cases are invalid. */
3072 case TBLOCK_DEFAULT:
3074 case TBLOCK_SUBBEGIN:
3077 case TBLOCK_ABORT_END:
3078 case TBLOCK_SUBABORT_END:
3079 case TBLOCK_ABORT_PENDING:
3080 case TBLOCK_SUBABORT_PENDING:
3081 case TBLOCK_SUBRESTART:
3082 case TBLOCK_SUBABORT_RESTART:
3083 case TBLOCK_PREPARE:
3084 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3085 BlockStateAsString(s->blockState));
3093 * UserAbortTransactionBlock
3094 * This executes a ROLLBACK command.
3096 * As above, we don't actually do anything here except change blockState.
3099 UserAbortTransactionBlock(void)
3101 TransactionState s = CurrentTransactionState;
3103 switch (s->blockState)
3106 * We are inside a transaction block and we got a ROLLBACK command
3107 * from the user, so tell CommitTransactionCommand to abort and
3108 * exit the transaction block.
3110 case TBLOCK_INPROGRESS:
3111 s->blockState = TBLOCK_ABORT_PENDING;
3115 * We are inside a failed transaction block and we got a ROLLBACK
3116 * command from the user. Abort processing is already done, so
3117 * CommitTransactionCommand just has to cleanup and go back to
3121 s->blockState = TBLOCK_ABORT_END;
3125 * We are inside a subtransaction. Mark everything up to top
3126 * level as exitable.
3128 case TBLOCK_SUBINPROGRESS:
3129 case TBLOCK_SUBABORT:
3130 while (s->parent != NULL)
3132 if (s->blockState == TBLOCK_SUBINPROGRESS)
3133 s->blockState = TBLOCK_SUBABORT_PENDING;
3134 else if (s->blockState == TBLOCK_SUBABORT)
3135 s->blockState = TBLOCK_SUBABORT_END;
3137 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3138 BlockStateAsString(s->blockState));
3141 if (s->blockState == TBLOCK_INPROGRESS)
3142 s->blockState = TBLOCK_ABORT_PENDING;
3143 else if (s->blockState == TBLOCK_ABORT)
3144 s->blockState = TBLOCK_ABORT_END;
3146 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3147 BlockStateAsString(s->blockState));
3151 * The user issued ABORT when not inside a transaction. Issue a
3152 * WARNING and go to abort state. The upcoming call to
3153 * CommitTransactionCommand() will then put us back into the
3156 case TBLOCK_STARTED:
3158 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3159 errmsg("there is no transaction in progress")));
3160 s->blockState = TBLOCK_ABORT_PENDING;
3163 /* These cases are invalid. */
3164 case TBLOCK_DEFAULT:
3166 case TBLOCK_SUBBEGIN:
3169 case TBLOCK_ABORT_END:
3170 case TBLOCK_SUBABORT_END:
3171 case TBLOCK_ABORT_PENDING:
3172 case TBLOCK_SUBABORT_PENDING:
3173 case TBLOCK_SUBRESTART:
3174 case TBLOCK_SUBABORT_RESTART:
3175 case TBLOCK_PREPARE:
3176 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3177 BlockStateAsString(s->blockState));
3184 * This executes a SAVEPOINT command.
3187 DefineSavepoint(char *name)
3189 TransactionState s = CurrentTransactionState;
3191 switch (s->blockState)
3193 case TBLOCK_INPROGRESS:
3194 case TBLOCK_SUBINPROGRESS:
3195 /* Normal subtransaction start */
3197 s = CurrentTransactionState; /* changed by push */
3200 * Savepoint names, like the TransactionState block itself, live
3201 * in TopTransactionContext.
3204 s->name = MemoryContextStrdup(TopTransactionContext, name);
3207 /* These cases are invalid. */
3208 case TBLOCK_DEFAULT:
3209 case TBLOCK_STARTED:
3211 case TBLOCK_SUBBEGIN:
3215 case TBLOCK_SUBABORT:
3216 case TBLOCK_ABORT_END:
3217 case TBLOCK_SUBABORT_END:
3218 case TBLOCK_ABORT_PENDING:
3219 case TBLOCK_SUBABORT_PENDING:
3220 case TBLOCK_SUBRESTART:
3221 case TBLOCK_SUBABORT_RESTART:
3222 case TBLOCK_PREPARE:
3223 elog(FATAL, "DefineSavepoint: unexpected state %s",
3224 BlockStateAsString(s->blockState));
3231 * This executes a RELEASE command.
3233 * As above, we don't actually do anything here except change blockState.
3236 ReleaseSavepoint(List *options)
3238 TransactionState s = CurrentTransactionState;
3239 TransactionState target,
3244 switch (s->blockState)
3247 * We can't rollback to a savepoint if there is no savepoint
3250 case TBLOCK_INPROGRESS:
3252 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3253 errmsg("no such savepoint")));
3257 * We are in a non-aborted subtransaction. This is the only valid
3260 case TBLOCK_SUBINPROGRESS:
3263 /* These cases are invalid. */
3264 case TBLOCK_DEFAULT:
3265 case TBLOCK_STARTED:
3267 case TBLOCK_SUBBEGIN:
3271 case TBLOCK_SUBABORT:
3272 case TBLOCK_ABORT_END:
3273 case TBLOCK_SUBABORT_END:
3274 case TBLOCK_ABORT_PENDING:
3275 case TBLOCK_SUBABORT_PENDING:
3276 case TBLOCK_SUBRESTART:
3277 case TBLOCK_SUBABORT_RESTART:
3278 case TBLOCK_PREPARE:
3279 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3280 BlockStateAsString(s->blockState));
3284 foreach(cell, options)
3286 DefElem *elem = lfirst(cell);
3288 if (strcmp(elem->defname, "savepoint_name") == 0)
3289 name = strVal(elem->arg);
3292 Assert(PointerIsValid(name));
3294 for (target = s; PointerIsValid(target); target = target->parent)
3296 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3300 if (!PointerIsValid(target))
3302 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3303 errmsg("no such savepoint")));
3305 /* disallow crossing savepoint level boundaries */
3306 if (target->savepointLevel != s->savepointLevel)
3308 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3309 errmsg("no such savepoint")));
3312 * Mark "commit pending" all subtransactions up to the target
3313 * subtransaction. The actual commits will happen when control gets to
3314 * CommitTransactionCommand.
3316 xact = CurrentTransactionState;
3319 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3320 xact->blockState = TBLOCK_SUBEND;
3323 xact = xact->parent;
3324 Assert(PointerIsValid(xact));
3329 * RollbackToSavepoint
3330 * This executes a ROLLBACK TO <savepoint> command.
3332 * As above, we don't actually do anything here except change blockState.
3335 RollbackToSavepoint(List *options)
3337 TransactionState s = CurrentTransactionState;
3338 TransactionState target,
3343 switch (s->blockState)
3346 * We can't rollback to a savepoint if there is no savepoint
3349 case TBLOCK_INPROGRESS:
3352 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3353 errmsg("no such savepoint")));
3357 * There is at least one savepoint, so proceed.
3359 case TBLOCK_SUBINPROGRESS:
3360 case TBLOCK_SUBABORT:
3363 /* These cases are invalid. */
3364 case TBLOCK_DEFAULT:
3365 case TBLOCK_STARTED:
3367 case TBLOCK_SUBBEGIN:
3370 case TBLOCK_ABORT_END:
3371 case TBLOCK_SUBABORT_END:
3372 case TBLOCK_ABORT_PENDING:
3373 case TBLOCK_SUBABORT_PENDING:
3374 case TBLOCK_SUBRESTART:
3375 case TBLOCK_SUBABORT_RESTART:
3376 case TBLOCK_PREPARE:
3377 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3378 BlockStateAsString(s->blockState));
3382 foreach(cell, options)
3384 DefElem *elem = lfirst(cell);
3386 if (strcmp(elem->defname, "savepoint_name") == 0)
3387 name = strVal(elem->arg);
3390 Assert(PointerIsValid(name));
3392 for (target = s; PointerIsValid(target); target = target->parent)
3394 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3398 if (!PointerIsValid(target))
3400 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3401 errmsg("no such savepoint")));
3403 /* disallow crossing savepoint level boundaries */
3404 if (target->savepointLevel != s->savepointLevel)
3406 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3407 errmsg("no such savepoint")));
3410 * Mark "abort pending" all subtransactions up to the target
3411 * subtransaction. The actual aborts will happen when control gets to
3412 * CommitTransactionCommand.
3414 xact = CurrentTransactionState;
3419 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3420 xact->blockState = TBLOCK_SUBABORT_PENDING;
3421 else if (xact->blockState == TBLOCK_SUBABORT)
3422 xact->blockState = TBLOCK_SUBABORT_END;
3424 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3425 BlockStateAsString(xact->blockState));
3426 xact = xact->parent;
3427 Assert(PointerIsValid(xact));
3430 /* And mark the target as "restart pending" */
3431 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3432 xact->blockState = TBLOCK_SUBRESTART;
3433 else if (xact->blockState == TBLOCK_SUBABORT)
3434 xact->blockState = TBLOCK_SUBABORT_RESTART;
3436 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3437 BlockStateAsString(xact->blockState));
3441 * BeginInternalSubTransaction
3442 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
3443 * TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
3444 * used in functions that might be called when not inside a BEGIN block
3445 * or when running deferred triggers at COMMIT/PREPARE time. Also, it
3446 * automatically does CommitTransactionCommand/StartTransactionCommand
3447 * instead of expecting the caller to do it.
3450 BeginInternalSubTransaction(char *name)
3452 TransactionState s = CurrentTransactionState;
3454 switch (s->blockState)
3456 case TBLOCK_STARTED:
3457 case TBLOCK_INPROGRESS:
3459 case TBLOCK_PREPARE:
3460 case TBLOCK_SUBINPROGRESS:
3461 /* Normal subtransaction start */
3463 s = CurrentTransactionState; /* changed by push */
3466 * Savepoint names, like the TransactionState block itself, live
3467 * in TopTransactionContext.
3470 s->name = MemoryContextStrdup(TopTransactionContext, name);
3473 /* These cases are invalid. */
3474 case TBLOCK_DEFAULT:
3476 case TBLOCK_SUBBEGIN:
3479 case TBLOCK_SUBABORT:
3480 case TBLOCK_ABORT_END:
3481 case TBLOCK_SUBABORT_END:
3482 case TBLOCK_ABORT_PENDING:
3483 case TBLOCK_SUBABORT_PENDING:
3484 case TBLOCK_SUBRESTART:
3485 case TBLOCK_SUBABORT_RESTART:
3486 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
3487 BlockStateAsString(s->blockState));
3491 CommitTransactionCommand();
3492 StartTransactionCommand();
3496 * ReleaseCurrentSubTransaction
3498 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
3499 * savepoint name (if any).
3500 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3503 ReleaseCurrentSubTransaction(void)
3505 TransactionState s = CurrentTransactionState;
3507 if (s->blockState != TBLOCK_SUBINPROGRESS)
3508 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
3509 BlockStateAsString(s->blockState));
3510 Assert(s->state == TRANS_INPROGRESS);
3511 MemoryContextSwitchTo(CurTransactionContext);
3512 CommitSubTransaction();
3513 s = CurrentTransactionState; /* changed by pop */
3514 Assert(s->state == TRANS_INPROGRESS);
3518 * RollbackAndReleaseCurrentSubTransaction
3520 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
3521 * of its savepoint name (if any).
3522 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3525 RollbackAndReleaseCurrentSubTransaction(void)
3527 TransactionState s = CurrentTransactionState;
3529 switch (s->blockState)
3531 /* Must be in a subtransaction */
3532 case TBLOCK_SUBINPROGRESS:
3533 case TBLOCK_SUBABORT:
3536 /* These cases are invalid. */
3537 case TBLOCK_DEFAULT:
3538 case TBLOCK_STARTED:
3540 case TBLOCK_SUBBEGIN:
3541 case TBLOCK_INPROGRESS:
3545 case TBLOCK_ABORT_END:
3546 case TBLOCK_SUBABORT_END:
3547 case TBLOCK_ABORT_PENDING:
3548 case TBLOCK_SUBABORT_PENDING:
3549 case TBLOCK_SUBRESTART:
3550 case TBLOCK_SUBABORT_RESTART:
3551 case TBLOCK_PREPARE:
3552 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
3553 BlockStateAsString(s->blockState));
3558 * Abort the current subtransaction, if needed.
3560 if (s->blockState == TBLOCK_SUBINPROGRESS)
3561 AbortSubTransaction();
3563 /* And clean it up, too */
3564 CleanupSubTransaction();
3566 s = CurrentTransactionState; /* changed by pop */
3567 AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
3568 s->blockState == TBLOCK_INPROGRESS ||
3569 s->blockState == TBLOCK_STARTED);
3573 * AbortOutOfAnyTransaction
3575 * This routine is provided for error recovery purposes. It aborts any
3576 * active transaction or transaction block, leaving the system in a known
3580 AbortOutOfAnyTransaction(void)
3582 TransactionState s = CurrentTransactionState;
3585 * Get out of any transaction or nested transaction
3589 switch (s->blockState)
3591 case TBLOCK_DEFAULT:
3592 /* Not in a transaction, do nothing */
3594 case TBLOCK_STARTED:
3596 case TBLOCK_INPROGRESS:
3598 case TBLOCK_ABORT_PENDING:
3599 case TBLOCK_PREPARE:
3600 /* In a transaction, so clean up */
3602 CleanupTransaction();
3603 s->blockState = TBLOCK_DEFAULT;
3606 case TBLOCK_ABORT_END:
3607 /* AbortTransaction already done, still need Cleanup */
3608 CleanupTransaction();
3609 s->blockState = TBLOCK_DEFAULT;
3613 * In a subtransaction, so clean it up and abort parent too
3615 case TBLOCK_SUBBEGIN:
3616 case TBLOCK_SUBINPROGRESS:
3618 case TBLOCK_SUBABORT_PENDING:
3619 case TBLOCK_SUBRESTART:
3620 AbortSubTransaction();
3621 CleanupSubTransaction();
3622 s = CurrentTransactionState; /* changed by pop */
3625 case TBLOCK_SUBABORT:
3626 case TBLOCK_SUBABORT_END:
3627 case TBLOCK_SUBABORT_RESTART:
3628 /* As above, but AbortSubTransaction already done */
3629 CleanupSubTransaction();
3630 s = CurrentTransactionState; /* changed by pop */
3633 } while (s->blockState != TBLOCK_DEFAULT);
3635 /* Should be out of all subxacts now */
3636 Assert(s->parent == NULL);
3640 * IsTransactionBlock --- are we within a transaction block?
3643 IsTransactionBlock(void)
3645 TransactionState s = CurrentTransactionState;
3647 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
3654 * IsTransactionOrTransactionBlock --- are we within either a transaction
3655 * or a transaction block? (The backend is only really "idle" when this
3658 * This should match up with IsTransactionBlock and IsTransactionState.
3661 IsTransactionOrTransactionBlock(void)
3663 TransactionState s = CurrentTransactionState;
3665 if (s->blockState == TBLOCK_DEFAULT)
3672 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
3675 TransactionBlockStatusCode(void)
3677 TransactionState s = CurrentTransactionState;
3679 switch (s->blockState)
3681 case TBLOCK_DEFAULT:
3682 case TBLOCK_STARTED:
3683 return 'I'; /* idle --- not in transaction */
3685 case TBLOCK_SUBBEGIN:
3686 case TBLOCK_INPROGRESS:
3687 case TBLOCK_SUBINPROGRESS:
3690 case TBLOCK_PREPARE:
3691 return 'T'; /* in transaction */
3693 case TBLOCK_SUBABORT:
3694 case TBLOCK_ABORT_END:
3695 case TBLOCK_SUBABORT_END:
3696 case TBLOCK_ABORT_PENDING:
3697 case TBLOCK_SUBABORT_PENDING:
3698 case TBLOCK_SUBRESTART:
3699 case TBLOCK_SUBABORT_RESTART:
3700 return 'E'; /* in failed transaction */
3703 /* should never get here */
3704 elog(FATAL, "invalid transaction block state: %s",
3705 BlockStateAsString(s->blockState));
3706 return 0; /* keep compiler quiet */
3713 IsSubTransaction(void)
3715 TransactionState s = CurrentTransactionState;
3717 if (s->nestingLevel >= 2)
3724 * StartSubTransaction
3726 * If you're wondering why this is separate from PushTransaction: it's because
3727 * we can't conveniently do this stuff right inside DefineSavepoint. The
3728 * SAVEPOINT utility command will be executed inside a Portal, and if we
3729 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
3730 * the Portal will undo those settings. So we make DefineSavepoint just
3731 * push a dummy transaction block, and when control returns to the main
3732 * idle loop, CommitTransactionCommand will be called, and we'll come here
3733 * to finish starting the subtransaction.
3736 StartSubTransaction(void)
3738 TransactionState s = CurrentTransactionState;
3740 if (s->state != TRANS_DEFAULT)
3741 elog(WARNING, "StartSubTransaction while in %s state",
3742 TransStateAsString(s->state));
3744 s->state = TRANS_START;
3747 * Initialize subsystems for new subtransaction
3749 * must initialize resource-management stuff first
3751 AtSubStart_Memory();
3752 AtSubStart_ResourceOwner();
3754 AtSubStart_Notify();
3755 AfterTriggerBeginSubXact();
3757 s->state = TRANS_INPROGRESS;
3760 * Call start-of-subxact callbacks
3762 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
3763 s->parent->subTransactionId);
3765 ShowTransactionState("StartSubTransaction");
3769 * CommitSubTransaction
3771 * The caller has to make sure to always reassign CurrentTransactionState
3772 * if it has a local pointer to it after calling this function.
3775 CommitSubTransaction(void)
3777 TransactionState s = CurrentTransactionState;
3779 ShowTransactionState("CommitSubTransaction");
3781 if (s->state != TRANS_INPROGRESS)
3782 elog(WARNING, "CommitSubTransaction while in %s state",
3783 TransStateAsString(s->state));
3785 /* Pre-commit processing goes here -- nothing to do at the moment */
3787 s->state = TRANS_COMMIT;
3789 /* Must CCI to ensure commands of subtransaction are seen as done */
3790 CommandCounterIncrement();
3792 /* Mark subtransaction as subcommitted */
3793 RecordSubTransactionCommit();
3795 /* Post-commit cleanup */
3796 if (TransactionIdIsValid(s->transactionId))
3797 AtSubCommit_childXids();
3798 AfterTriggerEndSubXact(true);
3799 AtSubCommit_Portals(s->subTransactionId,
3800 s->parent->subTransactionId,
3801 s->parent->curTransactionOwner);
3802 AtEOSubXact_LargeObject(true, s->subTransactionId,
3803 s->parent->subTransactionId);
3804 AtSubCommit_Notify();
3805 AtEOSubXact_UpdateFlatFiles(true, s->subTransactionId,
3806 s->parent->subTransactionId);
3808 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
3809 s->parent->subTransactionId);
3811 ResourceOwnerRelease(s->curTransactionOwner,
3812 RESOURCE_RELEASE_BEFORE_LOCKS,
3814 AtEOSubXact_RelationCache(true, s->subTransactionId,
3815 s->parent->subTransactionId);
3816 AtEOSubXact_Inval(true);
3820 * The only lock we actually release here is the subtransaction XID lock.
3821 * The rest just get transferred to the parent resource owner.
3823 CurrentResourceOwner = s->curTransactionOwner;
3824 if (TransactionIdIsValid(s->transactionId))
3825 XactLockTableDelete(s->transactionId);
3827 ResourceOwnerRelease(s->curTransactionOwner,
3828 RESOURCE_RELEASE_LOCKS,
3830 ResourceOwnerRelease(s->curTransactionOwner,
3831 RESOURCE_RELEASE_AFTER_LOCKS,
3834 AtEOXact_GUC(true, s->gucNestLevel);
3835 AtEOSubXact_SPI(true, s->subTransactionId);
3836 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
3837 s->parent->subTransactionId);
3838 AtEOSubXact_Namespace(true, s->subTransactionId,
3839 s->parent->subTransactionId);
3840 AtEOSubXact_Files(true, s->subTransactionId,
3841 s->parent->subTransactionId);
3842 AtEOSubXact_HashTables(true, s->nestingLevel);
3843 AtEOSubXact_PgStat(true, s->nestingLevel);
3846 * We need to restore the upper transaction's read-only state, in case the
3847 * upper is read-write while the child is read-only; GUC will incorrectly
3848 * think it should leave the child state in place.
3850 XactReadOnly = s->prevXactReadOnly;
3852 CurrentResourceOwner = s->parent->curTransactionOwner;
3853 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3854 ResourceOwnerDelete(s->curTransactionOwner);
3855 s->curTransactionOwner = NULL;
3857 AtSubCommit_Memory();
3859 s->state = TRANS_DEFAULT;
3865 * AbortSubTransaction
3868 AbortSubTransaction(void)
3870 TransactionState s = CurrentTransactionState;
3872 /* Prevent cancel/die interrupt while cleaning up */
3875 /* Make sure we have a valid memory context and resource owner */
3876 AtSubAbort_Memory();
3877 AtSubAbort_ResourceOwner();
3880 * Release any LW locks we might be holding as quickly as possible.
3881 * (Regular locks, however, must be held till we finish aborting.)
3882 * Releasing LW locks is critical since we might try to grab them again
3883 * while cleaning up!
3885 * FIXME This may be incorrect --- Are there some locks we should keep?
3886 * Buffer locks, for example? I don't think so but I'm not sure.
3896 * check the current transaction state
3898 ShowTransactionState("AbortSubTransaction");
3900 if (s->state != TRANS_INPROGRESS)
3901 elog(WARNING, "AbortSubTransaction while in %s state",
3902 TransStateAsString(s->state));
3904 s->state = TRANS_ABORT;
3907 * Reset user ID which might have been changed transiently. (See notes
3908 * in AbortTransaction.)
3910 SetUserIdAndContext(s->prevUser, s->prevSecDefCxt);
3913 * We can skip all this stuff if the subxact failed before creating a
3916 if (s->curTransactionOwner)
3918 AfterTriggerEndSubXact(false);
3919 AtSubAbort_Portals(s->subTransactionId,
3920 s->parent->subTransactionId,
3921 s->parent->curTransactionOwner);
3922 AtEOSubXact_LargeObject(false, s->subTransactionId,
3923 s->parent->subTransactionId);
3924 AtSubAbort_Notify();
3925 AtEOSubXact_UpdateFlatFiles(false, s->subTransactionId,
3926 s->parent->subTransactionId);
3928 /* Advertise the fact that we aborted in pg_clog. */
3929 (void) RecordTransactionAbort(true);
3931 /* Post-abort cleanup */
3932 if (TransactionIdIsValid(s->transactionId))
3933 AtSubAbort_childXids();
3935 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
3936 s->parent->subTransactionId);
3938 ResourceOwnerRelease(s->curTransactionOwner,
3939 RESOURCE_RELEASE_BEFORE_LOCKS,
3941 AtEOSubXact_RelationCache(false, s->subTransactionId,
3942 s->parent->subTransactionId);
3943 AtEOSubXact_Inval(false);
3945 ResourceOwnerRelease(s->curTransactionOwner,
3946 RESOURCE_RELEASE_LOCKS,
3948 ResourceOwnerRelease(s->curTransactionOwner,
3949 RESOURCE_RELEASE_AFTER_LOCKS,
3952 AtEOXact_GUC(false, s->gucNestLevel);
3953 AtEOSubXact_SPI(false, s->subTransactionId);
3955 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
3956 s->parent->subTransactionId);
3957 AtEOSubXact_Namespace(false, s->subTransactionId,
3958 s->parent->subTransactionId);
3959 AtEOSubXact_Files(false, s->subTransactionId,
3960 s->parent->subTransactionId);
3961 AtEOSubXact_HashTables(false, s->nestingLevel);
3962 AtEOSubXact_PgStat(false, s->nestingLevel);
3966 * Restore the upper transaction's read-only state, too. This should be
3967 * redundant with GUC's cleanup but we may as well do it for consistency
3968 * with the commit case.
3970 XactReadOnly = s->prevXactReadOnly;
3972 RESUME_INTERRUPTS();
3976 * CleanupSubTransaction
3978 * The caller has to make sure to always reassign CurrentTransactionState
3979 * if it has a local pointer to it after calling this function.
3982 CleanupSubTransaction(void)
3984 TransactionState s = CurrentTransactionState;
3986 ShowTransactionState("CleanupSubTransaction");
3988 if (s->state != TRANS_ABORT)
3989 elog(WARNING, "CleanupSubTransaction while in %s state",
3990 TransStateAsString(s->state));
3992 AtSubCleanup_Portals(s->subTransactionId);
3994 CurrentResourceOwner = s->parent->curTransactionOwner;
3995 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3996 if (s->curTransactionOwner)
3997 ResourceOwnerDelete(s->curTransactionOwner);
3998 s->curTransactionOwner = NULL;
4000 AtSubCleanup_Memory();
4002 s->state = TRANS_DEFAULT;
4009 * Create transaction state stack entry for a subtransaction
4011 * The caller has to make sure to always reassign CurrentTransactionState
4012 * if it has a local pointer to it after calling this function.
4015 PushTransaction(void)
4017 TransactionState p = CurrentTransactionState;
4021 * We keep subtransaction state nodes in TopTransactionContext.
4023 s = (TransactionState)
4024 MemoryContextAllocZero(TopTransactionContext,
4025 sizeof(TransactionStateData));
4028 * Assign a subtransaction ID, watching out for counter wraparound.
4030 currentSubTransactionId += 1;
4031 if (currentSubTransactionId == InvalidSubTransactionId)
4033 currentSubTransactionId -= 1;
4036 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
4037 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
4041 * We can now stack a minimally valid subtransaction without fear of
4044 s->transactionId = InvalidTransactionId; /* until assigned */
4045 s->subTransactionId = currentSubTransactionId;
4047 s->nestingLevel = p->nestingLevel + 1;
4048 s->gucNestLevel = NewGUCNestLevel();
4049 s->savepointLevel = p->savepointLevel;
4050 s->state = TRANS_DEFAULT;
4051 s->blockState = TBLOCK_SUBBEGIN;
4052 GetUserIdAndContext(&s->prevUser, &s->prevSecDefCxt);
4053 s->prevXactReadOnly = XactReadOnly;
4055 CurrentTransactionState = s;
4058 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
4059 * with the subtransaction from here on out; in particular they should not
4060 * assume that it necessarily has a transaction context, resource owner,
4067 * Pop back to parent transaction state
4069 * The caller has to make sure to always reassign CurrentTransactionState
4070 * if it has a local pointer to it after calling this function.
4073 PopTransaction(void)
4075 TransactionState s = CurrentTransactionState;
4077 if (s->state != TRANS_DEFAULT)
4078 elog(WARNING, "PopTransaction while in %s state",
4079 TransStateAsString(s->state));
4081 if (s->parent == NULL)
4082 elog(FATAL, "PopTransaction with no parent");
4084 CurrentTransactionState = s->parent;
4086 /* Let's just make sure CurTransactionContext is good */
4087 CurTransactionContext = s->parent->curTransactionContext;
4088 MemoryContextSwitchTo(CurTransactionContext);
4090 /* Ditto for ResourceOwner links */
4091 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4092 CurrentResourceOwner = s->parent->curTransactionOwner;
4094 /* Free the old child structure */
4101 * ShowTransactionState
4105 ShowTransactionState(const char *str)
4107 /* skip work if message will definitely not be printed */
4108 if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
4110 elog(DEBUG3, "%s", str);
4111 ShowTransactionStateRec(CurrentTransactionState);
4116 * ShowTransactionStateRec
4117 * Recursive subroutine for ShowTransactionState
4120 ShowTransactionStateRec(TransactionState s)
4124 initStringInfo(&buf);
4126 if (s->nChildXids > 0)
4130 appendStringInfo(&buf, "%u", s->childXids[0]);
4131 for (i = 1; i < s->nChildXids; i++)
4132 appendStringInfo(&buf, " %u", s->childXids[i]);
4136 ShowTransactionStateRec(s->parent);
4138 /* use ereport to suppress computation if msg will not be printed */
4140 (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u%s, nestlvl: %d, children: %s",
4141 PointerIsValid(s->name) ? s->name : "unnamed",
4142 BlockStateAsString(s->blockState),
4143 TransStateAsString(s->state),
4144 (unsigned int) s->transactionId,
4145 (unsigned int) s->subTransactionId,
4146 (unsigned int) currentCommandId,
4147 currentCommandIdUsed ? " (used)" : "",
4148 s->nestingLevel, buf.data)));
4154 * BlockStateAsString
4158 BlockStateAsString(TBlockState blockState)
4162 case TBLOCK_DEFAULT:
4164 case TBLOCK_STARTED:
4168 case TBLOCK_INPROGRESS:
4169 return "INPROGRESS";
4174 case TBLOCK_ABORT_END:
4176 case TBLOCK_ABORT_PENDING:
4177 return "ABORT PEND";
4178 case TBLOCK_PREPARE:
4180 case TBLOCK_SUBBEGIN:
4182 case TBLOCK_SUBINPROGRESS:
4183 return "SUB INPROGRS";
4186 case TBLOCK_SUBABORT:
4188 case TBLOCK_SUBABORT_END:
4189 return "SUB ABORT END";
4190 case TBLOCK_SUBABORT_PENDING:
4191 return "SUB ABRT PEND";
4192 case TBLOCK_SUBRESTART:
4193 return "SUB RESTART";
4194 case TBLOCK_SUBABORT_RESTART:
4195 return "SUB AB RESTRT";
4197 return "UNRECOGNIZED";
4201 * TransStateAsString
4205 TransStateAsString(TransState state)
4213 case TRANS_INPROGRESS:
4222 return "UNRECOGNIZED";
4226 * xactGetCommittedChildren
4228 * Gets the list of committed children of the current transaction. The return
4229 * value is the number of child transactions. *ptr is set to point to an
4230 * array of TransactionIds. The array is allocated in TopTransactionContext;
4231 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
4232 * If there are no subxacts, *ptr is set to NULL.
4235 xactGetCommittedChildren(TransactionId **ptr)
4237 TransactionState s = CurrentTransactionState;
4239 if (s->nChildXids == 0)
4242 *ptr = s->childXids;
4244 return s->nChildXids;
4248 * XLOG support routines
4252 xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid)
4254 TransactionId *sub_xids;
4255 TransactionId max_xid;
4258 TransactionIdCommit(xid);
4260 /* Mark committed subtransactions as committed */
4261 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4262 TransactionIdCommitTree(xlrec->nsubxacts, sub_xids);
4264 /* Make sure nextXid is beyond any XID mentioned in the record */
4266 for (i = 0; i < xlrec->nsubxacts; i++)
4268 if (TransactionIdPrecedes(max_xid, sub_xids[i]))
4269 max_xid = sub_xids[i];
4271 if (TransactionIdFollowsOrEquals(max_xid,
4272 ShmemVariableCache->nextXid))
4274 ShmemVariableCache->nextXid = max_xid;
4275 TransactionIdAdvance(ShmemVariableCache->nextXid);
4278 /* Make sure files supposed to be dropped are dropped */
4279 for (i = 0; i < xlrec->nrels; i++)
4281 XLogDropRelation(xlrec->xnodes[i]);
4282 smgrdounlink(smgropen(xlrec->xnodes[i]), false, true);
4287 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
4289 TransactionId *sub_xids;
4290 TransactionId max_xid;
4293 TransactionIdAbort(xid);
4295 /* Mark subtransactions as aborted */
4296 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4297 TransactionIdAbortTree(xlrec->nsubxacts, sub_xids);
4299 /* Make sure nextXid is beyond any XID mentioned in the record */
4301 for (i = 0; i < xlrec->nsubxacts; i++)
4303 if (TransactionIdPrecedes(max_xid, sub_xids[i]))
4304 max_xid = sub_xids[i];
4306 if (TransactionIdFollowsOrEquals(max_xid,
4307 ShmemVariableCache->nextXid))
4309 ShmemVariableCache->nextXid = max_xid;
4310 TransactionIdAdvance(ShmemVariableCache->nextXid);
4313 /* Make sure files supposed to be dropped are dropped */
4314 for (i = 0; i < xlrec->nrels; i++)
4316 XLogDropRelation(xlrec->xnodes[i]);
4317 smgrdounlink(smgropen(xlrec->xnodes[i]), false, true);
4322 xact_redo(XLogRecPtr lsn, XLogRecord *record)
4324 uint8 info = record->xl_info & ~XLR_INFO_MASK;
4326 if (info == XLOG_XACT_COMMIT)
4328 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
4330 xact_redo_commit(xlrec, record->xl_xid);
4332 else if (info == XLOG_XACT_ABORT)
4334 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
4336 xact_redo_abort(xlrec, record->xl_xid);
4338 else if (info == XLOG_XACT_PREPARE)
4340 /* the record contents are exactly the 2PC file */
4341 RecreateTwoPhaseFile(record->xl_xid,
4342 XLogRecGetData(record), record->xl_len);
4344 else if (info == XLOG_XACT_COMMIT_PREPARED)
4346 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
4348 xact_redo_commit(&xlrec->crec, xlrec->xid);
4349 RemoveTwoPhaseFile(xlrec->xid, false);
4351 else if (info == XLOG_XACT_ABORT_PREPARED)
4353 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
4355 xact_redo_abort(&xlrec->arec, xlrec->xid);
4356 RemoveTwoPhaseFile(xlrec->xid, false);
4359 elog(PANIC, "xact_redo: unknown op code %u", info);
4363 xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
4367 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4368 if (xlrec->nrels > 0)
4370 appendStringInfo(buf, "; rels:");
4371 for (i = 0; i < xlrec->nrels; i++)
4373 RelFileNode rnode = xlrec->xnodes[i];
4375 appendStringInfo(buf, " %u/%u/%u",
4376 rnode.spcNode, rnode.dbNode, rnode.relNode);
4379 if (xlrec->nsubxacts > 0)
4381 TransactionId *xacts = (TransactionId *)
4382 &xlrec->xnodes[xlrec->nrels];
4384 appendStringInfo(buf, "; subxacts:");
4385 for (i = 0; i < xlrec->nsubxacts; i++)
4386 appendStringInfo(buf, " %u", xacts[i]);
4391 xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
4395 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4396 if (xlrec->nrels > 0)
4398 appendStringInfo(buf, "; rels:");
4399 for (i = 0; i < xlrec->nrels; i++)
4401 RelFileNode rnode = xlrec->xnodes[i];
4403 appendStringInfo(buf, " %u/%u/%u",
4404 rnode.spcNode, rnode.dbNode, rnode.relNode);
4407 if (xlrec->nsubxacts > 0)
4409 TransactionId *xacts = (TransactionId *)
4410 &xlrec->xnodes[xlrec->nrels];
4412 appendStringInfo(buf, "; subxacts:");
4413 for (i = 0; i < xlrec->nsubxacts; i++)
4414 appendStringInfo(buf, " %u", xacts[i]);
4419 xact_desc(StringInfo buf, uint8 xl_info, char *rec)
4421 uint8 info = xl_info & ~XLR_INFO_MASK;
4423 if (info == XLOG_XACT_COMMIT)
4425 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
4427 appendStringInfo(buf, "commit: ");
4428 xact_desc_commit(buf, xlrec);
4430 else if (info == XLOG_XACT_ABORT)
4432 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
4434 appendStringInfo(buf, "abort: ");
4435 xact_desc_abort(buf, xlrec);
4437 else if (info == XLOG_XACT_PREPARE)
4439 appendStringInfo(buf, "prepare");
4441 else if (info == XLOG_XACT_COMMIT_PREPARED)
4443 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
4445 appendStringInfo(buf, "commit %u: ", xlrec->xid);
4446 xact_desc_commit(buf, &xlrec->crec);
4448 else if (info == XLOG_XACT_ABORT_PREPARED)
4450 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
4452 appendStringInfo(buf, "abort %u: ", xlrec->xid);
4453 xact_desc_abort(buf, &xlrec->arec);
4456 appendStringInfo(buf, "UNKNOWN");