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"
52 #include "utils/timestamp.h"
57 * User-tweakable parameters
59 int DefaultXactIsoLevel = XACT_READ_COMMITTED;
62 bool DefaultXactReadOnly = false;
65 bool DefaultXactDeferrable = false;
68 int synchronous_commit = SYNCHRONOUS_COMMIT_ON;
70 int CommitDelay = 0; /* precommit delay in microseconds */
71 int CommitSiblings = 5; /* # concurrent xacts needed to sleep */
74 * MyXactAccessedTempRel is set when a temporary relation is accessed.
75 * We don't allow PREPARE TRANSACTION in that case. (This is global
76 * so that it can be set from heapam.c.)
78 bool MyXactAccessedTempRel = false;
82 * transaction states - transaction state from server perspective
84 typedef enum TransState
86 TRANS_DEFAULT, /* idle */
87 TRANS_START, /* transaction starting */
88 TRANS_INPROGRESS, /* inside a valid transaction */
89 TRANS_COMMIT, /* commit in progress */
90 TRANS_ABORT, /* abort in progress */
91 TRANS_PREPARE /* prepare in progress */
95 * transaction block states - transaction state of client queries
97 * Note: the subtransaction states are used only for non-topmost
98 * transactions; the others appear only in the topmost transaction.
100 typedef enum TBlockState
102 /* not-in-transaction-block states */
103 TBLOCK_DEFAULT, /* idle */
104 TBLOCK_STARTED, /* running single-query transaction */
106 /* transaction block states */
107 TBLOCK_BEGIN, /* starting transaction block */
108 TBLOCK_INPROGRESS, /* live transaction */
109 TBLOCK_END, /* COMMIT received */
110 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
111 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
112 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
113 TBLOCK_PREPARE, /* live xact, PREPARE received */
115 /* subtransaction states */
116 TBLOCK_SUBBEGIN, /* starting a subtransaction */
117 TBLOCK_SUBINPROGRESS, /* live subtransaction */
118 TBLOCK_SUBRELEASE, /* RELEASE received */
119 TBLOCK_SUBCOMMIT, /* COMMIT received while TBLOCK_SUBINPROGRESS */
120 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
121 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
122 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
123 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
124 TBLOCK_SUBABORT_RESTART /* failed subxact, ROLLBACK TO received */
128 * transaction state structure
130 typedef struct TransactionStateData
132 TransactionId transactionId; /* my XID, or Invalid if none */
133 SubTransactionId subTransactionId; /* my subxact ID */
134 char *name; /* savepoint name, if any */
135 int savepointLevel; /* savepoint level */
136 TransState state; /* low-level state */
137 TBlockState blockState; /* high-level state */
138 int nestingLevel; /* transaction nesting depth */
139 int gucNestLevel; /* GUC context nesting depth */
140 MemoryContext curTransactionContext; /* my xact-lifetime context */
141 ResourceOwner curTransactionOwner; /* my query resources */
142 TransactionId *childXids; /* subcommitted child XIDs, in XID order */
143 int nChildXids; /* # of subcommitted child XIDs */
144 int maxChildXids; /* allocated size of childXids[] */
145 Oid prevUser; /* previous CurrentUserId setting */
146 int prevSecContext; /* previous SecurityRestrictionContext */
147 bool prevXactReadOnly; /* entry-time xact r/o state */
148 bool startedInRecovery; /* did we start in recovery? */
149 struct TransactionStateData *parent; /* back link to parent */
150 } TransactionStateData;
152 typedef TransactionStateData *TransactionState;
155 * CurrentTransactionState always points to the current transaction state
156 * block. It will point to TopTransactionStateData when not in a
157 * transaction at all, or when in a top-level transaction.
159 static TransactionStateData TopTransactionStateData = {
160 0, /* transaction id */
161 0, /* subtransaction id */
162 NULL, /* savepoint name */
163 0, /* savepoint level */
164 TRANS_DEFAULT, /* transaction state */
165 TBLOCK_DEFAULT, /* transaction block state from the client
167 0, /* transaction nesting depth */
168 0, /* GUC context nesting depth */
169 NULL, /* cur transaction context */
170 NULL, /* cur transaction resource owner */
171 NULL, /* subcommitted child Xids */
172 0, /* # of subcommitted child Xids */
173 0, /* allocated size of childXids[] */
174 InvalidOid, /* previous CurrentUserId setting */
175 0, /* previous SecurityRestrictionContext */
176 false, /* entry-time xact r/o state */
177 false, /* startedInRecovery */
178 NULL /* link to parent state block */
182 * unreportedXids holds XIDs of all subtransactions that have not yet been
183 * reported in a XLOG_XACT_ASSIGNMENT record.
185 static int nUnreportedXids;
186 static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS];
188 static TransactionState CurrentTransactionState = &TopTransactionStateData;
191 * The subtransaction ID and command ID assignment counters are global
192 * to a whole transaction, so we do not keep them in the state stack.
194 static SubTransactionId currentSubTransactionId;
195 static CommandId currentCommandId;
196 static bool currentCommandIdUsed;
199 * xactStartTimestamp is the value of transaction_timestamp().
200 * stmtStartTimestamp is the value of statement_timestamp().
201 * xactStopTimestamp is the time at which we log a commit or abort WAL record.
202 * These do not change as we enter and exit subtransactions, so we don't
203 * keep them inside the TransactionState stack.
205 static TimestampTz xactStartTimestamp;
206 static TimestampTz stmtStartTimestamp;
207 static TimestampTz xactStopTimestamp;
210 * GID to be used for preparing the current transaction. This is also
211 * global to a whole transaction, so we don't keep it in the state stack.
213 static char *prepareGID;
216 * Some commands want to force synchronous commit.
218 static bool forceSyncCommit = false;
221 * Private context for transaction-abort work --- we reserve space for this
222 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
223 * when we've run out of memory.
225 static MemoryContext TransactionAbortContext = NULL;
228 * List of add-on start- and end-of-xact callbacks
230 typedef struct XactCallbackItem
232 struct XactCallbackItem *next;
233 XactCallback callback;
237 static XactCallbackItem *Xact_callbacks = NULL;
240 * List of add-on start- and end-of-subxact callbacks
242 typedef struct SubXactCallbackItem
244 struct SubXactCallbackItem *next;
245 SubXactCallback callback;
247 } SubXactCallbackItem;
249 static SubXactCallbackItem *SubXact_callbacks = NULL;
252 /* local function prototypes */
253 static void AssignTransactionId(TransactionState s);
254 static void AbortTransaction(void);
255 static void AtAbort_Memory(void);
256 static void AtCleanup_Memory(void);
257 static void AtAbort_ResourceOwner(void);
258 static void AtCCI_LocalCache(void);
259 static void AtCommit_Memory(void);
260 static void AtStart_Cache(void);
261 static void AtStart_Memory(void);
262 static void AtStart_ResourceOwner(void);
263 static void CallXactCallbacks(XactEvent event);
264 static void CallSubXactCallbacks(SubXactEvent event,
265 SubTransactionId mySubid,
266 SubTransactionId parentSubid);
267 static void CleanupTransaction(void);
268 static void CommitTransaction(void);
269 static TransactionId RecordTransactionAbort(bool isSubXact);
270 static void StartTransaction(void);
272 static void StartSubTransaction(void);
273 static void CommitSubTransaction(void);
274 static void AbortSubTransaction(void);
275 static void CleanupSubTransaction(void);
276 static void PushTransaction(void);
277 static void PopTransaction(void);
279 static void AtSubAbort_Memory(void);
280 static void AtSubCleanup_Memory(void);
281 static void AtSubAbort_ResourceOwner(void);
282 static void AtSubCommit_Memory(void);
283 static void AtSubStart_Memory(void);
284 static void AtSubStart_ResourceOwner(void);
286 static void ShowTransactionState(const char *str);
287 static void ShowTransactionStateRec(TransactionState state);
288 static const char *BlockStateAsString(TBlockState blockState);
289 static const char *TransStateAsString(TransState state);
292 /* ----------------------------------------------------------------
293 * transaction state accessors
294 * ----------------------------------------------------------------
300 * This returns true if we are inside a valid transaction; that is,
301 * it is safe to initiate database access, take heavyweight locks, etc.
304 IsTransactionState(void)
306 TransactionState s = CurrentTransactionState;
309 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
310 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
311 * TRANS_PREPARE since it might be too soon or too late within those
312 * transition states to do anything interesting. Hence, the only "valid"
313 * state is TRANS_INPROGRESS.
315 return (s->state == TRANS_INPROGRESS);
319 * IsAbortedTransactionBlockState
321 * This returns true if we are within an aborted transaction block.
324 IsAbortedTransactionBlockState(void)
326 TransactionState s = CurrentTransactionState;
328 if (s->blockState == TBLOCK_ABORT ||
329 s->blockState == TBLOCK_SUBABORT)
337 * GetTopTransactionId
339 * This will return the XID of the main transaction, assigning one if
340 * it's not yet set. Be careful to call this only inside a valid xact.
343 GetTopTransactionId(void)
345 if (!TransactionIdIsValid(TopTransactionStateData.transactionId))
346 AssignTransactionId(&TopTransactionStateData);
347 return TopTransactionStateData.transactionId;
351 * GetTopTransactionIdIfAny
353 * This will return the XID of the main transaction, if one is assigned.
354 * It will return InvalidTransactionId if we are not currently inside a
355 * transaction, or inside a transaction that hasn't yet been assigned an XID.
358 GetTopTransactionIdIfAny(void)
360 return TopTransactionStateData.transactionId;
364 * GetCurrentTransactionId
366 * This will return the XID of the current transaction (main or sub
367 * transaction), assigning one if it's not yet set. Be careful to call this
368 * only inside a valid xact.
371 GetCurrentTransactionId(void)
373 TransactionState s = CurrentTransactionState;
375 if (!TransactionIdIsValid(s->transactionId))
376 AssignTransactionId(s);
377 return s->transactionId;
381 * GetCurrentTransactionIdIfAny
383 * This will return the XID of the current sub xact, if one is assigned.
384 * It will return InvalidTransactionId if we are not currently inside a
385 * transaction, or inside a transaction that hasn't been assigned an XID yet.
388 GetCurrentTransactionIdIfAny(void)
390 return CurrentTransactionState->transactionId;
395 * AssignTransactionId
397 * Assigns a new permanent XID to the given TransactionState.
398 * We do not assign XIDs to transactions until/unless this is called.
399 * Also, any parent TransactionStates that don't yet have XIDs are assigned
400 * one; this maintains the invariant that a child transaction has an XID
401 * following its parent's.
404 AssignTransactionId(TransactionState s)
406 bool isSubXact = (s->parent != NULL);
407 ResourceOwner currentOwner;
409 /* Assert that caller didn't screw up */
410 Assert(!TransactionIdIsValid(s->transactionId));
411 Assert(s->state == TRANS_INPROGRESS);
414 * Ensure parent(s) have XIDs, so that a child always has an XID later
415 * than its parent. Musn't recurse here, or we might get a stack overflow
416 * if we're at the bottom of a huge stack of subtransactions none of which
419 if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
421 TransactionState p = s->parent;
422 TransactionState *parents;
423 size_t parentOffset = 0;
425 parents = palloc(sizeof(TransactionState) * s->nestingLevel);
426 while (p != NULL && !TransactionIdIsValid(p->transactionId))
428 parents[parentOffset++] = p;
433 * This is technically a recursive call, but the recursion will never
434 * be more than one layer deep.
436 while (parentOffset != 0)
437 AssignTransactionId(parents[--parentOffset]);
443 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
445 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
446 * shared storage other than PG_PROC; because if there's no room for it in
447 * PG_PROC, the subtrans entry is needed to ensure that other backends see
448 * the Xid as "running". See GetNewTransactionId.
450 s->transactionId = GetNewTransactionId(isSubXact);
453 SubTransSetParent(s->transactionId, s->parent->transactionId, false);
456 * If it's a top-level transaction, the predicate locking system needs to
457 * be told about it too.
460 RegisterPredicateLockingXid(s->transactionId);
463 * Acquire lock on the transaction XID. (We assume this cannot block.) We
464 * have to ensure that the lock is assigned to the transaction's own
467 currentOwner = CurrentResourceOwner;
470 CurrentResourceOwner = s->curTransactionOwner;
471 XactLockTableInsert(s->transactionId);
475 /* Ensure CurrentResourceOwner is restored on error */
476 CurrentResourceOwner = currentOwner;
480 CurrentResourceOwner = currentOwner;
483 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
484 * top-level transaction we issue a WAL record for the assignment. We
485 * include the top-level xid and all the subxids that have not yet been
486 * reported using XLOG_XACT_ASSIGNMENT records.
488 * This is required to limit the amount of shared memory required in a hot
489 * standby server to keep track of in-progress XIDs. See notes for
490 * RecordKnownAssignedTransactionIds().
492 * We don't keep track of the immediate parent of each subxid, only the
493 * top-level transaction that each subxact belongs to. This is correct in
494 * recovery only because aborted subtransactions are separately WAL
497 if (isSubXact && XLogStandbyInfoActive())
499 unreportedXids[nUnreportedXids] = s->transactionId;
503 * ensure this test matches similar one in
504 * RecoverPreparedTransactions()
506 if (nUnreportedXids >= PGPROC_MAX_CACHED_SUBXIDS)
508 XLogRecData rdata[2];
509 xl_xact_assignment xlrec;
512 * xtop is always set by now because we recurse up transaction
513 * stack to the highest unassigned xid and then come back down
515 xlrec.xtop = GetTopTransactionId();
516 Assert(TransactionIdIsValid(xlrec.xtop));
517 xlrec.nsubxacts = nUnreportedXids;
519 rdata[0].data = (char *) &xlrec;
520 rdata[0].len = MinSizeOfXactAssignment;
521 rdata[0].buffer = InvalidBuffer;
522 rdata[0].next = &rdata[1];
524 rdata[1].data = (char *) unreportedXids;
525 rdata[1].len = PGPROC_MAX_CACHED_SUBXIDS * sizeof(TransactionId);
526 rdata[1].buffer = InvalidBuffer;
527 rdata[1].next = NULL;
529 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT, rdata);
537 * GetCurrentSubTransactionId
540 GetCurrentSubTransactionId(void)
542 TransactionState s = CurrentTransactionState;
544 return s->subTransactionId;
549 * GetCurrentCommandId
551 * "used" must be TRUE if the caller intends to use the command ID to mark
552 * inserted/updated/deleted tuples. FALSE means the ID is being fetched
553 * for read-only purposes (ie, as a snapshot validity cutoff). See
554 * CommandCounterIncrement() for discussion.
557 GetCurrentCommandId(bool used)
559 /* this is global to a transaction, not subtransaction-local */
561 currentCommandIdUsed = true;
562 return currentCommandId;
566 * GetCurrentTransactionStartTimestamp
569 GetCurrentTransactionStartTimestamp(void)
571 return xactStartTimestamp;
575 * GetCurrentStatementStartTimestamp
578 GetCurrentStatementStartTimestamp(void)
580 return stmtStartTimestamp;
584 * GetCurrentTransactionStopTimestamp
586 * We return current time if the transaction stop time hasn't been set
587 * (which can happen if we decide we don't need to log an XLOG record).
590 GetCurrentTransactionStopTimestamp(void)
592 if (xactStopTimestamp != 0)
593 return xactStopTimestamp;
594 return GetCurrentTimestamp();
598 * SetCurrentStatementStartTimestamp
601 SetCurrentStatementStartTimestamp(void)
603 stmtStartTimestamp = GetCurrentTimestamp();
607 * SetCurrentTransactionStopTimestamp
610 SetCurrentTransactionStopTimestamp(void)
612 xactStopTimestamp = GetCurrentTimestamp();
616 * GetCurrentTransactionNestLevel
618 * Note: this will return zero when not inside any transaction, one when
619 * inside a top-level transaction, etc.
622 GetCurrentTransactionNestLevel(void)
624 TransactionState s = CurrentTransactionState;
626 return s->nestingLevel;
631 * TransactionIdIsCurrentTransactionId
634 TransactionIdIsCurrentTransactionId(TransactionId xid)
639 * We always say that BootstrapTransactionId is "not my transaction ID"
640 * even when it is (ie, during bootstrap). Along with the fact that
641 * transam.c always treats BootstrapTransactionId as already committed,
642 * this causes the tqual.c routines to see all tuples as committed, which
643 * is what we need during bootstrap. (Bootstrap mode only inserts tuples,
644 * it never updates or deletes them, so all tuples can be presumed good
647 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
648 * not my transaction ID, so we can just return "false" immediately for
649 * any non-normal XID.
651 if (!TransactionIdIsNormal(xid))
655 * We will return true for the Xid of the current subtransaction, any of
656 * its subcommitted children, any of its parents, or any of their
657 * previously subcommitted children. However, a transaction being aborted
658 * is no longer "current", even though it may still have an entry on the
661 for (s = CurrentTransactionState; s != NULL; s = s->parent)
666 if (s->state == TRANS_ABORT)
668 if (!TransactionIdIsValid(s->transactionId))
669 continue; /* it can't have any child XIDs either */
670 if (TransactionIdEquals(xid, s->transactionId))
672 /* As the childXids array is ordered, we can use binary search */
674 high = s->nChildXids - 1;
680 middle = low + (high - low) / 2;
681 probe = s->childXids[middle];
682 if (TransactionIdEquals(probe, xid))
684 else if (TransactionIdPrecedes(probe, xid))
695 * TransactionStartedDuringRecovery
697 * Returns true if the current transaction started while recovery was still
698 * in progress. Recovery might have ended since so RecoveryInProgress() might
699 * return false already.
702 TransactionStartedDuringRecovery(void)
704 return CurrentTransactionState->startedInRecovery;
708 * CommandCounterIncrement
711 CommandCounterIncrement(void)
714 * If the current value of the command counter hasn't been "used" to mark
715 * tuples, we need not increment it, since there's no need to distinguish
716 * a read-only command from others. This helps postpone command counter
717 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
719 if (currentCommandIdUsed)
721 currentCommandId += 1;
722 if (currentCommandId == FirstCommandId) /* check for overflow */
724 currentCommandId -= 1;
726 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
727 errmsg("cannot have more than 2^32-1 commands in a transaction")));
729 currentCommandIdUsed = false;
731 /* Propagate new command ID into static snapshots */
732 SnapshotSetCommandId(currentCommandId);
735 * Make any catalog changes done by the just-completed command visible
736 * in the local syscache. We obviously don't need to do this after a
737 * read-only command. (But see hacks in inval.c to make real sure we
738 * don't think a command that queued inval messages was read-only.)
747 * Interface routine to allow commands to force a synchronous commit of the
748 * current top-level transaction
751 ForceSyncCommit(void)
753 forceSyncCommit = true;
757 /* ----------------------------------------------------------------
758 * StartTransaction stuff
759 * ----------------------------------------------------------------
768 AcceptInvalidationMessages();
777 TransactionState s = CurrentTransactionState;
780 * If this is the first time through, create a private context for
781 * AbortTransaction to work in. By reserving some space now, we can
782 * insulate AbortTransaction from out-of-memory scenarios. Like
783 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
784 * size, so that space will be reserved immediately.
786 if (TransactionAbortContext == NULL)
787 TransactionAbortContext =
788 AllocSetContextCreate(TopMemoryContext,
789 "TransactionAbortContext",
795 * We shouldn't have a transaction context already.
797 Assert(TopTransactionContext == NULL);
800 * Create a toplevel context for the transaction.
802 TopTransactionContext =
803 AllocSetContextCreate(TopMemoryContext,
804 "TopTransactionContext",
805 ALLOCSET_DEFAULT_MINSIZE,
806 ALLOCSET_DEFAULT_INITSIZE,
807 ALLOCSET_DEFAULT_MAXSIZE);
810 * In a top-level transaction, CurTransactionContext is the same as
811 * TopTransactionContext.
813 CurTransactionContext = TopTransactionContext;
814 s->curTransactionContext = CurTransactionContext;
816 /* Make the CurTransactionContext active. */
817 MemoryContextSwitchTo(CurTransactionContext);
821 * AtStart_ResourceOwner
824 AtStart_ResourceOwner(void)
826 TransactionState s = CurrentTransactionState;
829 * We shouldn't have a transaction resource owner already.
831 Assert(TopTransactionResourceOwner == NULL);
834 * Create a toplevel resource owner for the transaction.
836 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
838 TopTransactionResourceOwner = s->curTransactionOwner;
839 CurTransactionResourceOwner = s->curTransactionOwner;
840 CurrentResourceOwner = s->curTransactionOwner;
843 /* ----------------------------------------------------------------
844 * StartSubTransaction stuff
845 * ----------------------------------------------------------------
852 AtSubStart_Memory(void)
854 TransactionState s = CurrentTransactionState;
856 Assert(CurTransactionContext != NULL);
859 * Create a CurTransactionContext, which will be used to hold data that
860 * survives subtransaction commit but disappears on subtransaction abort.
861 * We make it a child of the immediate parent's CurTransactionContext.
863 CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
864 "CurTransactionContext",
865 ALLOCSET_DEFAULT_MINSIZE,
866 ALLOCSET_DEFAULT_INITSIZE,
867 ALLOCSET_DEFAULT_MAXSIZE);
868 s->curTransactionContext = CurTransactionContext;
870 /* Make the CurTransactionContext active. */
871 MemoryContextSwitchTo(CurTransactionContext);
875 * AtSubStart_ResourceOwner
878 AtSubStart_ResourceOwner(void)
880 TransactionState s = CurrentTransactionState;
882 Assert(s->parent != NULL);
885 * Create a resource owner for the subtransaction. We make it a child of
886 * the immediate parent's resource owner.
888 s->curTransactionOwner =
889 ResourceOwnerCreate(s->parent->curTransactionOwner,
892 CurTransactionResourceOwner = s->curTransactionOwner;
893 CurrentResourceOwner = s->curTransactionOwner;
896 /* ----------------------------------------------------------------
897 * CommitTransaction stuff
898 * ----------------------------------------------------------------
902 * RecordTransactionCommit
904 * Returns latest XID among xact and its children, or InvalidTransactionId
905 * if the xact has no XID. (We compute that here just because it's easier.)
908 RecordTransactionCommit(void)
910 TransactionId xid = GetTopTransactionIdIfAny();
911 bool markXidCommitted = TransactionIdIsValid(xid);
912 TransactionId latestXid = InvalidTransactionId;
916 TransactionId *children;
918 SharedInvalidationMessage *invalMessages = NULL;
919 bool RelcacheInitFileInval = false;
922 /* Get data needed for commit record */
923 nrels = smgrGetPendingDeletes(true, &rels);
924 nchildren = xactGetCommittedChildren(&children);
925 if (XLogStandbyInfoActive())
926 nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
927 &RelcacheInitFileInval);
928 wrote_xlog = (XactLastRecEnd.xrecoff != 0);
931 * If we haven't been assigned an XID yet, we neither can, nor do we want
932 * to write a COMMIT record.
934 if (!markXidCommitted)
937 * We expect that every smgrscheduleunlink is followed by a catalog
938 * update, and hence XID assignment, so we shouldn't get here with any
939 * pending deletes. Use a real test not just an Assert to check this,
940 * since it's a bit fragile.
943 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
945 /* Can't have child XIDs either; AssignTransactionId enforces this */
946 Assert(nchildren == 0);
949 * If we didn't create XLOG entries, we're done here; otherwise we
950 * should flush those entries the same as a commit record. (An
951 * example of a possible record that wouldn't cause an XID to be
952 * assigned is a sequence advance record due to nextval() --- we want
953 * to flush that to disk before reporting commit.)
961 * Begin commit critical section and insert the commit XLOG record.
963 /* Tell bufmgr and smgr to prepare for commit */
967 * Mark ourselves as within our "commit critical section". This
968 * forces any concurrent checkpoint to wait until we've updated
969 * pg_clog. Without this, it is possible for the checkpoint to set
970 * REDO after the XLOG record but fail to flush the pg_clog update to
971 * disk, leading to loss of the transaction commit if the system
972 * crashes a little later.
974 * Note: we could, but don't bother to, set this flag in
975 * RecordTransactionAbort. That's because loss of a transaction abort
976 * is noncritical; the presumption would be that it aborted, anyway.
978 * It's safe to change the inCommit flag of our own backend without
979 * holding the ProcArrayLock, since we're the only one modifying it.
980 * This makes checkpoint's determination of which xacts are inCommit a
981 * bit fuzzy, but it doesn't matter.
983 START_CRIT_SECTION();
984 MyPgXact->inCommit = true;
986 SetCurrentTransactionStopTimestamp();
989 * Do we need the long commit record? If not, use the compact format.
991 if (nrels > 0 || nmsgs > 0 || RelcacheInitFileInval || forceSyncCommit)
993 XLogRecData rdata[4];
995 xl_xact_commit xlrec;
997 * Set flags required for recovery processing of commits.
1000 if (RelcacheInitFileInval)
1001 xlrec.xinfo |= XACT_COMPLETION_UPDATE_RELCACHE_FILE;
1002 if (forceSyncCommit)
1003 xlrec.xinfo |= XACT_COMPLETION_FORCE_SYNC_COMMIT;
1005 xlrec.dbId = MyDatabaseId;
1006 xlrec.tsId = MyDatabaseTableSpace;
1008 xlrec.xact_time = xactStopTimestamp;
1009 xlrec.nrels = nrels;
1010 xlrec.nsubxacts = nchildren;
1011 xlrec.nmsgs = nmsgs;
1012 rdata[0].data = (char *) (&xlrec);
1013 rdata[0].len = MinSizeOfXactCommit;
1014 rdata[0].buffer = InvalidBuffer;
1015 /* dump rels to delete */
1018 rdata[0].next = &(rdata[1]);
1019 rdata[1].data = (char *) rels;
1020 rdata[1].len = nrels * sizeof(RelFileNode);
1021 rdata[1].buffer = InvalidBuffer;
1024 /* dump committed child Xids */
1027 rdata[lastrdata].next = &(rdata[2]);
1028 rdata[2].data = (char *) children;
1029 rdata[2].len = nchildren * sizeof(TransactionId);
1030 rdata[2].buffer = InvalidBuffer;
1033 /* dump shared cache invalidation messages */
1036 rdata[lastrdata].next = &(rdata[3]);
1037 rdata[3].data = (char *) invalMessages;
1038 rdata[3].len = nmsgs * sizeof(SharedInvalidationMessage);
1039 rdata[3].buffer = InvalidBuffer;
1042 rdata[lastrdata].next = NULL;
1044 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
1048 XLogRecData rdata[2];
1050 xl_xact_commit_compact xlrec;
1051 xlrec.xact_time = xactStopTimestamp;
1052 xlrec.nsubxacts = nchildren;
1053 rdata[0].data = (char *) (&xlrec);
1054 rdata[0].len = MinSizeOfXactCommitCompact;
1055 rdata[0].buffer = InvalidBuffer;
1056 /* dump committed child Xids */
1059 rdata[0].next = &(rdata[1]);
1060 rdata[1].data = (char *) children;
1061 rdata[1].len = nchildren * sizeof(TransactionId);
1062 rdata[1].buffer = InvalidBuffer;
1065 rdata[lastrdata].next = NULL;
1067 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT_COMPACT, rdata);
1072 * Check if we want to commit asynchronously. We can allow the XLOG flush
1073 * to happen asynchronously if synchronous_commit=off, or if the current
1074 * transaction has not performed any WAL-logged operation. The latter
1075 * case can arise if the current transaction wrote only to temporary
1076 * and/or unlogged tables. In case of a crash, the loss of such a
1077 * transaction will be irrelevant since temp tables will be lost anyway,
1078 * and unlogged tables will be truncated. (Given the foregoing, you might
1079 * think that it would be unnecessary to emit the XLOG record at all in
1080 * this case, but we don't currently try to do that. It would certainly
1081 * cause problems at least in Hot Standby mode, where the
1082 * KnownAssignedXids machinery requires tracking every XID assignment. It
1083 * might be OK to skip it only when wal_level < hot_standby, but for now
1086 * However, if we're doing cleanup of any non-temp rels or committing any
1087 * command that wanted to force sync commit, then we must flush XLOG
1088 * immediately. (We must not allow asynchronous commit if there are any
1089 * non-temp tables to be deleted, because we might delete the files before
1090 * the COMMIT record is flushed to disk. We do allow asynchronous commit
1091 * if all to-be-deleted tables are temporary though, since they are lost
1092 * anyway if we crash.)
1094 if ((wrote_xlog && synchronous_commit > SYNCHRONOUS_COMMIT_OFF) ||
1095 forceSyncCommit || nrels > 0)
1098 * Synchronous commit case:
1100 * Sleep before flush! So we can flush more than one commit records
1101 * per single fsync. (The idea is some other backend may do the
1102 * XLogFlush while we're sleeping. This needs work still, because on
1103 * most Unixen, the minimum select() delay is 10msec or more, which is
1106 * We do not sleep if enableFsync is not turned on, nor if there are
1107 * fewer than CommitSiblings other backends with active transactions.
1109 if (CommitDelay > 0 && enableFsync &&
1110 MinimumActiveBackends(CommitSiblings))
1111 pg_usleep(CommitDelay);
1113 XLogFlush(XactLastRecEnd);
1116 * Wake up all walsenders to send WAL up to the COMMIT record
1117 * immediately if replication is enabled
1119 if (max_wal_senders > 0)
1123 * Now we may update the CLOG, if we wrote a COMMIT record above
1125 if (markXidCommitted)
1126 TransactionIdCommitTree(xid, nchildren, children);
1131 * Asynchronous commit case:
1133 * This enables possible committed transaction loss in the case of a
1134 * postmaster crash because WAL buffers are left unwritten. Ideally we
1135 * could issue the WAL write without the fsync, but some
1136 * wal_sync_methods do not allow separate write/fsync.
1138 * Report the latest async commit LSN, so that the WAL writer knows to
1139 * flush this commit.
1141 XLogSetAsyncXactLSN(XactLastRecEnd);
1144 * We must not immediately update the CLOG, since we didn't flush the
1145 * XLOG. Instead, we store the LSN up to which the XLOG must be
1146 * flushed before the CLOG may be updated.
1148 if (markXidCommitted)
1149 TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1153 * If we entered a commit critical section, leave it now, and let
1154 * checkpoints proceed.
1156 if (markXidCommitted)
1158 MyPgXact->inCommit = false;
1162 /* Compute latestXid while we have the child XIDs handy */
1163 latestXid = TransactionIdLatest(xid, nchildren, children);
1166 * Wait for synchronous replication, if required.
1168 * Note that at this stage we have marked clog, but still show as running
1169 * in the procarray and continue to hold locks.
1171 SyncRepWaitForLSN(XactLastRecEnd);
1173 /* Reset XactLastRecEnd until the next transaction writes something */
1174 XactLastRecEnd.xrecoff = 0;
1177 /* Clean up local data */
1189 AtCCI_LocalCache(void)
1192 * Make any pending relation map changes visible. We must do this before
1193 * processing local sinval messages, so that the map changes will get
1194 * reflected into the relcache when relcache invals are processed.
1196 AtCCI_RelationMap();
1199 * Make catalog changes visible to me for the next command.
1201 CommandEndInvalidationMessages();
1208 AtCommit_Memory(void)
1211 * Now that we're "out" of a transaction, have the system allocate things
1212 * in the top memory context instead of per-transaction contexts.
1214 MemoryContextSwitchTo(TopMemoryContext);
1217 * Release all transaction-local memory.
1219 Assert(TopTransactionContext != NULL);
1220 MemoryContextDelete(TopTransactionContext);
1221 TopTransactionContext = NULL;
1222 CurTransactionContext = NULL;
1223 CurrentTransactionState->curTransactionContext = NULL;
1226 /* ----------------------------------------------------------------
1227 * CommitSubTransaction stuff
1228 * ----------------------------------------------------------------
1232 * AtSubCommit_Memory
1235 AtSubCommit_Memory(void)
1237 TransactionState s = CurrentTransactionState;
1239 Assert(s->parent != NULL);
1241 /* Return to parent transaction level's memory context. */
1242 CurTransactionContext = s->parent->curTransactionContext;
1243 MemoryContextSwitchTo(CurTransactionContext);
1246 * Ordinarily we cannot throw away the child's CurTransactionContext,
1247 * since the data it contains will be needed at upper commit. However, if
1248 * there isn't actually anything in it, we can throw it away. This avoids
1249 * a small memory leak in the common case of "trivial" subxacts.
1251 if (MemoryContextIsEmpty(s->curTransactionContext))
1253 MemoryContextDelete(s->curTransactionContext);
1254 s->curTransactionContext = NULL;
1259 * AtSubCommit_childXids
1261 * Pass my own XID and my child XIDs up to my parent as committed children.
1264 AtSubCommit_childXids(void)
1266 TransactionState s = CurrentTransactionState;
1269 Assert(s->parent != NULL);
1272 * The parent childXids array will need to hold my XID and all my
1273 * childXids, in addition to the XIDs already there.
1275 new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1277 /* Allocate or enlarge the parent array if necessary */
1278 if (s->parent->maxChildXids < new_nChildXids)
1280 int new_maxChildXids;
1281 TransactionId *new_childXids;
1284 * Make it 2x what's needed right now, to avoid having to enlarge it
1285 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1286 * is what ensures that we don't need to worry about integer overflow
1287 * here or in the calculation of new_nChildXids.)
1289 new_maxChildXids = Min(new_nChildXids * 2,
1290 (int) (MaxAllocSize / sizeof(TransactionId)));
1292 if (new_maxChildXids < new_nChildXids)
1294 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1295 errmsg("maximum number of committed subtransactions (%d) exceeded",
1296 (int) (MaxAllocSize / sizeof(TransactionId)))));
1299 * We keep the child-XID arrays in TopTransactionContext; this avoids
1300 * setting up child-transaction contexts for what might be just a few
1301 * bytes of grandchild XIDs.
1303 if (s->parent->childXids == NULL)
1305 MemoryContextAlloc(TopTransactionContext,
1306 new_maxChildXids * sizeof(TransactionId));
1308 new_childXids = repalloc(s->parent->childXids,
1309 new_maxChildXids * sizeof(TransactionId));
1311 s->parent->childXids = new_childXids;
1312 s->parent->maxChildXids = new_maxChildXids;
1316 * Copy all my XIDs to parent's array.
1318 * Note: We rely on the fact that the XID of a child always follows that
1319 * of its parent. By copying the XID of this subtransaction before the
1320 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1321 * all XIDs already in the array belong to subtransactions started and
1322 * subcommitted before us, so their XIDs must precede ours.
1324 s->parent->childXids[s->parent->nChildXids] = s->transactionId;
1326 if (s->nChildXids > 0)
1327 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1329 s->nChildXids * sizeof(TransactionId));
1331 s->parent->nChildXids = new_nChildXids;
1333 /* Release child's array to avoid leakage */
1334 if (s->childXids != NULL)
1335 pfree(s->childXids);
1336 /* We must reset these to avoid double-free if fail later in commit */
1337 s->childXids = NULL;
1339 s->maxChildXids = 0;
1342 /* ----------------------------------------------------------------
1343 * AbortTransaction stuff
1344 * ----------------------------------------------------------------
1348 * RecordTransactionAbort
1350 * Returns latest XID among xact and its children, or InvalidTransactionId
1351 * if the xact has no XID. (We compute that here just because it's easier.)
1353 static TransactionId
1354 RecordTransactionAbort(bool isSubXact)
1356 TransactionId xid = GetCurrentTransactionIdIfAny();
1357 TransactionId latestXid;
1361 TransactionId *children;
1362 XLogRecData rdata[3];
1364 xl_xact_abort xlrec;
1367 * If we haven't been assigned an XID, nobody will care whether we aborted
1368 * or not. Hence, we're done in that case. It does not matter if we have
1369 * rels to delete (note that this routine is not responsible for actually
1370 * deleting 'em). We cannot have any child XIDs, either.
1372 if (!TransactionIdIsValid(xid))
1374 /* Reset XactLastRecEnd until the next transaction writes something */
1376 XactLastRecEnd.xrecoff = 0;
1377 return InvalidTransactionId;
1381 * We have a valid XID, so we should write an ABORT record for it.
1383 * We do not flush XLOG to disk here, since the default assumption after a
1384 * crash would be that we aborted, anyway. For the same reason, we don't
1385 * need to worry about interlocking against checkpoint start.
1389 * Check that we haven't aborted halfway through RecordTransactionCommit.
1391 if (TransactionIdDidCommit(xid))
1392 elog(PANIC, "cannot abort transaction %u, it was already committed",
1395 /* Fetch the data we need for the abort record */
1396 nrels = smgrGetPendingDeletes(false, &rels);
1397 nchildren = xactGetCommittedChildren(&children);
1399 /* XXX do we really need a critical section here? */
1400 START_CRIT_SECTION();
1402 /* Write the ABORT record */
1404 xlrec.xact_time = GetCurrentTimestamp();
1407 SetCurrentTransactionStopTimestamp();
1408 xlrec.xact_time = xactStopTimestamp;
1410 xlrec.nrels = nrels;
1411 xlrec.nsubxacts = nchildren;
1412 rdata[0].data = (char *) (&xlrec);
1413 rdata[0].len = MinSizeOfXactAbort;
1414 rdata[0].buffer = InvalidBuffer;
1415 /* dump rels to delete */
1418 rdata[0].next = &(rdata[1]);
1419 rdata[1].data = (char *) rels;
1420 rdata[1].len = nrels * sizeof(RelFileNode);
1421 rdata[1].buffer = InvalidBuffer;
1424 /* dump committed child Xids */
1427 rdata[lastrdata].next = &(rdata[2]);
1428 rdata[2].data = (char *) children;
1429 rdata[2].len = nchildren * sizeof(TransactionId);
1430 rdata[2].buffer = InvalidBuffer;
1433 rdata[lastrdata].next = NULL;
1435 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
1438 * Report the latest async abort LSN, so that the WAL writer knows to
1439 * flush this abort. There's nothing to be gained by delaying this, since
1440 * WALWriter may as well do this when it can. This is important with
1441 * streaming replication because if we don't flush WAL regularly we will
1442 * find that large aborts leave us with a long backlog for when commits
1443 * occur after the abort, increasing our window of data loss should
1444 * problems occur at that point.
1447 XLogSetAsyncXactLSN(XactLastRecEnd);
1450 * Mark the transaction aborted in clog. This is not absolutely necessary
1451 * but we may as well do it while we are here; also, in the subxact case
1452 * it is helpful because XactLockTableWait makes use of it to avoid
1453 * waiting for already-aborted subtransactions. It is OK to do it without
1454 * having flushed the ABORT record to disk, because in event of a crash
1455 * we'd be assumed to have aborted anyway.
1457 TransactionIdAbortTree(xid, nchildren, children);
1461 /* Compute latestXid while we have the child XIDs handy */
1462 latestXid = TransactionIdLatest(xid, nchildren, children);
1465 * If we're aborting a subtransaction, we can immediately remove failed
1466 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1467 * subxacts, because we already have the child XID array at hand. For
1468 * main xacts, the equivalent happens just after this function returns.
1471 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1473 /* Reset XactLastRecEnd until the next transaction writes something */
1475 XactLastRecEnd.xrecoff = 0;
1477 /* And clean up local data */
1488 AtAbort_Memory(void)
1491 * Switch into TransactionAbortContext, which should have some free space
1492 * even if nothing else does. We'll work in this context until we've
1493 * finished cleaning up.
1495 * It is barely possible to get here when we've not been able to create
1496 * TransactionAbortContext yet; if so use TopMemoryContext.
1498 if (TransactionAbortContext != NULL)
1499 MemoryContextSwitchTo(TransactionAbortContext);
1501 MemoryContextSwitchTo(TopMemoryContext);
1508 AtSubAbort_Memory(void)
1510 Assert(TransactionAbortContext != NULL);
1512 MemoryContextSwitchTo(TransactionAbortContext);
1517 * AtAbort_ResourceOwner
1520 AtAbort_ResourceOwner(void)
1523 * Make sure we have a valid ResourceOwner, if possible (else it will be
1524 * NULL, which is OK)
1526 CurrentResourceOwner = TopTransactionResourceOwner;
1530 * AtSubAbort_ResourceOwner
1533 AtSubAbort_ResourceOwner(void)
1535 TransactionState s = CurrentTransactionState;
1537 /* Make sure we have a valid ResourceOwner */
1538 CurrentResourceOwner = s->curTransactionOwner;
1543 * AtSubAbort_childXids
1546 AtSubAbort_childXids(void)
1548 TransactionState s = CurrentTransactionState;
1551 * We keep the child-XID arrays in TopTransactionContext (see
1552 * AtSubCommit_childXids). This means we'd better free the array
1553 * explicitly at abort to avoid leakage.
1555 if (s->childXids != NULL)
1556 pfree(s->childXids);
1557 s->childXids = NULL;
1559 s->maxChildXids = 0;
1562 * We could prune the unreportedXids array here. But we don't bother. That
1563 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1564 * would likely introduce more CPU time into the more common paths, so we
1565 * choose not to do that.
1569 /* ----------------------------------------------------------------
1570 * CleanupTransaction stuff
1571 * ----------------------------------------------------------------
1578 AtCleanup_Memory(void)
1580 Assert(CurrentTransactionState->parent == NULL);
1583 * Now that we're "out" of a transaction, have the system allocate things
1584 * in the top memory context instead of per-transaction contexts.
1586 MemoryContextSwitchTo(TopMemoryContext);
1589 * Clear the special abort context for next time.
1591 if (TransactionAbortContext != NULL)
1592 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1595 * Release all transaction-local memory.
1597 if (TopTransactionContext != NULL)
1598 MemoryContextDelete(TopTransactionContext);
1599 TopTransactionContext = NULL;
1600 CurTransactionContext = NULL;
1601 CurrentTransactionState->curTransactionContext = NULL;
1605 /* ----------------------------------------------------------------
1606 * CleanupSubTransaction stuff
1607 * ----------------------------------------------------------------
1611 * AtSubCleanup_Memory
1614 AtSubCleanup_Memory(void)
1616 TransactionState s = CurrentTransactionState;
1618 Assert(s->parent != NULL);
1620 /* Make sure we're not in an about-to-be-deleted context */
1621 MemoryContextSwitchTo(s->parent->curTransactionContext);
1622 CurTransactionContext = s->parent->curTransactionContext;
1625 * Clear the special abort context for next time.
1627 if (TransactionAbortContext != NULL)
1628 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1631 * Delete the subxact local memory contexts. Its CurTransactionContext can
1632 * go too (note this also kills CurTransactionContexts from any children
1635 if (s->curTransactionContext)
1636 MemoryContextDelete(s->curTransactionContext);
1637 s->curTransactionContext = NULL;
1640 /* ----------------------------------------------------------------
1641 * interface routines
1642 * ----------------------------------------------------------------
1649 StartTransaction(void)
1652 VirtualTransactionId vxid;
1655 * Let's just make sure the state stack is empty
1657 s = &TopTransactionStateData;
1658 CurrentTransactionState = s;
1661 * check the current transaction state
1663 if (s->state != TRANS_DEFAULT)
1664 elog(WARNING, "StartTransaction while in %s state",
1665 TransStateAsString(s->state));
1668 * set the current transaction state information appropriately during
1671 s->state = TRANS_START;
1672 s->transactionId = InvalidTransactionId; /* until assigned */
1675 * Make sure we've reset xact state variables
1677 * If recovery is still in progress, mark this transaction as read-only.
1678 * We have lower level defences in XLogInsert and elsewhere to stop us
1679 * from modifying data during recovery, but this gives the normal
1680 * indication to the user that the transaction is read-only.
1682 if (RecoveryInProgress())
1684 s->startedInRecovery = true;
1685 XactReadOnly = true;
1689 s->startedInRecovery = false;
1690 XactReadOnly = DefaultXactReadOnly;
1692 XactDeferrable = DefaultXactDeferrable;
1693 XactIsoLevel = DefaultXactIsoLevel;
1694 forceSyncCommit = false;
1695 MyXactAccessedTempRel = false;
1698 * reinitialize within-transaction counters
1700 s->subTransactionId = TopSubTransactionId;
1701 currentSubTransactionId = TopSubTransactionId;
1702 currentCommandId = FirstCommandId;
1703 currentCommandIdUsed = false;
1706 * initialize reported xid accounting
1708 nUnreportedXids = 0;
1711 * must initialize resource-management stuff first
1714 AtStart_ResourceOwner();
1717 * Assign a new LocalTransactionId, and combine it with the backendId to
1718 * form a virtual transaction id.
1720 vxid.backendId = MyBackendId;
1721 vxid.localTransactionId = GetNextLocalTransactionId();
1724 * Lock the virtual transaction id before we announce it in the proc array
1726 VirtualXactLockTableInsert(vxid);
1729 * Advertise it in the proc array. We assume assignment of
1730 * LocalTransactionID is atomic, and the backendId should be set already.
1732 Assert(MyProc->backendId == vxid.backendId);
1733 MyProc->lxid = vxid.localTransactionId;
1735 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
1738 * set transaction_timestamp() (a/k/a now()). We want this to be the same
1739 * as the first command's statement_timestamp(), so don't do a fresh
1740 * GetCurrentTimestamp() call (which'd be expensive anyway). Also, mark
1741 * xactStopTimestamp as unset.
1743 xactStartTimestamp = stmtStartTimestamp;
1744 xactStopTimestamp = 0;
1745 pgstat_report_xact_timestamp(xactStartTimestamp);
1748 * initialize current transaction state fields
1750 * note: prevXactReadOnly is not used at the outermost level
1752 s->nestingLevel = 1;
1753 s->gucNestLevel = 1;
1754 s->childXids = NULL;
1756 s->maxChildXids = 0;
1757 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
1758 /* SecurityRestrictionContext should never be set outside a transaction */
1759 Assert(s->prevSecContext == 0);
1762 * initialize other subsystems for new transaction
1767 AfterTriggerBeginXact();
1770 * done with start processing, set current transaction state to "in
1773 s->state = TRANS_INPROGRESS;
1775 ShowTransactionState("StartTransaction");
1782 * NB: if you change this routine, better look at PrepareTransaction too!
1785 CommitTransaction(void)
1787 TransactionState s = CurrentTransactionState;
1788 TransactionId latestXid;
1790 ShowTransactionState("CommitTransaction");
1793 * check the current transaction state
1795 if (s->state != TRANS_INPROGRESS)
1796 elog(WARNING, "CommitTransaction while in %s state",
1797 TransStateAsString(s->state));
1798 Assert(s->parent == NULL);
1801 * Do pre-commit processing that involves calling user-defined code, such
1802 * as triggers. Since closing cursors could queue trigger actions,
1803 * triggers could open cursors, etc, we have to keep looping until there's
1804 * nothing left to do.
1809 * Fire all currently pending deferred triggers.
1811 AfterTriggerFireDeferred();
1814 * Close open portals (converting holdable ones into static portals).
1815 * If there weren't any, we are done ... otherwise loop back to check
1816 * if they queued deferred triggers. Lather, rinse, repeat.
1818 if (!PreCommit_Portals(false))
1823 * The remaining actions cannot call any user-defined code, so it's safe
1824 * to start shutting down within-transaction services. But note that most
1825 * of this stuff could still throw an error, which would switch us into
1826 * the transaction-abort path.
1829 /* Shut down the deferred-trigger manager */
1830 AfterTriggerEndXact(true);
1833 * Let ON COMMIT management do its thing (must happen after closing
1834 * cursors, to avoid dangling-reference problems)
1836 PreCommit_on_commit_actions();
1838 /* close large objects before lower-level cleanup */
1839 AtEOXact_LargeObject(true);
1842 * Mark serializable transaction as complete for predicate locking
1843 * purposes. This should be done as late as we can put it and still allow
1844 * errors to be raised for failure patterns found at commit.
1846 PreCommit_CheckForSerializationFailure();
1849 * Insert notifications sent by NOTIFY commands into the queue. This
1850 * should be late in the pre-commit sequence to minimize time spent
1851 * holding the notify-insertion lock.
1855 /* Prevent cancel/die interrupt while cleaning up */
1858 /* Commit updates to the relation map --- do this as late as possible */
1859 AtEOXact_RelationMap(true);
1862 * set the current transaction state information appropriately during
1865 s->state = TRANS_COMMIT;
1868 * Here is where we really truly commit.
1870 latestXid = RecordTransactionCommit();
1872 TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
1875 * Let others know about no transaction in progress by me. Note that this
1876 * must be done _before_ releasing locks we hold and _after_
1877 * RecordTransactionCommit.
1879 ProcArrayEndTransaction(MyProc, latestXid);
1882 * This is all post-commit cleanup. Note that if an error is raised here,
1883 * it's too late to abort the transaction. This should be just
1884 * noncritical resource releasing.
1886 * The ordering of operations is not entirely random. The idea is:
1887 * release resources visible to other backends (eg, files, buffer pins);
1888 * then release locks; then release backend-local resources. We want to
1889 * release locks at the point where any backend waiting for us will see
1890 * our transaction as being fully cleaned up.
1892 * Resources that can be associated with individual queries are handled by
1893 * the ResourceOwner mechanism. The other calls here are for backend-wide
1897 CallXactCallbacks(XACT_EVENT_COMMIT);
1899 ResourceOwnerRelease(TopTransactionResourceOwner,
1900 RESOURCE_RELEASE_BEFORE_LOCKS,
1903 /* Check we've released all buffer pins */
1904 AtEOXact_Buffers(true);
1906 /* Clean up the relation cache */
1907 AtEOXact_RelationCache(true);
1910 * Make catalog changes visible to all backends. This has to happen after
1911 * relcache references are dropped (see comments for
1912 * AtEOXact_RelationCache), but before locks are released (if anyone is
1913 * waiting for lock on a relation we've modified, we want them to know
1914 * about the catalog change before they start using the relation).
1916 AtEOXact_Inval(true);
1919 * Likewise, dropping of files deleted during the transaction is best done
1920 * after releasing relcache and buffer pins. (This is not strictly
1921 * necessary during commit, since such pins should have been released
1922 * already, but this ordering is definitely critical during abort.)
1924 smgrDoPendingDeletes(true);
1926 AtEOXact_MultiXact();
1928 ResourceOwnerRelease(TopTransactionResourceOwner,
1929 RESOURCE_RELEASE_LOCKS,
1931 ResourceOwnerRelease(TopTransactionResourceOwner,
1932 RESOURCE_RELEASE_AFTER_LOCKS,
1935 /* Check we've released all catcache entries */
1936 AtEOXact_CatCache(true);
1939 AtEOXact_GUC(true, 1);
1941 AtEOXact_on_commit_actions(true);
1942 AtEOXact_Namespace(true);
1943 /* smgrcommit already done */
1945 AtEOXact_ComboCid();
1946 AtEOXact_HashTables(true);
1947 AtEOXact_PgStat(true);
1948 AtEOXact_Snapshot(true);
1949 pgstat_report_xact_timestamp(0);
1951 CurrentResourceOwner = NULL;
1952 ResourceOwnerDelete(TopTransactionResourceOwner);
1953 s->curTransactionOwner = NULL;
1954 CurTransactionResourceOwner = NULL;
1955 TopTransactionResourceOwner = NULL;
1959 s->transactionId = InvalidTransactionId;
1960 s->subTransactionId = InvalidSubTransactionId;
1961 s->nestingLevel = 0;
1962 s->gucNestLevel = 0;
1963 s->childXids = NULL;
1965 s->maxChildXids = 0;
1968 * done with commit processing, set current transaction state back to
1971 s->state = TRANS_DEFAULT;
1973 RESUME_INTERRUPTS();
1978 * PrepareTransaction
1980 * NB: if you change this routine, better look at CommitTransaction too!
1983 PrepareTransaction(void)
1985 TransactionState s = CurrentTransactionState;
1986 TransactionId xid = GetCurrentTransactionId();
1987 GlobalTransaction gxact;
1988 TimestampTz prepared_at;
1990 ShowTransactionState("PrepareTransaction");
1993 * check the current transaction state
1995 if (s->state != TRANS_INPROGRESS)
1996 elog(WARNING, "PrepareTransaction while in %s state",
1997 TransStateAsString(s->state));
1998 Assert(s->parent == NULL);
2001 * Do pre-commit processing that involves calling user-defined code, such
2002 * as triggers. Since closing cursors could queue trigger actions,
2003 * triggers could open cursors, etc, we have to keep looping until there's
2004 * nothing left to do.
2009 * Fire all currently pending deferred triggers.
2011 AfterTriggerFireDeferred();
2014 * Close open portals (converting holdable ones into static portals).
2015 * If there weren't any, we are done ... otherwise loop back to check
2016 * if they queued deferred triggers. Lather, rinse, repeat.
2018 if (!PreCommit_Portals(true))
2023 * The remaining actions cannot call any user-defined code, so it's safe
2024 * to start shutting down within-transaction services. But note that most
2025 * of this stuff could still throw an error, which would switch us into
2026 * the transaction-abort path.
2029 /* Shut down the deferred-trigger manager */
2030 AfterTriggerEndXact(true);
2033 * Let ON COMMIT management do its thing (must happen after closing
2034 * cursors, to avoid dangling-reference problems)
2036 PreCommit_on_commit_actions();
2038 /* close large objects before lower-level cleanup */
2039 AtEOXact_LargeObject(true);
2042 * Mark serializable transaction as complete for predicate locking
2043 * purposes. This should be done as late as we can put it and still allow
2044 * errors to be raised for failure patterns found at commit.
2046 PreCommit_CheckForSerializationFailure();
2048 /* NOTIFY will be handled below */
2051 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2052 * this transaction. Having the prepared xact hold locks on another
2053 * backend's temp table seems a bad idea --- for instance it would prevent
2054 * the backend from exiting. There are other problems too, such as how to
2055 * clean up the source backend's local buffers and ON COMMIT state if the
2056 * prepared xact includes a DROP of a temp table.
2058 * We must check this after executing any ON COMMIT actions, because they
2059 * might still access a temp relation.
2061 * XXX In principle this could be relaxed to allow some useful special
2062 * cases, such as a temp table created and dropped all within the
2063 * transaction. That seems to require much more bookkeeping though.
2065 if (MyXactAccessedTempRel)
2067 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2068 errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
2071 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2072 * supported if we added cleanup logic to twophase.c, but for now it
2073 * doesn't seem worth the trouble.
2075 if (XactHasExportedSnapshots())
2077 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2078 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2080 /* Prevent cancel/die interrupt while cleaning up */
2084 * set the current transaction state information appropriately during
2085 * prepare processing
2087 s->state = TRANS_PREPARE;
2089 prepared_at = GetCurrentTimestamp();
2091 /* Tell bufmgr and smgr to prepare for commit */
2095 * Reserve the GID for this transaction. This could fail if the requested
2096 * GID is invalid or already in use.
2098 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
2099 GetUserId(), MyDatabaseId);
2103 * Collect data for the 2PC state file. Note that in general, no actual
2104 * state change should happen in the called modules during this step,
2105 * since it's still possible to fail before commit, and in that case we
2106 * want transaction abort to be able to clean up. (In particular, the
2107 * AtPrepare routines may error out if they find cases they cannot
2108 * handle.) State cleanup should happen in the PostPrepare routines
2109 * below. However, some modules can go ahead and clear state here because
2110 * they wouldn't do anything with it during abort anyway.
2112 * Note: because the 2PC state file records will be replayed in the same
2113 * order they are made, the order of these calls has to match the order in
2114 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2115 * PREPARED; in particular, pay attention to whether things should happen
2116 * before or after releasing the transaction's locks.
2118 StartPrepare(gxact);
2122 AtPrepare_PredicateLocks();
2124 AtPrepare_MultiXact();
2125 AtPrepare_RelationMap();
2128 * Here is where we really truly prepare.
2130 * We have to record transaction prepares even if we didn't make any
2131 * updates, because the transaction manager might get confused if we lose
2132 * a global transaction.
2137 * Now we clean up backend-internal state and release internal resources.
2140 /* Reset XactLastRecEnd until the next transaction writes something */
2141 XactLastRecEnd.xrecoff = 0;
2144 * Let others know about no transaction in progress by me. This has to be
2145 * done *after* the prepared transaction has been marked valid, else
2146 * someone may think it is unlocked and recyclable.
2148 ProcArrayClearTransaction(MyProc);
2151 * This is all post-transaction cleanup. Note that if an error is raised
2152 * here, it's too late to abort the transaction. This should be just
2153 * noncritical resource releasing. See notes in CommitTransaction.
2156 CallXactCallbacks(XACT_EVENT_PREPARE);
2158 ResourceOwnerRelease(TopTransactionResourceOwner,
2159 RESOURCE_RELEASE_BEFORE_LOCKS,
2162 /* Check we've released all buffer pins */
2163 AtEOXact_Buffers(true);
2165 /* Clean up the relation cache */
2166 AtEOXact_RelationCache(true);
2168 /* notify doesn't need a postprepare call */
2170 PostPrepare_PgStat();
2172 PostPrepare_Inval();
2176 PostPrepare_MultiXact(xid);
2178 PostPrepare_Locks(xid);
2179 PostPrepare_PredicateLocks(xid);
2181 ResourceOwnerRelease(TopTransactionResourceOwner,
2182 RESOURCE_RELEASE_LOCKS,
2184 ResourceOwnerRelease(TopTransactionResourceOwner,
2185 RESOURCE_RELEASE_AFTER_LOCKS,
2188 /* Check we've released all catcache entries */
2189 AtEOXact_CatCache(true);
2191 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2192 AtEOXact_GUC(true, 1);
2194 AtEOXact_on_commit_actions(true);
2195 AtEOXact_Namespace(true);
2196 /* smgrcommit already done */
2198 AtEOXact_ComboCid();
2199 AtEOXact_HashTables(true);
2200 /* don't call AtEOXact_PgStat here */
2201 AtEOXact_Snapshot(true);
2203 CurrentResourceOwner = NULL;
2204 ResourceOwnerDelete(TopTransactionResourceOwner);
2205 s->curTransactionOwner = NULL;
2206 CurTransactionResourceOwner = NULL;
2207 TopTransactionResourceOwner = NULL;
2211 s->transactionId = InvalidTransactionId;
2212 s->subTransactionId = InvalidSubTransactionId;
2213 s->nestingLevel = 0;
2214 s->gucNestLevel = 0;
2215 s->childXids = NULL;
2217 s->maxChildXids = 0;
2220 * done with 1st phase commit processing, set current transaction state
2223 s->state = TRANS_DEFAULT;
2225 RESUME_INTERRUPTS();
2233 AbortTransaction(void)
2235 TransactionState s = CurrentTransactionState;
2236 TransactionId latestXid;
2238 /* Prevent cancel/die interrupt while cleaning up */
2241 /* Make sure we have a valid memory context and resource owner */
2243 AtAbort_ResourceOwner();
2246 * Release any LW locks we might be holding as quickly as possible.
2247 * (Regular locks, however, must be held till we finish aborting.)
2248 * Releasing LW locks is critical since we might try to grab them again
2249 * while cleaning up!
2253 /* Clean up buffer I/O and buffer context locks, too */
2258 * Also clean up any open wait for lock, since the lock manager will choke
2259 * if we try to wait for another lock before doing this.
2264 * check the current transaction state
2266 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2267 elog(WARNING, "AbortTransaction while in %s state",
2268 TransStateAsString(s->state));
2269 Assert(s->parent == NULL);
2272 * set the current transaction state information appropriately during the
2275 s->state = TRANS_ABORT;
2278 * Reset user ID which might have been changed transiently. We need this
2279 * to clean up in case control escaped out of a SECURITY DEFINER function
2280 * or other local change of CurrentUserId; therefore, the prior value of
2281 * SecurityRestrictionContext also needs to be restored.
2283 * (Note: it is not necessary to restore session authorization or role
2284 * settings here because those can only be changed via GUC, and GUC will
2285 * take care of rolling them back if need be.)
2287 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
2290 * do abort processing
2292 AfterTriggerEndXact(false); /* 'false' means it's abort */
2294 AtEOXact_LargeObject(false);
2296 AtEOXact_RelationMap(false);
2299 * Advertise the fact that we aborted in pg_clog (assuming that we got as
2300 * far as assigning an XID to advertise).
2302 latestXid = RecordTransactionAbort(false);
2304 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
2307 * Let others know about no transaction in progress by me. Note that this
2308 * must be done _before_ releasing locks we hold and _after_
2309 * RecordTransactionAbort.
2311 ProcArrayEndTransaction(MyProc, latestXid);
2314 * Post-abort cleanup. See notes in CommitTransaction() concerning
2315 * ordering. We can skip all of it if the transaction failed before
2316 * creating a resource owner.
2318 if (TopTransactionResourceOwner != NULL)
2320 CallXactCallbacks(XACT_EVENT_ABORT);
2322 ResourceOwnerRelease(TopTransactionResourceOwner,
2323 RESOURCE_RELEASE_BEFORE_LOCKS,
2325 AtEOXact_Buffers(false);
2326 AtEOXact_RelationCache(false);
2327 AtEOXact_Inval(false);
2328 smgrDoPendingDeletes(false);
2329 AtEOXact_MultiXact();
2330 ResourceOwnerRelease(TopTransactionResourceOwner,
2331 RESOURCE_RELEASE_LOCKS,
2333 ResourceOwnerRelease(TopTransactionResourceOwner,
2334 RESOURCE_RELEASE_AFTER_LOCKS,
2336 AtEOXact_CatCache(false);
2338 AtEOXact_GUC(false, 1);
2339 AtEOXact_SPI(false);
2340 AtEOXact_on_commit_actions(false);
2341 AtEOXact_Namespace(false);
2343 AtEOXact_ComboCid();
2344 AtEOXact_HashTables(false);
2345 AtEOXact_PgStat(false);
2346 pgstat_report_xact_timestamp(0);
2350 * State remains TRANS_ABORT until CleanupTransaction().
2352 RESUME_INTERRUPTS();
2356 * CleanupTransaction
2359 CleanupTransaction(void)
2361 TransactionState s = CurrentTransactionState;
2364 * State should still be TRANS_ABORT from AbortTransaction().
2366 if (s->state != TRANS_ABORT)
2367 elog(FATAL, "CleanupTransaction: unexpected state %s",
2368 TransStateAsString(s->state));
2371 * do abort cleanup processing
2373 AtCleanup_Portals(); /* now safe to release portal memory */
2374 AtEOXact_Snapshot(false); /* and release the transaction's snapshots */
2376 CurrentResourceOwner = NULL; /* and resource owner */
2377 if (TopTransactionResourceOwner)
2378 ResourceOwnerDelete(TopTransactionResourceOwner);
2379 s->curTransactionOwner = NULL;
2380 CurTransactionResourceOwner = NULL;
2381 TopTransactionResourceOwner = NULL;
2383 AtCleanup_Memory(); /* and transaction memory */
2385 s->transactionId = InvalidTransactionId;
2386 s->subTransactionId = InvalidSubTransactionId;
2387 s->nestingLevel = 0;
2388 s->gucNestLevel = 0;
2389 s->childXids = NULL;
2391 s->maxChildXids = 0;
2394 * done with abort processing, set current transaction state back to
2397 s->state = TRANS_DEFAULT;
2401 * StartTransactionCommand
2404 StartTransactionCommand(void)
2406 TransactionState s = CurrentTransactionState;
2408 switch (s->blockState)
2411 * if we aren't in a transaction block, we just do our usual start
2414 case TBLOCK_DEFAULT:
2416 s->blockState = TBLOCK_STARTED;
2420 * We are somewhere in a transaction block or subtransaction and
2421 * about to start a new command. For now we do nothing, but
2422 * someday we may do command-local resource initialization. (Note
2423 * that any needed CommandCounterIncrement was done by the
2424 * previous CommitTransactionCommand.)
2426 case TBLOCK_INPROGRESS:
2427 case TBLOCK_SUBINPROGRESS:
2431 * Here we are in a failed transaction block (one of the commands
2432 * caused an abort) so we do nothing but remain in the abort
2433 * state. Eventually we will get a ROLLBACK command which will
2434 * get us out of this state. (It is up to other code to ensure
2435 * that no commands other than ROLLBACK will be processed in these
2439 case TBLOCK_SUBABORT:
2442 /* These cases are invalid. */
2443 case TBLOCK_STARTED:
2445 case TBLOCK_SUBBEGIN:
2447 case TBLOCK_SUBRELEASE:
2448 case TBLOCK_SUBCOMMIT:
2449 case TBLOCK_ABORT_END:
2450 case TBLOCK_SUBABORT_END:
2451 case TBLOCK_ABORT_PENDING:
2452 case TBLOCK_SUBABORT_PENDING:
2453 case TBLOCK_SUBRESTART:
2454 case TBLOCK_SUBABORT_RESTART:
2455 case TBLOCK_PREPARE:
2456 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2457 BlockStateAsString(s->blockState));
2462 * We must switch to CurTransactionContext before returning. This is
2463 * already done if we called StartTransaction, otherwise not.
2465 Assert(CurTransactionContext != NULL);
2466 MemoryContextSwitchTo(CurTransactionContext);
2470 * CommitTransactionCommand
2473 CommitTransactionCommand(void)
2475 TransactionState s = CurrentTransactionState;
2477 switch (s->blockState)
2480 * This shouldn't happen, because it means the previous
2481 * StartTransactionCommand didn't set the STARTED state
2484 case TBLOCK_DEFAULT:
2485 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2486 BlockStateAsString(s->blockState));
2490 * If we aren't in a transaction block, just do our usual
2491 * transaction commit, and return to the idle state.
2493 case TBLOCK_STARTED:
2494 CommitTransaction();
2495 s->blockState = TBLOCK_DEFAULT;
2499 * We are completing a "BEGIN TRANSACTION" command, so we change
2500 * to the "transaction block in progress" state and return. (We
2501 * assume the BEGIN did nothing to the database, so we need no
2502 * CommandCounterIncrement.)
2505 s->blockState = TBLOCK_INPROGRESS;
2509 * This is the case when we have finished executing a command
2510 * someplace within a transaction block. We increment the command
2511 * counter and return.
2513 case TBLOCK_INPROGRESS:
2514 case TBLOCK_SUBINPROGRESS:
2515 CommandCounterIncrement();
2519 * We are completing a "COMMIT" command. Do it and return to the
2523 CommitTransaction();
2524 s->blockState = TBLOCK_DEFAULT;
2528 * Here we are in the middle of a transaction block but one of the
2529 * commands caused an abort so we do nothing but remain in the
2530 * abort state. Eventually we will get a ROLLBACK comand.
2533 case TBLOCK_SUBABORT:
2537 * Here we were in an aborted transaction block and we just got
2538 * the ROLLBACK command from the user, so clean up the
2539 * already-aborted transaction and return to the idle state.
2541 case TBLOCK_ABORT_END:
2542 CleanupTransaction();
2543 s->blockState = TBLOCK_DEFAULT;
2547 * Here we were in a perfectly good transaction block but the user
2548 * told us to ROLLBACK anyway. We have to abort the transaction
2549 * and then clean up.
2551 case TBLOCK_ABORT_PENDING:
2553 CleanupTransaction();
2554 s->blockState = TBLOCK_DEFAULT;
2558 * We are completing a "PREPARE TRANSACTION" command. Do it and
2559 * return to the idle state.
2561 case TBLOCK_PREPARE:
2562 PrepareTransaction();
2563 s->blockState = TBLOCK_DEFAULT;
2567 * We were just issued a SAVEPOINT inside a transaction block.
2568 * Start a subtransaction. (DefineSavepoint already did
2569 * PushTransaction, so as to have someplace to put the SUBBEGIN
2572 case TBLOCK_SUBBEGIN:
2573 StartSubTransaction();
2574 s->blockState = TBLOCK_SUBINPROGRESS;
2578 * We were issued a RELEASE command, so we end the
2579 * current subtransaction and return to the parent transaction.
2580 * The parent might be ended too, so repeat till we find an
2581 * INPROGRESS transaction or subtransaction.
2583 case TBLOCK_SUBRELEASE:
2586 CommitSubTransaction();
2587 s = CurrentTransactionState; /* changed by pop */
2588 } while (s->blockState == TBLOCK_SUBRELEASE);
2590 Assert(s->blockState == TBLOCK_INPROGRESS ||
2591 s->blockState == TBLOCK_SUBINPROGRESS);
2595 * We were issued a COMMIT, so we end the current subtransaction
2596 * hierarchy and perform final commit. We do this by rolling up
2597 * any subtransactions into their parent, which leads to O(N^2)
2598 * operations with respect to resource owners - this isn't that
2599 * bad until we approach a thousands of savepoints but is necessary
2600 * for correctness should after triggers create new resource
2603 case TBLOCK_SUBCOMMIT:
2606 CommitSubTransaction();
2607 s = CurrentTransactionState; /* changed by pop */
2608 } while (s->blockState == TBLOCK_SUBCOMMIT);
2609 /* If we had a COMMIT command, finish off the main xact too */
2610 if (s->blockState == TBLOCK_END)
2612 Assert(s->parent == NULL);
2613 CommitTransaction();
2614 s->blockState = TBLOCK_DEFAULT;
2616 else if (s->blockState == TBLOCK_PREPARE)
2618 Assert(s->parent == NULL);
2619 PrepareTransaction();
2620 s->blockState = TBLOCK_DEFAULT;
2623 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
2624 BlockStateAsString(s->blockState));
2628 * The current already-failed subtransaction is ending due to a
2629 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2630 * examine the parent (which could be in any of several states).
2632 case TBLOCK_SUBABORT_END:
2633 CleanupSubTransaction();
2634 CommitTransactionCommand();
2638 * As above, but it's not dead yet, so abort first.
2640 case TBLOCK_SUBABORT_PENDING:
2641 AbortSubTransaction();
2642 CleanupSubTransaction();
2643 CommitTransactionCommand();
2647 * The current subtransaction is the target of a ROLLBACK TO
2648 * command. Abort and pop it, then start a new subtransaction
2649 * with the same name.
2651 case TBLOCK_SUBRESTART:
2656 /* save name and keep Cleanup from freeing it */
2659 savepointLevel = s->savepointLevel;
2661 AbortSubTransaction();
2662 CleanupSubTransaction();
2664 DefineSavepoint(NULL);
2665 s = CurrentTransactionState; /* changed by push */
2667 s->savepointLevel = savepointLevel;
2669 /* This is the same as TBLOCK_SUBBEGIN case */
2670 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2671 StartSubTransaction();
2672 s->blockState = TBLOCK_SUBINPROGRESS;
2677 * Same as above, but the subtransaction had already failed, so we
2678 * don't need AbortSubTransaction.
2680 case TBLOCK_SUBABORT_RESTART:
2685 /* save name and keep Cleanup from freeing it */
2688 savepointLevel = s->savepointLevel;
2690 CleanupSubTransaction();
2692 DefineSavepoint(NULL);
2693 s = CurrentTransactionState; /* changed by push */
2695 s->savepointLevel = savepointLevel;
2697 /* This is the same as TBLOCK_SUBBEGIN case */
2698 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2699 StartSubTransaction();
2700 s->blockState = TBLOCK_SUBINPROGRESS;
2707 * AbortCurrentTransaction
2710 AbortCurrentTransaction(void)
2712 TransactionState s = CurrentTransactionState;
2714 switch (s->blockState)
2716 case TBLOCK_DEFAULT:
2717 if (s->state == TRANS_DEFAULT)
2719 /* we are idle, so nothing to do */
2724 * We can get here after an error during transaction start
2725 * (state will be TRANS_START). Need to clean up the
2726 * incompletely started transaction. First, adjust the
2727 * low-level state to suppress warning message from
2730 if (s->state == TRANS_START)
2731 s->state = TRANS_INPROGRESS;
2733 CleanupTransaction();
2738 * if we aren't in a transaction block, we just do the basic abort
2739 * & cleanup transaction.
2741 case TBLOCK_STARTED:
2743 CleanupTransaction();
2744 s->blockState = TBLOCK_DEFAULT;
2748 * If we are in TBLOCK_BEGIN it means something screwed up right
2749 * after reading "BEGIN TRANSACTION". We assume that the user
2750 * will interpret the error as meaning the BEGIN failed to get him
2751 * into a transaction block, so we should abort and return to idle
2756 CleanupTransaction();
2757 s->blockState = TBLOCK_DEFAULT;
2761 * We are somewhere in a transaction block and we've gotten a
2762 * failure, so we abort the transaction and set up the persistent
2763 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
2765 case TBLOCK_INPROGRESS:
2767 s->blockState = TBLOCK_ABORT;
2768 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
2772 * Here, we failed while trying to COMMIT. Clean up the
2773 * transaction and return to idle state (we do not want to stay in
2778 CleanupTransaction();
2779 s->blockState = TBLOCK_DEFAULT;
2783 * Here, we are already in an aborted transaction state and are
2784 * waiting for a ROLLBACK, but for some reason we failed again! So
2785 * we just remain in the abort state.
2788 case TBLOCK_SUBABORT:
2792 * We are in a failed transaction and we got the ROLLBACK command.
2793 * We have already aborted, we just need to cleanup and go to idle
2796 case TBLOCK_ABORT_END:
2797 CleanupTransaction();
2798 s->blockState = TBLOCK_DEFAULT;
2802 * We are in a live transaction and we got a ROLLBACK command.
2803 * Abort, cleanup, go to idle state.
2805 case TBLOCK_ABORT_PENDING:
2807 CleanupTransaction();
2808 s->blockState = TBLOCK_DEFAULT;
2812 * Here, we failed while trying to PREPARE. Clean up the
2813 * transaction and return to idle state (we do not want to stay in
2816 case TBLOCK_PREPARE:
2818 CleanupTransaction();
2819 s->blockState = TBLOCK_DEFAULT;
2823 * We got an error inside a subtransaction. Abort just the
2824 * subtransaction, and go to the persistent SUBABORT state until
2827 case TBLOCK_SUBINPROGRESS:
2828 AbortSubTransaction();
2829 s->blockState = TBLOCK_SUBABORT;
2833 * If we failed while trying to create a subtransaction, clean up
2834 * the broken subtransaction and abort the parent. The same
2835 * applies if we get a failure while ending a subtransaction.
2837 case TBLOCK_SUBBEGIN:
2838 case TBLOCK_SUBRELEASE:
2839 case TBLOCK_SUBCOMMIT:
2840 case TBLOCK_SUBABORT_PENDING:
2841 case TBLOCK_SUBRESTART:
2842 AbortSubTransaction();
2843 CleanupSubTransaction();
2844 AbortCurrentTransaction();
2848 * Same as above, except the Abort() was already done.
2850 case TBLOCK_SUBABORT_END:
2851 case TBLOCK_SUBABORT_RESTART:
2852 CleanupSubTransaction();
2853 AbortCurrentTransaction();
2859 * PreventTransactionChain
2861 * This routine is to be called by statements that must not run inside
2862 * a transaction block, typically because they have non-rollback-able
2863 * side effects or do internal commits.
2865 * If we have already started a transaction block, issue an error; also issue
2866 * an error if we appear to be running inside a user-defined function (which
2867 * could issue more commands and possibly cause a failure after the statement
2868 * completes). Subtransactions are verboten too.
2870 * isTopLevel: passed down from ProcessUtility to determine whether we are
2871 * inside a function or multi-query querystring. (We will always fail if
2872 * this is false, but it's convenient to centralize the check here instead of
2873 * making callers do it.)
2874 * stmtType: statement type name, for error messages.
2877 PreventTransactionChain(bool isTopLevel, const char *stmtType)
2880 * xact block already started?
2882 if (IsTransactionBlock())
2884 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2885 /* translator: %s represents an SQL statement name */
2886 errmsg("%s cannot run inside a transaction block",
2892 if (IsSubTransaction())
2894 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2895 /* translator: %s represents an SQL statement name */
2896 errmsg("%s cannot run inside a subtransaction",
2900 * inside a function call?
2904 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2905 /* translator: %s represents an SQL statement name */
2906 errmsg("%s cannot be executed from a function or multi-command string",
2909 /* If we got past IsTransactionBlock test, should be in default state */
2910 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2911 CurrentTransactionState->blockState != TBLOCK_STARTED)
2912 elog(FATAL, "cannot prevent transaction chain");
2917 * RequireTransactionChain
2919 * This routine is to be called by statements that must run inside
2920 * a transaction block, because they have no effects that persist past
2921 * transaction end (and so calling them outside a transaction block
2922 * is presumably an error). DECLARE CURSOR is an example.
2924 * If we appear to be running inside a user-defined function, we do not
2925 * issue an error, since the function could issue more commands that make
2926 * use of the current statement's results. Likewise subtransactions.
2927 * Thus this is an inverse for PreventTransactionChain.
2929 * isTopLevel: passed down from ProcessUtility to determine whether we are
2930 * inside a function.
2931 * stmtType: statement type name, for error messages.
2934 RequireTransactionChain(bool isTopLevel, const char *stmtType)
2937 * xact block already started?
2939 if (IsTransactionBlock())
2945 if (IsSubTransaction())
2949 * inside a function call?
2955 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2956 /* translator: %s represents an SQL statement name */
2957 errmsg("%s can only be used in transaction blocks",
2962 * IsInTransactionChain
2964 * This routine is for statements that need to behave differently inside
2965 * a transaction block than when running as single commands. ANALYZE is
2966 * currently the only example.
2968 * isTopLevel: passed down from ProcessUtility to determine whether we are
2969 * inside a function.
2972 IsInTransactionChain(bool isTopLevel)
2975 * Return true on same conditions that would make PreventTransactionChain
2978 if (IsTransactionBlock())
2981 if (IsSubTransaction())
2987 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2988 CurrentTransactionState->blockState != TBLOCK_STARTED)
2996 * Register or deregister callback functions for start- and end-of-xact
2999 * These functions are intended for use by dynamically loaded modules.
3000 * For built-in modules we generally just hardwire the appropriate calls
3001 * (mainly because it's easier to control the order that way, where needed).
3003 * At transaction end, the callback occurs post-commit or post-abort, so the
3004 * callback functions can only do noncritical cleanup.
3007 RegisterXactCallback(XactCallback callback, void *arg)
3009 XactCallbackItem *item;
3011 item = (XactCallbackItem *)
3012 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
3013 item->callback = callback;
3015 item->next = Xact_callbacks;
3016 Xact_callbacks = item;
3020 UnregisterXactCallback(XactCallback callback, void *arg)
3022 XactCallbackItem *item;
3023 XactCallbackItem *prev;
3026 for (item = Xact_callbacks; item; prev = item, item = item->next)
3028 if (item->callback == callback && item->arg == arg)
3031 prev->next = item->next;
3033 Xact_callbacks = item->next;
3041 CallXactCallbacks(XactEvent event)
3043 XactCallbackItem *item;
3045 for (item = Xact_callbacks; item; item = item->next)
3046 (*item->callback) (event, item->arg);
3051 * Register or deregister callback functions for start- and end-of-subxact
3054 * Pretty much same as above, but for subtransaction events.
3056 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3057 * so the callback functions can only do noncritical cleanup. At
3058 * subtransaction start, the callback is called when the subtransaction has
3059 * finished initializing.
3062 RegisterSubXactCallback(SubXactCallback callback, void *arg)
3064 SubXactCallbackItem *item;
3066 item = (SubXactCallbackItem *)
3067 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
3068 item->callback = callback;
3070 item->next = SubXact_callbacks;
3071 SubXact_callbacks = item;
3075 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
3077 SubXactCallbackItem *item;
3078 SubXactCallbackItem *prev;
3081 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3083 if (item->callback == callback && item->arg == arg)
3086 prev->next = item->next;
3088 SubXact_callbacks = item->next;
3096 CallSubXactCallbacks(SubXactEvent event,
3097 SubTransactionId mySubid,
3098 SubTransactionId parentSubid)
3100 SubXactCallbackItem *item;
3102 for (item = SubXact_callbacks; item; item = item->next)
3103 (*item->callback) (event, mySubid, parentSubid, item->arg);
3107 /* ----------------------------------------------------------------
3108 * transaction block support
3109 * ----------------------------------------------------------------
3113 * BeginTransactionBlock
3114 * This executes a BEGIN command.
3117 BeginTransactionBlock(void)
3119 TransactionState s = CurrentTransactionState;
3121 switch (s->blockState)
3124 * We are not inside a transaction block, so allow one to begin.
3126 case TBLOCK_STARTED:
3127 s->blockState = TBLOCK_BEGIN;
3131 * Already a transaction block in progress.
3133 case TBLOCK_INPROGRESS:
3134 case TBLOCK_SUBINPROGRESS:
3136 case TBLOCK_SUBABORT:
3138 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3139 errmsg("there is already a transaction in progress")));
3142 /* These cases are invalid. */
3143 case TBLOCK_DEFAULT:
3145 case TBLOCK_SUBBEGIN:
3147 case TBLOCK_SUBRELEASE:
3148 case TBLOCK_SUBCOMMIT:
3149 case TBLOCK_ABORT_END:
3150 case TBLOCK_SUBABORT_END:
3151 case TBLOCK_ABORT_PENDING:
3152 case TBLOCK_SUBABORT_PENDING:
3153 case TBLOCK_SUBRESTART:
3154 case TBLOCK_SUBABORT_RESTART:
3155 case TBLOCK_PREPARE:
3156 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3157 BlockStateAsString(s->blockState));
3163 * PrepareTransactionBlock
3164 * This executes a PREPARE command.
3166 * Since PREPARE may actually do a ROLLBACK, the result indicates what
3167 * happened: TRUE for PREPARE, FALSE for ROLLBACK.
3169 * Note that we don't actually do anything here except change blockState.
3170 * The real work will be done in the upcoming PrepareTransaction().
3171 * We do it this way because it's not convenient to change memory context,
3172 * resource owner, etc while executing inside a Portal.
3175 PrepareTransactionBlock(char *gid)
3180 /* Set up to commit the current transaction */
3181 result = EndTransactionBlock();
3183 /* If successful, change outer tblock state to PREPARE */
3186 s = CurrentTransactionState;
3188 while (s->parent != NULL)
3191 if (s->blockState == TBLOCK_END)
3193 /* Save GID where PrepareTransaction can find it again */
3194 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
3196 s->blockState = TBLOCK_PREPARE;
3201 * ignore case where we are not in a transaction;
3202 * EndTransactionBlock already issued a warning.
3204 Assert(s->blockState == TBLOCK_STARTED);
3205 /* Don't send back a PREPARE result tag... */
3214 * EndTransactionBlock
3215 * This executes a COMMIT command.
3217 * Since COMMIT may actually do a ROLLBACK, the result indicates what
3218 * happened: TRUE for COMMIT, FALSE for ROLLBACK.
3220 * Note that we don't actually do anything here except change blockState.
3221 * The real work will be done in the upcoming CommitTransactionCommand().
3222 * We do it this way because it's not convenient to change memory context,
3223 * resource owner, etc while executing inside a Portal.
3226 EndTransactionBlock(void)
3228 TransactionState s = CurrentTransactionState;
3229 bool result = false;
3231 switch (s->blockState)
3234 * We are in a transaction block, so tell CommitTransactionCommand
3237 case TBLOCK_INPROGRESS:
3238 s->blockState = TBLOCK_END;
3243 * We are in a failed transaction block. Tell
3244 * CommitTransactionCommand it's time to exit the block.
3247 s->blockState = TBLOCK_ABORT_END;
3251 * We are in a live subtransaction block. Set up to subcommit all
3252 * open subtransactions and then commit the main transaction.
3254 case TBLOCK_SUBINPROGRESS:
3255 while (s->parent != NULL)
3257 if (s->blockState == TBLOCK_SUBINPROGRESS)
3258 s->blockState = TBLOCK_SUBCOMMIT;
3260 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3261 BlockStateAsString(s->blockState));
3264 if (s->blockState == TBLOCK_INPROGRESS)
3265 s->blockState = TBLOCK_END;
3267 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3268 BlockStateAsString(s->blockState));
3273 * Here we are inside an aborted subtransaction. Treat the COMMIT
3274 * as ROLLBACK: set up to abort everything and exit the main
3277 case TBLOCK_SUBABORT:
3278 while (s->parent != NULL)
3280 if (s->blockState == TBLOCK_SUBINPROGRESS)
3281 s->blockState = TBLOCK_SUBABORT_PENDING;
3282 else if (s->blockState == TBLOCK_SUBABORT)
3283 s->blockState = TBLOCK_SUBABORT_END;
3285 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3286 BlockStateAsString(s->blockState));
3289 if (s->blockState == TBLOCK_INPROGRESS)
3290 s->blockState = TBLOCK_ABORT_PENDING;
3291 else if (s->blockState == TBLOCK_ABORT)
3292 s->blockState = TBLOCK_ABORT_END;
3294 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3295 BlockStateAsString(s->blockState));
3299 * The user issued COMMIT when not inside a transaction. Issue a
3300 * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
3301 * CommitTransactionCommand() will then close the transaction and
3302 * put us back into the default state.
3304 case TBLOCK_STARTED:
3306 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3307 errmsg("there is no transaction in progress")));
3311 /* These cases are invalid. */
3312 case TBLOCK_DEFAULT:
3314 case TBLOCK_SUBBEGIN:
3316 case TBLOCK_SUBRELEASE:
3317 case TBLOCK_SUBCOMMIT:
3318 case TBLOCK_ABORT_END:
3319 case TBLOCK_SUBABORT_END:
3320 case TBLOCK_ABORT_PENDING:
3321 case TBLOCK_SUBABORT_PENDING:
3322 case TBLOCK_SUBRESTART:
3323 case TBLOCK_SUBABORT_RESTART:
3324 case TBLOCK_PREPARE:
3325 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3326 BlockStateAsString(s->blockState));
3334 * UserAbortTransactionBlock
3335 * This executes a ROLLBACK command.
3337 * As above, we don't actually do anything here except change blockState.
3340 UserAbortTransactionBlock(void)
3342 TransactionState s = CurrentTransactionState;
3344 switch (s->blockState)
3347 * We are inside a transaction block and we got a ROLLBACK command
3348 * from the user, so tell CommitTransactionCommand to abort and
3349 * exit the transaction block.
3351 case TBLOCK_INPROGRESS:
3352 s->blockState = TBLOCK_ABORT_PENDING;
3356 * We are inside a failed transaction block and we got a ROLLBACK
3357 * command from the user. Abort processing is already done, so
3358 * CommitTransactionCommand just has to cleanup and go back to
3362 s->blockState = TBLOCK_ABORT_END;
3366 * We are inside a subtransaction. Mark everything up to top
3367 * level as exitable.
3369 case TBLOCK_SUBINPROGRESS:
3370 case TBLOCK_SUBABORT:
3371 while (s->parent != NULL)
3373 if (s->blockState == TBLOCK_SUBINPROGRESS)
3374 s->blockState = TBLOCK_SUBABORT_PENDING;
3375 else if (s->blockState == TBLOCK_SUBABORT)
3376 s->blockState = TBLOCK_SUBABORT_END;
3378 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3379 BlockStateAsString(s->blockState));
3382 if (s->blockState == TBLOCK_INPROGRESS)
3383 s->blockState = TBLOCK_ABORT_PENDING;
3384 else if (s->blockState == TBLOCK_ABORT)
3385 s->blockState = TBLOCK_ABORT_END;
3387 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3388 BlockStateAsString(s->blockState));
3392 * The user issued ABORT when not inside a transaction. Issue a
3393 * WARNING and go to abort state. The upcoming call to
3394 * CommitTransactionCommand() will then put us back into the
3397 case TBLOCK_STARTED:
3399 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3400 errmsg("there is no transaction in progress")));
3401 s->blockState = TBLOCK_ABORT_PENDING;
3404 /* These cases are invalid. */
3405 case TBLOCK_DEFAULT:
3407 case TBLOCK_SUBBEGIN:
3409 case TBLOCK_SUBRELEASE:
3410 case TBLOCK_SUBCOMMIT:
3411 case TBLOCK_ABORT_END:
3412 case TBLOCK_SUBABORT_END:
3413 case TBLOCK_ABORT_PENDING:
3414 case TBLOCK_SUBABORT_PENDING:
3415 case TBLOCK_SUBRESTART:
3416 case TBLOCK_SUBABORT_RESTART:
3417 case TBLOCK_PREPARE:
3418 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3419 BlockStateAsString(s->blockState));
3426 * This executes a SAVEPOINT command.
3429 DefineSavepoint(char *name)
3431 TransactionState s = CurrentTransactionState;
3433 switch (s->blockState)
3435 case TBLOCK_INPROGRESS:
3436 case TBLOCK_SUBINPROGRESS:
3437 /* Normal subtransaction start */
3439 s = CurrentTransactionState; /* changed by push */
3442 * Savepoint names, like the TransactionState block itself, live
3443 * in TopTransactionContext.
3446 s->name = MemoryContextStrdup(TopTransactionContext, name);
3449 /* These cases are invalid. */
3450 case TBLOCK_DEFAULT:
3451 case TBLOCK_STARTED:
3453 case TBLOCK_SUBBEGIN:
3455 case TBLOCK_SUBRELEASE:
3456 case TBLOCK_SUBCOMMIT:
3458 case TBLOCK_SUBABORT:
3459 case TBLOCK_ABORT_END:
3460 case TBLOCK_SUBABORT_END:
3461 case TBLOCK_ABORT_PENDING:
3462 case TBLOCK_SUBABORT_PENDING:
3463 case TBLOCK_SUBRESTART:
3464 case TBLOCK_SUBABORT_RESTART:
3465 case TBLOCK_PREPARE:
3466 elog(FATAL, "DefineSavepoint: unexpected state %s",
3467 BlockStateAsString(s->blockState));
3474 * This executes a RELEASE command.
3476 * As above, we don't actually do anything here except change blockState.
3479 ReleaseSavepoint(List *options)
3481 TransactionState s = CurrentTransactionState;
3482 TransactionState target,
3487 switch (s->blockState)
3490 * We can't rollback to a savepoint if there is no savepoint
3493 case TBLOCK_INPROGRESS:
3495 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3496 errmsg("no such savepoint")));
3500 * We are in a non-aborted subtransaction. This is the only valid
3503 case TBLOCK_SUBINPROGRESS:
3506 /* These cases are invalid. */
3507 case TBLOCK_DEFAULT:
3508 case TBLOCK_STARTED:
3510 case TBLOCK_SUBBEGIN:
3512 case TBLOCK_SUBRELEASE:
3513 case TBLOCK_SUBCOMMIT:
3515 case TBLOCK_SUBABORT:
3516 case TBLOCK_ABORT_END:
3517 case TBLOCK_SUBABORT_END:
3518 case TBLOCK_ABORT_PENDING:
3519 case TBLOCK_SUBABORT_PENDING:
3520 case TBLOCK_SUBRESTART:
3521 case TBLOCK_SUBABORT_RESTART:
3522 case TBLOCK_PREPARE:
3523 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3524 BlockStateAsString(s->blockState));
3528 foreach(cell, options)
3530 DefElem *elem = lfirst(cell);
3532 if (strcmp(elem->defname, "savepoint_name") == 0)
3533 name = strVal(elem->arg);
3536 Assert(PointerIsValid(name));
3538 for (target = s; PointerIsValid(target); target = target->parent)
3540 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3544 if (!PointerIsValid(target))
3546 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3547 errmsg("no such savepoint")));
3549 /* disallow crossing savepoint level boundaries */
3550 if (target->savepointLevel != s->savepointLevel)
3552 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3553 errmsg("no such savepoint")));
3556 * Mark "commit pending" all subtransactions up to the target
3557 * subtransaction. The actual commits will happen when control gets to
3558 * CommitTransactionCommand.
3560 xact = CurrentTransactionState;
3563 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3564 xact->blockState = TBLOCK_SUBRELEASE;
3567 xact = xact->parent;
3568 Assert(PointerIsValid(xact));
3573 * RollbackToSavepoint
3574 * This executes a ROLLBACK TO <savepoint> command.
3576 * As above, we don't actually do anything here except change blockState.
3579 RollbackToSavepoint(List *options)
3581 TransactionState s = CurrentTransactionState;
3582 TransactionState target,
3587 switch (s->blockState)
3590 * We can't rollback to a savepoint if there is no savepoint
3593 case TBLOCK_INPROGRESS:
3596 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3597 errmsg("no such savepoint")));
3601 * There is at least one savepoint, so proceed.
3603 case TBLOCK_SUBINPROGRESS:
3604 case TBLOCK_SUBABORT:
3607 /* These cases are invalid. */
3608 case TBLOCK_DEFAULT:
3609 case TBLOCK_STARTED:
3611 case TBLOCK_SUBBEGIN:
3613 case TBLOCK_SUBRELEASE:
3614 case TBLOCK_SUBCOMMIT:
3615 case TBLOCK_ABORT_END:
3616 case TBLOCK_SUBABORT_END:
3617 case TBLOCK_ABORT_PENDING:
3618 case TBLOCK_SUBABORT_PENDING:
3619 case TBLOCK_SUBRESTART:
3620 case TBLOCK_SUBABORT_RESTART:
3621 case TBLOCK_PREPARE:
3622 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3623 BlockStateAsString(s->blockState));
3627 foreach(cell, options)
3629 DefElem *elem = lfirst(cell);
3631 if (strcmp(elem->defname, "savepoint_name") == 0)
3632 name = strVal(elem->arg);
3635 Assert(PointerIsValid(name));
3637 for (target = s; PointerIsValid(target); target = target->parent)
3639 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3643 if (!PointerIsValid(target))
3645 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3646 errmsg("no such savepoint")));
3648 /* disallow crossing savepoint level boundaries */
3649 if (target->savepointLevel != s->savepointLevel)
3651 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3652 errmsg("no such savepoint")));
3655 * Mark "abort pending" all subtransactions up to the target
3656 * subtransaction. The actual aborts will happen when control gets to
3657 * CommitTransactionCommand.
3659 xact = CurrentTransactionState;
3664 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3665 xact->blockState = TBLOCK_SUBABORT_PENDING;
3666 else if (xact->blockState == TBLOCK_SUBABORT)
3667 xact->blockState = TBLOCK_SUBABORT_END;
3669 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3670 BlockStateAsString(xact->blockState));
3671 xact = xact->parent;
3672 Assert(PointerIsValid(xact));
3675 /* And mark the target as "restart pending" */
3676 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3677 xact->blockState = TBLOCK_SUBRESTART;
3678 else if (xact->blockState == TBLOCK_SUBABORT)
3679 xact->blockState = TBLOCK_SUBABORT_RESTART;
3681 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3682 BlockStateAsString(xact->blockState));
3686 * BeginInternalSubTransaction
3687 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
3688 * TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
3689 * used in functions that might be called when not inside a BEGIN block
3690 * or when running deferred triggers at COMMIT/PREPARE time. Also, it
3691 * automatically does CommitTransactionCommand/StartTransactionCommand
3692 * instead of expecting the caller to do it.
3695 BeginInternalSubTransaction(char *name)
3697 TransactionState s = CurrentTransactionState;
3699 switch (s->blockState)
3701 case TBLOCK_STARTED:
3702 case TBLOCK_INPROGRESS:
3704 case TBLOCK_PREPARE:
3705 case TBLOCK_SUBINPROGRESS:
3706 /* Normal subtransaction start */
3708 s = CurrentTransactionState; /* changed by push */
3711 * Savepoint names, like the TransactionState block itself, live
3712 * in TopTransactionContext.
3715 s->name = MemoryContextStrdup(TopTransactionContext, name);
3718 /* These cases are invalid. */
3719 case TBLOCK_DEFAULT:
3721 case TBLOCK_SUBBEGIN:
3722 case TBLOCK_SUBRELEASE:
3723 case TBLOCK_SUBCOMMIT:
3725 case TBLOCK_SUBABORT:
3726 case TBLOCK_ABORT_END:
3727 case TBLOCK_SUBABORT_END:
3728 case TBLOCK_ABORT_PENDING:
3729 case TBLOCK_SUBABORT_PENDING:
3730 case TBLOCK_SUBRESTART:
3731 case TBLOCK_SUBABORT_RESTART:
3732 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
3733 BlockStateAsString(s->blockState));
3737 CommitTransactionCommand();
3738 StartTransactionCommand();
3742 * ReleaseCurrentSubTransaction
3744 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
3745 * savepoint name (if any).
3746 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3749 ReleaseCurrentSubTransaction(void)
3751 TransactionState s = CurrentTransactionState;
3753 if (s->blockState != TBLOCK_SUBINPROGRESS)
3754 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
3755 BlockStateAsString(s->blockState));
3756 Assert(s->state == TRANS_INPROGRESS);
3757 MemoryContextSwitchTo(CurTransactionContext);
3758 CommitSubTransaction();
3759 s = CurrentTransactionState; /* changed by pop */
3760 Assert(s->state == TRANS_INPROGRESS);
3764 * RollbackAndReleaseCurrentSubTransaction
3766 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
3767 * of its savepoint name (if any).
3768 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3771 RollbackAndReleaseCurrentSubTransaction(void)
3773 TransactionState s = CurrentTransactionState;
3775 switch (s->blockState)
3777 /* Must be in a subtransaction */
3778 case TBLOCK_SUBINPROGRESS:
3779 case TBLOCK_SUBABORT:
3782 /* These cases are invalid. */
3783 case TBLOCK_DEFAULT:
3784 case TBLOCK_STARTED:
3786 case TBLOCK_SUBBEGIN:
3787 case TBLOCK_INPROGRESS:
3789 case TBLOCK_SUBRELEASE:
3790 case TBLOCK_SUBCOMMIT:
3792 case TBLOCK_ABORT_END:
3793 case TBLOCK_SUBABORT_END:
3794 case TBLOCK_ABORT_PENDING:
3795 case TBLOCK_SUBABORT_PENDING:
3796 case TBLOCK_SUBRESTART:
3797 case TBLOCK_SUBABORT_RESTART:
3798 case TBLOCK_PREPARE:
3799 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
3800 BlockStateAsString(s->blockState));
3805 * Abort the current subtransaction, if needed.
3807 if (s->blockState == TBLOCK_SUBINPROGRESS)
3808 AbortSubTransaction();
3810 /* And clean it up, too */
3811 CleanupSubTransaction();
3813 s = CurrentTransactionState; /* changed by pop */
3814 AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
3815 s->blockState == TBLOCK_INPROGRESS ||
3816 s->blockState == TBLOCK_STARTED);
3820 * AbortOutOfAnyTransaction
3822 * This routine is provided for error recovery purposes. It aborts any
3823 * active transaction or transaction block, leaving the system in a known
3827 AbortOutOfAnyTransaction(void)
3829 TransactionState s = CurrentTransactionState;
3832 * Get out of any transaction or nested transaction
3836 switch (s->blockState)
3838 case TBLOCK_DEFAULT:
3839 /* Not in a transaction, do nothing */
3841 case TBLOCK_STARTED:
3843 case TBLOCK_INPROGRESS:
3845 case TBLOCK_ABORT_PENDING:
3846 case TBLOCK_PREPARE:
3847 /* In a transaction, so clean up */
3849 CleanupTransaction();
3850 s->blockState = TBLOCK_DEFAULT;
3853 case TBLOCK_ABORT_END:
3854 /* AbortTransaction already done, still need Cleanup */
3855 CleanupTransaction();
3856 s->blockState = TBLOCK_DEFAULT;
3860 * In a subtransaction, so clean it up and abort parent too
3862 case TBLOCK_SUBBEGIN:
3863 case TBLOCK_SUBINPROGRESS:
3864 case TBLOCK_SUBRELEASE:
3865 case TBLOCK_SUBCOMMIT:
3866 case TBLOCK_SUBABORT_PENDING:
3867 case TBLOCK_SUBRESTART:
3868 AbortSubTransaction();
3869 CleanupSubTransaction();
3870 s = CurrentTransactionState; /* changed by pop */
3873 case TBLOCK_SUBABORT:
3874 case TBLOCK_SUBABORT_END:
3875 case TBLOCK_SUBABORT_RESTART:
3876 /* As above, but AbortSubTransaction already done */
3877 CleanupSubTransaction();
3878 s = CurrentTransactionState; /* changed by pop */
3881 } while (s->blockState != TBLOCK_DEFAULT);
3883 /* Should be out of all subxacts now */
3884 Assert(s->parent == NULL);
3888 * IsTransactionBlock --- are we within a transaction block?
3891 IsTransactionBlock(void)
3893 TransactionState s = CurrentTransactionState;
3895 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
3902 * IsTransactionOrTransactionBlock --- are we within either a transaction
3903 * or a transaction block? (The backend is only really "idle" when this
3906 * This should match up with IsTransactionBlock and IsTransactionState.
3909 IsTransactionOrTransactionBlock(void)
3911 TransactionState s = CurrentTransactionState;
3913 if (s->blockState == TBLOCK_DEFAULT)
3920 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
3923 TransactionBlockStatusCode(void)
3925 TransactionState s = CurrentTransactionState;
3927 switch (s->blockState)
3929 case TBLOCK_DEFAULT:
3930 case TBLOCK_STARTED:
3931 return 'I'; /* idle --- not in transaction */
3933 case TBLOCK_SUBBEGIN:
3934 case TBLOCK_INPROGRESS:
3935 case TBLOCK_SUBINPROGRESS:
3937 case TBLOCK_SUBRELEASE:
3938 case TBLOCK_SUBCOMMIT:
3939 case TBLOCK_PREPARE:
3940 return 'T'; /* in transaction */
3942 case TBLOCK_SUBABORT:
3943 case TBLOCK_ABORT_END:
3944 case TBLOCK_SUBABORT_END:
3945 case TBLOCK_ABORT_PENDING:
3946 case TBLOCK_SUBABORT_PENDING:
3947 case TBLOCK_SUBRESTART:
3948 case TBLOCK_SUBABORT_RESTART:
3949 return 'E'; /* in failed transaction */
3952 /* should never get here */
3953 elog(FATAL, "invalid transaction block state: %s",
3954 BlockStateAsString(s->blockState));
3955 return 0; /* keep compiler quiet */
3962 IsSubTransaction(void)
3964 TransactionState s = CurrentTransactionState;
3966 if (s->nestingLevel >= 2)
3973 * StartSubTransaction
3975 * If you're wondering why this is separate from PushTransaction: it's because
3976 * we can't conveniently do this stuff right inside DefineSavepoint. The
3977 * SAVEPOINT utility command will be executed inside a Portal, and if we
3978 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
3979 * the Portal will undo those settings. So we make DefineSavepoint just
3980 * push a dummy transaction block, and when control returns to the main
3981 * idle loop, CommitTransactionCommand will be called, and we'll come here
3982 * to finish starting the subtransaction.
3985 StartSubTransaction(void)
3987 TransactionState s = CurrentTransactionState;
3989 if (s->state != TRANS_DEFAULT)
3990 elog(WARNING, "StartSubTransaction while in %s state",
3991 TransStateAsString(s->state));
3993 s->state = TRANS_START;
3996 * Initialize subsystems for new subtransaction
3998 * must initialize resource-management stuff first
4000 AtSubStart_Memory();
4001 AtSubStart_ResourceOwner();
4003 AtSubStart_Notify();
4004 AfterTriggerBeginSubXact();
4006 s->state = TRANS_INPROGRESS;
4009 * Call start-of-subxact callbacks
4011 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
4012 s->parent->subTransactionId);
4014 ShowTransactionState("StartSubTransaction");
4018 * CommitSubTransaction
4020 * The caller has to make sure to always reassign CurrentTransactionState
4021 * if it has a local pointer to it after calling this function.
4024 CommitSubTransaction(void)
4026 TransactionState s = CurrentTransactionState;
4028 ShowTransactionState("CommitSubTransaction");
4030 if (s->state != TRANS_INPROGRESS)
4031 elog(WARNING, "CommitSubTransaction while in %s state",
4032 TransStateAsString(s->state));
4034 /* Pre-commit processing goes here -- nothing to do at the moment */
4036 s->state = TRANS_COMMIT;
4038 /* Must CCI to ensure commands of subtransaction are seen as done */
4039 CommandCounterIncrement();
4042 * Prior to 8.4 we marked subcommit in clog at this point. We now only
4043 * perform that step, if required, as part of the atomic update of the
4044 * whole transaction tree at top level commit or abort.
4047 /* Post-commit cleanup */
4048 if (TransactionIdIsValid(s->transactionId))
4049 AtSubCommit_childXids();
4050 AfterTriggerEndSubXact(true);
4051 AtSubCommit_Portals(s->subTransactionId,
4052 s->parent->subTransactionId,
4053 s->parent->curTransactionOwner);
4054 AtEOSubXact_LargeObject(true, s->subTransactionId,
4055 s->parent->subTransactionId);
4056 AtSubCommit_Notify();
4058 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
4059 s->parent->subTransactionId);
4061 ResourceOwnerRelease(s->curTransactionOwner,
4062 RESOURCE_RELEASE_BEFORE_LOCKS,
4064 AtEOSubXact_RelationCache(true, s->subTransactionId,
4065 s->parent->subTransactionId);
4066 AtEOSubXact_Inval(true);
4070 * The only lock we actually release here is the subtransaction XID lock.
4072 CurrentResourceOwner = s->curTransactionOwner;
4073 if (TransactionIdIsValid(s->transactionId))
4074 XactLockTableDelete(s->transactionId);
4077 * Other locks should get transferred to their parent resource owner.
4079 ResourceOwnerRelease(s->curTransactionOwner,
4080 RESOURCE_RELEASE_LOCKS,
4082 ResourceOwnerRelease(s->curTransactionOwner,
4083 RESOURCE_RELEASE_AFTER_LOCKS,
4086 AtEOXact_GUC(true, s->gucNestLevel);
4087 AtEOSubXact_SPI(true, s->subTransactionId);
4088 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
4089 s->parent->subTransactionId);
4090 AtEOSubXact_Namespace(true, s->subTransactionId,
4091 s->parent->subTransactionId);
4092 AtEOSubXact_Files(true, s->subTransactionId,
4093 s->parent->subTransactionId);
4094 AtEOSubXact_HashTables(true, s->nestingLevel);
4095 AtEOSubXact_PgStat(true, s->nestingLevel);
4096 AtSubCommit_Snapshot(s->nestingLevel);
4099 * We need to restore the upper transaction's read-only state, in case the
4100 * upper is read-write while the child is read-only; GUC will incorrectly
4101 * think it should leave the child state in place.
4103 XactReadOnly = s->prevXactReadOnly;
4105 CurrentResourceOwner = s->parent->curTransactionOwner;
4106 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4107 ResourceOwnerDelete(s->curTransactionOwner);
4108 s->curTransactionOwner = NULL;
4110 AtSubCommit_Memory();
4112 s->state = TRANS_DEFAULT;
4118 * AbortSubTransaction
4121 AbortSubTransaction(void)
4123 TransactionState s = CurrentTransactionState;
4125 /* Prevent cancel/die interrupt while cleaning up */
4128 /* Make sure we have a valid memory context and resource owner */
4129 AtSubAbort_Memory();
4130 AtSubAbort_ResourceOwner();
4133 * Release any LW locks we might be holding as quickly as possible.
4134 * (Regular locks, however, must be held till we finish aborting.)
4135 * Releasing LW locks is critical since we might try to grab them again
4136 * while cleaning up!
4138 * FIXME This may be incorrect --- Are there some locks we should keep?
4139 * Buffer locks, for example? I don't think so but I'm not sure.
4149 * check the current transaction state
4151 ShowTransactionState("AbortSubTransaction");
4153 if (s->state != TRANS_INPROGRESS)
4154 elog(WARNING, "AbortSubTransaction while in %s state",
4155 TransStateAsString(s->state));
4157 s->state = TRANS_ABORT;
4160 * Reset user ID which might have been changed transiently. (See notes in
4161 * AbortTransaction.)
4163 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
4166 * We can skip all this stuff if the subxact failed before creating a
4169 if (s->curTransactionOwner)
4171 AfterTriggerEndSubXact(false);
4172 AtSubAbort_Portals(s->subTransactionId,
4173 s->parent->subTransactionId,
4174 s->parent->curTransactionOwner);
4175 AtEOSubXact_LargeObject(false, s->subTransactionId,
4176 s->parent->subTransactionId);
4177 AtSubAbort_Notify();
4179 /* Advertise the fact that we aborted in pg_clog. */
4180 (void) RecordTransactionAbort(true);
4182 /* Post-abort cleanup */
4183 if (TransactionIdIsValid(s->transactionId))
4184 AtSubAbort_childXids();
4186 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
4187 s->parent->subTransactionId);
4189 ResourceOwnerRelease(s->curTransactionOwner,
4190 RESOURCE_RELEASE_BEFORE_LOCKS,
4192 AtEOSubXact_RelationCache(false, s->subTransactionId,
4193 s->parent->subTransactionId);
4194 AtEOSubXact_Inval(false);
4196 ResourceOwnerRelease(s->curTransactionOwner,
4197 RESOURCE_RELEASE_LOCKS,
4199 ResourceOwnerRelease(s->curTransactionOwner,
4200 RESOURCE_RELEASE_AFTER_LOCKS,
4203 AtEOXact_GUC(false, s->gucNestLevel);
4204 AtEOSubXact_SPI(false, s->subTransactionId);
4205 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
4206 s->parent->subTransactionId);
4207 AtEOSubXact_Namespace(false, s->subTransactionId,
4208 s->parent->subTransactionId);
4209 AtEOSubXact_Files(false, s->subTransactionId,
4210 s->parent->subTransactionId);
4211 AtEOSubXact_HashTables(false, s->nestingLevel);
4212 AtEOSubXact_PgStat(false, s->nestingLevel);
4213 AtSubAbort_Snapshot(s->nestingLevel);
4217 * Restore the upper transaction's read-only state, too. This should be
4218 * redundant with GUC's cleanup but we may as well do it for consistency
4219 * with the commit case.
4221 XactReadOnly = s->prevXactReadOnly;
4223 RESUME_INTERRUPTS();
4227 * CleanupSubTransaction
4229 * The caller has to make sure to always reassign CurrentTransactionState
4230 * if it has a local pointer to it after calling this function.
4233 CleanupSubTransaction(void)
4235 TransactionState s = CurrentTransactionState;
4237 ShowTransactionState("CleanupSubTransaction");
4239 if (s->state != TRANS_ABORT)
4240 elog(WARNING, "CleanupSubTransaction while in %s state",
4241 TransStateAsString(s->state));
4243 AtSubCleanup_Portals(s->subTransactionId);
4245 CurrentResourceOwner = s->parent->curTransactionOwner;
4246 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4247 if (s->curTransactionOwner)
4248 ResourceOwnerDelete(s->curTransactionOwner);
4249 s->curTransactionOwner = NULL;
4251 AtSubCleanup_Memory();
4253 s->state = TRANS_DEFAULT;
4260 * Create transaction state stack entry for a subtransaction
4262 * The caller has to make sure to always reassign CurrentTransactionState
4263 * if it has a local pointer to it after calling this function.
4266 PushTransaction(void)
4268 TransactionState p = CurrentTransactionState;
4272 * We keep subtransaction state nodes in TopTransactionContext.
4274 s = (TransactionState)
4275 MemoryContextAllocZero(TopTransactionContext,
4276 sizeof(TransactionStateData));
4279 * Assign a subtransaction ID, watching out for counter wraparound.
4281 currentSubTransactionId += 1;
4282 if (currentSubTransactionId == InvalidSubTransactionId)
4284 currentSubTransactionId -= 1;
4287 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
4288 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
4292 * We can now stack a minimally valid subtransaction without fear of
4295 s->transactionId = InvalidTransactionId; /* until assigned */
4296 s->subTransactionId = currentSubTransactionId;
4298 s->nestingLevel = p->nestingLevel + 1;
4299 s->gucNestLevel = NewGUCNestLevel();
4300 s->savepointLevel = p->savepointLevel;
4301 s->state = TRANS_DEFAULT;
4302 s->blockState = TBLOCK_SUBBEGIN;
4303 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
4304 s->prevXactReadOnly = XactReadOnly;
4306 CurrentTransactionState = s;
4309 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
4310 * with the subtransaction from here on out; in particular they should not
4311 * assume that it necessarily has a transaction context, resource owner,
4318 * Pop back to parent transaction state
4320 * The caller has to make sure to always reassign CurrentTransactionState
4321 * if it has a local pointer to it after calling this function.
4324 PopTransaction(void)
4326 TransactionState s = CurrentTransactionState;
4328 if (s->state != TRANS_DEFAULT)
4329 elog(WARNING, "PopTransaction while in %s state",
4330 TransStateAsString(s->state));
4332 if (s->parent == NULL)
4333 elog(FATAL, "PopTransaction with no parent");
4335 CurrentTransactionState = s->parent;
4337 /* Let's just make sure CurTransactionContext is good */
4338 CurTransactionContext = s->parent->curTransactionContext;
4339 MemoryContextSwitchTo(CurTransactionContext);
4341 /* Ditto for ResourceOwner links */
4342 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4343 CurrentResourceOwner = s->parent->curTransactionOwner;
4345 /* Free the old child structure */
4352 * ShowTransactionState
4356 ShowTransactionState(const char *str)
4358 /* skip work if message will definitely not be printed */
4359 if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
4361 elog(DEBUG3, "%s", str);
4362 ShowTransactionStateRec(CurrentTransactionState);
4367 * ShowTransactionStateRec
4368 * Recursive subroutine for ShowTransactionState
4371 ShowTransactionStateRec(TransactionState s)
4375 initStringInfo(&buf);
4377 if (s->nChildXids > 0)
4381 appendStringInfo(&buf, "%u", s->childXids[0]);
4382 for (i = 1; i < s->nChildXids; i++)
4383 appendStringInfo(&buf, " %u", s->childXids[i]);
4387 ShowTransactionStateRec(s->parent);
4389 /* use ereport to suppress computation if msg will not be printed */
4391 (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u%s, nestlvl: %d, children: %s",
4392 PointerIsValid(s->name) ? s->name : "unnamed",
4393 BlockStateAsString(s->blockState),
4394 TransStateAsString(s->state),
4395 (unsigned int) s->transactionId,
4396 (unsigned int) s->subTransactionId,
4397 (unsigned int) currentCommandId,
4398 currentCommandIdUsed ? " (used)" : "",
4399 s->nestingLevel, buf.data)));
4405 * BlockStateAsString
4409 BlockStateAsString(TBlockState blockState)
4413 case TBLOCK_DEFAULT:
4415 case TBLOCK_STARTED:
4419 case TBLOCK_INPROGRESS:
4420 return "INPROGRESS";
4425 case TBLOCK_ABORT_END:
4427 case TBLOCK_ABORT_PENDING:
4428 return "ABORT PEND";
4429 case TBLOCK_PREPARE:
4431 case TBLOCK_SUBBEGIN:
4433 case TBLOCK_SUBINPROGRESS:
4434 return "SUB INPROGRS";
4435 case TBLOCK_SUBRELEASE:
4436 return "SUB RELEASE";
4437 case TBLOCK_SUBCOMMIT:
4438 return "SUB COMMIT";
4439 case TBLOCK_SUBABORT:
4441 case TBLOCK_SUBABORT_END:
4442 return "SUB ABORT END";
4443 case TBLOCK_SUBABORT_PENDING:
4444 return "SUB ABRT PEND";
4445 case TBLOCK_SUBRESTART:
4446 return "SUB RESTART";
4447 case TBLOCK_SUBABORT_RESTART:
4448 return "SUB AB RESTRT";
4450 return "UNRECOGNIZED";
4454 * TransStateAsString
4458 TransStateAsString(TransState state)
4466 case TRANS_INPROGRESS:
4475 return "UNRECOGNIZED";
4479 * xactGetCommittedChildren
4481 * Gets the list of committed children of the current transaction. The return
4482 * value is the number of child transactions. *ptr is set to point to an
4483 * array of TransactionIds. The array is allocated in TopTransactionContext;
4484 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
4485 * If there are no subxacts, *ptr is set to NULL.
4488 xactGetCommittedChildren(TransactionId **ptr)
4490 TransactionState s = CurrentTransactionState;
4492 if (s->nChildXids == 0)
4495 *ptr = s->childXids;
4497 return s->nChildXids;
4501 * XLOG support routines
4505 * Before 9.0 this was a fairly short function, but now it performs many
4506 * actions for which the order of execution is critical.
4509 xact_redo_commit_internal(TransactionId xid, XLogRecPtr lsn,
4510 TransactionId *sub_xids, int nsubxacts,
4511 SharedInvalidationMessage *inval_msgs, int nmsgs,
4512 RelFileNode *xnodes, int nrels,
4516 TransactionId max_xid;
4519 max_xid = TransactionIdLatest(xid, nsubxacts, sub_xids);
4522 * Make sure nextXid is beyond any XID mentioned in the record.
4524 * We don't expect anyone else to modify nextXid, hence we don't need to
4525 * hold a lock while checking this. We still acquire the lock to modify
4528 if (TransactionIdFollowsOrEquals(max_xid,
4529 ShmemVariableCache->nextXid))
4531 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4532 ShmemVariableCache->nextXid = max_xid;
4533 TransactionIdAdvance(ShmemVariableCache->nextXid);
4534 LWLockRelease(XidGenLock);
4537 if (standbyState == STANDBY_DISABLED)
4540 * Mark the transaction committed in pg_clog.
4542 TransactionIdCommitTree(xid, nsubxacts, sub_xids);
4547 * If a transaction completion record arrives that has as-yet
4548 * unobserved subtransactions then this will not have been fully
4549 * handled by the call to RecordKnownAssignedTransactionIds() in the
4550 * main recovery loop in xlog.c. So we need to do bookkeeping again to
4551 * cover that case. This is confusing and it is easy to think this
4552 * call is irrelevant, which has happened three times in development
4553 * already. Leave it in.
4555 RecordKnownAssignedTransactionIds(max_xid);
4558 * Mark the transaction committed in pg_clog. We use async commit
4559 * protocol during recovery to provide information on database
4560 * consistency for when users try to set hint bits. It is important
4561 * that we do not set hint bits until the minRecoveryPoint is past
4562 * this commit record. This ensures that if we crash we don't see hint
4563 * bits set on changes made by transactions that haven't yet
4564 * recovered. It's unlikely but it's good to be safe.
4566 TransactionIdAsyncCommitTree(xid, nsubxacts, sub_xids, lsn);
4569 * We must mark clog before we update the ProcArray.
4571 ExpireTreeKnownAssignedTransactionIds(xid, nsubxacts, sub_xids, max_xid);
4574 * Send any cache invalidations attached to the commit. We must
4575 * maintain the same order of invalidation then release locks as
4576 * occurs in CommitTransaction().
4578 ProcessCommittedInvalidationMessages(inval_msgs, nmsgs,
4579 XactCompletionRelcacheInitFileInval(xinfo),
4583 * Release locks, if any. We do this for both two phase and normal one
4584 * phase transactions. In effect we are ignoring the prepare phase and
4585 * just going straight to lock release.
4587 StandbyReleaseLockTree(xid, nsubxacts, sub_xids);
4590 /* Make sure files supposed to be dropped are dropped */
4591 for (i = 0; i < nrels; i++)
4593 SMgrRelation srel = smgropen(xnodes[i], InvalidBackendId);
4596 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4598 if (smgrexists(srel, fork))
4600 XLogDropRelation(xnodes[i], fork);
4601 smgrdounlink(srel, fork, true);
4608 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
4609 * in normal operation. For example, in DROP DATABASE, we delete all the
4610 * files belonging to the database, and then commit the transaction. If we
4611 * crash after all the files have been deleted but before the commit, you
4612 * have an entry in pg_database without any files. To minimize the window
4613 * for that, we use ForceSyncCommit() to rush the commit record to disk as
4614 * quick as possible. We have the same window during recovery, and forcing
4615 * an XLogFlush() (which updates minRecoveryPoint during recovery) helps
4616 * to reduce that problem window, for any user that requested
4617 * ForceSyncCommit().
4619 if (XactCompletionForceSyncCommit(xinfo))
4624 * Utility function to call xact_redo_commit_internal after breaking down xlrec
4627 xact_redo_commit(xl_xact_commit *xlrec,
4628 TransactionId xid, XLogRecPtr lsn)
4630 TransactionId *subxacts;
4631 SharedInvalidationMessage *inval_msgs;
4633 /* subxid array follows relfilenodes */
4634 subxacts = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4635 /* invalidation messages array follows subxids */
4636 inval_msgs = (SharedInvalidationMessage *) &(subxacts[xlrec->nsubxacts]);
4638 xact_redo_commit_internal(xid, lsn, subxacts, xlrec->nsubxacts,
4639 inval_msgs, xlrec->nmsgs,
4640 xlrec->xnodes, xlrec->nrels,
4647 * Utility function to call xact_redo_commit_internal for compact form of message.
4650 xact_redo_commit_compact(xl_xact_commit_compact *xlrec,
4651 TransactionId xid, XLogRecPtr lsn)
4653 xact_redo_commit_internal(xid, lsn, xlrec->subxacts, xlrec->nsubxacts,
4654 NULL, 0, /* inval msgs */
4655 NULL, 0, /* relfilenodes */
4656 InvalidOid, /* dbId */
4657 InvalidOid, /* tsId */
4662 * Be careful with the order of execution, as with xact_redo_commit().
4663 * The two functions are similar but differ in key places.
4665 * Note also that an abort can be for a subtransaction and its children,
4666 * not just for a top level abort. That means we have to consider
4667 * topxid != xid, whereas in commit we would find topxid == xid always
4668 * because subtransaction commit is never WAL logged.
4671 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
4673 TransactionId *sub_xids;
4674 TransactionId max_xid;
4677 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4678 max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
4681 * Make sure nextXid is beyond any XID mentioned in the record.
4683 * We don't expect anyone else to modify nextXid, hence we don't need to
4684 * hold a lock while checking this. We still acquire the lock to modify
4687 if (TransactionIdFollowsOrEquals(max_xid,
4688 ShmemVariableCache->nextXid))
4690 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4691 ShmemVariableCache->nextXid = max_xid;
4692 TransactionIdAdvance(ShmemVariableCache->nextXid);
4693 LWLockRelease(XidGenLock);
4696 if (standbyState == STANDBY_DISABLED)
4698 /* Mark the transaction aborted in pg_clog, no need for async stuff */
4699 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4704 * If a transaction completion record arrives that has as-yet
4705 * unobserved subtransactions then this will not have been fully
4706 * handled by the call to RecordKnownAssignedTransactionIds() in the
4707 * main recovery loop in xlog.c. So we need to do bookkeeping again to
4708 * cover that case. This is confusing and it is easy to think this
4709 * call is irrelevant, which has happened three times in development
4710 * already. Leave it in.
4712 RecordKnownAssignedTransactionIds(max_xid);
4714 /* Mark the transaction aborted in pg_clog, no need for async stuff */
4715 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4718 * We must update the ProcArray after we have marked clog.
4720 ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids, max_xid);
4723 * There are no flat files that need updating, nor invalidation
4724 * messages to send or undo.
4728 * Release locks, if any. There are no invalidations to send.
4730 StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
4733 /* Make sure files supposed to be dropped are dropped */
4734 for (i = 0; i < xlrec->nrels; i++)
4736 SMgrRelation srel = smgropen(xlrec->xnodes[i], InvalidBackendId);
4739 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4741 if (smgrexists(srel, fork))
4743 XLogDropRelation(xlrec->xnodes[i], fork);
4744 smgrdounlink(srel, fork, true);
4752 xact_redo(XLogRecPtr lsn, XLogRecord *record)
4754 uint8 info = record->xl_info & ~XLR_INFO_MASK;
4756 /* Backup blocks are not used in xact records */
4757 Assert(!(record->xl_info & XLR_BKP_BLOCK_MASK));
4759 if (info == XLOG_XACT_COMMIT_COMPACT)
4761 xl_xact_commit_compact *xlrec = (xl_xact_commit_compact *) XLogRecGetData(record);
4763 xact_redo_commit_compact(xlrec, record->xl_xid, lsn);
4765 else if (info == XLOG_XACT_COMMIT)
4767 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
4769 xact_redo_commit(xlrec, record->xl_xid, lsn);
4771 else if (info == XLOG_XACT_ABORT)
4773 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
4775 xact_redo_abort(xlrec, record->xl_xid);
4777 else if (info == XLOG_XACT_PREPARE)
4779 /* the record contents are exactly the 2PC file */
4780 RecreateTwoPhaseFile(record->xl_xid,
4781 XLogRecGetData(record), record->xl_len);
4783 else if (info == XLOG_XACT_COMMIT_PREPARED)
4785 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
4787 xact_redo_commit(&xlrec->crec, xlrec->xid, lsn);
4788 RemoveTwoPhaseFile(xlrec->xid, false);
4790 else if (info == XLOG_XACT_ABORT_PREPARED)
4792 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
4794 xact_redo_abort(&xlrec->arec, xlrec->xid);
4795 RemoveTwoPhaseFile(xlrec->xid, false);
4797 else if (info == XLOG_XACT_ASSIGNMENT)
4799 xl_xact_assignment *xlrec = (xl_xact_assignment *) XLogRecGetData(record);
4801 if (standbyState >= STANDBY_INITIALIZED)
4802 ProcArrayApplyXidAssignment(xlrec->xtop,
4803 xlrec->nsubxacts, xlrec->xsub);
4806 elog(PANIC, "xact_redo: unknown op code %u", info);
4810 xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
4813 TransactionId *subxacts;
4815 subxacts = (TransactionId *) &xlrec->xnodes[xlrec->nrels];
4817 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4819 if (xlrec->nrels > 0)
4821 appendStringInfo(buf, "; rels:");
4822 for (i = 0; i < xlrec->nrels; i++)
4824 char *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);
4826 appendStringInfo(buf, " %s", path);
4830 if (xlrec->nsubxacts > 0)
4832 appendStringInfo(buf, "; subxacts:");
4833 for (i = 0; i < xlrec->nsubxacts; i++)
4834 appendStringInfo(buf, " %u", subxacts[i]);
4836 if (xlrec->nmsgs > 0)
4838 SharedInvalidationMessage *msgs;
4840 msgs = (SharedInvalidationMessage *) &subxacts[xlrec->nsubxacts];
4842 if (XactCompletionRelcacheInitFileInval(xlrec->xinfo))
4843 appendStringInfo(buf, "; relcache init file inval dbid %u tsid %u",
4844 xlrec->dbId, xlrec->tsId);
4846 appendStringInfo(buf, "; inval msgs:");
4847 for (i = 0; i < xlrec->nmsgs; i++)
4849 SharedInvalidationMessage *msg = &msgs[i];
4852 appendStringInfo(buf, " catcache %d", msg->id);
4853 else if (msg->id == SHAREDINVALCATALOG_ID)
4854 appendStringInfo(buf, " catalog %u", msg->cat.catId);
4855 else if (msg->id == SHAREDINVALRELCACHE_ID)
4856 appendStringInfo(buf, " relcache %u", msg->rc.relId);
4857 /* remaining cases not expected, but print something anyway */
4858 else if (msg->id == SHAREDINVALSMGR_ID)
4859 appendStringInfo(buf, " smgr");
4860 else if (msg->id == SHAREDINVALRELMAP_ID)
4861 appendStringInfo(buf, " relmap");
4863 appendStringInfo(buf, " unknown id %d", msg->id);
4869 xact_desc_commit_compact(StringInfo buf, xl_xact_commit_compact *xlrec)
4873 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4875 if (xlrec->nsubxacts > 0)
4877 appendStringInfo(buf, "; subxacts:");
4878 for (i = 0; i < xlrec->nsubxacts; i++)
4879 appendStringInfo(buf, " %u", xlrec->subxacts[i]);
4884 xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
4888 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4889 if (xlrec->nrels > 0)
4891 appendStringInfo(buf, "; rels:");
4892 for (i = 0; i < xlrec->nrels; i++)
4894 char *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);
4896 appendStringInfo(buf, " %s", path);
4900 if (xlrec->nsubxacts > 0)
4902 TransactionId *xacts = (TransactionId *)
4903 &xlrec->xnodes[xlrec->nrels];
4905 appendStringInfo(buf, "; subxacts:");
4906 for (i = 0; i < xlrec->nsubxacts; i++)
4907 appendStringInfo(buf, " %u", xacts[i]);
4912 xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
4916 appendStringInfo(buf, "subxacts:");
4918 for (i = 0; i < xlrec->nsubxacts; i++)
4919 appendStringInfo(buf, " %u", xlrec->xsub[i]);
4923 xact_desc(StringInfo buf, uint8 xl_info, char *rec)
4925 uint8 info = xl_info & ~XLR_INFO_MASK;
4927 if (info == XLOG_XACT_COMMIT_COMPACT)
4929 xl_xact_commit_compact *xlrec = (xl_xact_commit_compact *) rec;
4931 appendStringInfo(buf, "commit: ");
4932 xact_desc_commit_compact(buf, xlrec);
4934 else if (info == XLOG_XACT_COMMIT)
4936 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
4938 appendStringInfo(buf, "commit: ");
4939 xact_desc_commit(buf, xlrec);
4941 else if (info == XLOG_XACT_ABORT)
4943 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
4945 appendStringInfo(buf, "abort: ");
4946 xact_desc_abort(buf, xlrec);
4948 else if (info == XLOG_XACT_PREPARE)
4950 appendStringInfo(buf, "prepare");
4952 else if (info == XLOG_XACT_COMMIT_PREPARED)
4954 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
4956 appendStringInfo(buf, "commit prepared %u: ", xlrec->xid);
4957 xact_desc_commit(buf, &xlrec->crec);
4959 else if (info == XLOG_XACT_ABORT_PREPARED)
4961 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
4963 appendStringInfo(buf, "abort prepared %u: ", xlrec->xid);
4964 xact_desc_abort(buf, &xlrec->arec);
4966 else if (info == XLOG_XACT_ASSIGNMENT)
4968 xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
4971 * Note that we ignore the WAL record's xid, since we're more
4972 * interested in the top-level xid that issued the record and which
4973 * xids are being reported here.
4975 appendStringInfo(buf, "xid assignment xtop %u: ", xlrec->xtop);
4976 xact_desc_assignment(buf, xlrec);
4979 appendStringInfo(buf, "UNKNOWN");