1 /*-------------------------------------------------------------------------
4 * top level transaction system support routines
6 * See src/backend/access/transam/README for more information.
8 * Portions Copyright (c) 1996-2012, 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;
394 * GetStableLatestTransactionId
396 * Get the transaction's XID if it has one, else read the next-to-be-assigned
397 * XID. Once we have a value, return that same value for the remainder of the
398 * current transaction. This is meant to provide the reference point for the
399 * age(xid) function, but might be useful for other maintenance tasks as well.
402 GetStableLatestTransactionId(void)
404 static LocalTransactionId lxid = InvalidLocalTransactionId;
405 static TransactionId stablexid = InvalidTransactionId;
407 if (lxid != MyProc->lxid)
410 stablexid = GetTopTransactionIdIfAny();
411 if (!TransactionIdIsValid(stablexid))
412 stablexid = ReadNewTransactionId();
415 Assert(TransactionIdIsValid(stablexid));
421 * AssignTransactionId
423 * Assigns a new permanent XID to the given TransactionState.
424 * We do not assign XIDs to transactions until/unless this is called.
425 * Also, any parent TransactionStates that don't yet have XIDs are assigned
426 * one; this maintains the invariant that a child transaction has an XID
427 * following its parent's.
430 AssignTransactionId(TransactionState s)
432 bool isSubXact = (s->parent != NULL);
433 ResourceOwner currentOwner;
435 /* Assert that caller didn't screw up */
436 Assert(!TransactionIdIsValid(s->transactionId));
437 Assert(s->state == TRANS_INPROGRESS);
440 * Ensure parent(s) have XIDs, so that a child always has an XID later
441 * than its parent. Musn't recurse here, or we might get a stack overflow
442 * if we're at the bottom of a huge stack of subtransactions none of which
445 if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
447 TransactionState p = s->parent;
448 TransactionState *parents;
449 size_t parentOffset = 0;
451 parents = palloc(sizeof(TransactionState) * s->nestingLevel);
452 while (p != NULL && !TransactionIdIsValid(p->transactionId))
454 parents[parentOffset++] = p;
459 * This is technically a recursive call, but the recursion will never
460 * be more than one layer deep.
462 while (parentOffset != 0)
463 AssignTransactionId(parents[--parentOffset]);
469 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
471 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
472 * shared storage other than PG_PROC; because if there's no room for it in
473 * PG_PROC, the subtrans entry is needed to ensure that other backends see
474 * the Xid as "running". See GetNewTransactionId.
476 s->transactionId = GetNewTransactionId(isSubXact);
479 SubTransSetParent(s->transactionId, s->parent->transactionId, false);
482 * If it's a top-level transaction, the predicate locking system needs to
483 * be told about it too.
486 RegisterPredicateLockingXid(s->transactionId);
489 * Acquire lock on the transaction XID. (We assume this cannot block.) We
490 * have to ensure that the lock is assigned to the transaction's own
493 currentOwner = CurrentResourceOwner;
496 CurrentResourceOwner = s->curTransactionOwner;
497 XactLockTableInsert(s->transactionId);
501 /* Ensure CurrentResourceOwner is restored on error */
502 CurrentResourceOwner = currentOwner;
506 CurrentResourceOwner = currentOwner;
509 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
510 * top-level transaction we issue a WAL record for the assignment. We
511 * include the top-level xid and all the subxids that have not yet been
512 * reported using XLOG_XACT_ASSIGNMENT records.
514 * This is required to limit the amount of shared memory required in a hot
515 * standby server to keep track of in-progress XIDs. See notes for
516 * RecordKnownAssignedTransactionIds().
518 * We don't keep track of the immediate parent of each subxid, only the
519 * top-level transaction that each subxact belongs to. This is correct in
520 * recovery only because aborted subtransactions are separately WAL
523 if (isSubXact && XLogStandbyInfoActive())
525 unreportedXids[nUnreportedXids] = s->transactionId;
529 * ensure this test matches similar one in
530 * RecoverPreparedTransactions()
532 if (nUnreportedXids >= PGPROC_MAX_CACHED_SUBXIDS)
534 XLogRecData rdata[2];
535 xl_xact_assignment xlrec;
538 * xtop is always set by now because we recurse up transaction
539 * stack to the highest unassigned xid and then come back down
541 xlrec.xtop = GetTopTransactionId();
542 Assert(TransactionIdIsValid(xlrec.xtop));
543 xlrec.nsubxacts = nUnreportedXids;
545 rdata[0].data = (char *) &xlrec;
546 rdata[0].len = MinSizeOfXactAssignment;
547 rdata[0].buffer = InvalidBuffer;
548 rdata[0].next = &rdata[1];
550 rdata[1].data = (char *) unreportedXids;
551 rdata[1].len = PGPROC_MAX_CACHED_SUBXIDS * sizeof(TransactionId);
552 rdata[1].buffer = InvalidBuffer;
553 rdata[1].next = NULL;
555 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT, rdata);
563 * GetCurrentSubTransactionId
566 GetCurrentSubTransactionId(void)
568 TransactionState s = CurrentTransactionState;
570 return s->subTransactionId;
575 * GetCurrentCommandId
577 * "used" must be TRUE if the caller intends to use the command ID to mark
578 * inserted/updated/deleted tuples. FALSE means the ID is being fetched
579 * for read-only purposes (ie, as a snapshot validity cutoff). See
580 * CommandCounterIncrement() for discussion.
583 GetCurrentCommandId(bool used)
585 /* this is global to a transaction, not subtransaction-local */
587 currentCommandIdUsed = true;
588 return currentCommandId;
592 * GetCurrentTransactionStartTimestamp
595 GetCurrentTransactionStartTimestamp(void)
597 return xactStartTimestamp;
601 * GetCurrentStatementStartTimestamp
604 GetCurrentStatementStartTimestamp(void)
606 return stmtStartTimestamp;
610 * GetCurrentTransactionStopTimestamp
612 * We return current time if the transaction stop time hasn't been set
613 * (which can happen if we decide we don't need to log an XLOG record).
616 GetCurrentTransactionStopTimestamp(void)
618 if (xactStopTimestamp != 0)
619 return xactStopTimestamp;
620 return GetCurrentTimestamp();
624 * SetCurrentStatementStartTimestamp
627 SetCurrentStatementStartTimestamp(void)
629 stmtStartTimestamp = GetCurrentTimestamp();
633 * SetCurrentTransactionStopTimestamp
636 SetCurrentTransactionStopTimestamp(void)
638 xactStopTimestamp = GetCurrentTimestamp();
642 * GetCurrentTransactionNestLevel
644 * Note: this will return zero when not inside any transaction, one when
645 * inside a top-level transaction, etc.
648 GetCurrentTransactionNestLevel(void)
650 TransactionState s = CurrentTransactionState;
652 return s->nestingLevel;
657 * TransactionIdIsCurrentTransactionId
660 TransactionIdIsCurrentTransactionId(TransactionId xid)
665 * We always say that BootstrapTransactionId is "not my transaction ID"
666 * even when it is (ie, during bootstrap). Along with the fact that
667 * transam.c always treats BootstrapTransactionId as already committed,
668 * this causes the tqual.c routines to see all tuples as committed, which
669 * is what we need during bootstrap. (Bootstrap mode only inserts tuples,
670 * it never updates or deletes them, so all tuples can be presumed good
673 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
674 * not my transaction ID, so we can just return "false" immediately for
675 * any non-normal XID.
677 if (!TransactionIdIsNormal(xid))
681 * We will return true for the Xid of the current subtransaction, any of
682 * its subcommitted children, any of its parents, or any of their
683 * previously subcommitted children. However, a transaction being aborted
684 * is no longer "current", even though it may still have an entry on the
687 for (s = CurrentTransactionState; s != NULL; s = s->parent)
692 if (s->state == TRANS_ABORT)
694 if (!TransactionIdIsValid(s->transactionId))
695 continue; /* it can't have any child XIDs either */
696 if (TransactionIdEquals(xid, s->transactionId))
698 /* As the childXids array is ordered, we can use binary search */
700 high = s->nChildXids - 1;
706 middle = low + (high - low) / 2;
707 probe = s->childXids[middle];
708 if (TransactionIdEquals(probe, xid))
710 else if (TransactionIdPrecedes(probe, xid))
721 * TransactionStartedDuringRecovery
723 * Returns true if the current transaction started while recovery was still
724 * in progress. Recovery might have ended since so RecoveryInProgress() might
725 * return false already.
728 TransactionStartedDuringRecovery(void)
730 return CurrentTransactionState->startedInRecovery;
734 * CommandCounterIncrement
737 CommandCounterIncrement(void)
740 * If the current value of the command counter hasn't been "used" to mark
741 * tuples, we need not increment it, since there's no need to distinguish
742 * a read-only command from others. This helps postpone command counter
743 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
745 if (currentCommandIdUsed)
747 currentCommandId += 1;
748 if (currentCommandId == FirstCommandId) /* check for overflow */
750 currentCommandId -= 1;
752 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
753 errmsg("cannot have more than 2^32-1 commands in a transaction")));
755 currentCommandIdUsed = false;
757 /* Propagate new command ID into static snapshots */
758 SnapshotSetCommandId(currentCommandId);
761 * Make any catalog changes done by the just-completed command visible
762 * in the local syscache. We obviously don't need to do this after a
763 * read-only command. (But see hacks in inval.c to make real sure we
764 * don't think a command that queued inval messages was read-only.)
773 * Interface routine to allow commands to force a synchronous commit of the
774 * current top-level transaction
777 ForceSyncCommit(void)
779 forceSyncCommit = true;
783 /* ----------------------------------------------------------------
784 * StartTransaction stuff
785 * ----------------------------------------------------------------
794 AcceptInvalidationMessages();
803 TransactionState s = CurrentTransactionState;
806 * If this is the first time through, create a private context for
807 * AbortTransaction to work in. By reserving some space now, we can
808 * insulate AbortTransaction from out-of-memory scenarios. Like
809 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
810 * size, so that space will be reserved immediately.
812 if (TransactionAbortContext == NULL)
813 TransactionAbortContext =
814 AllocSetContextCreate(TopMemoryContext,
815 "TransactionAbortContext",
821 * We shouldn't have a transaction context already.
823 Assert(TopTransactionContext == NULL);
826 * Create a toplevel context for the transaction.
828 TopTransactionContext =
829 AllocSetContextCreate(TopMemoryContext,
830 "TopTransactionContext",
831 ALLOCSET_DEFAULT_MINSIZE,
832 ALLOCSET_DEFAULT_INITSIZE,
833 ALLOCSET_DEFAULT_MAXSIZE);
836 * In a top-level transaction, CurTransactionContext is the same as
837 * TopTransactionContext.
839 CurTransactionContext = TopTransactionContext;
840 s->curTransactionContext = CurTransactionContext;
842 /* Make the CurTransactionContext active. */
843 MemoryContextSwitchTo(CurTransactionContext);
847 * AtStart_ResourceOwner
850 AtStart_ResourceOwner(void)
852 TransactionState s = CurrentTransactionState;
855 * We shouldn't have a transaction resource owner already.
857 Assert(TopTransactionResourceOwner == NULL);
860 * Create a toplevel resource owner for the transaction.
862 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
864 TopTransactionResourceOwner = s->curTransactionOwner;
865 CurTransactionResourceOwner = s->curTransactionOwner;
866 CurrentResourceOwner = s->curTransactionOwner;
869 /* ----------------------------------------------------------------
870 * StartSubTransaction stuff
871 * ----------------------------------------------------------------
878 AtSubStart_Memory(void)
880 TransactionState s = CurrentTransactionState;
882 Assert(CurTransactionContext != NULL);
885 * Create a CurTransactionContext, which will be used to hold data that
886 * survives subtransaction commit but disappears on subtransaction abort.
887 * We make it a child of the immediate parent's CurTransactionContext.
889 CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
890 "CurTransactionContext",
891 ALLOCSET_DEFAULT_MINSIZE,
892 ALLOCSET_DEFAULT_INITSIZE,
893 ALLOCSET_DEFAULT_MAXSIZE);
894 s->curTransactionContext = CurTransactionContext;
896 /* Make the CurTransactionContext active. */
897 MemoryContextSwitchTo(CurTransactionContext);
901 * AtSubStart_ResourceOwner
904 AtSubStart_ResourceOwner(void)
906 TransactionState s = CurrentTransactionState;
908 Assert(s->parent != NULL);
911 * Create a resource owner for the subtransaction. We make it a child of
912 * the immediate parent's resource owner.
914 s->curTransactionOwner =
915 ResourceOwnerCreate(s->parent->curTransactionOwner,
918 CurTransactionResourceOwner = s->curTransactionOwner;
919 CurrentResourceOwner = s->curTransactionOwner;
922 /* ----------------------------------------------------------------
923 * CommitTransaction stuff
924 * ----------------------------------------------------------------
928 * RecordTransactionCommit
930 * Returns latest XID among xact and its children, or InvalidTransactionId
931 * if the xact has no XID. (We compute that here just because it's easier.)
934 RecordTransactionCommit(void)
936 TransactionId xid = GetTopTransactionIdIfAny();
937 bool markXidCommitted = TransactionIdIsValid(xid);
938 TransactionId latestXid = InvalidTransactionId;
942 TransactionId *children;
944 SharedInvalidationMessage *invalMessages = NULL;
945 bool RelcacheInitFileInval = false;
948 /* Get data needed for commit record */
949 nrels = smgrGetPendingDeletes(true, &rels);
950 nchildren = xactGetCommittedChildren(&children);
951 if (XLogStandbyInfoActive())
952 nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
953 &RelcacheInitFileInval);
954 wrote_xlog = (XactLastRecEnd.xrecoff != 0);
957 * If we haven't been assigned an XID yet, we neither can, nor do we want
958 * to write a COMMIT record.
960 if (!markXidCommitted)
963 * We expect that every smgrscheduleunlink is followed by a catalog
964 * update, and hence XID assignment, so we shouldn't get here with any
965 * pending deletes. Use a real test not just an Assert to check this,
966 * since it's a bit fragile.
969 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
971 /* Can't have child XIDs either; AssignTransactionId enforces this */
972 Assert(nchildren == 0);
975 * If we didn't create XLOG entries, we're done here; otherwise we
976 * should flush those entries the same as a commit record. (An
977 * example of a possible record that wouldn't cause an XID to be
978 * assigned is a sequence advance record due to nextval() --- we want
979 * to flush that to disk before reporting commit.)
987 * Begin commit critical section and insert the commit XLOG record.
989 /* Tell bufmgr and smgr to prepare for commit */
993 * Mark ourselves as within our "commit critical section". This
994 * forces any concurrent checkpoint to wait until we've updated
995 * pg_clog. Without this, it is possible for the checkpoint to set
996 * REDO after the XLOG record but fail to flush the pg_clog update to
997 * disk, leading to loss of the transaction commit if the system
998 * crashes a little later.
1000 * Note: we could, but don't bother to, set this flag in
1001 * RecordTransactionAbort. That's because loss of a transaction abort
1002 * is noncritical; the presumption would be that it aborted, anyway.
1004 * It's safe to change the inCommit flag of our own backend without
1005 * holding the ProcArrayLock, since we're the only one modifying it.
1006 * This makes checkpoint's determination of which xacts are inCommit a
1007 * bit fuzzy, but it doesn't matter.
1009 START_CRIT_SECTION();
1010 MyPgXact->inCommit = true;
1012 SetCurrentTransactionStopTimestamp();
1015 * Do we need the long commit record? If not, use the compact format.
1017 if (nrels > 0 || nmsgs > 0 || RelcacheInitFileInval || forceSyncCommit)
1019 XLogRecData rdata[4];
1021 xl_xact_commit xlrec;
1023 * Set flags required for recovery processing of commits.
1026 if (RelcacheInitFileInval)
1027 xlrec.xinfo |= XACT_COMPLETION_UPDATE_RELCACHE_FILE;
1028 if (forceSyncCommit)
1029 xlrec.xinfo |= XACT_COMPLETION_FORCE_SYNC_COMMIT;
1031 xlrec.dbId = MyDatabaseId;
1032 xlrec.tsId = MyDatabaseTableSpace;
1034 xlrec.xact_time = xactStopTimestamp;
1035 xlrec.nrels = nrels;
1036 xlrec.nsubxacts = nchildren;
1037 xlrec.nmsgs = nmsgs;
1038 rdata[0].data = (char *) (&xlrec);
1039 rdata[0].len = MinSizeOfXactCommit;
1040 rdata[0].buffer = InvalidBuffer;
1041 /* dump rels to delete */
1044 rdata[0].next = &(rdata[1]);
1045 rdata[1].data = (char *) rels;
1046 rdata[1].len = nrels * sizeof(RelFileNode);
1047 rdata[1].buffer = InvalidBuffer;
1050 /* dump committed child Xids */
1053 rdata[lastrdata].next = &(rdata[2]);
1054 rdata[2].data = (char *) children;
1055 rdata[2].len = nchildren * sizeof(TransactionId);
1056 rdata[2].buffer = InvalidBuffer;
1059 /* dump shared cache invalidation messages */
1062 rdata[lastrdata].next = &(rdata[3]);
1063 rdata[3].data = (char *) invalMessages;
1064 rdata[3].len = nmsgs * sizeof(SharedInvalidationMessage);
1065 rdata[3].buffer = InvalidBuffer;
1068 rdata[lastrdata].next = NULL;
1070 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
1074 XLogRecData rdata[2];
1076 xl_xact_commit_compact xlrec;
1077 xlrec.xact_time = xactStopTimestamp;
1078 xlrec.nsubxacts = nchildren;
1079 rdata[0].data = (char *) (&xlrec);
1080 rdata[0].len = MinSizeOfXactCommitCompact;
1081 rdata[0].buffer = InvalidBuffer;
1082 /* dump committed child Xids */
1085 rdata[0].next = &(rdata[1]);
1086 rdata[1].data = (char *) children;
1087 rdata[1].len = nchildren * sizeof(TransactionId);
1088 rdata[1].buffer = InvalidBuffer;
1091 rdata[lastrdata].next = NULL;
1093 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT_COMPACT, rdata);
1098 * Check if we want to commit asynchronously. We can allow the XLOG flush
1099 * to happen asynchronously if synchronous_commit=off, or if the current
1100 * transaction has not performed any WAL-logged operation. The latter
1101 * case can arise if the current transaction wrote only to temporary
1102 * and/or unlogged tables. In case of a crash, the loss of such a
1103 * transaction will be irrelevant since temp tables will be lost anyway,
1104 * and unlogged tables will be truncated. (Given the foregoing, you might
1105 * think that it would be unnecessary to emit the XLOG record at all in
1106 * this case, but we don't currently try to do that. It would certainly
1107 * cause problems at least in Hot Standby mode, where the
1108 * KnownAssignedXids machinery requires tracking every XID assignment. It
1109 * might be OK to skip it only when wal_level < hot_standby, but for now
1112 * However, if we're doing cleanup of any non-temp rels or committing any
1113 * command that wanted to force sync commit, then we must flush XLOG
1114 * immediately. (We must not allow asynchronous commit if there are any
1115 * non-temp tables to be deleted, because we might delete the files before
1116 * the COMMIT record is flushed to disk. We do allow asynchronous commit
1117 * if all to-be-deleted tables are temporary though, since they are lost
1118 * anyway if we crash.)
1120 if ((wrote_xlog && synchronous_commit > SYNCHRONOUS_COMMIT_OFF) ||
1121 forceSyncCommit || nrels > 0)
1124 * Synchronous commit case:
1126 * Sleep before flush! So we can flush more than one commit records
1127 * per single fsync. (The idea is some other backend may do the
1128 * XLogFlush while we're sleeping. This needs work still, because on
1129 * most Unixen, the minimum select() delay is 10msec or more, which is
1132 * We do not sleep if enableFsync is not turned on, nor if there are
1133 * fewer than CommitSiblings other backends with active transactions.
1135 if (CommitDelay > 0 && enableFsync &&
1136 MinimumActiveBackends(CommitSiblings))
1137 pg_usleep(CommitDelay);
1139 XLogFlush(XactLastRecEnd);
1142 * Wake up all walsenders to send WAL up to the COMMIT record
1143 * immediately if replication is enabled
1145 if (max_wal_senders > 0)
1149 * Now we may update the CLOG, if we wrote a COMMIT record above
1151 if (markXidCommitted)
1152 TransactionIdCommitTree(xid, nchildren, children);
1157 * Asynchronous commit case:
1159 * This enables possible committed transaction loss in the case of a
1160 * postmaster crash because WAL buffers are left unwritten. Ideally we
1161 * could issue the WAL write without the fsync, but some
1162 * wal_sync_methods do not allow separate write/fsync.
1164 * Report the latest async commit LSN, so that the WAL writer knows to
1165 * flush this commit.
1167 XLogSetAsyncXactLSN(XactLastRecEnd);
1170 * We must not immediately update the CLOG, since we didn't flush the
1171 * XLOG. Instead, we store the LSN up to which the XLOG must be
1172 * flushed before the CLOG may be updated.
1174 if (markXidCommitted)
1175 TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1179 * If we entered a commit critical section, leave it now, and let
1180 * checkpoints proceed.
1182 if (markXidCommitted)
1184 MyPgXact->inCommit = false;
1188 /* Compute latestXid while we have the child XIDs handy */
1189 latestXid = TransactionIdLatest(xid, nchildren, children);
1192 * Wait for synchronous replication, if required.
1194 * Note that at this stage we have marked clog, but still show as running
1195 * in the procarray and continue to hold locks.
1198 SyncRepWaitForLSN(XactLastRecEnd);
1200 /* Reset XactLastRecEnd until the next transaction writes something */
1201 XactLastRecEnd.xrecoff = 0;
1204 /* Clean up local data */
1216 AtCCI_LocalCache(void)
1219 * Make any pending relation map changes visible. We must do this before
1220 * processing local sinval messages, so that the map changes will get
1221 * reflected into the relcache when relcache invals are processed.
1223 AtCCI_RelationMap();
1226 * Make catalog changes visible to me for the next command.
1228 CommandEndInvalidationMessages();
1235 AtCommit_Memory(void)
1238 * Now that we're "out" of a transaction, have the system allocate things
1239 * in the top memory context instead of per-transaction contexts.
1241 MemoryContextSwitchTo(TopMemoryContext);
1244 * Release all transaction-local memory.
1246 Assert(TopTransactionContext != NULL);
1247 MemoryContextDelete(TopTransactionContext);
1248 TopTransactionContext = NULL;
1249 CurTransactionContext = NULL;
1250 CurrentTransactionState->curTransactionContext = NULL;
1253 /* ----------------------------------------------------------------
1254 * CommitSubTransaction stuff
1255 * ----------------------------------------------------------------
1259 * AtSubCommit_Memory
1262 AtSubCommit_Memory(void)
1264 TransactionState s = CurrentTransactionState;
1266 Assert(s->parent != NULL);
1268 /* Return to parent transaction level's memory context. */
1269 CurTransactionContext = s->parent->curTransactionContext;
1270 MemoryContextSwitchTo(CurTransactionContext);
1273 * Ordinarily we cannot throw away the child's CurTransactionContext,
1274 * since the data it contains will be needed at upper commit. However, if
1275 * there isn't actually anything in it, we can throw it away. This avoids
1276 * a small memory leak in the common case of "trivial" subxacts.
1278 if (MemoryContextIsEmpty(s->curTransactionContext))
1280 MemoryContextDelete(s->curTransactionContext);
1281 s->curTransactionContext = NULL;
1286 * AtSubCommit_childXids
1288 * Pass my own XID and my child XIDs up to my parent as committed children.
1291 AtSubCommit_childXids(void)
1293 TransactionState s = CurrentTransactionState;
1296 Assert(s->parent != NULL);
1299 * The parent childXids array will need to hold my XID and all my
1300 * childXids, in addition to the XIDs already there.
1302 new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1304 /* Allocate or enlarge the parent array if necessary */
1305 if (s->parent->maxChildXids < new_nChildXids)
1307 int new_maxChildXids;
1308 TransactionId *new_childXids;
1311 * Make it 2x what's needed right now, to avoid having to enlarge it
1312 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1313 * is what ensures that we don't need to worry about integer overflow
1314 * here or in the calculation of new_nChildXids.)
1316 new_maxChildXids = Min(new_nChildXids * 2,
1317 (int) (MaxAllocSize / sizeof(TransactionId)));
1319 if (new_maxChildXids < new_nChildXids)
1321 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1322 errmsg("maximum number of committed subtransactions (%d) exceeded",
1323 (int) (MaxAllocSize / sizeof(TransactionId)))));
1326 * We keep the child-XID arrays in TopTransactionContext; this avoids
1327 * setting up child-transaction contexts for what might be just a few
1328 * bytes of grandchild XIDs.
1330 if (s->parent->childXids == NULL)
1332 MemoryContextAlloc(TopTransactionContext,
1333 new_maxChildXids * sizeof(TransactionId));
1335 new_childXids = repalloc(s->parent->childXids,
1336 new_maxChildXids * sizeof(TransactionId));
1338 s->parent->childXids = new_childXids;
1339 s->parent->maxChildXids = new_maxChildXids;
1343 * Copy all my XIDs to parent's array.
1345 * Note: We rely on the fact that the XID of a child always follows that
1346 * of its parent. By copying the XID of this subtransaction before the
1347 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1348 * all XIDs already in the array belong to subtransactions started and
1349 * subcommitted before us, so their XIDs must precede ours.
1351 s->parent->childXids[s->parent->nChildXids] = s->transactionId;
1353 if (s->nChildXids > 0)
1354 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1356 s->nChildXids * sizeof(TransactionId));
1358 s->parent->nChildXids = new_nChildXids;
1360 /* Release child's array to avoid leakage */
1361 if (s->childXids != NULL)
1362 pfree(s->childXids);
1363 /* We must reset these to avoid double-free if fail later in commit */
1364 s->childXids = NULL;
1366 s->maxChildXids = 0;
1369 /* ----------------------------------------------------------------
1370 * AbortTransaction stuff
1371 * ----------------------------------------------------------------
1375 * RecordTransactionAbort
1377 * Returns latest XID among xact and its children, or InvalidTransactionId
1378 * if the xact has no XID. (We compute that here just because it's easier.)
1380 static TransactionId
1381 RecordTransactionAbort(bool isSubXact)
1383 TransactionId xid = GetCurrentTransactionIdIfAny();
1384 TransactionId latestXid;
1388 TransactionId *children;
1389 XLogRecData rdata[3];
1391 xl_xact_abort xlrec;
1394 * If we haven't been assigned an XID, nobody will care whether we aborted
1395 * or not. Hence, we're done in that case. It does not matter if we have
1396 * rels to delete (note that this routine is not responsible for actually
1397 * deleting 'em). We cannot have any child XIDs, either.
1399 if (!TransactionIdIsValid(xid))
1401 /* Reset XactLastRecEnd until the next transaction writes something */
1403 XactLastRecEnd.xrecoff = 0;
1404 return InvalidTransactionId;
1408 * We have a valid XID, so we should write an ABORT record for it.
1410 * We do not flush XLOG to disk here, since the default assumption after a
1411 * crash would be that we aborted, anyway. For the same reason, we don't
1412 * need to worry about interlocking against checkpoint start.
1416 * Check that we haven't aborted halfway through RecordTransactionCommit.
1418 if (TransactionIdDidCommit(xid))
1419 elog(PANIC, "cannot abort transaction %u, it was already committed",
1422 /* Fetch the data we need for the abort record */
1423 nrels = smgrGetPendingDeletes(false, &rels);
1424 nchildren = xactGetCommittedChildren(&children);
1426 /* XXX do we really need a critical section here? */
1427 START_CRIT_SECTION();
1429 /* Write the ABORT record */
1431 xlrec.xact_time = GetCurrentTimestamp();
1434 SetCurrentTransactionStopTimestamp();
1435 xlrec.xact_time = xactStopTimestamp;
1437 xlrec.nrels = nrels;
1438 xlrec.nsubxacts = nchildren;
1439 rdata[0].data = (char *) (&xlrec);
1440 rdata[0].len = MinSizeOfXactAbort;
1441 rdata[0].buffer = InvalidBuffer;
1442 /* dump rels to delete */
1445 rdata[0].next = &(rdata[1]);
1446 rdata[1].data = (char *) rels;
1447 rdata[1].len = nrels * sizeof(RelFileNode);
1448 rdata[1].buffer = InvalidBuffer;
1451 /* dump committed child Xids */
1454 rdata[lastrdata].next = &(rdata[2]);
1455 rdata[2].data = (char *) children;
1456 rdata[2].len = nchildren * sizeof(TransactionId);
1457 rdata[2].buffer = InvalidBuffer;
1460 rdata[lastrdata].next = NULL;
1462 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
1465 * Report the latest async abort LSN, so that the WAL writer knows to
1466 * flush this abort. There's nothing to be gained by delaying this, since
1467 * WALWriter may as well do this when it can. This is important with
1468 * streaming replication because if we don't flush WAL regularly we will
1469 * find that large aborts leave us with a long backlog for when commits
1470 * occur after the abort, increasing our window of data loss should
1471 * problems occur at that point.
1474 XLogSetAsyncXactLSN(XactLastRecEnd);
1477 * Mark the transaction aborted in clog. This is not absolutely necessary
1478 * but we may as well do it while we are here; also, in the subxact case
1479 * it is helpful because XactLockTableWait makes use of it to avoid
1480 * waiting for already-aborted subtransactions. It is OK to do it without
1481 * having flushed the ABORT record to disk, because in event of a crash
1482 * we'd be assumed to have aborted anyway.
1484 TransactionIdAbortTree(xid, nchildren, children);
1488 /* Compute latestXid while we have the child XIDs handy */
1489 latestXid = TransactionIdLatest(xid, nchildren, children);
1492 * If we're aborting a subtransaction, we can immediately remove failed
1493 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1494 * subxacts, because we already have the child XID array at hand. For
1495 * main xacts, the equivalent happens just after this function returns.
1498 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1500 /* Reset XactLastRecEnd until the next transaction writes something */
1502 XactLastRecEnd.xrecoff = 0;
1504 /* And clean up local data */
1515 AtAbort_Memory(void)
1518 * Switch into TransactionAbortContext, which should have some free space
1519 * even if nothing else does. We'll work in this context until we've
1520 * finished cleaning up.
1522 * It is barely possible to get here when we've not been able to create
1523 * TransactionAbortContext yet; if so use TopMemoryContext.
1525 if (TransactionAbortContext != NULL)
1526 MemoryContextSwitchTo(TransactionAbortContext);
1528 MemoryContextSwitchTo(TopMemoryContext);
1535 AtSubAbort_Memory(void)
1537 Assert(TransactionAbortContext != NULL);
1539 MemoryContextSwitchTo(TransactionAbortContext);
1544 * AtAbort_ResourceOwner
1547 AtAbort_ResourceOwner(void)
1550 * Make sure we have a valid ResourceOwner, if possible (else it will be
1551 * NULL, which is OK)
1553 CurrentResourceOwner = TopTransactionResourceOwner;
1557 * AtSubAbort_ResourceOwner
1560 AtSubAbort_ResourceOwner(void)
1562 TransactionState s = CurrentTransactionState;
1564 /* Make sure we have a valid ResourceOwner */
1565 CurrentResourceOwner = s->curTransactionOwner;
1570 * AtSubAbort_childXids
1573 AtSubAbort_childXids(void)
1575 TransactionState s = CurrentTransactionState;
1578 * We keep the child-XID arrays in TopTransactionContext (see
1579 * AtSubCommit_childXids). This means we'd better free the array
1580 * explicitly at abort to avoid leakage.
1582 if (s->childXids != NULL)
1583 pfree(s->childXids);
1584 s->childXids = NULL;
1586 s->maxChildXids = 0;
1589 * We could prune the unreportedXids array here. But we don't bother. That
1590 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1591 * would likely introduce more CPU time into the more common paths, so we
1592 * choose not to do that.
1596 /* ----------------------------------------------------------------
1597 * CleanupTransaction stuff
1598 * ----------------------------------------------------------------
1605 AtCleanup_Memory(void)
1607 Assert(CurrentTransactionState->parent == NULL);
1610 * Now that we're "out" of a transaction, have the system allocate things
1611 * in the top memory context instead of per-transaction contexts.
1613 MemoryContextSwitchTo(TopMemoryContext);
1616 * Clear the special abort context for next time.
1618 if (TransactionAbortContext != NULL)
1619 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1622 * Release all transaction-local memory.
1624 if (TopTransactionContext != NULL)
1625 MemoryContextDelete(TopTransactionContext);
1626 TopTransactionContext = NULL;
1627 CurTransactionContext = NULL;
1628 CurrentTransactionState->curTransactionContext = NULL;
1632 /* ----------------------------------------------------------------
1633 * CleanupSubTransaction stuff
1634 * ----------------------------------------------------------------
1638 * AtSubCleanup_Memory
1641 AtSubCleanup_Memory(void)
1643 TransactionState s = CurrentTransactionState;
1645 Assert(s->parent != NULL);
1647 /* Make sure we're not in an about-to-be-deleted context */
1648 MemoryContextSwitchTo(s->parent->curTransactionContext);
1649 CurTransactionContext = s->parent->curTransactionContext;
1652 * Clear the special abort context for next time.
1654 if (TransactionAbortContext != NULL)
1655 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1658 * Delete the subxact local memory contexts. Its CurTransactionContext can
1659 * go too (note this also kills CurTransactionContexts from any children
1662 if (s->curTransactionContext)
1663 MemoryContextDelete(s->curTransactionContext);
1664 s->curTransactionContext = NULL;
1667 /* ----------------------------------------------------------------
1668 * interface routines
1669 * ----------------------------------------------------------------
1676 StartTransaction(void)
1679 VirtualTransactionId vxid;
1682 * Let's just make sure the state stack is empty
1684 s = &TopTransactionStateData;
1685 CurrentTransactionState = s;
1688 * check the current transaction state
1690 if (s->state != TRANS_DEFAULT)
1691 elog(WARNING, "StartTransaction while in %s state",
1692 TransStateAsString(s->state));
1695 * set the current transaction state information appropriately during
1698 s->state = TRANS_START;
1699 s->transactionId = InvalidTransactionId; /* until assigned */
1702 * Make sure we've reset xact state variables
1704 * If recovery is still in progress, mark this transaction as read-only.
1705 * We have lower level defences in XLogInsert and elsewhere to stop us
1706 * from modifying data during recovery, but this gives the normal
1707 * indication to the user that the transaction is read-only.
1709 if (RecoveryInProgress())
1711 s->startedInRecovery = true;
1712 XactReadOnly = true;
1716 s->startedInRecovery = false;
1717 XactReadOnly = DefaultXactReadOnly;
1719 XactDeferrable = DefaultXactDeferrable;
1720 XactIsoLevel = DefaultXactIsoLevel;
1721 forceSyncCommit = false;
1722 MyXactAccessedTempRel = false;
1725 * reinitialize within-transaction counters
1727 s->subTransactionId = TopSubTransactionId;
1728 currentSubTransactionId = TopSubTransactionId;
1729 currentCommandId = FirstCommandId;
1730 currentCommandIdUsed = false;
1733 * initialize reported xid accounting
1735 nUnreportedXids = 0;
1738 * must initialize resource-management stuff first
1741 AtStart_ResourceOwner();
1744 * Assign a new LocalTransactionId, and combine it with the backendId to
1745 * form a virtual transaction id.
1747 vxid.backendId = MyBackendId;
1748 vxid.localTransactionId = GetNextLocalTransactionId();
1751 * Lock the virtual transaction id before we announce it in the proc array
1753 VirtualXactLockTableInsert(vxid);
1756 * Advertise it in the proc array. We assume assignment of
1757 * LocalTransactionID is atomic, and the backendId should be set already.
1759 Assert(MyProc->backendId == vxid.backendId);
1760 MyProc->lxid = vxid.localTransactionId;
1762 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
1765 * set transaction_timestamp() (a/k/a now()). We want this to be the same
1766 * as the first command's statement_timestamp(), so don't do a fresh
1767 * GetCurrentTimestamp() call (which'd be expensive anyway). Also, mark
1768 * xactStopTimestamp as unset.
1770 xactStartTimestamp = stmtStartTimestamp;
1771 xactStopTimestamp = 0;
1772 pgstat_report_xact_timestamp(xactStartTimestamp);
1775 * initialize current transaction state fields
1777 * note: prevXactReadOnly is not used at the outermost level
1779 s->nestingLevel = 1;
1780 s->gucNestLevel = 1;
1781 s->childXids = NULL;
1783 s->maxChildXids = 0;
1784 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
1785 /* SecurityRestrictionContext should never be set outside a transaction */
1786 Assert(s->prevSecContext == 0);
1789 * initialize other subsystems for new transaction
1794 AfterTriggerBeginXact();
1797 * done with start processing, set current transaction state to "in
1800 s->state = TRANS_INPROGRESS;
1802 ShowTransactionState("StartTransaction");
1809 * NB: if you change this routine, better look at PrepareTransaction too!
1812 CommitTransaction(void)
1814 TransactionState s = CurrentTransactionState;
1815 TransactionId latestXid;
1817 ShowTransactionState("CommitTransaction");
1820 * check the current transaction state
1822 if (s->state != TRANS_INPROGRESS)
1823 elog(WARNING, "CommitTransaction while in %s state",
1824 TransStateAsString(s->state));
1825 Assert(s->parent == NULL);
1828 * Do pre-commit processing that involves calling user-defined code, such
1829 * as triggers. Since closing cursors could queue trigger actions,
1830 * triggers could open cursors, etc, we have to keep looping until there's
1831 * nothing left to do.
1836 * Fire all currently pending deferred triggers.
1838 AfterTriggerFireDeferred();
1841 * Close open portals (converting holdable ones into static portals).
1842 * If there weren't any, we are done ... otherwise loop back to check
1843 * if they queued deferred triggers. Lather, rinse, repeat.
1845 if (!PreCommit_Portals(false))
1850 * The remaining actions cannot call any user-defined code, so it's safe
1851 * to start shutting down within-transaction services. But note that most
1852 * of this stuff could still throw an error, which would switch us into
1853 * the transaction-abort path.
1856 /* Shut down the deferred-trigger manager */
1857 AfterTriggerEndXact(true);
1860 * Let ON COMMIT management do its thing (must happen after closing
1861 * cursors, to avoid dangling-reference problems)
1863 PreCommit_on_commit_actions();
1865 /* close large objects before lower-level cleanup */
1866 AtEOXact_LargeObject(true);
1869 * Mark serializable transaction as complete for predicate locking
1870 * purposes. This should be done as late as we can put it and still allow
1871 * errors to be raised for failure patterns found at commit.
1873 PreCommit_CheckForSerializationFailure();
1876 * Insert notifications sent by NOTIFY commands into the queue. This
1877 * should be late in the pre-commit sequence to minimize time spent
1878 * holding the notify-insertion lock.
1882 /* Prevent cancel/die interrupt while cleaning up */
1885 /* Commit updates to the relation map --- do this as late as possible */
1886 AtEOXact_RelationMap(true);
1889 * set the current transaction state information appropriately during
1892 s->state = TRANS_COMMIT;
1895 * Here is where we really truly commit.
1897 latestXid = RecordTransactionCommit();
1899 TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
1902 * Let others know about no transaction in progress by me. Note that this
1903 * must be done _before_ releasing locks we hold and _after_
1904 * RecordTransactionCommit.
1906 ProcArrayEndTransaction(MyProc, latestXid);
1909 * This is all post-commit cleanup. Note that if an error is raised here,
1910 * it's too late to abort the transaction. This should be just
1911 * noncritical resource releasing.
1913 * The ordering of operations is not entirely random. The idea is:
1914 * release resources visible to other backends (eg, files, buffer pins);
1915 * then release locks; then release backend-local resources. We want to
1916 * release locks at the point where any backend waiting for us will see
1917 * our transaction as being fully cleaned up.
1919 * Resources that can be associated with individual queries are handled by
1920 * the ResourceOwner mechanism. The other calls here are for backend-wide
1924 CallXactCallbacks(XACT_EVENT_COMMIT);
1926 ResourceOwnerRelease(TopTransactionResourceOwner,
1927 RESOURCE_RELEASE_BEFORE_LOCKS,
1930 /* Check we've released all buffer pins */
1931 AtEOXact_Buffers(true);
1933 /* Clean up the relation cache */
1934 AtEOXact_RelationCache(true);
1937 * Make catalog changes visible to all backends. This has to happen after
1938 * relcache references are dropped (see comments for
1939 * AtEOXact_RelationCache), but before locks are released (if anyone is
1940 * waiting for lock on a relation we've modified, we want them to know
1941 * about the catalog change before they start using the relation).
1943 AtEOXact_Inval(true);
1946 * Likewise, dropping of files deleted during the transaction is best done
1947 * after releasing relcache and buffer pins. (This is not strictly
1948 * necessary during commit, since such pins should have been released
1949 * already, but this ordering is definitely critical during abort.)
1951 smgrDoPendingDeletes(true);
1953 AtEOXact_MultiXact();
1955 ResourceOwnerRelease(TopTransactionResourceOwner,
1956 RESOURCE_RELEASE_LOCKS,
1958 ResourceOwnerRelease(TopTransactionResourceOwner,
1959 RESOURCE_RELEASE_AFTER_LOCKS,
1962 /* Check we've released all catcache entries */
1963 AtEOXact_CatCache(true);
1966 AtEOXact_GUC(true, 1);
1968 AtEOXact_on_commit_actions(true);
1969 AtEOXact_Namespace(true);
1970 /* smgrcommit already done */
1972 AtEOXact_ComboCid();
1973 AtEOXact_HashTables(true);
1974 AtEOXact_PgStat(true);
1975 AtEOXact_Snapshot(true);
1976 pgstat_report_xact_timestamp(0);
1978 CurrentResourceOwner = NULL;
1979 ResourceOwnerDelete(TopTransactionResourceOwner);
1980 s->curTransactionOwner = NULL;
1981 CurTransactionResourceOwner = NULL;
1982 TopTransactionResourceOwner = NULL;
1986 s->transactionId = InvalidTransactionId;
1987 s->subTransactionId = InvalidSubTransactionId;
1988 s->nestingLevel = 0;
1989 s->gucNestLevel = 0;
1990 s->childXids = NULL;
1992 s->maxChildXids = 0;
1995 * done with commit processing, set current transaction state back to
1998 s->state = TRANS_DEFAULT;
2000 RESUME_INTERRUPTS();
2005 * PrepareTransaction
2007 * NB: if you change this routine, better look at CommitTransaction too!
2010 PrepareTransaction(void)
2012 TransactionState s = CurrentTransactionState;
2013 TransactionId xid = GetCurrentTransactionId();
2014 GlobalTransaction gxact;
2015 TimestampTz prepared_at;
2017 ShowTransactionState("PrepareTransaction");
2020 * check the current transaction state
2022 if (s->state != TRANS_INPROGRESS)
2023 elog(WARNING, "PrepareTransaction while in %s state",
2024 TransStateAsString(s->state));
2025 Assert(s->parent == NULL);
2028 * Do pre-commit processing that involves calling user-defined code, such
2029 * as triggers. Since closing cursors could queue trigger actions,
2030 * triggers could open cursors, etc, we have to keep looping until there's
2031 * nothing left to do.
2036 * Fire all currently pending deferred triggers.
2038 AfterTriggerFireDeferred();
2041 * Close open portals (converting holdable ones into static portals).
2042 * If there weren't any, we are done ... otherwise loop back to check
2043 * if they queued deferred triggers. Lather, rinse, repeat.
2045 if (!PreCommit_Portals(true))
2050 * The remaining actions cannot call any user-defined code, so it's safe
2051 * to start shutting down within-transaction services. But note that most
2052 * of this stuff could still throw an error, which would switch us into
2053 * the transaction-abort path.
2056 /* Shut down the deferred-trigger manager */
2057 AfterTriggerEndXact(true);
2060 * Let ON COMMIT management do its thing (must happen after closing
2061 * cursors, to avoid dangling-reference problems)
2063 PreCommit_on_commit_actions();
2065 /* close large objects before lower-level cleanup */
2066 AtEOXact_LargeObject(true);
2069 * Mark serializable transaction as complete for predicate locking
2070 * purposes. This should be done as late as we can put it and still allow
2071 * errors to be raised for failure patterns found at commit.
2073 PreCommit_CheckForSerializationFailure();
2075 /* NOTIFY will be handled below */
2078 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2079 * this transaction. Having the prepared xact hold locks on another
2080 * backend's temp table seems a bad idea --- for instance it would prevent
2081 * the backend from exiting. There are other problems too, such as how to
2082 * clean up the source backend's local buffers and ON COMMIT state if the
2083 * prepared xact includes a DROP of a temp table.
2085 * We must check this after executing any ON COMMIT actions, because they
2086 * might still access a temp relation.
2088 * XXX In principle this could be relaxed to allow some useful special
2089 * cases, such as a temp table created and dropped all within the
2090 * transaction. That seems to require much more bookkeeping though.
2092 if (MyXactAccessedTempRel)
2094 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2095 errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
2098 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2099 * supported if we added cleanup logic to twophase.c, but for now it
2100 * doesn't seem worth the trouble.
2102 if (XactHasExportedSnapshots())
2104 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2105 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2107 /* Prevent cancel/die interrupt while cleaning up */
2111 * set the current transaction state information appropriately during
2112 * prepare processing
2114 s->state = TRANS_PREPARE;
2116 prepared_at = GetCurrentTimestamp();
2118 /* Tell bufmgr and smgr to prepare for commit */
2122 * Reserve the GID for this transaction. This could fail if the requested
2123 * GID is invalid or already in use.
2125 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
2126 GetUserId(), MyDatabaseId);
2130 * Collect data for the 2PC state file. Note that in general, no actual
2131 * state change should happen in the called modules during this step,
2132 * since it's still possible to fail before commit, and in that case we
2133 * want transaction abort to be able to clean up. (In particular, the
2134 * AtPrepare routines may error out if they find cases they cannot
2135 * handle.) State cleanup should happen in the PostPrepare routines
2136 * below. However, some modules can go ahead and clear state here because
2137 * they wouldn't do anything with it during abort anyway.
2139 * Note: because the 2PC state file records will be replayed in the same
2140 * order they are made, the order of these calls has to match the order in
2141 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2142 * PREPARED; in particular, pay attention to whether things should happen
2143 * before or after releasing the transaction's locks.
2145 StartPrepare(gxact);
2149 AtPrepare_PredicateLocks();
2151 AtPrepare_MultiXact();
2152 AtPrepare_RelationMap();
2155 * Here is where we really truly prepare.
2157 * We have to record transaction prepares even if we didn't make any
2158 * updates, because the transaction manager might get confused if we lose
2159 * a global transaction.
2164 * Now we clean up backend-internal state and release internal resources.
2167 /* Reset XactLastRecEnd until the next transaction writes something */
2168 XactLastRecEnd.xrecoff = 0;
2171 * Let others know about no transaction in progress by me. This has to be
2172 * done *after* the prepared transaction has been marked valid, else
2173 * someone may think it is unlocked and recyclable.
2175 ProcArrayClearTransaction(MyProc);
2178 * This is all post-transaction cleanup. Note that if an error is raised
2179 * here, it's too late to abort the transaction. This should be just
2180 * noncritical resource releasing. See notes in CommitTransaction.
2183 CallXactCallbacks(XACT_EVENT_PREPARE);
2185 ResourceOwnerRelease(TopTransactionResourceOwner,
2186 RESOURCE_RELEASE_BEFORE_LOCKS,
2189 /* Check we've released all buffer pins */
2190 AtEOXact_Buffers(true);
2192 /* Clean up the relation cache */
2193 AtEOXact_RelationCache(true);
2195 /* notify doesn't need a postprepare call */
2197 PostPrepare_PgStat();
2199 PostPrepare_Inval();
2203 PostPrepare_MultiXact(xid);
2205 PostPrepare_Locks(xid);
2206 PostPrepare_PredicateLocks(xid);
2208 ResourceOwnerRelease(TopTransactionResourceOwner,
2209 RESOURCE_RELEASE_LOCKS,
2211 ResourceOwnerRelease(TopTransactionResourceOwner,
2212 RESOURCE_RELEASE_AFTER_LOCKS,
2215 /* Check we've released all catcache entries */
2216 AtEOXact_CatCache(true);
2218 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2219 AtEOXact_GUC(true, 1);
2221 AtEOXact_on_commit_actions(true);
2222 AtEOXact_Namespace(true);
2223 /* smgrcommit already done */
2225 AtEOXact_ComboCid();
2226 AtEOXact_HashTables(true);
2227 /* don't call AtEOXact_PgStat here */
2228 AtEOXact_Snapshot(true);
2230 CurrentResourceOwner = NULL;
2231 ResourceOwnerDelete(TopTransactionResourceOwner);
2232 s->curTransactionOwner = NULL;
2233 CurTransactionResourceOwner = NULL;
2234 TopTransactionResourceOwner = NULL;
2238 s->transactionId = InvalidTransactionId;
2239 s->subTransactionId = InvalidSubTransactionId;
2240 s->nestingLevel = 0;
2241 s->gucNestLevel = 0;
2242 s->childXids = NULL;
2244 s->maxChildXids = 0;
2247 * done with 1st phase commit processing, set current transaction state
2250 s->state = TRANS_DEFAULT;
2252 RESUME_INTERRUPTS();
2260 AbortTransaction(void)
2262 TransactionState s = CurrentTransactionState;
2263 TransactionId latestXid;
2265 /* Prevent cancel/die interrupt while cleaning up */
2268 /* Make sure we have a valid memory context and resource owner */
2270 AtAbort_ResourceOwner();
2273 * Release any LW locks we might be holding as quickly as possible.
2274 * (Regular locks, however, must be held till we finish aborting.)
2275 * Releasing LW locks is critical since we might try to grab them again
2276 * while cleaning up!
2280 /* Clean up buffer I/O and buffer context locks, too */
2285 * Also clean up any open wait for lock, since the lock manager will choke
2286 * if we try to wait for another lock before doing this.
2291 * check the current transaction state
2293 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2294 elog(WARNING, "AbortTransaction while in %s state",
2295 TransStateAsString(s->state));
2296 Assert(s->parent == NULL);
2299 * set the current transaction state information appropriately during the
2302 s->state = TRANS_ABORT;
2305 * Reset user ID which might have been changed transiently. We need this
2306 * to clean up in case control escaped out of a SECURITY DEFINER function
2307 * or other local change of CurrentUserId; therefore, the prior value of
2308 * SecurityRestrictionContext also needs to be restored.
2310 * (Note: it is not necessary to restore session authorization or role
2311 * settings here because those can only be changed via GUC, and GUC will
2312 * take care of rolling them back if need be.)
2314 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
2317 * do abort processing
2319 AfterTriggerEndXact(false); /* 'false' means it's abort */
2321 AtEOXact_LargeObject(false);
2323 AtEOXact_RelationMap(false);
2326 * Advertise the fact that we aborted in pg_clog (assuming that we got as
2327 * far as assigning an XID to advertise).
2329 latestXid = RecordTransactionAbort(false);
2331 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
2334 * Let others know about no transaction in progress by me. Note that this
2335 * must be done _before_ releasing locks we hold and _after_
2336 * RecordTransactionAbort.
2338 ProcArrayEndTransaction(MyProc, latestXid);
2341 * Post-abort cleanup. See notes in CommitTransaction() concerning
2342 * ordering. We can skip all of it if the transaction failed before
2343 * creating a resource owner.
2345 if (TopTransactionResourceOwner != NULL)
2347 CallXactCallbacks(XACT_EVENT_ABORT);
2349 ResourceOwnerRelease(TopTransactionResourceOwner,
2350 RESOURCE_RELEASE_BEFORE_LOCKS,
2352 AtEOXact_Buffers(false);
2353 AtEOXact_RelationCache(false);
2354 AtEOXact_Inval(false);
2355 smgrDoPendingDeletes(false);
2356 AtEOXact_MultiXact();
2357 ResourceOwnerRelease(TopTransactionResourceOwner,
2358 RESOURCE_RELEASE_LOCKS,
2360 ResourceOwnerRelease(TopTransactionResourceOwner,
2361 RESOURCE_RELEASE_AFTER_LOCKS,
2363 AtEOXact_CatCache(false);
2365 AtEOXact_GUC(false, 1);
2366 AtEOXact_SPI(false);
2367 AtEOXact_on_commit_actions(false);
2368 AtEOXact_Namespace(false);
2370 AtEOXact_ComboCid();
2371 AtEOXact_HashTables(false);
2372 AtEOXact_PgStat(false);
2373 pgstat_report_xact_timestamp(0);
2377 * State remains TRANS_ABORT until CleanupTransaction().
2379 RESUME_INTERRUPTS();
2383 * CleanupTransaction
2386 CleanupTransaction(void)
2388 TransactionState s = CurrentTransactionState;
2391 * State should still be TRANS_ABORT from AbortTransaction().
2393 if (s->state != TRANS_ABORT)
2394 elog(FATAL, "CleanupTransaction: unexpected state %s",
2395 TransStateAsString(s->state));
2398 * do abort cleanup processing
2400 AtCleanup_Portals(); /* now safe to release portal memory */
2401 AtEOXact_Snapshot(false); /* and release the transaction's snapshots */
2403 CurrentResourceOwner = NULL; /* and resource owner */
2404 if (TopTransactionResourceOwner)
2405 ResourceOwnerDelete(TopTransactionResourceOwner);
2406 s->curTransactionOwner = NULL;
2407 CurTransactionResourceOwner = NULL;
2408 TopTransactionResourceOwner = NULL;
2410 AtCleanup_Memory(); /* and transaction memory */
2412 s->transactionId = InvalidTransactionId;
2413 s->subTransactionId = InvalidSubTransactionId;
2414 s->nestingLevel = 0;
2415 s->gucNestLevel = 0;
2416 s->childXids = NULL;
2418 s->maxChildXids = 0;
2421 * done with abort processing, set current transaction state back to
2424 s->state = TRANS_DEFAULT;
2428 * StartTransactionCommand
2431 StartTransactionCommand(void)
2433 TransactionState s = CurrentTransactionState;
2435 switch (s->blockState)
2438 * if we aren't in a transaction block, we just do our usual start
2441 case TBLOCK_DEFAULT:
2443 s->blockState = TBLOCK_STARTED;
2447 * We are somewhere in a transaction block or subtransaction and
2448 * about to start a new command. For now we do nothing, but
2449 * someday we may do command-local resource initialization. (Note
2450 * that any needed CommandCounterIncrement was done by the
2451 * previous CommitTransactionCommand.)
2453 case TBLOCK_INPROGRESS:
2454 case TBLOCK_SUBINPROGRESS:
2458 * Here we are in a failed transaction block (one of the commands
2459 * caused an abort) so we do nothing but remain in the abort
2460 * state. Eventually we will get a ROLLBACK command which will
2461 * get us out of this state. (It is up to other code to ensure
2462 * that no commands other than ROLLBACK will be processed in these
2466 case TBLOCK_SUBABORT:
2469 /* These cases are invalid. */
2470 case TBLOCK_STARTED:
2472 case TBLOCK_SUBBEGIN:
2474 case TBLOCK_SUBRELEASE:
2475 case TBLOCK_SUBCOMMIT:
2476 case TBLOCK_ABORT_END:
2477 case TBLOCK_SUBABORT_END:
2478 case TBLOCK_ABORT_PENDING:
2479 case TBLOCK_SUBABORT_PENDING:
2480 case TBLOCK_SUBRESTART:
2481 case TBLOCK_SUBABORT_RESTART:
2482 case TBLOCK_PREPARE:
2483 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2484 BlockStateAsString(s->blockState));
2489 * We must switch to CurTransactionContext before returning. This is
2490 * already done if we called StartTransaction, otherwise not.
2492 Assert(CurTransactionContext != NULL);
2493 MemoryContextSwitchTo(CurTransactionContext);
2497 * CommitTransactionCommand
2500 CommitTransactionCommand(void)
2502 TransactionState s = CurrentTransactionState;
2504 switch (s->blockState)
2507 * This shouldn't happen, because it means the previous
2508 * StartTransactionCommand didn't set the STARTED state
2511 case TBLOCK_DEFAULT:
2512 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2513 BlockStateAsString(s->blockState));
2517 * If we aren't in a transaction block, just do our usual
2518 * transaction commit, and return to the idle state.
2520 case TBLOCK_STARTED:
2521 CommitTransaction();
2522 s->blockState = TBLOCK_DEFAULT;
2526 * We are completing a "BEGIN TRANSACTION" command, so we change
2527 * to the "transaction block in progress" state and return. (We
2528 * assume the BEGIN did nothing to the database, so we need no
2529 * CommandCounterIncrement.)
2532 s->blockState = TBLOCK_INPROGRESS;
2536 * This is the case when we have finished executing a command
2537 * someplace within a transaction block. We increment the command
2538 * counter and return.
2540 case TBLOCK_INPROGRESS:
2541 case TBLOCK_SUBINPROGRESS:
2542 CommandCounterIncrement();
2546 * We are completing a "COMMIT" command. Do it and return to the
2550 CommitTransaction();
2551 s->blockState = TBLOCK_DEFAULT;
2555 * Here we are in the middle of a transaction block but one of the
2556 * commands caused an abort so we do nothing but remain in the
2557 * abort state. Eventually we will get a ROLLBACK comand.
2560 case TBLOCK_SUBABORT:
2564 * Here we were in an aborted transaction block and we just got
2565 * the ROLLBACK command from the user, so clean up the
2566 * already-aborted transaction and return to the idle state.
2568 case TBLOCK_ABORT_END:
2569 CleanupTransaction();
2570 s->blockState = TBLOCK_DEFAULT;
2574 * Here we were in a perfectly good transaction block but the user
2575 * told us to ROLLBACK anyway. We have to abort the transaction
2576 * and then clean up.
2578 case TBLOCK_ABORT_PENDING:
2580 CleanupTransaction();
2581 s->blockState = TBLOCK_DEFAULT;
2585 * We are completing a "PREPARE TRANSACTION" command. Do it and
2586 * return to the idle state.
2588 case TBLOCK_PREPARE:
2589 PrepareTransaction();
2590 s->blockState = TBLOCK_DEFAULT;
2594 * We were just issued a SAVEPOINT inside a transaction block.
2595 * Start a subtransaction. (DefineSavepoint already did
2596 * PushTransaction, so as to have someplace to put the SUBBEGIN
2599 case TBLOCK_SUBBEGIN:
2600 StartSubTransaction();
2601 s->blockState = TBLOCK_SUBINPROGRESS;
2605 * We were issued a RELEASE command, so we end the
2606 * current subtransaction and return to the parent transaction.
2607 * The parent might be ended too, so repeat till we find an
2608 * INPROGRESS transaction or subtransaction.
2610 case TBLOCK_SUBRELEASE:
2613 CommitSubTransaction();
2614 s = CurrentTransactionState; /* changed by pop */
2615 } while (s->blockState == TBLOCK_SUBRELEASE);
2617 Assert(s->blockState == TBLOCK_INPROGRESS ||
2618 s->blockState == TBLOCK_SUBINPROGRESS);
2622 * We were issued a COMMIT, so we end the current subtransaction
2623 * hierarchy and perform final commit. We do this by rolling up
2624 * any subtransactions into their parent, which leads to O(N^2)
2625 * operations with respect to resource owners - this isn't that
2626 * bad until we approach a thousands of savepoints but is necessary
2627 * for correctness should after triggers create new resource
2630 case TBLOCK_SUBCOMMIT:
2633 CommitSubTransaction();
2634 s = CurrentTransactionState; /* changed by pop */
2635 } while (s->blockState == TBLOCK_SUBCOMMIT);
2636 /* If we had a COMMIT command, finish off the main xact too */
2637 if (s->blockState == TBLOCK_END)
2639 Assert(s->parent == NULL);
2640 CommitTransaction();
2641 s->blockState = TBLOCK_DEFAULT;
2643 else if (s->blockState == TBLOCK_PREPARE)
2645 Assert(s->parent == NULL);
2646 PrepareTransaction();
2647 s->blockState = TBLOCK_DEFAULT;
2650 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
2651 BlockStateAsString(s->blockState));
2655 * The current already-failed subtransaction is ending due to a
2656 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2657 * examine the parent (which could be in any of several states).
2659 case TBLOCK_SUBABORT_END:
2660 CleanupSubTransaction();
2661 CommitTransactionCommand();
2665 * As above, but it's not dead yet, so abort first.
2667 case TBLOCK_SUBABORT_PENDING:
2668 AbortSubTransaction();
2669 CleanupSubTransaction();
2670 CommitTransactionCommand();
2674 * The current subtransaction is the target of a ROLLBACK TO
2675 * command. Abort and pop it, then start a new subtransaction
2676 * with the same name.
2678 case TBLOCK_SUBRESTART:
2683 /* save name and keep Cleanup from freeing it */
2686 savepointLevel = s->savepointLevel;
2688 AbortSubTransaction();
2689 CleanupSubTransaction();
2691 DefineSavepoint(NULL);
2692 s = CurrentTransactionState; /* changed by push */
2694 s->savepointLevel = savepointLevel;
2696 /* This is the same as TBLOCK_SUBBEGIN case */
2697 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2698 StartSubTransaction();
2699 s->blockState = TBLOCK_SUBINPROGRESS;
2704 * Same as above, but the subtransaction had already failed, so we
2705 * don't need AbortSubTransaction.
2707 case TBLOCK_SUBABORT_RESTART:
2712 /* save name and keep Cleanup from freeing it */
2715 savepointLevel = s->savepointLevel;
2717 CleanupSubTransaction();
2719 DefineSavepoint(NULL);
2720 s = CurrentTransactionState; /* changed by push */
2722 s->savepointLevel = savepointLevel;
2724 /* This is the same as TBLOCK_SUBBEGIN case */
2725 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2726 StartSubTransaction();
2727 s->blockState = TBLOCK_SUBINPROGRESS;
2734 * AbortCurrentTransaction
2737 AbortCurrentTransaction(void)
2739 TransactionState s = CurrentTransactionState;
2741 switch (s->blockState)
2743 case TBLOCK_DEFAULT:
2744 if (s->state == TRANS_DEFAULT)
2746 /* we are idle, so nothing to do */
2751 * We can get here after an error during transaction start
2752 * (state will be TRANS_START). Need to clean up the
2753 * incompletely started transaction. First, adjust the
2754 * low-level state to suppress warning message from
2757 if (s->state == TRANS_START)
2758 s->state = TRANS_INPROGRESS;
2760 CleanupTransaction();
2765 * if we aren't in a transaction block, we just do the basic abort
2766 * & cleanup transaction.
2768 case TBLOCK_STARTED:
2770 CleanupTransaction();
2771 s->blockState = TBLOCK_DEFAULT;
2775 * If we are in TBLOCK_BEGIN it means something screwed up right
2776 * after reading "BEGIN TRANSACTION". We assume that the user
2777 * will interpret the error as meaning the BEGIN failed to get him
2778 * into a transaction block, so we should abort and return to idle
2783 CleanupTransaction();
2784 s->blockState = TBLOCK_DEFAULT;
2788 * We are somewhere in a transaction block and we've gotten a
2789 * failure, so we abort the transaction and set up the persistent
2790 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
2792 case TBLOCK_INPROGRESS:
2794 s->blockState = TBLOCK_ABORT;
2795 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
2799 * Here, we failed while trying to COMMIT. Clean up the
2800 * transaction and return to idle state (we do not want to stay in
2805 CleanupTransaction();
2806 s->blockState = TBLOCK_DEFAULT;
2810 * Here, we are already in an aborted transaction state and are
2811 * waiting for a ROLLBACK, but for some reason we failed again! So
2812 * we just remain in the abort state.
2815 case TBLOCK_SUBABORT:
2819 * We are in a failed transaction and we got the ROLLBACK command.
2820 * We have already aborted, we just need to cleanup and go to idle
2823 case TBLOCK_ABORT_END:
2824 CleanupTransaction();
2825 s->blockState = TBLOCK_DEFAULT;
2829 * We are in a live transaction and we got a ROLLBACK command.
2830 * Abort, cleanup, go to idle state.
2832 case TBLOCK_ABORT_PENDING:
2834 CleanupTransaction();
2835 s->blockState = TBLOCK_DEFAULT;
2839 * Here, we failed while trying to PREPARE. Clean up the
2840 * transaction and return to idle state (we do not want to stay in
2843 case TBLOCK_PREPARE:
2845 CleanupTransaction();
2846 s->blockState = TBLOCK_DEFAULT;
2850 * We got an error inside a subtransaction. Abort just the
2851 * subtransaction, and go to the persistent SUBABORT state until
2854 case TBLOCK_SUBINPROGRESS:
2855 AbortSubTransaction();
2856 s->blockState = TBLOCK_SUBABORT;
2860 * If we failed while trying to create a subtransaction, clean up
2861 * the broken subtransaction and abort the parent. The same
2862 * applies if we get a failure while ending a subtransaction.
2864 case TBLOCK_SUBBEGIN:
2865 case TBLOCK_SUBRELEASE:
2866 case TBLOCK_SUBCOMMIT:
2867 case TBLOCK_SUBABORT_PENDING:
2868 case TBLOCK_SUBRESTART:
2869 AbortSubTransaction();
2870 CleanupSubTransaction();
2871 AbortCurrentTransaction();
2875 * Same as above, except the Abort() was already done.
2877 case TBLOCK_SUBABORT_END:
2878 case TBLOCK_SUBABORT_RESTART:
2879 CleanupSubTransaction();
2880 AbortCurrentTransaction();
2886 * PreventTransactionChain
2888 * This routine is to be called by statements that must not run inside
2889 * a transaction block, typically because they have non-rollback-able
2890 * side effects or do internal commits.
2892 * If we have already started a transaction block, issue an error; also issue
2893 * an error if we appear to be running inside a user-defined function (which
2894 * could issue more commands and possibly cause a failure after the statement
2895 * completes). Subtransactions are verboten too.
2897 * isTopLevel: passed down from ProcessUtility to determine whether we are
2898 * inside a function or multi-query querystring. (We will always fail if
2899 * this is false, but it's convenient to centralize the check here instead of
2900 * making callers do it.)
2901 * stmtType: statement type name, for error messages.
2904 PreventTransactionChain(bool isTopLevel, const char *stmtType)
2907 * xact block already started?
2909 if (IsTransactionBlock())
2911 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2912 /* translator: %s represents an SQL statement name */
2913 errmsg("%s cannot run inside a transaction block",
2919 if (IsSubTransaction())
2921 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2922 /* translator: %s represents an SQL statement name */
2923 errmsg("%s cannot run inside a subtransaction",
2927 * inside a function call?
2931 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2932 /* translator: %s represents an SQL statement name */
2933 errmsg("%s cannot be executed from a function or multi-command string",
2936 /* If we got past IsTransactionBlock test, should be in default state */
2937 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2938 CurrentTransactionState->blockState != TBLOCK_STARTED)
2939 elog(FATAL, "cannot prevent transaction chain");
2944 * RequireTransactionChain
2946 * This routine is to be called by statements that must run inside
2947 * a transaction block, because they have no effects that persist past
2948 * transaction end (and so calling them outside a transaction block
2949 * is presumably an error). DECLARE CURSOR is an example.
2951 * If we appear to be running inside a user-defined function, we do not
2952 * issue an error, since the function could issue more commands that make
2953 * use of the current statement's results. Likewise subtransactions.
2954 * Thus this is an inverse for PreventTransactionChain.
2956 * isTopLevel: passed down from ProcessUtility to determine whether we are
2957 * inside a function.
2958 * stmtType: statement type name, for error messages.
2961 RequireTransactionChain(bool isTopLevel, const char *stmtType)
2964 * xact block already started?
2966 if (IsTransactionBlock())
2972 if (IsSubTransaction())
2976 * inside a function call?
2982 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2983 /* translator: %s represents an SQL statement name */
2984 errmsg("%s can only be used in transaction blocks",
2989 * IsInTransactionChain
2991 * This routine is for statements that need to behave differently inside
2992 * a transaction block than when running as single commands. ANALYZE is
2993 * currently the only example.
2995 * isTopLevel: passed down from ProcessUtility to determine whether we are
2996 * inside a function.
2999 IsInTransactionChain(bool isTopLevel)
3002 * Return true on same conditions that would make PreventTransactionChain
3005 if (IsTransactionBlock())
3008 if (IsSubTransaction())
3014 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
3015 CurrentTransactionState->blockState != TBLOCK_STARTED)
3023 * Register or deregister callback functions for start- and end-of-xact
3026 * These functions are intended for use by dynamically loaded modules.
3027 * For built-in modules we generally just hardwire the appropriate calls
3028 * (mainly because it's easier to control the order that way, where needed).
3030 * At transaction end, the callback occurs post-commit or post-abort, so the
3031 * callback functions can only do noncritical cleanup.
3034 RegisterXactCallback(XactCallback callback, void *arg)
3036 XactCallbackItem *item;
3038 item = (XactCallbackItem *)
3039 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
3040 item->callback = callback;
3042 item->next = Xact_callbacks;
3043 Xact_callbacks = item;
3047 UnregisterXactCallback(XactCallback callback, void *arg)
3049 XactCallbackItem *item;
3050 XactCallbackItem *prev;
3053 for (item = Xact_callbacks; item; prev = item, item = item->next)
3055 if (item->callback == callback && item->arg == arg)
3058 prev->next = item->next;
3060 Xact_callbacks = item->next;
3068 CallXactCallbacks(XactEvent event)
3070 XactCallbackItem *item;
3072 for (item = Xact_callbacks; item; item = item->next)
3073 (*item->callback) (event, item->arg);
3078 * Register or deregister callback functions for start- and end-of-subxact
3081 * Pretty much same as above, but for subtransaction events.
3083 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3084 * so the callback functions can only do noncritical cleanup. At
3085 * subtransaction start, the callback is called when the subtransaction has
3086 * finished initializing.
3089 RegisterSubXactCallback(SubXactCallback callback, void *arg)
3091 SubXactCallbackItem *item;
3093 item = (SubXactCallbackItem *)
3094 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
3095 item->callback = callback;
3097 item->next = SubXact_callbacks;
3098 SubXact_callbacks = item;
3102 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
3104 SubXactCallbackItem *item;
3105 SubXactCallbackItem *prev;
3108 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3110 if (item->callback == callback && item->arg == arg)
3113 prev->next = item->next;
3115 SubXact_callbacks = item->next;
3123 CallSubXactCallbacks(SubXactEvent event,
3124 SubTransactionId mySubid,
3125 SubTransactionId parentSubid)
3127 SubXactCallbackItem *item;
3129 for (item = SubXact_callbacks; item; item = item->next)
3130 (*item->callback) (event, mySubid, parentSubid, item->arg);
3134 /* ----------------------------------------------------------------
3135 * transaction block support
3136 * ----------------------------------------------------------------
3140 * BeginTransactionBlock
3141 * This executes a BEGIN command.
3144 BeginTransactionBlock(void)
3146 TransactionState s = CurrentTransactionState;
3148 switch (s->blockState)
3151 * We are not inside a transaction block, so allow one to begin.
3153 case TBLOCK_STARTED:
3154 s->blockState = TBLOCK_BEGIN;
3158 * Already a transaction block in progress.
3160 case TBLOCK_INPROGRESS:
3161 case TBLOCK_SUBINPROGRESS:
3163 case TBLOCK_SUBABORT:
3165 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3166 errmsg("there is already a transaction in progress")));
3169 /* These cases are invalid. */
3170 case TBLOCK_DEFAULT:
3172 case TBLOCK_SUBBEGIN:
3174 case TBLOCK_SUBRELEASE:
3175 case TBLOCK_SUBCOMMIT:
3176 case TBLOCK_ABORT_END:
3177 case TBLOCK_SUBABORT_END:
3178 case TBLOCK_ABORT_PENDING:
3179 case TBLOCK_SUBABORT_PENDING:
3180 case TBLOCK_SUBRESTART:
3181 case TBLOCK_SUBABORT_RESTART:
3182 case TBLOCK_PREPARE:
3183 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3184 BlockStateAsString(s->blockState));
3190 * PrepareTransactionBlock
3191 * This executes a PREPARE command.
3193 * Since PREPARE may actually do a ROLLBACK, the result indicates what
3194 * happened: TRUE for PREPARE, FALSE for ROLLBACK.
3196 * Note that we don't actually do anything here except change blockState.
3197 * The real work will be done in the upcoming PrepareTransaction().
3198 * We do it this way because it's not convenient to change memory context,
3199 * resource owner, etc while executing inside a Portal.
3202 PrepareTransactionBlock(char *gid)
3207 /* Set up to commit the current transaction */
3208 result = EndTransactionBlock();
3210 /* If successful, change outer tblock state to PREPARE */
3213 s = CurrentTransactionState;
3215 while (s->parent != NULL)
3218 if (s->blockState == TBLOCK_END)
3220 /* Save GID where PrepareTransaction can find it again */
3221 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
3223 s->blockState = TBLOCK_PREPARE;
3228 * ignore case where we are not in a transaction;
3229 * EndTransactionBlock already issued a warning.
3231 Assert(s->blockState == TBLOCK_STARTED);
3232 /* Don't send back a PREPARE result tag... */
3241 * EndTransactionBlock
3242 * This executes a COMMIT command.
3244 * Since COMMIT may actually do a ROLLBACK, the result indicates what
3245 * happened: TRUE for COMMIT, FALSE for ROLLBACK.
3247 * Note that we don't actually do anything here except change blockState.
3248 * The real work will be done in the upcoming CommitTransactionCommand().
3249 * We do it this way because it's not convenient to change memory context,
3250 * resource owner, etc while executing inside a Portal.
3253 EndTransactionBlock(void)
3255 TransactionState s = CurrentTransactionState;
3256 bool result = false;
3258 switch (s->blockState)
3261 * We are in a transaction block, so tell CommitTransactionCommand
3264 case TBLOCK_INPROGRESS:
3265 s->blockState = TBLOCK_END;
3270 * We are in a failed transaction block. Tell
3271 * CommitTransactionCommand it's time to exit the block.
3274 s->blockState = TBLOCK_ABORT_END;
3278 * We are in a live subtransaction block. Set up to subcommit all
3279 * open subtransactions and then commit the main transaction.
3281 case TBLOCK_SUBINPROGRESS:
3282 while (s->parent != NULL)
3284 if (s->blockState == TBLOCK_SUBINPROGRESS)
3285 s->blockState = TBLOCK_SUBCOMMIT;
3287 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3288 BlockStateAsString(s->blockState));
3291 if (s->blockState == TBLOCK_INPROGRESS)
3292 s->blockState = TBLOCK_END;
3294 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3295 BlockStateAsString(s->blockState));
3300 * Here we are inside an aborted subtransaction. Treat the COMMIT
3301 * as ROLLBACK: set up to abort everything and exit the main
3304 case TBLOCK_SUBABORT:
3305 while (s->parent != NULL)
3307 if (s->blockState == TBLOCK_SUBINPROGRESS)
3308 s->blockState = TBLOCK_SUBABORT_PENDING;
3309 else if (s->blockState == TBLOCK_SUBABORT)
3310 s->blockState = TBLOCK_SUBABORT_END;
3312 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3313 BlockStateAsString(s->blockState));
3316 if (s->blockState == TBLOCK_INPROGRESS)
3317 s->blockState = TBLOCK_ABORT_PENDING;
3318 else if (s->blockState == TBLOCK_ABORT)
3319 s->blockState = TBLOCK_ABORT_END;
3321 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3322 BlockStateAsString(s->blockState));
3326 * The user issued COMMIT when not inside a transaction. Issue a
3327 * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
3328 * CommitTransactionCommand() will then close the transaction and
3329 * put us back into the default state.
3331 case TBLOCK_STARTED:
3333 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3334 errmsg("there is no transaction in progress")));
3338 /* These cases are invalid. */
3339 case TBLOCK_DEFAULT:
3341 case TBLOCK_SUBBEGIN:
3343 case TBLOCK_SUBRELEASE:
3344 case TBLOCK_SUBCOMMIT:
3345 case TBLOCK_ABORT_END:
3346 case TBLOCK_SUBABORT_END:
3347 case TBLOCK_ABORT_PENDING:
3348 case TBLOCK_SUBABORT_PENDING:
3349 case TBLOCK_SUBRESTART:
3350 case TBLOCK_SUBABORT_RESTART:
3351 case TBLOCK_PREPARE:
3352 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3353 BlockStateAsString(s->blockState));
3361 * UserAbortTransactionBlock
3362 * This executes a ROLLBACK command.
3364 * As above, we don't actually do anything here except change blockState.
3367 UserAbortTransactionBlock(void)
3369 TransactionState s = CurrentTransactionState;
3371 switch (s->blockState)
3374 * We are inside a transaction block and we got a ROLLBACK command
3375 * from the user, so tell CommitTransactionCommand to abort and
3376 * exit the transaction block.
3378 case TBLOCK_INPROGRESS:
3379 s->blockState = TBLOCK_ABORT_PENDING;
3383 * We are inside a failed transaction block and we got a ROLLBACK
3384 * command from the user. Abort processing is already done, so
3385 * CommitTransactionCommand just has to cleanup and go back to
3389 s->blockState = TBLOCK_ABORT_END;
3393 * We are inside a subtransaction. Mark everything up to top
3394 * level as exitable.
3396 case TBLOCK_SUBINPROGRESS:
3397 case TBLOCK_SUBABORT:
3398 while (s->parent != NULL)
3400 if (s->blockState == TBLOCK_SUBINPROGRESS)
3401 s->blockState = TBLOCK_SUBABORT_PENDING;
3402 else if (s->blockState == TBLOCK_SUBABORT)
3403 s->blockState = TBLOCK_SUBABORT_END;
3405 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3406 BlockStateAsString(s->blockState));
3409 if (s->blockState == TBLOCK_INPROGRESS)
3410 s->blockState = TBLOCK_ABORT_PENDING;
3411 else if (s->blockState == TBLOCK_ABORT)
3412 s->blockState = TBLOCK_ABORT_END;
3414 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3415 BlockStateAsString(s->blockState));
3419 * The user issued ABORT when not inside a transaction. Issue a
3420 * WARNING and go to abort state. The upcoming call to
3421 * CommitTransactionCommand() will then put us back into the
3424 case TBLOCK_STARTED:
3426 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3427 errmsg("there is no transaction in progress")));
3428 s->blockState = TBLOCK_ABORT_PENDING;
3431 /* These cases are invalid. */
3432 case TBLOCK_DEFAULT:
3434 case TBLOCK_SUBBEGIN:
3436 case TBLOCK_SUBRELEASE:
3437 case TBLOCK_SUBCOMMIT:
3438 case TBLOCK_ABORT_END:
3439 case TBLOCK_SUBABORT_END:
3440 case TBLOCK_ABORT_PENDING:
3441 case TBLOCK_SUBABORT_PENDING:
3442 case TBLOCK_SUBRESTART:
3443 case TBLOCK_SUBABORT_RESTART:
3444 case TBLOCK_PREPARE:
3445 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3446 BlockStateAsString(s->blockState));
3453 * This executes a SAVEPOINT command.
3456 DefineSavepoint(char *name)
3458 TransactionState s = CurrentTransactionState;
3460 switch (s->blockState)
3462 case TBLOCK_INPROGRESS:
3463 case TBLOCK_SUBINPROGRESS:
3464 /* Normal subtransaction start */
3466 s = CurrentTransactionState; /* changed by push */
3469 * Savepoint names, like the TransactionState block itself, live
3470 * in TopTransactionContext.
3473 s->name = MemoryContextStrdup(TopTransactionContext, name);
3476 /* These cases are invalid. */
3477 case TBLOCK_DEFAULT:
3478 case TBLOCK_STARTED:
3480 case TBLOCK_SUBBEGIN:
3482 case TBLOCK_SUBRELEASE:
3483 case TBLOCK_SUBCOMMIT:
3485 case TBLOCK_SUBABORT:
3486 case TBLOCK_ABORT_END:
3487 case TBLOCK_SUBABORT_END:
3488 case TBLOCK_ABORT_PENDING:
3489 case TBLOCK_SUBABORT_PENDING:
3490 case TBLOCK_SUBRESTART:
3491 case TBLOCK_SUBABORT_RESTART:
3492 case TBLOCK_PREPARE:
3493 elog(FATAL, "DefineSavepoint: unexpected state %s",
3494 BlockStateAsString(s->blockState));
3501 * This executes a RELEASE command.
3503 * As above, we don't actually do anything here except change blockState.
3506 ReleaseSavepoint(List *options)
3508 TransactionState s = CurrentTransactionState;
3509 TransactionState target,
3514 switch (s->blockState)
3517 * We can't rollback to a savepoint if there is no savepoint
3520 case TBLOCK_INPROGRESS:
3522 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3523 errmsg("no such savepoint")));
3527 * We are in a non-aborted subtransaction. This is the only valid
3530 case TBLOCK_SUBINPROGRESS:
3533 /* These cases are invalid. */
3534 case TBLOCK_DEFAULT:
3535 case TBLOCK_STARTED:
3537 case TBLOCK_SUBBEGIN:
3539 case TBLOCK_SUBRELEASE:
3540 case TBLOCK_SUBCOMMIT:
3542 case TBLOCK_SUBABORT:
3543 case TBLOCK_ABORT_END:
3544 case TBLOCK_SUBABORT_END:
3545 case TBLOCK_ABORT_PENDING:
3546 case TBLOCK_SUBABORT_PENDING:
3547 case TBLOCK_SUBRESTART:
3548 case TBLOCK_SUBABORT_RESTART:
3549 case TBLOCK_PREPARE:
3550 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3551 BlockStateAsString(s->blockState));
3555 foreach(cell, options)
3557 DefElem *elem = lfirst(cell);
3559 if (strcmp(elem->defname, "savepoint_name") == 0)
3560 name = strVal(elem->arg);
3563 Assert(PointerIsValid(name));
3565 for (target = s; PointerIsValid(target); target = target->parent)
3567 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3571 if (!PointerIsValid(target))
3573 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3574 errmsg("no such savepoint")));
3576 /* disallow crossing savepoint level boundaries */
3577 if (target->savepointLevel != s->savepointLevel)
3579 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3580 errmsg("no such savepoint")));
3583 * Mark "commit pending" all subtransactions up to the target
3584 * subtransaction. The actual commits will happen when control gets to
3585 * CommitTransactionCommand.
3587 xact = CurrentTransactionState;
3590 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3591 xact->blockState = TBLOCK_SUBRELEASE;
3594 xact = xact->parent;
3595 Assert(PointerIsValid(xact));
3600 * RollbackToSavepoint
3601 * This executes a ROLLBACK TO <savepoint> command.
3603 * As above, we don't actually do anything here except change blockState.
3606 RollbackToSavepoint(List *options)
3608 TransactionState s = CurrentTransactionState;
3609 TransactionState target,
3614 switch (s->blockState)
3617 * We can't rollback to a savepoint if there is no savepoint
3620 case TBLOCK_INPROGRESS:
3623 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3624 errmsg("no such savepoint")));
3628 * There is at least one savepoint, so proceed.
3630 case TBLOCK_SUBINPROGRESS:
3631 case TBLOCK_SUBABORT:
3634 /* These cases are invalid. */
3635 case TBLOCK_DEFAULT:
3636 case TBLOCK_STARTED:
3638 case TBLOCK_SUBBEGIN:
3640 case TBLOCK_SUBRELEASE:
3641 case TBLOCK_SUBCOMMIT:
3642 case TBLOCK_ABORT_END:
3643 case TBLOCK_SUBABORT_END:
3644 case TBLOCK_ABORT_PENDING:
3645 case TBLOCK_SUBABORT_PENDING:
3646 case TBLOCK_SUBRESTART:
3647 case TBLOCK_SUBABORT_RESTART:
3648 case TBLOCK_PREPARE:
3649 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3650 BlockStateAsString(s->blockState));
3654 foreach(cell, options)
3656 DefElem *elem = lfirst(cell);
3658 if (strcmp(elem->defname, "savepoint_name") == 0)
3659 name = strVal(elem->arg);
3662 Assert(PointerIsValid(name));
3664 for (target = s; PointerIsValid(target); target = target->parent)
3666 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3670 if (!PointerIsValid(target))
3672 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3673 errmsg("no such savepoint")));
3675 /* disallow crossing savepoint level boundaries */
3676 if (target->savepointLevel != s->savepointLevel)
3678 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3679 errmsg("no such savepoint")));
3682 * Mark "abort pending" all subtransactions up to the target
3683 * subtransaction. The actual aborts will happen when control gets to
3684 * CommitTransactionCommand.
3686 xact = CurrentTransactionState;
3691 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3692 xact->blockState = TBLOCK_SUBABORT_PENDING;
3693 else if (xact->blockState == TBLOCK_SUBABORT)
3694 xact->blockState = TBLOCK_SUBABORT_END;
3696 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3697 BlockStateAsString(xact->blockState));
3698 xact = xact->parent;
3699 Assert(PointerIsValid(xact));
3702 /* And mark the target as "restart pending" */
3703 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3704 xact->blockState = TBLOCK_SUBRESTART;
3705 else if (xact->blockState == TBLOCK_SUBABORT)
3706 xact->blockState = TBLOCK_SUBABORT_RESTART;
3708 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3709 BlockStateAsString(xact->blockState));
3713 * BeginInternalSubTransaction
3714 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
3715 * TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
3716 * used in functions that might be called when not inside a BEGIN block
3717 * or when running deferred triggers at COMMIT/PREPARE time. Also, it
3718 * automatically does CommitTransactionCommand/StartTransactionCommand
3719 * instead of expecting the caller to do it.
3722 BeginInternalSubTransaction(char *name)
3724 TransactionState s = CurrentTransactionState;
3726 switch (s->blockState)
3728 case TBLOCK_STARTED:
3729 case TBLOCK_INPROGRESS:
3731 case TBLOCK_PREPARE:
3732 case TBLOCK_SUBINPROGRESS:
3733 /* Normal subtransaction start */
3735 s = CurrentTransactionState; /* changed by push */
3738 * Savepoint names, like the TransactionState block itself, live
3739 * in TopTransactionContext.
3742 s->name = MemoryContextStrdup(TopTransactionContext, name);
3745 /* These cases are invalid. */
3746 case TBLOCK_DEFAULT:
3748 case TBLOCK_SUBBEGIN:
3749 case TBLOCK_SUBRELEASE:
3750 case TBLOCK_SUBCOMMIT:
3752 case TBLOCK_SUBABORT:
3753 case TBLOCK_ABORT_END:
3754 case TBLOCK_SUBABORT_END:
3755 case TBLOCK_ABORT_PENDING:
3756 case TBLOCK_SUBABORT_PENDING:
3757 case TBLOCK_SUBRESTART:
3758 case TBLOCK_SUBABORT_RESTART:
3759 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
3760 BlockStateAsString(s->blockState));
3764 CommitTransactionCommand();
3765 StartTransactionCommand();
3769 * ReleaseCurrentSubTransaction
3771 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
3772 * savepoint name (if any).
3773 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3776 ReleaseCurrentSubTransaction(void)
3778 TransactionState s = CurrentTransactionState;
3780 if (s->blockState != TBLOCK_SUBINPROGRESS)
3781 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
3782 BlockStateAsString(s->blockState));
3783 Assert(s->state == TRANS_INPROGRESS);
3784 MemoryContextSwitchTo(CurTransactionContext);
3785 CommitSubTransaction();
3786 s = CurrentTransactionState; /* changed by pop */
3787 Assert(s->state == TRANS_INPROGRESS);
3791 * RollbackAndReleaseCurrentSubTransaction
3793 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
3794 * of its savepoint name (if any).
3795 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3798 RollbackAndReleaseCurrentSubTransaction(void)
3800 TransactionState s = CurrentTransactionState;
3802 switch (s->blockState)
3804 /* Must be in a subtransaction */
3805 case TBLOCK_SUBINPROGRESS:
3806 case TBLOCK_SUBABORT:
3809 /* These cases are invalid. */
3810 case TBLOCK_DEFAULT:
3811 case TBLOCK_STARTED:
3813 case TBLOCK_SUBBEGIN:
3814 case TBLOCK_INPROGRESS:
3816 case TBLOCK_SUBRELEASE:
3817 case TBLOCK_SUBCOMMIT:
3819 case TBLOCK_ABORT_END:
3820 case TBLOCK_SUBABORT_END:
3821 case TBLOCK_ABORT_PENDING:
3822 case TBLOCK_SUBABORT_PENDING:
3823 case TBLOCK_SUBRESTART:
3824 case TBLOCK_SUBABORT_RESTART:
3825 case TBLOCK_PREPARE:
3826 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
3827 BlockStateAsString(s->blockState));
3832 * Abort the current subtransaction, if needed.
3834 if (s->blockState == TBLOCK_SUBINPROGRESS)
3835 AbortSubTransaction();
3837 /* And clean it up, too */
3838 CleanupSubTransaction();
3840 s = CurrentTransactionState; /* changed by pop */
3841 AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
3842 s->blockState == TBLOCK_INPROGRESS ||
3843 s->blockState == TBLOCK_STARTED);
3847 * AbortOutOfAnyTransaction
3849 * This routine is provided for error recovery purposes. It aborts any
3850 * active transaction or transaction block, leaving the system in a known
3854 AbortOutOfAnyTransaction(void)
3856 TransactionState s = CurrentTransactionState;
3859 * Get out of any transaction or nested transaction
3863 switch (s->blockState)
3865 case TBLOCK_DEFAULT:
3866 if (s->state == TRANS_DEFAULT)
3868 /* Not in a transaction, do nothing */
3873 * We can get here after an error during transaction start
3874 * (state will be TRANS_START). Need to clean up the
3875 * incompletely started transaction. First, adjust the
3876 * low-level state to suppress warning message from
3879 if (s->state == TRANS_START)
3880 s->state = TRANS_INPROGRESS;
3882 CleanupTransaction();
3885 case TBLOCK_STARTED:
3887 case TBLOCK_INPROGRESS:
3889 case TBLOCK_ABORT_PENDING:
3890 case TBLOCK_PREPARE:
3891 /* In a transaction, so clean up */
3893 CleanupTransaction();
3894 s->blockState = TBLOCK_DEFAULT;
3897 case TBLOCK_ABORT_END:
3898 /* AbortTransaction already done, still need Cleanup */
3899 CleanupTransaction();
3900 s->blockState = TBLOCK_DEFAULT;
3904 * In a subtransaction, so clean it up and abort parent too
3906 case TBLOCK_SUBBEGIN:
3907 case TBLOCK_SUBINPROGRESS:
3908 case TBLOCK_SUBRELEASE:
3909 case TBLOCK_SUBCOMMIT:
3910 case TBLOCK_SUBABORT_PENDING:
3911 case TBLOCK_SUBRESTART:
3912 AbortSubTransaction();
3913 CleanupSubTransaction();
3914 s = CurrentTransactionState; /* changed by pop */
3917 case TBLOCK_SUBABORT:
3918 case TBLOCK_SUBABORT_END:
3919 case TBLOCK_SUBABORT_RESTART:
3920 /* As above, but AbortSubTransaction already done */
3921 CleanupSubTransaction();
3922 s = CurrentTransactionState; /* changed by pop */
3925 } while (s->blockState != TBLOCK_DEFAULT);
3927 /* Should be out of all subxacts now */
3928 Assert(s->parent == NULL);
3932 * IsTransactionBlock --- are we within a transaction block?
3935 IsTransactionBlock(void)
3937 TransactionState s = CurrentTransactionState;
3939 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
3946 * IsTransactionOrTransactionBlock --- are we within either a transaction
3947 * or a transaction block? (The backend is only really "idle" when this
3950 * This should match up with IsTransactionBlock and IsTransactionState.
3953 IsTransactionOrTransactionBlock(void)
3955 TransactionState s = CurrentTransactionState;
3957 if (s->blockState == TBLOCK_DEFAULT)
3964 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
3967 TransactionBlockStatusCode(void)
3969 TransactionState s = CurrentTransactionState;
3971 switch (s->blockState)
3973 case TBLOCK_DEFAULT:
3974 case TBLOCK_STARTED:
3975 return 'I'; /* idle --- not in transaction */
3977 case TBLOCK_SUBBEGIN:
3978 case TBLOCK_INPROGRESS:
3979 case TBLOCK_SUBINPROGRESS:
3981 case TBLOCK_SUBRELEASE:
3982 case TBLOCK_SUBCOMMIT:
3983 case TBLOCK_PREPARE:
3984 return 'T'; /* in transaction */
3986 case TBLOCK_SUBABORT:
3987 case TBLOCK_ABORT_END:
3988 case TBLOCK_SUBABORT_END:
3989 case TBLOCK_ABORT_PENDING:
3990 case TBLOCK_SUBABORT_PENDING:
3991 case TBLOCK_SUBRESTART:
3992 case TBLOCK_SUBABORT_RESTART:
3993 return 'E'; /* in failed transaction */
3996 /* should never get here */
3997 elog(FATAL, "invalid transaction block state: %s",
3998 BlockStateAsString(s->blockState));
3999 return 0; /* keep compiler quiet */
4006 IsSubTransaction(void)
4008 TransactionState s = CurrentTransactionState;
4010 if (s->nestingLevel >= 2)
4017 * StartSubTransaction
4019 * If you're wondering why this is separate from PushTransaction: it's because
4020 * we can't conveniently do this stuff right inside DefineSavepoint. The
4021 * SAVEPOINT utility command will be executed inside a Portal, and if we
4022 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
4023 * the Portal will undo those settings. So we make DefineSavepoint just
4024 * push a dummy transaction block, and when control returns to the main
4025 * idle loop, CommitTransactionCommand will be called, and we'll come here
4026 * to finish starting the subtransaction.
4029 StartSubTransaction(void)
4031 TransactionState s = CurrentTransactionState;
4033 if (s->state != TRANS_DEFAULT)
4034 elog(WARNING, "StartSubTransaction while in %s state",
4035 TransStateAsString(s->state));
4037 s->state = TRANS_START;
4040 * Initialize subsystems for new subtransaction
4042 * must initialize resource-management stuff first
4044 AtSubStart_Memory();
4045 AtSubStart_ResourceOwner();
4047 AtSubStart_Notify();
4048 AfterTriggerBeginSubXact();
4050 s->state = TRANS_INPROGRESS;
4053 * Call start-of-subxact callbacks
4055 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
4056 s->parent->subTransactionId);
4058 ShowTransactionState("StartSubTransaction");
4062 * CommitSubTransaction
4064 * The caller has to make sure to always reassign CurrentTransactionState
4065 * if it has a local pointer to it after calling this function.
4068 CommitSubTransaction(void)
4070 TransactionState s = CurrentTransactionState;
4072 ShowTransactionState("CommitSubTransaction");
4074 if (s->state != TRANS_INPROGRESS)
4075 elog(WARNING, "CommitSubTransaction while in %s state",
4076 TransStateAsString(s->state));
4078 /* Pre-commit processing goes here -- nothing to do at the moment */
4080 s->state = TRANS_COMMIT;
4082 /* Must CCI to ensure commands of subtransaction are seen as done */
4083 CommandCounterIncrement();
4086 * Prior to 8.4 we marked subcommit in clog at this point. We now only
4087 * perform that step, if required, as part of the atomic update of the
4088 * whole transaction tree at top level commit or abort.
4091 /* Post-commit cleanup */
4092 if (TransactionIdIsValid(s->transactionId))
4093 AtSubCommit_childXids();
4094 AfterTriggerEndSubXact(true);
4095 AtSubCommit_Portals(s->subTransactionId,
4096 s->parent->subTransactionId,
4097 s->parent->curTransactionOwner);
4098 AtEOSubXact_LargeObject(true, s->subTransactionId,
4099 s->parent->subTransactionId);
4100 AtSubCommit_Notify();
4102 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
4103 s->parent->subTransactionId);
4105 ResourceOwnerRelease(s->curTransactionOwner,
4106 RESOURCE_RELEASE_BEFORE_LOCKS,
4108 AtEOSubXact_RelationCache(true, s->subTransactionId,
4109 s->parent->subTransactionId);
4110 AtEOSubXact_Inval(true);
4114 * The only lock we actually release here is the subtransaction XID lock.
4116 CurrentResourceOwner = s->curTransactionOwner;
4117 if (TransactionIdIsValid(s->transactionId))
4118 XactLockTableDelete(s->transactionId);
4121 * Other locks should get transferred to their parent resource owner.
4123 ResourceOwnerRelease(s->curTransactionOwner,
4124 RESOURCE_RELEASE_LOCKS,
4126 ResourceOwnerRelease(s->curTransactionOwner,
4127 RESOURCE_RELEASE_AFTER_LOCKS,
4130 AtEOXact_GUC(true, s->gucNestLevel);
4131 AtEOSubXact_SPI(true, s->subTransactionId);
4132 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
4133 s->parent->subTransactionId);
4134 AtEOSubXact_Namespace(true, s->subTransactionId,
4135 s->parent->subTransactionId);
4136 AtEOSubXact_Files(true, s->subTransactionId,
4137 s->parent->subTransactionId);
4138 AtEOSubXact_HashTables(true, s->nestingLevel);
4139 AtEOSubXact_PgStat(true, s->nestingLevel);
4140 AtSubCommit_Snapshot(s->nestingLevel);
4143 * We need to restore the upper transaction's read-only state, in case the
4144 * upper is read-write while the child is read-only; GUC will incorrectly
4145 * think it should leave the child state in place.
4147 XactReadOnly = s->prevXactReadOnly;
4149 CurrentResourceOwner = s->parent->curTransactionOwner;
4150 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4151 ResourceOwnerDelete(s->curTransactionOwner);
4152 s->curTransactionOwner = NULL;
4154 AtSubCommit_Memory();
4156 s->state = TRANS_DEFAULT;
4162 * AbortSubTransaction
4165 AbortSubTransaction(void)
4167 TransactionState s = CurrentTransactionState;
4169 /* Prevent cancel/die interrupt while cleaning up */
4172 /* Make sure we have a valid memory context and resource owner */
4173 AtSubAbort_Memory();
4174 AtSubAbort_ResourceOwner();
4177 * Release any LW locks we might be holding as quickly as possible.
4178 * (Regular locks, however, must be held till we finish aborting.)
4179 * Releasing LW locks is critical since we might try to grab them again
4180 * while cleaning up!
4182 * FIXME This may be incorrect --- Are there some locks we should keep?
4183 * Buffer locks, for example? I don't think so but I'm not sure.
4193 * check the current transaction state
4195 ShowTransactionState("AbortSubTransaction");
4197 if (s->state != TRANS_INPROGRESS)
4198 elog(WARNING, "AbortSubTransaction while in %s state",
4199 TransStateAsString(s->state));
4201 s->state = TRANS_ABORT;
4204 * Reset user ID which might have been changed transiently. (See notes in
4205 * AbortTransaction.)
4207 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
4210 * We can skip all this stuff if the subxact failed before creating a
4213 if (s->curTransactionOwner)
4215 AfterTriggerEndSubXact(false);
4216 AtSubAbort_Portals(s->subTransactionId,
4217 s->parent->subTransactionId,
4218 s->parent->curTransactionOwner);
4219 AtEOSubXact_LargeObject(false, s->subTransactionId,
4220 s->parent->subTransactionId);
4221 AtSubAbort_Notify();
4223 /* Advertise the fact that we aborted in pg_clog. */
4224 (void) RecordTransactionAbort(true);
4226 /* Post-abort cleanup */
4227 if (TransactionIdIsValid(s->transactionId))
4228 AtSubAbort_childXids();
4230 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
4231 s->parent->subTransactionId);
4233 ResourceOwnerRelease(s->curTransactionOwner,
4234 RESOURCE_RELEASE_BEFORE_LOCKS,
4236 AtEOSubXact_RelationCache(false, s->subTransactionId,
4237 s->parent->subTransactionId);
4238 AtEOSubXact_Inval(false);
4240 ResourceOwnerRelease(s->curTransactionOwner,
4241 RESOURCE_RELEASE_LOCKS,
4243 ResourceOwnerRelease(s->curTransactionOwner,
4244 RESOURCE_RELEASE_AFTER_LOCKS,
4247 AtEOXact_GUC(false, s->gucNestLevel);
4248 AtEOSubXact_SPI(false, s->subTransactionId);
4249 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
4250 s->parent->subTransactionId);
4251 AtEOSubXact_Namespace(false, s->subTransactionId,
4252 s->parent->subTransactionId);
4253 AtEOSubXact_Files(false, s->subTransactionId,
4254 s->parent->subTransactionId);
4255 AtEOSubXact_HashTables(false, s->nestingLevel);
4256 AtEOSubXact_PgStat(false, s->nestingLevel);
4257 AtSubAbort_Snapshot(s->nestingLevel);
4261 * Restore the upper transaction's read-only state, too. This should be
4262 * redundant with GUC's cleanup but we may as well do it for consistency
4263 * with the commit case.
4265 XactReadOnly = s->prevXactReadOnly;
4267 RESUME_INTERRUPTS();
4271 * CleanupSubTransaction
4273 * The caller has to make sure to always reassign CurrentTransactionState
4274 * if it has a local pointer to it after calling this function.
4277 CleanupSubTransaction(void)
4279 TransactionState s = CurrentTransactionState;
4281 ShowTransactionState("CleanupSubTransaction");
4283 if (s->state != TRANS_ABORT)
4284 elog(WARNING, "CleanupSubTransaction while in %s state",
4285 TransStateAsString(s->state));
4287 AtSubCleanup_Portals(s->subTransactionId);
4289 CurrentResourceOwner = s->parent->curTransactionOwner;
4290 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4291 if (s->curTransactionOwner)
4292 ResourceOwnerDelete(s->curTransactionOwner);
4293 s->curTransactionOwner = NULL;
4295 AtSubCleanup_Memory();
4297 s->state = TRANS_DEFAULT;
4304 * Create transaction state stack entry for a subtransaction
4306 * The caller has to make sure to always reassign CurrentTransactionState
4307 * if it has a local pointer to it after calling this function.
4310 PushTransaction(void)
4312 TransactionState p = CurrentTransactionState;
4316 * We keep subtransaction state nodes in TopTransactionContext.
4318 s = (TransactionState)
4319 MemoryContextAllocZero(TopTransactionContext,
4320 sizeof(TransactionStateData));
4323 * Assign a subtransaction ID, watching out for counter wraparound.
4325 currentSubTransactionId += 1;
4326 if (currentSubTransactionId == InvalidSubTransactionId)
4328 currentSubTransactionId -= 1;
4331 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
4332 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
4336 * We can now stack a minimally valid subtransaction without fear of
4339 s->transactionId = InvalidTransactionId; /* until assigned */
4340 s->subTransactionId = currentSubTransactionId;
4342 s->nestingLevel = p->nestingLevel + 1;
4343 s->gucNestLevel = NewGUCNestLevel();
4344 s->savepointLevel = p->savepointLevel;
4345 s->state = TRANS_DEFAULT;
4346 s->blockState = TBLOCK_SUBBEGIN;
4347 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
4348 s->prevXactReadOnly = XactReadOnly;
4350 CurrentTransactionState = s;
4353 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
4354 * with the subtransaction from here on out; in particular they should not
4355 * assume that it necessarily has a transaction context, resource owner,
4362 * Pop back to parent transaction state
4364 * The caller has to make sure to always reassign CurrentTransactionState
4365 * if it has a local pointer to it after calling this function.
4368 PopTransaction(void)
4370 TransactionState s = CurrentTransactionState;
4372 if (s->state != TRANS_DEFAULT)
4373 elog(WARNING, "PopTransaction while in %s state",
4374 TransStateAsString(s->state));
4376 if (s->parent == NULL)
4377 elog(FATAL, "PopTransaction with no parent");
4379 CurrentTransactionState = s->parent;
4381 /* Let's just make sure CurTransactionContext is good */
4382 CurTransactionContext = s->parent->curTransactionContext;
4383 MemoryContextSwitchTo(CurTransactionContext);
4385 /* Ditto for ResourceOwner links */
4386 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4387 CurrentResourceOwner = s->parent->curTransactionOwner;
4389 /* Free the old child structure */
4396 * ShowTransactionState
4400 ShowTransactionState(const char *str)
4402 /* skip work if message will definitely not be printed */
4403 if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
4405 elog(DEBUG3, "%s", str);
4406 ShowTransactionStateRec(CurrentTransactionState);
4411 * ShowTransactionStateRec
4412 * Recursive subroutine for ShowTransactionState
4415 ShowTransactionStateRec(TransactionState s)
4419 initStringInfo(&buf);
4421 if (s->nChildXids > 0)
4425 appendStringInfo(&buf, "%u", s->childXids[0]);
4426 for (i = 1; i < s->nChildXids; i++)
4427 appendStringInfo(&buf, " %u", s->childXids[i]);
4431 ShowTransactionStateRec(s->parent);
4433 /* use ereport to suppress computation if msg will not be printed */
4435 (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u%s, nestlvl: %d, children: %s",
4436 PointerIsValid(s->name) ? s->name : "unnamed",
4437 BlockStateAsString(s->blockState),
4438 TransStateAsString(s->state),
4439 (unsigned int) s->transactionId,
4440 (unsigned int) s->subTransactionId,
4441 (unsigned int) currentCommandId,
4442 currentCommandIdUsed ? " (used)" : "",
4443 s->nestingLevel, buf.data)));
4449 * BlockStateAsString
4453 BlockStateAsString(TBlockState blockState)
4457 case TBLOCK_DEFAULT:
4459 case TBLOCK_STARTED:
4463 case TBLOCK_INPROGRESS:
4464 return "INPROGRESS";
4469 case TBLOCK_ABORT_END:
4471 case TBLOCK_ABORT_PENDING:
4472 return "ABORT PEND";
4473 case TBLOCK_PREPARE:
4475 case TBLOCK_SUBBEGIN:
4477 case TBLOCK_SUBINPROGRESS:
4478 return "SUB INPROGRS";
4479 case TBLOCK_SUBRELEASE:
4480 return "SUB RELEASE";
4481 case TBLOCK_SUBCOMMIT:
4482 return "SUB COMMIT";
4483 case TBLOCK_SUBABORT:
4485 case TBLOCK_SUBABORT_END:
4486 return "SUB ABORT END";
4487 case TBLOCK_SUBABORT_PENDING:
4488 return "SUB ABRT PEND";
4489 case TBLOCK_SUBRESTART:
4490 return "SUB RESTART";
4491 case TBLOCK_SUBABORT_RESTART:
4492 return "SUB AB RESTRT";
4494 return "UNRECOGNIZED";
4498 * TransStateAsString
4502 TransStateAsString(TransState state)
4510 case TRANS_INPROGRESS:
4519 return "UNRECOGNIZED";
4523 * xactGetCommittedChildren
4525 * Gets the list of committed children of the current transaction. The return
4526 * value is the number of child transactions. *ptr is set to point to an
4527 * array of TransactionIds. The array is allocated in TopTransactionContext;
4528 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
4529 * If there are no subxacts, *ptr is set to NULL.
4532 xactGetCommittedChildren(TransactionId **ptr)
4534 TransactionState s = CurrentTransactionState;
4536 if (s->nChildXids == 0)
4539 *ptr = s->childXids;
4541 return s->nChildXids;
4545 * XLOG support routines
4549 * Before 9.0 this was a fairly short function, but now it performs many
4550 * actions for which the order of execution is critical.
4553 xact_redo_commit_internal(TransactionId xid, XLogRecPtr lsn,
4554 TransactionId *sub_xids, int nsubxacts,
4555 SharedInvalidationMessage *inval_msgs, int nmsgs,
4556 RelFileNode *xnodes, int nrels,
4560 TransactionId max_xid;
4563 max_xid = TransactionIdLatest(xid, nsubxacts, sub_xids);
4566 * Make sure nextXid is beyond any XID mentioned in the record.
4568 * We don't expect anyone else to modify nextXid, hence we don't need to
4569 * hold a lock while checking this. We still acquire the lock to modify
4572 if (TransactionIdFollowsOrEquals(max_xid,
4573 ShmemVariableCache->nextXid))
4575 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4576 ShmemVariableCache->nextXid = max_xid;
4577 TransactionIdAdvance(ShmemVariableCache->nextXid);
4578 LWLockRelease(XidGenLock);
4581 if (standbyState == STANDBY_DISABLED)
4584 * Mark the transaction committed in pg_clog.
4586 TransactionIdCommitTree(xid, nsubxacts, sub_xids);
4591 * If a transaction completion record arrives that has as-yet
4592 * unobserved subtransactions then this will not have been fully
4593 * handled by the call to RecordKnownAssignedTransactionIds() in the
4594 * main recovery loop in xlog.c. So we need to do bookkeeping again to
4595 * cover that case. This is confusing and it is easy to think this
4596 * call is irrelevant, which has happened three times in development
4597 * already. Leave it in.
4599 RecordKnownAssignedTransactionIds(max_xid);
4602 * Mark the transaction committed in pg_clog. We use async commit
4603 * protocol during recovery to provide information on database
4604 * consistency for when users try to set hint bits. It is important
4605 * that we do not set hint bits until the minRecoveryPoint is past
4606 * this commit record. This ensures that if we crash we don't see hint
4607 * bits set on changes made by transactions that haven't yet
4608 * recovered. It's unlikely but it's good to be safe.
4610 TransactionIdAsyncCommitTree(xid, nsubxacts, sub_xids, lsn);
4613 * We must mark clog before we update the ProcArray.
4615 ExpireTreeKnownAssignedTransactionIds(xid, nsubxacts, sub_xids, max_xid);
4618 * Send any cache invalidations attached to the commit. We must
4619 * maintain the same order of invalidation then release locks as
4620 * occurs in CommitTransaction().
4622 ProcessCommittedInvalidationMessages(inval_msgs, nmsgs,
4623 XactCompletionRelcacheInitFileInval(xinfo),
4627 * Release locks, if any. We do this for both two phase and normal one
4628 * phase transactions. In effect we are ignoring the prepare phase and
4629 * just going straight to lock release.
4631 StandbyReleaseLockTree(xid, nsubxacts, sub_xids);
4634 /* Make sure files supposed to be dropped are dropped */
4635 for (i = 0; i < nrels; i++)
4637 SMgrRelation srel = smgropen(xnodes[i], InvalidBackendId);
4640 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4641 XLogDropRelation(xnodes[i], fork);
4642 smgrdounlink(srel, true);
4647 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
4648 * in normal operation. For example, in DROP DATABASE, we delete all the
4649 * files belonging to the database, and then commit the transaction. If we
4650 * crash after all the files have been deleted but before the commit, you
4651 * have an entry in pg_database without any files. To minimize the window
4652 * for that, we use ForceSyncCommit() to rush the commit record to disk as
4653 * quick as possible. We have the same window during recovery, and forcing
4654 * an XLogFlush() (which updates minRecoveryPoint during recovery) helps
4655 * to reduce that problem window, for any user that requested
4656 * ForceSyncCommit().
4658 if (XactCompletionForceSyncCommit(xinfo))
4663 * Utility function to call xact_redo_commit_internal after breaking down xlrec
4666 xact_redo_commit(xl_xact_commit *xlrec,
4667 TransactionId xid, XLogRecPtr lsn)
4669 TransactionId *subxacts;
4670 SharedInvalidationMessage *inval_msgs;
4672 /* subxid array follows relfilenodes */
4673 subxacts = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4674 /* invalidation messages array follows subxids */
4675 inval_msgs = (SharedInvalidationMessage *) &(subxacts[xlrec->nsubxacts]);
4677 xact_redo_commit_internal(xid, lsn, subxacts, xlrec->nsubxacts,
4678 inval_msgs, xlrec->nmsgs,
4679 xlrec->xnodes, xlrec->nrels,
4686 * Utility function to call xact_redo_commit_internal for compact form of message.
4689 xact_redo_commit_compact(xl_xact_commit_compact *xlrec,
4690 TransactionId xid, XLogRecPtr lsn)
4692 xact_redo_commit_internal(xid, lsn, xlrec->subxacts, xlrec->nsubxacts,
4693 NULL, 0, /* inval msgs */
4694 NULL, 0, /* relfilenodes */
4695 InvalidOid, /* dbId */
4696 InvalidOid, /* tsId */
4701 * Be careful with the order of execution, as with xact_redo_commit().
4702 * The two functions are similar but differ in key places.
4704 * Note also that an abort can be for a subtransaction and its children,
4705 * not just for a top level abort. That means we have to consider
4706 * topxid != xid, whereas in commit we would find topxid == xid always
4707 * because subtransaction commit is never WAL logged.
4710 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
4712 TransactionId *sub_xids;
4713 TransactionId max_xid;
4716 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4717 max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
4720 * Make sure nextXid is beyond any XID mentioned in the record.
4722 * We don't expect anyone else to modify nextXid, hence we don't need to
4723 * hold a lock while checking this. We still acquire the lock to modify
4726 if (TransactionIdFollowsOrEquals(max_xid,
4727 ShmemVariableCache->nextXid))
4729 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4730 ShmemVariableCache->nextXid = max_xid;
4731 TransactionIdAdvance(ShmemVariableCache->nextXid);
4732 LWLockRelease(XidGenLock);
4735 if (standbyState == STANDBY_DISABLED)
4737 /* Mark the transaction aborted in pg_clog, no need for async stuff */
4738 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4743 * If a transaction completion record arrives that has as-yet
4744 * unobserved subtransactions then this will not have been fully
4745 * handled by the call to RecordKnownAssignedTransactionIds() in the
4746 * main recovery loop in xlog.c. So we need to do bookkeeping again to
4747 * cover that case. This is confusing and it is easy to think this
4748 * call is irrelevant, which has happened three times in development
4749 * already. Leave it in.
4751 RecordKnownAssignedTransactionIds(max_xid);
4753 /* Mark the transaction aborted in pg_clog, no need for async stuff */
4754 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4757 * We must update the ProcArray after we have marked clog.
4759 ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids, max_xid);
4762 * There are no flat files that need updating, nor invalidation
4763 * messages to send or undo.
4767 * Release locks, if any. There are no invalidations to send.
4769 StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
4772 /* Make sure files supposed to be dropped are dropped */
4773 for (i = 0; i < xlrec->nrels; i++)
4775 SMgrRelation srel = smgropen(xlrec->xnodes[i], InvalidBackendId);
4778 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4779 XLogDropRelation(xlrec->xnodes[i], fork);
4780 smgrdounlink(srel, true);
4786 xact_redo(XLogRecPtr lsn, XLogRecord *record)
4788 uint8 info = record->xl_info & ~XLR_INFO_MASK;
4790 /* Backup blocks are not used in xact records */
4791 Assert(!(record->xl_info & XLR_BKP_BLOCK_MASK));
4793 if (info == XLOG_XACT_COMMIT_COMPACT)
4795 xl_xact_commit_compact *xlrec = (xl_xact_commit_compact *) XLogRecGetData(record);
4797 xact_redo_commit_compact(xlrec, record->xl_xid, lsn);
4799 else if (info == XLOG_XACT_COMMIT)
4801 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
4803 xact_redo_commit(xlrec, record->xl_xid, lsn);
4805 else if (info == XLOG_XACT_ABORT)
4807 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
4809 xact_redo_abort(xlrec, record->xl_xid);
4811 else if (info == XLOG_XACT_PREPARE)
4813 /* the record contents are exactly the 2PC file */
4814 RecreateTwoPhaseFile(record->xl_xid,
4815 XLogRecGetData(record), record->xl_len);
4817 else if (info == XLOG_XACT_COMMIT_PREPARED)
4819 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
4821 xact_redo_commit(&xlrec->crec, xlrec->xid, lsn);
4822 RemoveTwoPhaseFile(xlrec->xid, false);
4824 else if (info == XLOG_XACT_ABORT_PREPARED)
4826 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
4828 xact_redo_abort(&xlrec->arec, xlrec->xid);
4829 RemoveTwoPhaseFile(xlrec->xid, false);
4831 else if (info == XLOG_XACT_ASSIGNMENT)
4833 xl_xact_assignment *xlrec = (xl_xact_assignment *) XLogRecGetData(record);
4835 if (standbyState >= STANDBY_INITIALIZED)
4836 ProcArrayApplyXidAssignment(xlrec->xtop,
4837 xlrec->nsubxacts, xlrec->xsub);
4840 elog(PANIC, "xact_redo: unknown op code %u", info);
4844 xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
4847 TransactionId *subxacts;
4849 subxacts = (TransactionId *) &xlrec->xnodes[xlrec->nrels];
4851 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4853 if (xlrec->nrels > 0)
4855 appendStringInfo(buf, "; rels:");
4856 for (i = 0; i < xlrec->nrels; i++)
4858 char *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);
4860 appendStringInfo(buf, " %s", path);
4864 if (xlrec->nsubxacts > 0)
4866 appendStringInfo(buf, "; subxacts:");
4867 for (i = 0; i < xlrec->nsubxacts; i++)
4868 appendStringInfo(buf, " %u", subxacts[i]);
4870 if (xlrec->nmsgs > 0)
4872 SharedInvalidationMessage *msgs;
4874 msgs = (SharedInvalidationMessage *) &subxacts[xlrec->nsubxacts];
4876 if (XactCompletionRelcacheInitFileInval(xlrec->xinfo))
4877 appendStringInfo(buf, "; relcache init file inval dbid %u tsid %u",
4878 xlrec->dbId, xlrec->tsId);
4880 appendStringInfo(buf, "; inval msgs:");
4881 for (i = 0; i < xlrec->nmsgs; i++)
4883 SharedInvalidationMessage *msg = &msgs[i];
4886 appendStringInfo(buf, " catcache %d", msg->id);
4887 else if (msg->id == SHAREDINVALCATALOG_ID)
4888 appendStringInfo(buf, " catalog %u", msg->cat.catId);
4889 else if (msg->id == SHAREDINVALRELCACHE_ID)
4890 appendStringInfo(buf, " relcache %u", msg->rc.relId);
4891 /* remaining cases not expected, but print something anyway */
4892 else if (msg->id == SHAREDINVALSMGR_ID)
4893 appendStringInfo(buf, " smgr");
4894 else if (msg->id == SHAREDINVALRELMAP_ID)
4895 appendStringInfo(buf, " relmap");
4897 appendStringInfo(buf, " unknown id %d", msg->id);
4903 xact_desc_commit_compact(StringInfo buf, xl_xact_commit_compact *xlrec)
4907 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4909 if (xlrec->nsubxacts > 0)
4911 appendStringInfo(buf, "; subxacts:");
4912 for (i = 0; i < xlrec->nsubxacts; i++)
4913 appendStringInfo(buf, " %u", xlrec->subxacts[i]);
4918 xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
4922 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4923 if (xlrec->nrels > 0)
4925 appendStringInfo(buf, "; rels:");
4926 for (i = 0; i < xlrec->nrels; i++)
4928 char *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);
4930 appendStringInfo(buf, " %s", path);
4934 if (xlrec->nsubxacts > 0)
4936 TransactionId *xacts = (TransactionId *)
4937 &xlrec->xnodes[xlrec->nrels];
4939 appendStringInfo(buf, "; subxacts:");
4940 for (i = 0; i < xlrec->nsubxacts; i++)
4941 appendStringInfo(buf, " %u", xacts[i]);
4946 xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
4950 appendStringInfo(buf, "subxacts:");
4952 for (i = 0; i < xlrec->nsubxacts; i++)
4953 appendStringInfo(buf, " %u", xlrec->xsub[i]);
4957 xact_desc(StringInfo buf, uint8 xl_info, char *rec)
4959 uint8 info = xl_info & ~XLR_INFO_MASK;
4961 if (info == XLOG_XACT_COMMIT_COMPACT)
4963 xl_xact_commit_compact *xlrec = (xl_xact_commit_compact *) rec;
4965 appendStringInfo(buf, "commit: ");
4966 xact_desc_commit_compact(buf, xlrec);
4968 else if (info == XLOG_XACT_COMMIT)
4970 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
4972 appendStringInfo(buf, "commit: ");
4973 xact_desc_commit(buf, xlrec);
4975 else if (info == XLOG_XACT_ABORT)
4977 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
4979 appendStringInfo(buf, "abort: ");
4980 xact_desc_abort(buf, xlrec);
4982 else if (info == XLOG_XACT_PREPARE)
4984 appendStringInfo(buf, "prepare");
4986 else if (info == XLOG_XACT_COMMIT_PREPARED)
4988 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
4990 appendStringInfo(buf, "commit prepared %u: ", xlrec->xid);
4991 xact_desc_commit(buf, &xlrec->crec);
4993 else if (info == XLOG_XACT_ABORT_PREPARED)
4995 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
4997 appendStringInfo(buf, "abort prepared %u: ", xlrec->xid);
4998 xact_desc_abort(buf, &xlrec->arec);
5000 else if (info == XLOG_XACT_ASSIGNMENT)
5002 xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
5005 * Note that we ignore the WAL record's xid, since we're more
5006 * interested in the top-level xid that issued the record and which
5007 * xids are being reported here.
5009 appendStringInfo(buf, "xid assignment xtop %u: ", xlrec->xtop);
5010 xact_desc_assignment(buf, xlrec);
5013 appendStringInfo(buf, "UNKNOWN");