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.280 2010/01/09 16:49:27 sriggs 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/snapmgr.h"
56 * User-tweakable parameters
58 int DefaultXactIsoLevel = XACT_READ_COMMITTED;
61 bool DefaultXactReadOnly = false;
64 bool XactSyncCommit = true;
66 int CommitDelay = 0; /* precommit delay in microseconds */
67 int CommitSiblings = 5; /* # concurrent xacts needed to sleep */
70 * MyXactAccessedTempRel is set when a temporary relation is accessed.
71 * We don't allow PREPARE TRANSACTION in that case. (This is global
72 * so that it can be set from heapam.c.)
74 bool MyXactAccessedTempRel = false;
78 * transaction states - transaction state from server perspective
80 typedef enum TransState
82 TRANS_DEFAULT, /* idle */
83 TRANS_START, /* transaction starting */
84 TRANS_INPROGRESS, /* inside a valid transaction */
85 TRANS_COMMIT, /* commit in progress */
86 TRANS_ABORT, /* abort in progress */
87 TRANS_PREPARE /* prepare in progress */
91 * transaction block states - transaction state of client queries
93 * Note: the subtransaction states are used only for non-topmost
94 * transactions; the others appear only in the topmost transaction.
96 typedef enum TBlockState
98 /* not-in-transaction-block states */
99 TBLOCK_DEFAULT, /* idle */
100 TBLOCK_STARTED, /* running single-query transaction */
102 /* transaction block states */
103 TBLOCK_BEGIN, /* starting transaction block */
104 TBLOCK_INPROGRESS, /* live transaction */
105 TBLOCK_END, /* COMMIT received */
106 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
107 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
108 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
109 TBLOCK_PREPARE, /* live xact, PREPARE received */
111 /* subtransaction states */
112 TBLOCK_SUBBEGIN, /* starting a subtransaction */
113 TBLOCK_SUBINPROGRESS, /* live subtransaction */
114 TBLOCK_SUBEND, /* RELEASE received */
115 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
116 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
117 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
118 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
119 TBLOCK_SUBABORT_RESTART /* failed subxact, ROLLBACK TO received */
123 * transaction state structure
125 typedef struct TransactionStateData
127 TransactionId transactionId; /* my XID, or Invalid if none */
128 SubTransactionId subTransactionId; /* my subxact ID */
129 char *name; /* savepoint name, if any */
130 int savepointLevel; /* savepoint level */
131 TransState state; /* low-level state */
132 TBlockState blockState; /* high-level state */
133 int nestingLevel; /* transaction nesting depth */
134 int gucNestLevel; /* GUC context nesting depth */
135 MemoryContext curTransactionContext; /* my xact-lifetime context */
136 ResourceOwner curTransactionOwner; /* my query resources */
137 TransactionId *childXids; /* subcommitted child XIDs, in XID order */
138 int nChildXids; /* # of subcommitted child XIDs */
139 int maxChildXids; /* allocated size of childXids[] */
140 Oid prevUser; /* previous CurrentUserId setting */
141 int prevSecContext; /* previous SecurityRestrictionContext */
142 bool prevXactReadOnly; /* entry-time xact r/o state */
143 bool startedInRecovery; /* did we start in recovery? */
144 struct TransactionStateData *parent; /* back link to parent */
145 } TransactionStateData;
147 typedef TransactionStateData *TransactionState;
150 * CurrentTransactionState always points to the current transaction state
151 * block. It will point to TopTransactionStateData when not in a
152 * transaction at all, or when in a top-level transaction.
154 static TransactionStateData TopTransactionStateData = {
155 0, /* transaction id */
156 0, /* subtransaction id */
157 NULL, /* savepoint name */
158 0, /* savepoint level */
159 TRANS_DEFAULT, /* transaction state */
160 TBLOCK_DEFAULT, /* transaction block state from the client
162 0, /* transaction nesting depth */
163 0, /* GUC context nesting depth */
164 NULL, /* cur transaction context */
165 NULL, /* cur transaction resource owner */
166 NULL, /* subcommitted child Xids */
167 0, /* # of subcommitted child Xids */
168 0, /* allocated size of childXids[] */
169 InvalidOid, /* previous CurrentUserId setting */
170 0, /* previous SecurityRestrictionContext */
171 false, /* entry-time xact r/o state */
172 false, /* startedInRecovery */
173 NULL /* link to parent state block */
177 * unreportedXids holds XIDs of all subtransactions that have not yet been
178 * reported in a XLOG_XACT_ASSIGNMENT record.
180 static int nUnreportedXids;
181 static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS];
183 static TransactionState CurrentTransactionState = &TopTransactionStateData;
186 * The subtransaction ID and command ID assignment counters are global
187 * to a whole transaction, so we do not keep them in the state stack.
189 static SubTransactionId currentSubTransactionId;
190 static CommandId currentCommandId;
191 static bool currentCommandIdUsed;
194 * xactStartTimestamp is the value of transaction_timestamp().
195 * stmtStartTimestamp is the value of statement_timestamp().
196 * xactStopTimestamp is the time at which we log a commit or abort WAL record.
197 * These do not change as we enter and exit subtransactions, so we don't
198 * keep them inside the TransactionState stack.
200 static TimestampTz xactStartTimestamp;
201 static TimestampTz stmtStartTimestamp;
202 static TimestampTz xactStopTimestamp;
205 * GID to be used for preparing the current transaction. This is also
206 * global to a whole transaction, so we don't keep it in the state stack.
208 static char *prepareGID;
211 * Some commands want to force synchronous commit.
213 static bool forceSyncCommit = false;
216 * Private context for transaction-abort work --- we reserve space for this
217 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
218 * when we've run out of memory.
220 static MemoryContext TransactionAbortContext = NULL;
223 * List of add-on start- and end-of-xact callbacks
225 typedef struct XactCallbackItem
227 struct XactCallbackItem *next;
228 XactCallback callback;
232 static XactCallbackItem *Xact_callbacks = NULL;
235 * List of add-on start- and end-of-subxact callbacks
237 typedef struct SubXactCallbackItem
239 struct SubXactCallbackItem *next;
240 SubXactCallback callback;
242 } SubXactCallbackItem;
244 static SubXactCallbackItem *SubXact_callbacks = NULL;
247 /* local function prototypes */
248 static void AssignTransactionId(TransactionState s);
249 static void AbortTransaction(void);
250 static void AtAbort_Memory(void);
251 static void AtCleanup_Memory(void);
252 static void AtAbort_ResourceOwner(void);
253 static void AtCommit_LocalCache(void);
254 static void AtCommit_Memory(void);
255 static void AtStart_Cache(void);
256 static void AtStart_Memory(void);
257 static void AtStart_ResourceOwner(void);
258 static void CallXactCallbacks(XactEvent event);
259 static void CallSubXactCallbacks(SubXactEvent event,
260 SubTransactionId mySubid,
261 SubTransactionId parentSubid);
262 static void CleanupTransaction(void);
263 static void CommitTransaction(void);
264 static TransactionId RecordTransactionAbort(bool isSubXact);
265 static void StartTransaction(void);
267 static void StartSubTransaction(void);
268 static void CommitSubTransaction(void);
269 static void AbortSubTransaction(void);
270 static void CleanupSubTransaction(void);
271 static void PushTransaction(void);
272 static void PopTransaction(void);
274 static void AtSubAbort_Memory(void);
275 static void AtSubCleanup_Memory(void);
276 static void AtSubAbort_ResourceOwner(void);
277 static void AtSubCommit_Memory(void);
278 static void AtSubStart_Memory(void);
279 static void AtSubStart_ResourceOwner(void);
281 static void ShowTransactionState(const char *str);
282 static void ShowTransactionStateRec(TransactionState state);
283 static const char *BlockStateAsString(TBlockState blockState);
284 static const char *TransStateAsString(TransState state);
287 /* ----------------------------------------------------------------
288 * transaction state accessors
289 * ----------------------------------------------------------------
295 * This returns true if we are inside a valid transaction; that is,
296 * it is safe to initiate database access, take heavyweight locks, etc.
299 IsTransactionState(void)
301 TransactionState s = CurrentTransactionState;
304 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
305 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
306 * TRANS_PREPARE since it might be too soon or too late within those
307 * transition states to do anything interesting. Hence, the only "valid"
308 * state is TRANS_INPROGRESS.
310 return (s->state == TRANS_INPROGRESS);
314 * IsAbortedTransactionBlockState
316 * This returns true if we are currently running a query
317 * 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 if (RecoveryInProgress())
406 elog(ERROR, "cannot assign TransactionIds during recovery");
408 /* Assert that caller didn't screw up */
409 Assert(!TransactionIdIsValid(s->transactionId));
410 Assert(s->state == TRANS_INPROGRESS);
413 * Ensure parent(s) have XIDs, so that a child always has an XID later
416 if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
417 AssignTransactionId(s->parent);
420 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
422 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
423 * shared storage other than PG_PROC; because if there's no room for it in
424 * PG_PROC, the subtrans entry is needed to ensure that other backends see
425 * the Xid as "running". See GetNewTransactionId.
427 s->transactionId = GetNewTransactionId(isSubXact);
430 SubTransSetParent(s->transactionId, s->parent->transactionId, false);
433 * Acquire lock on the transaction XID. (We assume this cannot block.) We
434 * have to ensure that the lock is assigned to the transaction's own
437 currentOwner = CurrentResourceOwner;
440 CurrentResourceOwner = s->curTransactionOwner;
441 XactLockTableInsert(s->transactionId);
445 /* Ensure CurrentResourceOwner is restored on error */
446 CurrentResourceOwner = currentOwner;
450 CurrentResourceOwner = currentOwner;
453 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
454 * top-level transaction we issue a WAL record for the assignment. We
455 * include the top-level xid and all the subxids that have not yet been
456 * reported using XLOG_XACT_ASSIGNMENT records.
458 * This is required to limit the amount of shared memory required in a
459 * hot standby server to keep track of in-progress XIDs. See notes for
460 * RecordKnownAssignedTransactionIds().
462 * We don't keep track of the immediate parent of each subxid,
463 * only the top-level transaction that each subxact belongs to. This
464 * is correct in recovery only because aborted subtransactions are
465 * separately WAL logged.
467 if (isSubXact && XLogStandbyInfoActive())
469 unreportedXids[nUnreportedXids] = s->transactionId;
472 /* ensure this test matches similar one in RecoverPreparedTransactions() */
473 if (nUnreportedXids >= PGPROC_MAX_CACHED_SUBXIDS)
475 XLogRecData rdata[2];
476 xl_xact_assignment xlrec;
479 * xtop is always set by now because we recurse up transaction
480 * stack to the highest unassigned xid and then come back down
482 xlrec.xtop = GetTopTransactionId();
483 Assert(TransactionIdIsValid(xlrec.xtop));
484 xlrec.nsubxacts = nUnreportedXids;
486 rdata[0].data = (char *) &xlrec;
487 rdata[0].len = MinSizeOfXactAssignment;
488 rdata[0].buffer = InvalidBuffer;
489 rdata[0].next = &rdata[1];
491 rdata[1].data = (char *) unreportedXids;
492 rdata[1].len = PGPROC_MAX_CACHED_SUBXIDS * sizeof(TransactionId);
493 rdata[1].buffer = InvalidBuffer;
494 rdata[1].next = NULL;
496 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT, rdata);
504 * GetCurrentSubTransactionId
507 GetCurrentSubTransactionId(void)
509 TransactionState s = CurrentTransactionState;
511 return s->subTransactionId;
516 * GetCurrentCommandId
518 * "used" must be TRUE if the caller intends to use the command ID to mark
519 * inserted/updated/deleted tuples. FALSE means the ID is being fetched
520 * for read-only purposes (ie, as a snapshot validity cutoff). See
521 * CommandCounterIncrement() for discussion.
524 GetCurrentCommandId(bool used)
526 /* this is global to a transaction, not subtransaction-local */
528 currentCommandIdUsed = true;
529 return currentCommandId;
533 * GetCurrentTransactionStartTimestamp
536 GetCurrentTransactionStartTimestamp(void)
538 return xactStartTimestamp;
542 * GetCurrentStatementStartTimestamp
545 GetCurrentStatementStartTimestamp(void)
547 return stmtStartTimestamp;
551 * GetCurrentTransactionStopTimestamp
553 * We return current time if the transaction stop time hasn't been set
554 * (which can happen if we decide we don't need to log an XLOG record).
557 GetCurrentTransactionStopTimestamp(void)
559 if (xactStopTimestamp != 0)
560 return xactStopTimestamp;
561 return GetCurrentTimestamp();
565 * SetCurrentStatementStartTimestamp
568 SetCurrentStatementStartTimestamp(void)
570 stmtStartTimestamp = GetCurrentTimestamp();
574 * SetCurrentTransactionStopTimestamp
577 SetCurrentTransactionStopTimestamp(void)
579 xactStopTimestamp = GetCurrentTimestamp();
583 * GetCurrentTransactionNestLevel
585 * Note: this will return zero when not inside any transaction, one when
586 * inside a top-level transaction, etc.
589 GetCurrentTransactionNestLevel(void)
591 TransactionState s = CurrentTransactionState;
593 return s->nestingLevel;
598 * TransactionIdIsCurrentTransactionId
601 TransactionIdIsCurrentTransactionId(TransactionId xid)
606 * We always say that BootstrapTransactionId is "not my transaction ID"
607 * even when it is (ie, during bootstrap). Along with the fact that
608 * transam.c always treats BootstrapTransactionId as already committed,
609 * this causes the tqual.c routines to see all tuples as committed, which
610 * is what we need during bootstrap. (Bootstrap mode only inserts tuples,
611 * it never updates or deletes them, so all tuples can be presumed good
614 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
615 * not my transaction ID, so we can just return "false" immediately for
616 * any non-normal XID.
618 if (!TransactionIdIsNormal(xid))
622 * We will return true for the Xid of the current subtransaction, any of
623 * its subcommitted children, any of its parents, or any of their
624 * previously subcommitted children. However, a transaction being aborted
625 * is no longer "current", even though it may still have an entry on the
628 for (s = CurrentTransactionState; s != NULL; s = s->parent)
633 if (s->state == TRANS_ABORT)
635 if (!TransactionIdIsValid(s->transactionId))
636 continue; /* it can't have any child XIDs either */
637 if (TransactionIdEquals(xid, s->transactionId))
639 /* As the childXids array is ordered, we can use binary search */
641 high = s->nChildXids - 1;
647 middle = low + (high - low) / 2;
648 probe = s->childXids[middle];
649 if (TransactionIdEquals(probe, xid))
651 else if (TransactionIdPrecedes(probe, xid))
662 * TransactionStartedDuringRecovery
664 * Returns true if the current transaction started while recovery was still
665 * in progress. Recovery might have ended since so RecoveryInProgress() might
666 * return false already.
669 TransactionStartedDuringRecovery(void)
671 return CurrentTransactionState->startedInRecovery;
675 * CommandCounterIncrement
678 CommandCounterIncrement(void)
681 * If the current value of the command counter hasn't been "used" to mark
682 * tuples, we need not increment it, since there's no need to distinguish
683 * a read-only command from others. This helps postpone command counter
684 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
686 if (currentCommandIdUsed)
688 currentCommandId += 1;
689 if (currentCommandId == FirstCommandId) /* check for overflow */
691 currentCommandId -= 1;
693 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
694 errmsg("cannot have more than 2^32-1 commands in a transaction")));
696 currentCommandIdUsed = false;
698 /* Propagate new command ID into static snapshots */
699 SnapshotSetCommandId(currentCommandId);
702 * Make any catalog changes done by the just-completed command visible
703 * in the local syscache. We obviously don't need to do this after a
704 * read-only command. (But see hacks in inval.c to make real sure we
705 * don't think a command that queued inval messages was read-only.)
707 AtCommit_LocalCache();
711 * Make any other backends' catalog changes visible to me.
713 * XXX this is probably in the wrong place: CommandCounterIncrement should
714 * be purely a local operation, most likely. However fooling with this
715 * will affect asynchronous cross-backend interactions, which doesn't seem
716 * like a wise thing to do in late beta, so save improving this for
717 * another day - tgl 2007-11-30
725 * Interface routine to allow commands to force a synchronous commit of the
726 * current top-level transaction
729 ForceSyncCommit(void)
731 forceSyncCommit = true;
735 /* ----------------------------------------------------------------
736 * StartTransaction stuff
737 * ----------------------------------------------------------------
746 AcceptInvalidationMessages();
755 TransactionState s = CurrentTransactionState;
758 * If this is the first time through, create a private context for
759 * AbortTransaction to work in. By reserving some space now, we can
760 * insulate AbortTransaction from out-of-memory scenarios. Like
761 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
762 * size, so that space will be reserved immediately.
764 if (TransactionAbortContext == NULL)
765 TransactionAbortContext =
766 AllocSetContextCreate(TopMemoryContext,
767 "TransactionAbortContext",
773 * We shouldn't have a transaction context already.
775 Assert(TopTransactionContext == NULL);
778 * Create a toplevel context for the transaction.
780 TopTransactionContext =
781 AllocSetContextCreate(TopMemoryContext,
782 "TopTransactionContext",
783 ALLOCSET_DEFAULT_MINSIZE,
784 ALLOCSET_DEFAULT_INITSIZE,
785 ALLOCSET_DEFAULT_MAXSIZE);
788 * In a top-level transaction, CurTransactionContext is the same as
789 * TopTransactionContext.
791 CurTransactionContext = TopTransactionContext;
792 s->curTransactionContext = CurTransactionContext;
794 /* Make the CurTransactionContext active. */
795 MemoryContextSwitchTo(CurTransactionContext);
799 * AtStart_ResourceOwner
802 AtStart_ResourceOwner(void)
804 TransactionState s = CurrentTransactionState;
807 * We shouldn't have a transaction resource owner already.
809 Assert(TopTransactionResourceOwner == NULL);
812 * Create a toplevel resource owner for the transaction.
814 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
816 TopTransactionResourceOwner = s->curTransactionOwner;
817 CurTransactionResourceOwner = s->curTransactionOwner;
818 CurrentResourceOwner = s->curTransactionOwner;
821 /* ----------------------------------------------------------------
822 * StartSubTransaction stuff
823 * ----------------------------------------------------------------
830 AtSubStart_Memory(void)
832 TransactionState s = CurrentTransactionState;
834 Assert(CurTransactionContext != NULL);
837 * Create a CurTransactionContext, which will be used to hold data that
838 * survives subtransaction commit but disappears on subtransaction abort.
839 * We make it a child of the immediate parent's CurTransactionContext.
841 CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
842 "CurTransactionContext",
843 ALLOCSET_DEFAULT_MINSIZE,
844 ALLOCSET_DEFAULT_INITSIZE,
845 ALLOCSET_DEFAULT_MAXSIZE);
846 s->curTransactionContext = CurTransactionContext;
848 /* Make the CurTransactionContext active. */
849 MemoryContextSwitchTo(CurTransactionContext);
853 * AtSubStart_ResourceOwner
856 AtSubStart_ResourceOwner(void)
858 TransactionState s = CurrentTransactionState;
860 Assert(s->parent != NULL);
863 * Create a resource owner for the subtransaction. We make it a child of
864 * the immediate parent's resource owner.
866 s->curTransactionOwner =
867 ResourceOwnerCreate(s->parent->curTransactionOwner,
870 CurTransactionResourceOwner = s->curTransactionOwner;
871 CurrentResourceOwner = s->curTransactionOwner;
874 /* ----------------------------------------------------------------
875 * CommitTransaction stuff
876 * ----------------------------------------------------------------
880 * RecordTransactionCommit
882 * Returns latest XID among xact and its children, or InvalidTransactionId
883 * if the xact has no XID. (We compute that here just because it's easier.)
885 * This is exported only to support an ugly hack in VACUUM FULL.
888 RecordTransactionCommit(bool isVacuumFull)
890 TransactionId xid = GetTopTransactionIdIfAny();
891 bool markXidCommitted = TransactionIdIsValid(xid);
892 TransactionId latestXid = InvalidTransactionId;
897 TransactionId *children;
899 SharedInvalidationMessage *invalMessages = NULL;
900 bool RelcacheInitFileInval;
902 /* Get data needed for commit record */
903 nrels = smgrGetPendingDeletes(true, &rels, &haveNonTemp);
904 nchildren = xactGetCommittedChildren(&children);
905 nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
906 &RelcacheInitFileInval);
908 * If we haven't been assigned an XID yet, we neither can, nor do we want
909 * to write a COMMIT record.
911 if (!markXidCommitted)
914 * We expect that every smgrscheduleunlink is followed by a catalog
915 * update, and hence XID assignment, so we shouldn't get here with any
916 * pending deletes. Use a real test not just an Assert to check this,
917 * since it's a bit fragile.
920 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
922 /* Can't have child XIDs either; AssignTransactionId enforces this */
923 Assert(nchildren == 0);
926 * If we didn't create XLOG entries, we're done here; otherwise we
927 * should flush those entries the same as a commit record. (An
928 * example of a possible record that wouldn't cause an XID to be
929 * assigned is a sequence advance record due to nextval() --- we want
930 * to flush that to disk before reporting commit.)
932 if (XactLastRecEnd.xrecoff == 0)
938 * Begin commit critical section and insert the commit XLOG record.
940 XLogRecData rdata[4];
942 xl_xact_commit xlrec;
944 /* Tell bufmgr and smgr to prepare for commit */
948 * Set flags required for recovery processing of commits.
951 if (RelcacheInitFileInval)
952 xlrec.xinfo |= XACT_COMPLETION_UPDATE_RELCACHE_FILE;
954 xlrec.xinfo |= XACT_COMPLETION_VACUUM_FULL;
956 xlrec.xinfo |= XACT_COMPLETION_FORCE_SYNC_COMMIT;
959 * Mark ourselves as within our "commit critical section". This
960 * forces any concurrent checkpoint to wait until we've updated
961 * pg_clog. Without this, it is possible for the checkpoint to set
962 * REDO after the XLOG record but fail to flush the pg_clog update to
963 * disk, leading to loss of the transaction commit if the system
964 * crashes a little later.
966 * Note: we could, but don't bother to, set this flag in
967 * RecordTransactionAbort. That's because loss of a transaction abort
968 * is noncritical; the presumption would be that it aborted, anyway.
970 * It's safe to change the inCommit flag of our own backend without
971 * holding the ProcArrayLock, since we're the only one modifying it.
972 * This makes checkpoint's determination of which xacts are inCommit a
973 * bit fuzzy, but it doesn't matter.
975 START_CRIT_SECTION();
976 MyProc->inCommit = true;
978 SetCurrentTransactionStopTimestamp();
979 xlrec.xact_time = xactStopTimestamp;
981 xlrec.nsubxacts = nchildren;
983 rdata[0].data = (char *) (&xlrec);
984 rdata[0].len = MinSizeOfXactCommit;
985 rdata[0].buffer = InvalidBuffer;
986 /* dump rels to delete */
989 rdata[0].next = &(rdata[1]);
990 rdata[1].data = (char *) rels;
991 rdata[1].len = nrels * sizeof(RelFileNode);
992 rdata[1].buffer = InvalidBuffer;
995 /* dump committed child Xids */
998 rdata[lastrdata].next = &(rdata[2]);
999 rdata[2].data = (char *) children;
1000 rdata[2].len = nchildren * sizeof(TransactionId);
1001 rdata[2].buffer = InvalidBuffer;
1004 /* dump shared cache invalidation messages */
1007 rdata[lastrdata].next = &(rdata[3]);
1008 rdata[3].data = (char *) invalMessages;
1009 rdata[3].len = nmsgs * sizeof(SharedInvalidationMessage);
1010 rdata[3].buffer = InvalidBuffer;
1013 rdata[lastrdata].next = NULL;
1015 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
1019 * Check if we want to commit asynchronously. If the user has set
1020 * synchronous_commit = off, and we're not doing cleanup of any non-temp
1021 * rels nor committing any command that wanted to force sync commit, then
1022 * we can defer flushing XLOG. (We must not allow asynchronous commit if
1023 * there are any non-temp tables to be deleted, because we might delete
1024 * the files before the COMMIT record is flushed to disk. We do allow
1025 * asynchronous commit if all to-be-deleted tables are temporary though,
1026 * since they are lost anyway if we crash.)
1028 if (XactSyncCommit || forceSyncCommit || haveNonTemp)
1031 * Synchronous commit case.
1033 * Sleep before flush! So we can flush more than one commit records
1034 * per single fsync. (The idea is some other backend may do the
1035 * XLogFlush while we're sleeping. This needs work still, because on
1036 * most Unixen, the minimum select() delay is 10msec or more, which is
1039 * We do not sleep if enableFsync is not turned on, nor if there are
1040 * fewer than CommitSiblings other backends with active transactions.
1042 if (CommitDelay > 0 && enableFsync &&
1043 CountActiveBackends() >= CommitSiblings)
1044 pg_usleep(CommitDelay);
1046 XLogFlush(XactLastRecEnd);
1049 * Now we may update the CLOG, if we wrote a COMMIT record above
1051 if (markXidCommitted)
1052 TransactionIdCommitTree(xid, nchildren, children);
1057 * Asynchronous commit case.
1059 * Report the latest async commit LSN, so that the WAL writer knows to
1060 * flush this commit.
1062 XLogSetAsyncCommitLSN(XactLastRecEnd);
1065 * We must not immediately update the CLOG, since we didn't flush the
1066 * XLOG. Instead, we store the LSN up to which the XLOG must be
1067 * flushed before the CLOG may be updated.
1069 if (markXidCommitted)
1070 TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1074 * If we entered a commit critical section, leave it now, and let
1075 * checkpoints proceed.
1077 if (markXidCommitted)
1079 MyProc->inCommit = false;
1083 /* Compute latestXid while we have the child XIDs handy */
1084 latestXid = TransactionIdLatest(xid, nchildren, children);
1086 /* Reset XactLastRecEnd until the next transaction writes something */
1087 XactLastRecEnd.xrecoff = 0;
1090 /* Clean up local data */
1099 * AtCommit_LocalCache
1102 AtCommit_LocalCache(void)
1105 * Make catalog changes visible to me for the next command.
1107 CommandEndInvalidationMessages();
1114 AtCommit_Memory(void)
1117 * Now that we're "out" of a transaction, have the system allocate things
1118 * in the top memory context instead of per-transaction contexts.
1120 MemoryContextSwitchTo(TopMemoryContext);
1123 * Release all transaction-local memory.
1125 Assert(TopTransactionContext != NULL);
1126 MemoryContextDelete(TopTransactionContext);
1127 TopTransactionContext = NULL;
1128 CurTransactionContext = NULL;
1129 CurrentTransactionState->curTransactionContext = NULL;
1132 /* ----------------------------------------------------------------
1133 * CommitSubTransaction stuff
1134 * ----------------------------------------------------------------
1138 * AtSubCommit_Memory
1141 AtSubCommit_Memory(void)
1143 TransactionState s = CurrentTransactionState;
1145 Assert(s->parent != NULL);
1147 /* Return to parent transaction level's memory context. */
1148 CurTransactionContext = s->parent->curTransactionContext;
1149 MemoryContextSwitchTo(CurTransactionContext);
1152 * Ordinarily we cannot throw away the child's CurTransactionContext,
1153 * since the data it contains will be needed at upper commit. However, if
1154 * there isn't actually anything in it, we can throw it away. This avoids
1155 * a small memory leak in the common case of "trivial" subxacts.
1157 if (MemoryContextIsEmpty(s->curTransactionContext))
1159 MemoryContextDelete(s->curTransactionContext);
1160 s->curTransactionContext = NULL;
1165 * AtSubCommit_childXids
1167 * Pass my own XID and my child XIDs up to my parent as committed children.
1170 AtSubCommit_childXids(void)
1172 TransactionState s = CurrentTransactionState;
1175 Assert(s->parent != NULL);
1178 * The parent childXids array will need to hold my XID and all my
1179 * childXids, in addition to the XIDs already there.
1181 new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1183 /* Allocate or enlarge the parent array if necessary */
1184 if (s->parent->maxChildXids < new_nChildXids)
1186 int new_maxChildXids;
1187 TransactionId *new_childXids;
1190 * Make it 2x what's needed right now, to avoid having to enlarge it
1191 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1192 * is what ensures that we don't need to worry about integer overflow
1193 * here or in the calculation of new_nChildXids.)
1195 new_maxChildXids = Min(new_nChildXids * 2,
1196 (int) (MaxAllocSize / sizeof(TransactionId)));
1198 if (new_maxChildXids < new_nChildXids)
1200 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1201 errmsg("maximum number of committed subtransactions (%d) exceeded",
1202 (int) (MaxAllocSize / sizeof(TransactionId)))));
1205 * We keep the child-XID arrays in TopTransactionContext; this avoids
1206 * setting up child-transaction contexts for what might be just a few
1207 * bytes of grandchild XIDs.
1209 if (s->parent->childXids == NULL)
1211 MemoryContextAlloc(TopTransactionContext,
1212 new_maxChildXids * sizeof(TransactionId));
1214 new_childXids = repalloc(s->parent->childXids,
1215 new_maxChildXids * sizeof(TransactionId));
1217 s->parent->childXids = new_childXids;
1218 s->parent->maxChildXids = new_maxChildXids;
1222 * Copy all my XIDs to parent's array.
1224 * Note: We rely on the fact that the XID of a child always follows that
1225 * of its parent. By copying the XID of this subtransaction before the
1226 * XIDs of its children, we ensure that the array stays ordered.
1227 * Likewise, all XIDs already in the array belong to subtransactions
1228 * started and subcommitted before us, so their XIDs must precede ours.
1230 s->parent->childXids[s->parent->nChildXids] = s->transactionId;
1232 if (s->nChildXids > 0)
1233 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1235 s->nChildXids * sizeof(TransactionId));
1237 s->parent->nChildXids = new_nChildXids;
1239 /* Release child's array to avoid leakage */
1240 if (s->childXids != NULL)
1241 pfree(s->childXids);
1242 /* We must reset these to avoid double-free if fail later in commit */
1243 s->childXids = NULL;
1245 s->maxChildXids = 0;
1248 /* ----------------------------------------------------------------
1249 * AbortTransaction stuff
1250 * ----------------------------------------------------------------
1254 * RecordTransactionAbort
1256 * Returns latest XID among xact and its children, or InvalidTransactionId
1257 * if the xact has no XID. (We compute that here just because it's easier.)
1259 static TransactionId
1260 RecordTransactionAbort(bool isSubXact)
1262 TransactionId xid = GetCurrentTransactionIdIfAny();
1263 TransactionId latestXid;
1267 TransactionId *children;
1268 XLogRecData rdata[3];
1270 xl_xact_abort xlrec;
1273 * If we haven't been assigned an XID, nobody will care whether we aborted
1274 * or not. Hence, we're done in that case. It does not matter if we have
1275 * rels to delete (note that this routine is not responsible for actually
1276 * deleting 'em). We cannot have any child XIDs, either.
1278 if (!TransactionIdIsValid(xid))
1280 /* Reset XactLastRecEnd until the next transaction writes something */
1282 XactLastRecEnd.xrecoff = 0;
1283 return InvalidTransactionId;
1287 * We have a valid XID, so we should write an ABORT record for it.
1289 * We do not flush XLOG to disk here, since the default assumption after a
1290 * crash would be that we aborted, anyway. For the same reason, we don't
1291 * need to worry about interlocking against checkpoint start.
1295 * Check that we haven't aborted halfway through RecordTransactionCommit.
1297 if (TransactionIdDidCommit(xid))
1298 elog(PANIC, "cannot abort transaction %u, it was already committed",
1301 /* Fetch the data we need for the abort record */
1302 nrels = smgrGetPendingDeletes(false, &rels, NULL);
1303 nchildren = xactGetCommittedChildren(&children);
1305 /* XXX do we really need a critical section here? */
1306 START_CRIT_SECTION();
1308 /* Write the ABORT record */
1310 xlrec.xact_time = GetCurrentTimestamp();
1313 SetCurrentTransactionStopTimestamp();
1314 xlrec.xact_time = xactStopTimestamp;
1316 xlrec.nrels = nrels;
1317 xlrec.nsubxacts = nchildren;
1318 rdata[0].data = (char *) (&xlrec);
1319 rdata[0].len = MinSizeOfXactAbort;
1320 rdata[0].buffer = InvalidBuffer;
1321 /* dump rels to delete */
1324 rdata[0].next = &(rdata[1]);
1325 rdata[1].data = (char *) rels;
1326 rdata[1].len = nrels * sizeof(RelFileNode);
1327 rdata[1].buffer = InvalidBuffer;
1330 /* dump committed child Xids */
1333 rdata[lastrdata].next = &(rdata[2]);
1334 rdata[2].data = (char *) children;
1335 rdata[2].len = nchildren * sizeof(TransactionId);
1336 rdata[2].buffer = InvalidBuffer;
1339 rdata[lastrdata].next = NULL;
1341 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
1344 * Mark the transaction aborted in clog. This is not absolutely necessary
1345 * but we may as well do it while we are here; also, in the subxact case
1346 * it is helpful because XactLockTableWait makes use of it to avoid
1347 * waiting for already-aborted subtransactions. It is OK to do it without
1348 * having flushed the ABORT record to disk, because in event of a crash
1349 * we'd be assumed to have aborted anyway.
1351 TransactionIdAbortTree(xid, nchildren, children);
1355 /* Compute latestXid while we have the child XIDs handy */
1356 latestXid = TransactionIdLatest(xid, nchildren, children);
1359 * If we're aborting a subtransaction, we can immediately remove failed
1360 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1361 * subxacts, because we already have the child XID array at hand. For
1362 * main xacts, the equivalent happens just after this function returns.
1365 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1367 /* Reset XactLastRecEnd until the next transaction writes something */
1369 XactLastRecEnd.xrecoff = 0;
1371 /* And clean up local data */
1382 AtAbort_Memory(void)
1385 * Switch into TransactionAbortContext, which should have some free space
1386 * even if nothing else does. We'll work in this context until we've
1387 * finished cleaning up.
1389 * It is barely possible to get here when we've not been able to create
1390 * TransactionAbortContext yet; if so use TopMemoryContext.
1392 if (TransactionAbortContext != NULL)
1393 MemoryContextSwitchTo(TransactionAbortContext);
1395 MemoryContextSwitchTo(TopMemoryContext);
1402 AtSubAbort_Memory(void)
1404 Assert(TransactionAbortContext != NULL);
1406 MemoryContextSwitchTo(TransactionAbortContext);
1411 * AtAbort_ResourceOwner
1414 AtAbort_ResourceOwner(void)
1417 * Make sure we have a valid ResourceOwner, if possible (else it will be
1418 * NULL, which is OK)
1420 CurrentResourceOwner = TopTransactionResourceOwner;
1424 * AtSubAbort_ResourceOwner
1427 AtSubAbort_ResourceOwner(void)
1429 TransactionState s = CurrentTransactionState;
1431 /* Make sure we have a valid ResourceOwner */
1432 CurrentResourceOwner = s->curTransactionOwner;
1437 * AtSubAbort_childXids
1440 AtSubAbort_childXids(void)
1442 TransactionState s = CurrentTransactionState;
1445 * We keep the child-XID arrays in TopTransactionContext (see
1446 * AtSubCommit_childXids). This means we'd better free the array
1447 * explicitly at abort to avoid leakage.
1449 if (s->childXids != NULL)
1450 pfree(s->childXids);
1451 s->childXids = NULL;
1453 s->maxChildXids = 0;
1456 * We could prune the unreportedXids array here. But we don't bother.
1457 * That would potentially reduce number of XLOG_XACT_ASSIGNMENT records
1458 * but it would likely introduce more CPU time into the more common
1459 * paths, so we choose not to do that.
1463 /* ----------------------------------------------------------------
1464 * CleanupTransaction stuff
1465 * ----------------------------------------------------------------
1472 AtCleanup_Memory(void)
1474 Assert(CurrentTransactionState->parent == NULL);
1477 * Now that we're "out" of a transaction, have the system allocate things
1478 * in the top memory context instead of per-transaction contexts.
1480 MemoryContextSwitchTo(TopMemoryContext);
1483 * Clear the special abort context for next time.
1485 if (TransactionAbortContext != NULL)
1486 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1489 * Release all transaction-local memory.
1491 if (TopTransactionContext != NULL)
1492 MemoryContextDelete(TopTransactionContext);
1493 TopTransactionContext = NULL;
1494 CurTransactionContext = NULL;
1495 CurrentTransactionState->curTransactionContext = NULL;
1499 /* ----------------------------------------------------------------
1500 * CleanupSubTransaction stuff
1501 * ----------------------------------------------------------------
1505 * AtSubCleanup_Memory
1508 AtSubCleanup_Memory(void)
1510 TransactionState s = CurrentTransactionState;
1512 Assert(s->parent != NULL);
1514 /* Make sure we're not in an about-to-be-deleted context */
1515 MemoryContextSwitchTo(s->parent->curTransactionContext);
1516 CurTransactionContext = s->parent->curTransactionContext;
1519 * Clear the special abort context for next time.
1521 if (TransactionAbortContext != NULL)
1522 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1525 * Delete the subxact local memory contexts. Its CurTransactionContext can
1526 * go too (note this also kills CurTransactionContexts from any children
1529 if (s->curTransactionContext)
1530 MemoryContextDelete(s->curTransactionContext);
1531 s->curTransactionContext = NULL;
1534 /* ----------------------------------------------------------------
1535 * interface routines
1536 * ----------------------------------------------------------------
1543 StartTransaction(void)
1546 VirtualTransactionId vxid;
1549 * Let's just make sure the state stack is empty
1551 s = &TopTransactionStateData;
1552 CurrentTransactionState = s;
1555 * check the current transaction state
1557 if (s->state != TRANS_DEFAULT)
1558 elog(WARNING, "StartTransaction while in %s state",
1559 TransStateAsString(s->state));
1562 * set the current transaction state information appropriately during
1565 s->state = TRANS_START;
1566 s->transactionId = InvalidTransactionId; /* until assigned */
1569 * Make sure we've reset xact state variables
1571 * If recovery is still in progress, mark this transaction as read-only.
1572 * We have lower level defences in XLogInsert and elsewhere to stop us
1573 * from modifying data during recovery, but this gives the normal
1574 * indication to the user that the transaction is read-only.
1576 if (RecoveryInProgress())
1578 s->startedInRecovery = true;
1579 XactReadOnly = true;
1583 s->startedInRecovery = false;
1584 XactReadOnly = DefaultXactReadOnly;
1586 XactIsoLevel = DefaultXactIsoLevel;
1587 forceSyncCommit = false;
1588 MyXactAccessedTempRel = false;
1591 * reinitialize within-transaction counters
1593 s->subTransactionId = TopSubTransactionId;
1594 currentSubTransactionId = TopSubTransactionId;
1595 currentCommandId = FirstCommandId;
1596 currentCommandIdUsed = false;
1599 * initialize reported xid accounting
1601 nUnreportedXids = 0;
1604 * must initialize resource-management stuff first
1607 AtStart_ResourceOwner();
1610 * Assign a new LocalTransactionId, and combine it with the backendId to
1611 * form a virtual transaction id.
1613 vxid.backendId = MyBackendId;
1614 vxid.localTransactionId = GetNextLocalTransactionId();
1617 * Lock the virtual transaction id before we announce it in the proc array
1619 VirtualXactLockTableInsert(vxid);
1622 * Advertise it in the proc array. We assume assignment of
1623 * LocalTransactionID is atomic, and the backendId should be set already.
1625 Assert(MyProc->backendId == vxid.backendId);
1626 MyProc->lxid = vxid.localTransactionId;
1628 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
1631 * set transaction_timestamp() (a/k/a now()). We want this to be the same
1632 * as the first command's statement_timestamp(), so don't do a fresh
1633 * GetCurrentTimestamp() call (which'd be expensive anyway). Also, mark
1634 * xactStopTimestamp as unset.
1636 xactStartTimestamp = stmtStartTimestamp;
1637 xactStopTimestamp = 0;
1638 pgstat_report_xact_timestamp(xactStartTimestamp);
1641 * initialize current transaction state fields
1643 * note: prevXactReadOnly is not used at the outermost level
1645 s->nestingLevel = 1;
1646 s->gucNestLevel = 1;
1647 s->childXids = NULL;
1649 s->maxChildXids = 0;
1650 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
1651 /* SecurityRestrictionContext should never be set outside a transaction */
1652 Assert(s->prevSecContext == 0);
1655 * initialize other subsystems for new transaction
1660 AfterTriggerBeginXact();
1663 * done with start processing, set current transaction state to "in
1666 s->state = TRANS_INPROGRESS;
1668 ShowTransactionState("StartTransaction");
1675 * NB: if you change this routine, better look at PrepareTransaction too!
1678 CommitTransaction(void)
1680 TransactionState s = CurrentTransactionState;
1681 TransactionId latestXid;
1683 ShowTransactionState("CommitTransaction");
1686 * check the current transaction state
1688 if (s->state != TRANS_INPROGRESS)
1689 elog(WARNING, "CommitTransaction while in %s state",
1690 TransStateAsString(s->state));
1691 Assert(s->parent == NULL);
1694 * Do pre-commit processing (most of this stuff requires database access,
1695 * and in fact could still cause an error...)
1697 * It is possible for CommitHoldablePortals to invoke functions that queue
1698 * deferred triggers, and it's also possible that triggers create holdable
1699 * cursors. So we have to loop until there's nothing left to do.
1704 * Fire all currently pending deferred triggers.
1706 AfterTriggerFireDeferred();
1709 * Convert any open holdable cursors into static portals. If there
1710 * weren't any, we are done ... otherwise loop back to check if they
1711 * queued deferred triggers. Lather, rinse, repeat.
1713 if (!CommitHoldablePortals())
1717 /* Now we can shut down the deferred-trigger manager */
1718 AfterTriggerEndXact(true);
1720 /* Close any open regular cursors */
1724 * Let ON COMMIT management do its thing (must happen after closing
1725 * cursors, to avoid dangling-reference problems)
1727 PreCommit_on_commit_actions();
1729 /* close large objects before lower-level cleanup */
1730 AtEOXact_LargeObject(true);
1732 /* NOTIFY commit must come before lower-level cleanup */
1735 /* Prevent cancel/die interrupt while cleaning up */
1739 * set the current transaction state information appropriately during
1742 s->state = TRANS_COMMIT;
1745 * Here is where we really truly commit.
1747 latestXid = RecordTransactionCommit(false);
1749 TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
1752 * Let others know about no transaction in progress by me. Note that this
1753 * must be done _before_ releasing locks we hold and _after_
1754 * RecordTransactionCommit.
1756 ProcArrayEndTransaction(MyProc, latestXid);
1759 * This is all post-commit cleanup. Note that if an error is raised here,
1760 * it's too late to abort the transaction. This should be just
1761 * noncritical resource releasing.
1763 * The ordering of operations is not entirely random. The idea is:
1764 * release resources visible to other backends (eg, files, buffer pins);
1765 * then release locks; then release backend-local resources. We want to
1766 * release locks at the point where any backend waiting for us will see
1767 * our transaction as being fully cleaned up.
1769 * Resources that can be associated with individual queries are handled by
1770 * the ResourceOwner mechanism. The other calls here are for backend-wide
1774 CallXactCallbacks(XACT_EVENT_COMMIT);
1776 ResourceOwnerRelease(TopTransactionResourceOwner,
1777 RESOURCE_RELEASE_BEFORE_LOCKS,
1780 /* Check we've released all buffer pins */
1781 AtEOXact_Buffers(true);
1783 /* Clean up the relation cache */
1784 AtEOXact_RelationCache(true);
1786 /* Clean up the snapshot manager */
1787 AtEarlyCommit_Snapshot();
1790 * Make catalog changes visible to all backends. This has to happen after
1791 * relcache references are dropped (see comments for
1792 * AtEOXact_RelationCache), but before locks are released (if anyone is
1793 * waiting for lock on a relation we've modified, we want them to know
1794 * about the catalog change before they start using the relation).
1796 AtEOXact_Inval(true);
1799 * Likewise, dropping of files deleted during the transaction is best done
1800 * after releasing relcache and buffer pins. (This is not strictly
1801 * necessary during commit, since such pins should have been released
1802 * already, but this ordering is definitely critical during abort.)
1804 smgrDoPendingDeletes(true);
1806 AtEOXact_MultiXact();
1808 ResourceOwnerRelease(TopTransactionResourceOwner,
1809 RESOURCE_RELEASE_LOCKS,
1811 ResourceOwnerRelease(TopTransactionResourceOwner,
1812 RESOURCE_RELEASE_AFTER_LOCKS,
1815 /* Check we've released all catcache entries */
1816 AtEOXact_CatCache(true);
1818 AtEOXact_GUC(true, 1);
1820 AtEOXact_on_commit_actions(true);
1821 AtEOXact_Namespace(true);
1822 /* smgrcommit already done */
1824 AtEOXact_ComboCid();
1825 AtEOXact_HashTables(true);
1826 AtEOXact_PgStat(true);
1827 AtEOXact_Snapshot(true);
1828 pgstat_report_xact_timestamp(0);
1830 CurrentResourceOwner = NULL;
1831 ResourceOwnerDelete(TopTransactionResourceOwner);
1832 s->curTransactionOwner = NULL;
1833 CurTransactionResourceOwner = NULL;
1834 TopTransactionResourceOwner = NULL;
1838 s->transactionId = InvalidTransactionId;
1839 s->subTransactionId = InvalidSubTransactionId;
1840 s->nestingLevel = 0;
1841 s->gucNestLevel = 0;
1842 s->childXids = NULL;
1844 s->maxChildXids = 0;
1847 * done with commit processing, set current transaction state back to
1850 s->state = TRANS_DEFAULT;
1852 RESUME_INTERRUPTS();
1857 * PrepareTransaction
1859 * NB: if you change this routine, better look at CommitTransaction too!
1862 PrepareTransaction(void)
1864 TransactionState s = CurrentTransactionState;
1865 TransactionId xid = GetCurrentTransactionId();
1866 GlobalTransaction gxact;
1867 TimestampTz prepared_at;
1869 ShowTransactionState("PrepareTransaction");
1872 * check the current transaction state
1874 if (s->state != TRANS_INPROGRESS)
1875 elog(WARNING, "PrepareTransaction while in %s state",
1876 TransStateAsString(s->state));
1877 Assert(s->parent == NULL);
1880 * Do pre-commit processing (most of this stuff requires database access,
1881 * and in fact could still cause an error...)
1883 * It is possible for PrepareHoldablePortals to invoke functions that
1884 * queue deferred triggers, and it's also possible that triggers create
1885 * holdable cursors. So we have to loop until there's nothing left to do.
1890 * Fire all currently pending deferred triggers.
1892 AfterTriggerFireDeferred();
1895 * Convert any open holdable cursors into static portals. If there
1896 * weren't any, we are done ... otherwise loop back to check if they
1897 * queued deferred triggers. Lather, rinse, repeat.
1899 if (!PrepareHoldablePortals())
1903 /* Now we can shut down the deferred-trigger manager */
1904 AfterTriggerEndXact(true);
1906 /* Close any open regular cursors */
1910 * Let ON COMMIT management do its thing (must happen after closing
1911 * cursors, to avoid dangling-reference problems)
1913 PreCommit_on_commit_actions();
1915 /* close large objects before lower-level cleanup */
1916 AtEOXact_LargeObject(true);
1918 /* NOTIFY will be handled below */
1921 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
1922 * this transaction. Having the prepared xact hold locks on another
1923 * backend's temp table seems a bad idea --- for instance it would prevent
1924 * the backend from exiting. There are other problems too, such as how to
1925 * clean up the source backend's local buffers and ON COMMIT state if the
1926 * prepared xact includes a DROP of a temp table.
1928 * We must check this after executing any ON COMMIT actions, because they
1929 * might still access a temp relation.
1931 * XXX In principle this could be relaxed to allow some useful special
1932 * cases, such as a temp table created and dropped all within the
1933 * transaction. That seems to require much more bookkeeping though.
1935 if (MyXactAccessedTempRel)
1937 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1938 errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
1940 /* Prevent cancel/die interrupt while cleaning up */
1944 * set the current transaction state information appropriately during
1945 * prepare processing
1947 s->state = TRANS_PREPARE;
1949 prepared_at = GetCurrentTimestamp();
1951 /* Tell bufmgr and smgr to prepare for commit */
1955 * Reserve the GID for this transaction. This could fail if the requested
1956 * GID is invalid or already in use.
1958 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
1959 GetUserId(), MyDatabaseId);
1963 * Collect data for the 2PC state file. Note that in general, no actual
1964 * state change should happen in the called modules during this step,
1965 * since it's still possible to fail before commit, and in that case we
1966 * want transaction abort to be able to clean up. (In particular, the
1967 * AtPrepare routines may error out if they find cases they cannot
1968 * handle.) State cleanup should happen in the PostPrepare routines
1969 * below. However, some modules can go ahead and clear state here because
1970 * they wouldn't do anything with it during abort anyway.
1972 * Note: because the 2PC state file records will be replayed in the same
1973 * order they are made, the order of these calls has to match the order in
1974 * which we want things to happen during COMMIT PREPARED or ROLLBACK
1975 * PREPARED; in particular, pay attention to whether things should happen
1976 * before or after releasing the transaction's locks.
1978 StartPrepare(gxact);
1983 AtPrepare_MultiXact();
1986 * Here is where we really truly prepare.
1988 * We have to record transaction prepares even if we didn't make any
1989 * updates, because the transaction manager might get confused if we lose
1990 * a global transaction.
1995 * Now we clean up backend-internal state and release internal resources.
1998 /* Reset XactLastRecEnd until the next transaction writes something */
1999 XactLastRecEnd.xrecoff = 0;
2002 * Let others know about no transaction in progress by me. This has to be
2003 * done *after* the prepared transaction has been marked valid, else
2004 * someone may think it is unlocked and recyclable.
2006 ProcArrayClearTransaction(MyProc);
2009 * This is all post-transaction cleanup. Note that if an error is raised
2010 * here, it's too late to abort the transaction. This should be just
2011 * noncritical resource releasing. See notes in CommitTransaction.
2014 CallXactCallbacks(XACT_EVENT_PREPARE);
2016 ResourceOwnerRelease(TopTransactionResourceOwner,
2017 RESOURCE_RELEASE_BEFORE_LOCKS,
2020 /* Check we've released all buffer pins */
2021 AtEOXact_Buffers(true);
2023 /* Clean up the relation cache */
2024 AtEOXact_RelationCache(true);
2026 /* Clean up the snapshot manager */
2027 AtEarlyCommit_Snapshot();
2029 /* notify doesn't need a postprepare call */
2031 PostPrepare_PgStat();
2033 PostPrepare_Inval();
2037 PostPrepare_MultiXact(xid);
2039 PostPrepare_Locks(xid);
2041 ResourceOwnerRelease(TopTransactionResourceOwner,
2042 RESOURCE_RELEASE_LOCKS,
2044 ResourceOwnerRelease(TopTransactionResourceOwner,
2045 RESOURCE_RELEASE_AFTER_LOCKS,
2048 /* Check we've released all catcache entries */
2049 AtEOXact_CatCache(true);
2051 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2052 AtEOXact_GUC(true, 1);
2054 AtEOXact_on_commit_actions(true);
2055 AtEOXact_Namespace(true);
2056 /* smgrcommit already done */
2058 AtEOXact_ComboCid();
2059 AtEOXact_HashTables(true);
2060 /* don't call AtEOXact_PgStat here */
2061 AtEOXact_Snapshot(true);
2063 CurrentResourceOwner = NULL;
2064 ResourceOwnerDelete(TopTransactionResourceOwner);
2065 s->curTransactionOwner = NULL;
2066 CurTransactionResourceOwner = NULL;
2067 TopTransactionResourceOwner = NULL;
2071 s->transactionId = InvalidTransactionId;
2072 s->subTransactionId = InvalidSubTransactionId;
2073 s->nestingLevel = 0;
2074 s->gucNestLevel = 0;
2075 s->childXids = NULL;
2077 s->maxChildXids = 0;
2080 * done with 1st phase commit processing, set current transaction state
2083 s->state = TRANS_DEFAULT;
2085 RESUME_INTERRUPTS();
2093 AbortTransaction(void)
2095 TransactionState s = CurrentTransactionState;
2096 TransactionId latestXid;
2098 /* Prevent cancel/die interrupt while cleaning up */
2101 /* Make sure we have a valid memory context and resource owner */
2103 AtAbort_ResourceOwner();
2106 * Release any LW locks we might be holding as quickly as possible.
2107 * (Regular locks, however, must be held till we finish aborting.)
2108 * Releasing LW locks is critical since we might try to grab them again
2109 * while cleaning up!
2113 /* Clean up buffer I/O and buffer context locks, too */
2118 * Also clean up any open wait for lock, since the lock manager will choke
2119 * if we try to wait for another lock before doing this.
2124 * check the current transaction state
2126 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2127 elog(WARNING, "AbortTransaction while in %s state",
2128 TransStateAsString(s->state));
2129 Assert(s->parent == NULL);
2132 * set the current transaction state information appropriately during the
2135 s->state = TRANS_ABORT;
2138 * Reset user ID which might have been changed transiently. We need this
2139 * to clean up in case control escaped out of a SECURITY DEFINER function
2140 * or other local change of CurrentUserId; therefore, the prior value of
2141 * SecurityRestrictionContext also needs to be restored.
2143 * (Note: it is not necessary to restore session authorization or role
2144 * settings here because those can only be changed via GUC, and GUC will
2145 * take care of rolling them back if need be.)
2147 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
2150 * do abort processing
2152 AfterTriggerEndXact(false);
2154 AtEOXact_LargeObject(false); /* 'false' means it's abort */
2158 * Advertise the fact that we aborted in pg_clog (assuming that we got as
2159 * far as assigning an XID to advertise).
2161 latestXid = RecordTransactionAbort(false);
2163 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
2166 * Let others know about no transaction in progress by me. Note that this
2167 * must be done _before_ releasing locks we hold and _after_
2168 * RecordTransactionAbort.
2170 ProcArrayEndTransaction(MyProc, latestXid);
2173 * Post-abort cleanup. See notes in CommitTransaction() concerning
2177 CallXactCallbacks(XACT_EVENT_ABORT);
2179 ResourceOwnerRelease(TopTransactionResourceOwner,
2180 RESOURCE_RELEASE_BEFORE_LOCKS,
2182 AtEOXact_Buffers(false);
2183 AtEOXact_RelationCache(false);
2184 AtEOXact_Inval(false);
2185 smgrDoPendingDeletes(false);
2186 AtEOXact_MultiXact();
2187 ResourceOwnerRelease(TopTransactionResourceOwner,
2188 RESOURCE_RELEASE_LOCKS,
2190 ResourceOwnerRelease(TopTransactionResourceOwner,
2191 RESOURCE_RELEASE_AFTER_LOCKS,
2193 AtEOXact_CatCache(false);
2195 AtEOXact_GUC(false, 1);
2196 AtEOXact_SPI(false);
2197 AtEOXact_on_commit_actions(false);
2198 AtEOXact_Namespace(false);
2200 AtEOXact_ComboCid();
2201 AtEOXact_HashTables(false);
2202 AtEOXact_PgStat(false);
2203 AtEOXact_Snapshot(false);
2204 pgstat_report_xact_timestamp(0);
2207 * State remains TRANS_ABORT until CleanupTransaction().
2209 RESUME_INTERRUPTS();
2213 * CleanupTransaction
2216 CleanupTransaction(void)
2218 TransactionState s = CurrentTransactionState;
2221 * State should still be TRANS_ABORT from AbortTransaction().
2223 if (s->state != TRANS_ABORT)
2224 elog(FATAL, "CleanupTransaction: unexpected state %s",
2225 TransStateAsString(s->state));
2228 * do abort cleanup processing
2230 AtCleanup_Portals(); /* now safe to release portal memory */
2232 CurrentResourceOwner = NULL; /* and resource owner */
2233 if (TopTransactionResourceOwner)
2234 ResourceOwnerDelete(TopTransactionResourceOwner);
2235 s->curTransactionOwner = NULL;
2236 CurTransactionResourceOwner = NULL;
2237 TopTransactionResourceOwner = NULL;
2239 AtCleanup_Memory(); /* and transaction memory */
2241 s->transactionId = InvalidTransactionId;
2242 s->subTransactionId = InvalidSubTransactionId;
2243 s->nestingLevel = 0;
2244 s->gucNestLevel = 0;
2245 s->childXids = NULL;
2247 s->maxChildXids = 0;
2250 * done with abort processing, set current transaction state back to
2253 s->state = TRANS_DEFAULT;
2257 * StartTransactionCommand
2260 StartTransactionCommand(void)
2262 TransactionState s = CurrentTransactionState;
2264 switch (s->blockState)
2267 * if we aren't in a transaction block, we just do our usual start
2270 case TBLOCK_DEFAULT:
2272 s->blockState = TBLOCK_STARTED;
2276 * We are somewhere in a transaction block or subtransaction and
2277 * about to start a new command. For now we do nothing, but
2278 * someday we may do command-local resource initialization. (Note
2279 * that any needed CommandCounterIncrement was done by the
2280 * previous CommitTransactionCommand.)
2282 case TBLOCK_INPROGRESS:
2283 case TBLOCK_SUBINPROGRESS:
2287 * Here we are in a failed transaction block (one of the commands
2288 * caused an abort) so we do nothing but remain in the abort
2289 * state. Eventually we will get a ROLLBACK command which will
2290 * get us out of this state. (It is up to other code to ensure
2291 * that no commands other than ROLLBACK will be processed in these
2295 case TBLOCK_SUBABORT:
2298 /* These cases are invalid. */
2299 case TBLOCK_STARTED:
2301 case TBLOCK_SUBBEGIN:
2304 case TBLOCK_ABORT_END:
2305 case TBLOCK_SUBABORT_END:
2306 case TBLOCK_ABORT_PENDING:
2307 case TBLOCK_SUBABORT_PENDING:
2308 case TBLOCK_SUBRESTART:
2309 case TBLOCK_SUBABORT_RESTART:
2310 case TBLOCK_PREPARE:
2311 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2312 BlockStateAsString(s->blockState));
2317 * We must switch to CurTransactionContext before returning. This is
2318 * already done if we called StartTransaction, otherwise not.
2320 Assert(CurTransactionContext != NULL);
2321 MemoryContextSwitchTo(CurTransactionContext);
2325 * CommitTransactionCommand
2328 CommitTransactionCommand(void)
2330 TransactionState s = CurrentTransactionState;
2332 switch (s->blockState)
2335 * This shouldn't happen, because it means the previous
2336 * StartTransactionCommand didn't set the STARTED state
2339 case TBLOCK_DEFAULT:
2340 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2341 BlockStateAsString(s->blockState));
2345 * If we aren't in a transaction block, just do our usual
2346 * transaction commit, and return to the idle state.
2348 case TBLOCK_STARTED:
2349 CommitTransaction();
2350 s->blockState = TBLOCK_DEFAULT;
2354 * We are completing a "BEGIN TRANSACTION" command, so we change
2355 * to the "transaction block in progress" state and return. (We
2356 * assume the BEGIN did nothing to the database, so we need no
2357 * CommandCounterIncrement.)
2360 s->blockState = TBLOCK_INPROGRESS;
2364 * This is the case when we have finished executing a command
2365 * someplace within a transaction block. We increment the command
2366 * counter and return.
2368 case TBLOCK_INPROGRESS:
2369 case TBLOCK_SUBINPROGRESS:
2370 CommandCounterIncrement();
2374 * We are completing a "COMMIT" command. Do it and return to the
2378 CommitTransaction();
2379 s->blockState = TBLOCK_DEFAULT;
2383 * Here we are in the middle of a transaction block but one of the
2384 * commands caused an abort so we do nothing but remain in the
2385 * abort state. Eventually we will get a ROLLBACK comand.
2388 case TBLOCK_SUBABORT:
2392 * Here we were in an aborted transaction block and we just got
2393 * the ROLLBACK command from the user, so clean up the
2394 * already-aborted transaction and return to the idle state.
2396 case TBLOCK_ABORT_END:
2397 CleanupTransaction();
2398 s->blockState = TBLOCK_DEFAULT;
2402 * Here we were in a perfectly good transaction block but the user
2403 * told us to ROLLBACK anyway. We have to abort the transaction
2404 * and then clean up.
2406 case TBLOCK_ABORT_PENDING:
2408 CleanupTransaction();
2409 s->blockState = TBLOCK_DEFAULT;
2413 * We are completing a "PREPARE TRANSACTION" command. Do it and
2414 * return to the idle state.
2416 case TBLOCK_PREPARE:
2417 PrepareTransaction();
2418 s->blockState = TBLOCK_DEFAULT;
2422 * We were just issued a SAVEPOINT inside a transaction block.
2423 * Start a subtransaction. (DefineSavepoint already did
2424 * PushTransaction, so as to have someplace to put the SUBBEGIN
2427 case TBLOCK_SUBBEGIN:
2428 StartSubTransaction();
2429 s->blockState = TBLOCK_SUBINPROGRESS;
2433 * We were issued a COMMIT or RELEASE command, so we end the
2434 * current subtransaction and return to the parent transaction.
2435 * The parent might be ended too, so repeat till we are all the
2436 * way out or find an INPROGRESS transaction.
2441 CommitSubTransaction();
2442 s = CurrentTransactionState; /* changed by pop */
2443 } while (s->blockState == TBLOCK_SUBEND);
2444 /* If we had a COMMIT command, finish off the main xact too */
2445 if (s->blockState == TBLOCK_END)
2447 Assert(s->parent == NULL);
2448 CommitTransaction();
2449 s->blockState = TBLOCK_DEFAULT;
2451 else if (s->blockState == TBLOCK_PREPARE)
2453 Assert(s->parent == NULL);
2454 PrepareTransaction();
2455 s->blockState = TBLOCK_DEFAULT;
2459 Assert(s->blockState == TBLOCK_INPROGRESS ||
2460 s->blockState == TBLOCK_SUBINPROGRESS);
2465 * The current already-failed subtransaction is ending due to a
2466 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2467 * examine the parent (which could be in any of several states).
2469 case TBLOCK_SUBABORT_END:
2470 CleanupSubTransaction();
2471 CommitTransactionCommand();
2475 * As above, but it's not dead yet, so abort first.
2477 case TBLOCK_SUBABORT_PENDING:
2478 AbortSubTransaction();
2479 CleanupSubTransaction();
2480 CommitTransactionCommand();
2484 * The current subtransaction is the target of a ROLLBACK TO
2485 * command. Abort and pop it, then start a new subtransaction
2486 * with the same name.
2488 case TBLOCK_SUBRESTART:
2493 /* save name and keep Cleanup from freeing it */
2496 savepointLevel = s->savepointLevel;
2498 AbortSubTransaction();
2499 CleanupSubTransaction();
2501 DefineSavepoint(NULL);
2502 s = CurrentTransactionState; /* changed by push */
2504 s->savepointLevel = savepointLevel;
2506 /* This is the same as TBLOCK_SUBBEGIN case */
2507 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2508 StartSubTransaction();
2509 s->blockState = TBLOCK_SUBINPROGRESS;
2514 * Same as above, but the subtransaction had already failed, so we
2515 * don't need AbortSubTransaction.
2517 case TBLOCK_SUBABORT_RESTART:
2522 /* save name and keep Cleanup from freeing it */
2525 savepointLevel = s->savepointLevel;
2527 CleanupSubTransaction();
2529 DefineSavepoint(NULL);
2530 s = CurrentTransactionState; /* changed by push */
2532 s->savepointLevel = savepointLevel;
2534 /* This is the same as TBLOCK_SUBBEGIN case */
2535 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2536 StartSubTransaction();
2537 s->blockState = TBLOCK_SUBINPROGRESS;
2544 * AbortCurrentTransaction
2547 AbortCurrentTransaction(void)
2549 TransactionState s = CurrentTransactionState;
2551 switch (s->blockState)
2553 case TBLOCK_DEFAULT:
2554 if (s->state == TRANS_DEFAULT)
2556 /* we are idle, so nothing to do */
2561 * We can get here after an error during transaction start
2562 * (state will be TRANS_START). Need to clean up the
2563 * incompletely started transaction. First, adjust the
2564 * low-level state to suppress warning message from
2567 if (s->state == TRANS_START)
2568 s->state = TRANS_INPROGRESS;
2570 CleanupTransaction();
2575 * if we aren't in a transaction block, we just do the basic abort
2576 * & cleanup transaction.
2578 case TBLOCK_STARTED:
2580 CleanupTransaction();
2581 s->blockState = TBLOCK_DEFAULT;
2585 * If we are in TBLOCK_BEGIN it means something screwed up right
2586 * after reading "BEGIN TRANSACTION". We assume that the user
2587 * will interpret the error as meaning the BEGIN failed to get him
2588 * into a transaction block, so we should abort and return to idle
2593 CleanupTransaction();
2594 s->blockState = TBLOCK_DEFAULT;
2598 * We are somewhere in a transaction block and we've gotten a
2599 * failure, so we abort the transaction and set up the persistent
2600 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
2602 case TBLOCK_INPROGRESS:
2604 s->blockState = TBLOCK_ABORT;
2605 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
2609 * Here, we failed while trying to COMMIT. Clean up the
2610 * transaction and return to idle state (we do not want to stay in
2615 CleanupTransaction();
2616 s->blockState = TBLOCK_DEFAULT;
2620 * Here, we are already in an aborted transaction state and are
2621 * waiting for a ROLLBACK, but for some reason we failed again! So
2622 * we just remain in the abort state.
2625 case TBLOCK_SUBABORT:
2629 * We are in a failed transaction and we got the ROLLBACK command.
2630 * We have already aborted, we just need to cleanup and go to idle
2633 case TBLOCK_ABORT_END:
2634 CleanupTransaction();
2635 s->blockState = TBLOCK_DEFAULT;
2639 * We are in a live transaction and we got a ROLLBACK command.
2640 * Abort, cleanup, go to idle state.
2642 case TBLOCK_ABORT_PENDING:
2644 CleanupTransaction();
2645 s->blockState = TBLOCK_DEFAULT;
2649 * Here, we failed while trying to PREPARE. Clean up the
2650 * transaction and return to idle state (we do not want to stay in
2653 case TBLOCK_PREPARE:
2655 CleanupTransaction();
2656 s->blockState = TBLOCK_DEFAULT;
2660 * We got an error inside a subtransaction. Abort just the
2661 * subtransaction, and go to the persistent SUBABORT state until
2664 case TBLOCK_SUBINPROGRESS:
2665 AbortSubTransaction();
2666 s->blockState = TBLOCK_SUBABORT;
2670 * If we failed while trying to create a subtransaction, clean up
2671 * the broken subtransaction and abort the parent. The same
2672 * applies if we get a failure while ending a subtransaction.
2674 case TBLOCK_SUBBEGIN:
2676 case TBLOCK_SUBABORT_PENDING:
2677 case TBLOCK_SUBRESTART:
2678 AbortSubTransaction();
2679 CleanupSubTransaction();
2680 AbortCurrentTransaction();
2684 * Same as above, except the Abort() was already done.
2686 case TBLOCK_SUBABORT_END:
2687 case TBLOCK_SUBABORT_RESTART:
2688 CleanupSubTransaction();
2689 AbortCurrentTransaction();
2695 * PreventTransactionChain
2697 * This routine is to be called by statements that must not run inside
2698 * a transaction block, typically because they have non-rollback-able
2699 * side effects or do internal commits.
2701 * If we have already started a transaction block, issue an error; also issue
2702 * an error if we appear to be running inside a user-defined function (which
2703 * could issue more commands and possibly cause a failure after the statement
2704 * completes). Subtransactions are verboten too.
2706 * isTopLevel: passed down from ProcessUtility to determine whether we are
2707 * inside a function or multi-query querystring. (We will always fail if
2708 * this is false, but it's convenient to centralize the check here instead of
2709 * making callers do it.)
2710 * stmtType: statement type name, for error messages.
2713 PreventTransactionChain(bool isTopLevel, const char *stmtType)
2716 * xact block already started?
2718 if (IsTransactionBlock())
2720 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2721 /* translator: %s represents an SQL statement name */
2722 errmsg("%s cannot run inside a transaction block",
2728 if (IsSubTransaction())
2730 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2731 /* translator: %s represents an SQL statement name */
2732 errmsg("%s cannot run inside a subtransaction",
2736 * inside a function call?
2740 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2741 /* translator: %s represents an SQL statement name */
2742 errmsg("%s cannot be executed from a function or multi-command string",
2745 /* If we got past IsTransactionBlock test, should be in default state */
2746 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2747 CurrentTransactionState->blockState != TBLOCK_STARTED)
2748 elog(FATAL, "cannot prevent transaction chain");
2753 * RequireTransactionChain
2755 * This routine is to be called by statements that must run inside
2756 * a transaction block, because they have no effects that persist past
2757 * transaction end (and so calling them outside a transaction block
2758 * is presumably an error). DECLARE CURSOR is an example.
2760 * If we appear to be running inside a user-defined function, we do not
2761 * issue an error, since the function could issue more commands that make
2762 * use of the current statement's results. Likewise subtransactions.
2763 * Thus this is an inverse for PreventTransactionChain.
2765 * isTopLevel: passed down from ProcessUtility to determine whether we are
2766 * inside a function.
2767 * stmtType: statement type name, for error messages.
2770 RequireTransactionChain(bool isTopLevel, const char *stmtType)
2773 * xact block already started?
2775 if (IsTransactionBlock())
2781 if (IsSubTransaction())
2785 * inside a function call?
2791 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2792 /* translator: %s represents an SQL statement name */
2793 errmsg("%s can only be used in transaction blocks",
2798 * IsInTransactionChain
2800 * This routine is for statements that need to behave differently inside
2801 * a transaction block than when running as single commands. ANALYZE is
2802 * currently the only example.
2804 * isTopLevel: passed down from ProcessUtility to determine whether we are
2805 * inside a function.
2808 IsInTransactionChain(bool isTopLevel)
2811 * Return true on same conditions that would make PreventTransactionChain
2814 if (IsTransactionBlock())
2817 if (IsSubTransaction())
2823 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2824 CurrentTransactionState->blockState != TBLOCK_STARTED)
2832 * Register or deregister callback functions for start- and end-of-xact
2835 * These functions are intended for use by dynamically loaded modules.
2836 * For built-in modules we generally just hardwire the appropriate calls
2837 * (mainly because it's easier to control the order that way, where needed).
2839 * At transaction end, the callback occurs post-commit or post-abort, so the
2840 * callback functions can only do noncritical cleanup.
2843 RegisterXactCallback(XactCallback callback, void *arg)
2845 XactCallbackItem *item;
2847 item = (XactCallbackItem *)
2848 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
2849 item->callback = callback;
2851 item->next = Xact_callbacks;
2852 Xact_callbacks = item;
2856 UnregisterXactCallback(XactCallback callback, void *arg)
2858 XactCallbackItem *item;
2859 XactCallbackItem *prev;
2862 for (item = Xact_callbacks; item; prev = item, item = item->next)
2864 if (item->callback == callback && item->arg == arg)
2867 prev->next = item->next;
2869 Xact_callbacks = item->next;
2877 CallXactCallbacks(XactEvent event)
2879 XactCallbackItem *item;
2881 for (item = Xact_callbacks; item; item = item->next)
2882 (*item->callback) (event, item->arg);
2887 * Register or deregister callback functions for start- and end-of-subxact
2890 * Pretty much same as above, but for subtransaction events.
2892 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
2893 * so the callback functions can only do noncritical cleanup. At
2894 * subtransaction start, the callback is called when the subtransaction has
2895 * finished initializing.
2898 RegisterSubXactCallback(SubXactCallback callback, void *arg)
2900 SubXactCallbackItem *item;
2902 item = (SubXactCallbackItem *)
2903 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
2904 item->callback = callback;
2906 item->next = SubXact_callbacks;
2907 SubXact_callbacks = item;
2911 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
2913 SubXactCallbackItem *item;
2914 SubXactCallbackItem *prev;
2917 for (item = SubXact_callbacks; item; prev = item, item = item->next)
2919 if (item->callback == callback && item->arg == arg)
2922 prev->next = item->next;
2924 SubXact_callbacks = item->next;
2932 CallSubXactCallbacks(SubXactEvent event,
2933 SubTransactionId mySubid,
2934 SubTransactionId parentSubid)
2936 SubXactCallbackItem *item;
2938 for (item = SubXact_callbacks; item; item = item->next)
2939 (*item->callback) (event, mySubid, parentSubid, item->arg);
2943 /* ----------------------------------------------------------------
2944 * transaction block support
2945 * ----------------------------------------------------------------
2949 * BeginTransactionBlock
2950 * This executes a BEGIN command.
2953 BeginTransactionBlock(void)
2955 TransactionState s = CurrentTransactionState;
2957 switch (s->blockState)
2960 * We are not inside a transaction block, so allow one to begin.
2962 case TBLOCK_STARTED:
2963 s->blockState = TBLOCK_BEGIN;
2967 * Already a transaction block in progress.
2969 case TBLOCK_INPROGRESS:
2970 case TBLOCK_SUBINPROGRESS:
2972 case TBLOCK_SUBABORT:
2974 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2975 errmsg("there is already a transaction in progress")));
2978 /* These cases are invalid. */
2979 case TBLOCK_DEFAULT:
2981 case TBLOCK_SUBBEGIN:
2984 case TBLOCK_ABORT_END:
2985 case TBLOCK_SUBABORT_END:
2986 case TBLOCK_ABORT_PENDING:
2987 case TBLOCK_SUBABORT_PENDING:
2988 case TBLOCK_SUBRESTART:
2989 case TBLOCK_SUBABORT_RESTART:
2990 case TBLOCK_PREPARE:
2991 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
2992 BlockStateAsString(s->blockState));
2998 * PrepareTransactionBlock
2999 * This executes a PREPARE command.
3001 * Since PREPARE may actually do a ROLLBACK, the result indicates what
3002 * happened: TRUE for PREPARE, FALSE for ROLLBACK.
3004 * Note that we don't actually do anything here except change blockState.
3005 * The real work will be done in the upcoming PrepareTransaction().
3006 * We do it this way because it's not convenient to change memory context,
3007 * resource owner, etc while executing inside a Portal.
3010 PrepareTransactionBlock(char *gid)
3015 /* Set up to commit the current transaction */
3016 result = EndTransactionBlock();
3018 /* If successful, change outer tblock state to PREPARE */
3021 s = CurrentTransactionState;
3023 while (s->parent != NULL)
3026 if (s->blockState == TBLOCK_END)
3028 /* Save GID where PrepareTransaction can find it again */
3029 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
3031 s->blockState = TBLOCK_PREPARE;
3036 * ignore case where we are not in a transaction;
3037 * EndTransactionBlock already issued a warning.
3039 Assert(s->blockState == TBLOCK_STARTED);
3040 /* Don't send back a PREPARE result tag... */
3049 * EndTransactionBlock
3050 * This executes a COMMIT command.
3052 * Since COMMIT may actually do a ROLLBACK, the result indicates what
3053 * happened: TRUE for COMMIT, FALSE for ROLLBACK.
3055 * Note that we don't actually do anything here except change blockState.
3056 * The real work will be done in the upcoming CommitTransactionCommand().
3057 * We do it this way because it's not convenient to change memory context,
3058 * resource owner, etc while executing inside a Portal.
3061 EndTransactionBlock(void)
3063 TransactionState s = CurrentTransactionState;
3064 bool result = false;
3066 switch (s->blockState)
3069 * We are in a transaction block, so tell CommitTransactionCommand
3072 case TBLOCK_INPROGRESS:
3073 s->blockState = TBLOCK_END;
3078 * We are in a failed transaction block. Tell
3079 * CommitTransactionCommand it's time to exit the block.
3082 s->blockState = TBLOCK_ABORT_END;
3086 * We are in a live subtransaction block. Set up to subcommit all
3087 * open subtransactions and then commit the main transaction.
3089 case TBLOCK_SUBINPROGRESS:
3090 while (s->parent != NULL)
3092 if (s->blockState == TBLOCK_SUBINPROGRESS)
3093 s->blockState = TBLOCK_SUBEND;
3095 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3096 BlockStateAsString(s->blockState));
3099 if (s->blockState == TBLOCK_INPROGRESS)
3100 s->blockState = TBLOCK_END;
3102 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3103 BlockStateAsString(s->blockState));
3108 * Here we are inside an aborted subtransaction. Treat the COMMIT
3109 * as ROLLBACK: set up to abort everything and exit the main
3112 case TBLOCK_SUBABORT:
3113 while (s->parent != NULL)
3115 if (s->blockState == TBLOCK_SUBINPROGRESS)
3116 s->blockState = TBLOCK_SUBABORT_PENDING;
3117 else if (s->blockState == TBLOCK_SUBABORT)
3118 s->blockState = TBLOCK_SUBABORT_END;
3120 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3121 BlockStateAsString(s->blockState));
3124 if (s->blockState == TBLOCK_INPROGRESS)
3125 s->blockState = TBLOCK_ABORT_PENDING;
3126 else if (s->blockState == TBLOCK_ABORT)
3127 s->blockState = TBLOCK_ABORT_END;
3129 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3130 BlockStateAsString(s->blockState));
3134 * The user issued COMMIT when not inside a transaction. Issue a
3135 * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
3136 * CommitTransactionCommand() will then close the transaction and
3137 * put us back into the default state.
3139 case TBLOCK_STARTED:
3141 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3142 errmsg("there is no transaction in progress")));
3146 /* These cases are invalid. */
3147 case TBLOCK_DEFAULT:
3149 case TBLOCK_SUBBEGIN:
3152 case TBLOCK_ABORT_END:
3153 case TBLOCK_SUBABORT_END:
3154 case TBLOCK_ABORT_PENDING:
3155 case TBLOCK_SUBABORT_PENDING:
3156 case TBLOCK_SUBRESTART:
3157 case TBLOCK_SUBABORT_RESTART:
3158 case TBLOCK_PREPARE:
3159 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3160 BlockStateAsString(s->blockState));
3168 * UserAbortTransactionBlock
3169 * This executes a ROLLBACK command.
3171 * As above, we don't actually do anything here except change blockState.
3174 UserAbortTransactionBlock(void)
3176 TransactionState s = CurrentTransactionState;
3178 switch (s->blockState)
3181 * We are inside a transaction block and we got a ROLLBACK command
3182 * from the user, so tell CommitTransactionCommand to abort and
3183 * exit the transaction block.
3185 case TBLOCK_INPROGRESS:
3186 s->blockState = TBLOCK_ABORT_PENDING;
3190 * We are inside a failed transaction block and we got a ROLLBACK
3191 * command from the user. Abort processing is already done, so
3192 * CommitTransactionCommand just has to cleanup and go back to
3196 s->blockState = TBLOCK_ABORT_END;
3200 * We are inside a subtransaction. Mark everything up to top
3201 * level as exitable.
3203 case TBLOCK_SUBINPROGRESS:
3204 case TBLOCK_SUBABORT:
3205 while (s->parent != NULL)
3207 if (s->blockState == TBLOCK_SUBINPROGRESS)
3208 s->blockState = TBLOCK_SUBABORT_PENDING;
3209 else if (s->blockState == TBLOCK_SUBABORT)
3210 s->blockState = TBLOCK_SUBABORT_END;
3212 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3213 BlockStateAsString(s->blockState));
3216 if (s->blockState == TBLOCK_INPROGRESS)
3217 s->blockState = TBLOCK_ABORT_PENDING;
3218 else if (s->blockState == TBLOCK_ABORT)
3219 s->blockState = TBLOCK_ABORT_END;
3221 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3222 BlockStateAsString(s->blockState));
3226 * The user issued ABORT when not inside a transaction. Issue a
3227 * WARNING and go to abort state. The upcoming call to
3228 * CommitTransactionCommand() will then put us back into the
3231 case TBLOCK_STARTED:
3233 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3234 errmsg("there is no transaction in progress")));
3235 s->blockState = TBLOCK_ABORT_PENDING;
3238 /* These cases are invalid. */
3239 case TBLOCK_DEFAULT:
3241 case TBLOCK_SUBBEGIN:
3244 case TBLOCK_ABORT_END:
3245 case TBLOCK_SUBABORT_END:
3246 case TBLOCK_ABORT_PENDING:
3247 case TBLOCK_SUBABORT_PENDING:
3248 case TBLOCK_SUBRESTART:
3249 case TBLOCK_SUBABORT_RESTART:
3250 case TBLOCK_PREPARE:
3251 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3252 BlockStateAsString(s->blockState));
3259 * This executes a SAVEPOINT command.
3262 DefineSavepoint(char *name)
3264 TransactionState s = CurrentTransactionState;
3266 switch (s->blockState)
3268 case TBLOCK_INPROGRESS:
3269 case TBLOCK_SUBINPROGRESS:
3270 /* Normal subtransaction start */
3272 s = CurrentTransactionState; /* changed by push */
3275 * Savepoint names, like the TransactionState block itself, live
3276 * in TopTransactionContext.
3279 s->name = MemoryContextStrdup(TopTransactionContext, name);
3282 /* These cases are invalid. */
3283 case TBLOCK_DEFAULT:
3284 case TBLOCK_STARTED:
3286 case TBLOCK_SUBBEGIN:
3290 case TBLOCK_SUBABORT:
3291 case TBLOCK_ABORT_END:
3292 case TBLOCK_SUBABORT_END:
3293 case TBLOCK_ABORT_PENDING:
3294 case TBLOCK_SUBABORT_PENDING:
3295 case TBLOCK_SUBRESTART:
3296 case TBLOCK_SUBABORT_RESTART:
3297 case TBLOCK_PREPARE:
3298 elog(FATAL, "DefineSavepoint: unexpected state %s",
3299 BlockStateAsString(s->blockState));
3306 * This executes a RELEASE command.
3308 * As above, we don't actually do anything here except change blockState.
3311 ReleaseSavepoint(List *options)
3313 TransactionState s = CurrentTransactionState;
3314 TransactionState target,
3319 switch (s->blockState)
3322 * We can't rollback to a savepoint if there is no savepoint
3325 case TBLOCK_INPROGRESS:
3327 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3328 errmsg("no such savepoint")));
3332 * We are in a non-aborted subtransaction. This is the only valid
3335 case TBLOCK_SUBINPROGRESS:
3338 /* These cases are invalid. */
3339 case TBLOCK_DEFAULT:
3340 case TBLOCK_STARTED:
3342 case TBLOCK_SUBBEGIN:
3346 case TBLOCK_SUBABORT:
3347 case TBLOCK_ABORT_END:
3348 case TBLOCK_SUBABORT_END:
3349 case TBLOCK_ABORT_PENDING:
3350 case TBLOCK_SUBABORT_PENDING:
3351 case TBLOCK_SUBRESTART:
3352 case TBLOCK_SUBABORT_RESTART:
3353 case TBLOCK_PREPARE:
3354 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3355 BlockStateAsString(s->blockState));
3359 foreach(cell, options)
3361 DefElem *elem = lfirst(cell);
3363 if (strcmp(elem->defname, "savepoint_name") == 0)
3364 name = strVal(elem->arg);
3367 Assert(PointerIsValid(name));
3369 for (target = s; PointerIsValid(target); target = target->parent)
3371 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3375 if (!PointerIsValid(target))
3377 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3378 errmsg("no such savepoint")));
3380 /* disallow crossing savepoint level boundaries */
3381 if (target->savepointLevel != s->savepointLevel)
3383 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3384 errmsg("no such savepoint")));
3387 * Mark "commit pending" all subtransactions up to the target
3388 * subtransaction. The actual commits will happen when control gets to
3389 * CommitTransactionCommand.
3391 xact = CurrentTransactionState;
3394 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3395 xact->blockState = TBLOCK_SUBEND;
3398 xact = xact->parent;
3399 Assert(PointerIsValid(xact));
3404 * RollbackToSavepoint
3405 * This executes a ROLLBACK TO <savepoint> command.
3407 * As above, we don't actually do anything here except change blockState.
3410 RollbackToSavepoint(List *options)
3412 TransactionState s = CurrentTransactionState;
3413 TransactionState target,
3418 switch (s->blockState)
3421 * We can't rollback to a savepoint if there is no savepoint
3424 case TBLOCK_INPROGRESS:
3427 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3428 errmsg("no such savepoint")));
3432 * There is at least one savepoint, so proceed.
3434 case TBLOCK_SUBINPROGRESS:
3435 case TBLOCK_SUBABORT:
3438 /* These cases are invalid. */
3439 case TBLOCK_DEFAULT:
3440 case TBLOCK_STARTED:
3442 case TBLOCK_SUBBEGIN:
3445 case TBLOCK_ABORT_END:
3446 case TBLOCK_SUBABORT_END:
3447 case TBLOCK_ABORT_PENDING:
3448 case TBLOCK_SUBABORT_PENDING:
3449 case TBLOCK_SUBRESTART:
3450 case TBLOCK_SUBABORT_RESTART:
3451 case TBLOCK_PREPARE:
3452 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3453 BlockStateAsString(s->blockState));
3457 foreach(cell, options)
3459 DefElem *elem = lfirst(cell);
3461 if (strcmp(elem->defname, "savepoint_name") == 0)
3462 name = strVal(elem->arg);
3465 Assert(PointerIsValid(name));
3467 for (target = s; PointerIsValid(target); target = target->parent)
3469 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3473 if (!PointerIsValid(target))
3475 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3476 errmsg("no such savepoint")));
3478 /* disallow crossing savepoint level boundaries */
3479 if (target->savepointLevel != s->savepointLevel)
3481 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3482 errmsg("no such savepoint")));
3485 * Mark "abort pending" all subtransactions up to the target
3486 * subtransaction. The actual aborts will happen when control gets to
3487 * CommitTransactionCommand.
3489 xact = CurrentTransactionState;
3494 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3495 xact->blockState = TBLOCK_SUBABORT_PENDING;
3496 else if (xact->blockState == TBLOCK_SUBABORT)
3497 xact->blockState = TBLOCK_SUBABORT_END;
3499 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3500 BlockStateAsString(xact->blockState));
3501 xact = xact->parent;
3502 Assert(PointerIsValid(xact));
3505 /* And mark the target as "restart pending" */
3506 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3507 xact->blockState = TBLOCK_SUBRESTART;
3508 else if (xact->blockState == TBLOCK_SUBABORT)
3509 xact->blockState = TBLOCK_SUBABORT_RESTART;
3511 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3512 BlockStateAsString(xact->blockState));
3516 * BeginInternalSubTransaction
3517 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
3518 * TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
3519 * used in functions that might be called when not inside a BEGIN block
3520 * or when running deferred triggers at COMMIT/PREPARE time. Also, it
3521 * automatically does CommitTransactionCommand/StartTransactionCommand
3522 * instead of expecting the caller to do it.
3525 BeginInternalSubTransaction(char *name)
3527 TransactionState s = CurrentTransactionState;
3529 switch (s->blockState)
3531 case TBLOCK_STARTED:
3532 case TBLOCK_INPROGRESS:
3534 case TBLOCK_PREPARE:
3535 case TBLOCK_SUBINPROGRESS:
3536 /* Normal subtransaction start */
3538 s = CurrentTransactionState; /* changed by push */
3541 * Savepoint names, like the TransactionState block itself, live
3542 * in TopTransactionContext.
3545 s->name = MemoryContextStrdup(TopTransactionContext, name);
3548 /* These cases are invalid. */
3549 case TBLOCK_DEFAULT:
3551 case TBLOCK_SUBBEGIN:
3554 case TBLOCK_SUBABORT:
3555 case TBLOCK_ABORT_END:
3556 case TBLOCK_SUBABORT_END:
3557 case TBLOCK_ABORT_PENDING:
3558 case TBLOCK_SUBABORT_PENDING:
3559 case TBLOCK_SUBRESTART:
3560 case TBLOCK_SUBABORT_RESTART:
3561 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
3562 BlockStateAsString(s->blockState));
3566 CommitTransactionCommand();
3567 StartTransactionCommand();
3571 * ReleaseCurrentSubTransaction
3573 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
3574 * savepoint name (if any).
3575 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3578 ReleaseCurrentSubTransaction(void)
3580 TransactionState s = CurrentTransactionState;
3582 if (s->blockState != TBLOCK_SUBINPROGRESS)
3583 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
3584 BlockStateAsString(s->blockState));
3585 Assert(s->state == TRANS_INPROGRESS);
3586 MemoryContextSwitchTo(CurTransactionContext);
3587 CommitSubTransaction();
3588 s = CurrentTransactionState; /* changed by pop */
3589 Assert(s->state == TRANS_INPROGRESS);
3593 * RollbackAndReleaseCurrentSubTransaction
3595 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
3596 * of its savepoint name (if any).
3597 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3600 RollbackAndReleaseCurrentSubTransaction(void)
3602 TransactionState s = CurrentTransactionState;
3604 switch (s->blockState)
3606 /* Must be in a subtransaction */
3607 case TBLOCK_SUBINPROGRESS:
3608 case TBLOCK_SUBABORT:
3611 /* These cases are invalid. */
3612 case TBLOCK_DEFAULT:
3613 case TBLOCK_STARTED:
3615 case TBLOCK_SUBBEGIN:
3616 case TBLOCK_INPROGRESS:
3620 case TBLOCK_ABORT_END:
3621 case TBLOCK_SUBABORT_END:
3622 case TBLOCK_ABORT_PENDING:
3623 case TBLOCK_SUBABORT_PENDING:
3624 case TBLOCK_SUBRESTART:
3625 case TBLOCK_SUBABORT_RESTART:
3626 case TBLOCK_PREPARE:
3627 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
3628 BlockStateAsString(s->blockState));
3633 * Abort the current subtransaction, if needed.
3635 if (s->blockState == TBLOCK_SUBINPROGRESS)
3636 AbortSubTransaction();
3638 /* And clean it up, too */
3639 CleanupSubTransaction();
3641 s = CurrentTransactionState; /* changed by pop */
3642 AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
3643 s->blockState == TBLOCK_INPROGRESS ||
3644 s->blockState == TBLOCK_STARTED);
3648 * AbortOutOfAnyTransaction
3650 * This routine is provided for error recovery purposes. It aborts any
3651 * active transaction or transaction block, leaving the system in a known
3655 AbortOutOfAnyTransaction(void)
3657 TransactionState s = CurrentTransactionState;
3660 * Get out of any transaction or nested transaction
3664 switch (s->blockState)
3666 case TBLOCK_DEFAULT:
3667 /* Not in a transaction, do nothing */
3669 case TBLOCK_STARTED:
3671 case TBLOCK_INPROGRESS:
3673 case TBLOCK_ABORT_PENDING:
3674 case TBLOCK_PREPARE:
3675 /* In a transaction, so clean up */
3677 CleanupTransaction();
3678 s->blockState = TBLOCK_DEFAULT;
3681 case TBLOCK_ABORT_END:
3682 /* AbortTransaction already done, still need Cleanup */
3683 CleanupTransaction();
3684 s->blockState = TBLOCK_DEFAULT;
3688 * In a subtransaction, so clean it up and abort parent too
3690 case TBLOCK_SUBBEGIN:
3691 case TBLOCK_SUBINPROGRESS:
3693 case TBLOCK_SUBABORT_PENDING:
3694 case TBLOCK_SUBRESTART:
3695 AbortSubTransaction();
3696 CleanupSubTransaction();
3697 s = CurrentTransactionState; /* changed by pop */
3700 case TBLOCK_SUBABORT:
3701 case TBLOCK_SUBABORT_END:
3702 case TBLOCK_SUBABORT_RESTART:
3703 /* As above, but AbortSubTransaction already done */
3704 CleanupSubTransaction();
3705 s = CurrentTransactionState; /* changed by pop */
3708 } while (s->blockState != TBLOCK_DEFAULT);
3710 /* Should be out of all subxacts now */
3711 Assert(s->parent == NULL);
3715 * IsTransactionBlock --- are we within a transaction block?
3718 IsTransactionBlock(void)
3720 TransactionState s = CurrentTransactionState;
3722 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
3729 * IsTransactionOrTransactionBlock --- are we within either a transaction
3730 * or a transaction block? (The backend is only really "idle" when this
3733 * This should match up with IsTransactionBlock and IsTransactionState.
3736 IsTransactionOrTransactionBlock(void)
3738 TransactionState s = CurrentTransactionState;
3740 if (s->blockState == TBLOCK_DEFAULT)
3747 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
3750 TransactionBlockStatusCode(void)
3752 TransactionState s = CurrentTransactionState;
3754 switch (s->blockState)
3756 case TBLOCK_DEFAULT:
3757 case TBLOCK_STARTED:
3758 return 'I'; /* idle --- not in transaction */
3760 case TBLOCK_SUBBEGIN:
3761 case TBLOCK_INPROGRESS:
3762 case TBLOCK_SUBINPROGRESS:
3765 case TBLOCK_PREPARE:
3766 return 'T'; /* in transaction */
3768 case TBLOCK_SUBABORT:
3769 case TBLOCK_ABORT_END:
3770 case TBLOCK_SUBABORT_END:
3771 case TBLOCK_ABORT_PENDING:
3772 case TBLOCK_SUBABORT_PENDING:
3773 case TBLOCK_SUBRESTART:
3774 case TBLOCK_SUBABORT_RESTART:
3775 return 'E'; /* in failed transaction */
3778 /* should never get here */
3779 elog(FATAL, "invalid transaction block state: %s",
3780 BlockStateAsString(s->blockState));
3781 return 0; /* keep compiler quiet */
3788 IsSubTransaction(void)
3790 TransactionState s = CurrentTransactionState;
3792 if (s->nestingLevel >= 2)
3799 * StartSubTransaction
3801 * If you're wondering why this is separate from PushTransaction: it's because
3802 * we can't conveniently do this stuff right inside DefineSavepoint. The
3803 * SAVEPOINT utility command will be executed inside a Portal, and if we
3804 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
3805 * the Portal will undo those settings. So we make DefineSavepoint just
3806 * push a dummy transaction block, and when control returns to the main
3807 * idle loop, CommitTransactionCommand will be called, and we'll come here
3808 * to finish starting the subtransaction.
3811 StartSubTransaction(void)
3813 TransactionState s = CurrentTransactionState;
3815 if (s->state != TRANS_DEFAULT)
3816 elog(WARNING, "StartSubTransaction while in %s state",
3817 TransStateAsString(s->state));
3819 s->state = TRANS_START;
3822 * Initialize subsystems for new subtransaction
3824 * must initialize resource-management stuff first
3826 AtSubStart_Memory();
3827 AtSubStart_ResourceOwner();
3829 AtSubStart_Notify();
3830 AfterTriggerBeginSubXact();
3832 s->state = TRANS_INPROGRESS;
3835 * Call start-of-subxact callbacks
3837 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
3838 s->parent->subTransactionId);
3840 ShowTransactionState("StartSubTransaction");
3844 * CommitSubTransaction
3846 * The caller has to make sure to always reassign CurrentTransactionState
3847 * if it has a local pointer to it after calling this function.
3850 CommitSubTransaction(void)
3852 TransactionState s = CurrentTransactionState;
3854 ShowTransactionState("CommitSubTransaction");
3856 if (s->state != TRANS_INPROGRESS)
3857 elog(WARNING, "CommitSubTransaction while in %s state",
3858 TransStateAsString(s->state));
3860 /* Pre-commit processing goes here -- nothing to do at the moment */
3862 s->state = TRANS_COMMIT;
3864 /* Must CCI to ensure commands of subtransaction are seen as done */
3865 CommandCounterIncrement();
3868 * Prior to 8.4 we marked subcommit in clog at this point. We now only
3869 * perform that step, if required, as part of the atomic update of the
3870 * whole transaction tree at top level commit or abort.
3873 /* Post-commit cleanup */
3874 if (TransactionIdIsValid(s->transactionId))
3875 AtSubCommit_childXids();
3876 AfterTriggerEndSubXact(true);
3877 AtSubCommit_Portals(s->subTransactionId,
3878 s->parent->subTransactionId,
3879 s->parent->curTransactionOwner);
3880 AtEOSubXact_LargeObject(true, s->subTransactionId,
3881 s->parent->subTransactionId);
3882 AtSubCommit_Notify();
3884 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
3885 s->parent->subTransactionId);
3887 ResourceOwnerRelease(s->curTransactionOwner,
3888 RESOURCE_RELEASE_BEFORE_LOCKS,
3890 AtEOSubXact_RelationCache(true, s->subTransactionId,
3891 s->parent->subTransactionId);
3892 AtEOSubXact_Inval(true);
3896 * The only lock we actually release here is the subtransaction XID lock.
3897 * The rest just get transferred to the parent resource owner.
3899 CurrentResourceOwner = s->curTransactionOwner;
3900 if (TransactionIdIsValid(s->transactionId))
3901 XactLockTableDelete(s->transactionId);
3903 ResourceOwnerRelease(s->curTransactionOwner,
3904 RESOURCE_RELEASE_LOCKS,
3906 ResourceOwnerRelease(s->curTransactionOwner,
3907 RESOURCE_RELEASE_AFTER_LOCKS,
3910 AtEOXact_GUC(true, s->gucNestLevel);
3911 AtEOSubXact_SPI(true, s->subTransactionId);
3912 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
3913 s->parent->subTransactionId);
3914 AtEOSubXact_Namespace(true, s->subTransactionId,
3915 s->parent->subTransactionId);
3916 AtEOSubXact_Files(true, s->subTransactionId,
3917 s->parent->subTransactionId);
3918 AtEOSubXact_HashTables(true, s->nestingLevel);
3919 AtEOSubXact_PgStat(true, s->nestingLevel);
3920 AtSubCommit_Snapshot(s->nestingLevel);
3923 * We need to restore the upper transaction's read-only state, in case the
3924 * upper is read-write while the child is read-only; GUC will incorrectly
3925 * think it should leave the child state in place.
3927 XactReadOnly = s->prevXactReadOnly;
3929 CurrentResourceOwner = s->parent->curTransactionOwner;
3930 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3931 ResourceOwnerDelete(s->curTransactionOwner);
3932 s->curTransactionOwner = NULL;
3934 AtSubCommit_Memory();
3936 s->state = TRANS_DEFAULT;
3942 * AbortSubTransaction
3945 AbortSubTransaction(void)
3947 TransactionState s = CurrentTransactionState;
3949 /* Prevent cancel/die interrupt while cleaning up */
3952 /* Make sure we have a valid memory context and resource owner */
3953 AtSubAbort_Memory();
3954 AtSubAbort_ResourceOwner();
3957 * Release any LW locks we might be holding as quickly as possible.
3958 * (Regular locks, however, must be held till we finish aborting.)
3959 * Releasing LW locks is critical since we might try to grab them again
3960 * while cleaning up!
3962 * FIXME This may be incorrect --- Are there some locks we should keep?
3963 * Buffer locks, for example? I don't think so but I'm not sure.
3973 * check the current transaction state
3975 ShowTransactionState("AbortSubTransaction");
3977 if (s->state != TRANS_INPROGRESS)
3978 elog(WARNING, "AbortSubTransaction while in %s state",
3979 TransStateAsString(s->state));
3981 s->state = TRANS_ABORT;
3984 * Reset user ID which might have been changed transiently. (See notes in
3985 * AbortTransaction.)
3987 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
3990 * We can skip all this stuff if the subxact failed before creating a
3993 if (s->curTransactionOwner)
3995 AfterTriggerEndSubXact(false);
3996 AtSubAbort_Portals(s->subTransactionId,
3997 s->parent->subTransactionId,
3998 s->parent->curTransactionOwner);
3999 AtEOSubXact_LargeObject(false, s->subTransactionId,
4000 s->parent->subTransactionId);
4001 AtSubAbort_Notify();
4003 /* Advertise the fact that we aborted in pg_clog. */
4004 (void) RecordTransactionAbort(true);
4006 /* Post-abort cleanup */
4007 if (TransactionIdIsValid(s->transactionId))
4008 AtSubAbort_childXids();
4010 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
4011 s->parent->subTransactionId);
4013 ResourceOwnerRelease(s->curTransactionOwner,
4014 RESOURCE_RELEASE_BEFORE_LOCKS,
4016 AtEOSubXact_RelationCache(false, s->subTransactionId,
4017 s->parent->subTransactionId);
4018 AtEOSubXact_Inval(false);
4020 ResourceOwnerRelease(s->curTransactionOwner,
4021 RESOURCE_RELEASE_LOCKS,
4023 ResourceOwnerRelease(s->curTransactionOwner,
4024 RESOURCE_RELEASE_AFTER_LOCKS,
4027 AtEOXact_GUC(false, s->gucNestLevel);
4028 AtEOSubXact_SPI(false, s->subTransactionId);
4029 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
4030 s->parent->subTransactionId);
4031 AtEOSubXact_Namespace(false, s->subTransactionId,
4032 s->parent->subTransactionId);
4033 AtEOSubXact_Files(false, s->subTransactionId,
4034 s->parent->subTransactionId);
4035 AtEOSubXact_HashTables(false, s->nestingLevel);
4036 AtEOSubXact_PgStat(false, s->nestingLevel);
4037 AtSubAbort_Snapshot(s->nestingLevel);
4041 * Restore the upper transaction's read-only state, too. This should be
4042 * redundant with GUC's cleanup but we may as well do it for consistency
4043 * with the commit case.
4045 XactReadOnly = s->prevXactReadOnly;
4047 RESUME_INTERRUPTS();
4051 * CleanupSubTransaction
4053 * The caller has to make sure to always reassign CurrentTransactionState
4054 * if it has a local pointer to it after calling this function.
4057 CleanupSubTransaction(void)
4059 TransactionState s = CurrentTransactionState;
4061 ShowTransactionState("CleanupSubTransaction");
4063 if (s->state != TRANS_ABORT)
4064 elog(WARNING, "CleanupSubTransaction while in %s state",
4065 TransStateAsString(s->state));
4067 AtSubCleanup_Portals(s->subTransactionId);
4069 CurrentResourceOwner = s->parent->curTransactionOwner;
4070 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4071 if (s->curTransactionOwner)
4072 ResourceOwnerDelete(s->curTransactionOwner);
4073 s->curTransactionOwner = NULL;
4075 AtSubCleanup_Memory();
4077 s->state = TRANS_DEFAULT;
4084 * Create transaction state stack entry for a subtransaction
4086 * The caller has to make sure to always reassign CurrentTransactionState
4087 * if it has a local pointer to it after calling this function.
4090 PushTransaction(void)
4092 TransactionState p = CurrentTransactionState;
4096 * We keep subtransaction state nodes in TopTransactionContext.
4098 s = (TransactionState)
4099 MemoryContextAllocZero(TopTransactionContext,
4100 sizeof(TransactionStateData));
4103 * Assign a subtransaction ID, watching out for counter wraparound.
4105 currentSubTransactionId += 1;
4106 if (currentSubTransactionId == InvalidSubTransactionId)
4108 currentSubTransactionId -= 1;
4111 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
4112 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
4116 * We can now stack a minimally valid subtransaction without fear of
4119 s->transactionId = InvalidTransactionId; /* until assigned */
4120 s->subTransactionId = currentSubTransactionId;
4122 s->nestingLevel = p->nestingLevel + 1;
4123 s->gucNestLevel = NewGUCNestLevel();
4124 s->savepointLevel = p->savepointLevel;
4125 s->state = TRANS_DEFAULT;
4126 s->blockState = TBLOCK_SUBBEGIN;
4127 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
4128 s->prevXactReadOnly = XactReadOnly;
4130 CurrentTransactionState = s;
4133 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
4134 * with the subtransaction from here on out; in particular they should not
4135 * assume that it necessarily has a transaction context, resource owner,
4142 * Pop back to parent transaction state
4144 * The caller has to make sure to always reassign CurrentTransactionState
4145 * if it has a local pointer to it after calling this function.
4148 PopTransaction(void)
4150 TransactionState s = CurrentTransactionState;
4152 if (s->state != TRANS_DEFAULT)
4153 elog(WARNING, "PopTransaction while in %s state",
4154 TransStateAsString(s->state));
4156 if (s->parent == NULL)
4157 elog(FATAL, "PopTransaction with no parent");
4159 CurrentTransactionState = s->parent;
4161 /* Let's just make sure CurTransactionContext is good */
4162 CurTransactionContext = s->parent->curTransactionContext;
4163 MemoryContextSwitchTo(CurTransactionContext);
4165 /* Ditto for ResourceOwner links */
4166 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4167 CurrentResourceOwner = s->parent->curTransactionOwner;
4169 /* Free the old child structure */
4176 * ShowTransactionState
4180 ShowTransactionState(const char *str)
4182 /* skip work if message will definitely not be printed */
4183 if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
4185 elog(DEBUG3, "%s", str);
4186 ShowTransactionStateRec(CurrentTransactionState);
4191 * ShowTransactionStateRec
4192 * Recursive subroutine for ShowTransactionState
4195 ShowTransactionStateRec(TransactionState s)
4199 initStringInfo(&buf);
4201 if (s->nChildXids > 0)
4205 appendStringInfo(&buf, "%u", s->childXids[0]);
4206 for (i = 1; i < s->nChildXids; i++)
4207 appendStringInfo(&buf, " %u", s->childXids[i]);
4211 ShowTransactionStateRec(s->parent);
4213 /* use ereport to suppress computation if msg will not be printed */
4215 (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u%s, nestlvl: %d, children: %s",
4216 PointerIsValid(s->name) ? s->name : "unnamed",
4217 BlockStateAsString(s->blockState),
4218 TransStateAsString(s->state),
4219 (unsigned int) s->transactionId,
4220 (unsigned int) s->subTransactionId,
4221 (unsigned int) currentCommandId,
4222 currentCommandIdUsed ? " (used)" : "",
4223 s->nestingLevel, buf.data)));
4229 * BlockStateAsString
4233 BlockStateAsString(TBlockState blockState)
4237 case TBLOCK_DEFAULT:
4239 case TBLOCK_STARTED:
4243 case TBLOCK_INPROGRESS:
4244 return "INPROGRESS";
4249 case TBLOCK_ABORT_END:
4251 case TBLOCK_ABORT_PENDING:
4252 return "ABORT PEND";
4253 case TBLOCK_PREPARE:
4255 case TBLOCK_SUBBEGIN:
4257 case TBLOCK_SUBINPROGRESS:
4258 return "SUB INPROGRS";
4261 case TBLOCK_SUBABORT:
4263 case TBLOCK_SUBABORT_END:
4264 return "SUB ABORT END";
4265 case TBLOCK_SUBABORT_PENDING:
4266 return "SUB ABRT PEND";
4267 case TBLOCK_SUBRESTART:
4268 return "SUB RESTART";
4269 case TBLOCK_SUBABORT_RESTART:
4270 return "SUB AB RESTRT";
4272 return "UNRECOGNIZED";
4276 * TransStateAsString
4280 TransStateAsString(TransState state)
4288 case TRANS_INPROGRESS:
4297 return "UNRECOGNIZED";
4301 * xactGetCommittedChildren
4303 * Gets the list of committed children of the current transaction. The return
4304 * value is the number of child transactions. *ptr is set to point to an
4305 * array of TransactionIds. The array is allocated in TopTransactionContext;
4306 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
4307 * If there are no subxacts, *ptr is set to NULL.
4310 xactGetCommittedChildren(TransactionId **ptr)
4312 TransactionState s = CurrentTransactionState;
4314 if (s->nChildXids == 0)
4317 *ptr = s->childXids;
4319 return s->nChildXids;
4323 * XLOG support routines
4327 * Before 8.5 this was a fairly short function, but now it performs many
4328 * actions for which the order of execution is critical.
4331 xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid, XLogRecPtr lsn)
4333 TransactionId *sub_xids;
4334 SharedInvalidationMessage *inval_msgs;
4335 TransactionId max_xid;
4338 /* subxid array follows relfilenodes */
4339 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4340 /* invalidation messages array follows subxids */
4341 inval_msgs = (SharedInvalidationMessage *) &(sub_xids[xlrec->nsubxacts]);
4343 max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
4346 * Make sure nextXid is beyond any XID mentioned in the record.
4348 * We don't expect anyone else to modify nextXid, hence we
4349 * don't need to hold a lock while checking this. We still acquire
4350 * the lock to modify it, though.
4352 if (TransactionIdFollowsOrEquals(max_xid,
4353 ShmemVariableCache->nextXid))
4355 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4356 ShmemVariableCache->nextXid = max_xid;
4357 TransactionIdAdvance(ShmemVariableCache->nextXid);
4358 LWLockRelease(XidGenLock);
4361 if (!InHotStandby || XactCompletionVacuumFull(xlrec))
4364 * Mark the transaction committed in pg_clog.
4366 * If InHotStandby and this is the first commit of a VACUUM FULL INPLACE
4367 * we perform only the actual commit to clog. Strangely, there are two
4368 * commits that share the same xid for every VFI, so we need to skip
4369 * some steps for the first commit. It's OK to repeat the clog update
4370 * when we see the second commit on a VFI.
4372 TransactionIdCommitTree(xid, xlrec->nsubxacts, sub_xids);
4377 * If a transaction completion record arrives that has as-yet unobserved
4378 * subtransactions then this will not have been fully handled by the call
4379 * to RecordKnownAssignedTransactionIds() in the main recovery loop in
4380 * xlog.c. So we need to do bookkeeping again to cover that case. This is
4381 * confusing and it is easy to think this call is irrelevant, which has
4382 * happened three times in development already. Leave it in.
4384 RecordKnownAssignedTransactionIds(max_xid);
4387 * Mark the transaction committed in pg_clog. We use async commit
4388 * protocol during recovery to provide information on database
4389 * consistency for when users try to set hint bits. It is important
4390 * that we do not set hint bits until the minRecoveryPoint is past
4391 * this commit record. This ensures that if we crash we don't see
4392 * hint bits set on changes made by transactions that haven't yet
4393 * recovered. It's unlikely but it's good to be safe.
4395 TransactionIdAsyncCommitTree(xid, xlrec->nsubxacts, sub_xids, lsn);
4398 * We must mark clog before we update the ProcArray.
4400 ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids);
4403 * Send any cache invalidations attached to the commit. We must
4404 * maintain the same order of invalidation then release locks
4407 ProcessCommittedInvalidationMessages(inval_msgs, xlrec->nmsgs,
4408 XactCompletionRelcacheInitFileInval(xlrec));
4411 * Release locks, if any. We do this for both two phase and normal
4412 * one phase transactions. In effect we are ignoring the prepare
4413 * phase and just going straight to lock release.
4415 StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
4418 /* Make sure files supposed to be dropped are dropped */
4419 for (i = 0; i < xlrec->nrels; i++)
4421 SMgrRelation srel = smgropen(xlrec->xnodes[i]);
4424 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4426 if (smgrexists(srel, fork))
4428 XLogDropRelation(xlrec->xnodes[i], fork);
4429 smgrdounlink(srel, fork, false, true);
4436 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit() in
4437 * normal operation. For example, in DROP DATABASE, we delete all the files
4438 * belonging to the database, and then commit the transaction. If we crash
4439 * after all the files have been deleted but before the commit, you have an
4440 * entry in pg_database without any files. To minimize the window for that,
4441 * we use ForceSyncCommit() to rush the commit record to disk as quick as
4442 * possible. We have the same window during recovery, and forcing an
4443 * XLogFlush() (which updates minRecoveryPoint during recovery) helps
4444 * to reduce that problem window, for any user that requested ForceSyncCommit().
4446 if (XactCompletionForceSyncCommit(xlrec))
4451 * Be careful with the order of execution, as with xact_redo_commit().
4452 * The two functions are similar but differ in key places.
4454 * Note also that an abort can be for a subtransaction and its children,
4455 * not just for a top level abort. That means we have to consider
4456 * topxid != xid, whereas in commit we would find topxid == xid always
4457 * because subtransaction commit is never WAL logged.
4460 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
4462 TransactionId *sub_xids;
4463 TransactionId max_xid;
4466 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4467 max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
4469 /* Make sure nextXid is beyond any XID mentioned in the record */
4470 /* We don't expect anyone else to modify nextXid, hence we
4471 * don't need to hold a lock while checking this. We still acquire
4472 * the lock to modify it, though.
4474 if (TransactionIdFollowsOrEquals(max_xid,
4475 ShmemVariableCache->nextXid))
4477 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4478 ShmemVariableCache->nextXid = max_xid;
4479 TransactionIdAdvance(ShmemVariableCache->nextXid);
4480 LWLockRelease(XidGenLock);
4486 * If a transaction completion record arrives that has as-yet unobserved
4487 * subtransactions then this will not have been fully handled by the call
4488 * to RecordKnownAssignedTransactionIds() in the main recovery loop in
4489 * xlog.c. So we need to do bookkeeping again to cover that case. This is
4490 * confusing and it is easy to think this call is irrelevant, which has
4491 * happened three times in development already. Leave it in.
4493 RecordKnownAssignedTransactionIds(max_xid);
4496 /* Mark the transaction aborted in pg_clog, no need for async stuff */
4497 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4502 * We must mark clog before we update the ProcArray.
4504 ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids);
4507 * There are no flat files that need updating, nor invalidation
4508 * messages to send or undo.
4512 * Release locks, if any. There are no invalidations to send.
4514 StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
4517 /* Make sure files supposed to be dropped are dropped */
4518 for (i = 0; i < xlrec->nrels; i++)
4520 SMgrRelation srel = smgropen(xlrec->xnodes[i]);
4523 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4525 if (smgrexists(srel, fork))
4527 XLogDropRelation(xlrec->xnodes[i], fork);
4528 smgrdounlink(srel, fork, false, true);
4536 xact_redo(XLogRecPtr lsn, XLogRecord *record)
4538 uint8 info = record->xl_info & ~XLR_INFO_MASK;
4540 /* Backup blocks are not used in xact records */
4541 Assert(!(record->xl_info & XLR_BKP_BLOCK_MASK));
4543 if (info == XLOG_XACT_COMMIT)
4545 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
4547 xact_redo_commit(xlrec, record->xl_xid, lsn);
4549 else if (info == XLOG_XACT_ABORT)
4551 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
4553 xact_redo_abort(xlrec, record->xl_xid);
4555 else if (info == XLOG_XACT_PREPARE)
4557 /* the record contents are exactly the 2PC file */
4558 RecreateTwoPhaseFile(record->xl_xid,
4559 XLogRecGetData(record), record->xl_len);
4561 else if (info == XLOG_XACT_COMMIT_PREPARED)
4563 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
4565 xact_redo_commit(&xlrec->crec, xlrec->xid, lsn);
4566 RemoveTwoPhaseFile(xlrec->xid, false);
4568 else if (info == XLOG_XACT_ABORT_PREPARED)
4570 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
4572 xact_redo_abort(&xlrec->arec, xlrec->xid);
4573 RemoveTwoPhaseFile(xlrec->xid, false);
4575 else if (info == XLOG_XACT_ASSIGNMENT)
4577 xl_xact_assignment *xlrec = (xl_xact_assignment *) XLogRecGetData(record);
4580 ProcArrayApplyXidAssignment(xlrec->xtop,
4581 xlrec->nsubxacts, xlrec->xsub);
4584 elog(PANIC, "xact_redo: unknown op code %u", info);
4588 xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
4591 TransactionId *xacts;
4592 SharedInvalidationMessage *msgs;
4594 xacts = (TransactionId *) &xlrec->xnodes[xlrec->nrels];
4595 msgs = (SharedInvalidationMessage *) &xacts[xlrec->nsubxacts];
4597 if (XactCompletionRelcacheInitFileInval(xlrec))
4598 appendStringInfo(buf, "; relcache init file inval");
4600 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4601 if (xlrec->nrels > 0)
4603 appendStringInfo(buf, "; rels:");
4604 for (i = 0; i < xlrec->nrels; i++)
4606 char *path = relpath(xlrec->xnodes[i], MAIN_FORKNUM);
4608 appendStringInfo(buf, " %s", path);
4612 if (xlrec->nsubxacts > 0)
4614 appendStringInfo(buf, "; subxacts:");
4615 for (i = 0; i < xlrec->nsubxacts; i++)
4616 appendStringInfo(buf, " %u", xacts[i]);
4618 if (xlrec->nmsgs > 0)
4620 appendStringInfo(buf, "; inval msgs:");
4621 for (i = 0; i < xlrec->nmsgs; i++)
4623 SharedInvalidationMessage *msg = &msgs[i];
4626 appendStringInfo(buf, "catcache id%d ", msg->id);
4627 else if (msg->id == SHAREDINVALRELCACHE_ID)
4628 appendStringInfo(buf, "relcache ");
4629 else if (msg->id == SHAREDINVALSMGR_ID)
4630 appendStringInfo(buf, "smgr ");
4636 xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
4640 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4641 if (xlrec->nrels > 0)
4643 appendStringInfo(buf, "; rels:");
4644 for (i = 0; i < xlrec->nrels; i++)
4646 char *path = relpath(xlrec->xnodes[i], MAIN_FORKNUM);
4648 appendStringInfo(buf, " %s", path);
4652 if (xlrec->nsubxacts > 0)
4654 TransactionId *xacts = (TransactionId *)
4655 &xlrec->xnodes[xlrec->nrels];
4657 appendStringInfo(buf, "; subxacts:");
4658 for (i = 0; i < xlrec->nsubxacts; i++)
4659 appendStringInfo(buf, " %u", xacts[i]);
4664 xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
4668 appendStringInfo(buf, "subxacts:");
4670 for (i = 0; i < xlrec->nsubxacts; i++)
4671 appendStringInfo(buf, " %u", xlrec->xsub[i]);
4675 xact_desc(StringInfo buf, uint8 xl_info, char *rec)
4677 uint8 info = xl_info & ~XLR_INFO_MASK;
4679 if (info == XLOG_XACT_COMMIT)
4681 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
4683 appendStringInfo(buf, "commit: ");
4684 xact_desc_commit(buf, xlrec);
4686 else if (info == XLOG_XACT_ABORT)
4688 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
4690 appendStringInfo(buf, "abort: ");
4691 xact_desc_abort(buf, xlrec);
4693 else if (info == XLOG_XACT_PREPARE)
4695 appendStringInfo(buf, "prepare");
4697 else if (info == XLOG_XACT_COMMIT_PREPARED)
4699 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
4701 appendStringInfo(buf, "commit prepared %u: ", xlrec->xid);
4702 xact_desc_commit(buf, &xlrec->crec);
4704 else if (info == XLOG_XACT_ABORT_PREPARED)
4706 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
4708 appendStringInfo(buf, "abort prepared %u: ", xlrec->xid);
4709 xact_desc_abort(buf, &xlrec->arec);
4711 else if (info == XLOG_XACT_ASSIGNMENT)
4713 xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
4716 * Note that we ignore the WAL record's xid, since we're more
4717 * interested in the top-level xid that issued the record
4718 * and which xids are being reported here.
4720 appendStringInfo(buf, "xid assignment xtop %u: ", xlrec->xtop);
4721 xact_desc_assignment(buf, xlrec);
4724 appendStringInfo(buf, "UNKNOWN");