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.288 2010/02/20 21:24:01 tgl Exp $
15 *-------------------------------------------------------------------------
23 #include "access/multixact.h"
24 #include "access/subtrans.h"
25 #include "access/transam.h"
26 #include "access/twophase.h"
27 #include "access/xact.h"
28 #include "access/xlogutils.h"
29 #include "catalog/catalog.h"
30 #include "catalog/namespace.h"
31 #include "catalog/storage.h"
32 #include "commands/async.h"
33 #include "commands/tablecmds.h"
34 #include "commands/trigger.h"
35 #include "executor/spi.h"
36 #include "libpq/be-fsstubs.h"
37 #include "miscadmin.h"
39 #include "storage/bufmgr.h"
40 #include "storage/fd.h"
41 #include "storage/lmgr.h"
42 #include "storage/procarray.h"
43 #include "storage/sinvaladt.h"
44 #include "storage/smgr.h"
45 #include "storage/standby.h"
46 #include "utils/combocid.h"
47 #include "utils/guc.h"
48 #include "utils/inval.h"
49 #include "utils/memutils.h"
50 #include "utils/relcache.h"
51 #include "utils/relmapper.h"
52 #include "utils/snapmgr.h"
57 * User-tweakable parameters
59 int DefaultXactIsoLevel = XACT_READ_COMMITTED;
62 bool DefaultXactReadOnly = false;
65 bool XactSyncCommit = true;
67 int CommitDelay = 0; /* precommit delay in microseconds */
68 int CommitSiblings = 5; /* # concurrent xacts needed to sleep */
71 * MyXactAccessedTempRel is set when a temporary relation is accessed.
72 * We don't allow PREPARE TRANSACTION in that case. (This is global
73 * so that it can be set from heapam.c.)
75 bool MyXactAccessedTempRel = false;
79 * transaction states - transaction state from server perspective
81 typedef enum TransState
83 TRANS_DEFAULT, /* idle */
84 TRANS_START, /* transaction starting */
85 TRANS_INPROGRESS, /* inside a valid transaction */
86 TRANS_COMMIT, /* commit in progress */
87 TRANS_ABORT, /* abort in progress */
88 TRANS_PREPARE /* prepare in progress */
92 * transaction block states - transaction state of client queries
94 * Note: the subtransaction states are used only for non-topmost
95 * transactions; the others appear only in the topmost transaction.
97 typedef enum TBlockState
99 /* not-in-transaction-block states */
100 TBLOCK_DEFAULT, /* idle */
101 TBLOCK_STARTED, /* running single-query transaction */
103 /* transaction block states */
104 TBLOCK_BEGIN, /* starting transaction block */
105 TBLOCK_INPROGRESS, /* live transaction */
106 TBLOCK_END, /* COMMIT received */
107 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
108 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
109 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
110 TBLOCK_PREPARE, /* live xact, PREPARE received */
112 /* subtransaction states */
113 TBLOCK_SUBBEGIN, /* starting a subtransaction */
114 TBLOCK_SUBINPROGRESS, /* live subtransaction */
115 TBLOCK_SUBEND, /* RELEASE received */
116 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
117 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
118 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
119 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
120 TBLOCK_SUBABORT_RESTART /* failed subxact, ROLLBACK TO received */
124 * transaction state structure
126 typedef struct TransactionStateData
128 TransactionId transactionId; /* my XID, or Invalid if none */
129 SubTransactionId subTransactionId; /* my subxact ID */
130 char *name; /* savepoint name, if any */
131 int savepointLevel; /* savepoint level */
132 TransState state; /* low-level state */
133 TBlockState blockState; /* high-level state */
134 int nestingLevel; /* transaction nesting depth */
135 int gucNestLevel; /* GUC context nesting depth */
136 MemoryContext curTransactionContext; /* my xact-lifetime context */
137 ResourceOwner curTransactionOwner; /* my query resources */
138 TransactionId *childXids; /* subcommitted child XIDs, in XID order */
139 int nChildXids; /* # of subcommitted child XIDs */
140 int maxChildXids; /* allocated size of childXids[] */
141 Oid prevUser; /* previous CurrentUserId setting */
142 int prevSecContext; /* previous SecurityRestrictionContext */
143 bool prevXactReadOnly; /* entry-time xact r/o state */
144 bool startedInRecovery; /* did we start in recovery? */
145 struct TransactionStateData *parent; /* back link to parent */
146 } TransactionStateData;
148 typedef TransactionStateData *TransactionState;
151 * CurrentTransactionState always points to the current transaction state
152 * block. It will point to TopTransactionStateData when not in a
153 * transaction at all, or when in a top-level transaction.
155 static TransactionStateData TopTransactionStateData = {
156 0, /* transaction id */
157 0, /* subtransaction id */
158 NULL, /* savepoint name */
159 0, /* savepoint level */
160 TRANS_DEFAULT, /* transaction state */
161 TBLOCK_DEFAULT, /* transaction block state from the client
163 0, /* transaction nesting depth */
164 0, /* GUC context nesting depth */
165 NULL, /* cur transaction context */
166 NULL, /* cur transaction resource owner */
167 NULL, /* subcommitted child Xids */
168 0, /* # of subcommitted child Xids */
169 0, /* allocated size of childXids[] */
170 InvalidOid, /* previous CurrentUserId setting */
171 0, /* previous SecurityRestrictionContext */
172 false, /* entry-time xact r/o state */
173 false, /* startedInRecovery */
174 NULL /* link to parent state block */
178 * unreportedXids holds XIDs of all subtransactions that have not yet been
179 * reported in a XLOG_XACT_ASSIGNMENT record.
181 static int nUnreportedXids;
182 static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS];
184 static TransactionState CurrentTransactionState = &TopTransactionStateData;
187 * The subtransaction ID and command ID assignment counters are global
188 * to a whole transaction, so we do not keep them in the state stack.
190 static SubTransactionId currentSubTransactionId;
191 static CommandId currentCommandId;
192 static bool currentCommandIdUsed;
195 * xactStartTimestamp is the value of transaction_timestamp().
196 * stmtStartTimestamp is the value of statement_timestamp().
197 * xactStopTimestamp is the time at which we log a commit or abort WAL record.
198 * These do not change as we enter and exit subtransactions, so we don't
199 * keep them inside the TransactionState stack.
201 static TimestampTz xactStartTimestamp;
202 static TimestampTz stmtStartTimestamp;
203 static TimestampTz xactStopTimestamp;
206 * GID to be used for preparing the current transaction. This is also
207 * global to a whole transaction, so we don't keep it in the state stack.
209 static char *prepareGID;
212 * Some commands want to force synchronous commit.
214 static bool forceSyncCommit = false;
217 * Private context for transaction-abort work --- we reserve space for this
218 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
219 * when we've run out of memory.
221 static MemoryContext TransactionAbortContext = NULL;
224 * List of add-on start- and end-of-xact callbacks
226 typedef struct XactCallbackItem
228 struct XactCallbackItem *next;
229 XactCallback callback;
233 static XactCallbackItem *Xact_callbacks = NULL;
236 * List of add-on start- and end-of-subxact callbacks
238 typedef struct SubXactCallbackItem
240 struct SubXactCallbackItem *next;
241 SubXactCallback callback;
243 } SubXactCallbackItem;
245 static SubXactCallbackItem *SubXact_callbacks = NULL;
248 /* local function prototypes */
249 static void AssignTransactionId(TransactionState s);
250 static void AbortTransaction(void);
251 static void AtAbort_Memory(void);
252 static void AtCleanup_Memory(void);
253 static void AtAbort_ResourceOwner(void);
254 static void AtCCI_LocalCache(void);
255 static void AtCommit_Memory(void);
256 static void AtStart_Cache(void);
257 static void AtStart_Memory(void);
258 static void AtStart_ResourceOwner(void);
259 static void CallXactCallbacks(XactEvent event);
260 static void CallSubXactCallbacks(SubXactEvent event,
261 SubTransactionId mySubid,
262 SubTransactionId parentSubid);
263 static void CleanupTransaction(void);
264 static void CommitTransaction(void);
265 static TransactionId RecordTransactionAbort(bool isSubXact);
266 static void StartTransaction(void);
268 static void StartSubTransaction(void);
269 static void CommitSubTransaction(void);
270 static void AbortSubTransaction(void);
271 static void CleanupSubTransaction(void);
272 static void PushTransaction(void);
273 static void PopTransaction(void);
275 static void AtSubAbort_Memory(void);
276 static void AtSubCleanup_Memory(void);
277 static void AtSubAbort_ResourceOwner(void);
278 static void AtSubCommit_Memory(void);
279 static void AtSubStart_Memory(void);
280 static void AtSubStart_ResourceOwner(void);
282 static void ShowTransactionState(const char *str);
283 static void ShowTransactionStateRec(TransactionState state);
284 static const char *BlockStateAsString(TBlockState blockState);
285 static const char *TransStateAsString(TransState state);
288 /* ----------------------------------------------------------------
289 * transaction state accessors
290 * ----------------------------------------------------------------
296 * This returns true if we are inside a valid transaction; that is,
297 * it is safe to initiate database access, take heavyweight locks, etc.
300 IsTransactionState(void)
302 TransactionState s = CurrentTransactionState;
305 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
306 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
307 * TRANS_PREPARE since it might be too soon or too late within those
308 * transition states to do anything interesting. Hence, the only "valid"
309 * state is TRANS_INPROGRESS.
311 return (s->state == TRANS_INPROGRESS);
315 * IsAbortedTransactionBlockState
317 * This returns true if we are within an aborted transaction block.
320 IsAbortedTransactionBlockState(void)
322 TransactionState s = CurrentTransactionState;
324 if (s->blockState == TBLOCK_ABORT ||
325 s->blockState == TBLOCK_SUBABORT)
333 * GetTopTransactionId
335 * This will return the XID of the main transaction, assigning one if
336 * it's not yet set. Be careful to call this only inside a valid xact.
339 GetTopTransactionId(void)
341 if (!TransactionIdIsValid(TopTransactionStateData.transactionId))
342 AssignTransactionId(&TopTransactionStateData);
343 return TopTransactionStateData.transactionId;
347 * GetTopTransactionIdIfAny
349 * This will return the XID of the main transaction, if one is assigned.
350 * It will return InvalidTransactionId if we are not currently inside a
351 * transaction, or inside a transaction that hasn't yet been assigned an XID.
354 GetTopTransactionIdIfAny(void)
356 return TopTransactionStateData.transactionId;
360 * GetCurrentTransactionId
362 * This will return the XID of the current transaction (main or sub
363 * transaction), assigning one if it's not yet set. Be careful to call this
364 * only inside a valid xact.
367 GetCurrentTransactionId(void)
369 TransactionState s = CurrentTransactionState;
371 if (!TransactionIdIsValid(s->transactionId))
372 AssignTransactionId(s);
373 return s->transactionId;
377 * GetCurrentTransactionIdIfAny
379 * This will return the XID of the current sub xact, if one is assigned.
380 * It will return InvalidTransactionId if we are not currently inside a
381 * transaction, or inside a transaction that hasn't been assigned an XID yet.
384 GetCurrentTransactionIdIfAny(void)
386 return CurrentTransactionState->transactionId;
391 * AssignTransactionId
393 * Assigns a new permanent XID to the given TransactionState.
394 * We do not assign XIDs to transactions until/unless this is called.
395 * Also, any parent TransactionStates that don't yet have XIDs are assigned
396 * one; this maintains the invariant that a child transaction has an XID
397 * following its parent's.
400 AssignTransactionId(TransactionState s)
402 bool isSubXact = (s->parent != NULL);
403 ResourceOwner currentOwner;
405 /* Assert that caller didn't screw up */
406 Assert(!TransactionIdIsValid(s->transactionId));
407 Assert(s->state == TRANS_INPROGRESS);
410 * Ensure parent(s) have XIDs, so that a child always has an XID later
413 if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
414 AssignTransactionId(s->parent);
417 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
419 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
420 * shared storage other than PG_PROC; because if there's no room for it in
421 * PG_PROC, the subtrans entry is needed to ensure that other backends see
422 * the Xid as "running". See GetNewTransactionId.
424 s->transactionId = GetNewTransactionId(isSubXact);
427 SubTransSetParent(s->transactionId, s->parent->transactionId, false);
430 * Acquire lock on the transaction XID. (We assume this cannot block.) We
431 * have to ensure that the lock is assigned to the transaction's own
434 currentOwner = CurrentResourceOwner;
437 CurrentResourceOwner = s->curTransactionOwner;
438 XactLockTableInsert(s->transactionId);
442 /* Ensure CurrentResourceOwner is restored on error */
443 CurrentResourceOwner = currentOwner;
447 CurrentResourceOwner = currentOwner;
450 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
451 * top-level transaction we issue a WAL record for the assignment. We
452 * include the top-level xid and all the subxids that have not yet been
453 * reported using XLOG_XACT_ASSIGNMENT records.
455 * This is required to limit the amount of shared memory required in a
456 * hot standby server to keep track of in-progress XIDs. See notes for
457 * RecordKnownAssignedTransactionIds().
459 * We don't keep track of the immediate parent of each subxid,
460 * only the top-level transaction that each subxact belongs to. This
461 * is correct in recovery only because aborted subtransactions are
462 * separately WAL logged.
464 if (isSubXact && XLogStandbyInfoActive())
466 unreportedXids[nUnreportedXids] = s->transactionId;
469 /* ensure this test matches similar one in RecoverPreparedTransactions() */
470 if (nUnreportedXids >= PGPROC_MAX_CACHED_SUBXIDS)
472 XLogRecData rdata[2];
473 xl_xact_assignment xlrec;
476 * xtop is always set by now because we recurse up transaction
477 * stack to the highest unassigned xid and then come back down
479 xlrec.xtop = GetTopTransactionId();
480 Assert(TransactionIdIsValid(xlrec.xtop));
481 xlrec.nsubxacts = nUnreportedXids;
483 rdata[0].data = (char *) &xlrec;
484 rdata[0].len = MinSizeOfXactAssignment;
485 rdata[0].buffer = InvalidBuffer;
486 rdata[0].next = &rdata[1];
488 rdata[1].data = (char *) unreportedXids;
489 rdata[1].len = PGPROC_MAX_CACHED_SUBXIDS * sizeof(TransactionId);
490 rdata[1].buffer = InvalidBuffer;
491 rdata[1].next = NULL;
493 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT, rdata);
501 * GetCurrentSubTransactionId
504 GetCurrentSubTransactionId(void)
506 TransactionState s = CurrentTransactionState;
508 return s->subTransactionId;
513 * GetCurrentCommandId
515 * "used" must be TRUE if the caller intends to use the command ID to mark
516 * inserted/updated/deleted tuples. FALSE means the ID is being fetched
517 * for read-only purposes (ie, as a snapshot validity cutoff). See
518 * CommandCounterIncrement() for discussion.
521 GetCurrentCommandId(bool used)
523 /* this is global to a transaction, not subtransaction-local */
525 currentCommandIdUsed = true;
526 return currentCommandId;
530 * GetCurrentTransactionStartTimestamp
533 GetCurrentTransactionStartTimestamp(void)
535 return xactStartTimestamp;
539 * GetCurrentStatementStartTimestamp
542 GetCurrentStatementStartTimestamp(void)
544 return stmtStartTimestamp;
548 * GetCurrentTransactionStopTimestamp
550 * We return current time if the transaction stop time hasn't been set
551 * (which can happen if we decide we don't need to log an XLOG record).
554 GetCurrentTransactionStopTimestamp(void)
556 if (xactStopTimestamp != 0)
557 return xactStopTimestamp;
558 return GetCurrentTimestamp();
562 * SetCurrentStatementStartTimestamp
565 SetCurrentStatementStartTimestamp(void)
567 stmtStartTimestamp = GetCurrentTimestamp();
571 * SetCurrentTransactionStopTimestamp
574 SetCurrentTransactionStopTimestamp(void)
576 xactStopTimestamp = GetCurrentTimestamp();
580 * GetCurrentTransactionNestLevel
582 * Note: this will return zero when not inside any transaction, one when
583 * inside a top-level transaction, etc.
586 GetCurrentTransactionNestLevel(void)
588 TransactionState s = CurrentTransactionState;
590 return s->nestingLevel;
595 * TransactionIdIsCurrentTransactionId
598 TransactionIdIsCurrentTransactionId(TransactionId xid)
603 * We always say that BootstrapTransactionId is "not my transaction ID"
604 * even when it is (ie, during bootstrap). Along with the fact that
605 * transam.c always treats BootstrapTransactionId as already committed,
606 * this causes the tqual.c routines to see all tuples as committed, which
607 * is what we need during bootstrap. (Bootstrap mode only inserts tuples,
608 * it never updates or deletes them, so all tuples can be presumed good
611 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
612 * not my transaction ID, so we can just return "false" immediately for
613 * any non-normal XID.
615 if (!TransactionIdIsNormal(xid))
619 * We will return true for the Xid of the current subtransaction, any of
620 * its subcommitted children, any of its parents, or any of their
621 * previously subcommitted children. However, a transaction being aborted
622 * is no longer "current", even though it may still have an entry on the
625 for (s = CurrentTransactionState; s != NULL; s = s->parent)
630 if (s->state == TRANS_ABORT)
632 if (!TransactionIdIsValid(s->transactionId))
633 continue; /* it can't have any child XIDs either */
634 if (TransactionIdEquals(xid, s->transactionId))
636 /* As the childXids array is ordered, we can use binary search */
638 high = s->nChildXids - 1;
644 middle = low + (high - low) / 2;
645 probe = s->childXids[middle];
646 if (TransactionIdEquals(probe, xid))
648 else if (TransactionIdPrecedes(probe, xid))
659 * TransactionStartedDuringRecovery
661 * Returns true if the current transaction started while recovery was still
662 * in progress. Recovery might have ended since so RecoveryInProgress() might
663 * return false already.
666 TransactionStartedDuringRecovery(void)
668 return CurrentTransactionState->startedInRecovery;
672 * CommandCounterIncrement
675 CommandCounterIncrement(void)
678 * If the current value of the command counter hasn't been "used" to mark
679 * tuples, we need not increment it, since there's no need to distinguish
680 * a read-only command from others. This helps postpone command counter
681 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
683 if (currentCommandIdUsed)
685 currentCommandId += 1;
686 if (currentCommandId == FirstCommandId) /* check for overflow */
688 currentCommandId -= 1;
690 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
691 errmsg("cannot have more than 2^32-1 commands in a transaction")));
693 currentCommandIdUsed = false;
695 /* Propagate new command ID into static snapshots */
696 SnapshotSetCommandId(currentCommandId);
699 * Make any catalog changes done by the just-completed command visible
700 * in the local syscache. We obviously don't need to do this after a
701 * read-only command. (But see hacks in inval.c to make real sure we
702 * don't think a command that queued inval messages was read-only.)
708 * Make any other backends' catalog changes visible to me.
710 * XXX this is probably in the wrong place: CommandCounterIncrement should
711 * be purely a local operation, most likely. However fooling with this
712 * will affect asynchronous cross-backend interactions, which doesn't seem
713 * like a wise thing to do in late beta, so save improving this for
714 * another day - tgl 2007-11-30
722 * Interface routine to allow commands to force a synchronous commit of the
723 * current top-level transaction
726 ForceSyncCommit(void)
728 forceSyncCommit = true;
732 /* ----------------------------------------------------------------
733 * StartTransaction stuff
734 * ----------------------------------------------------------------
743 AcceptInvalidationMessages();
752 TransactionState s = CurrentTransactionState;
755 * If this is the first time through, create a private context for
756 * AbortTransaction to work in. By reserving some space now, we can
757 * insulate AbortTransaction from out-of-memory scenarios. Like
758 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
759 * size, so that space will be reserved immediately.
761 if (TransactionAbortContext == NULL)
762 TransactionAbortContext =
763 AllocSetContextCreate(TopMemoryContext,
764 "TransactionAbortContext",
770 * We shouldn't have a transaction context already.
772 Assert(TopTransactionContext == NULL);
775 * Create a toplevel context for the transaction.
777 TopTransactionContext =
778 AllocSetContextCreate(TopMemoryContext,
779 "TopTransactionContext",
780 ALLOCSET_DEFAULT_MINSIZE,
781 ALLOCSET_DEFAULT_INITSIZE,
782 ALLOCSET_DEFAULT_MAXSIZE);
785 * In a top-level transaction, CurTransactionContext is the same as
786 * TopTransactionContext.
788 CurTransactionContext = TopTransactionContext;
789 s->curTransactionContext = CurTransactionContext;
791 /* Make the CurTransactionContext active. */
792 MemoryContextSwitchTo(CurTransactionContext);
796 * AtStart_ResourceOwner
799 AtStart_ResourceOwner(void)
801 TransactionState s = CurrentTransactionState;
804 * We shouldn't have a transaction resource owner already.
806 Assert(TopTransactionResourceOwner == NULL);
809 * Create a toplevel resource owner for the transaction.
811 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
813 TopTransactionResourceOwner = s->curTransactionOwner;
814 CurTransactionResourceOwner = s->curTransactionOwner;
815 CurrentResourceOwner = s->curTransactionOwner;
818 /* ----------------------------------------------------------------
819 * StartSubTransaction stuff
820 * ----------------------------------------------------------------
827 AtSubStart_Memory(void)
829 TransactionState s = CurrentTransactionState;
831 Assert(CurTransactionContext != NULL);
834 * Create a CurTransactionContext, which will be used to hold data that
835 * survives subtransaction commit but disappears on subtransaction abort.
836 * We make it a child of the immediate parent's CurTransactionContext.
838 CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
839 "CurTransactionContext",
840 ALLOCSET_DEFAULT_MINSIZE,
841 ALLOCSET_DEFAULT_INITSIZE,
842 ALLOCSET_DEFAULT_MAXSIZE);
843 s->curTransactionContext = CurTransactionContext;
845 /* Make the CurTransactionContext active. */
846 MemoryContextSwitchTo(CurTransactionContext);
850 * AtSubStart_ResourceOwner
853 AtSubStart_ResourceOwner(void)
855 TransactionState s = CurrentTransactionState;
857 Assert(s->parent != NULL);
860 * Create a resource owner for the subtransaction. We make it a child of
861 * the immediate parent's resource owner.
863 s->curTransactionOwner =
864 ResourceOwnerCreate(s->parent->curTransactionOwner,
867 CurTransactionResourceOwner = s->curTransactionOwner;
868 CurrentResourceOwner = s->curTransactionOwner;
871 /* ----------------------------------------------------------------
872 * CommitTransaction stuff
873 * ----------------------------------------------------------------
877 * RecordTransactionCommit
879 * Returns latest XID among xact and its children, or InvalidTransactionId
880 * if the xact has no XID. (We compute that here just because it's easier.)
883 RecordTransactionCommit(void)
885 TransactionId xid = GetTopTransactionIdIfAny();
886 bool markXidCommitted = TransactionIdIsValid(xid);
887 TransactionId latestXid = InvalidTransactionId;
892 TransactionId *children;
894 SharedInvalidationMessage *invalMessages = NULL;
895 bool RelcacheInitFileInval;
897 /* Get data needed for commit record */
898 nrels = smgrGetPendingDeletes(true, &rels, &haveNonTemp);
899 nchildren = xactGetCommittedChildren(&children);
900 nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
901 &RelcacheInitFileInval);
903 * If we haven't been assigned an XID yet, we neither can, nor do we want
904 * to write a COMMIT record.
906 if (!markXidCommitted)
909 * We expect that every smgrscheduleunlink is followed by a catalog
910 * update, and hence XID assignment, so we shouldn't get here with any
911 * pending deletes. Use a real test not just an Assert to check this,
912 * since it's a bit fragile.
915 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
917 /* Can't have child XIDs either; AssignTransactionId enforces this */
918 Assert(nchildren == 0);
921 * If we didn't create XLOG entries, we're done here; otherwise we
922 * should flush those entries the same as a commit record. (An
923 * example of a possible record that wouldn't cause an XID to be
924 * assigned is a sequence advance record due to nextval() --- we want
925 * to flush that to disk before reporting commit.)
927 if (XactLastRecEnd.xrecoff == 0)
933 * Begin commit critical section and insert the commit XLOG record.
935 XLogRecData rdata[4];
937 xl_xact_commit xlrec;
939 /* Tell bufmgr and smgr to prepare for commit */
943 * Set flags required for recovery processing of commits.
946 if (RelcacheInitFileInval)
947 xlrec.xinfo |= XACT_COMPLETION_UPDATE_RELCACHE_FILE;
949 xlrec.xinfo |= XACT_COMPLETION_FORCE_SYNC_COMMIT;
951 xlrec.dbId = MyDatabaseId;
952 xlrec.tsId = MyDatabaseTableSpace;
955 * Mark ourselves as within our "commit critical section". This
956 * forces any concurrent checkpoint to wait until we've updated
957 * pg_clog. Without this, it is possible for the checkpoint to set
958 * REDO after the XLOG record but fail to flush the pg_clog update to
959 * disk, leading to loss of the transaction commit if the system
960 * crashes a little later.
962 * Note: we could, but don't bother to, set this flag in
963 * RecordTransactionAbort. That's because loss of a transaction abort
964 * is noncritical; the presumption would be that it aborted, anyway.
966 * It's safe to change the inCommit flag of our own backend without
967 * holding the ProcArrayLock, since we're the only one modifying it.
968 * This makes checkpoint's determination of which xacts are inCommit a
969 * bit fuzzy, but it doesn't matter.
971 START_CRIT_SECTION();
972 MyProc->inCommit = true;
974 SetCurrentTransactionStopTimestamp();
975 xlrec.xact_time = xactStopTimestamp;
977 xlrec.nsubxacts = nchildren;
979 rdata[0].data = (char *) (&xlrec);
980 rdata[0].len = MinSizeOfXactCommit;
981 rdata[0].buffer = InvalidBuffer;
982 /* dump rels to delete */
985 rdata[0].next = &(rdata[1]);
986 rdata[1].data = (char *) rels;
987 rdata[1].len = nrels * sizeof(RelFileNode);
988 rdata[1].buffer = InvalidBuffer;
991 /* dump committed child Xids */
994 rdata[lastrdata].next = &(rdata[2]);
995 rdata[2].data = (char *) children;
996 rdata[2].len = nchildren * sizeof(TransactionId);
997 rdata[2].buffer = InvalidBuffer;
1000 /* dump shared cache invalidation messages */
1003 rdata[lastrdata].next = &(rdata[3]);
1004 rdata[3].data = (char *) invalMessages;
1005 rdata[3].len = nmsgs * sizeof(SharedInvalidationMessage);
1006 rdata[3].buffer = InvalidBuffer;
1009 rdata[lastrdata].next = NULL;
1011 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
1015 * Check if we want to commit asynchronously. If the user has set
1016 * synchronous_commit = off, and we're not doing cleanup of any non-temp
1017 * rels nor committing any command that wanted to force sync commit, then
1018 * we can defer flushing XLOG. (We must not allow asynchronous commit if
1019 * there are any non-temp tables to be deleted, because we might delete
1020 * the files before the COMMIT record is flushed to disk. We do allow
1021 * asynchronous commit if all to-be-deleted tables are temporary though,
1022 * since they are lost anyway if we crash.)
1024 if (XactSyncCommit || forceSyncCommit || haveNonTemp)
1027 * Synchronous commit case.
1029 * Sleep before flush! So we can flush more than one commit records
1030 * per single fsync. (The idea is some other backend may do the
1031 * XLogFlush while we're sleeping. This needs work still, because on
1032 * most Unixen, the minimum select() delay is 10msec or more, which is
1035 * We do not sleep if enableFsync is not turned on, nor if there are
1036 * fewer than CommitSiblings other backends with active transactions.
1038 if (CommitDelay > 0 && enableFsync &&
1039 CountActiveBackends() >= CommitSiblings)
1040 pg_usleep(CommitDelay);
1042 XLogFlush(XactLastRecEnd);
1045 * Now we may update the CLOG, if we wrote a COMMIT record above
1047 if (markXidCommitted)
1048 TransactionIdCommitTree(xid, nchildren, children);
1053 * Asynchronous commit case.
1055 * Report the latest async commit LSN, so that the WAL writer knows to
1056 * flush this commit.
1058 XLogSetAsyncCommitLSN(XactLastRecEnd);
1061 * We must not immediately update the CLOG, since we didn't flush the
1062 * XLOG. Instead, we store the LSN up to which the XLOG must be
1063 * flushed before the CLOG may be updated.
1065 if (markXidCommitted)
1066 TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1070 * If we entered a commit critical section, leave it now, and let
1071 * checkpoints proceed.
1073 if (markXidCommitted)
1075 MyProc->inCommit = false;
1079 /* Compute latestXid while we have the child XIDs handy */
1080 latestXid = TransactionIdLatest(xid, nchildren, children);
1082 /* Reset XactLastRecEnd until the next transaction writes something */
1083 XactLastRecEnd.xrecoff = 0;
1086 /* Clean up local data */
1098 AtCCI_LocalCache(void)
1101 * Make any pending relation map changes visible. We must do this
1102 * before processing local sinval messages, so that the map changes
1103 * will get reflected into the relcache when relcache invals are
1106 AtCCI_RelationMap();
1109 * Make catalog changes visible to me for the next command.
1111 CommandEndInvalidationMessages();
1118 AtCommit_Memory(void)
1121 * Now that we're "out" of a transaction, have the system allocate things
1122 * in the top memory context instead of per-transaction contexts.
1124 MemoryContextSwitchTo(TopMemoryContext);
1127 * Release all transaction-local memory.
1129 Assert(TopTransactionContext != NULL);
1130 MemoryContextDelete(TopTransactionContext);
1131 TopTransactionContext = NULL;
1132 CurTransactionContext = NULL;
1133 CurrentTransactionState->curTransactionContext = NULL;
1136 /* ----------------------------------------------------------------
1137 * CommitSubTransaction stuff
1138 * ----------------------------------------------------------------
1142 * AtSubCommit_Memory
1145 AtSubCommit_Memory(void)
1147 TransactionState s = CurrentTransactionState;
1149 Assert(s->parent != NULL);
1151 /* Return to parent transaction level's memory context. */
1152 CurTransactionContext = s->parent->curTransactionContext;
1153 MemoryContextSwitchTo(CurTransactionContext);
1156 * Ordinarily we cannot throw away the child's CurTransactionContext,
1157 * since the data it contains will be needed at upper commit. However, if
1158 * there isn't actually anything in it, we can throw it away. This avoids
1159 * a small memory leak in the common case of "trivial" subxacts.
1161 if (MemoryContextIsEmpty(s->curTransactionContext))
1163 MemoryContextDelete(s->curTransactionContext);
1164 s->curTransactionContext = NULL;
1169 * AtSubCommit_childXids
1171 * Pass my own XID and my child XIDs up to my parent as committed children.
1174 AtSubCommit_childXids(void)
1176 TransactionState s = CurrentTransactionState;
1179 Assert(s->parent != NULL);
1182 * The parent childXids array will need to hold my XID and all my
1183 * childXids, in addition to the XIDs already there.
1185 new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1187 /* Allocate or enlarge the parent array if necessary */
1188 if (s->parent->maxChildXids < new_nChildXids)
1190 int new_maxChildXids;
1191 TransactionId *new_childXids;
1194 * Make it 2x what's needed right now, to avoid having to enlarge it
1195 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1196 * is what ensures that we don't need to worry about integer overflow
1197 * here or in the calculation of new_nChildXids.)
1199 new_maxChildXids = Min(new_nChildXids * 2,
1200 (int) (MaxAllocSize / sizeof(TransactionId)));
1202 if (new_maxChildXids < new_nChildXids)
1204 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1205 errmsg("maximum number of committed subtransactions (%d) exceeded",
1206 (int) (MaxAllocSize / sizeof(TransactionId)))));
1209 * We keep the child-XID arrays in TopTransactionContext; this avoids
1210 * setting up child-transaction contexts for what might be just a few
1211 * bytes of grandchild XIDs.
1213 if (s->parent->childXids == NULL)
1215 MemoryContextAlloc(TopTransactionContext,
1216 new_maxChildXids * sizeof(TransactionId));
1218 new_childXids = repalloc(s->parent->childXids,
1219 new_maxChildXids * sizeof(TransactionId));
1221 s->parent->childXids = new_childXids;
1222 s->parent->maxChildXids = new_maxChildXids;
1226 * Copy all my XIDs to parent's array.
1228 * Note: We rely on the fact that the XID of a child always follows that
1229 * of its parent. By copying the XID of this subtransaction before the
1230 * XIDs of its children, we ensure that the array stays ordered.
1231 * Likewise, all XIDs already in the array belong to subtransactions
1232 * started and subcommitted before us, so their XIDs must precede ours.
1234 s->parent->childXids[s->parent->nChildXids] = s->transactionId;
1236 if (s->nChildXids > 0)
1237 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1239 s->nChildXids * sizeof(TransactionId));
1241 s->parent->nChildXids = new_nChildXids;
1243 /* Release child's array to avoid leakage */
1244 if (s->childXids != NULL)
1245 pfree(s->childXids);
1246 /* We must reset these to avoid double-free if fail later in commit */
1247 s->childXids = NULL;
1249 s->maxChildXids = 0;
1252 /* ----------------------------------------------------------------
1253 * AbortTransaction stuff
1254 * ----------------------------------------------------------------
1258 * RecordTransactionAbort
1260 * Returns latest XID among xact and its children, or InvalidTransactionId
1261 * if the xact has no XID. (We compute that here just because it's easier.)
1263 static TransactionId
1264 RecordTransactionAbort(bool isSubXact)
1266 TransactionId xid = GetCurrentTransactionIdIfAny();
1267 TransactionId latestXid;
1271 TransactionId *children;
1272 XLogRecData rdata[3];
1274 xl_xact_abort xlrec;
1277 * If we haven't been assigned an XID, nobody will care whether we aborted
1278 * or not. Hence, we're done in that case. It does not matter if we have
1279 * rels to delete (note that this routine is not responsible for actually
1280 * deleting 'em). We cannot have any child XIDs, either.
1282 if (!TransactionIdIsValid(xid))
1284 /* Reset XactLastRecEnd until the next transaction writes something */
1286 XactLastRecEnd.xrecoff = 0;
1287 return InvalidTransactionId;
1291 * We have a valid XID, so we should write an ABORT record for it.
1293 * We do not flush XLOG to disk here, since the default assumption after a
1294 * crash would be that we aborted, anyway. For the same reason, we don't
1295 * need to worry about interlocking against checkpoint start.
1299 * Check that we haven't aborted halfway through RecordTransactionCommit.
1301 if (TransactionIdDidCommit(xid))
1302 elog(PANIC, "cannot abort transaction %u, it was already committed",
1305 /* Fetch the data we need for the abort record */
1306 nrels = smgrGetPendingDeletes(false, &rels, NULL);
1307 nchildren = xactGetCommittedChildren(&children);
1309 /* XXX do we really need a critical section here? */
1310 START_CRIT_SECTION();
1312 /* Write the ABORT record */
1314 xlrec.xact_time = GetCurrentTimestamp();
1317 SetCurrentTransactionStopTimestamp();
1318 xlrec.xact_time = xactStopTimestamp;
1320 xlrec.nrels = nrels;
1321 xlrec.nsubxacts = nchildren;
1322 rdata[0].data = (char *) (&xlrec);
1323 rdata[0].len = MinSizeOfXactAbort;
1324 rdata[0].buffer = InvalidBuffer;
1325 /* dump rels to delete */
1328 rdata[0].next = &(rdata[1]);
1329 rdata[1].data = (char *) rels;
1330 rdata[1].len = nrels * sizeof(RelFileNode);
1331 rdata[1].buffer = InvalidBuffer;
1334 /* dump committed child Xids */
1337 rdata[lastrdata].next = &(rdata[2]);
1338 rdata[2].data = (char *) children;
1339 rdata[2].len = nchildren * sizeof(TransactionId);
1340 rdata[2].buffer = InvalidBuffer;
1343 rdata[lastrdata].next = NULL;
1345 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
1348 * Mark the transaction aborted in clog. This is not absolutely necessary
1349 * but we may as well do it while we are here; also, in the subxact case
1350 * it is helpful because XactLockTableWait makes use of it to avoid
1351 * waiting for already-aborted subtransactions. It is OK to do it without
1352 * having flushed the ABORT record to disk, because in event of a crash
1353 * we'd be assumed to have aborted anyway.
1355 TransactionIdAbortTree(xid, nchildren, children);
1359 /* Compute latestXid while we have the child XIDs handy */
1360 latestXid = TransactionIdLatest(xid, nchildren, children);
1363 * If we're aborting a subtransaction, we can immediately remove failed
1364 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1365 * subxacts, because we already have the child XID array at hand. For
1366 * main xacts, the equivalent happens just after this function returns.
1369 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1371 /* Reset XactLastRecEnd until the next transaction writes something */
1373 XactLastRecEnd.xrecoff = 0;
1375 /* And clean up local data */
1386 AtAbort_Memory(void)
1389 * Switch into TransactionAbortContext, which should have some free space
1390 * even if nothing else does. We'll work in this context until we've
1391 * finished cleaning up.
1393 * It is barely possible to get here when we've not been able to create
1394 * TransactionAbortContext yet; if so use TopMemoryContext.
1396 if (TransactionAbortContext != NULL)
1397 MemoryContextSwitchTo(TransactionAbortContext);
1399 MemoryContextSwitchTo(TopMemoryContext);
1406 AtSubAbort_Memory(void)
1408 Assert(TransactionAbortContext != NULL);
1410 MemoryContextSwitchTo(TransactionAbortContext);
1415 * AtAbort_ResourceOwner
1418 AtAbort_ResourceOwner(void)
1421 * Make sure we have a valid ResourceOwner, if possible (else it will be
1422 * NULL, which is OK)
1424 CurrentResourceOwner = TopTransactionResourceOwner;
1428 * AtSubAbort_ResourceOwner
1431 AtSubAbort_ResourceOwner(void)
1433 TransactionState s = CurrentTransactionState;
1435 /* Make sure we have a valid ResourceOwner */
1436 CurrentResourceOwner = s->curTransactionOwner;
1441 * AtSubAbort_childXids
1444 AtSubAbort_childXids(void)
1446 TransactionState s = CurrentTransactionState;
1449 * We keep the child-XID arrays in TopTransactionContext (see
1450 * AtSubCommit_childXids). This means we'd better free the array
1451 * explicitly at abort to avoid leakage.
1453 if (s->childXids != NULL)
1454 pfree(s->childXids);
1455 s->childXids = NULL;
1457 s->maxChildXids = 0;
1460 * We could prune the unreportedXids array here. But we don't bother.
1461 * That would potentially reduce number of XLOG_XACT_ASSIGNMENT records
1462 * but it would likely introduce more CPU time into the more common
1463 * paths, so we choose not to do that.
1467 /* ----------------------------------------------------------------
1468 * CleanupTransaction stuff
1469 * ----------------------------------------------------------------
1476 AtCleanup_Memory(void)
1478 Assert(CurrentTransactionState->parent == NULL);
1481 * Now that we're "out" of a transaction, have the system allocate things
1482 * in the top memory context instead of per-transaction contexts.
1484 MemoryContextSwitchTo(TopMemoryContext);
1487 * Clear the special abort context for next time.
1489 if (TransactionAbortContext != NULL)
1490 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1493 * Release all transaction-local memory.
1495 if (TopTransactionContext != NULL)
1496 MemoryContextDelete(TopTransactionContext);
1497 TopTransactionContext = NULL;
1498 CurTransactionContext = NULL;
1499 CurrentTransactionState->curTransactionContext = NULL;
1503 /* ----------------------------------------------------------------
1504 * CleanupSubTransaction stuff
1505 * ----------------------------------------------------------------
1509 * AtSubCleanup_Memory
1512 AtSubCleanup_Memory(void)
1514 TransactionState s = CurrentTransactionState;
1516 Assert(s->parent != NULL);
1518 /* Make sure we're not in an about-to-be-deleted context */
1519 MemoryContextSwitchTo(s->parent->curTransactionContext);
1520 CurTransactionContext = s->parent->curTransactionContext;
1523 * Clear the special abort context for next time.
1525 if (TransactionAbortContext != NULL)
1526 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1529 * Delete the subxact local memory contexts. Its CurTransactionContext can
1530 * go too (note this also kills CurTransactionContexts from any children
1533 if (s->curTransactionContext)
1534 MemoryContextDelete(s->curTransactionContext);
1535 s->curTransactionContext = NULL;
1538 /* ----------------------------------------------------------------
1539 * interface routines
1540 * ----------------------------------------------------------------
1547 StartTransaction(void)
1550 VirtualTransactionId vxid;
1553 * Let's just make sure the state stack is empty
1555 s = &TopTransactionStateData;
1556 CurrentTransactionState = s;
1559 * check the current transaction state
1561 if (s->state != TRANS_DEFAULT)
1562 elog(WARNING, "StartTransaction while in %s state",
1563 TransStateAsString(s->state));
1566 * set the current transaction state information appropriately during
1569 s->state = TRANS_START;
1570 s->transactionId = InvalidTransactionId; /* until assigned */
1573 * Make sure we've reset xact state variables
1575 * If recovery is still in progress, mark this transaction as read-only.
1576 * We have lower level defences in XLogInsert and elsewhere to stop us
1577 * from modifying data during recovery, but this gives the normal
1578 * indication to the user that the transaction is read-only.
1580 if (RecoveryInProgress())
1582 s->startedInRecovery = true;
1583 XactReadOnly = true;
1587 s->startedInRecovery = false;
1588 XactReadOnly = DefaultXactReadOnly;
1590 XactIsoLevel = DefaultXactIsoLevel;
1591 forceSyncCommit = false;
1592 MyXactAccessedTempRel = false;
1595 * reinitialize within-transaction counters
1597 s->subTransactionId = TopSubTransactionId;
1598 currentSubTransactionId = TopSubTransactionId;
1599 currentCommandId = FirstCommandId;
1600 currentCommandIdUsed = false;
1603 * initialize reported xid accounting
1605 nUnreportedXids = 0;
1608 * must initialize resource-management stuff first
1611 AtStart_ResourceOwner();
1614 * Assign a new LocalTransactionId, and combine it with the backendId to
1615 * form a virtual transaction id.
1617 vxid.backendId = MyBackendId;
1618 vxid.localTransactionId = GetNextLocalTransactionId();
1621 * Lock the virtual transaction id before we announce it in the proc array
1623 VirtualXactLockTableInsert(vxid);
1626 * Advertise it in the proc array. We assume assignment of
1627 * LocalTransactionID is atomic, and the backendId should be set already.
1629 Assert(MyProc->backendId == vxid.backendId);
1630 MyProc->lxid = vxid.localTransactionId;
1632 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
1635 * set transaction_timestamp() (a/k/a now()). We want this to be the same
1636 * as the first command's statement_timestamp(), so don't do a fresh
1637 * GetCurrentTimestamp() call (which'd be expensive anyway). Also, mark
1638 * xactStopTimestamp as unset.
1640 xactStartTimestamp = stmtStartTimestamp;
1641 xactStopTimestamp = 0;
1642 pgstat_report_xact_timestamp(xactStartTimestamp);
1645 * initialize current transaction state fields
1647 * note: prevXactReadOnly is not used at the outermost level
1649 s->nestingLevel = 1;
1650 s->gucNestLevel = 1;
1651 s->childXids = NULL;
1653 s->maxChildXids = 0;
1654 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
1655 /* SecurityRestrictionContext should never be set outside a transaction */
1656 Assert(s->prevSecContext == 0);
1659 * initialize other subsystems for new transaction
1664 AfterTriggerBeginXact();
1667 * done with start processing, set current transaction state to "in
1670 s->state = TRANS_INPROGRESS;
1672 ShowTransactionState("StartTransaction");
1679 * NB: if you change this routine, better look at PrepareTransaction too!
1682 CommitTransaction(void)
1684 TransactionState s = CurrentTransactionState;
1685 TransactionId latestXid;
1687 ShowTransactionState("CommitTransaction");
1690 * check the current transaction state
1692 if (s->state != TRANS_INPROGRESS)
1693 elog(WARNING, "CommitTransaction while in %s state",
1694 TransStateAsString(s->state));
1695 Assert(s->parent == NULL);
1698 * Do pre-commit processing (most of this stuff requires database access,
1699 * and in fact could still cause an error...)
1701 * It is possible for CommitHoldablePortals to invoke functions that queue
1702 * deferred triggers, and it's also possible that triggers create holdable
1703 * cursors. So we have to loop until there's nothing left to do.
1708 * Fire all currently pending deferred triggers.
1710 AfterTriggerFireDeferred();
1713 * Convert any open holdable cursors into static portals. If there
1714 * weren't any, we are done ... otherwise loop back to check if they
1715 * queued deferred triggers. Lather, rinse, repeat.
1717 if (!CommitHoldablePortals())
1721 /* Now we can shut down the deferred-trigger manager */
1722 AfterTriggerEndXact(true);
1724 /* Close any open regular cursors */
1728 * Let ON COMMIT management do its thing (must happen after closing
1729 * cursors, to avoid dangling-reference problems)
1731 PreCommit_on_commit_actions();
1733 /* close large objects before lower-level cleanup */
1734 AtEOXact_LargeObject(true);
1737 * Insert notifications sent by NOTIFY commands into the queue. This
1738 * should be late in the pre-commit sequence to minimize time spent
1739 * holding the notify-insertion lock.
1743 /* Prevent cancel/die interrupt while cleaning up */
1746 /* Commit updates to the relation map --- do this as late as possible */
1747 AtEOXact_RelationMap(true);
1750 * set the current transaction state information appropriately during
1753 s->state = TRANS_COMMIT;
1756 * Here is where we really truly commit.
1758 latestXid = RecordTransactionCommit();
1760 TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
1763 * Let others know about no transaction in progress by me. Note that this
1764 * must be done _before_ releasing locks we hold and _after_
1765 * RecordTransactionCommit.
1767 ProcArrayEndTransaction(MyProc, latestXid);
1770 * This is all post-commit cleanup. Note that if an error is raised here,
1771 * it's too late to abort the transaction. This should be just
1772 * noncritical resource releasing.
1774 * The ordering of operations is not entirely random. The idea is:
1775 * release resources visible to other backends (eg, files, buffer pins);
1776 * then release locks; then release backend-local resources. We want to
1777 * release locks at the point where any backend waiting for us will see
1778 * our transaction as being fully cleaned up.
1780 * Resources that can be associated with individual queries are handled by
1781 * the ResourceOwner mechanism. The other calls here are for backend-wide
1785 CallXactCallbacks(XACT_EVENT_COMMIT);
1787 ResourceOwnerRelease(TopTransactionResourceOwner,
1788 RESOURCE_RELEASE_BEFORE_LOCKS,
1791 /* Check we've released all buffer pins */
1792 AtEOXact_Buffers(true);
1794 /* Clean up the relation cache */
1795 AtEOXact_RelationCache(true);
1797 /* Clean up the snapshot manager */
1798 AtEarlyCommit_Snapshot();
1801 * Make catalog changes visible to all backends. This has to happen after
1802 * relcache references are dropped (see comments for
1803 * AtEOXact_RelationCache), but before locks are released (if anyone is
1804 * waiting for lock on a relation we've modified, we want them to know
1805 * about the catalog change before they start using the relation).
1807 AtEOXact_Inval(true);
1810 * Likewise, dropping of files deleted during the transaction is best done
1811 * after releasing relcache and buffer pins. (This is not strictly
1812 * necessary during commit, since such pins should have been released
1813 * already, but this ordering is definitely critical during abort.)
1815 smgrDoPendingDeletes(true);
1817 AtEOXact_MultiXact();
1819 ResourceOwnerRelease(TopTransactionResourceOwner,
1820 RESOURCE_RELEASE_LOCKS,
1822 ResourceOwnerRelease(TopTransactionResourceOwner,
1823 RESOURCE_RELEASE_AFTER_LOCKS,
1826 /* Check we've released all catcache entries */
1827 AtEOXact_CatCache(true);
1830 AtEOXact_GUC(true, 1);
1832 AtEOXact_on_commit_actions(true);
1833 AtEOXact_Namespace(true);
1834 /* smgrcommit already done */
1836 AtEOXact_ComboCid();
1837 AtEOXact_HashTables(true);
1838 AtEOXact_PgStat(true);
1839 AtEOXact_Snapshot(true);
1840 pgstat_report_xact_timestamp(0);
1842 CurrentResourceOwner = NULL;
1843 ResourceOwnerDelete(TopTransactionResourceOwner);
1844 s->curTransactionOwner = NULL;
1845 CurTransactionResourceOwner = NULL;
1846 TopTransactionResourceOwner = NULL;
1850 s->transactionId = InvalidTransactionId;
1851 s->subTransactionId = InvalidSubTransactionId;
1852 s->nestingLevel = 0;
1853 s->gucNestLevel = 0;
1854 s->childXids = NULL;
1856 s->maxChildXids = 0;
1859 * done with commit processing, set current transaction state back to
1862 s->state = TRANS_DEFAULT;
1864 RESUME_INTERRUPTS();
1869 * PrepareTransaction
1871 * NB: if you change this routine, better look at CommitTransaction too!
1874 PrepareTransaction(void)
1876 TransactionState s = CurrentTransactionState;
1877 TransactionId xid = GetCurrentTransactionId();
1878 GlobalTransaction gxact;
1879 TimestampTz prepared_at;
1881 ShowTransactionState("PrepareTransaction");
1884 * check the current transaction state
1886 if (s->state != TRANS_INPROGRESS)
1887 elog(WARNING, "PrepareTransaction while in %s state",
1888 TransStateAsString(s->state));
1889 Assert(s->parent == NULL);
1892 * Do pre-commit processing (most of this stuff requires database access,
1893 * and in fact could still cause an error...)
1895 * It is possible for PrepareHoldablePortals to invoke functions that
1896 * queue deferred triggers, and it's also possible that triggers create
1897 * holdable cursors. So we have to loop until there's nothing left to do.
1902 * Fire all currently pending deferred triggers.
1904 AfterTriggerFireDeferred();
1907 * Convert any open holdable cursors into static portals. If there
1908 * weren't any, we are done ... otherwise loop back to check if they
1909 * queued deferred triggers. Lather, rinse, repeat.
1911 if (!PrepareHoldablePortals())
1915 /* Now we can shut down the deferred-trigger manager */
1916 AfterTriggerEndXact(true);
1918 /* Close any open regular cursors */
1922 * Let ON COMMIT management do its thing (must happen after closing
1923 * cursors, to avoid dangling-reference problems)
1925 PreCommit_on_commit_actions();
1927 /* close large objects before lower-level cleanup */
1928 AtEOXact_LargeObject(true);
1930 /* NOTIFY will be handled below */
1933 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
1934 * this transaction. Having the prepared xact hold locks on another
1935 * backend's temp table seems a bad idea --- for instance it would prevent
1936 * the backend from exiting. There are other problems too, such as how to
1937 * clean up the source backend's local buffers and ON COMMIT state if the
1938 * prepared xact includes a DROP of a temp table.
1940 * We must check this after executing any ON COMMIT actions, because they
1941 * might still access a temp relation.
1943 * XXX In principle this could be relaxed to allow some useful special
1944 * cases, such as a temp table created and dropped all within the
1945 * transaction. That seems to require much more bookkeeping though.
1947 if (MyXactAccessedTempRel)
1949 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1950 errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
1952 /* Prevent cancel/die interrupt while cleaning up */
1956 * set the current transaction state information appropriately during
1957 * prepare processing
1959 s->state = TRANS_PREPARE;
1961 prepared_at = GetCurrentTimestamp();
1963 /* Tell bufmgr and smgr to prepare for commit */
1967 * Reserve the GID for this transaction. This could fail if the requested
1968 * GID is invalid or already in use.
1970 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
1971 GetUserId(), MyDatabaseId);
1975 * Collect data for the 2PC state file. Note that in general, no actual
1976 * state change should happen in the called modules during this step,
1977 * since it's still possible to fail before commit, and in that case we
1978 * want transaction abort to be able to clean up. (In particular, the
1979 * AtPrepare routines may error out if they find cases they cannot
1980 * handle.) State cleanup should happen in the PostPrepare routines
1981 * below. However, some modules can go ahead and clear state here because
1982 * they wouldn't do anything with it during abort anyway.
1984 * Note: because the 2PC state file records will be replayed in the same
1985 * order they are made, the order of these calls has to match the order in
1986 * which we want things to happen during COMMIT PREPARED or ROLLBACK
1987 * PREPARED; in particular, pay attention to whether things should happen
1988 * before or after releasing the transaction's locks.
1990 StartPrepare(gxact);
1995 AtPrepare_MultiXact();
1996 AtPrepare_RelationMap();
1999 * Here is where we really truly prepare.
2001 * We have to record transaction prepares even if we didn't make any
2002 * updates, because the transaction manager might get confused if we lose
2003 * a global transaction.
2008 * Now we clean up backend-internal state and release internal resources.
2011 /* Reset XactLastRecEnd until the next transaction writes something */
2012 XactLastRecEnd.xrecoff = 0;
2015 * Let others know about no transaction in progress by me. This has to be
2016 * done *after* the prepared transaction has been marked valid, else
2017 * someone may think it is unlocked and recyclable.
2019 ProcArrayClearTransaction(MyProc);
2022 * This is all post-transaction cleanup. Note that if an error is raised
2023 * here, it's too late to abort the transaction. This should be just
2024 * noncritical resource releasing. See notes in CommitTransaction.
2027 CallXactCallbacks(XACT_EVENT_PREPARE);
2029 ResourceOwnerRelease(TopTransactionResourceOwner,
2030 RESOURCE_RELEASE_BEFORE_LOCKS,
2033 /* Check we've released all buffer pins */
2034 AtEOXact_Buffers(true);
2036 /* Clean up the relation cache */
2037 AtEOXact_RelationCache(true);
2039 /* Clean up the snapshot manager */
2040 AtEarlyCommit_Snapshot();
2042 /* notify doesn't need a postprepare call */
2044 PostPrepare_PgStat();
2046 PostPrepare_Inval();
2050 PostPrepare_MultiXact(xid);
2052 PostPrepare_Locks(xid);
2054 ResourceOwnerRelease(TopTransactionResourceOwner,
2055 RESOURCE_RELEASE_LOCKS,
2057 ResourceOwnerRelease(TopTransactionResourceOwner,
2058 RESOURCE_RELEASE_AFTER_LOCKS,
2061 /* Check we've released all catcache entries */
2062 AtEOXact_CatCache(true);
2064 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2065 AtEOXact_GUC(true, 1);
2067 AtEOXact_on_commit_actions(true);
2068 AtEOXact_Namespace(true);
2069 /* smgrcommit already done */
2071 AtEOXact_ComboCid();
2072 AtEOXact_HashTables(true);
2073 /* don't call AtEOXact_PgStat here */
2074 AtEOXact_Snapshot(true);
2076 CurrentResourceOwner = NULL;
2077 ResourceOwnerDelete(TopTransactionResourceOwner);
2078 s->curTransactionOwner = NULL;
2079 CurTransactionResourceOwner = NULL;
2080 TopTransactionResourceOwner = NULL;
2084 s->transactionId = InvalidTransactionId;
2085 s->subTransactionId = InvalidSubTransactionId;
2086 s->nestingLevel = 0;
2087 s->gucNestLevel = 0;
2088 s->childXids = NULL;
2090 s->maxChildXids = 0;
2093 * done with 1st phase commit processing, set current transaction state
2096 s->state = TRANS_DEFAULT;
2098 RESUME_INTERRUPTS();
2106 AbortTransaction(void)
2108 TransactionState s = CurrentTransactionState;
2109 TransactionId latestXid;
2111 /* Prevent cancel/die interrupt while cleaning up */
2114 /* Make sure we have a valid memory context and resource owner */
2116 AtAbort_ResourceOwner();
2119 * Release any LW locks we might be holding as quickly as possible.
2120 * (Regular locks, however, must be held till we finish aborting.)
2121 * Releasing LW locks is critical since we might try to grab them again
2122 * while cleaning up!
2126 /* Clean up buffer I/O and buffer context locks, too */
2131 * Also clean up any open wait for lock, since the lock manager will choke
2132 * if we try to wait for another lock before doing this.
2137 * check the current transaction state
2139 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2140 elog(WARNING, "AbortTransaction while in %s state",
2141 TransStateAsString(s->state));
2142 Assert(s->parent == NULL);
2145 * set the current transaction state information appropriately during the
2148 s->state = TRANS_ABORT;
2151 * Reset user ID which might have been changed transiently. We need this
2152 * to clean up in case control escaped out of a SECURITY DEFINER function
2153 * or other local change of CurrentUserId; therefore, the prior value of
2154 * SecurityRestrictionContext also needs to be restored.
2156 * (Note: it is not necessary to restore session authorization or role
2157 * settings here because those can only be changed via GUC, and GUC will
2158 * take care of rolling them back if need be.)
2160 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
2163 * do abort processing
2165 AfterTriggerEndXact(false); /* 'false' means it's abort */
2167 AtEOXact_LargeObject(false);
2169 AtEOXact_RelationMap(false);
2172 * Advertise the fact that we aborted in pg_clog (assuming that we got as
2173 * far as assigning an XID to advertise).
2175 latestXid = RecordTransactionAbort(false);
2177 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
2180 * Let others know about no transaction in progress by me. Note that this
2181 * must be done _before_ releasing locks we hold and _after_
2182 * RecordTransactionAbort.
2184 ProcArrayEndTransaction(MyProc, latestXid);
2187 * Post-abort cleanup. See notes in CommitTransaction() concerning
2188 * ordering. We can skip all of it if the transaction failed before
2189 * creating a resource owner.
2191 if (TopTransactionResourceOwner != NULL)
2193 CallXactCallbacks(XACT_EVENT_ABORT);
2195 ResourceOwnerRelease(TopTransactionResourceOwner,
2196 RESOURCE_RELEASE_BEFORE_LOCKS,
2198 AtEOXact_Buffers(false);
2199 AtEOXact_RelationCache(false);
2200 AtEOXact_Inval(false);
2201 smgrDoPendingDeletes(false);
2202 AtEOXact_MultiXact();
2203 ResourceOwnerRelease(TopTransactionResourceOwner,
2204 RESOURCE_RELEASE_LOCKS,
2206 ResourceOwnerRelease(TopTransactionResourceOwner,
2207 RESOURCE_RELEASE_AFTER_LOCKS,
2209 AtEOXact_CatCache(false);
2211 AtEOXact_GUC(false, 1);
2212 AtEOXact_SPI(false);
2213 AtEOXact_on_commit_actions(false);
2214 AtEOXact_Namespace(false);
2216 AtEOXact_ComboCid();
2217 AtEOXact_HashTables(false);
2218 AtEOXact_PgStat(false);
2219 AtEOXact_Snapshot(false);
2220 pgstat_report_xact_timestamp(0);
2224 * State remains TRANS_ABORT until CleanupTransaction().
2226 RESUME_INTERRUPTS();
2230 * CleanupTransaction
2233 CleanupTransaction(void)
2235 TransactionState s = CurrentTransactionState;
2238 * State should still be TRANS_ABORT from AbortTransaction().
2240 if (s->state != TRANS_ABORT)
2241 elog(FATAL, "CleanupTransaction: unexpected state %s",
2242 TransStateAsString(s->state));
2245 * do abort cleanup processing
2247 AtCleanup_Portals(); /* now safe to release portal memory */
2249 CurrentResourceOwner = NULL; /* and resource owner */
2250 if (TopTransactionResourceOwner)
2251 ResourceOwnerDelete(TopTransactionResourceOwner);
2252 s->curTransactionOwner = NULL;
2253 CurTransactionResourceOwner = NULL;
2254 TopTransactionResourceOwner = NULL;
2256 AtCleanup_Memory(); /* and transaction memory */
2258 s->transactionId = InvalidTransactionId;
2259 s->subTransactionId = InvalidSubTransactionId;
2260 s->nestingLevel = 0;
2261 s->gucNestLevel = 0;
2262 s->childXids = NULL;
2264 s->maxChildXids = 0;
2267 * done with abort processing, set current transaction state back to
2270 s->state = TRANS_DEFAULT;
2274 * StartTransactionCommand
2277 StartTransactionCommand(void)
2279 TransactionState s = CurrentTransactionState;
2281 switch (s->blockState)
2284 * if we aren't in a transaction block, we just do our usual start
2287 case TBLOCK_DEFAULT:
2289 s->blockState = TBLOCK_STARTED;
2293 * We are somewhere in a transaction block or subtransaction and
2294 * about to start a new command. For now we do nothing, but
2295 * someday we may do command-local resource initialization. (Note
2296 * that any needed CommandCounterIncrement was done by the
2297 * previous CommitTransactionCommand.)
2299 case TBLOCK_INPROGRESS:
2300 case TBLOCK_SUBINPROGRESS:
2304 * Here we are in a failed transaction block (one of the commands
2305 * caused an abort) so we do nothing but remain in the abort
2306 * state. Eventually we will get a ROLLBACK command which will
2307 * get us out of this state. (It is up to other code to ensure
2308 * that no commands other than ROLLBACK will be processed in these
2312 case TBLOCK_SUBABORT:
2315 /* These cases are invalid. */
2316 case TBLOCK_STARTED:
2318 case TBLOCK_SUBBEGIN:
2321 case TBLOCK_ABORT_END:
2322 case TBLOCK_SUBABORT_END:
2323 case TBLOCK_ABORT_PENDING:
2324 case TBLOCK_SUBABORT_PENDING:
2325 case TBLOCK_SUBRESTART:
2326 case TBLOCK_SUBABORT_RESTART:
2327 case TBLOCK_PREPARE:
2328 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2329 BlockStateAsString(s->blockState));
2334 * We must switch to CurTransactionContext before returning. This is
2335 * already done if we called StartTransaction, otherwise not.
2337 Assert(CurTransactionContext != NULL);
2338 MemoryContextSwitchTo(CurTransactionContext);
2342 * CommitTransactionCommand
2345 CommitTransactionCommand(void)
2347 TransactionState s = CurrentTransactionState;
2349 switch (s->blockState)
2352 * This shouldn't happen, because it means the previous
2353 * StartTransactionCommand didn't set the STARTED state
2356 case TBLOCK_DEFAULT:
2357 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2358 BlockStateAsString(s->blockState));
2362 * If we aren't in a transaction block, just do our usual
2363 * transaction commit, and return to the idle state.
2365 case TBLOCK_STARTED:
2366 CommitTransaction();
2367 s->blockState = TBLOCK_DEFAULT;
2371 * We are completing a "BEGIN TRANSACTION" command, so we change
2372 * to the "transaction block in progress" state and return. (We
2373 * assume the BEGIN did nothing to the database, so we need no
2374 * CommandCounterIncrement.)
2377 s->blockState = TBLOCK_INPROGRESS;
2381 * This is the case when we have finished executing a command
2382 * someplace within a transaction block. We increment the command
2383 * counter and return.
2385 case TBLOCK_INPROGRESS:
2386 case TBLOCK_SUBINPROGRESS:
2387 CommandCounterIncrement();
2391 * We are completing a "COMMIT" command. Do it and return to the
2395 CommitTransaction();
2396 s->blockState = TBLOCK_DEFAULT;
2400 * Here we are in the middle of a transaction block but one of the
2401 * commands caused an abort so we do nothing but remain in the
2402 * abort state. Eventually we will get a ROLLBACK comand.
2405 case TBLOCK_SUBABORT:
2409 * Here we were in an aborted transaction block and we just got
2410 * the ROLLBACK command from the user, so clean up the
2411 * already-aborted transaction and return to the idle state.
2413 case TBLOCK_ABORT_END:
2414 CleanupTransaction();
2415 s->blockState = TBLOCK_DEFAULT;
2419 * Here we were in a perfectly good transaction block but the user
2420 * told us to ROLLBACK anyway. We have to abort the transaction
2421 * and then clean up.
2423 case TBLOCK_ABORT_PENDING:
2425 CleanupTransaction();
2426 s->blockState = TBLOCK_DEFAULT;
2430 * We are completing a "PREPARE TRANSACTION" command. Do it and
2431 * return to the idle state.
2433 case TBLOCK_PREPARE:
2434 PrepareTransaction();
2435 s->blockState = TBLOCK_DEFAULT;
2439 * We were just issued a SAVEPOINT inside a transaction block.
2440 * Start a subtransaction. (DefineSavepoint already did
2441 * PushTransaction, so as to have someplace to put the SUBBEGIN
2444 case TBLOCK_SUBBEGIN:
2445 StartSubTransaction();
2446 s->blockState = TBLOCK_SUBINPROGRESS;
2450 * We were issued a COMMIT or RELEASE command, so we end the
2451 * current subtransaction and return to the parent transaction.
2452 * The parent might be ended too, so repeat till we are all the
2453 * way out or find an INPROGRESS transaction.
2458 CommitSubTransaction();
2459 s = CurrentTransactionState; /* changed by pop */
2460 } while (s->blockState == TBLOCK_SUBEND);
2461 /* If we had a COMMIT command, finish off the main xact too */
2462 if (s->blockState == TBLOCK_END)
2464 Assert(s->parent == NULL);
2465 CommitTransaction();
2466 s->blockState = TBLOCK_DEFAULT;
2468 else if (s->blockState == TBLOCK_PREPARE)
2470 Assert(s->parent == NULL);
2471 PrepareTransaction();
2472 s->blockState = TBLOCK_DEFAULT;
2476 Assert(s->blockState == TBLOCK_INPROGRESS ||
2477 s->blockState == TBLOCK_SUBINPROGRESS);
2482 * The current already-failed subtransaction is ending due to a
2483 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2484 * examine the parent (which could be in any of several states).
2486 case TBLOCK_SUBABORT_END:
2487 CleanupSubTransaction();
2488 CommitTransactionCommand();
2492 * As above, but it's not dead yet, so abort first.
2494 case TBLOCK_SUBABORT_PENDING:
2495 AbortSubTransaction();
2496 CleanupSubTransaction();
2497 CommitTransactionCommand();
2501 * The current subtransaction is the target of a ROLLBACK TO
2502 * command. Abort and pop it, then start a new subtransaction
2503 * with the same name.
2505 case TBLOCK_SUBRESTART:
2510 /* save name and keep Cleanup from freeing it */
2513 savepointLevel = s->savepointLevel;
2515 AbortSubTransaction();
2516 CleanupSubTransaction();
2518 DefineSavepoint(NULL);
2519 s = CurrentTransactionState; /* changed by push */
2521 s->savepointLevel = savepointLevel;
2523 /* This is the same as TBLOCK_SUBBEGIN case */
2524 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2525 StartSubTransaction();
2526 s->blockState = TBLOCK_SUBINPROGRESS;
2531 * Same as above, but the subtransaction had already failed, so we
2532 * don't need AbortSubTransaction.
2534 case TBLOCK_SUBABORT_RESTART:
2539 /* save name and keep Cleanup from freeing it */
2542 savepointLevel = s->savepointLevel;
2544 CleanupSubTransaction();
2546 DefineSavepoint(NULL);
2547 s = CurrentTransactionState; /* changed by push */
2549 s->savepointLevel = savepointLevel;
2551 /* This is the same as TBLOCK_SUBBEGIN case */
2552 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2553 StartSubTransaction();
2554 s->blockState = TBLOCK_SUBINPROGRESS;
2561 * AbortCurrentTransaction
2564 AbortCurrentTransaction(void)
2566 TransactionState s = CurrentTransactionState;
2568 switch (s->blockState)
2570 case TBLOCK_DEFAULT:
2571 if (s->state == TRANS_DEFAULT)
2573 /* we are idle, so nothing to do */
2578 * We can get here after an error during transaction start
2579 * (state will be TRANS_START). Need to clean up the
2580 * incompletely started transaction. First, adjust the
2581 * low-level state to suppress warning message from
2584 if (s->state == TRANS_START)
2585 s->state = TRANS_INPROGRESS;
2587 CleanupTransaction();
2592 * if we aren't in a transaction block, we just do the basic abort
2593 * & cleanup transaction.
2595 case TBLOCK_STARTED:
2597 CleanupTransaction();
2598 s->blockState = TBLOCK_DEFAULT;
2602 * If we are in TBLOCK_BEGIN it means something screwed up right
2603 * after reading "BEGIN TRANSACTION". We assume that the user
2604 * will interpret the error as meaning the BEGIN failed to get him
2605 * into a transaction block, so we should abort and return to idle
2610 CleanupTransaction();
2611 s->blockState = TBLOCK_DEFAULT;
2615 * We are somewhere in a transaction block and we've gotten a
2616 * failure, so we abort the transaction and set up the persistent
2617 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
2619 case TBLOCK_INPROGRESS:
2621 s->blockState = TBLOCK_ABORT;
2622 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
2626 * Here, we failed while trying to COMMIT. Clean up the
2627 * transaction and return to idle state (we do not want to stay in
2632 CleanupTransaction();
2633 s->blockState = TBLOCK_DEFAULT;
2637 * Here, we are already in an aborted transaction state and are
2638 * waiting for a ROLLBACK, but for some reason we failed again! So
2639 * we just remain in the abort state.
2642 case TBLOCK_SUBABORT:
2646 * We are in a failed transaction and we got the ROLLBACK command.
2647 * We have already aborted, we just need to cleanup and go to idle
2650 case TBLOCK_ABORT_END:
2651 CleanupTransaction();
2652 s->blockState = TBLOCK_DEFAULT;
2656 * We are in a live transaction and we got a ROLLBACK command.
2657 * Abort, cleanup, go to idle state.
2659 case TBLOCK_ABORT_PENDING:
2661 CleanupTransaction();
2662 s->blockState = TBLOCK_DEFAULT;
2666 * Here, we failed while trying to PREPARE. Clean up the
2667 * transaction and return to idle state (we do not want to stay in
2670 case TBLOCK_PREPARE:
2672 CleanupTransaction();
2673 s->blockState = TBLOCK_DEFAULT;
2677 * We got an error inside a subtransaction. Abort just the
2678 * subtransaction, and go to the persistent SUBABORT state until
2681 case TBLOCK_SUBINPROGRESS:
2682 AbortSubTransaction();
2683 s->blockState = TBLOCK_SUBABORT;
2687 * If we failed while trying to create a subtransaction, clean up
2688 * the broken subtransaction and abort the parent. The same
2689 * applies if we get a failure while ending a subtransaction.
2691 case TBLOCK_SUBBEGIN:
2693 case TBLOCK_SUBABORT_PENDING:
2694 case TBLOCK_SUBRESTART:
2695 AbortSubTransaction();
2696 CleanupSubTransaction();
2697 AbortCurrentTransaction();
2701 * Same as above, except the Abort() was already done.
2703 case TBLOCK_SUBABORT_END:
2704 case TBLOCK_SUBABORT_RESTART:
2705 CleanupSubTransaction();
2706 AbortCurrentTransaction();
2712 * PreventTransactionChain
2714 * This routine is to be called by statements that must not run inside
2715 * a transaction block, typically because they have non-rollback-able
2716 * side effects or do internal commits.
2718 * If we have already started a transaction block, issue an error; also issue
2719 * an error if we appear to be running inside a user-defined function (which
2720 * could issue more commands and possibly cause a failure after the statement
2721 * completes). Subtransactions are verboten too.
2723 * isTopLevel: passed down from ProcessUtility to determine whether we are
2724 * inside a function or multi-query querystring. (We will always fail if
2725 * this is false, but it's convenient to centralize the check here instead of
2726 * making callers do it.)
2727 * stmtType: statement type name, for error messages.
2730 PreventTransactionChain(bool isTopLevel, const char *stmtType)
2733 * xact block already started?
2735 if (IsTransactionBlock())
2737 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2738 /* translator: %s represents an SQL statement name */
2739 errmsg("%s cannot run inside a transaction block",
2745 if (IsSubTransaction())
2747 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2748 /* translator: %s represents an SQL statement name */
2749 errmsg("%s cannot run inside a subtransaction",
2753 * inside a function call?
2757 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2758 /* translator: %s represents an SQL statement name */
2759 errmsg("%s cannot be executed from a function or multi-command string",
2762 /* If we got past IsTransactionBlock test, should be in default state */
2763 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2764 CurrentTransactionState->blockState != TBLOCK_STARTED)
2765 elog(FATAL, "cannot prevent transaction chain");
2770 * RequireTransactionChain
2772 * This routine is to be called by statements that must run inside
2773 * a transaction block, because they have no effects that persist past
2774 * transaction end (and so calling them outside a transaction block
2775 * is presumably an error). DECLARE CURSOR is an example.
2777 * If we appear to be running inside a user-defined function, we do not
2778 * issue an error, since the function could issue more commands that make
2779 * use of the current statement's results. Likewise subtransactions.
2780 * Thus this is an inverse for PreventTransactionChain.
2782 * isTopLevel: passed down from ProcessUtility to determine whether we are
2783 * inside a function.
2784 * stmtType: statement type name, for error messages.
2787 RequireTransactionChain(bool isTopLevel, const char *stmtType)
2790 * xact block already started?
2792 if (IsTransactionBlock())
2798 if (IsSubTransaction())
2802 * inside a function call?
2808 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2809 /* translator: %s represents an SQL statement name */
2810 errmsg("%s can only be used in transaction blocks",
2815 * IsInTransactionChain
2817 * This routine is for statements that need to behave differently inside
2818 * a transaction block than when running as single commands. ANALYZE is
2819 * currently the only example.
2821 * isTopLevel: passed down from ProcessUtility to determine whether we are
2822 * inside a function.
2825 IsInTransactionChain(bool isTopLevel)
2828 * Return true on same conditions that would make PreventTransactionChain
2831 if (IsTransactionBlock())
2834 if (IsSubTransaction())
2840 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2841 CurrentTransactionState->blockState != TBLOCK_STARTED)
2849 * Register or deregister callback functions for start- and end-of-xact
2852 * These functions are intended for use by dynamically loaded modules.
2853 * For built-in modules we generally just hardwire the appropriate calls
2854 * (mainly because it's easier to control the order that way, where needed).
2856 * At transaction end, the callback occurs post-commit or post-abort, so the
2857 * callback functions can only do noncritical cleanup.
2860 RegisterXactCallback(XactCallback callback, void *arg)
2862 XactCallbackItem *item;
2864 item = (XactCallbackItem *)
2865 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
2866 item->callback = callback;
2868 item->next = Xact_callbacks;
2869 Xact_callbacks = item;
2873 UnregisterXactCallback(XactCallback callback, void *arg)
2875 XactCallbackItem *item;
2876 XactCallbackItem *prev;
2879 for (item = Xact_callbacks; item; prev = item, item = item->next)
2881 if (item->callback == callback && item->arg == arg)
2884 prev->next = item->next;
2886 Xact_callbacks = item->next;
2894 CallXactCallbacks(XactEvent event)
2896 XactCallbackItem *item;
2898 for (item = Xact_callbacks; item; item = item->next)
2899 (*item->callback) (event, item->arg);
2904 * Register or deregister callback functions for start- and end-of-subxact
2907 * Pretty much same as above, but for subtransaction events.
2909 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
2910 * so the callback functions can only do noncritical cleanup. At
2911 * subtransaction start, the callback is called when the subtransaction has
2912 * finished initializing.
2915 RegisterSubXactCallback(SubXactCallback callback, void *arg)
2917 SubXactCallbackItem *item;
2919 item = (SubXactCallbackItem *)
2920 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
2921 item->callback = callback;
2923 item->next = SubXact_callbacks;
2924 SubXact_callbacks = item;
2928 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
2930 SubXactCallbackItem *item;
2931 SubXactCallbackItem *prev;
2934 for (item = SubXact_callbacks; item; prev = item, item = item->next)
2936 if (item->callback == callback && item->arg == arg)
2939 prev->next = item->next;
2941 SubXact_callbacks = item->next;
2949 CallSubXactCallbacks(SubXactEvent event,
2950 SubTransactionId mySubid,
2951 SubTransactionId parentSubid)
2953 SubXactCallbackItem *item;
2955 for (item = SubXact_callbacks; item; item = item->next)
2956 (*item->callback) (event, mySubid, parentSubid, item->arg);
2960 /* ----------------------------------------------------------------
2961 * transaction block support
2962 * ----------------------------------------------------------------
2966 * BeginTransactionBlock
2967 * This executes a BEGIN command.
2970 BeginTransactionBlock(void)
2972 TransactionState s = CurrentTransactionState;
2974 switch (s->blockState)
2977 * We are not inside a transaction block, so allow one to begin.
2979 case TBLOCK_STARTED:
2980 s->blockState = TBLOCK_BEGIN;
2984 * Already a transaction block in progress.
2986 case TBLOCK_INPROGRESS:
2987 case TBLOCK_SUBINPROGRESS:
2989 case TBLOCK_SUBABORT:
2991 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2992 errmsg("there is already a transaction in progress")));
2995 /* These cases are invalid. */
2996 case TBLOCK_DEFAULT:
2998 case TBLOCK_SUBBEGIN:
3001 case TBLOCK_ABORT_END:
3002 case TBLOCK_SUBABORT_END:
3003 case TBLOCK_ABORT_PENDING:
3004 case TBLOCK_SUBABORT_PENDING:
3005 case TBLOCK_SUBRESTART:
3006 case TBLOCK_SUBABORT_RESTART:
3007 case TBLOCK_PREPARE:
3008 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3009 BlockStateAsString(s->blockState));
3015 * PrepareTransactionBlock
3016 * This executes a PREPARE command.
3018 * Since PREPARE may actually do a ROLLBACK, the result indicates what
3019 * happened: TRUE for PREPARE, FALSE for ROLLBACK.
3021 * Note that we don't actually do anything here except change blockState.
3022 * The real work will be done in the upcoming PrepareTransaction().
3023 * We do it this way because it's not convenient to change memory context,
3024 * resource owner, etc while executing inside a Portal.
3027 PrepareTransactionBlock(char *gid)
3032 /* Set up to commit the current transaction */
3033 result = EndTransactionBlock();
3035 /* If successful, change outer tblock state to PREPARE */
3038 s = CurrentTransactionState;
3040 while (s->parent != NULL)
3043 if (s->blockState == TBLOCK_END)
3045 /* Save GID where PrepareTransaction can find it again */
3046 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
3048 s->blockState = TBLOCK_PREPARE;
3053 * ignore case where we are not in a transaction;
3054 * EndTransactionBlock already issued a warning.
3056 Assert(s->blockState == TBLOCK_STARTED);
3057 /* Don't send back a PREPARE result tag... */
3066 * EndTransactionBlock
3067 * This executes a COMMIT command.
3069 * Since COMMIT may actually do a ROLLBACK, the result indicates what
3070 * happened: TRUE for COMMIT, FALSE for ROLLBACK.
3072 * Note that we don't actually do anything here except change blockState.
3073 * The real work will be done in the upcoming CommitTransactionCommand().
3074 * We do it this way because it's not convenient to change memory context,
3075 * resource owner, etc while executing inside a Portal.
3078 EndTransactionBlock(void)
3080 TransactionState s = CurrentTransactionState;
3081 bool result = false;
3083 switch (s->blockState)
3086 * We are in a transaction block, so tell CommitTransactionCommand
3089 case TBLOCK_INPROGRESS:
3090 s->blockState = TBLOCK_END;
3095 * We are in a failed transaction block. Tell
3096 * CommitTransactionCommand it's time to exit the block.
3099 s->blockState = TBLOCK_ABORT_END;
3103 * We are in a live subtransaction block. Set up to subcommit all
3104 * open subtransactions and then commit the main transaction.
3106 case TBLOCK_SUBINPROGRESS:
3107 while (s->parent != NULL)
3109 if (s->blockState == TBLOCK_SUBINPROGRESS)
3110 s->blockState = TBLOCK_SUBEND;
3112 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3113 BlockStateAsString(s->blockState));
3116 if (s->blockState == TBLOCK_INPROGRESS)
3117 s->blockState = TBLOCK_END;
3119 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3120 BlockStateAsString(s->blockState));
3125 * Here we are inside an aborted subtransaction. Treat the COMMIT
3126 * as ROLLBACK: set up to abort everything and exit the main
3129 case TBLOCK_SUBABORT:
3130 while (s->parent != NULL)
3132 if (s->blockState == TBLOCK_SUBINPROGRESS)
3133 s->blockState = TBLOCK_SUBABORT_PENDING;
3134 else if (s->blockState == TBLOCK_SUBABORT)
3135 s->blockState = TBLOCK_SUBABORT_END;
3137 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3138 BlockStateAsString(s->blockState));
3141 if (s->blockState == TBLOCK_INPROGRESS)
3142 s->blockState = TBLOCK_ABORT_PENDING;
3143 else if (s->blockState == TBLOCK_ABORT)
3144 s->blockState = TBLOCK_ABORT_END;
3146 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3147 BlockStateAsString(s->blockState));
3151 * The user issued COMMIT when not inside a transaction. Issue a
3152 * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
3153 * CommitTransactionCommand() will then close the transaction and
3154 * put us back into the default state.
3156 case TBLOCK_STARTED:
3158 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3159 errmsg("there is no transaction in progress")));
3163 /* These cases are invalid. */
3164 case TBLOCK_DEFAULT:
3166 case TBLOCK_SUBBEGIN:
3169 case TBLOCK_ABORT_END:
3170 case TBLOCK_SUBABORT_END:
3171 case TBLOCK_ABORT_PENDING:
3172 case TBLOCK_SUBABORT_PENDING:
3173 case TBLOCK_SUBRESTART:
3174 case TBLOCK_SUBABORT_RESTART:
3175 case TBLOCK_PREPARE:
3176 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3177 BlockStateAsString(s->blockState));
3185 * UserAbortTransactionBlock
3186 * This executes a ROLLBACK command.
3188 * As above, we don't actually do anything here except change blockState.
3191 UserAbortTransactionBlock(void)
3193 TransactionState s = CurrentTransactionState;
3195 switch (s->blockState)
3198 * We are inside a transaction block and we got a ROLLBACK command
3199 * from the user, so tell CommitTransactionCommand to abort and
3200 * exit the transaction block.
3202 case TBLOCK_INPROGRESS:
3203 s->blockState = TBLOCK_ABORT_PENDING;
3207 * We are inside a failed transaction block and we got a ROLLBACK
3208 * command from the user. Abort processing is already done, so
3209 * CommitTransactionCommand just has to cleanup and go back to
3213 s->blockState = TBLOCK_ABORT_END;
3217 * We are inside a subtransaction. Mark everything up to top
3218 * level as exitable.
3220 case TBLOCK_SUBINPROGRESS:
3221 case TBLOCK_SUBABORT:
3222 while (s->parent != NULL)
3224 if (s->blockState == TBLOCK_SUBINPROGRESS)
3225 s->blockState = TBLOCK_SUBABORT_PENDING;
3226 else if (s->blockState == TBLOCK_SUBABORT)
3227 s->blockState = TBLOCK_SUBABORT_END;
3229 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3230 BlockStateAsString(s->blockState));
3233 if (s->blockState == TBLOCK_INPROGRESS)
3234 s->blockState = TBLOCK_ABORT_PENDING;
3235 else if (s->blockState == TBLOCK_ABORT)
3236 s->blockState = TBLOCK_ABORT_END;
3238 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3239 BlockStateAsString(s->blockState));
3243 * The user issued ABORT when not inside a transaction. Issue a
3244 * WARNING and go to abort state. The upcoming call to
3245 * CommitTransactionCommand() will then put us back into the
3248 case TBLOCK_STARTED:
3250 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3251 errmsg("there is no transaction in progress")));
3252 s->blockState = TBLOCK_ABORT_PENDING;
3255 /* These cases are invalid. */
3256 case TBLOCK_DEFAULT:
3258 case TBLOCK_SUBBEGIN:
3261 case TBLOCK_ABORT_END:
3262 case TBLOCK_SUBABORT_END:
3263 case TBLOCK_ABORT_PENDING:
3264 case TBLOCK_SUBABORT_PENDING:
3265 case TBLOCK_SUBRESTART:
3266 case TBLOCK_SUBABORT_RESTART:
3267 case TBLOCK_PREPARE:
3268 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3269 BlockStateAsString(s->blockState));
3276 * This executes a SAVEPOINT command.
3279 DefineSavepoint(char *name)
3281 TransactionState s = CurrentTransactionState;
3283 switch (s->blockState)
3285 case TBLOCK_INPROGRESS:
3286 case TBLOCK_SUBINPROGRESS:
3287 /* Normal subtransaction start */
3289 s = CurrentTransactionState; /* changed by push */
3292 * Savepoint names, like the TransactionState block itself, live
3293 * in TopTransactionContext.
3296 s->name = MemoryContextStrdup(TopTransactionContext, name);
3299 /* These cases are invalid. */
3300 case TBLOCK_DEFAULT:
3301 case TBLOCK_STARTED:
3303 case TBLOCK_SUBBEGIN:
3307 case TBLOCK_SUBABORT:
3308 case TBLOCK_ABORT_END:
3309 case TBLOCK_SUBABORT_END:
3310 case TBLOCK_ABORT_PENDING:
3311 case TBLOCK_SUBABORT_PENDING:
3312 case TBLOCK_SUBRESTART:
3313 case TBLOCK_SUBABORT_RESTART:
3314 case TBLOCK_PREPARE:
3315 elog(FATAL, "DefineSavepoint: unexpected state %s",
3316 BlockStateAsString(s->blockState));
3323 * This executes a RELEASE command.
3325 * As above, we don't actually do anything here except change blockState.
3328 ReleaseSavepoint(List *options)
3330 TransactionState s = CurrentTransactionState;
3331 TransactionState target,
3336 switch (s->blockState)
3339 * We can't rollback to a savepoint if there is no savepoint
3342 case TBLOCK_INPROGRESS:
3344 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3345 errmsg("no such savepoint")));
3349 * We are in a non-aborted subtransaction. This is the only valid
3352 case TBLOCK_SUBINPROGRESS:
3355 /* These cases are invalid. */
3356 case TBLOCK_DEFAULT:
3357 case TBLOCK_STARTED:
3359 case TBLOCK_SUBBEGIN:
3363 case TBLOCK_SUBABORT:
3364 case TBLOCK_ABORT_END:
3365 case TBLOCK_SUBABORT_END:
3366 case TBLOCK_ABORT_PENDING:
3367 case TBLOCK_SUBABORT_PENDING:
3368 case TBLOCK_SUBRESTART:
3369 case TBLOCK_SUBABORT_RESTART:
3370 case TBLOCK_PREPARE:
3371 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3372 BlockStateAsString(s->blockState));
3376 foreach(cell, options)
3378 DefElem *elem = lfirst(cell);
3380 if (strcmp(elem->defname, "savepoint_name") == 0)
3381 name = strVal(elem->arg);
3384 Assert(PointerIsValid(name));
3386 for (target = s; PointerIsValid(target); target = target->parent)
3388 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3392 if (!PointerIsValid(target))
3394 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3395 errmsg("no such savepoint")));
3397 /* disallow crossing savepoint level boundaries */
3398 if (target->savepointLevel != s->savepointLevel)
3400 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3401 errmsg("no such savepoint")));
3404 * Mark "commit pending" all subtransactions up to the target
3405 * subtransaction. The actual commits will happen when control gets to
3406 * CommitTransactionCommand.
3408 xact = CurrentTransactionState;
3411 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3412 xact->blockState = TBLOCK_SUBEND;
3415 xact = xact->parent;
3416 Assert(PointerIsValid(xact));
3421 * RollbackToSavepoint
3422 * This executes a ROLLBACK TO <savepoint> command.
3424 * As above, we don't actually do anything here except change blockState.
3427 RollbackToSavepoint(List *options)
3429 TransactionState s = CurrentTransactionState;
3430 TransactionState target,
3435 switch (s->blockState)
3438 * We can't rollback to a savepoint if there is no savepoint
3441 case TBLOCK_INPROGRESS:
3444 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3445 errmsg("no such savepoint")));
3449 * There is at least one savepoint, so proceed.
3451 case TBLOCK_SUBINPROGRESS:
3452 case TBLOCK_SUBABORT:
3455 /* These cases are invalid. */
3456 case TBLOCK_DEFAULT:
3457 case TBLOCK_STARTED:
3459 case TBLOCK_SUBBEGIN:
3462 case TBLOCK_ABORT_END:
3463 case TBLOCK_SUBABORT_END:
3464 case TBLOCK_ABORT_PENDING:
3465 case TBLOCK_SUBABORT_PENDING:
3466 case TBLOCK_SUBRESTART:
3467 case TBLOCK_SUBABORT_RESTART:
3468 case TBLOCK_PREPARE:
3469 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3470 BlockStateAsString(s->blockState));
3474 foreach(cell, options)
3476 DefElem *elem = lfirst(cell);
3478 if (strcmp(elem->defname, "savepoint_name") == 0)
3479 name = strVal(elem->arg);
3482 Assert(PointerIsValid(name));
3484 for (target = s; PointerIsValid(target); target = target->parent)
3486 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3490 if (!PointerIsValid(target))
3492 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3493 errmsg("no such savepoint")));
3495 /* disallow crossing savepoint level boundaries */
3496 if (target->savepointLevel != s->savepointLevel)
3498 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3499 errmsg("no such savepoint")));
3502 * Mark "abort pending" all subtransactions up to the target
3503 * subtransaction. The actual aborts will happen when control gets to
3504 * CommitTransactionCommand.
3506 xact = CurrentTransactionState;
3511 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3512 xact->blockState = TBLOCK_SUBABORT_PENDING;
3513 else if (xact->blockState == TBLOCK_SUBABORT)
3514 xact->blockState = TBLOCK_SUBABORT_END;
3516 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3517 BlockStateAsString(xact->blockState));
3518 xact = xact->parent;
3519 Assert(PointerIsValid(xact));
3522 /* And mark the target as "restart pending" */
3523 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3524 xact->blockState = TBLOCK_SUBRESTART;
3525 else if (xact->blockState == TBLOCK_SUBABORT)
3526 xact->blockState = TBLOCK_SUBABORT_RESTART;
3528 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3529 BlockStateAsString(xact->blockState));
3533 * BeginInternalSubTransaction
3534 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
3535 * TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
3536 * used in functions that might be called when not inside a BEGIN block
3537 * or when running deferred triggers at COMMIT/PREPARE time. Also, it
3538 * automatically does CommitTransactionCommand/StartTransactionCommand
3539 * instead of expecting the caller to do it.
3542 BeginInternalSubTransaction(char *name)
3544 TransactionState s = CurrentTransactionState;
3546 switch (s->blockState)
3548 case TBLOCK_STARTED:
3549 case TBLOCK_INPROGRESS:
3551 case TBLOCK_PREPARE:
3552 case TBLOCK_SUBINPROGRESS:
3553 /* Normal subtransaction start */
3555 s = CurrentTransactionState; /* changed by push */
3558 * Savepoint names, like the TransactionState block itself, live
3559 * in TopTransactionContext.
3562 s->name = MemoryContextStrdup(TopTransactionContext, name);
3565 /* These cases are invalid. */
3566 case TBLOCK_DEFAULT:
3568 case TBLOCK_SUBBEGIN:
3571 case TBLOCK_SUBABORT:
3572 case TBLOCK_ABORT_END:
3573 case TBLOCK_SUBABORT_END:
3574 case TBLOCK_ABORT_PENDING:
3575 case TBLOCK_SUBABORT_PENDING:
3576 case TBLOCK_SUBRESTART:
3577 case TBLOCK_SUBABORT_RESTART:
3578 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
3579 BlockStateAsString(s->blockState));
3583 CommitTransactionCommand();
3584 StartTransactionCommand();
3588 * ReleaseCurrentSubTransaction
3590 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
3591 * savepoint name (if any).
3592 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3595 ReleaseCurrentSubTransaction(void)
3597 TransactionState s = CurrentTransactionState;
3599 if (s->blockState != TBLOCK_SUBINPROGRESS)
3600 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
3601 BlockStateAsString(s->blockState));
3602 Assert(s->state == TRANS_INPROGRESS);
3603 MemoryContextSwitchTo(CurTransactionContext);
3604 CommitSubTransaction();
3605 s = CurrentTransactionState; /* changed by pop */
3606 Assert(s->state == TRANS_INPROGRESS);
3610 * RollbackAndReleaseCurrentSubTransaction
3612 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
3613 * of its savepoint name (if any).
3614 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3617 RollbackAndReleaseCurrentSubTransaction(void)
3619 TransactionState s = CurrentTransactionState;
3621 switch (s->blockState)
3623 /* Must be in a subtransaction */
3624 case TBLOCK_SUBINPROGRESS:
3625 case TBLOCK_SUBABORT:
3628 /* These cases are invalid. */
3629 case TBLOCK_DEFAULT:
3630 case TBLOCK_STARTED:
3632 case TBLOCK_SUBBEGIN:
3633 case TBLOCK_INPROGRESS:
3637 case TBLOCK_ABORT_END:
3638 case TBLOCK_SUBABORT_END:
3639 case TBLOCK_ABORT_PENDING:
3640 case TBLOCK_SUBABORT_PENDING:
3641 case TBLOCK_SUBRESTART:
3642 case TBLOCK_SUBABORT_RESTART:
3643 case TBLOCK_PREPARE:
3644 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
3645 BlockStateAsString(s->blockState));
3650 * Abort the current subtransaction, if needed.
3652 if (s->blockState == TBLOCK_SUBINPROGRESS)
3653 AbortSubTransaction();
3655 /* And clean it up, too */
3656 CleanupSubTransaction();
3658 s = CurrentTransactionState; /* changed by pop */
3659 AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
3660 s->blockState == TBLOCK_INPROGRESS ||
3661 s->blockState == TBLOCK_STARTED);
3665 * AbortOutOfAnyTransaction
3667 * This routine is provided for error recovery purposes. It aborts any
3668 * active transaction or transaction block, leaving the system in a known
3672 AbortOutOfAnyTransaction(void)
3674 TransactionState s = CurrentTransactionState;
3677 * Get out of any transaction or nested transaction
3681 switch (s->blockState)
3683 case TBLOCK_DEFAULT:
3684 /* Not in a transaction, do nothing */
3686 case TBLOCK_STARTED:
3688 case TBLOCK_INPROGRESS:
3690 case TBLOCK_ABORT_PENDING:
3691 case TBLOCK_PREPARE:
3692 /* In a transaction, so clean up */
3694 CleanupTransaction();
3695 s->blockState = TBLOCK_DEFAULT;
3698 case TBLOCK_ABORT_END:
3699 /* AbortTransaction already done, still need Cleanup */
3700 CleanupTransaction();
3701 s->blockState = TBLOCK_DEFAULT;
3705 * In a subtransaction, so clean it up and abort parent too
3707 case TBLOCK_SUBBEGIN:
3708 case TBLOCK_SUBINPROGRESS:
3710 case TBLOCK_SUBABORT_PENDING:
3711 case TBLOCK_SUBRESTART:
3712 AbortSubTransaction();
3713 CleanupSubTransaction();
3714 s = CurrentTransactionState; /* changed by pop */
3717 case TBLOCK_SUBABORT:
3718 case TBLOCK_SUBABORT_END:
3719 case TBLOCK_SUBABORT_RESTART:
3720 /* As above, but AbortSubTransaction already done */
3721 CleanupSubTransaction();
3722 s = CurrentTransactionState; /* changed by pop */
3725 } while (s->blockState != TBLOCK_DEFAULT);
3727 /* Should be out of all subxacts now */
3728 Assert(s->parent == NULL);
3732 * IsTransactionBlock --- are we within a transaction block?
3735 IsTransactionBlock(void)
3737 TransactionState s = CurrentTransactionState;
3739 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
3746 * IsTransactionOrTransactionBlock --- are we within either a transaction
3747 * or a transaction block? (The backend is only really "idle" when this
3750 * This should match up with IsTransactionBlock and IsTransactionState.
3753 IsTransactionOrTransactionBlock(void)
3755 TransactionState s = CurrentTransactionState;
3757 if (s->blockState == TBLOCK_DEFAULT)
3764 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
3767 TransactionBlockStatusCode(void)
3769 TransactionState s = CurrentTransactionState;
3771 switch (s->blockState)
3773 case TBLOCK_DEFAULT:
3774 case TBLOCK_STARTED:
3775 return 'I'; /* idle --- not in transaction */
3777 case TBLOCK_SUBBEGIN:
3778 case TBLOCK_INPROGRESS:
3779 case TBLOCK_SUBINPROGRESS:
3782 case TBLOCK_PREPARE:
3783 return 'T'; /* in transaction */
3785 case TBLOCK_SUBABORT:
3786 case TBLOCK_ABORT_END:
3787 case TBLOCK_SUBABORT_END:
3788 case TBLOCK_ABORT_PENDING:
3789 case TBLOCK_SUBABORT_PENDING:
3790 case TBLOCK_SUBRESTART:
3791 case TBLOCK_SUBABORT_RESTART:
3792 return 'E'; /* in failed transaction */
3795 /* should never get here */
3796 elog(FATAL, "invalid transaction block state: %s",
3797 BlockStateAsString(s->blockState));
3798 return 0; /* keep compiler quiet */
3805 IsSubTransaction(void)
3807 TransactionState s = CurrentTransactionState;
3809 if (s->nestingLevel >= 2)
3816 * StartSubTransaction
3818 * If you're wondering why this is separate from PushTransaction: it's because
3819 * we can't conveniently do this stuff right inside DefineSavepoint. The
3820 * SAVEPOINT utility command will be executed inside a Portal, and if we
3821 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
3822 * the Portal will undo those settings. So we make DefineSavepoint just
3823 * push a dummy transaction block, and when control returns to the main
3824 * idle loop, CommitTransactionCommand will be called, and we'll come here
3825 * to finish starting the subtransaction.
3828 StartSubTransaction(void)
3830 TransactionState s = CurrentTransactionState;
3832 if (s->state != TRANS_DEFAULT)
3833 elog(WARNING, "StartSubTransaction while in %s state",
3834 TransStateAsString(s->state));
3836 s->state = TRANS_START;
3839 * Initialize subsystems for new subtransaction
3841 * must initialize resource-management stuff first
3843 AtSubStart_Memory();
3844 AtSubStart_ResourceOwner();
3846 AtSubStart_Notify();
3847 AfterTriggerBeginSubXact();
3849 s->state = TRANS_INPROGRESS;
3852 * Call start-of-subxact callbacks
3854 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
3855 s->parent->subTransactionId);
3857 ShowTransactionState("StartSubTransaction");
3861 * CommitSubTransaction
3863 * The caller has to make sure to always reassign CurrentTransactionState
3864 * if it has a local pointer to it after calling this function.
3867 CommitSubTransaction(void)
3869 TransactionState s = CurrentTransactionState;
3871 ShowTransactionState("CommitSubTransaction");
3873 if (s->state != TRANS_INPROGRESS)
3874 elog(WARNING, "CommitSubTransaction while in %s state",
3875 TransStateAsString(s->state));
3877 /* Pre-commit processing goes here -- nothing to do at the moment */
3879 s->state = TRANS_COMMIT;
3881 /* Must CCI to ensure commands of subtransaction are seen as done */
3882 CommandCounterIncrement();
3885 * Prior to 8.4 we marked subcommit in clog at this point. We now only
3886 * perform that step, if required, as part of the atomic update of the
3887 * whole transaction tree at top level commit or abort.
3890 /* Post-commit cleanup */
3891 if (TransactionIdIsValid(s->transactionId))
3892 AtSubCommit_childXids();
3893 AfterTriggerEndSubXact(true);
3894 AtSubCommit_Portals(s->subTransactionId,
3895 s->parent->subTransactionId,
3896 s->parent->curTransactionOwner);
3897 AtEOSubXact_LargeObject(true, s->subTransactionId,
3898 s->parent->subTransactionId);
3899 AtSubCommit_Notify();
3901 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
3902 s->parent->subTransactionId);
3904 ResourceOwnerRelease(s->curTransactionOwner,
3905 RESOURCE_RELEASE_BEFORE_LOCKS,
3907 AtEOSubXact_RelationCache(true, s->subTransactionId,
3908 s->parent->subTransactionId);
3909 AtEOSubXact_Inval(true);
3913 * The only lock we actually release here is the subtransaction XID lock.
3914 * The rest just get transferred to the parent resource owner.
3916 CurrentResourceOwner = s->curTransactionOwner;
3917 if (TransactionIdIsValid(s->transactionId))
3918 XactLockTableDelete(s->transactionId);
3920 ResourceOwnerRelease(s->curTransactionOwner,
3921 RESOURCE_RELEASE_LOCKS,
3923 ResourceOwnerRelease(s->curTransactionOwner,
3924 RESOURCE_RELEASE_AFTER_LOCKS,
3927 AtEOXact_GUC(true, s->gucNestLevel);
3928 AtEOSubXact_SPI(true, s->subTransactionId);
3929 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
3930 s->parent->subTransactionId);
3931 AtEOSubXact_Namespace(true, s->subTransactionId,
3932 s->parent->subTransactionId);
3933 AtEOSubXact_Files(true, s->subTransactionId,
3934 s->parent->subTransactionId);
3935 AtEOSubXact_HashTables(true, s->nestingLevel);
3936 AtEOSubXact_PgStat(true, s->nestingLevel);
3937 AtSubCommit_Snapshot(s->nestingLevel);
3940 * We need to restore the upper transaction's read-only state, in case the
3941 * upper is read-write while the child is read-only; GUC will incorrectly
3942 * think it should leave the child state in place.
3944 XactReadOnly = s->prevXactReadOnly;
3946 CurrentResourceOwner = s->parent->curTransactionOwner;
3947 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3948 ResourceOwnerDelete(s->curTransactionOwner);
3949 s->curTransactionOwner = NULL;
3951 AtSubCommit_Memory();
3953 s->state = TRANS_DEFAULT;
3959 * AbortSubTransaction
3962 AbortSubTransaction(void)
3964 TransactionState s = CurrentTransactionState;
3966 /* Prevent cancel/die interrupt while cleaning up */
3969 /* Make sure we have a valid memory context and resource owner */
3970 AtSubAbort_Memory();
3971 AtSubAbort_ResourceOwner();
3974 * Release any LW locks we might be holding as quickly as possible.
3975 * (Regular locks, however, must be held till we finish aborting.)
3976 * Releasing LW locks is critical since we might try to grab them again
3977 * while cleaning up!
3979 * FIXME This may be incorrect --- Are there some locks we should keep?
3980 * Buffer locks, for example? I don't think so but I'm not sure.
3990 * check the current transaction state
3992 ShowTransactionState("AbortSubTransaction");
3994 if (s->state != TRANS_INPROGRESS)
3995 elog(WARNING, "AbortSubTransaction while in %s state",
3996 TransStateAsString(s->state));
3998 s->state = TRANS_ABORT;
4001 * Reset user ID which might have been changed transiently. (See notes in
4002 * AbortTransaction.)
4004 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
4007 * We can skip all this stuff if the subxact failed before creating a
4010 if (s->curTransactionOwner)
4012 AfterTriggerEndSubXact(false);
4013 AtSubAbort_Portals(s->subTransactionId,
4014 s->parent->subTransactionId,
4015 s->parent->curTransactionOwner);
4016 AtEOSubXact_LargeObject(false, s->subTransactionId,
4017 s->parent->subTransactionId);
4018 AtSubAbort_Notify();
4020 /* Advertise the fact that we aborted in pg_clog. */
4021 (void) RecordTransactionAbort(true);
4023 /* Post-abort cleanup */
4024 if (TransactionIdIsValid(s->transactionId))
4025 AtSubAbort_childXids();
4027 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
4028 s->parent->subTransactionId);
4030 ResourceOwnerRelease(s->curTransactionOwner,
4031 RESOURCE_RELEASE_BEFORE_LOCKS,
4033 AtEOSubXact_RelationCache(false, s->subTransactionId,
4034 s->parent->subTransactionId);
4035 AtEOSubXact_Inval(false);
4037 ResourceOwnerRelease(s->curTransactionOwner,
4038 RESOURCE_RELEASE_LOCKS,
4040 ResourceOwnerRelease(s->curTransactionOwner,
4041 RESOURCE_RELEASE_AFTER_LOCKS,
4044 AtEOXact_GUC(false, s->gucNestLevel);
4045 AtEOSubXact_SPI(false, s->subTransactionId);
4046 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
4047 s->parent->subTransactionId);
4048 AtEOSubXact_Namespace(false, s->subTransactionId,
4049 s->parent->subTransactionId);
4050 AtEOSubXact_Files(false, s->subTransactionId,
4051 s->parent->subTransactionId);
4052 AtEOSubXact_HashTables(false, s->nestingLevel);
4053 AtEOSubXact_PgStat(false, s->nestingLevel);
4054 AtSubAbort_Snapshot(s->nestingLevel);
4058 * Restore the upper transaction's read-only state, too. This should be
4059 * redundant with GUC's cleanup but we may as well do it for consistency
4060 * with the commit case.
4062 XactReadOnly = s->prevXactReadOnly;
4064 RESUME_INTERRUPTS();
4068 * CleanupSubTransaction
4070 * The caller has to make sure to always reassign CurrentTransactionState
4071 * if it has a local pointer to it after calling this function.
4074 CleanupSubTransaction(void)
4076 TransactionState s = CurrentTransactionState;
4078 ShowTransactionState("CleanupSubTransaction");
4080 if (s->state != TRANS_ABORT)
4081 elog(WARNING, "CleanupSubTransaction while in %s state",
4082 TransStateAsString(s->state));
4084 AtSubCleanup_Portals(s->subTransactionId);
4086 CurrentResourceOwner = s->parent->curTransactionOwner;
4087 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4088 if (s->curTransactionOwner)
4089 ResourceOwnerDelete(s->curTransactionOwner);
4090 s->curTransactionOwner = NULL;
4092 AtSubCleanup_Memory();
4094 s->state = TRANS_DEFAULT;
4101 * Create transaction state stack entry for a subtransaction
4103 * The caller has to make sure to always reassign CurrentTransactionState
4104 * if it has a local pointer to it after calling this function.
4107 PushTransaction(void)
4109 TransactionState p = CurrentTransactionState;
4113 * We keep subtransaction state nodes in TopTransactionContext.
4115 s = (TransactionState)
4116 MemoryContextAllocZero(TopTransactionContext,
4117 sizeof(TransactionStateData));
4120 * Assign a subtransaction ID, watching out for counter wraparound.
4122 currentSubTransactionId += 1;
4123 if (currentSubTransactionId == InvalidSubTransactionId)
4125 currentSubTransactionId -= 1;
4128 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
4129 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
4133 * We can now stack a minimally valid subtransaction without fear of
4136 s->transactionId = InvalidTransactionId; /* until assigned */
4137 s->subTransactionId = currentSubTransactionId;
4139 s->nestingLevel = p->nestingLevel + 1;
4140 s->gucNestLevel = NewGUCNestLevel();
4141 s->savepointLevel = p->savepointLevel;
4142 s->state = TRANS_DEFAULT;
4143 s->blockState = TBLOCK_SUBBEGIN;
4144 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
4145 s->prevXactReadOnly = XactReadOnly;
4147 CurrentTransactionState = s;
4150 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
4151 * with the subtransaction from here on out; in particular they should not
4152 * assume that it necessarily has a transaction context, resource owner,
4159 * Pop back to parent transaction state
4161 * The caller has to make sure to always reassign CurrentTransactionState
4162 * if it has a local pointer to it after calling this function.
4165 PopTransaction(void)
4167 TransactionState s = CurrentTransactionState;
4169 if (s->state != TRANS_DEFAULT)
4170 elog(WARNING, "PopTransaction while in %s state",
4171 TransStateAsString(s->state));
4173 if (s->parent == NULL)
4174 elog(FATAL, "PopTransaction with no parent");
4176 CurrentTransactionState = s->parent;
4178 /* Let's just make sure CurTransactionContext is good */
4179 CurTransactionContext = s->parent->curTransactionContext;
4180 MemoryContextSwitchTo(CurTransactionContext);
4182 /* Ditto for ResourceOwner links */
4183 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4184 CurrentResourceOwner = s->parent->curTransactionOwner;
4186 /* Free the old child structure */
4193 * ShowTransactionState
4197 ShowTransactionState(const char *str)
4199 /* skip work if message will definitely not be printed */
4200 if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
4202 elog(DEBUG3, "%s", str);
4203 ShowTransactionStateRec(CurrentTransactionState);
4208 * ShowTransactionStateRec
4209 * Recursive subroutine for ShowTransactionState
4212 ShowTransactionStateRec(TransactionState s)
4216 initStringInfo(&buf);
4218 if (s->nChildXids > 0)
4222 appendStringInfo(&buf, "%u", s->childXids[0]);
4223 for (i = 1; i < s->nChildXids; i++)
4224 appendStringInfo(&buf, " %u", s->childXids[i]);
4228 ShowTransactionStateRec(s->parent);
4230 /* use ereport to suppress computation if msg will not be printed */
4232 (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u%s, nestlvl: %d, children: %s",
4233 PointerIsValid(s->name) ? s->name : "unnamed",
4234 BlockStateAsString(s->blockState),
4235 TransStateAsString(s->state),
4236 (unsigned int) s->transactionId,
4237 (unsigned int) s->subTransactionId,
4238 (unsigned int) currentCommandId,
4239 currentCommandIdUsed ? " (used)" : "",
4240 s->nestingLevel, buf.data)));
4246 * BlockStateAsString
4250 BlockStateAsString(TBlockState blockState)
4254 case TBLOCK_DEFAULT:
4256 case TBLOCK_STARTED:
4260 case TBLOCK_INPROGRESS:
4261 return "INPROGRESS";
4266 case TBLOCK_ABORT_END:
4268 case TBLOCK_ABORT_PENDING:
4269 return "ABORT PEND";
4270 case TBLOCK_PREPARE:
4272 case TBLOCK_SUBBEGIN:
4274 case TBLOCK_SUBINPROGRESS:
4275 return "SUB INPROGRS";
4278 case TBLOCK_SUBABORT:
4280 case TBLOCK_SUBABORT_END:
4281 return "SUB ABORT END";
4282 case TBLOCK_SUBABORT_PENDING:
4283 return "SUB ABRT PEND";
4284 case TBLOCK_SUBRESTART:
4285 return "SUB RESTART";
4286 case TBLOCK_SUBABORT_RESTART:
4287 return "SUB AB RESTRT";
4289 return "UNRECOGNIZED";
4293 * TransStateAsString
4297 TransStateAsString(TransState state)
4305 case TRANS_INPROGRESS:
4314 return "UNRECOGNIZED";
4318 * xactGetCommittedChildren
4320 * Gets the list of committed children of the current transaction. The return
4321 * value is the number of child transactions. *ptr is set to point to an
4322 * array of TransactionIds. The array is allocated in TopTransactionContext;
4323 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
4324 * If there are no subxacts, *ptr is set to NULL.
4327 xactGetCommittedChildren(TransactionId **ptr)
4329 TransactionState s = CurrentTransactionState;
4331 if (s->nChildXids == 0)
4334 *ptr = s->childXids;
4336 return s->nChildXids;
4340 * XLOG support routines
4344 * Before 9.0 this was a fairly short function, but now it performs many
4345 * actions for which the order of execution is critical.
4348 xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid, XLogRecPtr lsn)
4350 TransactionId *sub_xids;
4351 SharedInvalidationMessage *inval_msgs;
4352 TransactionId max_xid;
4355 /* subxid array follows relfilenodes */
4356 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4357 /* invalidation messages array follows subxids */
4358 inval_msgs = (SharedInvalidationMessage *) &(sub_xids[xlrec->nsubxacts]);
4360 max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
4363 * Make sure nextXid is beyond any XID mentioned in the record.
4365 * We don't expect anyone else to modify nextXid, hence we
4366 * don't need to hold a lock while checking this. We still acquire
4367 * the lock to modify it, though.
4369 if (TransactionIdFollowsOrEquals(max_xid,
4370 ShmemVariableCache->nextXid))
4372 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4373 ShmemVariableCache->nextXid = max_xid;
4374 TransactionIdAdvance(ShmemVariableCache->nextXid);
4375 LWLockRelease(XidGenLock);
4381 * Mark the transaction committed in pg_clog.
4383 TransactionIdCommitTree(xid, xlrec->nsubxacts, sub_xids);
4388 * If a transaction completion record arrives that has as-yet
4389 * unobserved subtransactions then this will not have been fully
4390 * handled by the call to RecordKnownAssignedTransactionIds() in the
4391 * main recovery loop in xlog.c. So we need to do bookkeeping again to
4392 * cover that case. This is confusing and it is easy to think this
4393 * call is irrelevant, which has happened three times in development
4394 * already. Leave it in.
4396 RecordKnownAssignedTransactionIds(max_xid);
4399 * Mark the transaction committed in pg_clog. We use async commit
4400 * protocol during recovery to provide information on database
4401 * consistency for when users try to set hint bits. It is important
4402 * that we do not set hint bits until the minRecoveryPoint is past
4403 * this commit record. This ensures that if we crash we don't see
4404 * hint bits set on changes made by transactions that haven't yet
4405 * recovered. It's unlikely but it's good to be safe.
4407 TransactionIdAsyncCommitTree(xid, xlrec->nsubxacts, sub_xids, lsn);
4410 * We must mark clog before we update the ProcArray.
4412 ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids);
4415 * Send any cache invalidations attached to the commit. We must
4416 * maintain the same order of invalidation then release locks
4419 ProcessCommittedInvalidationMessages(inval_msgs, xlrec->nmsgs,
4420 XactCompletionRelcacheInitFileInval(xlrec),
4421 xlrec->dbId, xlrec->tsId);
4424 * Release locks, if any. We do this for both two phase and normal
4425 * one phase transactions. In effect we are ignoring the prepare
4426 * phase and just going straight to lock release.
4428 StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
4431 /* Make sure files supposed to be dropped are dropped */
4432 for (i = 0; i < xlrec->nrels; i++)
4434 SMgrRelation srel = smgropen(xlrec->xnodes[i]);
4437 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4439 if (smgrexists(srel, fork))
4441 XLogDropRelation(xlrec->xnodes[i], fork);
4442 smgrdounlink(srel, fork, false, true);
4449 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit() in
4450 * normal operation. For example, in DROP DATABASE, we delete all the files
4451 * belonging to the database, and then commit the transaction. If we crash
4452 * after all the files have been deleted but before the commit, you have an
4453 * entry in pg_database without any files. To minimize the window for that,
4454 * we use ForceSyncCommit() to rush the commit record to disk as quick as
4455 * possible. We have the same window during recovery, and forcing an
4456 * XLogFlush() (which updates minRecoveryPoint during recovery) helps
4457 * to reduce that problem window, for any user that requested ForceSyncCommit().
4459 if (XactCompletionForceSyncCommit(xlrec))
4464 * Be careful with the order of execution, as with xact_redo_commit().
4465 * The two functions are similar but differ in key places.
4467 * Note also that an abort can be for a subtransaction and its children,
4468 * not just for a top level abort. That means we have to consider
4469 * topxid != xid, whereas in commit we would find topxid == xid always
4470 * because subtransaction commit is never WAL logged.
4473 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
4475 TransactionId *sub_xids;
4476 TransactionId max_xid;
4479 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4480 max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
4482 /* Make sure nextXid is beyond any XID mentioned in the record */
4483 /* We don't expect anyone else to modify nextXid, hence we
4484 * don't need to hold a lock while checking this. We still acquire
4485 * the lock to modify it, though.
4487 if (TransactionIdFollowsOrEquals(max_xid,
4488 ShmemVariableCache->nextXid))
4490 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4491 ShmemVariableCache->nextXid = max_xid;
4492 TransactionIdAdvance(ShmemVariableCache->nextXid);
4493 LWLockRelease(XidGenLock);
4499 * If a transaction completion record arrives that has as-yet unobserved
4500 * subtransactions then this will not have been fully handled by the call
4501 * to RecordKnownAssignedTransactionIds() in the main recovery loop in
4502 * xlog.c. So we need to do bookkeeping again to cover that case. This is
4503 * confusing and it is easy to think this call is irrelevant, which has
4504 * happened three times in development already. Leave it in.
4506 RecordKnownAssignedTransactionIds(max_xid);
4509 /* Mark the transaction aborted in pg_clog, no need for async stuff */
4510 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4515 * We must mark clog before we update the ProcArray.
4517 ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids);
4520 * There are no flat files that need updating, nor invalidation
4521 * messages to send or undo.
4525 * Release locks, if any. There are no invalidations to send.
4527 StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
4530 /* Make sure files supposed to be dropped are dropped */
4531 for (i = 0; i < xlrec->nrels; i++)
4533 SMgrRelation srel = smgropen(xlrec->xnodes[i]);
4536 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4538 if (smgrexists(srel, fork))
4540 XLogDropRelation(xlrec->xnodes[i], fork);
4541 smgrdounlink(srel, fork, false, true);
4549 xact_redo(XLogRecPtr lsn, XLogRecord *record)
4551 uint8 info = record->xl_info & ~XLR_INFO_MASK;
4553 /* Backup blocks are not used in xact records */
4554 Assert(!(record->xl_info & XLR_BKP_BLOCK_MASK));
4556 if (info == XLOG_XACT_COMMIT)
4558 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
4560 xact_redo_commit(xlrec, record->xl_xid, lsn);
4562 else if (info == XLOG_XACT_ABORT)
4564 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
4566 xact_redo_abort(xlrec, record->xl_xid);
4568 else if (info == XLOG_XACT_PREPARE)
4570 /* the record contents are exactly the 2PC file */
4571 RecreateTwoPhaseFile(record->xl_xid,
4572 XLogRecGetData(record), record->xl_len);
4574 else if (info == XLOG_XACT_COMMIT_PREPARED)
4576 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
4578 xact_redo_commit(&xlrec->crec, xlrec->xid, lsn);
4579 RemoveTwoPhaseFile(xlrec->xid, false);
4581 else if (info == XLOG_XACT_ABORT_PREPARED)
4583 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
4585 xact_redo_abort(&xlrec->arec, xlrec->xid);
4586 RemoveTwoPhaseFile(xlrec->xid, false);
4588 else if (info == XLOG_XACT_ASSIGNMENT)
4590 xl_xact_assignment *xlrec = (xl_xact_assignment *) XLogRecGetData(record);
4593 ProcArrayApplyXidAssignment(xlrec->xtop,
4594 xlrec->nsubxacts, xlrec->xsub);
4597 elog(PANIC, "xact_redo: unknown op code %u", info);
4601 xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
4604 TransactionId *xacts;
4606 xacts = (TransactionId *) &xlrec->xnodes[xlrec->nrels];
4608 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4610 if (xlrec->nrels > 0)
4612 appendStringInfo(buf, "; rels:");
4613 for (i = 0; i < xlrec->nrels; i++)
4615 char *path = relpath(xlrec->xnodes[i], MAIN_FORKNUM);
4617 appendStringInfo(buf, " %s", path);
4621 if (xlrec->nsubxacts > 0)
4623 appendStringInfo(buf, "; subxacts:");
4624 for (i = 0; i < xlrec->nsubxacts; i++)
4625 appendStringInfo(buf, " %u", xacts[i]);
4627 if (xlrec->nmsgs > 0)
4629 SharedInvalidationMessage *msgs;
4631 msgs = (SharedInvalidationMessage *) &xacts[xlrec->nsubxacts];
4633 if (XactCompletionRelcacheInitFileInval(xlrec))
4634 appendStringInfo(buf, "; relcache init file inval dbid %u tsid %u",
4635 xlrec->dbId, xlrec->tsId);
4637 appendStringInfo(buf, "; inval msgs:");
4638 for (i = 0; i < xlrec->nmsgs; i++)
4640 SharedInvalidationMessage *msg = &msgs[i];
4643 appendStringInfo(buf, " catcache %d", msg->id);
4644 else if (msg->id == SHAREDINVALCATALOG_ID)
4645 appendStringInfo(buf, " catalog %u", msg->cat.catId);
4646 else if (msg->id == SHAREDINVALRELCACHE_ID)
4647 appendStringInfo(buf, " relcache %u", msg->rc.relId);
4648 /* remaining cases not expected, but print something anyway */
4649 else if (msg->id == SHAREDINVALSMGR_ID)
4650 appendStringInfo(buf, " smgr");
4651 else if (msg->id == SHAREDINVALRELMAP_ID)
4652 appendStringInfo(buf, " relmap");
4654 appendStringInfo(buf, " unknown id %d", msg->id);
4660 xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
4664 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4665 if (xlrec->nrels > 0)
4667 appendStringInfo(buf, "; rels:");
4668 for (i = 0; i < xlrec->nrels; i++)
4670 char *path = relpath(xlrec->xnodes[i], MAIN_FORKNUM);
4672 appendStringInfo(buf, " %s", path);
4676 if (xlrec->nsubxacts > 0)
4678 TransactionId *xacts = (TransactionId *)
4679 &xlrec->xnodes[xlrec->nrels];
4681 appendStringInfo(buf, "; subxacts:");
4682 for (i = 0; i < xlrec->nsubxacts; i++)
4683 appendStringInfo(buf, " %u", xacts[i]);
4688 xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
4692 appendStringInfo(buf, "subxacts:");
4694 for (i = 0; i < xlrec->nsubxacts; i++)
4695 appendStringInfo(buf, " %u", xlrec->xsub[i]);
4699 xact_desc(StringInfo buf, uint8 xl_info, char *rec)
4701 uint8 info = xl_info & ~XLR_INFO_MASK;
4703 if (info == XLOG_XACT_COMMIT)
4705 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
4707 appendStringInfo(buf, "commit: ");
4708 xact_desc_commit(buf, xlrec);
4710 else if (info == XLOG_XACT_ABORT)
4712 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
4714 appendStringInfo(buf, "abort: ");
4715 xact_desc_abort(buf, xlrec);
4717 else if (info == XLOG_XACT_PREPARE)
4719 appendStringInfo(buf, "prepare");
4721 else if (info == XLOG_XACT_COMMIT_PREPARED)
4723 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
4725 appendStringInfo(buf, "commit prepared %u: ", xlrec->xid);
4726 xact_desc_commit(buf, &xlrec->crec);
4728 else if (info == XLOG_XACT_ABORT_PREPARED)
4730 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
4732 appendStringInfo(buf, "abort prepared %u: ", xlrec->xid);
4733 xact_desc_abort(buf, &xlrec->arec);
4735 else if (info == XLOG_XACT_ASSIGNMENT)
4737 xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
4740 * Note that we ignore the WAL record's xid, since we're more
4741 * interested in the top-level xid that issued the record
4742 * and which xids are being reported here.
4744 appendStringInfo(buf, "xid assignment xtop %u: ", xlrec->xtop);
4745 xact_desc_assignment(buf, xlrec);
4748 appendStringInfo(buf, "UNKNOWN");