1 /*-------------------------------------------------------------------------
4 * top level transaction system support routines
6 * See src/backend/access/transam/README for more information.
8 * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
13 * src/backend/access/transam/xact.c
15 *-------------------------------------------------------------------------
23 #include "access/multixact.h"
24 #include "access/subtrans.h"
25 #include "access/transam.h"
26 #include "access/twophase.h"
27 #include "access/xact.h"
28 #include "access/xlogutils.h"
29 #include "catalog/catalog.h"
30 #include "catalog/namespace.h"
31 #include "catalog/storage.h"
32 #include "commands/async.h"
33 #include "commands/tablecmds.h"
34 #include "commands/trigger.h"
35 #include "executor/spi.h"
36 #include "libpq/be-fsstubs.h"
37 #include "miscadmin.h"
39 #include "replication/walsender.h"
40 #include "replication/syncrep.h"
41 #include "storage/lmgr.h"
42 #include "storage/predicate.h"
43 #include "storage/procarray.h"
44 #include "storage/sinvaladt.h"
45 #include "storage/smgr.h"
46 #include "utils/combocid.h"
47 #include "utils/guc.h"
48 #include "utils/inval.h"
49 #include "utils/memutils.h"
50 #include "utils/relmapper.h"
51 #include "utils/snapmgr.h"
56 * User-tweakable parameters
58 int DefaultXactIsoLevel = XACT_READ_COMMITTED;
61 bool DefaultXactReadOnly = false;
64 bool DefaultXactDeferrable = false;
67 int synchronous_commit = SYNCHRONOUS_COMMIT_ON;
69 int CommitDelay = 0; /* precommit delay in microseconds */
70 int CommitSiblings = 5; /* # concurrent xacts needed to sleep */
73 * MyXactAccessedTempRel is set when a temporary relation is accessed.
74 * We don't allow PREPARE TRANSACTION in that case. (This is global
75 * so that it can be set from heapam.c.)
77 bool MyXactAccessedTempRel = false;
81 * transaction states - transaction state from server perspective
83 typedef enum TransState
85 TRANS_DEFAULT, /* idle */
86 TRANS_START, /* transaction starting */
87 TRANS_INPROGRESS, /* inside a valid transaction */
88 TRANS_COMMIT, /* commit in progress */
89 TRANS_ABORT, /* abort in progress */
90 TRANS_PREPARE /* prepare in progress */
94 * transaction block states - transaction state of client queries
96 * Note: the subtransaction states are used only for non-topmost
97 * transactions; the others appear only in the topmost transaction.
99 typedef enum TBlockState
101 /* not-in-transaction-block states */
102 TBLOCK_DEFAULT, /* idle */
103 TBLOCK_STARTED, /* running single-query transaction */
105 /* transaction block states */
106 TBLOCK_BEGIN, /* starting transaction block */
107 TBLOCK_INPROGRESS, /* live transaction */
108 TBLOCK_END, /* COMMIT received */
109 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
110 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
111 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
112 TBLOCK_PREPARE, /* live xact, PREPARE received */
114 /* subtransaction states */
115 TBLOCK_SUBBEGIN, /* starting a subtransaction */
116 TBLOCK_SUBINPROGRESS, /* live subtransaction */
117 TBLOCK_SUBRELEASE, /* RELEASE received */
118 TBLOCK_SUBCOMMIT, /* COMMIT received while TBLOCK_SUBINPROGRESS */
119 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
120 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
121 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
122 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
123 TBLOCK_SUBABORT_RESTART /* failed subxact, ROLLBACK TO received */
127 * transaction state structure
129 typedef struct TransactionStateData
131 TransactionId transactionId; /* my XID, or Invalid if none */
132 SubTransactionId subTransactionId; /* my subxact ID */
133 char *name; /* savepoint name, if any */
134 int savepointLevel; /* savepoint level */
135 TransState state; /* low-level state */
136 TBlockState blockState; /* high-level state */
137 int nestingLevel; /* transaction nesting depth */
138 int gucNestLevel; /* GUC context nesting depth */
139 MemoryContext curTransactionContext; /* my xact-lifetime context */
140 ResourceOwner curTransactionOwner; /* my query resources */
141 TransactionId *childXids; /* subcommitted child XIDs, in XID order */
142 int nChildXids; /* # of subcommitted child XIDs */
143 int maxChildXids; /* allocated size of childXids[] */
144 Oid prevUser; /* previous CurrentUserId setting */
145 int prevSecContext; /* previous SecurityRestrictionContext */
146 bool prevXactReadOnly; /* entry-time xact r/o state */
147 bool startedInRecovery; /* did we start in recovery? */
148 struct TransactionStateData *parent; /* back link to parent */
149 } TransactionStateData;
151 typedef TransactionStateData *TransactionState;
154 * CurrentTransactionState always points to the current transaction state
155 * block. It will point to TopTransactionStateData when not in a
156 * transaction at all, or when in a top-level transaction.
158 static TransactionStateData TopTransactionStateData = {
159 0, /* transaction id */
160 0, /* subtransaction id */
161 NULL, /* savepoint name */
162 0, /* savepoint level */
163 TRANS_DEFAULT, /* transaction state */
164 TBLOCK_DEFAULT, /* transaction block state from the client
166 0, /* transaction nesting depth */
167 0, /* GUC context nesting depth */
168 NULL, /* cur transaction context */
169 NULL, /* cur transaction resource owner */
170 NULL, /* subcommitted child Xids */
171 0, /* # of subcommitted child Xids */
172 0, /* allocated size of childXids[] */
173 InvalidOid, /* previous CurrentUserId setting */
174 0, /* previous SecurityRestrictionContext */
175 false, /* entry-time xact r/o state */
176 false, /* startedInRecovery */
177 NULL /* link to parent state block */
181 * unreportedXids holds XIDs of all subtransactions that have not yet been
182 * reported in a XLOG_XACT_ASSIGNMENT record.
184 static int nUnreportedXids;
185 static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS];
187 static TransactionState CurrentTransactionState = &TopTransactionStateData;
190 * The subtransaction ID and command ID assignment counters are global
191 * to a whole transaction, so we do not keep them in the state stack.
193 static SubTransactionId currentSubTransactionId;
194 static CommandId currentCommandId;
195 static bool currentCommandIdUsed;
198 * xactStartTimestamp is the value of transaction_timestamp().
199 * stmtStartTimestamp is the value of statement_timestamp().
200 * xactStopTimestamp is the time at which we log a commit or abort WAL record.
201 * These do not change as we enter and exit subtransactions, so we don't
202 * keep them inside the TransactionState stack.
204 static TimestampTz xactStartTimestamp;
205 static TimestampTz stmtStartTimestamp;
206 static TimestampTz xactStopTimestamp;
209 * GID to be used for preparing the current transaction. This is also
210 * global to a whole transaction, so we don't keep it in the state stack.
212 static char *prepareGID;
215 * Some commands want to force synchronous commit.
217 static bool forceSyncCommit = false;
220 * Private context for transaction-abort work --- we reserve space for this
221 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
222 * when we've run out of memory.
224 static MemoryContext TransactionAbortContext = NULL;
227 * List of add-on start- and end-of-xact callbacks
229 typedef struct XactCallbackItem
231 struct XactCallbackItem *next;
232 XactCallback callback;
236 static XactCallbackItem *Xact_callbacks = NULL;
239 * List of add-on start- and end-of-subxact callbacks
241 typedef struct SubXactCallbackItem
243 struct SubXactCallbackItem *next;
244 SubXactCallback callback;
246 } SubXactCallbackItem;
248 static SubXactCallbackItem *SubXact_callbacks = NULL;
251 /* local function prototypes */
252 static void AssignTransactionId(TransactionState s);
253 static void AbortTransaction(void);
254 static void AtAbort_Memory(void);
255 static void AtCleanup_Memory(void);
256 static void AtAbort_ResourceOwner(void);
257 static void AtCCI_LocalCache(void);
258 static void AtCommit_Memory(void);
259 static void AtStart_Cache(void);
260 static void AtStart_Memory(void);
261 static void AtStart_ResourceOwner(void);
262 static void CallXactCallbacks(XactEvent event);
263 static void CallSubXactCallbacks(SubXactEvent event,
264 SubTransactionId mySubid,
265 SubTransactionId parentSubid);
266 static void CleanupTransaction(void);
267 static void CommitTransaction(void);
268 static TransactionId RecordTransactionAbort(bool isSubXact);
269 static void StartTransaction(void);
271 static void StartSubTransaction(void);
272 static void CommitSubTransaction(void);
273 static void AbortSubTransaction(void);
274 static void CleanupSubTransaction(void);
275 static void PushTransaction(void);
276 static void PopTransaction(void);
278 static void AtSubAbort_Memory(void);
279 static void AtSubCleanup_Memory(void);
280 static void AtSubAbort_ResourceOwner(void);
281 static void AtSubCommit_Memory(void);
282 static void AtSubStart_Memory(void);
283 static void AtSubStart_ResourceOwner(void);
285 static void ShowTransactionState(const char *str);
286 static void ShowTransactionStateRec(TransactionState state);
287 static const char *BlockStateAsString(TBlockState blockState);
288 static const char *TransStateAsString(TransState state);
291 /* ----------------------------------------------------------------
292 * transaction state accessors
293 * ----------------------------------------------------------------
299 * This returns true if we are inside a valid transaction; that is,
300 * it is safe to initiate database access, take heavyweight locks, etc.
303 IsTransactionState(void)
305 TransactionState s = CurrentTransactionState;
308 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
309 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
310 * TRANS_PREPARE since it might be too soon or too late within those
311 * transition states to do anything interesting. Hence, the only "valid"
312 * state is TRANS_INPROGRESS.
314 return (s->state == TRANS_INPROGRESS);
318 * IsAbortedTransactionBlockState
320 * This returns true if we are within an aborted transaction block.
323 IsAbortedTransactionBlockState(void)
325 TransactionState s = CurrentTransactionState;
327 if (s->blockState == TBLOCK_ABORT ||
328 s->blockState == TBLOCK_SUBABORT)
336 * GetTopTransactionId
338 * This will return the XID of the main transaction, assigning one if
339 * it's not yet set. Be careful to call this only inside a valid xact.
342 GetTopTransactionId(void)
344 if (!TransactionIdIsValid(TopTransactionStateData.transactionId))
345 AssignTransactionId(&TopTransactionStateData);
346 return TopTransactionStateData.transactionId;
350 * GetTopTransactionIdIfAny
352 * This will return the XID of the main transaction, if one is assigned.
353 * It will return InvalidTransactionId if we are not currently inside a
354 * transaction, or inside a transaction that hasn't yet been assigned an XID.
357 GetTopTransactionIdIfAny(void)
359 return TopTransactionStateData.transactionId;
363 * GetCurrentTransactionId
365 * This will return the XID of the current transaction (main or sub
366 * transaction), assigning one if it's not yet set. Be careful to call this
367 * only inside a valid xact.
370 GetCurrentTransactionId(void)
372 TransactionState s = CurrentTransactionState;
374 if (!TransactionIdIsValid(s->transactionId))
375 AssignTransactionId(s);
376 return s->transactionId;
380 * GetCurrentTransactionIdIfAny
382 * This will return the XID of the current sub xact, if one is assigned.
383 * It will return InvalidTransactionId if we are not currently inside a
384 * transaction, or inside a transaction that hasn't been assigned an XID yet.
387 GetCurrentTransactionIdIfAny(void)
389 return CurrentTransactionState->transactionId;
394 * AssignTransactionId
396 * Assigns a new permanent XID to the given TransactionState.
397 * We do not assign XIDs to transactions until/unless this is called.
398 * Also, any parent TransactionStates that don't yet have XIDs are assigned
399 * one; this maintains the invariant that a child transaction has an XID
400 * following its parent's.
403 AssignTransactionId(TransactionState s)
405 bool isSubXact = (s->parent != NULL);
406 ResourceOwner currentOwner;
408 /* Assert that caller didn't screw up */
409 Assert(!TransactionIdIsValid(s->transactionId));
410 Assert(s->state == TRANS_INPROGRESS);
413 * Ensure parent(s) have XIDs, so that a child always has an XID later
414 * than its parent. Musn't recurse here, or we might get a stack overflow
415 * if we're at the bottom of a huge stack of subtransactions none of which
418 if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
420 TransactionState p = s->parent;
421 TransactionState *parents;
422 size_t parentOffset = 0;
424 parents = palloc(sizeof(TransactionState) * s->nestingLevel);
425 while (p != NULL && !TransactionIdIsValid(p->transactionId))
427 parents[parentOffset++] = p;
432 * This is technically a recursive call, but the recursion will never
433 * be more than one layer deep.
435 while (parentOffset != 0)
436 AssignTransactionId(parents[--parentOffset]);
442 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
444 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
445 * shared storage other than PG_PROC; because if there's no room for it in
446 * PG_PROC, the subtrans entry is needed to ensure that other backends see
447 * the Xid as "running". See GetNewTransactionId.
449 s->transactionId = GetNewTransactionId(isSubXact);
452 SubTransSetParent(s->transactionId, s->parent->transactionId, false);
455 * If it's a top-level transaction, the predicate locking system needs to
456 * be told about it too.
459 RegisterPredicateLockingXid(s->transactionId);
462 * Acquire lock on the transaction XID. (We assume this cannot block.) We
463 * have to ensure that the lock is assigned to the transaction's own
466 currentOwner = CurrentResourceOwner;
469 CurrentResourceOwner = s->curTransactionOwner;
470 XactLockTableInsert(s->transactionId);
474 /* Ensure CurrentResourceOwner is restored on error */
475 CurrentResourceOwner = currentOwner;
479 CurrentResourceOwner = currentOwner;
482 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
483 * top-level transaction we issue a WAL record for the assignment. We
484 * include the top-level xid and all the subxids that have not yet been
485 * reported using XLOG_XACT_ASSIGNMENT records.
487 * This is required to limit the amount of shared memory required in a hot
488 * standby server to keep track of in-progress XIDs. See notes for
489 * RecordKnownAssignedTransactionIds().
491 * We don't keep track of the immediate parent of each subxid, only the
492 * top-level transaction that each subxact belongs to. This is correct in
493 * recovery only because aborted subtransactions are separately WAL
496 if (isSubXact && XLogStandbyInfoActive())
498 unreportedXids[nUnreportedXids] = s->transactionId;
502 * ensure this test matches similar one in
503 * RecoverPreparedTransactions()
505 if (nUnreportedXids >= PGPROC_MAX_CACHED_SUBXIDS)
507 XLogRecData rdata[2];
508 xl_xact_assignment xlrec;
511 * xtop is always set by now because we recurse up transaction
512 * stack to the highest unassigned xid and then come back down
514 xlrec.xtop = GetTopTransactionId();
515 Assert(TransactionIdIsValid(xlrec.xtop));
516 xlrec.nsubxacts = nUnreportedXids;
518 rdata[0].data = (char *) &xlrec;
519 rdata[0].len = MinSizeOfXactAssignment;
520 rdata[0].buffer = InvalidBuffer;
521 rdata[0].next = &rdata[1];
523 rdata[1].data = (char *) unreportedXids;
524 rdata[1].len = PGPROC_MAX_CACHED_SUBXIDS * sizeof(TransactionId);
525 rdata[1].buffer = InvalidBuffer;
526 rdata[1].next = NULL;
528 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT, rdata);
536 * GetCurrentSubTransactionId
539 GetCurrentSubTransactionId(void)
541 TransactionState s = CurrentTransactionState;
543 return s->subTransactionId;
548 * GetCurrentCommandId
550 * "used" must be TRUE if the caller intends to use the command ID to mark
551 * inserted/updated/deleted tuples. FALSE means the ID is being fetched
552 * for read-only purposes (ie, as a snapshot validity cutoff). See
553 * CommandCounterIncrement() for discussion.
556 GetCurrentCommandId(bool used)
558 /* this is global to a transaction, not subtransaction-local */
560 currentCommandIdUsed = true;
561 return currentCommandId;
565 * GetCurrentTransactionStartTimestamp
568 GetCurrentTransactionStartTimestamp(void)
570 return xactStartTimestamp;
574 * GetCurrentStatementStartTimestamp
577 GetCurrentStatementStartTimestamp(void)
579 return stmtStartTimestamp;
583 * GetCurrentTransactionStopTimestamp
585 * We return current time if the transaction stop time hasn't been set
586 * (which can happen if we decide we don't need to log an XLOG record).
589 GetCurrentTransactionStopTimestamp(void)
591 if (xactStopTimestamp != 0)
592 return xactStopTimestamp;
593 return GetCurrentTimestamp();
597 * SetCurrentStatementStartTimestamp
600 SetCurrentStatementStartTimestamp(void)
602 stmtStartTimestamp = GetCurrentTimestamp();
606 * SetCurrentTransactionStopTimestamp
609 SetCurrentTransactionStopTimestamp(void)
611 xactStopTimestamp = GetCurrentTimestamp();
615 * GetCurrentTransactionNestLevel
617 * Note: this will return zero when not inside any transaction, one when
618 * inside a top-level transaction, etc.
621 GetCurrentTransactionNestLevel(void)
623 TransactionState s = CurrentTransactionState;
625 return s->nestingLevel;
630 * TransactionIdIsCurrentTransactionId
633 TransactionIdIsCurrentTransactionId(TransactionId xid)
638 * We always say that BootstrapTransactionId is "not my transaction ID"
639 * even when it is (ie, during bootstrap). Along with the fact that
640 * transam.c always treats BootstrapTransactionId as already committed,
641 * this causes the tqual.c routines to see all tuples as committed, which
642 * is what we need during bootstrap. (Bootstrap mode only inserts tuples,
643 * it never updates or deletes them, so all tuples can be presumed good
646 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
647 * not my transaction ID, so we can just return "false" immediately for
648 * any non-normal XID.
650 if (!TransactionIdIsNormal(xid))
654 * We will return true for the Xid of the current subtransaction, any of
655 * its subcommitted children, any of its parents, or any of their
656 * previously subcommitted children. However, a transaction being aborted
657 * is no longer "current", even though it may still have an entry on the
660 for (s = CurrentTransactionState; s != NULL; s = s->parent)
665 if (s->state == TRANS_ABORT)
667 if (!TransactionIdIsValid(s->transactionId))
668 continue; /* it can't have any child XIDs either */
669 if (TransactionIdEquals(xid, s->transactionId))
671 /* As the childXids array is ordered, we can use binary search */
673 high = s->nChildXids - 1;
679 middle = low + (high - low) / 2;
680 probe = s->childXids[middle];
681 if (TransactionIdEquals(probe, xid))
683 else if (TransactionIdPrecedes(probe, xid))
694 * TransactionStartedDuringRecovery
696 * Returns true if the current transaction started while recovery was still
697 * in progress. Recovery might have ended since so RecoveryInProgress() might
698 * return false already.
701 TransactionStartedDuringRecovery(void)
703 return CurrentTransactionState->startedInRecovery;
707 * CommandCounterIncrement
710 CommandCounterIncrement(void)
713 * If the current value of the command counter hasn't been "used" to mark
714 * tuples, we need not increment it, since there's no need to distinguish
715 * a read-only command from others. This helps postpone command counter
716 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
718 if (currentCommandIdUsed)
720 currentCommandId += 1;
721 if (currentCommandId == FirstCommandId) /* check for overflow */
723 currentCommandId -= 1;
725 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
726 errmsg("cannot have more than 2^32-1 commands in a transaction")));
728 currentCommandIdUsed = false;
730 /* Propagate new command ID into static snapshots */
731 SnapshotSetCommandId(currentCommandId);
734 * Make any catalog changes done by the just-completed command visible
735 * in the local syscache. We obviously don't need to do this after a
736 * read-only command. (But see hacks in inval.c to make real sure we
737 * don't think a command that queued inval messages was read-only.)
746 * Interface routine to allow commands to force a synchronous commit of the
747 * current top-level transaction
750 ForceSyncCommit(void)
752 forceSyncCommit = true;
756 /* ----------------------------------------------------------------
757 * StartTransaction stuff
758 * ----------------------------------------------------------------
767 AcceptInvalidationMessages();
776 TransactionState s = CurrentTransactionState;
779 * If this is the first time through, create a private context for
780 * AbortTransaction to work in. By reserving some space now, we can
781 * insulate AbortTransaction from out-of-memory scenarios. Like
782 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
783 * size, so that space will be reserved immediately.
785 if (TransactionAbortContext == NULL)
786 TransactionAbortContext =
787 AllocSetContextCreate(TopMemoryContext,
788 "TransactionAbortContext",
794 * We shouldn't have a transaction context already.
796 Assert(TopTransactionContext == NULL);
799 * Create a toplevel context for the transaction.
801 TopTransactionContext =
802 AllocSetContextCreate(TopMemoryContext,
803 "TopTransactionContext",
804 ALLOCSET_DEFAULT_MINSIZE,
805 ALLOCSET_DEFAULT_INITSIZE,
806 ALLOCSET_DEFAULT_MAXSIZE);
809 * In a top-level transaction, CurTransactionContext is the same as
810 * TopTransactionContext.
812 CurTransactionContext = TopTransactionContext;
813 s->curTransactionContext = CurTransactionContext;
815 /* Make the CurTransactionContext active. */
816 MemoryContextSwitchTo(CurTransactionContext);
820 * AtStart_ResourceOwner
823 AtStart_ResourceOwner(void)
825 TransactionState s = CurrentTransactionState;
828 * We shouldn't have a transaction resource owner already.
830 Assert(TopTransactionResourceOwner == NULL);
833 * Create a toplevel resource owner for the transaction.
835 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
837 TopTransactionResourceOwner = s->curTransactionOwner;
838 CurTransactionResourceOwner = s->curTransactionOwner;
839 CurrentResourceOwner = s->curTransactionOwner;
842 /* ----------------------------------------------------------------
843 * StartSubTransaction stuff
844 * ----------------------------------------------------------------
851 AtSubStart_Memory(void)
853 TransactionState s = CurrentTransactionState;
855 Assert(CurTransactionContext != NULL);
858 * Create a CurTransactionContext, which will be used to hold data that
859 * survives subtransaction commit but disappears on subtransaction abort.
860 * We make it a child of the immediate parent's CurTransactionContext.
862 CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
863 "CurTransactionContext",
864 ALLOCSET_DEFAULT_MINSIZE,
865 ALLOCSET_DEFAULT_INITSIZE,
866 ALLOCSET_DEFAULT_MAXSIZE);
867 s->curTransactionContext = CurTransactionContext;
869 /* Make the CurTransactionContext active. */
870 MemoryContextSwitchTo(CurTransactionContext);
874 * AtSubStart_ResourceOwner
877 AtSubStart_ResourceOwner(void)
879 TransactionState s = CurrentTransactionState;
881 Assert(s->parent != NULL);
884 * Create a resource owner for the subtransaction. We make it a child of
885 * the immediate parent's resource owner.
887 s->curTransactionOwner =
888 ResourceOwnerCreate(s->parent->curTransactionOwner,
891 CurTransactionResourceOwner = s->curTransactionOwner;
892 CurrentResourceOwner = s->curTransactionOwner;
895 /* ----------------------------------------------------------------
896 * CommitTransaction stuff
897 * ----------------------------------------------------------------
901 * RecordTransactionCommit
903 * Returns latest XID among xact and its children, or InvalidTransactionId
904 * if the xact has no XID. (We compute that here just because it's easier.)
907 RecordTransactionCommit(void)
909 TransactionId xid = GetTopTransactionIdIfAny();
910 bool markXidCommitted = TransactionIdIsValid(xid);
911 TransactionId latestXid = InvalidTransactionId;
915 TransactionId *children;
917 SharedInvalidationMessage *invalMessages = NULL;
918 bool RelcacheInitFileInval = false;
921 /* Get data needed for commit record */
922 nrels = smgrGetPendingDeletes(true, &rels);
923 nchildren = xactGetCommittedChildren(&children);
924 if (XLogStandbyInfoActive())
925 nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
926 &RelcacheInitFileInval);
927 wrote_xlog = (XactLastRecEnd.xrecoff != 0);
930 * If we haven't been assigned an XID yet, we neither can, nor do we want
931 * to write a COMMIT record.
933 if (!markXidCommitted)
936 * We expect that every smgrscheduleunlink is followed by a catalog
937 * update, and hence XID assignment, so we shouldn't get here with any
938 * pending deletes. Use a real test not just an Assert to check this,
939 * since it's a bit fragile.
942 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
944 /* Can't have child XIDs either; AssignTransactionId enforces this */
945 Assert(nchildren == 0);
948 * If we didn't create XLOG entries, we're done here; otherwise we
949 * should flush those entries the same as a commit record. (An
950 * example of a possible record that wouldn't cause an XID to be
951 * assigned is a sequence advance record due to nextval() --- we want
952 * to flush that to disk before reporting commit.)
960 * Begin commit critical section and insert the commit XLOG record.
962 /* Tell bufmgr and smgr to prepare for commit */
966 * Mark ourselves as within our "commit critical section". This
967 * forces any concurrent checkpoint to wait until we've updated
968 * pg_clog. Without this, it is possible for the checkpoint to set
969 * REDO after the XLOG record but fail to flush the pg_clog update to
970 * disk, leading to loss of the transaction commit if the system
971 * crashes a little later.
973 * Note: we could, but don't bother to, set this flag in
974 * RecordTransactionAbort. That's because loss of a transaction abort
975 * is noncritical; the presumption would be that it aborted, anyway.
977 * It's safe to change the inCommit flag of our own backend without
978 * holding the ProcArrayLock, since we're the only one modifying it.
979 * This makes checkpoint's determination of which xacts are inCommit a
980 * bit fuzzy, but it doesn't matter.
982 START_CRIT_SECTION();
983 MyProc->inCommit = true;
985 SetCurrentTransactionStopTimestamp();
988 * Do we need the long commit record? If not, use the compact format.
990 if (nrels > 0 || nmsgs > 0 || RelcacheInitFileInval || forceSyncCommit)
992 XLogRecData rdata[4];
994 xl_xact_commit xlrec;
996 * Set flags required for recovery processing of commits.
999 if (RelcacheInitFileInval)
1000 xlrec.xinfo |= XACT_COMPLETION_UPDATE_RELCACHE_FILE;
1001 if (forceSyncCommit)
1002 xlrec.xinfo |= XACT_COMPLETION_FORCE_SYNC_COMMIT;
1004 xlrec.dbId = MyDatabaseId;
1005 xlrec.tsId = MyDatabaseTableSpace;
1007 xlrec.xact_time = xactStopTimestamp;
1008 xlrec.nrels = nrels;
1009 xlrec.nsubxacts = nchildren;
1010 xlrec.nmsgs = nmsgs;
1011 rdata[0].data = (char *) (&xlrec);
1012 rdata[0].len = MinSizeOfXactCommit;
1013 rdata[0].buffer = InvalidBuffer;
1014 /* dump rels to delete */
1017 rdata[0].next = &(rdata[1]);
1018 rdata[1].data = (char *) rels;
1019 rdata[1].len = nrels * sizeof(RelFileNode);
1020 rdata[1].buffer = InvalidBuffer;
1023 /* dump committed child Xids */
1026 rdata[lastrdata].next = &(rdata[2]);
1027 rdata[2].data = (char *) children;
1028 rdata[2].len = nchildren * sizeof(TransactionId);
1029 rdata[2].buffer = InvalidBuffer;
1032 /* dump shared cache invalidation messages */
1035 rdata[lastrdata].next = &(rdata[3]);
1036 rdata[3].data = (char *) invalMessages;
1037 rdata[3].len = nmsgs * sizeof(SharedInvalidationMessage);
1038 rdata[3].buffer = InvalidBuffer;
1041 rdata[lastrdata].next = NULL;
1043 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
1047 XLogRecData rdata[2];
1049 xl_xact_commit_compact xlrec;
1050 xlrec.xact_time = xactStopTimestamp;
1051 xlrec.nsubxacts = nchildren;
1052 rdata[0].data = (char *) (&xlrec);
1053 rdata[0].len = MinSizeOfXactCommitCompact;
1054 rdata[0].buffer = InvalidBuffer;
1055 /* dump committed child Xids */
1058 rdata[0].next = &(rdata[1]);
1059 rdata[1].data = (char *) children;
1060 rdata[1].len = nchildren * sizeof(TransactionId);
1061 rdata[1].buffer = InvalidBuffer;
1064 rdata[lastrdata].next = NULL;
1066 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT_COMPACT, rdata);
1071 * Check if we want to commit asynchronously. We can allow the XLOG flush
1072 * to happen asynchronously if synchronous_commit=off, or if the current
1073 * transaction has not performed any WAL-logged operation. The latter
1074 * case can arise if the current transaction wrote only to temporary
1075 * and/or unlogged tables. In case of a crash, the loss of such a
1076 * transaction will be irrelevant since temp tables will be lost anyway,
1077 * and unlogged tables will be truncated. (Given the foregoing, you might
1078 * think that it would be unnecessary to emit the XLOG record at all in
1079 * this case, but we don't currently try to do that. It would certainly
1080 * cause problems at least in Hot Standby mode, where the
1081 * KnownAssignedXids machinery requires tracking every XID assignment. It
1082 * might be OK to skip it only when wal_level < hot_standby, but for now
1085 * However, if we're doing cleanup of any non-temp rels or committing any
1086 * command that wanted to force sync commit, then we must flush XLOG
1087 * immediately. (We must not allow asynchronous commit if there are any
1088 * non-temp tables to be deleted, because we might delete the files before
1089 * the COMMIT record is flushed to disk. We do allow asynchronous commit
1090 * if all to-be-deleted tables are temporary though, since they are lost
1091 * anyway if we crash.)
1093 if ((wrote_xlog && synchronous_commit > SYNCHRONOUS_COMMIT_OFF) ||
1094 forceSyncCommit || nrels > 0)
1097 * Synchronous commit case:
1099 * Sleep before flush! So we can flush more than one commit records
1100 * per single fsync. (The idea is some other backend may do the
1101 * XLogFlush while we're sleeping. This needs work still, because on
1102 * most Unixen, the minimum select() delay is 10msec or more, which is
1105 * We do not sleep if enableFsync is not turned on, nor if there are
1106 * fewer than CommitSiblings other backends with active transactions.
1108 if (CommitDelay > 0 && enableFsync &&
1109 MinimumActiveBackends(CommitSiblings))
1110 pg_usleep(CommitDelay);
1112 XLogFlush(XactLastRecEnd);
1115 * Wake up all walsenders to send WAL up to the COMMIT record
1116 * immediately if replication is enabled
1118 if (max_wal_senders > 0)
1122 * Now we may update the CLOG, if we wrote a COMMIT record above
1124 if (markXidCommitted)
1125 TransactionIdCommitTree(xid, nchildren, children);
1130 * Asynchronous commit case:
1132 * This enables possible committed transaction loss in the case of a
1133 * postmaster crash because WAL buffers are left unwritten. Ideally we
1134 * could issue the WAL write without the fsync, but some
1135 * wal_sync_methods do not allow separate write/fsync.
1137 * Report the latest async commit LSN, so that the WAL writer knows to
1138 * flush this commit.
1140 XLogSetAsyncXactLSN(XactLastRecEnd);
1143 * We must not immediately update the CLOG, since we didn't flush the
1144 * XLOG. Instead, we store the LSN up to which the XLOG must be
1145 * flushed before the CLOG may be updated.
1147 if (markXidCommitted)
1148 TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1152 * If we entered a commit critical section, leave it now, and let
1153 * checkpoints proceed.
1155 if (markXidCommitted)
1157 MyProc->inCommit = false;
1161 /* Compute latestXid while we have the child XIDs handy */
1162 latestXid = TransactionIdLatest(xid, nchildren, children);
1165 * Wait for synchronous replication, if required.
1167 * Note that at this stage we have marked clog, but still show as running
1168 * in the procarray and continue to hold locks.
1170 SyncRepWaitForLSN(XactLastRecEnd);
1172 /* Reset XactLastRecEnd until the next transaction writes something */
1173 XactLastRecEnd.xrecoff = 0;
1176 /* Clean up local data */
1188 AtCCI_LocalCache(void)
1191 * Make any pending relation map changes visible. We must do this before
1192 * processing local sinval messages, so that the map changes will get
1193 * reflected into the relcache when relcache invals are processed.
1195 AtCCI_RelationMap();
1198 * Make catalog changes visible to me for the next command.
1200 CommandEndInvalidationMessages();
1207 AtCommit_Memory(void)
1210 * Now that we're "out" of a transaction, have the system allocate things
1211 * in the top memory context instead of per-transaction contexts.
1213 MemoryContextSwitchTo(TopMemoryContext);
1216 * Release all transaction-local memory.
1218 Assert(TopTransactionContext != NULL);
1219 MemoryContextDelete(TopTransactionContext);
1220 TopTransactionContext = NULL;
1221 CurTransactionContext = NULL;
1222 CurrentTransactionState->curTransactionContext = NULL;
1225 /* ----------------------------------------------------------------
1226 * CommitSubTransaction stuff
1227 * ----------------------------------------------------------------
1231 * AtSubCommit_Memory
1234 AtSubCommit_Memory(void)
1236 TransactionState s = CurrentTransactionState;
1238 Assert(s->parent != NULL);
1240 /* Return to parent transaction level's memory context. */
1241 CurTransactionContext = s->parent->curTransactionContext;
1242 MemoryContextSwitchTo(CurTransactionContext);
1245 * Ordinarily we cannot throw away the child's CurTransactionContext,
1246 * since the data it contains will be needed at upper commit. However, if
1247 * there isn't actually anything in it, we can throw it away. This avoids
1248 * a small memory leak in the common case of "trivial" subxacts.
1250 if (MemoryContextIsEmpty(s->curTransactionContext))
1252 MemoryContextDelete(s->curTransactionContext);
1253 s->curTransactionContext = NULL;
1258 * AtSubCommit_childXids
1260 * Pass my own XID and my child XIDs up to my parent as committed children.
1263 AtSubCommit_childXids(void)
1265 TransactionState s = CurrentTransactionState;
1268 Assert(s->parent != NULL);
1271 * The parent childXids array will need to hold my XID and all my
1272 * childXids, in addition to the XIDs already there.
1274 new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1276 /* Allocate or enlarge the parent array if necessary */
1277 if (s->parent->maxChildXids < new_nChildXids)
1279 int new_maxChildXids;
1280 TransactionId *new_childXids;
1283 * Make it 2x what's needed right now, to avoid having to enlarge it
1284 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1285 * is what ensures that we don't need to worry about integer overflow
1286 * here or in the calculation of new_nChildXids.)
1288 new_maxChildXids = Min(new_nChildXids * 2,
1289 (int) (MaxAllocSize / sizeof(TransactionId)));
1291 if (new_maxChildXids < new_nChildXids)
1293 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1294 errmsg("maximum number of committed subtransactions (%d) exceeded",
1295 (int) (MaxAllocSize / sizeof(TransactionId)))));
1298 * We keep the child-XID arrays in TopTransactionContext; this avoids
1299 * setting up child-transaction contexts for what might be just a few
1300 * bytes of grandchild XIDs.
1302 if (s->parent->childXids == NULL)
1304 MemoryContextAlloc(TopTransactionContext,
1305 new_maxChildXids * sizeof(TransactionId));
1307 new_childXids = repalloc(s->parent->childXids,
1308 new_maxChildXids * sizeof(TransactionId));
1310 s->parent->childXids = new_childXids;
1311 s->parent->maxChildXids = new_maxChildXids;
1315 * Copy all my XIDs to parent's array.
1317 * Note: We rely on the fact that the XID of a child always follows that
1318 * of its parent. By copying the XID of this subtransaction before the
1319 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1320 * all XIDs already in the array belong to subtransactions started and
1321 * subcommitted before us, so their XIDs must precede ours.
1323 s->parent->childXids[s->parent->nChildXids] = s->transactionId;
1325 if (s->nChildXids > 0)
1326 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1328 s->nChildXids * sizeof(TransactionId));
1330 s->parent->nChildXids = new_nChildXids;
1332 /* Release child's array to avoid leakage */
1333 if (s->childXids != NULL)
1334 pfree(s->childXids);
1335 /* We must reset these to avoid double-free if fail later in commit */
1336 s->childXids = NULL;
1338 s->maxChildXids = 0;
1341 /* ----------------------------------------------------------------
1342 * AbortTransaction stuff
1343 * ----------------------------------------------------------------
1347 * RecordTransactionAbort
1349 * Returns latest XID among xact and its children, or InvalidTransactionId
1350 * if the xact has no XID. (We compute that here just because it's easier.)
1352 static TransactionId
1353 RecordTransactionAbort(bool isSubXact)
1355 TransactionId xid = GetCurrentTransactionIdIfAny();
1356 TransactionId latestXid;
1360 TransactionId *children;
1361 XLogRecData rdata[3];
1363 xl_xact_abort xlrec;
1366 * If we haven't been assigned an XID, nobody will care whether we aborted
1367 * or not. Hence, we're done in that case. It does not matter if we have
1368 * rels to delete (note that this routine is not responsible for actually
1369 * deleting 'em). We cannot have any child XIDs, either.
1371 if (!TransactionIdIsValid(xid))
1373 /* Reset XactLastRecEnd until the next transaction writes something */
1375 XactLastRecEnd.xrecoff = 0;
1376 return InvalidTransactionId;
1380 * We have a valid XID, so we should write an ABORT record for it.
1382 * We do not flush XLOG to disk here, since the default assumption after a
1383 * crash would be that we aborted, anyway. For the same reason, we don't
1384 * need to worry about interlocking against checkpoint start.
1388 * Check that we haven't aborted halfway through RecordTransactionCommit.
1390 if (TransactionIdDidCommit(xid))
1391 elog(PANIC, "cannot abort transaction %u, it was already committed",
1394 /* Fetch the data we need for the abort record */
1395 nrels = smgrGetPendingDeletes(false, &rels);
1396 nchildren = xactGetCommittedChildren(&children);
1398 /* XXX do we really need a critical section here? */
1399 START_CRIT_SECTION();
1401 /* Write the ABORT record */
1403 xlrec.xact_time = GetCurrentTimestamp();
1406 SetCurrentTransactionStopTimestamp();
1407 xlrec.xact_time = xactStopTimestamp;
1409 xlrec.nrels = nrels;
1410 xlrec.nsubxacts = nchildren;
1411 rdata[0].data = (char *) (&xlrec);
1412 rdata[0].len = MinSizeOfXactAbort;
1413 rdata[0].buffer = InvalidBuffer;
1414 /* dump rels to delete */
1417 rdata[0].next = &(rdata[1]);
1418 rdata[1].data = (char *) rels;
1419 rdata[1].len = nrels * sizeof(RelFileNode);
1420 rdata[1].buffer = InvalidBuffer;
1423 /* dump committed child Xids */
1426 rdata[lastrdata].next = &(rdata[2]);
1427 rdata[2].data = (char *) children;
1428 rdata[2].len = nchildren * sizeof(TransactionId);
1429 rdata[2].buffer = InvalidBuffer;
1432 rdata[lastrdata].next = NULL;
1434 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
1437 * Report the latest async abort LSN, so that the WAL writer knows to
1438 * flush this abort. There's nothing to be gained by delaying this, since
1439 * WALWriter may as well do this when it can. This is important with
1440 * streaming replication because if we don't flush WAL regularly we will
1441 * find that large aborts leave us with a long backlog for when commits
1442 * occur after the abort, increasing our window of data loss should
1443 * problems occur at that point.
1446 XLogSetAsyncXactLSN(XactLastRecEnd);
1449 * Mark the transaction aborted in clog. This is not absolutely necessary
1450 * but we may as well do it while we are here; also, in the subxact case
1451 * it is helpful because XactLockTableWait makes use of it to avoid
1452 * waiting for already-aborted subtransactions. It is OK to do it without
1453 * having flushed the ABORT record to disk, because in event of a crash
1454 * we'd be assumed to have aborted anyway.
1456 TransactionIdAbortTree(xid, nchildren, children);
1460 /* Compute latestXid while we have the child XIDs handy */
1461 latestXid = TransactionIdLatest(xid, nchildren, children);
1464 * If we're aborting a subtransaction, we can immediately remove failed
1465 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1466 * subxacts, because we already have the child XID array at hand. For
1467 * main xacts, the equivalent happens just after this function returns.
1470 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1472 /* Reset XactLastRecEnd until the next transaction writes something */
1474 XactLastRecEnd.xrecoff = 0;
1476 /* And clean up local data */
1487 AtAbort_Memory(void)
1490 * Switch into TransactionAbortContext, which should have some free space
1491 * even if nothing else does. We'll work in this context until we've
1492 * finished cleaning up.
1494 * It is barely possible to get here when we've not been able to create
1495 * TransactionAbortContext yet; if so use TopMemoryContext.
1497 if (TransactionAbortContext != NULL)
1498 MemoryContextSwitchTo(TransactionAbortContext);
1500 MemoryContextSwitchTo(TopMemoryContext);
1507 AtSubAbort_Memory(void)
1509 Assert(TransactionAbortContext != NULL);
1511 MemoryContextSwitchTo(TransactionAbortContext);
1516 * AtAbort_ResourceOwner
1519 AtAbort_ResourceOwner(void)
1522 * Make sure we have a valid ResourceOwner, if possible (else it will be
1523 * NULL, which is OK)
1525 CurrentResourceOwner = TopTransactionResourceOwner;
1529 * AtSubAbort_ResourceOwner
1532 AtSubAbort_ResourceOwner(void)
1534 TransactionState s = CurrentTransactionState;
1536 /* Make sure we have a valid ResourceOwner */
1537 CurrentResourceOwner = s->curTransactionOwner;
1542 * AtSubAbort_childXids
1545 AtSubAbort_childXids(void)
1547 TransactionState s = CurrentTransactionState;
1550 * We keep the child-XID arrays in TopTransactionContext (see
1551 * AtSubCommit_childXids). This means we'd better free the array
1552 * explicitly at abort to avoid leakage.
1554 if (s->childXids != NULL)
1555 pfree(s->childXids);
1556 s->childXids = NULL;
1558 s->maxChildXids = 0;
1561 * We could prune the unreportedXids array here. But we don't bother. That
1562 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1563 * would likely introduce more CPU time into the more common paths, so we
1564 * choose not to do that.
1568 /* ----------------------------------------------------------------
1569 * CleanupTransaction stuff
1570 * ----------------------------------------------------------------
1577 AtCleanup_Memory(void)
1579 Assert(CurrentTransactionState->parent == NULL);
1582 * Now that we're "out" of a transaction, have the system allocate things
1583 * in the top memory context instead of per-transaction contexts.
1585 MemoryContextSwitchTo(TopMemoryContext);
1588 * Clear the special abort context for next time.
1590 if (TransactionAbortContext != NULL)
1591 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1594 * Release all transaction-local memory.
1596 if (TopTransactionContext != NULL)
1597 MemoryContextDelete(TopTransactionContext);
1598 TopTransactionContext = NULL;
1599 CurTransactionContext = NULL;
1600 CurrentTransactionState->curTransactionContext = NULL;
1604 /* ----------------------------------------------------------------
1605 * CleanupSubTransaction stuff
1606 * ----------------------------------------------------------------
1610 * AtSubCleanup_Memory
1613 AtSubCleanup_Memory(void)
1615 TransactionState s = CurrentTransactionState;
1617 Assert(s->parent != NULL);
1619 /* Make sure we're not in an about-to-be-deleted context */
1620 MemoryContextSwitchTo(s->parent->curTransactionContext);
1621 CurTransactionContext = s->parent->curTransactionContext;
1624 * Clear the special abort context for next time.
1626 if (TransactionAbortContext != NULL)
1627 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1630 * Delete the subxact local memory contexts. Its CurTransactionContext can
1631 * go too (note this also kills CurTransactionContexts from any children
1634 if (s->curTransactionContext)
1635 MemoryContextDelete(s->curTransactionContext);
1636 s->curTransactionContext = NULL;
1639 /* ----------------------------------------------------------------
1640 * interface routines
1641 * ----------------------------------------------------------------
1648 StartTransaction(void)
1651 VirtualTransactionId vxid;
1654 * Let's just make sure the state stack is empty
1656 s = &TopTransactionStateData;
1657 CurrentTransactionState = s;
1660 * check the current transaction state
1662 if (s->state != TRANS_DEFAULT)
1663 elog(WARNING, "StartTransaction while in %s state",
1664 TransStateAsString(s->state));
1667 * set the current transaction state information appropriately during
1670 s->state = TRANS_START;
1671 s->transactionId = InvalidTransactionId; /* until assigned */
1674 * Make sure we've reset xact state variables
1676 * If recovery is still in progress, mark this transaction as read-only.
1677 * We have lower level defences in XLogInsert and elsewhere to stop us
1678 * from modifying data during recovery, but this gives the normal
1679 * indication to the user that the transaction is read-only.
1681 if (RecoveryInProgress())
1683 s->startedInRecovery = true;
1684 XactReadOnly = true;
1688 s->startedInRecovery = false;
1689 XactReadOnly = DefaultXactReadOnly;
1691 XactDeferrable = DefaultXactDeferrable;
1692 XactIsoLevel = DefaultXactIsoLevel;
1693 forceSyncCommit = false;
1694 MyXactAccessedTempRel = false;
1697 * reinitialize within-transaction counters
1699 s->subTransactionId = TopSubTransactionId;
1700 currentSubTransactionId = TopSubTransactionId;
1701 currentCommandId = FirstCommandId;
1702 currentCommandIdUsed = false;
1705 * initialize reported xid accounting
1707 nUnreportedXids = 0;
1710 * must initialize resource-management stuff first
1713 AtStart_ResourceOwner();
1716 * Assign a new LocalTransactionId, and combine it with the backendId to
1717 * form a virtual transaction id.
1719 vxid.backendId = MyBackendId;
1720 vxid.localTransactionId = GetNextLocalTransactionId();
1723 * Lock the virtual transaction id before we announce it in the proc array
1725 VirtualXactLockTableInsert(vxid);
1728 * Advertise it in the proc array. We assume assignment of
1729 * LocalTransactionID is atomic, and the backendId should be set already.
1731 Assert(MyProc->backendId == vxid.backendId);
1732 MyProc->lxid = vxid.localTransactionId;
1734 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
1737 * set transaction_timestamp() (a/k/a now()). We want this to be the same
1738 * as the first command's statement_timestamp(), so don't do a fresh
1739 * GetCurrentTimestamp() call (which'd be expensive anyway). Also, mark
1740 * xactStopTimestamp as unset.
1742 xactStartTimestamp = stmtStartTimestamp;
1743 xactStopTimestamp = 0;
1744 pgstat_report_xact_timestamp(xactStartTimestamp);
1747 * initialize current transaction state fields
1749 * note: prevXactReadOnly is not used at the outermost level
1751 s->nestingLevel = 1;
1752 s->gucNestLevel = 1;
1753 s->childXids = NULL;
1755 s->maxChildXids = 0;
1756 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
1757 /* SecurityRestrictionContext should never be set outside a transaction */
1758 Assert(s->prevSecContext == 0);
1761 * initialize other subsystems for new transaction
1766 AfterTriggerBeginXact();
1769 * done with start processing, set current transaction state to "in
1772 s->state = TRANS_INPROGRESS;
1774 ShowTransactionState("StartTransaction");
1781 * NB: if you change this routine, better look at PrepareTransaction too!
1784 CommitTransaction(void)
1786 TransactionState s = CurrentTransactionState;
1787 TransactionId latestXid;
1789 ShowTransactionState("CommitTransaction");
1792 * check the current transaction state
1794 if (s->state != TRANS_INPROGRESS)
1795 elog(WARNING, "CommitTransaction while in %s state",
1796 TransStateAsString(s->state));
1797 Assert(s->parent == NULL);
1800 * Do pre-commit processing that involves calling user-defined code, such
1801 * as triggers. Since closing cursors could queue trigger actions,
1802 * triggers could open cursors, etc, we have to keep looping until there's
1803 * nothing left to do.
1808 * Fire all currently pending deferred triggers.
1810 AfterTriggerFireDeferred();
1813 * Close open portals (converting holdable ones into static portals).
1814 * If there weren't any, we are done ... otherwise loop back to check
1815 * if they queued deferred triggers. Lather, rinse, repeat.
1817 if (!PreCommit_Portals(false))
1822 * The remaining actions cannot call any user-defined code, so it's safe
1823 * to start shutting down within-transaction services. But note that most
1824 * of this stuff could still throw an error, which would switch us into
1825 * the transaction-abort path.
1828 /* Shut down the deferred-trigger manager */
1829 AfterTriggerEndXact(true);
1832 * Let ON COMMIT management do its thing (must happen after closing
1833 * cursors, to avoid dangling-reference problems)
1835 PreCommit_on_commit_actions();
1837 /* close large objects before lower-level cleanup */
1838 AtEOXact_LargeObject(true);
1841 * Mark serializable transaction as complete for predicate locking
1842 * purposes. This should be done as late as we can put it and still allow
1843 * errors to be raised for failure patterns found at commit.
1845 PreCommit_CheckForSerializationFailure();
1848 * Insert notifications sent by NOTIFY commands into the queue. This
1849 * should be late in the pre-commit sequence to minimize time spent
1850 * holding the notify-insertion lock.
1854 /* Prevent cancel/die interrupt while cleaning up */
1857 /* Commit updates to the relation map --- do this as late as possible */
1858 AtEOXact_RelationMap(true);
1861 * set the current transaction state information appropriately during
1864 s->state = TRANS_COMMIT;
1867 * Here is where we really truly commit.
1869 latestXid = RecordTransactionCommit();
1871 TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
1874 * Let others know about no transaction in progress by me. Note that this
1875 * must be done _before_ releasing locks we hold and _after_
1876 * RecordTransactionCommit.
1878 ProcArrayEndTransaction(MyProc, latestXid);
1881 * This is all post-commit cleanup. Note that if an error is raised here,
1882 * it's too late to abort the transaction. This should be just
1883 * noncritical resource releasing.
1885 * The ordering of operations is not entirely random. The idea is:
1886 * release resources visible to other backends (eg, files, buffer pins);
1887 * then release locks; then release backend-local resources. We want to
1888 * release locks at the point where any backend waiting for us will see
1889 * our transaction as being fully cleaned up.
1891 * Resources that can be associated with individual queries are handled by
1892 * the ResourceOwner mechanism. The other calls here are for backend-wide
1896 CallXactCallbacks(XACT_EVENT_COMMIT);
1898 ResourceOwnerRelease(TopTransactionResourceOwner,
1899 RESOURCE_RELEASE_BEFORE_LOCKS,
1902 /* Check we've released all buffer pins */
1903 AtEOXact_Buffers(true);
1905 /* Clean up the relation cache */
1906 AtEOXact_RelationCache(true);
1908 /* Clean up the snapshot manager */
1909 AtEarlyCommit_Snapshot();
1912 * Make catalog changes visible to all backends. This has to happen after
1913 * relcache references are dropped (see comments for
1914 * AtEOXact_RelationCache), but before locks are released (if anyone is
1915 * waiting for lock on a relation we've modified, we want them to know
1916 * about the catalog change before they start using the relation).
1918 AtEOXact_Inval(true);
1921 * Likewise, dropping of files deleted during the transaction is best done
1922 * after releasing relcache and buffer pins. (This is not strictly
1923 * necessary during commit, since such pins should have been released
1924 * already, but this ordering is definitely critical during abort.)
1926 smgrDoPendingDeletes(true);
1928 AtEOXact_MultiXact();
1930 ResourceOwnerRelease(TopTransactionResourceOwner,
1931 RESOURCE_RELEASE_LOCKS,
1933 ResourceOwnerRelease(TopTransactionResourceOwner,
1934 RESOURCE_RELEASE_AFTER_LOCKS,
1937 /* Check we've released all catcache entries */
1938 AtEOXact_CatCache(true);
1941 AtEOXact_GUC(true, 1);
1943 AtEOXact_on_commit_actions(true);
1944 AtEOXact_Namespace(true);
1945 /* smgrcommit already done */
1947 AtEOXact_ComboCid();
1948 AtEOXact_HashTables(true);
1949 AtEOXact_PgStat(true);
1950 AtEOXact_Snapshot(true);
1951 pgstat_report_xact_timestamp(0);
1953 CurrentResourceOwner = NULL;
1954 ResourceOwnerDelete(TopTransactionResourceOwner);
1955 s->curTransactionOwner = NULL;
1956 CurTransactionResourceOwner = NULL;
1957 TopTransactionResourceOwner = NULL;
1961 s->transactionId = InvalidTransactionId;
1962 s->subTransactionId = InvalidSubTransactionId;
1963 s->nestingLevel = 0;
1964 s->gucNestLevel = 0;
1965 s->childXids = NULL;
1967 s->maxChildXids = 0;
1970 * done with commit processing, set current transaction state back to
1973 s->state = TRANS_DEFAULT;
1975 RESUME_INTERRUPTS();
1980 * PrepareTransaction
1982 * NB: if you change this routine, better look at CommitTransaction too!
1985 PrepareTransaction(void)
1987 TransactionState s = CurrentTransactionState;
1988 TransactionId xid = GetCurrentTransactionId();
1989 GlobalTransaction gxact;
1990 TimestampTz prepared_at;
1992 ShowTransactionState("PrepareTransaction");
1995 * check the current transaction state
1997 if (s->state != TRANS_INPROGRESS)
1998 elog(WARNING, "PrepareTransaction while in %s state",
1999 TransStateAsString(s->state));
2000 Assert(s->parent == NULL);
2003 * Do pre-commit processing that involves calling user-defined code, such
2004 * as triggers. Since closing cursors could queue trigger actions,
2005 * triggers could open cursors, etc, we have to keep looping until there's
2006 * nothing left to do.
2011 * Fire all currently pending deferred triggers.
2013 AfterTriggerFireDeferred();
2016 * Close open portals (converting holdable ones into static portals).
2017 * If there weren't any, we are done ... otherwise loop back to check
2018 * if they queued deferred triggers. Lather, rinse, repeat.
2020 if (!PreCommit_Portals(true))
2025 * The remaining actions cannot call any user-defined code, so it's safe
2026 * to start shutting down within-transaction services. But note that most
2027 * of this stuff could still throw an error, which would switch us into
2028 * the transaction-abort path.
2031 /* Shut down the deferred-trigger manager */
2032 AfterTriggerEndXact(true);
2035 * Let ON COMMIT management do its thing (must happen after closing
2036 * cursors, to avoid dangling-reference problems)
2038 PreCommit_on_commit_actions();
2040 /* close large objects before lower-level cleanup */
2041 AtEOXact_LargeObject(true);
2044 * Mark serializable transaction as complete for predicate locking
2045 * purposes. This should be done as late as we can put it and still allow
2046 * errors to be raised for failure patterns found at commit.
2048 PreCommit_CheckForSerializationFailure();
2050 /* NOTIFY will be handled below */
2053 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2054 * this transaction. Having the prepared xact hold locks on another
2055 * backend's temp table seems a bad idea --- for instance it would prevent
2056 * the backend from exiting. There are other problems too, such as how to
2057 * clean up the source backend's local buffers and ON COMMIT state if the
2058 * prepared xact includes a DROP of a temp table.
2060 * We must check this after executing any ON COMMIT actions, because they
2061 * might still access a temp relation.
2063 * XXX In principle this could be relaxed to allow some useful special
2064 * cases, such as a temp table created and dropped all within the
2065 * transaction. That seems to require much more bookkeeping though.
2067 if (MyXactAccessedTempRel)
2069 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2070 errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
2072 /* Prevent cancel/die interrupt while cleaning up */
2076 * set the current transaction state information appropriately during
2077 * prepare processing
2079 s->state = TRANS_PREPARE;
2081 prepared_at = GetCurrentTimestamp();
2083 /* Tell bufmgr and smgr to prepare for commit */
2087 * Reserve the GID for this transaction. This could fail if the requested
2088 * GID is invalid or already in use.
2090 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
2091 GetUserId(), MyDatabaseId);
2095 * Collect data for the 2PC state file. Note that in general, no actual
2096 * state change should happen in the called modules during this step,
2097 * since it's still possible to fail before commit, and in that case we
2098 * want transaction abort to be able to clean up. (In particular, the
2099 * AtPrepare routines may error out if they find cases they cannot
2100 * handle.) State cleanup should happen in the PostPrepare routines
2101 * below. However, some modules can go ahead and clear state here because
2102 * they wouldn't do anything with it during abort anyway.
2104 * Note: because the 2PC state file records will be replayed in the same
2105 * order they are made, the order of these calls has to match the order in
2106 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2107 * PREPARED; in particular, pay attention to whether things should happen
2108 * before or after releasing the transaction's locks.
2110 StartPrepare(gxact);
2114 AtPrepare_PredicateLocks();
2116 AtPrepare_MultiXact();
2117 AtPrepare_RelationMap();
2120 * Here is where we really truly prepare.
2122 * We have to record transaction prepares even if we didn't make any
2123 * updates, because the transaction manager might get confused if we lose
2124 * a global transaction.
2129 * Now we clean up backend-internal state and release internal resources.
2132 /* Reset XactLastRecEnd until the next transaction writes something */
2133 XactLastRecEnd.xrecoff = 0;
2136 * Let others know about no transaction in progress by me. This has to be
2137 * done *after* the prepared transaction has been marked valid, else
2138 * someone may think it is unlocked and recyclable.
2140 ProcArrayClearTransaction(MyProc);
2143 * This is all post-transaction cleanup. Note that if an error is raised
2144 * here, it's too late to abort the transaction. This should be just
2145 * noncritical resource releasing. See notes in CommitTransaction.
2148 CallXactCallbacks(XACT_EVENT_PREPARE);
2150 ResourceOwnerRelease(TopTransactionResourceOwner,
2151 RESOURCE_RELEASE_BEFORE_LOCKS,
2154 /* Check we've released all buffer pins */
2155 AtEOXact_Buffers(true);
2157 /* Clean up the relation cache */
2158 AtEOXact_RelationCache(true);
2160 /* Clean up the snapshot manager */
2161 AtEarlyCommit_Snapshot();
2163 /* notify doesn't need a postprepare call */
2165 PostPrepare_PgStat();
2167 PostPrepare_Inval();
2171 PostPrepare_MultiXact(xid);
2173 PostPrepare_Locks(xid);
2174 PostPrepare_PredicateLocks(xid);
2176 ResourceOwnerRelease(TopTransactionResourceOwner,
2177 RESOURCE_RELEASE_LOCKS,
2179 ResourceOwnerRelease(TopTransactionResourceOwner,
2180 RESOURCE_RELEASE_AFTER_LOCKS,
2183 /* Check we've released all catcache entries */
2184 AtEOXact_CatCache(true);
2186 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2187 AtEOXact_GUC(true, 1);
2189 AtEOXact_on_commit_actions(true);
2190 AtEOXact_Namespace(true);
2191 /* smgrcommit already done */
2193 AtEOXact_ComboCid();
2194 AtEOXact_HashTables(true);
2195 /* don't call AtEOXact_PgStat here */
2196 AtEOXact_Snapshot(true);
2198 CurrentResourceOwner = NULL;
2199 ResourceOwnerDelete(TopTransactionResourceOwner);
2200 s->curTransactionOwner = NULL;
2201 CurTransactionResourceOwner = NULL;
2202 TopTransactionResourceOwner = NULL;
2206 s->transactionId = InvalidTransactionId;
2207 s->subTransactionId = InvalidSubTransactionId;
2208 s->nestingLevel = 0;
2209 s->gucNestLevel = 0;
2210 s->childXids = NULL;
2212 s->maxChildXids = 0;
2215 * done with 1st phase commit processing, set current transaction state
2218 s->state = TRANS_DEFAULT;
2220 RESUME_INTERRUPTS();
2228 AbortTransaction(void)
2230 TransactionState s = CurrentTransactionState;
2231 TransactionId latestXid;
2233 /* Prevent cancel/die interrupt while cleaning up */
2236 /* Make sure we have a valid memory context and resource owner */
2238 AtAbort_ResourceOwner();
2241 * Release any LW locks we might be holding as quickly as possible.
2242 * (Regular locks, however, must be held till we finish aborting.)
2243 * Releasing LW locks is critical since we might try to grab them again
2244 * while cleaning up!
2248 /* Clean up buffer I/O and buffer context locks, too */
2253 * Also clean up any open wait for lock, since the lock manager will choke
2254 * if we try to wait for another lock before doing this.
2259 * check the current transaction state
2261 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2262 elog(WARNING, "AbortTransaction while in %s state",
2263 TransStateAsString(s->state));
2264 Assert(s->parent == NULL);
2267 * set the current transaction state information appropriately during the
2270 s->state = TRANS_ABORT;
2273 * Reset user ID which might have been changed transiently. We need this
2274 * to clean up in case control escaped out of a SECURITY DEFINER function
2275 * or other local change of CurrentUserId; therefore, the prior value of
2276 * SecurityRestrictionContext also needs to be restored.
2278 * (Note: it is not necessary to restore session authorization or role
2279 * settings here because those can only be changed via GUC, and GUC will
2280 * take care of rolling them back if need be.)
2282 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
2285 * do abort processing
2287 AfterTriggerEndXact(false); /* 'false' means it's abort */
2289 AtEOXact_LargeObject(false);
2291 AtEOXact_RelationMap(false);
2294 * Advertise the fact that we aborted in pg_clog (assuming that we got as
2295 * far as assigning an XID to advertise).
2297 latestXid = RecordTransactionAbort(false);
2299 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
2302 * Let others know about no transaction in progress by me. Note that this
2303 * must be done _before_ releasing locks we hold and _after_
2304 * RecordTransactionAbort.
2306 ProcArrayEndTransaction(MyProc, latestXid);
2309 * Post-abort cleanup. See notes in CommitTransaction() concerning
2310 * ordering. We can skip all of it if the transaction failed before
2311 * creating a resource owner.
2313 if (TopTransactionResourceOwner != NULL)
2315 CallXactCallbacks(XACT_EVENT_ABORT);
2317 ResourceOwnerRelease(TopTransactionResourceOwner,
2318 RESOURCE_RELEASE_BEFORE_LOCKS,
2320 AtEOXact_Buffers(false);
2321 AtEOXact_RelationCache(false);
2322 AtEOXact_Inval(false);
2323 smgrDoPendingDeletes(false);
2324 AtEOXact_MultiXact();
2325 ResourceOwnerRelease(TopTransactionResourceOwner,
2326 RESOURCE_RELEASE_LOCKS,
2328 ResourceOwnerRelease(TopTransactionResourceOwner,
2329 RESOURCE_RELEASE_AFTER_LOCKS,
2331 AtEOXact_CatCache(false);
2333 AtEOXact_GUC(false, 1);
2334 AtEOXact_SPI(false);
2335 AtEOXact_on_commit_actions(false);
2336 AtEOXact_Namespace(false);
2338 AtEOXact_ComboCid();
2339 AtEOXact_HashTables(false);
2340 AtEOXact_PgStat(false);
2341 AtEOXact_Snapshot(false);
2342 pgstat_report_xact_timestamp(0);
2346 * State remains TRANS_ABORT until CleanupTransaction().
2348 RESUME_INTERRUPTS();
2352 * CleanupTransaction
2355 CleanupTransaction(void)
2357 TransactionState s = CurrentTransactionState;
2360 * State should still be TRANS_ABORT from AbortTransaction().
2362 if (s->state != TRANS_ABORT)
2363 elog(FATAL, "CleanupTransaction: unexpected state %s",
2364 TransStateAsString(s->state));
2367 * do abort cleanup processing
2369 AtCleanup_Portals(); /* now safe to release portal memory */
2371 CurrentResourceOwner = NULL; /* and resource owner */
2372 if (TopTransactionResourceOwner)
2373 ResourceOwnerDelete(TopTransactionResourceOwner);
2374 s->curTransactionOwner = NULL;
2375 CurTransactionResourceOwner = NULL;
2376 TopTransactionResourceOwner = NULL;
2378 AtCleanup_Memory(); /* and transaction memory */
2380 s->transactionId = InvalidTransactionId;
2381 s->subTransactionId = InvalidSubTransactionId;
2382 s->nestingLevel = 0;
2383 s->gucNestLevel = 0;
2384 s->childXids = NULL;
2386 s->maxChildXids = 0;
2389 * done with abort processing, set current transaction state back to
2392 s->state = TRANS_DEFAULT;
2396 * StartTransactionCommand
2399 StartTransactionCommand(void)
2401 TransactionState s = CurrentTransactionState;
2403 switch (s->blockState)
2406 * if we aren't in a transaction block, we just do our usual start
2409 case TBLOCK_DEFAULT:
2411 s->blockState = TBLOCK_STARTED;
2415 * We are somewhere in a transaction block or subtransaction and
2416 * about to start a new command. For now we do nothing, but
2417 * someday we may do command-local resource initialization. (Note
2418 * that any needed CommandCounterIncrement was done by the
2419 * previous CommitTransactionCommand.)
2421 case TBLOCK_INPROGRESS:
2422 case TBLOCK_SUBINPROGRESS:
2426 * Here we are in a failed transaction block (one of the commands
2427 * caused an abort) so we do nothing but remain in the abort
2428 * state. Eventually we will get a ROLLBACK command which will
2429 * get us out of this state. (It is up to other code to ensure
2430 * that no commands other than ROLLBACK will be processed in these
2434 case TBLOCK_SUBABORT:
2437 /* These cases are invalid. */
2438 case TBLOCK_STARTED:
2440 case TBLOCK_SUBBEGIN:
2442 case TBLOCK_SUBRELEASE:
2443 case TBLOCK_SUBCOMMIT:
2444 case TBLOCK_ABORT_END:
2445 case TBLOCK_SUBABORT_END:
2446 case TBLOCK_ABORT_PENDING:
2447 case TBLOCK_SUBABORT_PENDING:
2448 case TBLOCK_SUBRESTART:
2449 case TBLOCK_SUBABORT_RESTART:
2450 case TBLOCK_PREPARE:
2451 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2452 BlockStateAsString(s->blockState));
2457 * We must switch to CurTransactionContext before returning. This is
2458 * already done if we called StartTransaction, otherwise not.
2460 Assert(CurTransactionContext != NULL);
2461 MemoryContextSwitchTo(CurTransactionContext);
2465 * CommitTransactionCommand
2468 CommitTransactionCommand(void)
2470 TransactionState s = CurrentTransactionState;
2472 switch (s->blockState)
2475 * This shouldn't happen, because it means the previous
2476 * StartTransactionCommand didn't set the STARTED state
2479 case TBLOCK_DEFAULT:
2480 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2481 BlockStateAsString(s->blockState));
2485 * If we aren't in a transaction block, just do our usual
2486 * transaction commit, and return to the idle state.
2488 case TBLOCK_STARTED:
2489 CommitTransaction();
2490 s->blockState = TBLOCK_DEFAULT;
2494 * We are completing a "BEGIN TRANSACTION" command, so we change
2495 * to the "transaction block in progress" state and return. (We
2496 * assume the BEGIN did nothing to the database, so we need no
2497 * CommandCounterIncrement.)
2500 s->blockState = TBLOCK_INPROGRESS;
2504 * This is the case when we have finished executing a command
2505 * someplace within a transaction block. We increment the command
2506 * counter and return.
2508 case TBLOCK_INPROGRESS:
2509 case TBLOCK_SUBINPROGRESS:
2510 CommandCounterIncrement();
2514 * We are completing a "COMMIT" command. Do it and return to the
2518 CommitTransaction();
2519 s->blockState = TBLOCK_DEFAULT;
2523 * Here we are in the middle of a transaction block but one of the
2524 * commands caused an abort so we do nothing but remain in the
2525 * abort state. Eventually we will get a ROLLBACK comand.
2528 case TBLOCK_SUBABORT:
2532 * Here we were in an aborted transaction block and we just got
2533 * the ROLLBACK command from the user, so clean up the
2534 * already-aborted transaction and return to the idle state.
2536 case TBLOCK_ABORT_END:
2537 CleanupTransaction();
2538 s->blockState = TBLOCK_DEFAULT;
2542 * Here we were in a perfectly good transaction block but the user
2543 * told us to ROLLBACK anyway. We have to abort the transaction
2544 * and then clean up.
2546 case TBLOCK_ABORT_PENDING:
2548 CleanupTransaction();
2549 s->blockState = TBLOCK_DEFAULT;
2553 * We are completing a "PREPARE TRANSACTION" command. Do it and
2554 * return to the idle state.
2556 case TBLOCK_PREPARE:
2557 PrepareTransaction();
2558 s->blockState = TBLOCK_DEFAULT;
2562 * We were just issued a SAVEPOINT inside a transaction block.
2563 * Start a subtransaction. (DefineSavepoint already did
2564 * PushTransaction, so as to have someplace to put the SUBBEGIN
2567 case TBLOCK_SUBBEGIN:
2568 StartSubTransaction();
2569 s->blockState = TBLOCK_SUBINPROGRESS;
2573 * We were issued a RELEASE command, so we end the
2574 * current subtransaction and return to the parent transaction.
2575 * The parent might be ended too, so repeat till we find an
2576 * INPROGRESS transaction or subtransaction.
2578 case TBLOCK_SUBRELEASE:
2581 CommitSubTransaction();
2582 s = CurrentTransactionState; /* changed by pop */
2583 } while (s->blockState == TBLOCK_SUBRELEASE);
2585 Assert(s->blockState == TBLOCK_INPROGRESS ||
2586 s->blockState == TBLOCK_SUBINPROGRESS);
2590 * We were issued a COMMIT, so we end the current subtransaction
2591 * hierarchy and perform final commit. We do this by rolling up
2592 * any subtransactions into their parent, which leads to O(N^2)
2593 * operations with respect to resource owners - this isn't that
2594 * bad until we approach a thousands of savepoints but is necessary
2595 * for correctness should after triggers create new resource
2598 case TBLOCK_SUBCOMMIT:
2601 CommitSubTransaction();
2602 s = CurrentTransactionState; /* changed by pop */
2603 } while (s->blockState == TBLOCK_SUBCOMMIT);
2604 /* If we had a COMMIT command, finish off the main xact too */
2605 if (s->blockState == TBLOCK_END)
2607 Assert(s->parent == NULL);
2608 CommitTransaction();
2609 s->blockState = TBLOCK_DEFAULT;
2611 else if (s->blockState == TBLOCK_PREPARE)
2613 Assert(s->parent == NULL);
2614 PrepareTransaction();
2615 s->blockState = TBLOCK_DEFAULT;
2618 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
2619 BlockStateAsString(s->blockState));
2623 * The current already-failed subtransaction is ending due to a
2624 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2625 * examine the parent (which could be in any of several states).
2627 case TBLOCK_SUBABORT_END:
2628 CleanupSubTransaction();
2629 CommitTransactionCommand();
2633 * As above, but it's not dead yet, so abort first.
2635 case TBLOCK_SUBABORT_PENDING:
2636 AbortSubTransaction();
2637 CleanupSubTransaction();
2638 CommitTransactionCommand();
2642 * The current subtransaction is the target of a ROLLBACK TO
2643 * command. Abort and pop it, then start a new subtransaction
2644 * with the same name.
2646 case TBLOCK_SUBRESTART:
2651 /* save name and keep Cleanup from freeing it */
2654 savepointLevel = s->savepointLevel;
2656 AbortSubTransaction();
2657 CleanupSubTransaction();
2659 DefineSavepoint(NULL);
2660 s = CurrentTransactionState; /* changed by push */
2662 s->savepointLevel = savepointLevel;
2664 /* This is the same as TBLOCK_SUBBEGIN case */
2665 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2666 StartSubTransaction();
2667 s->blockState = TBLOCK_SUBINPROGRESS;
2672 * Same as above, but the subtransaction had already failed, so we
2673 * don't need AbortSubTransaction.
2675 case TBLOCK_SUBABORT_RESTART:
2680 /* save name and keep Cleanup from freeing it */
2683 savepointLevel = s->savepointLevel;
2685 CleanupSubTransaction();
2687 DefineSavepoint(NULL);
2688 s = CurrentTransactionState; /* changed by push */
2690 s->savepointLevel = savepointLevel;
2692 /* This is the same as TBLOCK_SUBBEGIN case */
2693 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2694 StartSubTransaction();
2695 s->blockState = TBLOCK_SUBINPROGRESS;
2702 * AbortCurrentTransaction
2705 AbortCurrentTransaction(void)
2707 TransactionState s = CurrentTransactionState;
2709 switch (s->blockState)
2711 case TBLOCK_DEFAULT:
2712 if (s->state == TRANS_DEFAULT)
2714 /* we are idle, so nothing to do */
2719 * We can get here after an error during transaction start
2720 * (state will be TRANS_START). Need to clean up the
2721 * incompletely started transaction. First, adjust the
2722 * low-level state to suppress warning message from
2725 if (s->state == TRANS_START)
2726 s->state = TRANS_INPROGRESS;
2728 CleanupTransaction();
2733 * if we aren't in a transaction block, we just do the basic abort
2734 * & cleanup transaction.
2736 case TBLOCK_STARTED:
2738 CleanupTransaction();
2739 s->blockState = TBLOCK_DEFAULT;
2743 * If we are in TBLOCK_BEGIN it means something screwed up right
2744 * after reading "BEGIN TRANSACTION". We assume that the user
2745 * will interpret the error as meaning the BEGIN failed to get him
2746 * into a transaction block, so we should abort and return to idle
2751 CleanupTransaction();
2752 s->blockState = TBLOCK_DEFAULT;
2756 * We are somewhere in a transaction block and we've gotten a
2757 * failure, so we abort the transaction and set up the persistent
2758 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
2760 case TBLOCK_INPROGRESS:
2762 s->blockState = TBLOCK_ABORT;
2763 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
2767 * Here, we failed while trying to COMMIT. Clean up the
2768 * transaction and return to idle state (we do not want to stay in
2773 CleanupTransaction();
2774 s->blockState = TBLOCK_DEFAULT;
2778 * Here, we are already in an aborted transaction state and are
2779 * waiting for a ROLLBACK, but for some reason we failed again! So
2780 * we just remain in the abort state.
2783 case TBLOCK_SUBABORT:
2787 * We are in a failed transaction and we got the ROLLBACK command.
2788 * We have already aborted, we just need to cleanup and go to idle
2791 case TBLOCK_ABORT_END:
2792 CleanupTransaction();
2793 s->blockState = TBLOCK_DEFAULT;
2797 * We are in a live transaction and we got a ROLLBACK command.
2798 * Abort, cleanup, go to idle state.
2800 case TBLOCK_ABORT_PENDING:
2802 CleanupTransaction();
2803 s->blockState = TBLOCK_DEFAULT;
2807 * Here, we failed while trying to PREPARE. Clean up the
2808 * transaction and return to idle state (we do not want to stay in
2811 case TBLOCK_PREPARE:
2813 CleanupTransaction();
2814 s->blockState = TBLOCK_DEFAULT;
2818 * We got an error inside a subtransaction. Abort just the
2819 * subtransaction, and go to the persistent SUBABORT state until
2822 case TBLOCK_SUBINPROGRESS:
2823 AbortSubTransaction();
2824 s->blockState = TBLOCK_SUBABORT;
2828 * If we failed while trying to create a subtransaction, clean up
2829 * the broken subtransaction and abort the parent. The same
2830 * applies if we get a failure while ending a subtransaction.
2832 case TBLOCK_SUBBEGIN:
2833 case TBLOCK_SUBRELEASE:
2834 case TBLOCK_SUBCOMMIT:
2835 case TBLOCK_SUBABORT_PENDING:
2836 case TBLOCK_SUBRESTART:
2837 AbortSubTransaction();
2838 CleanupSubTransaction();
2839 AbortCurrentTransaction();
2843 * Same as above, except the Abort() was already done.
2845 case TBLOCK_SUBABORT_END:
2846 case TBLOCK_SUBABORT_RESTART:
2847 CleanupSubTransaction();
2848 AbortCurrentTransaction();
2854 * PreventTransactionChain
2856 * This routine is to be called by statements that must not run inside
2857 * a transaction block, typically because they have non-rollback-able
2858 * side effects or do internal commits.
2860 * If we have already started a transaction block, issue an error; also issue
2861 * an error if we appear to be running inside a user-defined function (which
2862 * could issue more commands and possibly cause a failure after the statement
2863 * completes). Subtransactions are verboten too.
2865 * isTopLevel: passed down from ProcessUtility to determine whether we are
2866 * inside a function or multi-query querystring. (We will always fail if
2867 * this is false, but it's convenient to centralize the check here instead of
2868 * making callers do it.)
2869 * stmtType: statement type name, for error messages.
2872 PreventTransactionChain(bool isTopLevel, const char *stmtType)
2875 * xact block already started?
2877 if (IsTransactionBlock())
2879 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2880 /* translator: %s represents an SQL statement name */
2881 errmsg("%s cannot run inside a transaction block",
2887 if (IsSubTransaction())
2889 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2890 /* translator: %s represents an SQL statement name */
2891 errmsg("%s cannot run inside a subtransaction",
2895 * inside a function call?
2899 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2900 /* translator: %s represents an SQL statement name */
2901 errmsg("%s cannot be executed from a function or multi-command string",
2904 /* If we got past IsTransactionBlock test, should be in default state */
2905 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2906 CurrentTransactionState->blockState != TBLOCK_STARTED)
2907 elog(FATAL, "cannot prevent transaction chain");
2912 * RequireTransactionChain
2914 * This routine is to be called by statements that must run inside
2915 * a transaction block, because they have no effects that persist past
2916 * transaction end (and so calling them outside a transaction block
2917 * is presumably an error). DECLARE CURSOR is an example.
2919 * If we appear to be running inside a user-defined function, we do not
2920 * issue an error, since the function could issue more commands that make
2921 * use of the current statement's results. Likewise subtransactions.
2922 * Thus this is an inverse for PreventTransactionChain.
2924 * isTopLevel: passed down from ProcessUtility to determine whether we are
2925 * inside a function.
2926 * stmtType: statement type name, for error messages.
2929 RequireTransactionChain(bool isTopLevel, const char *stmtType)
2932 * xact block already started?
2934 if (IsTransactionBlock())
2940 if (IsSubTransaction())
2944 * inside a function call?
2950 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2951 /* translator: %s represents an SQL statement name */
2952 errmsg("%s can only be used in transaction blocks",
2957 * IsInTransactionChain
2959 * This routine is for statements that need to behave differently inside
2960 * a transaction block than when running as single commands. ANALYZE is
2961 * currently the only example.
2963 * isTopLevel: passed down from ProcessUtility to determine whether we are
2964 * inside a function.
2967 IsInTransactionChain(bool isTopLevel)
2970 * Return true on same conditions that would make PreventTransactionChain
2973 if (IsTransactionBlock())
2976 if (IsSubTransaction())
2982 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2983 CurrentTransactionState->blockState != TBLOCK_STARTED)
2991 * Register or deregister callback functions for start- and end-of-xact
2994 * These functions are intended for use by dynamically loaded modules.
2995 * For built-in modules we generally just hardwire the appropriate calls
2996 * (mainly because it's easier to control the order that way, where needed).
2998 * At transaction end, the callback occurs post-commit or post-abort, so the
2999 * callback functions can only do noncritical cleanup.
3002 RegisterXactCallback(XactCallback callback, void *arg)
3004 XactCallbackItem *item;
3006 item = (XactCallbackItem *)
3007 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
3008 item->callback = callback;
3010 item->next = Xact_callbacks;
3011 Xact_callbacks = item;
3015 UnregisterXactCallback(XactCallback callback, void *arg)
3017 XactCallbackItem *item;
3018 XactCallbackItem *prev;
3021 for (item = Xact_callbacks; item; prev = item, item = item->next)
3023 if (item->callback == callback && item->arg == arg)
3026 prev->next = item->next;
3028 Xact_callbacks = item->next;
3036 CallXactCallbacks(XactEvent event)
3038 XactCallbackItem *item;
3040 for (item = Xact_callbacks; item; item = item->next)
3041 (*item->callback) (event, item->arg);
3046 * Register or deregister callback functions for start- and end-of-subxact
3049 * Pretty much same as above, but for subtransaction events.
3051 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3052 * so the callback functions can only do noncritical cleanup. At
3053 * subtransaction start, the callback is called when the subtransaction has
3054 * finished initializing.
3057 RegisterSubXactCallback(SubXactCallback callback, void *arg)
3059 SubXactCallbackItem *item;
3061 item = (SubXactCallbackItem *)
3062 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
3063 item->callback = callback;
3065 item->next = SubXact_callbacks;
3066 SubXact_callbacks = item;
3070 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
3072 SubXactCallbackItem *item;
3073 SubXactCallbackItem *prev;
3076 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3078 if (item->callback == callback && item->arg == arg)
3081 prev->next = item->next;
3083 SubXact_callbacks = item->next;
3091 CallSubXactCallbacks(SubXactEvent event,
3092 SubTransactionId mySubid,
3093 SubTransactionId parentSubid)
3095 SubXactCallbackItem *item;
3097 for (item = SubXact_callbacks; item; item = item->next)
3098 (*item->callback) (event, mySubid, parentSubid, item->arg);
3102 /* ----------------------------------------------------------------
3103 * transaction block support
3104 * ----------------------------------------------------------------
3108 * BeginTransactionBlock
3109 * This executes a BEGIN command.
3112 BeginTransactionBlock(void)
3114 TransactionState s = CurrentTransactionState;
3116 switch (s->blockState)
3119 * We are not inside a transaction block, so allow one to begin.
3121 case TBLOCK_STARTED:
3122 s->blockState = TBLOCK_BEGIN;
3126 * Already a transaction block in progress.
3128 case TBLOCK_INPROGRESS:
3129 case TBLOCK_SUBINPROGRESS:
3131 case TBLOCK_SUBABORT:
3133 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3134 errmsg("there is already a transaction in progress")));
3137 /* These cases are invalid. */
3138 case TBLOCK_DEFAULT:
3140 case TBLOCK_SUBBEGIN:
3142 case TBLOCK_SUBRELEASE:
3143 case TBLOCK_SUBCOMMIT:
3144 case TBLOCK_ABORT_END:
3145 case TBLOCK_SUBABORT_END:
3146 case TBLOCK_ABORT_PENDING:
3147 case TBLOCK_SUBABORT_PENDING:
3148 case TBLOCK_SUBRESTART:
3149 case TBLOCK_SUBABORT_RESTART:
3150 case TBLOCK_PREPARE:
3151 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3152 BlockStateAsString(s->blockState));
3158 * PrepareTransactionBlock
3159 * This executes a PREPARE command.
3161 * Since PREPARE may actually do a ROLLBACK, the result indicates what
3162 * happened: TRUE for PREPARE, FALSE for ROLLBACK.
3164 * Note that we don't actually do anything here except change blockState.
3165 * The real work will be done in the upcoming PrepareTransaction().
3166 * We do it this way because it's not convenient to change memory context,
3167 * resource owner, etc while executing inside a Portal.
3170 PrepareTransactionBlock(char *gid)
3175 /* Set up to commit the current transaction */
3176 result = EndTransactionBlock();
3178 /* If successful, change outer tblock state to PREPARE */
3181 s = CurrentTransactionState;
3183 while (s->parent != NULL)
3186 if (s->blockState == TBLOCK_END)
3188 /* Save GID where PrepareTransaction can find it again */
3189 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
3191 s->blockState = TBLOCK_PREPARE;
3196 * ignore case where we are not in a transaction;
3197 * EndTransactionBlock already issued a warning.
3199 Assert(s->blockState == TBLOCK_STARTED);
3200 /* Don't send back a PREPARE result tag... */
3209 * EndTransactionBlock
3210 * This executes a COMMIT command.
3212 * Since COMMIT may actually do a ROLLBACK, the result indicates what
3213 * happened: TRUE for COMMIT, FALSE for ROLLBACK.
3215 * Note that we don't actually do anything here except change blockState.
3216 * The real work will be done in the upcoming CommitTransactionCommand().
3217 * We do it this way because it's not convenient to change memory context,
3218 * resource owner, etc while executing inside a Portal.
3221 EndTransactionBlock(void)
3223 TransactionState s = CurrentTransactionState;
3224 bool result = false;
3226 switch (s->blockState)
3229 * We are in a transaction block, so tell CommitTransactionCommand
3232 case TBLOCK_INPROGRESS:
3233 s->blockState = TBLOCK_END;
3238 * We are in a failed transaction block. Tell
3239 * CommitTransactionCommand it's time to exit the block.
3242 s->blockState = TBLOCK_ABORT_END;
3246 * We are in a live subtransaction block. Set up to subcommit all
3247 * open subtransactions and then commit the main transaction.
3249 case TBLOCK_SUBINPROGRESS:
3250 while (s->parent != NULL)
3252 if (s->blockState == TBLOCK_SUBINPROGRESS)
3253 s->blockState = TBLOCK_SUBCOMMIT;
3255 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3256 BlockStateAsString(s->blockState));
3259 if (s->blockState == TBLOCK_INPROGRESS)
3260 s->blockState = TBLOCK_END;
3262 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3263 BlockStateAsString(s->blockState));
3268 * Here we are inside an aborted subtransaction. Treat the COMMIT
3269 * as ROLLBACK: set up to abort everything and exit the main
3272 case TBLOCK_SUBABORT:
3273 while (s->parent != NULL)
3275 if (s->blockState == TBLOCK_SUBINPROGRESS)
3276 s->blockState = TBLOCK_SUBABORT_PENDING;
3277 else if (s->blockState == TBLOCK_SUBABORT)
3278 s->blockState = TBLOCK_SUBABORT_END;
3280 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3281 BlockStateAsString(s->blockState));
3284 if (s->blockState == TBLOCK_INPROGRESS)
3285 s->blockState = TBLOCK_ABORT_PENDING;
3286 else if (s->blockState == TBLOCK_ABORT)
3287 s->blockState = TBLOCK_ABORT_END;
3289 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3290 BlockStateAsString(s->blockState));
3294 * The user issued COMMIT when not inside a transaction. Issue a
3295 * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
3296 * CommitTransactionCommand() will then close the transaction and
3297 * put us back into the default state.
3299 case TBLOCK_STARTED:
3301 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3302 errmsg("there is no transaction in progress")));
3306 /* These cases are invalid. */
3307 case TBLOCK_DEFAULT:
3309 case TBLOCK_SUBBEGIN:
3311 case TBLOCK_SUBRELEASE:
3312 case TBLOCK_SUBCOMMIT:
3313 case TBLOCK_ABORT_END:
3314 case TBLOCK_SUBABORT_END:
3315 case TBLOCK_ABORT_PENDING:
3316 case TBLOCK_SUBABORT_PENDING:
3317 case TBLOCK_SUBRESTART:
3318 case TBLOCK_SUBABORT_RESTART:
3319 case TBLOCK_PREPARE:
3320 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3321 BlockStateAsString(s->blockState));
3329 * UserAbortTransactionBlock
3330 * This executes a ROLLBACK command.
3332 * As above, we don't actually do anything here except change blockState.
3335 UserAbortTransactionBlock(void)
3337 TransactionState s = CurrentTransactionState;
3339 switch (s->blockState)
3342 * We are inside a transaction block and we got a ROLLBACK command
3343 * from the user, so tell CommitTransactionCommand to abort and
3344 * exit the transaction block.
3346 case TBLOCK_INPROGRESS:
3347 s->blockState = TBLOCK_ABORT_PENDING;
3351 * We are inside a failed transaction block and we got a ROLLBACK
3352 * command from the user. Abort processing is already done, so
3353 * CommitTransactionCommand just has to cleanup and go back to
3357 s->blockState = TBLOCK_ABORT_END;
3361 * We are inside a subtransaction. Mark everything up to top
3362 * level as exitable.
3364 case TBLOCK_SUBINPROGRESS:
3365 case TBLOCK_SUBABORT:
3366 while (s->parent != NULL)
3368 if (s->blockState == TBLOCK_SUBINPROGRESS)
3369 s->blockState = TBLOCK_SUBABORT_PENDING;
3370 else if (s->blockState == TBLOCK_SUBABORT)
3371 s->blockState = TBLOCK_SUBABORT_END;
3373 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3374 BlockStateAsString(s->blockState));
3377 if (s->blockState == TBLOCK_INPROGRESS)
3378 s->blockState = TBLOCK_ABORT_PENDING;
3379 else if (s->blockState == TBLOCK_ABORT)
3380 s->blockState = TBLOCK_ABORT_END;
3382 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3383 BlockStateAsString(s->blockState));
3387 * The user issued ABORT when not inside a transaction. Issue a
3388 * WARNING and go to abort state. The upcoming call to
3389 * CommitTransactionCommand() will then put us back into the
3392 case TBLOCK_STARTED:
3394 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3395 errmsg("there is no transaction in progress")));
3396 s->blockState = TBLOCK_ABORT_PENDING;
3399 /* These cases are invalid. */
3400 case TBLOCK_DEFAULT:
3402 case TBLOCK_SUBBEGIN:
3404 case TBLOCK_SUBRELEASE:
3405 case TBLOCK_SUBCOMMIT:
3406 case TBLOCK_ABORT_END:
3407 case TBLOCK_SUBABORT_END:
3408 case TBLOCK_ABORT_PENDING:
3409 case TBLOCK_SUBABORT_PENDING:
3410 case TBLOCK_SUBRESTART:
3411 case TBLOCK_SUBABORT_RESTART:
3412 case TBLOCK_PREPARE:
3413 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3414 BlockStateAsString(s->blockState));
3421 * This executes a SAVEPOINT command.
3424 DefineSavepoint(char *name)
3426 TransactionState s = CurrentTransactionState;
3428 switch (s->blockState)
3430 case TBLOCK_INPROGRESS:
3431 case TBLOCK_SUBINPROGRESS:
3432 /* Normal subtransaction start */
3434 s = CurrentTransactionState; /* changed by push */
3437 * Savepoint names, like the TransactionState block itself, live
3438 * in TopTransactionContext.
3441 s->name = MemoryContextStrdup(TopTransactionContext, name);
3444 /* These cases are invalid. */
3445 case TBLOCK_DEFAULT:
3446 case TBLOCK_STARTED:
3448 case TBLOCK_SUBBEGIN:
3450 case TBLOCK_SUBRELEASE:
3451 case TBLOCK_SUBCOMMIT:
3453 case TBLOCK_SUBABORT:
3454 case TBLOCK_ABORT_END:
3455 case TBLOCK_SUBABORT_END:
3456 case TBLOCK_ABORT_PENDING:
3457 case TBLOCK_SUBABORT_PENDING:
3458 case TBLOCK_SUBRESTART:
3459 case TBLOCK_SUBABORT_RESTART:
3460 case TBLOCK_PREPARE:
3461 elog(FATAL, "DefineSavepoint: unexpected state %s",
3462 BlockStateAsString(s->blockState));
3469 * This executes a RELEASE command.
3471 * As above, we don't actually do anything here except change blockState.
3474 ReleaseSavepoint(List *options)
3476 TransactionState s = CurrentTransactionState;
3477 TransactionState target,
3482 switch (s->blockState)
3485 * We can't rollback to a savepoint if there is no savepoint
3488 case TBLOCK_INPROGRESS:
3490 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3491 errmsg("no such savepoint")));
3495 * We are in a non-aborted subtransaction. This is the only valid
3498 case TBLOCK_SUBINPROGRESS:
3501 /* These cases are invalid. */
3502 case TBLOCK_DEFAULT:
3503 case TBLOCK_STARTED:
3505 case TBLOCK_SUBBEGIN:
3507 case TBLOCK_SUBRELEASE:
3508 case TBLOCK_SUBCOMMIT:
3510 case TBLOCK_SUBABORT:
3511 case TBLOCK_ABORT_END:
3512 case TBLOCK_SUBABORT_END:
3513 case TBLOCK_ABORT_PENDING:
3514 case TBLOCK_SUBABORT_PENDING:
3515 case TBLOCK_SUBRESTART:
3516 case TBLOCK_SUBABORT_RESTART:
3517 case TBLOCK_PREPARE:
3518 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3519 BlockStateAsString(s->blockState));
3523 foreach(cell, options)
3525 DefElem *elem = lfirst(cell);
3527 if (strcmp(elem->defname, "savepoint_name") == 0)
3528 name = strVal(elem->arg);
3531 Assert(PointerIsValid(name));
3533 for (target = s; PointerIsValid(target); target = target->parent)
3535 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3539 if (!PointerIsValid(target))
3541 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3542 errmsg("no such savepoint")));
3544 /* disallow crossing savepoint level boundaries */
3545 if (target->savepointLevel != s->savepointLevel)
3547 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3548 errmsg("no such savepoint")));
3551 * Mark "commit pending" all subtransactions up to the target
3552 * subtransaction. The actual commits will happen when control gets to
3553 * CommitTransactionCommand.
3555 xact = CurrentTransactionState;
3558 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3559 xact->blockState = TBLOCK_SUBRELEASE;
3562 xact = xact->parent;
3563 Assert(PointerIsValid(xact));
3568 * RollbackToSavepoint
3569 * This executes a ROLLBACK TO <savepoint> command.
3571 * As above, we don't actually do anything here except change blockState.
3574 RollbackToSavepoint(List *options)
3576 TransactionState s = CurrentTransactionState;
3577 TransactionState target,
3582 switch (s->blockState)
3585 * We can't rollback to a savepoint if there is no savepoint
3588 case TBLOCK_INPROGRESS:
3591 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3592 errmsg("no such savepoint")));
3596 * There is at least one savepoint, so proceed.
3598 case TBLOCK_SUBINPROGRESS:
3599 case TBLOCK_SUBABORT:
3602 /* These cases are invalid. */
3603 case TBLOCK_DEFAULT:
3604 case TBLOCK_STARTED:
3606 case TBLOCK_SUBBEGIN:
3608 case TBLOCK_SUBRELEASE:
3609 case TBLOCK_SUBCOMMIT:
3610 case TBLOCK_ABORT_END:
3611 case TBLOCK_SUBABORT_END:
3612 case TBLOCK_ABORT_PENDING:
3613 case TBLOCK_SUBABORT_PENDING:
3614 case TBLOCK_SUBRESTART:
3615 case TBLOCK_SUBABORT_RESTART:
3616 case TBLOCK_PREPARE:
3617 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3618 BlockStateAsString(s->blockState));
3622 foreach(cell, options)
3624 DefElem *elem = lfirst(cell);
3626 if (strcmp(elem->defname, "savepoint_name") == 0)
3627 name = strVal(elem->arg);
3630 Assert(PointerIsValid(name));
3632 for (target = s; PointerIsValid(target); target = target->parent)
3634 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3638 if (!PointerIsValid(target))
3640 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3641 errmsg("no such savepoint")));
3643 /* disallow crossing savepoint level boundaries */
3644 if (target->savepointLevel != s->savepointLevel)
3646 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3647 errmsg("no such savepoint")));
3650 * Mark "abort pending" all subtransactions up to the target
3651 * subtransaction. The actual aborts will happen when control gets to
3652 * CommitTransactionCommand.
3654 xact = CurrentTransactionState;
3659 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3660 xact->blockState = TBLOCK_SUBABORT_PENDING;
3661 else if (xact->blockState == TBLOCK_SUBABORT)
3662 xact->blockState = TBLOCK_SUBABORT_END;
3664 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3665 BlockStateAsString(xact->blockState));
3666 xact = xact->parent;
3667 Assert(PointerIsValid(xact));
3670 /* And mark the target as "restart pending" */
3671 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3672 xact->blockState = TBLOCK_SUBRESTART;
3673 else if (xact->blockState == TBLOCK_SUBABORT)
3674 xact->blockState = TBLOCK_SUBABORT_RESTART;
3676 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3677 BlockStateAsString(xact->blockState));
3681 * BeginInternalSubTransaction
3682 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
3683 * TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
3684 * used in functions that might be called when not inside a BEGIN block
3685 * or when running deferred triggers at COMMIT/PREPARE time. Also, it
3686 * automatically does CommitTransactionCommand/StartTransactionCommand
3687 * instead of expecting the caller to do it.
3690 BeginInternalSubTransaction(char *name)
3692 TransactionState s = CurrentTransactionState;
3694 switch (s->blockState)
3696 case TBLOCK_STARTED:
3697 case TBLOCK_INPROGRESS:
3699 case TBLOCK_PREPARE:
3700 case TBLOCK_SUBINPROGRESS:
3701 /* Normal subtransaction start */
3703 s = CurrentTransactionState; /* changed by push */
3706 * Savepoint names, like the TransactionState block itself, live
3707 * in TopTransactionContext.
3710 s->name = MemoryContextStrdup(TopTransactionContext, name);
3713 /* These cases are invalid. */
3714 case TBLOCK_DEFAULT:
3716 case TBLOCK_SUBBEGIN:
3717 case TBLOCK_SUBRELEASE:
3718 case TBLOCK_SUBCOMMIT:
3720 case TBLOCK_SUBABORT:
3721 case TBLOCK_ABORT_END:
3722 case TBLOCK_SUBABORT_END:
3723 case TBLOCK_ABORT_PENDING:
3724 case TBLOCK_SUBABORT_PENDING:
3725 case TBLOCK_SUBRESTART:
3726 case TBLOCK_SUBABORT_RESTART:
3727 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
3728 BlockStateAsString(s->blockState));
3732 CommitTransactionCommand();
3733 StartTransactionCommand();
3737 * ReleaseCurrentSubTransaction
3739 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
3740 * savepoint name (if any).
3741 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3744 ReleaseCurrentSubTransaction(void)
3746 TransactionState s = CurrentTransactionState;
3748 if (s->blockState != TBLOCK_SUBINPROGRESS)
3749 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
3750 BlockStateAsString(s->blockState));
3751 Assert(s->state == TRANS_INPROGRESS);
3752 MemoryContextSwitchTo(CurTransactionContext);
3753 CommitSubTransaction();
3754 s = CurrentTransactionState; /* changed by pop */
3755 Assert(s->state == TRANS_INPROGRESS);
3759 * RollbackAndReleaseCurrentSubTransaction
3761 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
3762 * of its savepoint name (if any).
3763 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3766 RollbackAndReleaseCurrentSubTransaction(void)
3768 TransactionState s = CurrentTransactionState;
3770 switch (s->blockState)
3772 /* Must be in a subtransaction */
3773 case TBLOCK_SUBINPROGRESS:
3774 case TBLOCK_SUBABORT:
3777 /* These cases are invalid. */
3778 case TBLOCK_DEFAULT:
3779 case TBLOCK_STARTED:
3781 case TBLOCK_SUBBEGIN:
3782 case TBLOCK_INPROGRESS:
3784 case TBLOCK_SUBRELEASE:
3785 case TBLOCK_SUBCOMMIT:
3787 case TBLOCK_ABORT_END:
3788 case TBLOCK_SUBABORT_END:
3789 case TBLOCK_ABORT_PENDING:
3790 case TBLOCK_SUBABORT_PENDING:
3791 case TBLOCK_SUBRESTART:
3792 case TBLOCK_SUBABORT_RESTART:
3793 case TBLOCK_PREPARE:
3794 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
3795 BlockStateAsString(s->blockState));
3800 * Abort the current subtransaction, if needed.
3802 if (s->blockState == TBLOCK_SUBINPROGRESS)
3803 AbortSubTransaction();
3805 /* And clean it up, too */
3806 CleanupSubTransaction();
3808 s = CurrentTransactionState; /* changed by pop */
3809 AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
3810 s->blockState == TBLOCK_INPROGRESS ||
3811 s->blockState == TBLOCK_STARTED);
3815 * AbortOutOfAnyTransaction
3817 * This routine is provided for error recovery purposes. It aborts any
3818 * active transaction or transaction block, leaving the system in a known
3822 AbortOutOfAnyTransaction(void)
3824 TransactionState s = CurrentTransactionState;
3827 * Get out of any transaction or nested transaction
3831 switch (s->blockState)
3833 case TBLOCK_DEFAULT:
3834 /* Not in a transaction, do nothing */
3836 case TBLOCK_STARTED:
3838 case TBLOCK_INPROGRESS:
3840 case TBLOCK_ABORT_PENDING:
3841 case TBLOCK_PREPARE:
3842 /* In a transaction, so clean up */
3844 CleanupTransaction();
3845 s->blockState = TBLOCK_DEFAULT;
3848 case TBLOCK_ABORT_END:
3849 /* AbortTransaction already done, still need Cleanup */
3850 CleanupTransaction();
3851 s->blockState = TBLOCK_DEFAULT;
3855 * In a subtransaction, so clean it up and abort parent too
3857 case TBLOCK_SUBBEGIN:
3858 case TBLOCK_SUBINPROGRESS:
3859 case TBLOCK_SUBRELEASE:
3860 case TBLOCK_SUBCOMMIT:
3861 case TBLOCK_SUBABORT_PENDING:
3862 case TBLOCK_SUBRESTART:
3863 AbortSubTransaction();
3864 CleanupSubTransaction();
3865 s = CurrentTransactionState; /* changed by pop */
3868 case TBLOCK_SUBABORT:
3869 case TBLOCK_SUBABORT_END:
3870 case TBLOCK_SUBABORT_RESTART:
3871 /* As above, but AbortSubTransaction already done */
3872 CleanupSubTransaction();
3873 s = CurrentTransactionState; /* changed by pop */
3876 } while (s->blockState != TBLOCK_DEFAULT);
3878 /* Should be out of all subxacts now */
3879 Assert(s->parent == NULL);
3883 * IsTransactionBlock --- are we within a transaction block?
3886 IsTransactionBlock(void)
3888 TransactionState s = CurrentTransactionState;
3890 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
3897 * IsTransactionOrTransactionBlock --- are we within either a transaction
3898 * or a transaction block? (The backend is only really "idle" when this
3901 * This should match up with IsTransactionBlock and IsTransactionState.
3904 IsTransactionOrTransactionBlock(void)
3906 TransactionState s = CurrentTransactionState;
3908 if (s->blockState == TBLOCK_DEFAULT)
3915 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
3918 TransactionBlockStatusCode(void)
3920 TransactionState s = CurrentTransactionState;
3922 switch (s->blockState)
3924 case TBLOCK_DEFAULT:
3925 case TBLOCK_STARTED:
3926 return 'I'; /* idle --- not in transaction */
3928 case TBLOCK_SUBBEGIN:
3929 case TBLOCK_INPROGRESS:
3930 case TBLOCK_SUBINPROGRESS:
3932 case TBLOCK_SUBRELEASE:
3933 case TBLOCK_SUBCOMMIT:
3934 case TBLOCK_PREPARE:
3935 return 'T'; /* in transaction */
3937 case TBLOCK_SUBABORT:
3938 case TBLOCK_ABORT_END:
3939 case TBLOCK_SUBABORT_END:
3940 case TBLOCK_ABORT_PENDING:
3941 case TBLOCK_SUBABORT_PENDING:
3942 case TBLOCK_SUBRESTART:
3943 case TBLOCK_SUBABORT_RESTART:
3944 return 'E'; /* in failed transaction */
3947 /* should never get here */
3948 elog(FATAL, "invalid transaction block state: %s",
3949 BlockStateAsString(s->blockState));
3950 return 0; /* keep compiler quiet */
3957 IsSubTransaction(void)
3959 TransactionState s = CurrentTransactionState;
3961 if (s->nestingLevel >= 2)
3968 * StartSubTransaction
3970 * If you're wondering why this is separate from PushTransaction: it's because
3971 * we can't conveniently do this stuff right inside DefineSavepoint. The
3972 * SAVEPOINT utility command will be executed inside a Portal, and if we
3973 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
3974 * the Portal will undo those settings. So we make DefineSavepoint just
3975 * push a dummy transaction block, and when control returns to the main
3976 * idle loop, CommitTransactionCommand will be called, and we'll come here
3977 * to finish starting the subtransaction.
3980 StartSubTransaction(void)
3982 TransactionState s = CurrentTransactionState;
3984 if (s->state != TRANS_DEFAULT)
3985 elog(WARNING, "StartSubTransaction while in %s state",
3986 TransStateAsString(s->state));
3988 s->state = TRANS_START;
3991 * Initialize subsystems for new subtransaction
3993 * must initialize resource-management stuff first
3995 AtSubStart_Memory();
3996 AtSubStart_ResourceOwner();
3998 AtSubStart_Notify();
3999 AfterTriggerBeginSubXact();
4001 s->state = TRANS_INPROGRESS;
4004 * Call start-of-subxact callbacks
4006 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
4007 s->parent->subTransactionId);
4009 ShowTransactionState("StartSubTransaction");
4013 * CommitSubTransaction
4015 * The caller has to make sure to always reassign CurrentTransactionState
4016 * if it has a local pointer to it after calling this function.
4019 CommitSubTransaction(void)
4021 TransactionState s = CurrentTransactionState;
4023 ShowTransactionState("CommitSubTransaction");
4025 if (s->state != TRANS_INPROGRESS)
4026 elog(WARNING, "CommitSubTransaction while in %s state",
4027 TransStateAsString(s->state));
4029 /* Pre-commit processing goes here -- nothing to do at the moment */
4031 s->state = TRANS_COMMIT;
4033 /* Must CCI to ensure commands of subtransaction are seen as done */
4034 CommandCounterIncrement();
4037 * Prior to 8.4 we marked subcommit in clog at this point. We now only
4038 * perform that step, if required, as part of the atomic update of the
4039 * whole transaction tree at top level commit or abort.
4042 /* Post-commit cleanup */
4043 if (TransactionIdIsValid(s->transactionId))
4044 AtSubCommit_childXids();
4045 AfterTriggerEndSubXact(true);
4046 AtSubCommit_Portals(s->subTransactionId,
4047 s->parent->subTransactionId,
4048 s->parent->curTransactionOwner);
4049 AtEOSubXact_LargeObject(true, s->subTransactionId,
4050 s->parent->subTransactionId);
4051 AtSubCommit_Notify();
4053 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
4054 s->parent->subTransactionId);
4056 ResourceOwnerRelease(s->curTransactionOwner,
4057 RESOURCE_RELEASE_BEFORE_LOCKS,
4059 AtEOSubXact_RelationCache(true, s->subTransactionId,
4060 s->parent->subTransactionId);
4061 AtEOSubXact_Inval(true);
4065 * The only lock we actually release here is the subtransaction XID lock.
4067 CurrentResourceOwner = s->curTransactionOwner;
4068 if (TransactionIdIsValid(s->transactionId))
4069 XactLockTableDelete(s->transactionId);
4072 * Other locks should get transferred to their parent resource owner.
4074 ResourceOwnerRelease(s->curTransactionOwner,
4075 RESOURCE_RELEASE_LOCKS,
4077 ResourceOwnerRelease(s->curTransactionOwner,
4078 RESOURCE_RELEASE_AFTER_LOCKS,
4081 AtEOXact_GUC(true, s->gucNestLevel);
4082 AtEOSubXact_SPI(true, s->subTransactionId);
4083 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
4084 s->parent->subTransactionId);
4085 AtEOSubXact_Namespace(true, s->subTransactionId,
4086 s->parent->subTransactionId);
4087 AtEOSubXact_Files(true, s->subTransactionId,
4088 s->parent->subTransactionId);
4089 AtEOSubXact_HashTables(true, s->nestingLevel);
4090 AtEOSubXact_PgStat(true, s->nestingLevel);
4091 AtSubCommit_Snapshot(s->nestingLevel);
4094 * We need to restore the upper transaction's read-only state, in case the
4095 * upper is read-write while the child is read-only; GUC will incorrectly
4096 * think it should leave the child state in place.
4098 XactReadOnly = s->prevXactReadOnly;
4100 CurrentResourceOwner = s->parent->curTransactionOwner;
4101 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4102 ResourceOwnerDelete(s->curTransactionOwner);
4103 s->curTransactionOwner = NULL;
4105 AtSubCommit_Memory();
4107 s->state = TRANS_DEFAULT;
4113 * AbortSubTransaction
4116 AbortSubTransaction(void)
4118 TransactionState s = CurrentTransactionState;
4120 /* Prevent cancel/die interrupt while cleaning up */
4123 /* Make sure we have a valid memory context and resource owner */
4124 AtSubAbort_Memory();
4125 AtSubAbort_ResourceOwner();
4128 * Release any LW locks we might be holding as quickly as possible.
4129 * (Regular locks, however, must be held till we finish aborting.)
4130 * Releasing LW locks is critical since we might try to grab them again
4131 * while cleaning up!
4133 * FIXME This may be incorrect --- Are there some locks we should keep?
4134 * Buffer locks, for example? I don't think so but I'm not sure.
4144 * check the current transaction state
4146 ShowTransactionState("AbortSubTransaction");
4148 if (s->state != TRANS_INPROGRESS)
4149 elog(WARNING, "AbortSubTransaction while in %s state",
4150 TransStateAsString(s->state));
4152 s->state = TRANS_ABORT;
4155 * Reset user ID which might have been changed transiently. (See notes in
4156 * AbortTransaction.)
4158 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
4161 * We can skip all this stuff if the subxact failed before creating a
4164 if (s->curTransactionOwner)
4166 AfterTriggerEndSubXact(false);
4167 AtSubAbort_Portals(s->subTransactionId,
4168 s->parent->subTransactionId,
4169 s->parent->curTransactionOwner);
4170 AtEOSubXact_LargeObject(false, s->subTransactionId,
4171 s->parent->subTransactionId);
4172 AtSubAbort_Notify();
4174 /* Advertise the fact that we aborted in pg_clog. */
4175 (void) RecordTransactionAbort(true);
4177 /* Post-abort cleanup */
4178 if (TransactionIdIsValid(s->transactionId))
4179 AtSubAbort_childXids();
4181 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
4182 s->parent->subTransactionId);
4184 ResourceOwnerRelease(s->curTransactionOwner,
4185 RESOURCE_RELEASE_BEFORE_LOCKS,
4187 AtEOSubXact_RelationCache(false, s->subTransactionId,
4188 s->parent->subTransactionId);
4189 AtEOSubXact_Inval(false);
4191 ResourceOwnerRelease(s->curTransactionOwner,
4192 RESOURCE_RELEASE_LOCKS,
4194 ResourceOwnerRelease(s->curTransactionOwner,
4195 RESOURCE_RELEASE_AFTER_LOCKS,
4198 AtEOXact_GUC(false, s->gucNestLevel);
4199 AtEOSubXact_SPI(false, s->subTransactionId);
4200 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
4201 s->parent->subTransactionId);
4202 AtEOSubXact_Namespace(false, s->subTransactionId,
4203 s->parent->subTransactionId);
4204 AtEOSubXact_Files(false, s->subTransactionId,
4205 s->parent->subTransactionId);
4206 AtEOSubXact_HashTables(false, s->nestingLevel);
4207 AtEOSubXact_PgStat(false, s->nestingLevel);
4208 AtSubAbort_Snapshot(s->nestingLevel);
4212 * Restore the upper transaction's read-only state, too. This should be
4213 * redundant with GUC's cleanup but we may as well do it for consistency
4214 * with the commit case.
4216 XactReadOnly = s->prevXactReadOnly;
4218 RESUME_INTERRUPTS();
4222 * CleanupSubTransaction
4224 * The caller has to make sure to always reassign CurrentTransactionState
4225 * if it has a local pointer to it after calling this function.
4228 CleanupSubTransaction(void)
4230 TransactionState s = CurrentTransactionState;
4232 ShowTransactionState("CleanupSubTransaction");
4234 if (s->state != TRANS_ABORT)
4235 elog(WARNING, "CleanupSubTransaction while in %s state",
4236 TransStateAsString(s->state));
4238 AtSubCleanup_Portals(s->subTransactionId);
4240 CurrentResourceOwner = s->parent->curTransactionOwner;
4241 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4242 if (s->curTransactionOwner)
4243 ResourceOwnerDelete(s->curTransactionOwner);
4244 s->curTransactionOwner = NULL;
4246 AtSubCleanup_Memory();
4248 s->state = TRANS_DEFAULT;
4255 * Create transaction state stack entry for a subtransaction
4257 * The caller has to make sure to always reassign CurrentTransactionState
4258 * if it has a local pointer to it after calling this function.
4261 PushTransaction(void)
4263 TransactionState p = CurrentTransactionState;
4267 * We keep subtransaction state nodes in TopTransactionContext.
4269 s = (TransactionState)
4270 MemoryContextAllocZero(TopTransactionContext,
4271 sizeof(TransactionStateData));
4274 * Assign a subtransaction ID, watching out for counter wraparound.
4276 currentSubTransactionId += 1;
4277 if (currentSubTransactionId == InvalidSubTransactionId)
4279 currentSubTransactionId -= 1;
4282 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
4283 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
4287 * We can now stack a minimally valid subtransaction without fear of
4290 s->transactionId = InvalidTransactionId; /* until assigned */
4291 s->subTransactionId = currentSubTransactionId;
4293 s->nestingLevel = p->nestingLevel + 1;
4294 s->gucNestLevel = NewGUCNestLevel();
4295 s->savepointLevel = p->savepointLevel;
4296 s->state = TRANS_DEFAULT;
4297 s->blockState = TBLOCK_SUBBEGIN;
4298 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
4299 s->prevXactReadOnly = XactReadOnly;
4301 CurrentTransactionState = s;
4304 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
4305 * with the subtransaction from here on out; in particular they should not
4306 * assume that it necessarily has a transaction context, resource owner,
4313 * Pop back to parent transaction state
4315 * The caller has to make sure to always reassign CurrentTransactionState
4316 * if it has a local pointer to it after calling this function.
4319 PopTransaction(void)
4321 TransactionState s = CurrentTransactionState;
4323 if (s->state != TRANS_DEFAULT)
4324 elog(WARNING, "PopTransaction while in %s state",
4325 TransStateAsString(s->state));
4327 if (s->parent == NULL)
4328 elog(FATAL, "PopTransaction with no parent");
4330 CurrentTransactionState = s->parent;
4332 /* Let's just make sure CurTransactionContext is good */
4333 CurTransactionContext = s->parent->curTransactionContext;
4334 MemoryContextSwitchTo(CurTransactionContext);
4336 /* Ditto for ResourceOwner links */
4337 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4338 CurrentResourceOwner = s->parent->curTransactionOwner;
4340 /* Free the old child structure */
4347 * ShowTransactionState
4351 ShowTransactionState(const char *str)
4353 /* skip work if message will definitely not be printed */
4354 if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
4356 elog(DEBUG3, "%s", str);
4357 ShowTransactionStateRec(CurrentTransactionState);
4362 * ShowTransactionStateRec
4363 * Recursive subroutine for ShowTransactionState
4366 ShowTransactionStateRec(TransactionState s)
4370 initStringInfo(&buf);
4372 if (s->nChildXids > 0)
4376 appendStringInfo(&buf, "%u", s->childXids[0]);
4377 for (i = 1; i < s->nChildXids; i++)
4378 appendStringInfo(&buf, " %u", s->childXids[i]);
4382 ShowTransactionStateRec(s->parent);
4384 /* use ereport to suppress computation if msg will not be printed */
4386 (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u%s, nestlvl: %d, children: %s",
4387 PointerIsValid(s->name) ? s->name : "unnamed",
4388 BlockStateAsString(s->blockState),
4389 TransStateAsString(s->state),
4390 (unsigned int) s->transactionId,
4391 (unsigned int) s->subTransactionId,
4392 (unsigned int) currentCommandId,
4393 currentCommandIdUsed ? " (used)" : "",
4394 s->nestingLevel, buf.data)));
4400 * BlockStateAsString
4404 BlockStateAsString(TBlockState blockState)
4408 case TBLOCK_DEFAULT:
4410 case TBLOCK_STARTED:
4414 case TBLOCK_INPROGRESS:
4415 return "INPROGRESS";
4420 case TBLOCK_ABORT_END:
4422 case TBLOCK_ABORT_PENDING:
4423 return "ABORT PEND";
4424 case TBLOCK_PREPARE:
4426 case TBLOCK_SUBBEGIN:
4428 case TBLOCK_SUBINPROGRESS:
4429 return "SUB INPROGRS";
4430 case TBLOCK_SUBRELEASE:
4431 return "SUB RELEASE";
4432 case TBLOCK_SUBCOMMIT:
4433 return "SUB COMMIT";
4434 case TBLOCK_SUBABORT:
4436 case TBLOCK_SUBABORT_END:
4437 return "SUB ABORT END";
4438 case TBLOCK_SUBABORT_PENDING:
4439 return "SUB ABRT PEND";
4440 case TBLOCK_SUBRESTART:
4441 return "SUB RESTART";
4442 case TBLOCK_SUBABORT_RESTART:
4443 return "SUB AB RESTRT";
4445 return "UNRECOGNIZED";
4449 * TransStateAsString
4453 TransStateAsString(TransState state)
4461 case TRANS_INPROGRESS:
4470 return "UNRECOGNIZED";
4474 * xactGetCommittedChildren
4476 * Gets the list of committed children of the current transaction. The return
4477 * value is the number of child transactions. *ptr is set to point to an
4478 * array of TransactionIds. The array is allocated in TopTransactionContext;
4479 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
4480 * If there are no subxacts, *ptr is set to NULL.
4483 xactGetCommittedChildren(TransactionId **ptr)
4485 TransactionState s = CurrentTransactionState;
4487 if (s->nChildXids == 0)
4490 *ptr = s->childXids;
4492 return s->nChildXids;
4496 * XLOG support routines
4500 * Before 9.0 this was a fairly short function, but now it performs many
4501 * actions for which the order of execution is critical.
4504 xact_redo_commit_internal(TransactionId xid, XLogRecPtr lsn,
4505 TransactionId *sub_xids, int nsubxacts,
4506 SharedInvalidationMessage *inval_msgs, int nmsgs,
4507 RelFileNode *xnodes, int nrels,
4511 TransactionId max_xid;
4514 max_xid = TransactionIdLatest(xid, nsubxacts, sub_xids);
4517 * Make sure nextXid is beyond any XID mentioned in the record.
4519 * We don't expect anyone else to modify nextXid, hence we don't need to
4520 * hold a lock while checking this. We still acquire the lock to modify
4523 if (TransactionIdFollowsOrEquals(max_xid,
4524 ShmemVariableCache->nextXid))
4526 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4527 ShmemVariableCache->nextXid = max_xid;
4528 TransactionIdAdvance(ShmemVariableCache->nextXid);
4529 LWLockRelease(XidGenLock);
4532 if (standbyState == STANDBY_DISABLED)
4535 * Mark the transaction committed in pg_clog.
4537 TransactionIdCommitTree(xid, nsubxacts, sub_xids);
4542 * If a transaction completion record arrives that has as-yet
4543 * unobserved subtransactions then this will not have been fully
4544 * handled by the call to RecordKnownAssignedTransactionIds() in the
4545 * main recovery loop in xlog.c. So we need to do bookkeeping again to
4546 * cover that case. This is confusing and it is easy to think this
4547 * call is irrelevant, which has happened three times in development
4548 * already. Leave it in.
4550 RecordKnownAssignedTransactionIds(max_xid);
4553 * Mark the transaction committed in pg_clog. We use async commit
4554 * protocol during recovery to provide information on database
4555 * consistency for when users try to set hint bits. It is important
4556 * that we do not set hint bits until the minRecoveryPoint is past
4557 * this commit record. This ensures that if we crash we don't see hint
4558 * bits set on changes made by transactions that haven't yet
4559 * recovered. It's unlikely but it's good to be safe.
4561 TransactionIdAsyncCommitTree(xid, nsubxacts, sub_xids, lsn);
4564 * We must mark clog before we update the ProcArray.
4566 ExpireTreeKnownAssignedTransactionIds(xid, nsubxacts, sub_xids, max_xid);
4569 * Send any cache invalidations attached to the commit. We must
4570 * maintain the same order of invalidation then release locks as
4571 * occurs in CommitTransaction().
4573 ProcessCommittedInvalidationMessages(inval_msgs, nmsgs,
4574 XactCompletionRelcacheInitFileInval(xinfo),
4578 * Release locks, if any. We do this for both two phase and normal one
4579 * phase transactions. In effect we are ignoring the prepare phase and
4580 * just going straight to lock release.
4582 StandbyReleaseLockTree(xid, nsubxacts, sub_xids);
4585 /* Make sure files supposed to be dropped are dropped */
4586 for (i = 0; i < nrels; i++)
4588 SMgrRelation srel = smgropen(xnodes[i], InvalidBackendId);
4591 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4593 if (smgrexists(srel, fork))
4595 XLogDropRelation(xnodes[i], fork);
4596 smgrdounlink(srel, fork, true);
4603 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
4604 * in normal operation. For example, in DROP DATABASE, we delete all the
4605 * files belonging to the database, and then commit the transaction. If we
4606 * crash after all the files have been deleted but before the commit, you
4607 * have an entry in pg_database without any files. To minimize the window
4608 * for that, we use ForceSyncCommit() to rush the commit record to disk as
4609 * quick as possible. We have the same window during recovery, and forcing
4610 * an XLogFlush() (which updates minRecoveryPoint during recovery) helps
4611 * to reduce that problem window, for any user that requested
4612 * ForceSyncCommit().
4614 if (XactCompletionForceSyncCommit(xinfo))
4619 * Utility function to call xact_redo_commit_internal after breaking down xlrec
4622 xact_redo_commit(xl_xact_commit *xlrec,
4623 TransactionId xid, XLogRecPtr lsn)
4625 TransactionId *subxacts;
4626 SharedInvalidationMessage *inval_msgs;
4628 /* subxid array follows relfilenodes */
4629 subxacts = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4630 /* invalidation messages array follows subxids */
4631 inval_msgs = (SharedInvalidationMessage *) &(subxacts[xlrec->nsubxacts]);
4633 xact_redo_commit_internal(xid, lsn, subxacts, xlrec->nsubxacts,
4634 inval_msgs, xlrec->nmsgs,
4635 xlrec->xnodes, xlrec->nrels,
4642 * Utility function to call xact_redo_commit_internal for compact form of message.
4645 xact_redo_commit_compact(xl_xact_commit_compact *xlrec,
4646 TransactionId xid, XLogRecPtr lsn)
4648 xact_redo_commit_internal(xid, lsn, xlrec->subxacts, xlrec->nsubxacts,
4649 NULL, 0, /* inval msgs */
4650 NULL, 0, /* relfilenodes */
4651 InvalidOid, /* dbId */
4652 InvalidOid, /* tsId */
4657 * Be careful with the order of execution, as with xact_redo_commit().
4658 * The two functions are similar but differ in key places.
4660 * Note also that an abort can be for a subtransaction and its children,
4661 * not just for a top level abort. That means we have to consider
4662 * topxid != xid, whereas in commit we would find topxid == xid always
4663 * because subtransaction commit is never WAL logged.
4666 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
4668 TransactionId *sub_xids;
4669 TransactionId max_xid;
4672 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4673 max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
4676 * Make sure nextXid is beyond any XID mentioned in the record.
4678 * We don't expect anyone else to modify nextXid, hence we don't need to
4679 * hold a lock while checking this. We still acquire the lock to modify
4682 if (TransactionIdFollowsOrEquals(max_xid,
4683 ShmemVariableCache->nextXid))
4685 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4686 ShmemVariableCache->nextXid = max_xid;
4687 TransactionIdAdvance(ShmemVariableCache->nextXid);
4688 LWLockRelease(XidGenLock);
4691 if (standbyState == STANDBY_DISABLED)
4693 /* Mark the transaction aborted in pg_clog, no need for async stuff */
4694 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4699 * If a transaction completion record arrives that has as-yet
4700 * unobserved subtransactions then this will not have been fully
4701 * handled by the call to RecordKnownAssignedTransactionIds() in the
4702 * main recovery loop in xlog.c. So we need to do bookkeeping again to
4703 * cover that case. This is confusing and it is easy to think this
4704 * call is irrelevant, which has happened three times in development
4705 * already. Leave it in.
4707 RecordKnownAssignedTransactionIds(max_xid);
4709 /* Mark the transaction aborted in pg_clog, no need for async stuff */
4710 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4713 * We must update the ProcArray after we have marked clog.
4715 ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids, max_xid);
4718 * There are no flat files that need updating, nor invalidation
4719 * messages to send or undo.
4723 * Release locks, if any. There are no invalidations to send.
4725 StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
4728 /* Make sure files supposed to be dropped are dropped */
4729 for (i = 0; i < xlrec->nrels; i++)
4731 SMgrRelation srel = smgropen(xlrec->xnodes[i], InvalidBackendId);
4734 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4736 if (smgrexists(srel, fork))
4738 XLogDropRelation(xlrec->xnodes[i], fork);
4739 smgrdounlink(srel, fork, true);
4747 xact_redo(XLogRecPtr lsn, XLogRecord *record)
4749 uint8 info = record->xl_info & ~XLR_INFO_MASK;
4751 /* Backup blocks are not used in xact records */
4752 Assert(!(record->xl_info & XLR_BKP_BLOCK_MASK));
4754 if (info == XLOG_XACT_COMMIT_COMPACT)
4756 xl_xact_commit_compact *xlrec = (xl_xact_commit_compact *) XLogRecGetData(record);
4758 xact_redo_commit_compact(xlrec, record->xl_xid, lsn);
4760 else if (info == XLOG_XACT_COMMIT)
4762 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
4764 xact_redo_commit(xlrec, record->xl_xid, lsn);
4766 else if (info == XLOG_XACT_ABORT)
4768 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
4770 xact_redo_abort(xlrec, record->xl_xid);
4772 else if (info == XLOG_XACT_PREPARE)
4774 /* the record contents are exactly the 2PC file */
4775 RecreateTwoPhaseFile(record->xl_xid,
4776 XLogRecGetData(record), record->xl_len);
4778 else if (info == XLOG_XACT_COMMIT_PREPARED)
4780 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
4782 xact_redo_commit(&xlrec->crec, xlrec->xid, lsn);
4783 RemoveTwoPhaseFile(xlrec->xid, false);
4785 else if (info == XLOG_XACT_ABORT_PREPARED)
4787 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
4789 xact_redo_abort(&xlrec->arec, xlrec->xid);
4790 RemoveTwoPhaseFile(xlrec->xid, false);
4792 else if (info == XLOG_XACT_ASSIGNMENT)
4794 xl_xact_assignment *xlrec = (xl_xact_assignment *) XLogRecGetData(record);
4796 if (standbyState >= STANDBY_INITIALIZED)
4797 ProcArrayApplyXidAssignment(xlrec->xtop,
4798 xlrec->nsubxacts, xlrec->xsub);
4801 elog(PANIC, "xact_redo: unknown op code %u", info);
4805 xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
4808 TransactionId *subxacts;
4810 subxacts = (TransactionId *) &xlrec->xnodes[xlrec->nrels];
4812 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4814 if (xlrec->nrels > 0)
4816 appendStringInfo(buf, "; rels:");
4817 for (i = 0; i < xlrec->nrels; i++)
4819 char *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);
4821 appendStringInfo(buf, " %s", path);
4825 if (xlrec->nsubxacts > 0)
4827 appendStringInfo(buf, "; subxacts:");
4828 for (i = 0; i < xlrec->nsubxacts; i++)
4829 appendStringInfo(buf, " %u", subxacts[i]);
4831 if (xlrec->nmsgs > 0)
4833 SharedInvalidationMessage *msgs;
4835 msgs = (SharedInvalidationMessage *) &subxacts[xlrec->nsubxacts];
4837 if (XactCompletionRelcacheInitFileInval(xlrec->xinfo))
4838 appendStringInfo(buf, "; relcache init file inval dbid %u tsid %u",
4839 xlrec->dbId, xlrec->tsId);
4841 appendStringInfo(buf, "; inval msgs:");
4842 for (i = 0; i < xlrec->nmsgs; i++)
4844 SharedInvalidationMessage *msg = &msgs[i];
4847 appendStringInfo(buf, " catcache %d", msg->id);
4848 else if (msg->id == SHAREDINVALCATALOG_ID)
4849 appendStringInfo(buf, " catalog %u", msg->cat.catId);
4850 else if (msg->id == SHAREDINVALRELCACHE_ID)
4851 appendStringInfo(buf, " relcache %u", msg->rc.relId);
4852 /* remaining cases not expected, but print something anyway */
4853 else if (msg->id == SHAREDINVALSMGR_ID)
4854 appendStringInfo(buf, " smgr");
4855 else if (msg->id == SHAREDINVALRELMAP_ID)
4856 appendStringInfo(buf, " relmap");
4858 appendStringInfo(buf, " unknown id %d", msg->id);
4864 xact_desc_commit_compact(StringInfo buf, xl_xact_commit_compact *xlrec)
4868 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4870 if (xlrec->nsubxacts > 0)
4872 appendStringInfo(buf, "; subxacts:");
4873 for (i = 0; i < xlrec->nsubxacts; i++)
4874 appendStringInfo(buf, " %u", xlrec->subxacts[i]);
4879 xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
4883 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4884 if (xlrec->nrels > 0)
4886 appendStringInfo(buf, "; rels:");
4887 for (i = 0; i < xlrec->nrels; i++)
4889 char *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);
4891 appendStringInfo(buf, " %s", path);
4895 if (xlrec->nsubxacts > 0)
4897 TransactionId *xacts = (TransactionId *)
4898 &xlrec->xnodes[xlrec->nrels];
4900 appendStringInfo(buf, "; subxacts:");
4901 for (i = 0; i < xlrec->nsubxacts; i++)
4902 appendStringInfo(buf, " %u", xacts[i]);
4907 xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
4911 appendStringInfo(buf, "subxacts:");
4913 for (i = 0; i < xlrec->nsubxacts; i++)
4914 appendStringInfo(buf, " %u", xlrec->xsub[i]);
4918 xact_desc(StringInfo buf, uint8 xl_info, char *rec)
4920 uint8 info = xl_info & ~XLR_INFO_MASK;
4922 if (info == XLOG_XACT_COMMIT_COMPACT)
4924 xl_xact_commit_compact *xlrec = (xl_xact_commit_compact *) rec;
4926 appendStringInfo(buf, "commit: ");
4927 xact_desc_commit_compact(buf, xlrec);
4929 else if (info == XLOG_XACT_COMMIT)
4931 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
4933 appendStringInfo(buf, "commit: ");
4934 xact_desc_commit(buf, xlrec);
4936 else if (info == XLOG_XACT_ABORT)
4938 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
4940 appendStringInfo(buf, "abort: ");
4941 xact_desc_abort(buf, xlrec);
4943 else if (info == XLOG_XACT_PREPARE)
4945 appendStringInfo(buf, "prepare");
4947 else if (info == XLOG_XACT_COMMIT_PREPARED)
4949 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
4951 appendStringInfo(buf, "commit prepared %u: ", xlrec->xid);
4952 xact_desc_commit(buf, &xlrec->crec);
4954 else if (info == XLOG_XACT_ABORT_PREPARED)
4956 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
4958 appendStringInfo(buf, "abort prepared %u: ", xlrec->xid);
4959 xact_desc_abort(buf, &xlrec->arec);
4961 else if (info == XLOG_XACT_ASSIGNMENT)
4963 xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
4966 * Note that we ignore the WAL record's xid, since we're more
4967 * interested in the top-level xid that issued the record and which
4968 * xids are being reported here.
4970 appendStringInfo(buf, "xid assignment xtop %u: ", xlrec->xtop);
4971 xact_desc_assignment(buf, xlrec);
4974 appendStringInfo(buf, "UNKNOWN");