1 /*-------------------------------------------------------------------------
4 * top level transaction system support routines
6 * See src/backend/access/transam/README for more information.
8 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
13 * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.297 2010/08/13 15:42:21 rhaas Exp $
15 *-------------------------------------------------------------------------
23 #include "access/multixact.h"
24 #include "access/subtrans.h"
25 #include "access/transam.h"
26 #include "access/twophase.h"
27 #include "access/xact.h"
28 #include "access/xlogutils.h"
29 #include "catalog/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 "storage/bufmgr.h"
40 #include "storage/fd.h"
41 #include "storage/lmgr.h"
42 #include "storage/procarray.h"
43 #include "storage/sinvaladt.h"
44 #include "storage/smgr.h"
45 #include "storage/standby.h"
46 #include "utils/combocid.h"
47 #include "utils/guc.h"
48 #include "utils/inval.h"
49 #include "utils/memutils.h"
50 #include "utils/relcache.h"
51 #include "utils/relmapper.h"
52 #include "utils/snapmgr.h"
57 * User-tweakable parameters
59 int DefaultXactIsoLevel = XACT_READ_COMMITTED;
62 bool DefaultXactReadOnly = false;
65 bool XactSyncCommit = true;
67 int CommitDelay = 0; /* precommit delay in microseconds */
68 int CommitSiblings = 5; /* # concurrent xacts needed to sleep */
71 * MyXactAccessedTempRel is set when a temporary relation is accessed.
72 * We don't allow PREPARE TRANSACTION in that case. (This is global
73 * so that it can be set from heapam.c.)
75 bool MyXactAccessedTempRel = false;
79 * transaction states - transaction state from server perspective
81 typedef enum TransState
83 TRANS_DEFAULT, /* idle */
84 TRANS_START, /* transaction starting */
85 TRANS_INPROGRESS, /* inside a valid transaction */
86 TRANS_COMMIT, /* commit in progress */
87 TRANS_ABORT, /* abort in progress */
88 TRANS_PREPARE /* prepare in progress */
92 * transaction block states - transaction state of client queries
94 * Note: the subtransaction states are used only for non-topmost
95 * transactions; the others appear only in the topmost transaction.
97 typedef enum TBlockState
99 /* not-in-transaction-block states */
100 TBLOCK_DEFAULT, /* idle */
101 TBLOCK_STARTED, /* running single-query transaction */
103 /* transaction block states */
104 TBLOCK_BEGIN, /* starting transaction block */
105 TBLOCK_INPROGRESS, /* live transaction */
106 TBLOCK_END, /* COMMIT received */
107 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
108 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
109 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
110 TBLOCK_PREPARE, /* live xact, PREPARE received */
112 /* subtransaction states */
113 TBLOCK_SUBBEGIN, /* starting a subtransaction */
114 TBLOCK_SUBINPROGRESS, /* live subtransaction */
115 TBLOCK_SUBEND, /* RELEASE received */
116 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
117 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
118 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
119 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
120 TBLOCK_SUBABORT_RESTART /* failed subxact, ROLLBACK TO received */
124 * transaction state structure
126 typedef struct TransactionStateData
128 TransactionId transactionId; /* my XID, or Invalid if none */
129 SubTransactionId subTransactionId; /* my subxact ID */
130 char *name; /* savepoint name, if any */
131 int savepointLevel; /* savepoint level */
132 TransState state; /* low-level state */
133 TBlockState blockState; /* high-level state */
134 int nestingLevel; /* transaction nesting depth */
135 int gucNestLevel; /* GUC context nesting depth */
136 MemoryContext curTransactionContext; /* my xact-lifetime context */
137 ResourceOwner curTransactionOwner; /* my query resources */
138 TransactionId *childXids; /* subcommitted child XIDs, in XID order */
139 int nChildXids; /* # of subcommitted child XIDs */
140 int maxChildXids; /* allocated size of childXids[] */
141 Oid prevUser; /* previous CurrentUserId setting */
142 int prevSecContext; /* previous SecurityRestrictionContext */
143 bool prevXactReadOnly; /* entry-time xact r/o state */
144 bool startedInRecovery; /* did we start in recovery? */
145 struct TransactionStateData *parent; /* back link to parent */
146 } TransactionStateData;
148 typedef TransactionStateData *TransactionState;
151 * CurrentTransactionState always points to the current transaction state
152 * block. It will point to TopTransactionStateData when not in a
153 * transaction at all, or when in a top-level transaction.
155 static TransactionStateData TopTransactionStateData = {
156 0, /* transaction id */
157 0, /* subtransaction id */
158 NULL, /* savepoint name */
159 0, /* savepoint level */
160 TRANS_DEFAULT, /* transaction state */
161 TBLOCK_DEFAULT, /* transaction block state from the client
163 0, /* transaction nesting depth */
164 0, /* GUC context nesting depth */
165 NULL, /* cur transaction context */
166 NULL, /* cur transaction resource owner */
167 NULL, /* subcommitted child Xids */
168 0, /* # of subcommitted child Xids */
169 0, /* allocated size of childXids[] */
170 InvalidOid, /* previous CurrentUserId setting */
171 0, /* previous SecurityRestrictionContext */
172 false, /* entry-time xact r/o state */
173 false, /* startedInRecovery */
174 NULL /* link to parent state block */
178 * unreportedXids holds XIDs of all subtransactions that have not yet been
179 * reported in a XLOG_XACT_ASSIGNMENT record.
181 static int nUnreportedXids;
182 static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS];
184 static TransactionState CurrentTransactionState = &TopTransactionStateData;
187 * The subtransaction ID and command ID assignment counters are global
188 * to a whole transaction, so we do not keep them in the state stack.
190 static SubTransactionId currentSubTransactionId;
191 static CommandId currentCommandId;
192 static bool currentCommandIdUsed;
195 * xactStartTimestamp is the value of transaction_timestamp().
196 * stmtStartTimestamp is the value of statement_timestamp().
197 * xactStopTimestamp is the time at which we log a commit or abort WAL record.
198 * These do not change as we enter and exit subtransactions, so we don't
199 * keep them inside the TransactionState stack.
201 static TimestampTz xactStartTimestamp;
202 static TimestampTz stmtStartTimestamp;
203 static TimestampTz xactStopTimestamp;
206 * GID to be used for preparing the current transaction. This is also
207 * global to a whole transaction, so we don't keep it in the state stack.
209 static char *prepareGID;
212 * Some commands want to force synchronous commit.
214 static bool forceSyncCommit = false;
217 * Private context for transaction-abort work --- we reserve space for this
218 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
219 * when we've run out of memory.
221 static MemoryContext TransactionAbortContext = NULL;
224 * List of add-on start- and end-of-xact callbacks
226 typedef struct XactCallbackItem
228 struct XactCallbackItem *next;
229 XactCallback callback;
233 static XactCallbackItem *Xact_callbacks = NULL;
236 * List of add-on start- and end-of-subxact callbacks
238 typedef struct SubXactCallbackItem
240 struct SubXactCallbackItem *next;
241 SubXactCallback callback;
243 } SubXactCallbackItem;
245 static SubXactCallbackItem *SubXact_callbacks = NULL;
248 /* local function prototypes */
249 static void AssignTransactionId(TransactionState s);
250 static void AbortTransaction(void);
251 static void AtAbort_Memory(void);
252 static void AtCleanup_Memory(void);
253 static void AtAbort_ResourceOwner(void);
254 static void AtCCI_LocalCache(void);
255 static void AtCommit_Memory(void);
256 static void AtStart_Cache(void);
257 static void AtStart_Memory(void);
258 static void AtStart_ResourceOwner(void);
259 static void CallXactCallbacks(XactEvent event);
260 static void CallSubXactCallbacks(SubXactEvent event,
261 SubTransactionId mySubid,
262 SubTransactionId parentSubid);
263 static void CleanupTransaction(void);
264 static void CommitTransaction(void);
265 static TransactionId RecordTransactionAbort(bool isSubXact);
266 static void StartTransaction(void);
268 static void StartSubTransaction(void);
269 static void CommitSubTransaction(void);
270 static void AbortSubTransaction(void);
271 static void CleanupSubTransaction(void);
272 static void PushTransaction(void);
273 static void PopTransaction(void);
275 static void AtSubAbort_Memory(void);
276 static void AtSubCleanup_Memory(void);
277 static void AtSubAbort_ResourceOwner(void);
278 static void AtSubCommit_Memory(void);
279 static void AtSubStart_Memory(void);
280 static void AtSubStart_ResourceOwner(void);
282 static void ShowTransactionState(const char *str);
283 static void ShowTransactionStateRec(TransactionState state);
284 static const char *BlockStateAsString(TBlockState blockState);
285 static const char *TransStateAsString(TransState state);
288 /* ----------------------------------------------------------------
289 * transaction state accessors
290 * ----------------------------------------------------------------
296 * This returns true if we are inside a valid transaction; that is,
297 * it is safe to initiate database access, take heavyweight locks, etc.
300 IsTransactionState(void)
302 TransactionState s = CurrentTransactionState;
305 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
306 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
307 * TRANS_PREPARE since it might be too soon or too late within those
308 * transition states to do anything interesting. Hence, the only "valid"
309 * state is TRANS_INPROGRESS.
311 return (s->state == TRANS_INPROGRESS);
315 * IsAbortedTransactionBlockState
317 * This returns true if we are within an aborted transaction block.
320 IsAbortedTransactionBlockState(void)
322 TransactionState s = CurrentTransactionState;
324 if (s->blockState == TBLOCK_ABORT ||
325 s->blockState == TBLOCK_SUBABORT)
333 * GetTopTransactionId
335 * This will return the XID of the main transaction, assigning one if
336 * it's not yet set. Be careful to call this only inside a valid xact.
339 GetTopTransactionId(void)
341 if (!TransactionIdIsValid(TopTransactionStateData.transactionId))
342 AssignTransactionId(&TopTransactionStateData);
343 return TopTransactionStateData.transactionId;
347 * GetTopTransactionIdIfAny
349 * This will return the XID of the main transaction, if one is assigned.
350 * It will return InvalidTransactionId if we are not currently inside a
351 * transaction, or inside a transaction that hasn't yet been assigned an XID.
354 GetTopTransactionIdIfAny(void)
356 return TopTransactionStateData.transactionId;
360 * GetCurrentTransactionId
362 * This will return the XID of the current transaction (main or sub
363 * transaction), assigning one if it's not yet set. Be careful to call this
364 * only inside a valid xact.
367 GetCurrentTransactionId(void)
369 TransactionState s = CurrentTransactionState;
371 if (!TransactionIdIsValid(s->transactionId))
372 AssignTransactionId(s);
373 return s->transactionId;
377 * GetCurrentTransactionIdIfAny
379 * This will return the XID of the current sub xact, if one is assigned.
380 * It will return InvalidTransactionId if we are not currently inside a
381 * transaction, or inside a transaction that hasn't been assigned an XID yet.
384 GetCurrentTransactionIdIfAny(void)
386 return CurrentTransactionState->transactionId;
391 * AssignTransactionId
393 * Assigns a new permanent XID to the given TransactionState.
394 * We do not assign XIDs to transactions until/unless this is called.
395 * Also, any parent TransactionStates that don't yet have XIDs are assigned
396 * one; this maintains the invariant that a child transaction has an XID
397 * following its parent's.
400 AssignTransactionId(TransactionState s)
402 bool isSubXact = (s->parent != NULL);
403 ResourceOwner currentOwner;
405 /* Assert that caller didn't screw up */
406 Assert(!TransactionIdIsValid(s->transactionId));
407 Assert(s->state == TRANS_INPROGRESS);
410 * Ensure parent(s) have XIDs, so that a child always has an XID later
411 * than its parent. Musn't recurse here, or we might get a stack overflow
412 * if we're at the bottom of a huge stack of subtransactions none of which
415 if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
417 TransactionState p = s->parent;
418 TransactionState *parents;
419 size_t parentOffset = 0;
421 parents = palloc(sizeof(TransactionState) * s->nestingLevel);
422 while (p != NULL && !TransactionIdIsValid(p->transactionId))
424 parents[parentOffset++] = p;
429 * This is technically a recursive call, but the recursion will
430 * never be more than one layer deep.
432 while (parentOffset != 0)
433 AssignTransactionId(parents[--parentOffset]);
439 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
441 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
442 * shared storage other than PG_PROC; because if there's no room for it in
443 * PG_PROC, the subtrans entry is needed to ensure that other backends see
444 * the Xid as "running". See GetNewTransactionId.
446 s->transactionId = GetNewTransactionId(isSubXact);
449 SubTransSetParent(s->transactionId, s->parent->transactionId, false);
452 * Acquire lock on the transaction XID. (We assume this cannot block.) We
453 * have to ensure that the lock is assigned to the transaction's own
456 currentOwner = CurrentResourceOwner;
459 CurrentResourceOwner = s->curTransactionOwner;
460 XactLockTableInsert(s->transactionId);
464 /* Ensure CurrentResourceOwner is restored on error */
465 CurrentResourceOwner = currentOwner;
469 CurrentResourceOwner = currentOwner;
472 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
473 * top-level transaction we issue a WAL record for the assignment. We
474 * include the top-level xid and all the subxids that have not yet been
475 * reported using XLOG_XACT_ASSIGNMENT records.
477 * This is required to limit the amount of shared memory required in a hot
478 * standby server to keep track of in-progress XIDs. See notes for
479 * RecordKnownAssignedTransactionIds().
481 * We don't keep track of the immediate parent of each subxid, only the
482 * top-level transaction that each subxact belongs to. This is correct in
483 * recovery only because aborted subtransactions are separately WAL
486 if (isSubXact && XLogStandbyInfoActive())
488 unreportedXids[nUnreportedXids] = s->transactionId;
492 * ensure this test matches similar one in
493 * RecoverPreparedTransactions()
495 if (nUnreportedXids >= PGPROC_MAX_CACHED_SUBXIDS)
497 XLogRecData rdata[2];
498 xl_xact_assignment xlrec;
501 * xtop is always set by now because we recurse up transaction
502 * stack to the highest unassigned xid and then come back down
504 xlrec.xtop = GetTopTransactionId();
505 Assert(TransactionIdIsValid(xlrec.xtop));
506 xlrec.nsubxacts = nUnreportedXids;
508 rdata[0].data = (char *) &xlrec;
509 rdata[0].len = MinSizeOfXactAssignment;
510 rdata[0].buffer = InvalidBuffer;
511 rdata[0].next = &rdata[1];
513 rdata[1].data = (char *) unreportedXids;
514 rdata[1].len = PGPROC_MAX_CACHED_SUBXIDS * sizeof(TransactionId);
515 rdata[1].buffer = InvalidBuffer;
516 rdata[1].next = NULL;
518 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT, rdata);
526 * GetCurrentSubTransactionId
529 GetCurrentSubTransactionId(void)
531 TransactionState s = CurrentTransactionState;
533 return s->subTransactionId;
538 * GetCurrentCommandId
540 * "used" must be TRUE if the caller intends to use the command ID to mark
541 * inserted/updated/deleted tuples. FALSE means the ID is being fetched
542 * for read-only purposes (ie, as a snapshot validity cutoff). See
543 * CommandCounterIncrement() for discussion.
546 GetCurrentCommandId(bool used)
548 /* this is global to a transaction, not subtransaction-local */
550 currentCommandIdUsed = true;
551 return currentCommandId;
555 * GetCurrentTransactionStartTimestamp
558 GetCurrentTransactionStartTimestamp(void)
560 return xactStartTimestamp;
564 * GetCurrentStatementStartTimestamp
567 GetCurrentStatementStartTimestamp(void)
569 return stmtStartTimestamp;
573 * GetCurrentTransactionStopTimestamp
575 * We return current time if the transaction stop time hasn't been set
576 * (which can happen if we decide we don't need to log an XLOG record).
579 GetCurrentTransactionStopTimestamp(void)
581 if (xactStopTimestamp != 0)
582 return xactStopTimestamp;
583 return GetCurrentTimestamp();
587 * SetCurrentStatementStartTimestamp
590 SetCurrentStatementStartTimestamp(void)
592 stmtStartTimestamp = GetCurrentTimestamp();
596 * SetCurrentTransactionStopTimestamp
599 SetCurrentTransactionStopTimestamp(void)
601 xactStopTimestamp = GetCurrentTimestamp();
605 * GetCurrentTransactionNestLevel
607 * Note: this will return zero when not inside any transaction, one when
608 * inside a top-level transaction, etc.
611 GetCurrentTransactionNestLevel(void)
613 TransactionState s = CurrentTransactionState;
615 return s->nestingLevel;
620 * TransactionIdIsCurrentTransactionId
623 TransactionIdIsCurrentTransactionId(TransactionId xid)
628 * We always say that BootstrapTransactionId is "not my transaction ID"
629 * even when it is (ie, during bootstrap). Along with the fact that
630 * transam.c always treats BootstrapTransactionId as already committed,
631 * this causes the tqual.c routines to see all tuples as committed, which
632 * is what we need during bootstrap. (Bootstrap mode only inserts tuples,
633 * it never updates or deletes them, so all tuples can be presumed good
636 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
637 * not my transaction ID, so we can just return "false" immediately for
638 * any non-normal XID.
640 if (!TransactionIdIsNormal(xid))
644 * We will return true for the Xid of the current subtransaction, any of
645 * its subcommitted children, any of its parents, or any of their
646 * previously subcommitted children. However, a transaction being aborted
647 * is no longer "current", even though it may still have an entry on the
650 for (s = CurrentTransactionState; s != NULL; s = s->parent)
655 if (s->state == TRANS_ABORT)
657 if (!TransactionIdIsValid(s->transactionId))
658 continue; /* it can't have any child XIDs either */
659 if (TransactionIdEquals(xid, s->transactionId))
661 /* As the childXids array is ordered, we can use binary search */
663 high = s->nChildXids - 1;
669 middle = low + (high - low) / 2;
670 probe = s->childXids[middle];
671 if (TransactionIdEquals(probe, xid))
673 else if (TransactionIdPrecedes(probe, xid))
684 * TransactionStartedDuringRecovery
686 * Returns true if the current transaction started while recovery was still
687 * in progress. Recovery might have ended since so RecoveryInProgress() might
688 * return false already.
691 TransactionStartedDuringRecovery(void)
693 return CurrentTransactionState->startedInRecovery;
697 * CommandCounterIncrement
700 CommandCounterIncrement(void)
703 * If the current value of the command counter hasn't been "used" to mark
704 * tuples, we need not increment it, since there's no need to distinguish
705 * a read-only command from others. This helps postpone command counter
706 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
708 if (currentCommandIdUsed)
710 currentCommandId += 1;
711 if (currentCommandId == FirstCommandId) /* check for overflow */
713 currentCommandId -= 1;
715 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
716 errmsg("cannot have more than 2^32-1 commands in a transaction")));
718 currentCommandIdUsed = false;
720 /* Propagate new command ID into static snapshots */
721 SnapshotSetCommandId(currentCommandId);
724 * Make any catalog changes done by the just-completed command visible
725 * in the local syscache. We obviously don't need to do this after a
726 * read-only command. (But see hacks in inval.c to make real sure we
727 * don't think a command that queued inval messages was read-only.)
733 * Make any other backends' catalog changes visible to me.
735 * XXX this is probably in the wrong place: CommandCounterIncrement should
736 * be purely a local operation, most likely. However fooling with this
737 * will affect asynchronous cross-backend interactions, which doesn't seem
738 * like a wise thing to do in late beta, so save improving this for
739 * another day - tgl 2007-11-30
747 * Interface routine to allow commands to force a synchronous commit of the
748 * current top-level transaction
751 ForceSyncCommit(void)
753 forceSyncCommit = true;
757 /* ----------------------------------------------------------------
758 * StartTransaction stuff
759 * ----------------------------------------------------------------
768 AcceptInvalidationMessages();
777 TransactionState s = CurrentTransactionState;
780 * If this is the first time through, create a private context for
781 * AbortTransaction to work in. By reserving some space now, we can
782 * insulate AbortTransaction from out-of-memory scenarios. Like
783 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
784 * size, so that space will be reserved immediately.
786 if (TransactionAbortContext == NULL)
787 TransactionAbortContext =
788 AllocSetContextCreate(TopMemoryContext,
789 "TransactionAbortContext",
795 * We shouldn't have a transaction context already.
797 Assert(TopTransactionContext == NULL);
800 * Create a toplevel context for the transaction.
802 TopTransactionContext =
803 AllocSetContextCreate(TopMemoryContext,
804 "TopTransactionContext",
805 ALLOCSET_DEFAULT_MINSIZE,
806 ALLOCSET_DEFAULT_INITSIZE,
807 ALLOCSET_DEFAULT_MAXSIZE);
810 * In a top-level transaction, CurTransactionContext is the same as
811 * TopTransactionContext.
813 CurTransactionContext = TopTransactionContext;
814 s->curTransactionContext = CurTransactionContext;
816 /* Make the CurTransactionContext active. */
817 MemoryContextSwitchTo(CurTransactionContext);
821 * AtStart_ResourceOwner
824 AtStart_ResourceOwner(void)
826 TransactionState s = CurrentTransactionState;
829 * We shouldn't have a transaction resource owner already.
831 Assert(TopTransactionResourceOwner == NULL);
834 * Create a toplevel resource owner for the transaction.
836 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
838 TopTransactionResourceOwner = s->curTransactionOwner;
839 CurTransactionResourceOwner = s->curTransactionOwner;
840 CurrentResourceOwner = s->curTransactionOwner;
843 /* ----------------------------------------------------------------
844 * StartSubTransaction stuff
845 * ----------------------------------------------------------------
852 AtSubStart_Memory(void)
854 TransactionState s = CurrentTransactionState;
856 Assert(CurTransactionContext != NULL);
859 * Create a CurTransactionContext, which will be used to hold data that
860 * survives subtransaction commit but disappears on subtransaction abort.
861 * We make it a child of the immediate parent's CurTransactionContext.
863 CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
864 "CurTransactionContext",
865 ALLOCSET_DEFAULT_MINSIZE,
866 ALLOCSET_DEFAULT_INITSIZE,
867 ALLOCSET_DEFAULT_MAXSIZE);
868 s->curTransactionContext = CurTransactionContext;
870 /* Make the CurTransactionContext active. */
871 MemoryContextSwitchTo(CurTransactionContext);
875 * AtSubStart_ResourceOwner
878 AtSubStart_ResourceOwner(void)
880 TransactionState s = CurrentTransactionState;
882 Assert(s->parent != NULL);
885 * Create a resource owner for the subtransaction. We make it a child of
886 * the immediate parent's resource owner.
888 s->curTransactionOwner =
889 ResourceOwnerCreate(s->parent->curTransactionOwner,
892 CurTransactionResourceOwner = s->curTransactionOwner;
893 CurrentResourceOwner = s->curTransactionOwner;
896 /* ----------------------------------------------------------------
897 * CommitTransaction stuff
898 * ----------------------------------------------------------------
902 * RecordTransactionCommit
904 * Returns latest XID among xact and its children, or InvalidTransactionId
905 * if the xact has no XID. (We compute that here just because it's easier.)
908 RecordTransactionCommit(void)
910 TransactionId xid = GetTopTransactionIdIfAny();
911 bool markXidCommitted = TransactionIdIsValid(xid);
912 TransactionId latestXid = InvalidTransactionId;
917 TransactionId *children;
919 SharedInvalidationMessage *invalMessages = NULL;
920 bool RelcacheInitFileInval = false;
922 /* Get data needed for commit record */
923 nrels = smgrGetPendingDeletes(true, &rels, &haveNonTemp);
924 nchildren = xactGetCommittedChildren(&children);
925 if (XLogStandbyInfoActive())
926 nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
927 &RelcacheInitFileInval);
930 * If we haven't been assigned an XID yet, we neither can, nor do we want
931 * to write a COMMIT record.
933 if (!markXidCommitted)
936 * We expect that every smgrscheduleunlink is followed by a catalog
937 * update, and hence XID assignment, so we shouldn't get here with any
938 * pending deletes. Use a real test not just an Assert to check this,
939 * since it's a bit fragile.
942 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
944 /* Can't have child XIDs either; AssignTransactionId enforces this */
945 Assert(nchildren == 0);
948 * If we didn't create XLOG entries, we're done here; otherwise we
949 * should flush those entries the same as a commit record. (An
950 * example of a possible record that wouldn't cause an XID to be
951 * assigned is a sequence advance record due to nextval() --- we want
952 * to flush that to disk before reporting commit.)
954 if (XactLastRecEnd.xrecoff == 0)
960 * Begin commit critical section and insert the commit XLOG record.
962 XLogRecData rdata[4];
964 xl_xact_commit xlrec;
966 /* Tell bufmgr and smgr to prepare for commit */
970 * Set flags required for recovery processing of commits.
973 if (RelcacheInitFileInval)
974 xlrec.xinfo |= XACT_COMPLETION_UPDATE_RELCACHE_FILE;
976 xlrec.xinfo |= XACT_COMPLETION_FORCE_SYNC_COMMIT;
978 xlrec.dbId = MyDatabaseId;
979 xlrec.tsId = MyDatabaseTableSpace;
982 * Mark ourselves as within our "commit critical section". This
983 * forces any concurrent checkpoint to wait until we've updated
984 * pg_clog. Without this, it is possible for the checkpoint to set
985 * REDO after the XLOG record but fail to flush the pg_clog update to
986 * disk, leading to loss of the transaction commit if the system
987 * crashes a little later.
989 * Note: we could, but don't bother to, set this flag in
990 * RecordTransactionAbort. That's because loss of a transaction abort
991 * is noncritical; the presumption would be that it aborted, anyway.
993 * It's safe to change the inCommit flag of our own backend without
994 * holding the ProcArrayLock, since we're the only one modifying it.
995 * This makes checkpoint's determination of which xacts are inCommit a
996 * bit fuzzy, but it doesn't matter.
998 START_CRIT_SECTION();
999 MyProc->inCommit = true;
1001 SetCurrentTransactionStopTimestamp();
1002 xlrec.xact_time = xactStopTimestamp;
1003 xlrec.nrels = nrels;
1004 xlrec.nsubxacts = nchildren;
1005 xlrec.nmsgs = nmsgs;
1006 rdata[0].data = (char *) (&xlrec);
1007 rdata[0].len = MinSizeOfXactCommit;
1008 rdata[0].buffer = InvalidBuffer;
1009 /* dump rels to delete */
1012 rdata[0].next = &(rdata[1]);
1013 rdata[1].data = (char *) rels;
1014 rdata[1].len = nrels * sizeof(RelFileNode);
1015 rdata[1].buffer = InvalidBuffer;
1018 /* dump committed child Xids */
1021 rdata[lastrdata].next = &(rdata[2]);
1022 rdata[2].data = (char *) children;
1023 rdata[2].len = nchildren * sizeof(TransactionId);
1024 rdata[2].buffer = InvalidBuffer;
1027 /* dump shared cache invalidation messages */
1030 rdata[lastrdata].next = &(rdata[3]);
1031 rdata[3].data = (char *) invalMessages;
1032 rdata[3].len = nmsgs * sizeof(SharedInvalidationMessage);
1033 rdata[3].buffer = InvalidBuffer;
1036 rdata[lastrdata].next = NULL;
1038 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
1042 * Check if we want to commit asynchronously. If the user has set
1043 * synchronous_commit = off, and we're not doing cleanup of any non-temp
1044 * rels nor committing any command that wanted to force sync commit, then
1045 * we can defer flushing XLOG. (We must not allow asynchronous commit if
1046 * there are any non-temp tables to be deleted, because we might delete
1047 * the files before the COMMIT record is flushed to disk. We do allow
1048 * asynchronous commit if all to-be-deleted tables are temporary though,
1049 * since they are lost anyway if we crash.)
1051 if (XactSyncCommit || forceSyncCommit || haveNonTemp)
1054 * Synchronous commit case:
1056 * Sleep before flush! So we can flush more than one commit records
1057 * per single fsync. (The idea is some other backend may do the
1058 * XLogFlush while we're sleeping. This needs work still, because on
1059 * most Unixen, the minimum select() delay is 10msec or more, which is
1062 * We do not sleep if enableFsync is not turned on, nor if there are
1063 * fewer than CommitSiblings other backends with active transactions.
1065 if (CommitDelay > 0 && enableFsync &&
1066 CountActiveBackends() >= CommitSiblings)
1067 pg_usleep(CommitDelay);
1069 XLogFlush(XactLastRecEnd);
1072 * Now we may update the CLOG, if we wrote a COMMIT record above
1074 if (markXidCommitted)
1075 TransactionIdCommitTree(xid, nchildren, children);
1080 * Asynchronous commit case:
1082 * This enables possible committed transaction loss in the case of a
1083 * postmaster crash because WAL buffers are left unwritten. Ideally we
1084 * could issue the WAL write without the fsync, but some
1085 * wal_sync_methods do not allow separate write/fsync.
1087 * Report the latest async commit LSN, so that the WAL writer knows to
1088 * flush this commit.
1090 XLogSetAsyncXactLSN(XactLastRecEnd);
1093 * We must not immediately update the CLOG, since we didn't flush the
1094 * XLOG. Instead, we store the LSN up to which the XLOG must be
1095 * flushed before the CLOG may be updated.
1097 if (markXidCommitted)
1098 TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1102 * If we entered a commit critical section, leave it now, and let
1103 * checkpoints proceed.
1105 if (markXidCommitted)
1107 MyProc->inCommit = false;
1111 /* Compute latestXid while we have the child XIDs handy */
1112 latestXid = TransactionIdLatest(xid, nchildren, children);
1114 /* Reset XactLastRecEnd until the next transaction writes something */
1115 XactLastRecEnd.xrecoff = 0;
1118 /* Clean up local data */
1130 AtCCI_LocalCache(void)
1133 * Make any pending relation map changes visible. We must do this before
1134 * processing local sinval messages, so that the map changes will get
1135 * reflected into the relcache when relcache invals are processed.
1137 AtCCI_RelationMap();
1140 * Make catalog changes visible to me for the next command.
1142 CommandEndInvalidationMessages();
1149 AtCommit_Memory(void)
1152 * Now that we're "out" of a transaction, have the system allocate things
1153 * in the top memory context instead of per-transaction contexts.
1155 MemoryContextSwitchTo(TopMemoryContext);
1158 * Release all transaction-local memory.
1160 Assert(TopTransactionContext != NULL);
1161 MemoryContextDelete(TopTransactionContext);
1162 TopTransactionContext = NULL;
1163 CurTransactionContext = NULL;
1164 CurrentTransactionState->curTransactionContext = NULL;
1167 /* ----------------------------------------------------------------
1168 * CommitSubTransaction stuff
1169 * ----------------------------------------------------------------
1173 * AtSubCommit_Memory
1176 AtSubCommit_Memory(void)
1178 TransactionState s = CurrentTransactionState;
1180 Assert(s->parent != NULL);
1182 /* Return to parent transaction level's memory context. */
1183 CurTransactionContext = s->parent->curTransactionContext;
1184 MemoryContextSwitchTo(CurTransactionContext);
1187 * Ordinarily we cannot throw away the child's CurTransactionContext,
1188 * since the data it contains will be needed at upper commit. However, if
1189 * there isn't actually anything in it, we can throw it away. This avoids
1190 * a small memory leak in the common case of "trivial" subxacts.
1192 if (MemoryContextIsEmpty(s->curTransactionContext))
1194 MemoryContextDelete(s->curTransactionContext);
1195 s->curTransactionContext = NULL;
1200 * AtSubCommit_childXids
1202 * Pass my own XID and my child XIDs up to my parent as committed children.
1205 AtSubCommit_childXids(void)
1207 TransactionState s = CurrentTransactionState;
1210 Assert(s->parent != NULL);
1213 * The parent childXids array will need to hold my XID and all my
1214 * childXids, in addition to the XIDs already there.
1216 new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1218 /* Allocate or enlarge the parent array if necessary */
1219 if (s->parent->maxChildXids < new_nChildXids)
1221 int new_maxChildXids;
1222 TransactionId *new_childXids;
1225 * Make it 2x what's needed right now, to avoid having to enlarge it
1226 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1227 * is what ensures that we don't need to worry about integer overflow
1228 * here or in the calculation of new_nChildXids.)
1230 new_maxChildXids = Min(new_nChildXids * 2,
1231 (int) (MaxAllocSize / sizeof(TransactionId)));
1233 if (new_maxChildXids < new_nChildXids)
1235 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1236 errmsg("maximum number of committed subtransactions (%d) exceeded",
1237 (int) (MaxAllocSize / sizeof(TransactionId)))));
1240 * We keep the child-XID arrays in TopTransactionContext; this avoids
1241 * setting up child-transaction contexts for what might be just a few
1242 * bytes of grandchild XIDs.
1244 if (s->parent->childXids == NULL)
1246 MemoryContextAlloc(TopTransactionContext,
1247 new_maxChildXids * sizeof(TransactionId));
1249 new_childXids = repalloc(s->parent->childXids,
1250 new_maxChildXids * sizeof(TransactionId));
1252 s->parent->childXids = new_childXids;
1253 s->parent->maxChildXids = new_maxChildXids;
1257 * Copy all my XIDs to parent's array.
1259 * Note: We rely on the fact that the XID of a child always follows that
1260 * of its parent. By copying the XID of this subtransaction before the
1261 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1262 * all XIDs already in the array belong to subtransactions started and
1263 * subcommitted before us, so their XIDs must precede ours.
1265 s->parent->childXids[s->parent->nChildXids] = s->transactionId;
1267 if (s->nChildXids > 0)
1268 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1270 s->nChildXids * sizeof(TransactionId));
1272 s->parent->nChildXids = new_nChildXids;
1274 /* Release child's array to avoid leakage */
1275 if (s->childXids != NULL)
1276 pfree(s->childXids);
1277 /* We must reset these to avoid double-free if fail later in commit */
1278 s->childXids = NULL;
1280 s->maxChildXids = 0;
1283 /* ----------------------------------------------------------------
1284 * AbortTransaction stuff
1285 * ----------------------------------------------------------------
1289 * RecordTransactionAbort
1291 * Returns latest XID among xact and its children, or InvalidTransactionId
1292 * if the xact has no XID. (We compute that here just because it's easier.)
1294 static TransactionId
1295 RecordTransactionAbort(bool isSubXact)
1297 TransactionId xid = GetCurrentTransactionIdIfAny();
1298 TransactionId latestXid;
1302 TransactionId *children;
1303 XLogRecData rdata[3];
1305 xl_xact_abort xlrec;
1308 * If we haven't been assigned an XID, nobody will care whether we aborted
1309 * or not. Hence, we're done in that case. It does not matter if we have
1310 * rels to delete (note that this routine is not responsible for actually
1311 * deleting 'em). We cannot have any child XIDs, either.
1313 if (!TransactionIdIsValid(xid))
1315 /* Reset XactLastRecEnd until the next transaction writes something */
1317 XactLastRecEnd.xrecoff = 0;
1318 return InvalidTransactionId;
1322 * We have a valid XID, so we should write an ABORT record for it.
1324 * We do not flush XLOG to disk here, since the default assumption after a
1325 * crash would be that we aborted, anyway. For the same reason, we don't
1326 * need to worry about interlocking against checkpoint start.
1330 * Check that we haven't aborted halfway through RecordTransactionCommit.
1332 if (TransactionIdDidCommit(xid))
1333 elog(PANIC, "cannot abort transaction %u, it was already committed",
1336 /* Fetch the data we need for the abort record */
1337 nrels = smgrGetPendingDeletes(false, &rels, NULL);
1338 nchildren = xactGetCommittedChildren(&children);
1340 /* XXX do we really need a critical section here? */
1341 START_CRIT_SECTION();
1343 /* Write the ABORT record */
1345 xlrec.xact_time = GetCurrentTimestamp();
1348 SetCurrentTransactionStopTimestamp();
1349 xlrec.xact_time = xactStopTimestamp;
1351 xlrec.nrels = nrels;
1352 xlrec.nsubxacts = nchildren;
1353 rdata[0].data = (char *) (&xlrec);
1354 rdata[0].len = MinSizeOfXactAbort;
1355 rdata[0].buffer = InvalidBuffer;
1356 /* dump rels to delete */
1359 rdata[0].next = &(rdata[1]);
1360 rdata[1].data = (char *) rels;
1361 rdata[1].len = nrels * sizeof(RelFileNode);
1362 rdata[1].buffer = InvalidBuffer;
1365 /* dump committed child Xids */
1368 rdata[lastrdata].next = &(rdata[2]);
1369 rdata[2].data = (char *) children;
1370 rdata[2].len = nchildren * sizeof(TransactionId);
1371 rdata[2].buffer = InvalidBuffer;
1374 rdata[lastrdata].next = NULL;
1376 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
1379 * Report the latest async abort LSN, so that the WAL writer knows to
1380 * flush this abort. There's nothing to be gained by delaying this, since
1381 * WALWriter may as well do this when it can. This is important with
1382 * streaming replication because if we don't flush WAL regularly we will
1383 * find that large aborts leave us with a long backlog for when commits
1384 * occur after the abort, increasing our window of data loss should
1385 * problems occur at that point.
1388 XLogSetAsyncXactLSN(XactLastRecEnd);
1391 * Mark the transaction aborted in clog. This is not absolutely necessary
1392 * but we may as well do it while we are here; also, in the subxact case
1393 * it is helpful because XactLockTableWait makes use of it to avoid
1394 * waiting for already-aborted subtransactions. It is OK to do it without
1395 * having flushed the ABORT record to disk, because in event of a crash
1396 * we'd be assumed to have aborted anyway.
1398 TransactionIdAbortTree(xid, nchildren, children);
1402 /* Compute latestXid while we have the child XIDs handy */
1403 latestXid = TransactionIdLatest(xid, nchildren, children);
1406 * If we're aborting a subtransaction, we can immediately remove failed
1407 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1408 * subxacts, because we already have the child XID array at hand. For
1409 * main xacts, the equivalent happens just after this function returns.
1412 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1414 /* Reset XactLastRecEnd until the next transaction writes something */
1416 XactLastRecEnd.xrecoff = 0;
1418 /* And clean up local data */
1429 AtAbort_Memory(void)
1432 * Switch into TransactionAbortContext, which should have some free space
1433 * even if nothing else does. We'll work in this context until we've
1434 * finished cleaning up.
1436 * It is barely possible to get here when we've not been able to create
1437 * TransactionAbortContext yet; if so use TopMemoryContext.
1439 if (TransactionAbortContext != NULL)
1440 MemoryContextSwitchTo(TransactionAbortContext);
1442 MemoryContextSwitchTo(TopMemoryContext);
1449 AtSubAbort_Memory(void)
1451 Assert(TransactionAbortContext != NULL);
1453 MemoryContextSwitchTo(TransactionAbortContext);
1458 * AtAbort_ResourceOwner
1461 AtAbort_ResourceOwner(void)
1464 * Make sure we have a valid ResourceOwner, if possible (else it will be
1465 * NULL, which is OK)
1467 CurrentResourceOwner = TopTransactionResourceOwner;
1471 * AtSubAbort_ResourceOwner
1474 AtSubAbort_ResourceOwner(void)
1476 TransactionState s = CurrentTransactionState;
1478 /* Make sure we have a valid ResourceOwner */
1479 CurrentResourceOwner = s->curTransactionOwner;
1484 * AtSubAbort_childXids
1487 AtSubAbort_childXids(void)
1489 TransactionState s = CurrentTransactionState;
1492 * We keep the child-XID arrays in TopTransactionContext (see
1493 * AtSubCommit_childXids). This means we'd better free the array
1494 * explicitly at abort to avoid leakage.
1496 if (s->childXids != NULL)
1497 pfree(s->childXids);
1498 s->childXids = NULL;
1500 s->maxChildXids = 0;
1503 * We could prune the unreportedXids array here. But we don't bother. That
1504 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1505 * would likely introduce more CPU time into the more common paths, so we
1506 * choose not to do that.
1510 /* ----------------------------------------------------------------
1511 * CleanupTransaction stuff
1512 * ----------------------------------------------------------------
1519 AtCleanup_Memory(void)
1521 Assert(CurrentTransactionState->parent == NULL);
1524 * Now that we're "out" of a transaction, have the system allocate things
1525 * in the top memory context instead of per-transaction contexts.
1527 MemoryContextSwitchTo(TopMemoryContext);
1530 * Clear the special abort context for next time.
1532 if (TransactionAbortContext != NULL)
1533 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1536 * Release all transaction-local memory.
1538 if (TopTransactionContext != NULL)
1539 MemoryContextDelete(TopTransactionContext);
1540 TopTransactionContext = NULL;
1541 CurTransactionContext = NULL;
1542 CurrentTransactionState->curTransactionContext = NULL;
1546 /* ----------------------------------------------------------------
1547 * CleanupSubTransaction stuff
1548 * ----------------------------------------------------------------
1552 * AtSubCleanup_Memory
1555 AtSubCleanup_Memory(void)
1557 TransactionState s = CurrentTransactionState;
1559 Assert(s->parent != NULL);
1561 /* Make sure we're not in an about-to-be-deleted context */
1562 MemoryContextSwitchTo(s->parent->curTransactionContext);
1563 CurTransactionContext = s->parent->curTransactionContext;
1566 * Clear the special abort context for next time.
1568 if (TransactionAbortContext != NULL)
1569 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1572 * Delete the subxact local memory contexts. Its CurTransactionContext can
1573 * go too (note this also kills CurTransactionContexts from any children
1576 if (s->curTransactionContext)
1577 MemoryContextDelete(s->curTransactionContext);
1578 s->curTransactionContext = NULL;
1581 /* ----------------------------------------------------------------
1582 * interface routines
1583 * ----------------------------------------------------------------
1590 StartTransaction(void)
1593 VirtualTransactionId vxid;
1596 * Let's just make sure the state stack is empty
1598 s = &TopTransactionStateData;
1599 CurrentTransactionState = s;
1602 * check the current transaction state
1604 if (s->state != TRANS_DEFAULT)
1605 elog(WARNING, "StartTransaction while in %s state",
1606 TransStateAsString(s->state));
1609 * set the current transaction state information appropriately during
1612 s->state = TRANS_START;
1613 s->transactionId = InvalidTransactionId; /* until assigned */
1616 * Make sure we've reset xact state variables
1618 * If recovery is still in progress, mark this transaction as read-only.
1619 * We have lower level defences in XLogInsert and elsewhere to stop us
1620 * from modifying data during recovery, but this gives the normal
1621 * indication to the user that the transaction is read-only.
1623 if (RecoveryInProgress())
1625 s->startedInRecovery = true;
1626 XactReadOnly = true;
1630 s->startedInRecovery = false;
1631 XactReadOnly = DefaultXactReadOnly;
1633 XactIsoLevel = DefaultXactIsoLevel;
1634 forceSyncCommit = false;
1635 MyXactAccessedTempRel = false;
1638 * reinitialize within-transaction counters
1640 s->subTransactionId = TopSubTransactionId;
1641 currentSubTransactionId = TopSubTransactionId;
1642 currentCommandId = FirstCommandId;
1643 currentCommandIdUsed = false;
1646 * initialize reported xid accounting
1648 nUnreportedXids = 0;
1651 * must initialize resource-management stuff first
1654 AtStart_ResourceOwner();
1657 * Assign a new LocalTransactionId, and combine it with the backendId to
1658 * form a virtual transaction id.
1660 vxid.backendId = MyBackendId;
1661 vxid.localTransactionId = GetNextLocalTransactionId();
1664 * Lock the virtual transaction id before we announce it in the proc array
1666 VirtualXactLockTableInsert(vxid);
1669 * Advertise it in the proc array. We assume assignment of
1670 * LocalTransactionID is atomic, and the backendId should be set already.
1672 Assert(MyProc->backendId == vxid.backendId);
1673 MyProc->lxid = vxid.localTransactionId;
1675 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
1678 * set transaction_timestamp() (a/k/a now()). We want this to be the same
1679 * as the first command's statement_timestamp(), so don't do a fresh
1680 * GetCurrentTimestamp() call (which'd be expensive anyway). Also, mark
1681 * xactStopTimestamp as unset.
1683 xactStartTimestamp = stmtStartTimestamp;
1684 xactStopTimestamp = 0;
1685 pgstat_report_xact_timestamp(xactStartTimestamp);
1688 * initialize current transaction state fields
1690 * note: prevXactReadOnly is not used at the outermost level
1692 s->nestingLevel = 1;
1693 s->gucNestLevel = 1;
1694 s->childXids = NULL;
1696 s->maxChildXids = 0;
1697 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
1698 /* SecurityRestrictionContext should never be set outside a transaction */
1699 Assert(s->prevSecContext == 0);
1702 * initialize other subsystems for new transaction
1707 AfterTriggerBeginXact();
1710 * done with start processing, set current transaction state to "in
1713 s->state = TRANS_INPROGRESS;
1715 ShowTransactionState("StartTransaction");
1722 * NB: if you change this routine, better look at PrepareTransaction too!
1725 CommitTransaction(void)
1727 TransactionState s = CurrentTransactionState;
1728 TransactionId latestXid;
1730 ShowTransactionState("CommitTransaction");
1733 * check the current transaction state
1735 if (s->state != TRANS_INPROGRESS)
1736 elog(WARNING, "CommitTransaction while in %s state",
1737 TransStateAsString(s->state));
1738 Assert(s->parent == NULL);
1741 * Do pre-commit processing (most of this stuff requires database access,
1742 * and in fact could still cause an error...)
1744 * It is possible for CommitHoldablePortals to invoke functions that queue
1745 * deferred triggers, and it's also possible that triggers create holdable
1746 * cursors. So we have to loop until there's nothing left to do.
1751 * Fire all currently pending deferred triggers.
1753 AfterTriggerFireDeferred();
1756 * Convert any open holdable cursors into static portals. If there
1757 * weren't any, we are done ... otherwise loop back to check if they
1758 * queued deferred triggers. Lather, rinse, repeat.
1760 if (!CommitHoldablePortals())
1764 /* Now we can shut down the deferred-trigger manager */
1765 AfterTriggerEndXact(true);
1767 /* Close any open regular cursors */
1771 * Let ON COMMIT management do its thing (must happen after closing
1772 * cursors, to avoid dangling-reference problems)
1774 PreCommit_on_commit_actions();
1776 /* close large objects before lower-level cleanup */
1777 AtEOXact_LargeObject(true);
1780 * Insert notifications sent by NOTIFY commands into the queue. This
1781 * should be late in the pre-commit sequence to minimize time spent
1782 * holding the notify-insertion lock.
1786 /* Prevent cancel/die interrupt while cleaning up */
1789 /* Commit updates to the relation map --- do this as late as possible */
1790 AtEOXact_RelationMap(true);
1793 * set the current transaction state information appropriately during
1796 s->state = TRANS_COMMIT;
1799 * Here is where we really truly commit.
1801 latestXid = RecordTransactionCommit();
1803 TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
1806 * Let others know about no transaction in progress by me. Note that this
1807 * must be done _before_ releasing locks we hold and _after_
1808 * RecordTransactionCommit.
1810 ProcArrayEndTransaction(MyProc, latestXid);
1813 * This is all post-commit cleanup. Note that if an error is raised here,
1814 * it's too late to abort the transaction. This should be just
1815 * noncritical resource releasing.
1817 * The ordering of operations is not entirely random. The idea is:
1818 * release resources visible to other backends (eg, files, buffer pins);
1819 * then release locks; then release backend-local resources. We want to
1820 * release locks at the point where any backend waiting for us will see
1821 * our transaction as being fully cleaned up.
1823 * Resources that can be associated with individual queries are handled by
1824 * the ResourceOwner mechanism. The other calls here are for backend-wide
1828 CallXactCallbacks(XACT_EVENT_COMMIT);
1830 ResourceOwnerRelease(TopTransactionResourceOwner,
1831 RESOURCE_RELEASE_BEFORE_LOCKS,
1834 /* Check we've released all buffer pins */
1835 AtEOXact_Buffers(true);
1837 /* Clean up the relation cache */
1838 AtEOXact_RelationCache(true);
1840 /* Clean up the snapshot manager */
1841 AtEarlyCommit_Snapshot();
1844 * Make catalog changes visible to all backends. This has to happen after
1845 * relcache references are dropped (see comments for
1846 * AtEOXact_RelationCache), but before locks are released (if anyone is
1847 * waiting for lock on a relation we've modified, we want them to know
1848 * about the catalog change before they start using the relation).
1850 AtEOXact_Inval(true);
1853 * Likewise, dropping of files deleted during the transaction is best done
1854 * after releasing relcache and buffer pins. (This is not strictly
1855 * necessary during commit, since such pins should have been released
1856 * already, but this ordering is definitely critical during abort.)
1858 smgrDoPendingDeletes(true);
1860 AtEOXact_MultiXact();
1862 ResourceOwnerRelease(TopTransactionResourceOwner,
1863 RESOURCE_RELEASE_LOCKS,
1865 ResourceOwnerRelease(TopTransactionResourceOwner,
1866 RESOURCE_RELEASE_AFTER_LOCKS,
1869 /* Check we've released all catcache entries */
1870 AtEOXact_CatCache(true);
1873 AtEOXact_GUC(true, 1);
1875 AtEOXact_on_commit_actions(true);
1876 AtEOXact_Namespace(true);
1877 /* smgrcommit already done */
1879 AtEOXact_ComboCid();
1880 AtEOXact_HashTables(true);
1881 AtEOXact_PgStat(true);
1882 AtEOXact_Snapshot(true);
1883 pgstat_report_xact_timestamp(0);
1885 CurrentResourceOwner = NULL;
1886 ResourceOwnerDelete(TopTransactionResourceOwner);
1887 s->curTransactionOwner = NULL;
1888 CurTransactionResourceOwner = NULL;
1889 TopTransactionResourceOwner = NULL;
1893 s->transactionId = InvalidTransactionId;
1894 s->subTransactionId = InvalidSubTransactionId;
1895 s->nestingLevel = 0;
1896 s->gucNestLevel = 0;
1897 s->childXids = NULL;
1899 s->maxChildXids = 0;
1902 * done with commit processing, set current transaction state back to
1905 s->state = TRANS_DEFAULT;
1907 RESUME_INTERRUPTS();
1912 * PrepareTransaction
1914 * NB: if you change this routine, better look at CommitTransaction too!
1917 PrepareTransaction(void)
1919 TransactionState s = CurrentTransactionState;
1920 TransactionId xid = GetCurrentTransactionId();
1921 GlobalTransaction gxact;
1922 TimestampTz prepared_at;
1924 ShowTransactionState("PrepareTransaction");
1927 * check the current transaction state
1929 if (s->state != TRANS_INPROGRESS)
1930 elog(WARNING, "PrepareTransaction while in %s state",
1931 TransStateAsString(s->state));
1932 Assert(s->parent == NULL);
1935 * Do pre-commit processing (most of this stuff requires database access,
1936 * and in fact could still cause an error...)
1938 * It is possible for PrepareHoldablePortals to invoke functions that
1939 * queue deferred triggers, and it's also possible that triggers create
1940 * holdable cursors. So we have to loop until there's nothing left to do.
1945 * Fire all currently pending deferred triggers.
1947 AfterTriggerFireDeferred();
1950 * Convert any open holdable cursors into static portals. If there
1951 * weren't any, we are done ... otherwise loop back to check if they
1952 * queued deferred triggers. Lather, rinse, repeat.
1954 if (!PrepareHoldablePortals())
1958 /* Now we can shut down the deferred-trigger manager */
1959 AfterTriggerEndXact(true);
1961 /* Close any open regular cursors */
1965 * Let ON COMMIT management do its thing (must happen after closing
1966 * cursors, to avoid dangling-reference problems)
1968 PreCommit_on_commit_actions();
1970 /* close large objects before lower-level cleanup */
1971 AtEOXact_LargeObject(true);
1973 /* NOTIFY will be handled below */
1976 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
1977 * this transaction. Having the prepared xact hold locks on another
1978 * backend's temp table seems a bad idea --- for instance it would prevent
1979 * the backend from exiting. There are other problems too, such as how to
1980 * clean up the source backend's local buffers and ON COMMIT state if the
1981 * prepared xact includes a DROP of a temp table.
1983 * We must check this after executing any ON COMMIT actions, because they
1984 * might still access a temp relation.
1986 * XXX In principle this could be relaxed to allow some useful special
1987 * cases, such as a temp table created and dropped all within the
1988 * transaction. That seems to require much more bookkeeping though.
1990 if (MyXactAccessedTempRel)
1992 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1993 errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
1995 /* Prevent cancel/die interrupt while cleaning up */
1999 * set the current transaction state information appropriately during
2000 * prepare processing
2002 s->state = TRANS_PREPARE;
2004 prepared_at = GetCurrentTimestamp();
2006 /* Tell bufmgr and smgr to prepare for commit */
2010 * Reserve the GID for this transaction. This could fail if the requested
2011 * GID is invalid or already in use.
2013 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
2014 GetUserId(), MyDatabaseId);
2018 * Collect data for the 2PC state file. Note that in general, no actual
2019 * state change should happen in the called modules during this step,
2020 * since it's still possible to fail before commit, and in that case we
2021 * want transaction abort to be able to clean up. (In particular, the
2022 * AtPrepare routines may error out if they find cases they cannot
2023 * handle.) State cleanup should happen in the PostPrepare routines
2024 * below. However, some modules can go ahead and clear state here because
2025 * they wouldn't do anything with it during abort anyway.
2027 * Note: because the 2PC state file records will be replayed in the same
2028 * order they are made, the order of these calls has to match the order in
2029 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2030 * PREPARED; in particular, pay attention to whether things should happen
2031 * before or after releasing the transaction's locks.
2033 StartPrepare(gxact);
2038 AtPrepare_MultiXact();
2039 AtPrepare_RelationMap();
2042 * Here is where we really truly prepare.
2044 * We have to record transaction prepares even if we didn't make any
2045 * updates, because the transaction manager might get confused if we lose
2046 * a global transaction.
2051 * Now we clean up backend-internal state and release internal resources.
2054 /* Reset XactLastRecEnd until the next transaction writes something */
2055 XactLastRecEnd.xrecoff = 0;
2058 * Let others know about no transaction in progress by me. This has to be
2059 * done *after* the prepared transaction has been marked valid, else
2060 * someone may think it is unlocked and recyclable.
2062 ProcArrayClearTransaction(MyProc);
2065 * This is all post-transaction cleanup. Note that if an error is raised
2066 * here, it's too late to abort the transaction. This should be just
2067 * noncritical resource releasing. See notes in CommitTransaction.
2070 CallXactCallbacks(XACT_EVENT_PREPARE);
2072 ResourceOwnerRelease(TopTransactionResourceOwner,
2073 RESOURCE_RELEASE_BEFORE_LOCKS,
2076 /* Check we've released all buffer pins */
2077 AtEOXact_Buffers(true);
2079 /* Clean up the relation cache */
2080 AtEOXact_RelationCache(true);
2082 /* Clean up the snapshot manager */
2083 AtEarlyCommit_Snapshot();
2085 /* notify doesn't need a postprepare call */
2087 PostPrepare_PgStat();
2089 PostPrepare_Inval();
2093 PostPrepare_MultiXact(xid);
2095 PostPrepare_Locks(xid);
2097 ResourceOwnerRelease(TopTransactionResourceOwner,
2098 RESOURCE_RELEASE_LOCKS,
2100 ResourceOwnerRelease(TopTransactionResourceOwner,
2101 RESOURCE_RELEASE_AFTER_LOCKS,
2104 /* Check we've released all catcache entries */
2105 AtEOXact_CatCache(true);
2107 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2108 AtEOXact_GUC(true, 1);
2110 AtEOXact_on_commit_actions(true);
2111 AtEOXact_Namespace(true);
2112 /* smgrcommit already done */
2114 AtEOXact_ComboCid();
2115 AtEOXact_HashTables(true);
2116 /* don't call AtEOXact_PgStat here */
2117 AtEOXact_Snapshot(true);
2119 CurrentResourceOwner = NULL;
2120 ResourceOwnerDelete(TopTransactionResourceOwner);
2121 s->curTransactionOwner = NULL;
2122 CurTransactionResourceOwner = NULL;
2123 TopTransactionResourceOwner = NULL;
2127 s->transactionId = InvalidTransactionId;
2128 s->subTransactionId = InvalidSubTransactionId;
2129 s->nestingLevel = 0;
2130 s->gucNestLevel = 0;
2131 s->childXids = NULL;
2133 s->maxChildXids = 0;
2136 * done with 1st phase commit processing, set current transaction state
2139 s->state = TRANS_DEFAULT;
2141 RESUME_INTERRUPTS();
2149 AbortTransaction(void)
2151 TransactionState s = CurrentTransactionState;
2152 TransactionId latestXid;
2154 /* Prevent cancel/die interrupt while cleaning up */
2157 /* Make sure we have a valid memory context and resource owner */
2159 AtAbort_ResourceOwner();
2162 * Release any LW locks we might be holding as quickly as possible.
2163 * (Regular locks, however, must be held till we finish aborting.)
2164 * Releasing LW locks is critical since we might try to grab them again
2165 * while cleaning up!
2169 /* Clean up buffer I/O and buffer context locks, too */
2174 * Also clean up any open wait for lock, since the lock manager will choke
2175 * if we try to wait for another lock before doing this.
2180 * check the current transaction state
2182 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2183 elog(WARNING, "AbortTransaction while in %s state",
2184 TransStateAsString(s->state));
2185 Assert(s->parent == NULL);
2188 * set the current transaction state information appropriately during the
2191 s->state = TRANS_ABORT;
2194 * Reset user ID which might have been changed transiently. We need this
2195 * to clean up in case control escaped out of a SECURITY DEFINER function
2196 * or other local change of CurrentUserId; therefore, the prior value of
2197 * SecurityRestrictionContext also needs to be restored.
2199 * (Note: it is not necessary to restore session authorization or role
2200 * settings here because those can only be changed via GUC, and GUC will
2201 * take care of rolling them back if need be.)
2203 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
2206 * do abort processing
2208 AfterTriggerEndXact(false); /* 'false' means it's abort */
2210 AtEOXact_LargeObject(false);
2212 AtEOXact_RelationMap(false);
2215 * Advertise the fact that we aborted in pg_clog (assuming that we got as
2216 * far as assigning an XID to advertise).
2218 latestXid = RecordTransactionAbort(false);
2220 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
2223 * Let others know about no transaction in progress by me. Note that this
2224 * must be done _before_ releasing locks we hold and _after_
2225 * RecordTransactionAbort.
2227 ProcArrayEndTransaction(MyProc, latestXid);
2230 * Post-abort cleanup. See notes in CommitTransaction() concerning
2231 * ordering. We can skip all of it if the transaction failed before
2232 * creating a resource owner.
2234 if (TopTransactionResourceOwner != NULL)
2236 CallXactCallbacks(XACT_EVENT_ABORT);
2238 ResourceOwnerRelease(TopTransactionResourceOwner,
2239 RESOURCE_RELEASE_BEFORE_LOCKS,
2241 AtEOXact_Buffers(false);
2242 AtEOXact_RelationCache(false);
2243 AtEOXact_Inval(false);
2244 smgrDoPendingDeletes(false);
2245 AtEOXact_MultiXact();
2246 ResourceOwnerRelease(TopTransactionResourceOwner,
2247 RESOURCE_RELEASE_LOCKS,
2249 ResourceOwnerRelease(TopTransactionResourceOwner,
2250 RESOURCE_RELEASE_AFTER_LOCKS,
2252 AtEOXact_CatCache(false);
2254 AtEOXact_GUC(false, 1);
2255 AtEOXact_SPI(false);
2256 AtEOXact_on_commit_actions(false);
2257 AtEOXact_Namespace(false);
2259 AtEOXact_ComboCid();
2260 AtEOXact_HashTables(false);
2261 AtEOXact_PgStat(false);
2262 AtEOXact_Snapshot(false);
2263 pgstat_report_xact_timestamp(0);
2267 * State remains TRANS_ABORT until CleanupTransaction().
2269 RESUME_INTERRUPTS();
2273 * CleanupTransaction
2276 CleanupTransaction(void)
2278 TransactionState s = CurrentTransactionState;
2281 * State should still be TRANS_ABORT from AbortTransaction().
2283 if (s->state != TRANS_ABORT)
2284 elog(FATAL, "CleanupTransaction: unexpected state %s",
2285 TransStateAsString(s->state));
2288 * do abort cleanup processing
2290 AtCleanup_Portals(); /* now safe to release portal memory */
2292 CurrentResourceOwner = NULL; /* and resource owner */
2293 if (TopTransactionResourceOwner)
2294 ResourceOwnerDelete(TopTransactionResourceOwner);
2295 s->curTransactionOwner = NULL;
2296 CurTransactionResourceOwner = NULL;
2297 TopTransactionResourceOwner = NULL;
2299 AtCleanup_Memory(); /* and transaction memory */
2301 s->transactionId = InvalidTransactionId;
2302 s->subTransactionId = InvalidSubTransactionId;
2303 s->nestingLevel = 0;
2304 s->gucNestLevel = 0;
2305 s->childXids = NULL;
2307 s->maxChildXids = 0;
2310 * done with abort processing, set current transaction state back to
2313 s->state = TRANS_DEFAULT;
2317 * StartTransactionCommand
2320 StartTransactionCommand(void)
2322 TransactionState s = CurrentTransactionState;
2324 switch (s->blockState)
2327 * if we aren't in a transaction block, we just do our usual start
2330 case TBLOCK_DEFAULT:
2332 s->blockState = TBLOCK_STARTED;
2336 * We are somewhere in a transaction block or subtransaction and
2337 * about to start a new command. For now we do nothing, but
2338 * someday we may do command-local resource initialization. (Note
2339 * that any needed CommandCounterIncrement was done by the
2340 * previous CommitTransactionCommand.)
2342 case TBLOCK_INPROGRESS:
2343 case TBLOCK_SUBINPROGRESS:
2347 * Here we are in a failed transaction block (one of the commands
2348 * caused an abort) so we do nothing but remain in the abort
2349 * state. Eventually we will get a ROLLBACK command which will
2350 * get us out of this state. (It is up to other code to ensure
2351 * that no commands other than ROLLBACK will be processed in these
2355 case TBLOCK_SUBABORT:
2358 /* These cases are invalid. */
2359 case TBLOCK_STARTED:
2361 case TBLOCK_SUBBEGIN:
2364 case TBLOCK_ABORT_END:
2365 case TBLOCK_SUBABORT_END:
2366 case TBLOCK_ABORT_PENDING:
2367 case TBLOCK_SUBABORT_PENDING:
2368 case TBLOCK_SUBRESTART:
2369 case TBLOCK_SUBABORT_RESTART:
2370 case TBLOCK_PREPARE:
2371 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2372 BlockStateAsString(s->blockState));
2377 * We must switch to CurTransactionContext before returning. This is
2378 * already done if we called StartTransaction, otherwise not.
2380 Assert(CurTransactionContext != NULL);
2381 MemoryContextSwitchTo(CurTransactionContext);
2385 * CommitTransactionCommand
2388 CommitTransactionCommand(void)
2390 TransactionState s = CurrentTransactionState;
2392 switch (s->blockState)
2395 * This shouldn't happen, because it means the previous
2396 * StartTransactionCommand didn't set the STARTED state
2399 case TBLOCK_DEFAULT:
2400 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2401 BlockStateAsString(s->blockState));
2405 * If we aren't in a transaction block, just do our usual
2406 * transaction commit, and return to the idle state.
2408 case TBLOCK_STARTED:
2409 CommitTransaction();
2410 s->blockState = TBLOCK_DEFAULT;
2414 * We are completing a "BEGIN TRANSACTION" command, so we change
2415 * to the "transaction block in progress" state and return. (We
2416 * assume the BEGIN did nothing to the database, so we need no
2417 * CommandCounterIncrement.)
2420 s->blockState = TBLOCK_INPROGRESS;
2424 * This is the case when we have finished executing a command
2425 * someplace within a transaction block. We increment the command
2426 * counter and return.
2428 case TBLOCK_INPROGRESS:
2429 case TBLOCK_SUBINPROGRESS:
2430 CommandCounterIncrement();
2434 * We are completing a "COMMIT" command. Do it and return to the
2438 CommitTransaction();
2439 s->blockState = TBLOCK_DEFAULT;
2443 * Here we are in the middle of a transaction block but one of the
2444 * commands caused an abort so we do nothing but remain in the
2445 * abort state. Eventually we will get a ROLLBACK comand.
2448 case TBLOCK_SUBABORT:
2452 * Here we were in an aborted transaction block and we just got
2453 * the ROLLBACK command from the user, so clean up the
2454 * already-aborted transaction and return to the idle state.
2456 case TBLOCK_ABORT_END:
2457 CleanupTransaction();
2458 s->blockState = TBLOCK_DEFAULT;
2462 * Here we were in a perfectly good transaction block but the user
2463 * told us to ROLLBACK anyway. We have to abort the transaction
2464 * and then clean up.
2466 case TBLOCK_ABORT_PENDING:
2468 CleanupTransaction();
2469 s->blockState = TBLOCK_DEFAULT;
2473 * We are completing a "PREPARE TRANSACTION" command. Do it and
2474 * return to the idle state.
2476 case TBLOCK_PREPARE:
2477 PrepareTransaction();
2478 s->blockState = TBLOCK_DEFAULT;
2482 * We were just issued a SAVEPOINT inside a transaction block.
2483 * Start a subtransaction. (DefineSavepoint already did
2484 * PushTransaction, so as to have someplace to put the SUBBEGIN
2487 case TBLOCK_SUBBEGIN:
2488 StartSubTransaction();
2489 s->blockState = TBLOCK_SUBINPROGRESS;
2493 * We were issued a COMMIT or RELEASE command, so we end the
2494 * current subtransaction and return to the parent transaction.
2495 * The parent might be ended too, so repeat till we are all the
2496 * way out or find an INPROGRESS transaction.
2501 CommitSubTransaction();
2502 s = CurrentTransactionState; /* changed by pop */
2503 } while (s->blockState == TBLOCK_SUBEND);
2504 /* If we had a COMMIT command, finish off the main xact too */
2505 if (s->blockState == TBLOCK_END)
2507 Assert(s->parent == NULL);
2508 CommitTransaction();
2509 s->blockState = TBLOCK_DEFAULT;
2511 else if (s->blockState == TBLOCK_PREPARE)
2513 Assert(s->parent == NULL);
2514 PrepareTransaction();
2515 s->blockState = TBLOCK_DEFAULT;
2519 Assert(s->blockState == TBLOCK_INPROGRESS ||
2520 s->blockState == TBLOCK_SUBINPROGRESS);
2525 * The current already-failed subtransaction is ending due to a
2526 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2527 * examine the parent (which could be in any of several states).
2529 case TBLOCK_SUBABORT_END:
2530 CleanupSubTransaction();
2531 CommitTransactionCommand();
2535 * As above, but it's not dead yet, so abort first.
2537 case TBLOCK_SUBABORT_PENDING:
2538 AbortSubTransaction();
2539 CleanupSubTransaction();
2540 CommitTransactionCommand();
2544 * The current subtransaction is the target of a ROLLBACK TO
2545 * command. Abort and pop it, then start a new subtransaction
2546 * with the same name.
2548 case TBLOCK_SUBRESTART:
2553 /* save name and keep Cleanup from freeing it */
2556 savepointLevel = s->savepointLevel;
2558 AbortSubTransaction();
2559 CleanupSubTransaction();
2561 DefineSavepoint(NULL);
2562 s = CurrentTransactionState; /* changed by push */
2564 s->savepointLevel = savepointLevel;
2566 /* This is the same as TBLOCK_SUBBEGIN case */
2567 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2568 StartSubTransaction();
2569 s->blockState = TBLOCK_SUBINPROGRESS;
2574 * Same as above, but the subtransaction had already failed, so we
2575 * don't need AbortSubTransaction.
2577 case TBLOCK_SUBABORT_RESTART:
2582 /* save name and keep Cleanup from freeing it */
2585 savepointLevel = s->savepointLevel;
2587 CleanupSubTransaction();
2589 DefineSavepoint(NULL);
2590 s = CurrentTransactionState; /* changed by push */
2592 s->savepointLevel = savepointLevel;
2594 /* This is the same as TBLOCK_SUBBEGIN case */
2595 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2596 StartSubTransaction();
2597 s->blockState = TBLOCK_SUBINPROGRESS;
2604 * AbortCurrentTransaction
2607 AbortCurrentTransaction(void)
2609 TransactionState s = CurrentTransactionState;
2611 switch (s->blockState)
2613 case TBLOCK_DEFAULT:
2614 if (s->state == TRANS_DEFAULT)
2616 /* we are idle, so nothing to do */
2621 * We can get here after an error during transaction start
2622 * (state will be TRANS_START). Need to clean up the
2623 * incompletely started transaction. First, adjust the
2624 * low-level state to suppress warning message from
2627 if (s->state == TRANS_START)
2628 s->state = TRANS_INPROGRESS;
2630 CleanupTransaction();
2635 * if we aren't in a transaction block, we just do the basic abort
2636 * & cleanup transaction.
2638 case TBLOCK_STARTED:
2640 CleanupTransaction();
2641 s->blockState = TBLOCK_DEFAULT;
2645 * If we are in TBLOCK_BEGIN it means something screwed up right
2646 * after reading "BEGIN TRANSACTION". We assume that the user
2647 * will interpret the error as meaning the BEGIN failed to get him
2648 * into a transaction block, so we should abort and return to idle
2653 CleanupTransaction();
2654 s->blockState = TBLOCK_DEFAULT;
2658 * We are somewhere in a transaction block and we've gotten a
2659 * failure, so we abort the transaction and set up the persistent
2660 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
2662 case TBLOCK_INPROGRESS:
2664 s->blockState = TBLOCK_ABORT;
2665 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
2669 * Here, we failed while trying to COMMIT. Clean up the
2670 * transaction and return to idle state (we do not want to stay in
2675 CleanupTransaction();
2676 s->blockState = TBLOCK_DEFAULT;
2680 * Here, we are already in an aborted transaction state and are
2681 * waiting for a ROLLBACK, but for some reason we failed again! So
2682 * we just remain in the abort state.
2685 case TBLOCK_SUBABORT:
2689 * We are in a failed transaction and we got the ROLLBACK command.
2690 * We have already aborted, we just need to cleanup and go to idle
2693 case TBLOCK_ABORT_END:
2694 CleanupTransaction();
2695 s->blockState = TBLOCK_DEFAULT;
2699 * We are in a live transaction and we got a ROLLBACK command.
2700 * Abort, cleanup, go to idle state.
2702 case TBLOCK_ABORT_PENDING:
2704 CleanupTransaction();
2705 s->blockState = TBLOCK_DEFAULT;
2709 * Here, we failed while trying to PREPARE. Clean up the
2710 * transaction and return to idle state (we do not want to stay in
2713 case TBLOCK_PREPARE:
2715 CleanupTransaction();
2716 s->blockState = TBLOCK_DEFAULT;
2720 * We got an error inside a subtransaction. Abort just the
2721 * subtransaction, and go to the persistent SUBABORT state until
2724 case TBLOCK_SUBINPROGRESS:
2725 AbortSubTransaction();
2726 s->blockState = TBLOCK_SUBABORT;
2730 * If we failed while trying to create a subtransaction, clean up
2731 * the broken subtransaction and abort the parent. The same
2732 * applies if we get a failure while ending a subtransaction.
2734 case TBLOCK_SUBBEGIN:
2736 case TBLOCK_SUBABORT_PENDING:
2737 case TBLOCK_SUBRESTART:
2738 AbortSubTransaction();
2739 CleanupSubTransaction();
2740 AbortCurrentTransaction();
2744 * Same as above, except the Abort() was already done.
2746 case TBLOCK_SUBABORT_END:
2747 case TBLOCK_SUBABORT_RESTART:
2748 CleanupSubTransaction();
2749 AbortCurrentTransaction();
2755 * PreventTransactionChain
2757 * This routine is to be called by statements that must not run inside
2758 * a transaction block, typically because they have non-rollback-able
2759 * side effects or do internal commits.
2761 * If we have already started a transaction block, issue an error; also issue
2762 * an error if we appear to be running inside a user-defined function (which
2763 * could issue more commands and possibly cause a failure after the statement
2764 * completes). Subtransactions are verboten too.
2766 * isTopLevel: passed down from ProcessUtility to determine whether we are
2767 * inside a function or multi-query querystring. (We will always fail if
2768 * this is false, but it's convenient to centralize the check here instead of
2769 * making callers do it.)
2770 * stmtType: statement type name, for error messages.
2773 PreventTransactionChain(bool isTopLevel, const char *stmtType)
2776 * xact block already started?
2778 if (IsTransactionBlock())
2780 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2781 /* translator: %s represents an SQL statement name */
2782 errmsg("%s cannot run inside a transaction block",
2788 if (IsSubTransaction())
2790 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2791 /* translator: %s represents an SQL statement name */
2792 errmsg("%s cannot run inside a subtransaction",
2796 * inside a function call?
2800 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2801 /* translator: %s represents an SQL statement name */
2802 errmsg("%s cannot be executed from a function or multi-command string",
2805 /* If we got past IsTransactionBlock test, should be in default state */
2806 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2807 CurrentTransactionState->blockState != TBLOCK_STARTED)
2808 elog(FATAL, "cannot prevent transaction chain");
2813 * RequireTransactionChain
2815 * This routine is to be called by statements that must run inside
2816 * a transaction block, because they have no effects that persist past
2817 * transaction end (and so calling them outside a transaction block
2818 * is presumably an error). DECLARE CURSOR is an example.
2820 * If we appear to be running inside a user-defined function, we do not
2821 * issue an error, since the function could issue more commands that make
2822 * use of the current statement's results. Likewise subtransactions.
2823 * Thus this is an inverse for PreventTransactionChain.
2825 * isTopLevel: passed down from ProcessUtility to determine whether we are
2826 * inside a function.
2827 * stmtType: statement type name, for error messages.
2830 RequireTransactionChain(bool isTopLevel, const char *stmtType)
2833 * xact block already started?
2835 if (IsTransactionBlock())
2841 if (IsSubTransaction())
2845 * inside a function call?
2851 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2852 /* translator: %s represents an SQL statement name */
2853 errmsg("%s can only be used in transaction blocks",
2858 * IsInTransactionChain
2860 * This routine is for statements that need to behave differently inside
2861 * a transaction block than when running as single commands. ANALYZE is
2862 * currently the only example.
2864 * isTopLevel: passed down from ProcessUtility to determine whether we are
2865 * inside a function.
2868 IsInTransactionChain(bool isTopLevel)
2871 * Return true on same conditions that would make PreventTransactionChain
2874 if (IsTransactionBlock())
2877 if (IsSubTransaction())
2883 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2884 CurrentTransactionState->blockState != TBLOCK_STARTED)
2892 * Register or deregister callback functions for start- and end-of-xact
2895 * These functions are intended for use by dynamically loaded modules.
2896 * For built-in modules we generally just hardwire the appropriate calls
2897 * (mainly because it's easier to control the order that way, where needed).
2899 * At transaction end, the callback occurs post-commit or post-abort, so the
2900 * callback functions can only do noncritical cleanup.
2903 RegisterXactCallback(XactCallback callback, void *arg)
2905 XactCallbackItem *item;
2907 item = (XactCallbackItem *)
2908 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
2909 item->callback = callback;
2911 item->next = Xact_callbacks;
2912 Xact_callbacks = item;
2916 UnregisterXactCallback(XactCallback callback, void *arg)
2918 XactCallbackItem *item;
2919 XactCallbackItem *prev;
2922 for (item = Xact_callbacks; item; prev = item, item = item->next)
2924 if (item->callback == callback && item->arg == arg)
2927 prev->next = item->next;
2929 Xact_callbacks = item->next;
2937 CallXactCallbacks(XactEvent event)
2939 XactCallbackItem *item;
2941 for (item = Xact_callbacks; item; item = item->next)
2942 (*item->callback) (event, item->arg);
2947 * Register or deregister callback functions for start- and end-of-subxact
2950 * Pretty much same as above, but for subtransaction events.
2952 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
2953 * so the callback functions can only do noncritical cleanup. At
2954 * subtransaction start, the callback is called when the subtransaction has
2955 * finished initializing.
2958 RegisterSubXactCallback(SubXactCallback callback, void *arg)
2960 SubXactCallbackItem *item;
2962 item = (SubXactCallbackItem *)
2963 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
2964 item->callback = callback;
2966 item->next = SubXact_callbacks;
2967 SubXact_callbacks = item;
2971 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
2973 SubXactCallbackItem *item;
2974 SubXactCallbackItem *prev;
2977 for (item = SubXact_callbacks; item; prev = item, item = item->next)
2979 if (item->callback == callback && item->arg == arg)
2982 prev->next = item->next;
2984 SubXact_callbacks = item->next;
2992 CallSubXactCallbacks(SubXactEvent event,
2993 SubTransactionId mySubid,
2994 SubTransactionId parentSubid)
2996 SubXactCallbackItem *item;
2998 for (item = SubXact_callbacks; item; item = item->next)
2999 (*item->callback) (event, mySubid, parentSubid, item->arg);
3003 /* ----------------------------------------------------------------
3004 * transaction block support
3005 * ----------------------------------------------------------------
3009 * BeginTransactionBlock
3010 * This executes a BEGIN command.
3013 BeginTransactionBlock(void)
3015 TransactionState s = CurrentTransactionState;
3017 switch (s->blockState)
3020 * We are not inside a transaction block, so allow one to begin.
3022 case TBLOCK_STARTED:
3023 s->blockState = TBLOCK_BEGIN;
3027 * Already a transaction block in progress.
3029 case TBLOCK_INPROGRESS:
3030 case TBLOCK_SUBINPROGRESS:
3032 case TBLOCK_SUBABORT:
3034 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3035 errmsg("there is already a transaction in progress")));
3038 /* These cases are invalid. */
3039 case TBLOCK_DEFAULT:
3041 case TBLOCK_SUBBEGIN:
3044 case TBLOCK_ABORT_END:
3045 case TBLOCK_SUBABORT_END:
3046 case TBLOCK_ABORT_PENDING:
3047 case TBLOCK_SUBABORT_PENDING:
3048 case TBLOCK_SUBRESTART:
3049 case TBLOCK_SUBABORT_RESTART:
3050 case TBLOCK_PREPARE:
3051 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3052 BlockStateAsString(s->blockState));
3058 * PrepareTransactionBlock
3059 * This executes a PREPARE command.
3061 * Since PREPARE may actually do a ROLLBACK, the result indicates what
3062 * happened: TRUE for PREPARE, FALSE for ROLLBACK.
3064 * Note that we don't actually do anything here except change blockState.
3065 * The real work will be done in the upcoming PrepareTransaction().
3066 * We do it this way because it's not convenient to change memory context,
3067 * resource owner, etc while executing inside a Portal.
3070 PrepareTransactionBlock(char *gid)
3075 /* Set up to commit the current transaction */
3076 result = EndTransactionBlock();
3078 /* If successful, change outer tblock state to PREPARE */
3081 s = CurrentTransactionState;
3083 while (s->parent != NULL)
3086 if (s->blockState == TBLOCK_END)
3088 /* Save GID where PrepareTransaction can find it again */
3089 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
3091 s->blockState = TBLOCK_PREPARE;
3096 * ignore case where we are not in a transaction;
3097 * EndTransactionBlock already issued a warning.
3099 Assert(s->blockState == TBLOCK_STARTED);
3100 /* Don't send back a PREPARE result tag... */
3109 * EndTransactionBlock
3110 * This executes a COMMIT command.
3112 * Since COMMIT may actually do a ROLLBACK, the result indicates what
3113 * happened: TRUE for COMMIT, FALSE for ROLLBACK.
3115 * Note that we don't actually do anything here except change blockState.
3116 * The real work will be done in the upcoming CommitTransactionCommand().
3117 * We do it this way because it's not convenient to change memory context,
3118 * resource owner, etc while executing inside a Portal.
3121 EndTransactionBlock(void)
3123 TransactionState s = CurrentTransactionState;
3124 bool result = false;
3126 switch (s->blockState)
3129 * We are in a transaction block, so tell CommitTransactionCommand
3132 case TBLOCK_INPROGRESS:
3133 s->blockState = TBLOCK_END;
3138 * We are in a failed transaction block. Tell
3139 * CommitTransactionCommand it's time to exit the block.
3142 s->blockState = TBLOCK_ABORT_END;
3146 * We are in a live subtransaction block. Set up to subcommit all
3147 * open subtransactions and then commit the main transaction.
3149 case TBLOCK_SUBINPROGRESS:
3150 while (s->parent != NULL)
3152 if (s->blockState == TBLOCK_SUBINPROGRESS)
3153 s->blockState = TBLOCK_SUBEND;
3155 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3156 BlockStateAsString(s->blockState));
3159 if (s->blockState == TBLOCK_INPROGRESS)
3160 s->blockState = TBLOCK_END;
3162 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3163 BlockStateAsString(s->blockState));
3168 * Here we are inside an aborted subtransaction. Treat the COMMIT
3169 * as ROLLBACK: set up to abort everything and exit the main
3172 case TBLOCK_SUBABORT:
3173 while (s->parent != NULL)
3175 if (s->blockState == TBLOCK_SUBINPROGRESS)
3176 s->blockState = TBLOCK_SUBABORT_PENDING;
3177 else if (s->blockState == TBLOCK_SUBABORT)
3178 s->blockState = TBLOCK_SUBABORT_END;
3180 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3181 BlockStateAsString(s->blockState));
3184 if (s->blockState == TBLOCK_INPROGRESS)
3185 s->blockState = TBLOCK_ABORT_PENDING;
3186 else if (s->blockState == TBLOCK_ABORT)
3187 s->blockState = TBLOCK_ABORT_END;
3189 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3190 BlockStateAsString(s->blockState));
3194 * The user issued COMMIT when not inside a transaction. Issue a
3195 * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
3196 * CommitTransactionCommand() will then close the transaction and
3197 * put us back into the default state.
3199 case TBLOCK_STARTED:
3201 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3202 errmsg("there is no transaction in progress")));
3206 /* These cases are invalid. */
3207 case TBLOCK_DEFAULT:
3209 case TBLOCK_SUBBEGIN:
3212 case TBLOCK_ABORT_END:
3213 case TBLOCK_SUBABORT_END:
3214 case TBLOCK_ABORT_PENDING:
3215 case TBLOCK_SUBABORT_PENDING:
3216 case TBLOCK_SUBRESTART:
3217 case TBLOCK_SUBABORT_RESTART:
3218 case TBLOCK_PREPARE:
3219 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3220 BlockStateAsString(s->blockState));
3228 * UserAbortTransactionBlock
3229 * This executes a ROLLBACK command.
3231 * As above, we don't actually do anything here except change blockState.
3234 UserAbortTransactionBlock(void)
3236 TransactionState s = CurrentTransactionState;
3238 switch (s->blockState)
3241 * We are inside a transaction block and we got a ROLLBACK command
3242 * from the user, so tell CommitTransactionCommand to abort and
3243 * exit the transaction block.
3245 case TBLOCK_INPROGRESS:
3246 s->blockState = TBLOCK_ABORT_PENDING;
3250 * We are inside a failed transaction block and we got a ROLLBACK
3251 * command from the user. Abort processing is already done, so
3252 * CommitTransactionCommand just has to cleanup and go back to
3256 s->blockState = TBLOCK_ABORT_END;
3260 * We are inside a subtransaction. Mark everything up to top
3261 * level as exitable.
3263 case TBLOCK_SUBINPROGRESS:
3264 case TBLOCK_SUBABORT:
3265 while (s->parent != NULL)
3267 if (s->blockState == TBLOCK_SUBINPROGRESS)
3268 s->blockState = TBLOCK_SUBABORT_PENDING;
3269 else if (s->blockState == TBLOCK_SUBABORT)
3270 s->blockState = TBLOCK_SUBABORT_END;
3272 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3273 BlockStateAsString(s->blockState));
3276 if (s->blockState == TBLOCK_INPROGRESS)
3277 s->blockState = TBLOCK_ABORT_PENDING;
3278 else if (s->blockState == TBLOCK_ABORT)
3279 s->blockState = TBLOCK_ABORT_END;
3281 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3282 BlockStateAsString(s->blockState));
3286 * The user issued ABORT when not inside a transaction. Issue a
3287 * WARNING and go to abort state. The upcoming call to
3288 * CommitTransactionCommand() will then put us back into the
3291 case TBLOCK_STARTED:
3293 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3294 errmsg("there is no transaction in progress")));
3295 s->blockState = TBLOCK_ABORT_PENDING;
3298 /* These cases are invalid. */
3299 case TBLOCK_DEFAULT:
3301 case TBLOCK_SUBBEGIN:
3304 case TBLOCK_ABORT_END:
3305 case TBLOCK_SUBABORT_END:
3306 case TBLOCK_ABORT_PENDING:
3307 case TBLOCK_SUBABORT_PENDING:
3308 case TBLOCK_SUBRESTART:
3309 case TBLOCK_SUBABORT_RESTART:
3310 case TBLOCK_PREPARE:
3311 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3312 BlockStateAsString(s->blockState));
3319 * This executes a SAVEPOINT command.
3322 DefineSavepoint(char *name)
3324 TransactionState s = CurrentTransactionState;
3326 switch (s->blockState)
3328 case TBLOCK_INPROGRESS:
3329 case TBLOCK_SUBINPROGRESS:
3330 /* Normal subtransaction start */
3332 s = CurrentTransactionState; /* changed by push */
3335 * Savepoint names, like the TransactionState block itself, live
3336 * in TopTransactionContext.
3339 s->name = MemoryContextStrdup(TopTransactionContext, name);
3342 /* These cases are invalid. */
3343 case TBLOCK_DEFAULT:
3344 case TBLOCK_STARTED:
3346 case TBLOCK_SUBBEGIN:
3350 case TBLOCK_SUBABORT:
3351 case TBLOCK_ABORT_END:
3352 case TBLOCK_SUBABORT_END:
3353 case TBLOCK_ABORT_PENDING:
3354 case TBLOCK_SUBABORT_PENDING:
3355 case TBLOCK_SUBRESTART:
3356 case TBLOCK_SUBABORT_RESTART:
3357 case TBLOCK_PREPARE:
3358 elog(FATAL, "DefineSavepoint: unexpected state %s",
3359 BlockStateAsString(s->blockState));
3366 * This executes a RELEASE command.
3368 * As above, we don't actually do anything here except change blockState.
3371 ReleaseSavepoint(List *options)
3373 TransactionState s = CurrentTransactionState;
3374 TransactionState target,
3379 switch (s->blockState)
3382 * We can't rollback to a savepoint if there is no savepoint
3385 case TBLOCK_INPROGRESS:
3387 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3388 errmsg("no such savepoint")));
3392 * We are in a non-aborted subtransaction. This is the only valid
3395 case TBLOCK_SUBINPROGRESS:
3398 /* These cases are invalid. */
3399 case TBLOCK_DEFAULT:
3400 case TBLOCK_STARTED:
3402 case TBLOCK_SUBBEGIN:
3406 case TBLOCK_SUBABORT:
3407 case TBLOCK_ABORT_END:
3408 case TBLOCK_SUBABORT_END:
3409 case TBLOCK_ABORT_PENDING:
3410 case TBLOCK_SUBABORT_PENDING:
3411 case TBLOCK_SUBRESTART:
3412 case TBLOCK_SUBABORT_RESTART:
3413 case TBLOCK_PREPARE:
3414 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3415 BlockStateAsString(s->blockState));
3419 foreach(cell, options)
3421 DefElem *elem = lfirst(cell);
3423 if (strcmp(elem->defname, "savepoint_name") == 0)
3424 name = strVal(elem->arg);
3427 Assert(PointerIsValid(name));
3429 for (target = s; PointerIsValid(target); target = target->parent)
3431 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3435 if (!PointerIsValid(target))
3437 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3438 errmsg("no such savepoint")));
3440 /* disallow crossing savepoint level boundaries */
3441 if (target->savepointLevel != s->savepointLevel)
3443 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3444 errmsg("no such savepoint")));
3447 * Mark "commit pending" all subtransactions up to the target
3448 * subtransaction. The actual commits will happen when control gets to
3449 * CommitTransactionCommand.
3451 xact = CurrentTransactionState;
3454 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3455 xact->blockState = TBLOCK_SUBEND;
3458 xact = xact->parent;
3459 Assert(PointerIsValid(xact));
3464 * RollbackToSavepoint
3465 * This executes a ROLLBACK TO <savepoint> command.
3467 * As above, we don't actually do anything here except change blockState.
3470 RollbackToSavepoint(List *options)
3472 TransactionState s = CurrentTransactionState;
3473 TransactionState target,
3478 switch (s->blockState)
3481 * We can't rollback to a savepoint if there is no savepoint
3484 case TBLOCK_INPROGRESS:
3487 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3488 errmsg("no such savepoint")));
3492 * There is at least one savepoint, so proceed.
3494 case TBLOCK_SUBINPROGRESS:
3495 case TBLOCK_SUBABORT:
3498 /* These cases are invalid. */
3499 case TBLOCK_DEFAULT:
3500 case TBLOCK_STARTED:
3502 case TBLOCK_SUBBEGIN:
3505 case TBLOCK_ABORT_END:
3506 case TBLOCK_SUBABORT_END:
3507 case TBLOCK_ABORT_PENDING:
3508 case TBLOCK_SUBABORT_PENDING:
3509 case TBLOCK_SUBRESTART:
3510 case TBLOCK_SUBABORT_RESTART:
3511 case TBLOCK_PREPARE:
3512 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3513 BlockStateAsString(s->blockState));
3517 foreach(cell, options)
3519 DefElem *elem = lfirst(cell);
3521 if (strcmp(elem->defname, "savepoint_name") == 0)
3522 name = strVal(elem->arg);
3525 Assert(PointerIsValid(name));
3527 for (target = s; PointerIsValid(target); target = target->parent)
3529 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3533 if (!PointerIsValid(target))
3535 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3536 errmsg("no such savepoint")));
3538 /* disallow crossing savepoint level boundaries */
3539 if (target->savepointLevel != s->savepointLevel)
3541 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3542 errmsg("no such savepoint")));
3545 * Mark "abort pending" all subtransactions up to the target
3546 * subtransaction. The actual aborts will happen when control gets to
3547 * CommitTransactionCommand.
3549 xact = CurrentTransactionState;
3554 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3555 xact->blockState = TBLOCK_SUBABORT_PENDING;
3556 else if (xact->blockState == TBLOCK_SUBABORT)
3557 xact->blockState = TBLOCK_SUBABORT_END;
3559 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3560 BlockStateAsString(xact->blockState));
3561 xact = xact->parent;
3562 Assert(PointerIsValid(xact));
3565 /* And mark the target as "restart pending" */
3566 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3567 xact->blockState = TBLOCK_SUBRESTART;
3568 else if (xact->blockState == TBLOCK_SUBABORT)
3569 xact->blockState = TBLOCK_SUBABORT_RESTART;
3571 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3572 BlockStateAsString(xact->blockState));
3576 * BeginInternalSubTransaction
3577 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
3578 * TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
3579 * used in functions that might be called when not inside a BEGIN block
3580 * or when running deferred triggers at COMMIT/PREPARE time. Also, it
3581 * automatically does CommitTransactionCommand/StartTransactionCommand
3582 * instead of expecting the caller to do it.
3585 BeginInternalSubTransaction(char *name)
3587 TransactionState s = CurrentTransactionState;
3589 switch (s->blockState)
3591 case TBLOCK_STARTED:
3592 case TBLOCK_INPROGRESS:
3594 case TBLOCK_PREPARE:
3595 case TBLOCK_SUBINPROGRESS:
3596 /* Normal subtransaction start */
3598 s = CurrentTransactionState; /* changed by push */
3601 * Savepoint names, like the TransactionState block itself, live
3602 * in TopTransactionContext.
3605 s->name = MemoryContextStrdup(TopTransactionContext, name);
3608 /* These cases are invalid. */
3609 case TBLOCK_DEFAULT:
3611 case TBLOCK_SUBBEGIN:
3614 case TBLOCK_SUBABORT:
3615 case TBLOCK_ABORT_END:
3616 case TBLOCK_SUBABORT_END:
3617 case TBLOCK_ABORT_PENDING:
3618 case TBLOCK_SUBABORT_PENDING:
3619 case TBLOCK_SUBRESTART:
3620 case TBLOCK_SUBABORT_RESTART:
3621 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
3622 BlockStateAsString(s->blockState));
3626 CommitTransactionCommand();
3627 StartTransactionCommand();
3631 * ReleaseCurrentSubTransaction
3633 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
3634 * savepoint name (if any).
3635 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3638 ReleaseCurrentSubTransaction(void)
3640 TransactionState s = CurrentTransactionState;
3642 if (s->blockState != TBLOCK_SUBINPROGRESS)
3643 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
3644 BlockStateAsString(s->blockState));
3645 Assert(s->state == TRANS_INPROGRESS);
3646 MemoryContextSwitchTo(CurTransactionContext);
3647 CommitSubTransaction();
3648 s = CurrentTransactionState; /* changed by pop */
3649 Assert(s->state == TRANS_INPROGRESS);
3653 * RollbackAndReleaseCurrentSubTransaction
3655 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
3656 * of its savepoint name (if any).
3657 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3660 RollbackAndReleaseCurrentSubTransaction(void)
3662 TransactionState s = CurrentTransactionState;
3664 switch (s->blockState)
3666 /* Must be in a subtransaction */
3667 case TBLOCK_SUBINPROGRESS:
3668 case TBLOCK_SUBABORT:
3671 /* These cases are invalid. */
3672 case TBLOCK_DEFAULT:
3673 case TBLOCK_STARTED:
3675 case TBLOCK_SUBBEGIN:
3676 case TBLOCK_INPROGRESS:
3680 case TBLOCK_ABORT_END:
3681 case TBLOCK_SUBABORT_END:
3682 case TBLOCK_ABORT_PENDING:
3683 case TBLOCK_SUBABORT_PENDING:
3684 case TBLOCK_SUBRESTART:
3685 case TBLOCK_SUBABORT_RESTART:
3686 case TBLOCK_PREPARE:
3687 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
3688 BlockStateAsString(s->blockState));
3693 * Abort the current subtransaction, if needed.
3695 if (s->blockState == TBLOCK_SUBINPROGRESS)
3696 AbortSubTransaction();
3698 /* And clean it up, too */
3699 CleanupSubTransaction();
3701 s = CurrentTransactionState; /* changed by pop */
3702 AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
3703 s->blockState == TBLOCK_INPROGRESS ||
3704 s->blockState == TBLOCK_STARTED);
3708 * AbortOutOfAnyTransaction
3710 * This routine is provided for error recovery purposes. It aborts any
3711 * active transaction or transaction block, leaving the system in a known
3715 AbortOutOfAnyTransaction(void)
3717 TransactionState s = CurrentTransactionState;
3720 * Get out of any transaction or nested transaction
3724 switch (s->blockState)
3726 case TBLOCK_DEFAULT:
3727 /* Not in a transaction, do nothing */
3729 case TBLOCK_STARTED:
3731 case TBLOCK_INPROGRESS:
3733 case TBLOCK_ABORT_PENDING:
3734 case TBLOCK_PREPARE:
3735 /* In a transaction, so clean up */
3737 CleanupTransaction();
3738 s->blockState = TBLOCK_DEFAULT;
3741 case TBLOCK_ABORT_END:
3742 /* AbortTransaction already done, still need Cleanup */
3743 CleanupTransaction();
3744 s->blockState = TBLOCK_DEFAULT;
3748 * In a subtransaction, so clean it up and abort parent too
3750 case TBLOCK_SUBBEGIN:
3751 case TBLOCK_SUBINPROGRESS:
3753 case TBLOCK_SUBABORT_PENDING:
3754 case TBLOCK_SUBRESTART:
3755 AbortSubTransaction();
3756 CleanupSubTransaction();
3757 s = CurrentTransactionState; /* changed by pop */
3760 case TBLOCK_SUBABORT:
3761 case TBLOCK_SUBABORT_END:
3762 case TBLOCK_SUBABORT_RESTART:
3763 /* As above, but AbortSubTransaction already done */
3764 CleanupSubTransaction();
3765 s = CurrentTransactionState; /* changed by pop */
3768 } while (s->blockState != TBLOCK_DEFAULT);
3770 /* Should be out of all subxacts now */
3771 Assert(s->parent == NULL);
3775 * IsTransactionBlock --- are we within a transaction block?
3778 IsTransactionBlock(void)
3780 TransactionState s = CurrentTransactionState;
3782 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
3789 * IsTransactionOrTransactionBlock --- are we within either a transaction
3790 * or a transaction block? (The backend is only really "idle" when this
3793 * This should match up with IsTransactionBlock and IsTransactionState.
3796 IsTransactionOrTransactionBlock(void)
3798 TransactionState s = CurrentTransactionState;
3800 if (s->blockState == TBLOCK_DEFAULT)
3807 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
3810 TransactionBlockStatusCode(void)
3812 TransactionState s = CurrentTransactionState;
3814 switch (s->blockState)
3816 case TBLOCK_DEFAULT:
3817 case TBLOCK_STARTED:
3818 return 'I'; /* idle --- not in transaction */
3820 case TBLOCK_SUBBEGIN:
3821 case TBLOCK_INPROGRESS:
3822 case TBLOCK_SUBINPROGRESS:
3825 case TBLOCK_PREPARE:
3826 return 'T'; /* in transaction */
3828 case TBLOCK_SUBABORT:
3829 case TBLOCK_ABORT_END:
3830 case TBLOCK_SUBABORT_END:
3831 case TBLOCK_ABORT_PENDING:
3832 case TBLOCK_SUBABORT_PENDING:
3833 case TBLOCK_SUBRESTART:
3834 case TBLOCK_SUBABORT_RESTART:
3835 return 'E'; /* in failed transaction */
3838 /* should never get here */
3839 elog(FATAL, "invalid transaction block state: %s",
3840 BlockStateAsString(s->blockState));
3841 return 0; /* keep compiler quiet */
3848 IsSubTransaction(void)
3850 TransactionState s = CurrentTransactionState;
3852 if (s->nestingLevel >= 2)
3859 * StartSubTransaction
3861 * If you're wondering why this is separate from PushTransaction: it's because
3862 * we can't conveniently do this stuff right inside DefineSavepoint. The
3863 * SAVEPOINT utility command will be executed inside a Portal, and if we
3864 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
3865 * the Portal will undo those settings. So we make DefineSavepoint just
3866 * push a dummy transaction block, and when control returns to the main
3867 * idle loop, CommitTransactionCommand will be called, and we'll come here
3868 * to finish starting the subtransaction.
3871 StartSubTransaction(void)
3873 TransactionState s = CurrentTransactionState;
3875 if (s->state != TRANS_DEFAULT)
3876 elog(WARNING, "StartSubTransaction while in %s state",
3877 TransStateAsString(s->state));
3879 s->state = TRANS_START;
3882 * Initialize subsystems for new subtransaction
3884 * must initialize resource-management stuff first
3886 AtSubStart_Memory();
3887 AtSubStart_ResourceOwner();
3889 AtSubStart_Notify();
3890 AfterTriggerBeginSubXact();
3892 s->state = TRANS_INPROGRESS;
3895 * Call start-of-subxact callbacks
3897 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
3898 s->parent->subTransactionId);
3900 ShowTransactionState("StartSubTransaction");
3904 * CommitSubTransaction
3906 * The caller has to make sure to always reassign CurrentTransactionState
3907 * if it has a local pointer to it after calling this function.
3910 CommitSubTransaction(void)
3912 TransactionState s = CurrentTransactionState;
3914 ShowTransactionState("CommitSubTransaction");
3916 if (s->state != TRANS_INPROGRESS)
3917 elog(WARNING, "CommitSubTransaction while in %s state",
3918 TransStateAsString(s->state));
3920 /* Pre-commit processing goes here -- nothing to do at the moment */
3922 s->state = TRANS_COMMIT;
3924 /* Must CCI to ensure commands of subtransaction are seen as done */
3925 CommandCounterIncrement();
3928 * Prior to 8.4 we marked subcommit in clog at this point. We now only
3929 * perform that step, if required, as part of the atomic update of the
3930 * whole transaction tree at top level commit or abort.
3933 /* Post-commit cleanup */
3934 if (TransactionIdIsValid(s->transactionId))
3935 AtSubCommit_childXids();
3936 AfterTriggerEndSubXact(true);
3937 AtSubCommit_Portals(s->subTransactionId,
3938 s->parent->subTransactionId,
3939 s->parent->curTransactionOwner);
3940 AtEOSubXact_LargeObject(true, s->subTransactionId,
3941 s->parent->subTransactionId);
3942 AtSubCommit_Notify();
3944 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
3945 s->parent->subTransactionId);
3947 ResourceOwnerRelease(s->curTransactionOwner,
3948 RESOURCE_RELEASE_BEFORE_LOCKS,
3950 AtEOSubXact_RelationCache(true, s->subTransactionId,
3951 s->parent->subTransactionId);
3952 AtEOSubXact_Inval(true);
3956 * The only lock we actually release here is the subtransaction XID lock.
3957 * The rest just get transferred to the parent resource owner.
3959 CurrentResourceOwner = s->curTransactionOwner;
3960 if (TransactionIdIsValid(s->transactionId))
3961 XactLockTableDelete(s->transactionId);
3963 ResourceOwnerRelease(s->curTransactionOwner,
3964 RESOURCE_RELEASE_LOCKS,
3966 ResourceOwnerRelease(s->curTransactionOwner,
3967 RESOURCE_RELEASE_AFTER_LOCKS,
3970 AtEOXact_GUC(true, s->gucNestLevel);
3971 AtEOSubXact_SPI(true, s->subTransactionId);
3972 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
3973 s->parent->subTransactionId);
3974 AtEOSubXact_Namespace(true, s->subTransactionId,
3975 s->parent->subTransactionId);
3976 AtEOSubXact_Files(true, s->subTransactionId,
3977 s->parent->subTransactionId);
3978 AtEOSubXact_HashTables(true, s->nestingLevel);
3979 AtEOSubXact_PgStat(true, s->nestingLevel);
3980 AtSubCommit_Snapshot(s->nestingLevel);
3983 * We need to restore the upper transaction's read-only state, in case the
3984 * upper is read-write while the child is read-only; GUC will incorrectly
3985 * think it should leave the child state in place.
3987 XactReadOnly = s->prevXactReadOnly;
3989 CurrentResourceOwner = s->parent->curTransactionOwner;
3990 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3991 ResourceOwnerDelete(s->curTransactionOwner);
3992 s->curTransactionOwner = NULL;
3994 AtSubCommit_Memory();
3996 s->state = TRANS_DEFAULT;
4002 * AbortSubTransaction
4005 AbortSubTransaction(void)
4007 TransactionState s = CurrentTransactionState;
4009 /* Prevent cancel/die interrupt while cleaning up */
4012 /* Make sure we have a valid memory context and resource owner */
4013 AtSubAbort_Memory();
4014 AtSubAbort_ResourceOwner();
4017 * Release any LW locks we might be holding as quickly as possible.
4018 * (Regular locks, however, must be held till we finish aborting.)
4019 * Releasing LW locks is critical since we might try to grab them again
4020 * while cleaning up!
4022 * FIXME This may be incorrect --- Are there some locks we should keep?
4023 * Buffer locks, for example? I don't think so but I'm not sure.
4033 * check the current transaction state
4035 ShowTransactionState("AbortSubTransaction");
4037 if (s->state != TRANS_INPROGRESS)
4038 elog(WARNING, "AbortSubTransaction while in %s state",
4039 TransStateAsString(s->state));
4041 s->state = TRANS_ABORT;
4044 * Reset user ID which might have been changed transiently. (See notes in
4045 * AbortTransaction.)
4047 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
4050 * We can skip all this stuff if the subxact failed before creating a
4053 if (s->curTransactionOwner)
4055 AfterTriggerEndSubXact(false);
4056 AtSubAbort_Portals(s->subTransactionId,
4057 s->parent->subTransactionId,
4058 s->parent->curTransactionOwner);
4059 AtEOSubXact_LargeObject(false, s->subTransactionId,
4060 s->parent->subTransactionId);
4061 AtSubAbort_Notify();
4063 /* Advertise the fact that we aborted in pg_clog. */
4064 (void) RecordTransactionAbort(true);
4066 /* Post-abort cleanup */
4067 if (TransactionIdIsValid(s->transactionId))
4068 AtSubAbort_childXids();
4070 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
4071 s->parent->subTransactionId);
4073 ResourceOwnerRelease(s->curTransactionOwner,
4074 RESOURCE_RELEASE_BEFORE_LOCKS,
4076 AtEOSubXact_RelationCache(false, s->subTransactionId,
4077 s->parent->subTransactionId);
4078 AtEOSubXact_Inval(false);
4080 ResourceOwnerRelease(s->curTransactionOwner,
4081 RESOURCE_RELEASE_LOCKS,
4083 ResourceOwnerRelease(s->curTransactionOwner,
4084 RESOURCE_RELEASE_AFTER_LOCKS,
4087 AtEOXact_GUC(false, s->gucNestLevel);
4088 AtEOSubXact_SPI(false, s->subTransactionId);
4089 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
4090 s->parent->subTransactionId);
4091 AtEOSubXact_Namespace(false, s->subTransactionId,
4092 s->parent->subTransactionId);
4093 AtEOSubXact_Files(false, s->subTransactionId,
4094 s->parent->subTransactionId);
4095 AtEOSubXact_HashTables(false, s->nestingLevel);
4096 AtEOSubXact_PgStat(false, s->nestingLevel);
4097 AtSubAbort_Snapshot(s->nestingLevel);
4101 * Restore the upper transaction's read-only state, too. This should be
4102 * redundant with GUC's cleanup but we may as well do it for consistency
4103 * with the commit case.
4105 XactReadOnly = s->prevXactReadOnly;
4107 RESUME_INTERRUPTS();
4111 * CleanupSubTransaction
4113 * The caller has to make sure to always reassign CurrentTransactionState
4114 * if it has a local pointer to it after calling this function.
4117 CleanupSubTransaction(void)
4119 TransactionState s = CurrentTransactionState;
4121 ShowTransactionState("CleanupSubTransaction");
4123 if (s->state != TRANS_ABORT)
4124 elog(WARNING, "CleanupSubTransaction while in %s state",
4125 TransStateAsString(s->state));
4127 AtSubCleanup_Portals(s->subTransactionId);
4129 CurrentResourceOwner = s->parent->curTransactionOwner;
4130 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4131 if (s->curTransactionOwner)
4132 ResourceOwnerDelete(s->curTransactionOwner);
4133 s->curTransactionOwner = NULL;
4135 AtSubCleanup_Memory();
4137 s->state = TRANS_DEFAULT;
4144 * Create transaction state stack entry for a subtransaction
4146 * The caller has to make sure to always reassign CurrentTransactionState
4147 * if it has a local pointer to it after calling this function.
4150 PushTransaction(void)
4152 TransactionState p = CurrentTransactionState;
4156 * We keep subtransaction state nodes in TopTransactionContext.
4158 s = (TransactionState)
4159 MemoryContextAllocZero(TopTransactionContext,
4160 sizeof(TransactionStateData));
4163 * Assign a subtransaction ID, watching out for counter wraparound.
4165 currentSubTransactionId += 1;
4166 if (currentSubTransactionId == InvalidSubTransactionId)
4168 currentSubTransactionId -= 1;
4171 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
4172 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
4176 * We can now stack a minimally valid subtransaction without fear of
4179 s->transactionId = InvalidTransactionId; /* until assigned */
4180 s->subTransactionId = currentSubTransactionId;
4182 s->nestingLevel = p->nestingLevel + 1;
4183 s->gucNestLevel = NewGUCNestLevel();
4184 s->savepointLevel = p->savepointLevel;
4185 s->state = TRANS_DEFAULT;
4186 s->blockState = TBLOCK_SUBBEGIN;
4187 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
4188 s->prevXactReadOnly = XactReadOnly;
4190 CurrentTransactionState = s;
4193 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
4194 * with the subtransaction from here on out; in particular they should not
4195 * assume that it necessarily has a transaction context, resource owner,
4202 * Pop back to parent transaction state
4204 * The caller has to make sure to always reassign CurrentTransactionState
4205 * if it has a local pointer to it after calling this function.
4208 PopTransaction(void)
4210 TransactionState s = CurrentTransactionState;
4212 if (s->state != TRANS_DEFAULT)
4213 elog(WARNING, "PopTransaction while in %s state",
4214 TransStateAsString(s->state));
4216 if (s->parent == NULL)
4217 elog(FATAL, "PopTransaction with no parent");
4219 CurrentTransactionState = s->parent;
4221 /* Let's just make sure CurTransactionContext is good */
4222 CurTransactionContext = s->parent->curTransactionContext;
4223 MemoryContextSwitchTo(CurTransactionContext);
4225 /* Ditto for ResourceOwner links */
4226 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4227 CurrentResourceOwner = s->parent->curTransactionOwner;
4229 /* Free the old child structure */
4236 * ShowTransactionState
4240 ShowTransactionState(const char *str)
4242 /* skip work if message will definitely not be printed */
4243 if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
4245 elog(DEBUG3, "%s", str);
4246 ShowTransactionStateRec(CurrentTransactionState);
4251 * ShowTransactionStateRec
4252 * Recursive subroutine for ShowTransactionState
4255 ShowTransactionStateRec(TransactionState s)
4259 initStringInfo(&buf);
4261 if (s->nChildXids > 0)
4265 appendStringInfo(&buf, "%u", s->childXids[0]);
4266 for (i = 1; i < s->nChildXids; i++)
4267 appendStringInfo(&buf, " %u", s->childXids[i]);
4271 ShowTransactionStateRec(s->parent);
4273 /* use ereport to suppress computation if msg will not be printed */
4275 (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u%s, nestlvl: %d, children: %s",
4276 PointerIsValid(s->name) ? s->name : "unnamed",
4277 BlockStateAsString(s->blockState),
4278 TransStateAsString(s->state),
4279 (unsigned int) s->transactionId,
4280 (unsigned int) s->subTransactionId,
4281 (unsigned int) currentCommandId,
4282 currentCommandIdUsed ? " (used)" : "",
4283 s->nestingLevel, buf.data)));
4289 * BlockStateAsString
4293 BlockStateAsString(TBlockState blockState)
4297 case TBLOCK_DEFAULT:
4299 case TBLOCK_STARTED:
4303 case TBLOCK_INPROGRESS:
4304 return "INPROGRESS";
4309 case TBLOCK_ABORT_END:
4311 case TBLOCK_ABORT_PENDING:
4312 return "ABORT PEND";
4313 case TBLOCK_PREPARE:
4315 case TBLOCK_SUBBEGIN:
4317 case TBLOCK_SUBINPROGRESS:
4318 return "SUB INPROGRS";
4321 case TBLOCK_SUBABORT:
4323 case TBLOCK_SUBABORT_END:
4324 return "SUB ABORT END";
4325 case TBLOCK_SUBABORT_PENDING:
4326 return "SUB ABRT PEND";
4327 case TBLOCK_SUBRESTART:
4328 return "SUB RESTART";
4329 case TBLOCK_SUBABORT_RESTART:
4330 return "SUB AB RESTRT";
4332 return "UNRECOGNIZED";
4336 * TransStateAsString
4340 TransStateAsString(TransState state)
4348 case TRANS_INPROGRESS:
4357 return "UNRECOGNIZED";
4361 * xactGetCommittedChildren
4363 * Gets the list of committed children of the current transaction. The return
4364 * value is the number of child transactions. *ptr is set to point to an
4365 * array of TransactionIds. The array is allocated in TopTransactionContext;
4366 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
4367 * If there are no subxacts, *ptr is set to NULL.
4370 xactGetCommittedChildren(TransactionId **ptr)
4372 TransactionState s = CurrentTransactionState;
4374 if (s->nChildXids == 0)
4377 *ptr = s->childXids;
4379 return s->nChildXids;
4383 * XLOG support routines
4387 * Before 9.0 this was a fairly short function, but now it performs many
4388 * actions for which the order of execution is critical.
4391 xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid, XLogRecPtr lsn)
4393 TransactionId *sub_xids;
4394 SharedInvalidationMessage *inval_msgs;
4395 TransactionId max_xid;
4398 /* subxid array follows relfilenodes */
4399 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4400 /* invalidation messages array follows subxids */
4401 inval_msgs = (SharedInvalidationMessage *) &(sub_xids[xlrec->nsubxacts]);
4403 max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
4406 * Make sure nextXid is beyond any XID mentioned in the record.
4408 * We don't expect anyone else to modify nextXid, hence we don't need to
4409 * hold a lock while checking this. We still acquire the lock to modify
4412 if (TransactionIdFollowsOrEquals(max_xid,
4413 ShmemVariableCache->nextXid))
4415 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4416 ShmemVariableCache->nextXid = max_xid;
4417 TransactionIdAdvance(ShmemVariableCache->nextXid);
4418 LWLockRelease(XidGenLock);
4421 if (standbyState == STANDBY_DISABLED)
4424 * Mark the transaction committed in pg_clog.
4426 TransactionIdCommitTree(xid, xlrec->nsubxacts, sub_xids);
4431 * If a transaction completion record arrives that has as-yet
4432 * unobserved subtransactions then this will not have been fully
4433 * handled by the call to RecordKnownAssignedTransactionIds() in the
4434 * main recovery loop in xlog.c. So we need to do bookkeeping again to
4435 * cover that case. This is confusing and it is easy to think this
4436 * call is irrelevant, which has happened three times in development
4437 * already. Leave it in.
4439 RecordKnownAssignedTransactionIds(max_xid);
4442 * Mark the transaction committed in pg_clog. We use async commit
4443 * protocol during recovery to provide information on database
4444 * consistency for when users try to set hint bits. It is important
4445 * that we do not set hint bits until the minRecoveryPoint is past
4446 * this commit record. This ensures that if we crash we don't see hint
4447 * bits set on changes made by transactions that haven't yet
4448 * recovered. It's unlikely but it's good to be safe.
4450 TransactionIdAsyncCommitTree(xid, xlrec->nsubxacts, sub_xids, lsn);
4453 * We must mark clog before we update the ProcArray.
4455 ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids, max_xid);
4458 * Send any cache invalidations attached to the commit. We must
4459 * maintain the same order of invalidation then release locks as
4460 * occurs in CommitTransaction().
4462 ProcessCommittedInvalidationMessages(inval_msgs, xlrec->nmsgs,
4463 XactCompletionRelcacheInitFileInval(xlrec),
4464 xlrec->dbId, xlrec->tsId);
4467 * Release locks, if any. We do this for both two phase and normal one
4468 * phase transactions. In effect we are ignoring the prepare phase and
4469 * just going straight to lock release.
4471 StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
4474 /* Make sure files supposed to be dropped are dropped */
4475 for (i = 0; i < xlrec->nrels; i++)
4477 SMgrRelation srel = smgropen(xlrec->xnodes[i]);
4480 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4482 if (smgrexists(srel, fork))
4484 XLogDropRelation(xlrec->xnodes[i], fork);
4485 smgrdounlink(srel, fork, false, true);
4492 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
4493 * in normal operation. For example, in DROP DATABASE, we delete all the
4494 * files belonging to the database, and then commit the transaction. If we
4495 * crash after all the files have been deleted but before the commit, you
4496 * have an entry in pg_database without any files. To minimize the window
4497 * for that, we use ForceSyncCommit() to rush the commit record to disk as
4498 * quick as possible. We have the same window during recovery, and forcing
4499 * an XLogFlush() (which updates minRecoveryPoint during recovery) helps
4500 * to reduce that problem window, for any user that requested
4501 * ForceSyncCommit().
4503 if (XactCompletionForceSyncCommit(xlrec))
4508 * Be careful with the order of execution, as with xact_redo_commit().
4509 * The two functions are similar but differ in key places.
4511 * Note also that an abort can be for a subtransaction and its children,
4512 * not just for a top level abort. That means we have to consider
4513 * topxid != xid, whereas in commit we would find topxid == xid always
4514 * because subtransaction commit is never WAL logged.
4517 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
4519 TransactionId *sub_xids;
4520 TransactionId max_xid;
4523 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4524 max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
4527 * Make sure nextXid is beyond any XID mentioned in the record.
4529 * We don't expect anyone else to modify nextXid, hence we don't need to
4530 * hold a lock while checking this. We still acquire the lock to modify
4533 if (TransactionIdFollowsOrEquals(max_xid,
4534 ShmemVariableCache->nextXid))
4536 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4537 ShmemVariableCache->nextXid = max_xid;
4538 TransactionIdAdvance(ShmemVariableCache->nextXid);
4539 LWLockRelease(XidGenLock);
4542 if (standbyState == STANDBY_DISABLED)
4544 /* Mark the transaction aborted in pg_clog, no need for async stuff */
4545 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4550 * If a transaction completion record arrives that has as-yet
4551 * unobserved subtransactions then this will not have been fully
4552 * handled by the call to RecordKnownAssignedTransactionIds() in the
4553 * main recovery loop in xlog.c. So we need to do bookkeeping again to
4554 * cover that case. This is confusing and it is easy to think this
4555 * call is irrelevant, which has happened three times in development
4556 * already. Leave it in.
4558 RecordKnownAssignedTransactionIds(max_xid);
4560 /* Mark the transaction aborted in pg_clog, no need for async stuff */
4561 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4564 * We must update the ProcArray after we have marked clog.
4566 ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids, max_xid);
4569 * There are no flat files that need updating, nor invalidation
4570 * messages to send or undo.
4574 * Release locks, if any. There are no invalidations to send.
4576 StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
4579 /* Make sure files supposed to be dropped are dropped */
4580 for (i = 0; i < xlrec->nrels; i++)
4582 SMgrRelation srel = smgropen(xlrec->xnodes[i]);
4585 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4587 if (smgrexists(srel, fork))
4589 XLogDropRelation(xlrec->xnodes[i], fork);
4590 smgrdounlink(srel, fork, false, true);
4598 xact_redo(XLogRecPtr lsn, XLogRecord *record)
4600 uint8 info = record->xl_info & ~XLR_INFO_MASK;
4602 /* Backup blocks are not used in xact records */
4603 Assert(!(record->xl_info & XLR_BKP_BLOCK_MASK));
4605 if (info == XLOG_XACT_COMMIT)
4607 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
4609 xact_redo_commit(xlrec, record->xl_xid, lsn);
4611 else if (info == XLOG_XACT_ABORT)
4613 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
4615 xact_redo_abort(xlrec, record->xl_xid);
4617 else if (info == XLOG_XACT_PREPARE)
4619 /* the record contents are exactly the 2PC file */
4620 RecreateTwoPhaseFile(record->xl_xid,
4621 XLogRecGetData(record), record->xl_len);
4623 else if (info == XLOG_XACT_COMMIT_PREPARED)
4625 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
4627 xact_redo_commit(&xlrec->crec, xlrec->xid, lsn);
4628 RemoveTwoPhaseFile(xlrec->xid, false);
4630 else if (info == XLOG_XACT_ABORT_PREPARED)
4632 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
4634 xact_redo_abort(&xlrec->arec, xlrec->xid);
4635 RemoveTwoPhaseFile(xlrec->xid, false);
4637 else if (info == XLOG_XACT_ASSIGNMENT)
4639 xl_xact_assignment *xlrec = (xl_xact_assignment *) XLogRecGetData(record);
4641 if (standbyState >= STANDBY_INITIALIZED)
4642 ProcArrayApplyXidAssignment(xlrec->xtop,
4643 xlrec->nsubxacts, xlrec->xsub);
4646 elog(PANIC, "xact_redo: unknown op code %u", info);
4650 xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
4653 TransactionId *xacts;
4655 xacts = (TransactionId *) &xlrec->xnodes[xlrec->nrels];
4657 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4659 if (xlrec->nrels > 0)
4661 appendStringInfo(buf, "; rels:");
4662 for (i = 0; i < xlrec->nrels; i++)
4664 char *path = relpath(xlrec->xnodes[i], MAIN_FORKNUM);
4666 appendStringInfo(buf, " %s", path);
4670 if (xlrec->nsubxacts > 0)
4672 appendStringInfo(buf, "; subxacts:");
4673 for (i = 0; i < xlrec->nsubxacts; i++)
4674 appendStringInfo(buf, " %u", xacts[i]);
4676 if (xlrec->nmsgs > 0)
4678 SharedInvalidationMessage *msgs;
4680 msgs = (SharedInvalidationMessage *) &xacts[xlrec->nsubxacts];
4682 if (XactCompletionRelcacheInitFileInval(xlrec))
4683 appendStringInfo(buf, "; relcache init file inval dbid %u tsid %u",
4684 xlrec->dbId, xlrec->tsId);
4686 appendStringInfo(buf, "; inval msgs:");
4687 for (i = 0; i < xlrec->nmsgs; i++)
4689 SharedInvalidationMessage *msg = &msgs[i];
4692 appendStringInfo(buf, " catcache %d", msg->id);
4693 else if (msg->id == SHAREDINVALCATALOG_ID)
4694 appendStringInfo(buf, " catalog %u", msg->cat.catId);
4695 else if (msg->id == SHAREDINVALRELCACHE_ID)
4696 appendStringInfo(buf, " relcache %u", msg->rc.relId);
4697 /* remaining cases not expected, but print something anyway */
4698 else if (msg->id == SHAREDINVALSMGR_ID)
4699 appendStringInfo(buf, " smgr");
4700 else if (msg->id == SHAREDINVALRELMAP_ID)
4701 appendStringInfo(buf, " relmap");
4703 appendStringInfo(buf, " unknown id %d", msg->id);
4709 xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
4713 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4714 if (xlrec->nrels > 0)
4716 appendStringInfo(buf, "; rels:");
4717 for (i = 0; i < xlrec->nrels; i++)
4719 char *path = relpath(xlrec->xnodes[i], MAIN_FORKNUM);
4721 appendStringInfo(buf, " %s", path);
4725 if (xlrec->nsubxacts > 0)
4727 TransactionId *xacts = (TransactionId *)
4728 &xlrec->xnodes[xlrec->nrels];
4730 appendStringInfo(buf, "; subxacts:");
4731 for (i = 0; i < xlrec->nsubxacts; i++)
4732 appendStringInfo(buf, " %u", xacts[i]);
4737 xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
4741 appendStringInfo(buf, "subxacts:");
4743 for (i = 0; i < xlrec->nsubxacts; i++)
4744 appendStringInfo(buf, " %u", xlrec->xsub[i]);
4748 xact_desc(StringInfo buf, uint8 xl_info, char *rec)
4750 uint8 info = xl_info & ~XLR_INFO_MASK;
4752 if (info == XLOG_XACT_COMMIT)
4754 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
4756 appendStringInfo(buf, "commit: ");
4757 xact_desc_commit(buf, xlrec);
4759 else if (info == XLOG_XACT_ABORT)
4761 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
4763 appendStringInfo(buf, "abort: ");
4764 xact_desc_abort(buf, xlrec);
4766 else if (info == XLOG_XACT_PREPARE)
4768 appendStringInfo(buf, "prepare");
4770 else if (info == XLOG_XACT_COMMIT_PREPARED)
4772 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
4774 appendStringInfo(buf, "commit prepared %u: ", xlrec->xid);
4775 xact_desc_commit(buf, &xlrec->crec);
4777 else if (info == XLOG_XACT_ABORT_PREPARED)
4779 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
4781 appendStringInfo(buf, "abort prepared %u: ", xlrec->xid);
4782 xact_desc_abort(buf, &xlrec->arec);
4784 else if (info == XLOG_XACT_ASSIGNMENT)
4786 xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
4789 * Note that we ignore the WAL record's xid, since we're more
4790 * interested in the top-level xid that issued the record and which
4791 * xids are being reported here.
4793 appendStringInfo(buf, "xid assignment xtop %u: ", xlrec->xtop);
4794 xact_desc_assignment(buf, xlrec);
4797 appendStringInfo(buf, "UNKNOWN");