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.281 2010/01/16 10:05:50 sriggs Exp $
15 *-------------------------------------------------------------------------
23 #include "access/multixact.h"
24 #include "access/subtrans.h"
25 #include "access/transam.h"
26 #include "access/twophase.h"
27 #include "access/xact.h"
28 #include "access/xlogutils.h"
29 #include "catalog/catalog.h"
30 #include "catalog/namespace.h"
31 #include "catalog/storage.h"
32 #include "commands/async.h"
33 #include "commands/tablecmds.h"
34 #include "commands/trigger.h"
35 #include "executor/spi.h"
36 #include "libpq/be-fsstubs.h"
37 #include "miscadmin.h"
39 #include "storage/bufmgr.h"
40 #include "storage/fd.h"
41 #include "storage/lmgr.h"
42 #include "storage/procarray.h"
43 #include "storage/sinvaladt.h"
44 #include "storage/smgr.h"
45 #include "storage/standby.h"
46 #include "utils/combocid.h"
47 #include "utils/guc.h"
48 #include "utils/inval.h"
49 #include "utils/memutils.h"
50 #include "utils/relcache.h"
51 #include "utils/snapmgr.h"
56 * User-tweakable parameters
58 int DefaultXactIsoLevel = XACT_READ_COMMITTED;
61 bool DefaultXactReadOnly = false;
64 bool XactSyncCommit = true;
66 int CommitDelay = 0; /* precommit delay in microseconds */
67 int CommitSiblings = 5; /* # concurrent xacts needed to sleep */
70 * MyXactAccessedTempRel is set when a temporary relation is accessed.
71 * We don't allow PREPARE TRANSACTION in that case. (This is global
72 * so that it can be set from heapam.c.)
74 bool MyXactAccessedTempRel = false;
78 * transaction states - transaction state from server perspective
80 typedef enum TransState
82 TRANS_DEFAULT, /* idle */
83 TRANS_START, /* transaction starting */
84 TRANS_INPROGRESS, /* inside a valid transaction */
85 TRANS_COMMIT, /* commit in progress */
86 TRANS_ABORT, /* abort in progress */
87 TRANS_PREPARE /* prepare in progress */
91 * transaction block states - transaction state of client queries
93 * Note: the subtransaction states are used only for non-topmost
94 * transactions; the others appear only in the topmost transaction.
96 typedef enum TBlockState
98 /* not-in-transaction-block states */
99 TBLOCK_DEFAULT, /* idle */
100 TBLOCK_STARTED, /* running single-query transaction */
102 /* transaction block states */
103 TBLOCK_BEGIN, /* starting transaction block */
104 TBLOCK_INPROGRESS, /* live transaction */
105 TBLOCK_END, /* COMMIT received */
106 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
107 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
108 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
109 TBLOCK_PREPARE, /* live xact, PREPARE received */
111 /* subtransaction states */
112 TBLOCK_SUBBEGIN, /* starting a subtransaction */
113 TBLOCK_SUBINPROGRESS, /* live subtransaction */
114 TBLOCK_SUBEND, /* RELEASE received */
115 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
116 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
117 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
118 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
119 TBLOCK_SUBABORT_RESTART /* failed subxact, ROLLBACK TO received */
123 * transaction state structure
125 typedef struct TransactionStateData
127 TransactionId transactionId; /* my XID, or Invalid if none */
128 SubTransactionId subTransactionId; /* my subxact ID */
129 char *name; /* savepoint name, if any */
130 int savepointLevel; /* savepoint level */
131 TransState state; /* low-level state */
132 TBlockState blockState; /* high-level state */
133 int nestingLevel; /* transaction nesting depth */
134 int gucNestLevel; /* GUC context nesting depth */
135 MemoryContext curTransactionContext; /* my xact-lifetime context */
136 ResourceOwner curTransactionOwner; /* my query resources */
137 TransactionId *childXids; /* subcommitted child XIDs, in XID order */
138 int nChildXids; /* # of subcommitted child XIDs */
139 int maxChildXids; /* allocated size of childXids[] */
140 Oid prevUser; /* previous CurrentUserId setting */
141 int prevSecContext; /* previous SecurityRestrictionContext */
142 bool prevXactReadOnly; /* entry-time xact r/o state */
143 bool startedInRecovery; /* did we start in recovery? */
144 struct TransactionStateData *parent; /* back link to parent */
145 } TransactionStateData;
147 typedef TransactionStateData *TransactionState;
150 * CurrentTransactionState always points to the current transaction state
151 * block. It will point to TopTransactionStateData when not in a
152 * transaction at all, or when in a top-level transaction.
154 static TransactionStateData TopTransactionStateData = {
155 0, /* transaction id */
156 0, /* subtransaction id */
157 NULL, /* savepoint name */
158 0, /* savepoint level */
159 TRANS_DEFAULT, /* transaction state */
160 TBLOCK_DEFAULT, /* transaction block state from the client
162 0, /* transaction nesting depth */
163 0, /* GUC context nesting depth */
164 NULL, /* cur transaction context */
165 NULL, /* cur transaction resource owner */
166 NULL, /* subcommitted child Xids */
167 0, /* # of subcommitted child Xids */
168 0, /* allocated size of childXids[] */
169 InvalidOid, /* previous CurrentUserId setting */
170 0, /* previous SecurityRestrictionContext */
171 false, /* entry-time xact r/o state */
172 false, /* startedInRecovery */
173 NULL /* link to parent state block */
177 * unreportedXids holds XIDs of all subtransactions that have not yet been
178 * reported in a XLOG_XACT_ASSIGNMENT record.
180 static int nUnreportedXids;
181 static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS];
183 static TransactionState CurrentTransactionState = &TopTransactionStateData;
186 * The subtransaction ID and command ID assignment counters are global
187 * to a whole transaction, so we do not keep them in the state stack.
189 static SubTransactionId currentSubTransactionId;
190 static CommandId currentCommandId;
191 static bool currentCommandIdUsed;
194 * xactStartTimestamp is the value of transaction_timestamp().
195 * stmtStartTimestamp is the value of statement_timestamp().
196 * xactStopTimestamp is the time at which we log a commit or abort WAL record.
197 * These do not change as we enter and exit subtransactions, so we don't
198 * keep them inside the TransactionState stack.
200 static TimestampTz xactStartTimestamp;
201 static TimestampTz stmtStartTimestamp;
202 static TimestampTz xactStopTimestamp;
205 * GID to be used for preparing the current transaction. This is also
206 * global to a whole transaction, so we don't keep it in the state stack.
208 static char *prepareGID;
211 * Some commands want to force synchronous commit.
213 static bool forceSyncCommit = false;
216 * Private context for transaction-abort work --- we reserve space for this
217 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
218 * when we've run out of memory.
220 static MemoryContext TransactionAbortContext = NULL;
223 * List of add-on start- and end-of-xact callbacks
225 typedef struct XactCallbackItem
227 struct XactCallbackItem *next;
228 XactCallback callback;
232 static XactCallbackItem *Xact_callbacks = NULL;
235 * List of add-on start- and end-of-subxact callbacks
237 typedef struct SubXactCallbackItem
239 struct SubXactCallbackItem *next;
240 SubXactCallback callback;
242 } SubXactCallbackItem;
244 static SubXactCallbackItem *SubXact_callbacks = NULL;
247 /* local function prototypes */
248 static void AssignTransactionId(TransactionState s);
249 static void AbortTransaction(void);
250 static void AtAbort_Memory(void);
251 static void AtCleanup_Memory(void);
252 static void AtAbort_ResourceOwner(void);
253 static void AtCommit_LocalCache(void);
254 static void AtCommit_Memory(void);
255 static void AtStart_Cache(void);
256 static void AtStart_Memory(void);
257 static void AtStart_ResourceOwner(void);
258 static void CallXactCallbacks(XactEvent event);
259 static void CallSubXactCallbacks(SubXactEvent event,
260 SubTransactionId mySubid,
261 SubTransactionId parentSubid);
262 static void CleanupTransaction(void);
263 static void CommitTransaction(void);
264 static TransactionId RecordTransactionAbort(bool isSubXact);
265 static void StartTransaction(void);
267 static void StartSubTransaction(void);
268 static void CommitSubTransaction(void);
269 static void AbortSubTransaction(void);
270 static void CleanupSubTransaction(void);
271 static void PushTransaction(void);
272 static void PopTransaction(void);
274 static void AtSubAbort_Memory(void);
275 static void AtSubCleanup_Memory(void);
276 static void AtSubAbort_ResourceOwner(void);
277 static void AtSubCommit_Memory(void);
278 static void AtSubStart_Memory(void);
279 static void AtSubStart_ResourceOwner(void);
281 static void ShowTransactionState(const char *str);
282 static void ShowTransactionStateRec(TransactionState state);
283 static const char *BlockStateAsString(TBlockState blockState);
284 static const char *TransStateAsString(TransState state);
287 /* ----------------------------------------------------------------
288 * transaction state accessors
289 * ----------------------------------------------------------------
295 * This returns true if we are inside a valid transaction; that is,
296 * it is safe to initiate database access, take heavyweight locks, etc.
299 IsTransactionState(void)
301 TransactionState s = CurrentTransactionState;
304 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
305 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
306 * TRANS_PREPARE since it might be too soon or too late within those
307 * transition states to do anything interesting. Hence, the only "valid"
308 * state is TRANS_INPROGRESS.
310 return (s->state == TRANS_INPROGRESS);
314 * IsAbortedTransactionBlockState
316 * This returns true if we are within an aborted transaction block.
319 IsAbortedTransactionBlockState(void)
321 TransactionState s = CurrentTransactionState;
323 if (s->blockState == TBLOCK_ABORT ||
324 s->blockState == TBLOCK_SUBABORT)
332 * GetTopTransactionId
334 * This will return the XID of the main transaction, assigning one if
335 * it's not yet set. Be careful to call this only inside a valid xact.
338 GetTopTransactionId(void)
340 if (!TransactionIdIsValid(TopTransactionStateData.transactionId))
341 AssignTransactionId(&TopTransactionStateData);
342 return TopTransactionStateData.transactionId;
346 * GetTopTransactionIdIfAny
348 * This will return the XID of the main transaction, if one is assigned.
349 * It will return InvalidTransactionId if we are not currently inside a
350 * transaction, or inside a transaction that hasn't yet been assigned an XID.
353 GetTopTransactionIdIfAny(void)
355 return TopTransactionStateData.transactionId;
359 * GetCurrentTransactionId
361 * This will return the XID of the current transaction (main or sub
362 * transaction), assigning one if it's not yet set. Be careful to call this
363 * only inside a valid xact.
366 GetCurrentTransactionId(void)
368 TransactionState s = CurrentTransactionState;
370 if (!TransactionIdIsValid(s->transactionId))
371 AssignTransactionId(s);
372 return s->transactionId;
376 * GetCurrentTransactionIdIfAny
378 * This will return the XID of the current sub xact, if one is assigned.
379 * It will return InvalidTransactionId if we are not currently inside a
380 * transaction, or inside a transaction that hasn't been assigned an XID yet.
383 GetCurrentTransactionIdIfAny(void)
385 return CurrentTransactionState->transactionId;
390 * AssignTransactionId
392 * Assigns a new permanent XID to the given TransactionState.
393 * We do not assign XIDs to transactions until/unless this is called.
394 * Also, any parent TransactionStates that don't yet have XIDs are assigned
395 * one; this maintains the invariant that a child transaction has an XID
396 * following its parent's.
399 AssignTransactionId(TransactionState s)
401 bool isSubXact = (s->parent != NULL);
402 ResourceOwner currentOwner;
404 if (RecoveryInProgress())
405 elog(ERROR, "cannot assign TransactionIds during recovery");
407 /* Assert that caller didn't screw up */
408 Assert(!TransactionIdIsValid(s->transactionId));
409 Assert(s->state == TRANS_INPROGRESS);
412 * Ensure parent(s) have XIDs, so that a child always has an XID later
415 if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
416 AssignTransactionId(s->parent);
419 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
421 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
422 * shared storage other than PG_PROC; because if there's no room for it in
423 * PG_PROC, the subtrans entry is needed to ensure that other backends see
424 * the Xid as "running". See GetNewTransactionId.
426 s->transactionId = GetNewTransactionId(isSubXact);
429 SubTransSetParent(s->transactionId, s->parent->transactionId, false);
432 * Acquire lock on the transaction XID. (We assume this cannot block.) We
433 * have to ensure that the lock is assigned to the transaction's own
436 currentOwner = CurrentResourceOwner;
439 CurrentResourceOwner = s->curTransactionOwner;
440 XactLockTableInsert(s->transactionId);
444 /* Ensure CurrentResourceOwner is restored on error */
445 CurrentResourceOwner = currentOwner;
449 CurrentResourceOwner = currentOwner;
452 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
453 * top-level transaction we issue a WAL record for the assignment. We
454 * include the top-level xid and all the subxids that have not yet been
455 * reported using XLOG_XACT_ASSIGNMENT records.
457 * This is required to limit the amount of shared memory required in a
458 * hot standby server to keep track of in-progress XIDs. See notes for
459 * RecordKnownAssignedTransactionIds().
461 * We don't keep track of the immediate parent of each subxid,
462 * only the top-level transaction that each subxact belongs to. This
463 * is correct in recovery only because aborted subtransactions are
464 * separately WAL logged.
466 if (isSubXact && XLogStandbyInfoActive())
468 unreportedXids[nUnreportedXids] = s->transactionId;
471 /* ensure this test matches similar one in RecoverPreparedTransactions() */
472 if (nUnreportedXids >= PGPROC_MAX_CACHED_SUBXIDS)
474 XLogRecData rdata[2];
475 xl_xact_assignment xlrec;
478 * xtop is always set by now because we recurse up transaction
479 * stack to the highest unassigned xid and then come back down
481 xlrec.xtop = GetTopTransactionId();
482 Assert(TransactionIdIsValid(xlrec.xtop));
483 xlrec.nsubxacts = nUnreportedXids;
485 rdata[0].data = (char *) &xlrec;
486 rdata[0].len = MinSizeOfXactAssignment;
487 rdata[0].buffer = InvalidBuffer;
488 rdata[0].next = &rdata[1];
490 rdata[1].data = (char *) unreportedXids;
491 rdata[1].len = PGPROC_MAX_CACHED_SUBXIDS * sizeof(TransactionId);
492 rdata[1].buffer = InvalidBuffer;
493 rdata[1].next = NULL;
495 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT, rdata);
503 * GetCurrentSubTransactionId
506 GetCurrentSubTransactionId(void)
508 TransactionState s = CurrentTransactionState;
510 return s->subTransactionId;
515 * GetCurrentCommandId
517 * "used" must be TRUE if the caller intends to use the command ID to mark
518 * inserted/updated/deleted tuples. FALSE means the ID is being fetched
519 * for read-only purposes (ie, as a snapshot validity cutoff). See
520 * CommandCounterIncrement() for discussion.
523 GetCurrentCommandId(bool used)
525 /* this is global to a transaction, not subtransaction-local */
527 currentCommandIdUsed = true;
528 return currentCommandId;
532 * GetCurrentTransactionStartTimestamp
535 GetCurrentTransactionStartTimestamp(void)
537 return xactStartTimestamp;
541 * GetCurrentStatementStartTimestamp
544 GetCurrentStatementStartTimestamp(void)
546 return stmtStartTimestamp;
550 * GetCurrentTransactionStopTimestamp
552 * We return current time if the transaction stop time hasn't been set
553 * (which can happen if we decide we don't need to log an XLOG record).
556 GetCurrentTransactionStopTimestamp(void)
558 if (xactStopTimestamp != 0)
559 return xactStopTimestamp;
560 return GetCurrentTimestamp();
564 * SetCurrentStatementStartTimestamp
567 SetCurrentStatementStartTimestamp(void)
569 stmtStartTimestamp = GetCurrentTimestamp();
573 * SetCurrentTransactionStopTimestamp
576 SetCurrentTransactionStopTimestamp(void)
578 xactStopTimestamp = GetCurrentTimestamp();
582 * GetCurrentTransactionNestLevel
584 * Note: this will return zero when not inside any transaction, one when
585 * inside a top-level transaction, etc.
588 GetCurrentTransactionNestLevel(void)
590 TransactionState s = CurrentTransactionState;
592 return s->nestingLevel;
597 * TransactionIdIsCurrentTransactionId
600 TransactionIdIsCurrentTransactionId(TransactionId xid)
605 * We always say that BootstrapTransactionId is "not my transaction ID"
606 * even when it is (ie, during bootstrap). Along with the fact that
607 * transam.c always treats BootstrapTransactionId as already committed,
608 * this causes the tqual.c routines to see all tuples as committed, which
609 * is what we need during bootstrap. (Bootstrap mode only inserts tuples,
610 * it never updates or deletes them, so all tuples can be presumed good
613 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
614 * not my transaction ID, so we can just return "false" immediately for
615 * any non-normal XID.
617 if (!TransactionIdIsNormal(xid))
621 * We will return true for the Xid of the current subtransaction, any of
622 * its subcommitted children, any of its parents, or any of their
623 * previously subcommitted children. However, a transaction being aborted
624 * is no longer "current", even though it may still have an entry on the
627 for (s = CurrentTransactionState; s != NULL; s = s->parent)
632 if (s->state == TRANS_ABORT)
634 if (!TransactionIdIsValid(s->transactionId))
635 continue; /* it can't have any child XIDs either */
636 if (TransactionIdEquals(xid, s->transactionId))
638 /* As the childXids array is ordered, we can use binary search */
640 high = s->nChildXids - 1;
646 middle = low + (high - low) / 2;
647 probe = s->childXids[middle];
648 if (TransactionIdEquals(probe, xid))
650 else if (TransactionIdPrecedes(probe, xid))
661 * TransactionStartedDuringRecovery
663 * Returns true if the current transaction started while recovery was still
664 * in progress. Recovery might have ended since so RecoveryInProgress() might
665 * return false already.
668 TransactionStartedDuringRecovery(void)
670 return CurrentTransactionState->startedInRecovery;
674 * CommandCounterIncrement
677 CommandCounterIncrement(void)
680 * If the current value of the command counter hasn't been "used" to mark
681 * tuples, we need not increment it, since there's no need to distinguish
682 * a read-only command from others. This helps postpone command counter
683 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
685 if (currentCommandIdUsed)
687 currentCommandId += 1;
688 if (currentCommandId == FirstCommandId) /* check for overflow */
690 currentCommandId -= 1;
692 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
693 errmsg("cannot have more than 2^32-1 commands in a transaction")));
695 currentCommandIdUsed = false;
697 /* Propagate new command ID into static snapshots */
698 SnapshotSetCommandId(currentCommandId);
701 * Make any catalog changes done by the just-completed command visible
702 * in the local syscache. We obviously don't need to do this after a
703 * read-only command. (But see hacks in inval.c to make real sure we
704 * don't think a command that queued inval messages was read-only.)
706 AtCommit_LocalCache();
710 * Make any other backends' catalog changes visible to me.
712 * XXX this is probably in the wrong place: CommandCounterIncrement should
713 * be purely a local operation, most likely. However fooling with this
714 * will affect asynchronous cross-backend interactions, which doesn't seem
715 * like a wise thing to do in late beta, so save improving this for
716 * another day - tgl 2007-11-30
724 * Interface routine to allow commands to force a synchronous commit of the
725 * current top-level transaction
728 ForceSyncCommit(void)
730 forceSyncCommit = true;
734 /* ----------------------------------------------------------------
735 * StartTransaction stuff
736 * ----------------------------------------------------------------
745 AcceptInvalidationMessages();
754 TransactionState s = CurrentTransactionState;
757 * If this is the first time through, create a private context for
758 * AbortTransaction to work in. By reserving some space now, we can
759 * insulate AbortTransaction from out-of-memory scenarios. Like
760 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
761 * size, so that space will be reserved immediately.
763 if (TransactionAbortContext == NULL)
764 TransactionAbortContext =
765 AllocSetContextCreate(TopMemoryContext,
766 "TransactionAbortContext",
772 * We shouldn't have a transaction context already.
774 Assert(TopTransactionContext == NULL);
777 * Create a toplevel context for the transaction.
779 TopTransactionContext =
780 AllocSetContextCreate(TopMemoryContext,
781 "TopTransactionContext",
782 ALLOCSET_DEFAULT_MINSIZE,
783 ALLOCSET_DEFAULT_INITSIZE,
784 ALLOCSET_DEFAULT_MAXSIZE);
787 * In a top-level transaction, CurTransactionContext is the same as
788 * TopTransactionContext.
790 CurTransactionContext = TopTransactionContext;
791 s->curTransactionContext = CurTransactionContext;
793 /* Make the CurTransactionContext active. */
794 MemoryContextSwitchTo(CurTransactionContext);
798 * AtStart_ResourceOwner
801 AtStart_ResourceOwner(void)
803 TransactionState s = CurrentTransactionState;
806 * We shouldn't have a transaction resource owner already.
808 Assert(TopTransactionResourceOwner == NULL);
811 * Create a toplevel resource owner for the transaction.
813 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
815 TopTransactionResourceOwner = s->curTransactionOwner;
816 CurTransactionResourceOwner = s->curTransactionOwner;
817 CurrentResourceOwner = s->curTransactionOwner;
820 /* ----------------------------------------------------------------
821 * StartSubTransaction stuff
822 * ----------------------------------------------------------------
829 AtSubStart_Memory(void)
831 TransactionState s = CurrentTransactionState;
833 Assert(CurTransactionContext != NULL);
836 * Create a CurTransactionContext, which will be used to hold data that
837 * survives subtransaction commit but disappears on subtransaction abort.
838 * We make it a child of the immediate parent's CurTransactionContext.
840 CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
841 "CurTransactionContext",
842 ALLOCSET_DEFAULT_MINSIZE,
843 ALLOCSET_DEFAULT_INITSIZE,
844 ALLOCSET_DEFAULT_MAXSIZE);
845 s->curTransactionContext = CurTransactionContext;
847 /* Make the CurTransactionContext active. */
848 MemoryContextSwitchTo(CurTransactionContext);
852 * AtSubStart_ResourceOwner
855 AtSubStart_ResourceOwner(void)
857 TransactionState s = CurrentTransactionState;
859 Assert(s->parent != NULL);
862 * Create a resource owner for the subtransaction. We make it a child of
863 * the immediate parent's resource owner.
865 s->curTransactionOwner =
866 ResourceOwnerCreate(s->parent->curTransactionOwner,
869 CurTransactionResourceOwner = s->curTransactionOwner;
870 CurrentResourceOwner = s->curTransactionOwner;
873 /* ----------------------------------------------------------------
874 * CommitTransaction stuff
875 * ----------------------------------------------------------------
879 * RecordTransactionCommit
881 * Returns latest XID among xact and its children, or InvalidTransactionId
882 * if the xact has no XID. (We compute that here just because it's easier.)
884 * This is exported only to support an ugly hack in VACUUM FULL.
887 RecordTransactionCommit(bool isVacuumFull)
889 TransactionId xid = GetTopTransactionIdIfAny();
890 bool markXidCommitted = TransactionIdIsValid(xid);
891 TransactionId latestXid = InvalidTransactionId;
896 TransactionId *children;
898 SharedInvalidationMessage *invalMessages = NULL;
899 bool RelcacheInitFileInval;
901 /* Get data needed for commit record */
902 nrels = smgrGetPendingDeletes(true, &rels, &haveNonTemp);
903 nchildren = xactGetCommittedChildren(&children);
904 nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
905 &RelcacheInitFileInval);
907 * If we haven't been assigned an XID yet, we neither can, nor do we want
908 * to write a COMMIT record.
910 if (!markXidCommitted)
913 * We expect that every smgrscheduleunlink is followed by a catalog
914 * update, and hence XID assignment, so we shouldn't get here with any
915 * pending deletes. Use a real test not just an Assert to check this,
916 * since it's a bit fragile.
919 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
921 /* Can't have child XIDs either; AssignTransactionId enforces this */
922 Assert(nchildren == 0);
925 * If we didn't create XLOG entries, we're done here; otherwise we
926 * should flush those entries the same as a commit record. (An
927 * example of a possible record that wouldn't cause an XID to be
928 * assigned is a sequence advance record due to nextval() --- we want
929 * to flush that to disk before reporting commit.)
931 if (XactLastRecEnd.xrecoff == 0)
937 * Begin commit critical section and insert the commit XLOG record.
939 XLogRecData rdata[4];
941 xl_xact_commit xlrec;
943 /* Tell bufmgr and smgr to prepare for commit */
947 * Set flags required for recovery processing of commits.
950 if (RelcacheInitFileInval)
951 xlrec.xinfo |= XACT_COMPLETION_UPDATE_RELCACHE_FILE;
953 xlrec.xinfo |= XACT_COMPLETION_VACUUM_FULL;
955 xlrec.xinfo |= XACT_COMPLETION_FORCE_SYNC_COMMIT;
958 * Mark ourselves as within our "commit critical section". This
959 * forces any concurrent checkpoint to wait until we've updated
960 * pg_clog. Without this, it is possible for the checkpoint to set
961 * REDO after the XLOG record but fail to flush the pg_clog update to
962 * disk, leading to loss of the transaction commit if the system
963 * crashes a little later.
965 * Note: we could, but don't bother to, set this flag in
966 * RecordTransactionAbort. That's because loss of a transaction abort
967 * is noncritical; the presumption would be that it aborted, anyway.
969 * It's safe to change the inCommit flag of our own backend without
970 * holding the ProcArrayLock, since we're the only one modifying it.
971 * This makes checkpoint's determination of which xacts are inCommit a
972 * bit fuzzy, but it doesn't matter.
974 START_CRIT_SECTION();
975 MyProc->inCommit = true;
977 SetCurrentTransactionStopTimestamp();
978 xlrec.xact_time = xactStopTimestamp;
980 xlrec.nsubxacts = nchildren;
982 rdata[0].data = (char *) (&xlrec);
983 rdata[0].len = MinSizeOfXactCommit;
984 rdata[0].buffer = InvalidBuffer;
985 /* dump rels to delete */
988 rdata[0].next = &(rdata[1]);
989 rdata[1].data = (char *) rels;
990 rdata[1].len = nrels * sizeof(RelFileNode);
991 rdata[1].buffer = InvalidBuffer;
994 /* dump committed child Xids */
997 rdata[lastrdata].next = &(rdata[2]);
998 rdata[2].data = (char *) children;
999 rdata[2].len = nchildren * sizeof(TransactionId);
1000 rdata[2].buffer = InvalidBuffer;
1003 /* dump shared cache invalidation messages */
1006 rdata[lastrdata].next = &(rdata[3]);
1007 rdata[3].data = (char *) invalMessages;
1008 rdata[3].len = nmsgs * sizeof(SharedInvalidationMessage);
1009 rdata[3].buffer = InvalidBuffer;
1012 rdata[lastrdata].next = NULL;
1014 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
1018 * Check if we want to commit asynchronously. If the user has set
1019 * synchronous_commit = off, and we're not doing cleanup of any non-temp
1020 * rels nor committing any command that wanted to force sync commit, then
1021 * we can defer flushing XLOG. (We must not allow asynchronous commit if
1022 * there are any non-temp tables to be deleted, because we might delete
1023 * the files before the COMMIT record is flushed to disk. We do allow
1024 * asynchronous commit if all to-be-deleted tables are temporary though,
1025 * since they are lost anyway if we crash.)
1027 if (XactSyncCommit || forceSyncCommit || haveNonTemp)
1030 * Synchronous commit case.
1032 * Sleep before flush! So we can flush more than one commit records
1033 * per single fsync. (The idea is some other backend may do the
1034 * XLogFlush while we're sleeping. This needs work still, because on
1035 * most Unixen, the minimum select() delay is 10msec or more, which is
1038 * We do not sleep if enableFsync is not turned on, nor if there are
1039 * fewer than CommitSiblings other backends with active transactions.
1041 if (CommitDelay > 0 && enableFsync &&
1042 CountActiveBackends() >= CommitSiblings)
1043 pg_usleep(CommitDelay);
1045 XLogFlush(XactLastRecEnd);
1048 * Now we may update the CLOG, if we wrote a COMMIT record above
1050 if (markXidCommitted)
1051 TransactionIdCommitTree(xid, nchildren, children);
1056 * Asynchronous commit case.
1058 * Report the latest async commit LSN, so that the WAL writer knows to
1059 * flush this commit.
1061 XLogSetAsyncCommitLSN(XactLastRecEnd);
1064 * We must not immediately update the CLOG, since we didn't flush the
1065 * XLOG. Instead, we store the LSN up to which the XLOG must be
1066 * flushed before the CLOG may be updated.
1068 if (markXidCommitted)
1069 TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1073 * If we entered a commit critical section, leave it now, and let
1074 * checkpoints proceed.
1076 if (markXidCommitted)
1078 MyProc->inCommit = false;
1082 /* Compute latestXid while we have the child XIDs handy */
1083 latestXid = TransactionIdLatest(xid, nchildren, children);
1085 /* Reset XactLastRecEnd until the next transaction writes something */
1086 XactLastRecEnd.xrecoff = 0;
1089 /* Clean up local data */
1098 * AtCommit_LocalCache
1101 AtCommit_LocalCache(void)
1104 * Make catalog changes visible to me for the next command.
1106 CommandEndInvalidationMessages();
1113 AtCommit_Memory(void)
1116 * Now that we're "out" of a transaction, have the system allocate things
1117 * in the top memory context instead of per-transaction contexts.
1119 MemoryContextSwitchTo(TopMemoryContext);
1122 * Release all transaction-local memory.
1124 Assert(TopTransactionContext != NULL);
1125 MemoryContextDelete(TopTransactionContext);
1126 TopTransactionContext = NULL;
1127 CurTransactionContext = NULL;
1128 CurrentTransactionState->curTransactionContext = NULL;
1131 /* ----------------------------------------------------------------
1132 * CommitSubTransaction stuff
1133 * ----------------------------------------------------------------
1137 * AtSubCommit_Memory
1140 AtSubCommit_Memory(void)
1142 TransactionState s = CurrentTransactionState;
1144 Assert(s->parent != NULL);
1146 /* Return to parent transaction level's memory context. */
1147 CurTransactionContext = s->parent->curTransactionContext;
1148 MemoryContextSwitchTo(CurTransactionContext);
1151 * Ordinarily we cannot throw away the child's CurTransactionContext,
1152 * since the data it contains will be needed at upper commit. However, if
1153 * there isn't actually anything in it, we can throw it away. This avoids
1154 * a small memory leak in the common case of "trivial" subxacts.
1156 if (MemoryContextIsEmpty(s->curTransactionContext))
1158 MemoryContextDelete(s->curTransactionContext);
1159 s->curTransactionContext = NULL;
1164 * AtSubCommit_childXids
1166 * Pass my own XID and my child XIDs up to my parent as committed children.
1169 AtSubCommit_childXids(void)
1171 TransactionState s = CurrentTransactionState;
1174 Assert(s->parent != NULL);
1177 * The parent childXids array will need to hold my XID and all my
1178 * childXids, in addition to the XIDs already there.
1180 new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1182 /* Allocate or enlarge the parent array if necessary */
1183 if (s->parent->maxChildXids < new_nChildXids)
1185 int new_maxChildXids;
1186 TransactionId *new_childXids;
1189 * Make it 2x what's needed right now, to avoid having to enlarge it
1190 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1191 * is what ensures that we don't need to worry about integer overflow
1192 * here or in the calculation of new_nChildXids.)
1194 new_maxChildXids = Min(new_nChildXids * 2,
1195 (int) (MaxAllocSize / sizeof(TransactionId)));
1197 if (new_maxChildXids < new_nChildXids)
1199 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1200 errmsg("maximum number of committed subtransactions (%d) exceeded",
1201 (int) (MaxAllocSize / sizeof(TransactionId)))));
1204 * We keep the child-XID arrays in TopTransactionContext; this avoids
1205 * setting up child-transaction contexts for what might be just a few
1206 * bytes of grandchild XIDs.
1208 if (s->parent->childXids == NULL)
1210 MemoryContextAlloc(TopTransactionContext,
1211 new_maxChildXids * sizeof(TransactionId));
1213 new_childXids = repalloc(s->parent->childXids,
1214 new_maxChildXids * sizeof(TransactionId));
1216 s->parent->childXids = new_childXids;
1217 s->parent->maxChildXids = new_maxChildXids;
1221 * Copy all my XIDs to parent's array.
1223 * Note: We rely on the fact that the XID of a child always follows that
1224 * of its parent. By copying the XID of this subtransaction before the
1225 * XIDs of its children, we ensure that the array stays ordered.
1226 * Likewise, all XIDs already in the array belong to subtransactions
1227 * started and subcommitted before us, so their XIDs must precede ours.
1229 s->parent->childXids[s->parent->nChildXids] = s->transactionId;
1231 if (s->nChildXids > 0)
1232 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1234 s->nChildXids * sizeof(TransactionId));
1236 s->parent->nChildXids = new_nChildXids;
1238 /* Release child's array to avoid leakage */
1239 if (s->childXids != NULL)
1240 pfree(s->childXids);
1241 /* We must reset these to avoid double-free if fail later in commit */
1242 s->childXids = NULL;
1244 s->maxChildXids = 0;
1247 /* ----------------------------------------------------------------
1248 * AbortTransaction stuff
1249 * ----------------------------------------------------------------
1253 * RecordTransactionAbort
1255 * Returns latest XID among xact and its children, or InvalidTransactionId
1256 * if the xact has no XID. (We compute that here just because it's easier.)
1258 static TransactionId
1259 RecordTransactionAbort(bool isSubXact)
1261 TransactionId xid = GetCurrentTransactionIdIfAny();
1262 TransactionId latestXid;
1266 TransactionId *children;
1267 XLogRecData rdata[3];
1269 xl_xact_abort xlrec;
1272 * If we haven't been assigned an XID, nobody will care whether we aborted
1273 * or not. Hence, we're done in that case. It does not matter if we have
1274 * rels to delete (note that this routine is not responsible for actually
1275 * deleting 'em). We cannot have any child XIDs, either.
1277 if (!TransactionIdIsValid(xid))
1279 /* Reset XactLastRecEnd until the next transaction writes something */
1281 XactLastRecEnd.xrecoff = 0;
1282 return InvalidTransactionId;
1286 * We have a valid XID, so we should write an ABORT record for it.
1288 * We do not flush XLOG to disk here, since the default assumption after a
1289 * crash would be that we aborted, anyway. For the same reason, we don't
1290 * need to worry about interlocking against checkpoint start.
1294 * Check that we haven't aborted halfway through RecordTransactionCommit.
1296 if (TransactionIdDidCommit(xid))
1297 elog(PANIC, "cannot abort transaction %u, it was already committed",
1300 /* Fetch the data we need for the abort record */
1301 nrels = smgrGetPendingDeletes(false, &rels, NULL);
1302 nchildren = xactGetCommittedChildren(&children);
1304 /* XXX do we really need a critical section here? */
1305 START_CRIT_SECTION();
1307 /* Write the ABORT record */
1309 xlrec.xact_time = GetCurrentTimestamp();
1312 SetCurrentTransactionStopTimestamp();
1313 xlrec.xact_time = xactStopTimestamp;
1315 xlrec.nrels = nrels;
1316 xlrec.nsubxacts = nchildren;
1317 rdata[0].data = (char *) (&xlrec);
1318 rdata[0].len = MinSizeOfXactAbort;
1319 rdata[0].buffer = InvalidBuffer;
1320 /* dump rels to delete */
1323 rdata[0].next = &(rdata[1]);
1324 rdata[1].data = (char *) rels;
1325 rdata[1].len = nrels * sizeof(RelFileNode);
1326 rdata[1].buffer = InvalidBuffer;
1329 /* dump committed child Xids */
1332 rdata[lastrdata].next = &(rdata[2]);
1333 rdata[2].data = (char *) children;
1334 rdata[2].len = nchildren * sizeof(TransactionId);
1335 rdata[2].buffer = InvalidBuffer;
1338 rdata[lastrdata].next = NULL;
1340 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
1343 * Mark the transaction aborted in clog. This is not absolutely necessary
1344 * but we may as well do it while we are here; also, in the subxact case
1345 * it is helpful because XactLockTableWait makes use of it to avoid
1346 * waiting for already-aborted subtransactions. It is OK to do it without
1347 * having flushed the ABORT record to disk, because in event of a crash
1348 * we'd be assumed to have aborted anyway.
1350 TransactionIdAbortTree(xid, nchildren, children);
1354 /* Compute latestXid while we have the child XIDs handy */
1355 latestXid = TransactionIdLatest(xid, nchildren, children);
1358 * If we're aborting a subtransaction, we can immediately remove failed
1359 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1360 * subxacts, because we already have the child XID array at hand. For
1361 * main xacts, the equivalent happens just after this function returns.
1364 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1366 /* Reset XactLastRecEnd until the next transaction writes something */
1368 XactLastRecEnd.xrecoff = 0;
1370 /* And clean up local data */
1381 AtAbort_Memory(void)
1384 * Switch into TransactionAbortContext, which should have some free space
1385 * even if nothing else does. We'll work in this context until we've
1386 * finished cleaning up.
1388 * It is barely possible to get here when we've not been able to create
1389 * TransactionAbortContext yet; if so use TopMemoryContext.
1391 if (TransactionAbortContext != NULL)
1392 MemoryContextSwitchTo(TransactionAbortContext);
1394 MemoryContextSwitchTo(TopMemoryContext);
1401 AtSubAbort_Memory(void)
1403 Assert(TransactionAbortContext != NULL);
1405 MemoryContextSwitchTo(TransactionAbortContext);
1410 * AtAbort_ResourceOwner
1413 AtAbort_ResourceOwner(void)
1416 * Make sure we have a valid ResourceOwner, if possible (else it will be
1417 * NULL, which is OK)
1419 CurrentResourceOwner = TopTransactionResourceOwner;
1423 * AtSubAbort_ResourceOwner
1426 AtSubAbort_ResourceOwner(void)
1428 TransactionState s = CurrentTransactionState;
1430 /* Make sure we have a valid ResourceOwner */
1431 CurrentResourceOwner = s->curTransactionOwner;
1436 * AtSubAbort_childXids
1439 AtSubAbort_childXids(void)
1441 TransactionState s = CurrentTransactionState;
1444 * We keep the child-XID arrays in TopTransactionContext (see
1445 * AtSubCommit_childXids). This means we'd better free the array
1446 * explicitly at abort to avoid leakage.
1448 if (s->childXids != NULL)
1449 pfree(s->childXids);
1450 s->childXids = NULL;
1452 s->maxChildXids = 0;
1455 * We could prune the unreportedXids array here. But we don't bother.
1456 * That would potentially reduce number of XLOG_XACT_ASSIGNMENT records
1457 * but it would likely introduce more CPU time into the more common
1458 * paths, so we choose not to do that.
1462 /* ----------------------------------------------------------------
1463 * CleanupTransaction stuff
1464 * ----------------------------------------------------------------
1471 AtCleanup_Memory(void)
1473 Assert(CurrentTransactionState->parent == NULL);
1476 * Now that we're "out" of a transaction, have the system allocate things
1477 * in the top memory context instead of per-transaction contexts.
1479 MemoryContextSwitchTo(TopMemoryContext);
1482 * Clear the special abort context for next time.
1484 if (TransactionAbortContext != NULL)
1485 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1488 * Release all transaction-local memory.
1490 if (TopTransactionContext != NULL)
1491 MemoryContextDelete(TopTransactionContext);
1492 TopTransactionContext = NULL;
1493 CurTransactionContext = NULL;
1494 CurrentTransactionState->curTransactionContext = NULL;
1498 /* ----------------------------------------------------------------
1499 * CleanupSubTransaction stuff
1500 * ----------------------------------------------------------------
1504 * AtSubCleanup_Memory
1507 AtSubCleanup_Memory(void)
1509 TransactionState s = CurrentTransactionState;
1511 Assert(s->parent != NULL);
1513 /* Make sure we're not in an about-to-be-deleted context */
1514 MemoryContextSwitchTo(s->parent->curTransactionContext);
1515 CurTransactionContext = s->parent->curTransactionContext;
1518 * Clear the special abort context for next time.
1520 if (TransactionAbortContext != NULL)
1521 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1524 * Delete the subxact local memory contexts. Its CurTransactionContext can
1525 * go too (note this also kills CurTransactionContexts from any children
1528 if (s->curTransactionContext)
1529 MemoryContextDelete(s->curTransactionContext);
1530 s->curTransactionContext = NULL;
1533 /* ----------------------------------------------------------------
1534 * interface routines
1535 * ----------------------------------------------------------------
1542 StartTransaction(void)
1545 VirtualTransactionId vxid;
1548 * Let's just make sure the state stack is empty
1550 s = &TopTransactionStateData;
1551 CurrentTransactionState = s;
1554 * check the current transaction state
1556 if (s->state != TRANS_DEFAULT)
1557 elog(WARNING, "StartTransaction while in %s state",
1558 TransStateAsString(s->state));
1561 * set the current transaction state information appropriately during
1564 s->state = TRANS_START;
1565 s->transactionId = InvalidTransactionId; /* until assigned */
1568 * Make sure we've reset xact state variables
1570 * If recovery is still in progress, mark this transaction as read-only.
1571 * We have lower level defences in XLogInsert and elsewhere to stop us
1572 * from modifying data during recovery, but this gives the normal
1573 * indication to the user that the transaction is read-only.
1575 if (RecoveryInProgress())
1577 s->startedInRecovery = true;
1578 XactReadOnly = true;
1582 s->startedInRecovery = false;
1583 XactReadOnly = DefaultXactReadOnly;
1585 XactIsoLevel = DefaultXactIsoLevel;
1586 forceSyncCommit = false;
1587 MyXactAccessedTempRel = false;
1590 * reinitialize within-transaction counters
1592 s->subTransactionId = TopSubTransactionId;
1593 currentSubTransactionId = TopSubTransactionId;
1594 currentCommandId = FirstCommandId;
1595 currentCommandIdUsed = false;
1598 * initialize reported xid accounting
1600 nUnreportedXids = 0;
1603 * must initialize resource-management stuff first
1606 AtStart_ResourceOwner();
1609 * Assign a new LocalTransactionId, and combine it with the backendId to
1610 * form a virtual transaction id.
1612 vxid.backendId = MyBackendId;
1613 vxid.localTransactionId = GetNextLocalTransactionId();
1616 * Lock the virtual transaction id before we announce it in the proc array
1618 VirtualXactLockTableInsert(vxid);
1621 * Advertise it in the proc array. We assume assignment of
1622 * LocalTransactionID is atomic, and the backendId should be set already.
1624 Assert(MyProc->backendId == vxid.backendId);
1625 MyProc->lxid = vxid.localTransactionId;
1627 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
1630 * set transaction_timestamp() (a/k/a now()). We want this to be the same
1631 * as the first command's statement_timestamp(), so don't do a fresh
1632 * GetCurrentTimestamp() call (which'd be expensive anyway). Also, mark
1633 * xactStopTimestamp as unset.
1635 xactStartTimestamp = stmtStartTimestamp;
1636 xactStopTimestamp = 0;
1637 pgstat_report_xact_timestamp(xactStartTimestamp);
1640 * initialize current transaction state fields
1642 * note: prevXactReadOnly is not used at the outermost level
1644 s->nestingLevel = 1;
1645 s->gucNestLevel = 1;
1646 s->childXids = NULL;
1648 s->maxChildXids = 0;
1649 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
1650 /* SecurityRestrictionContext should never be set outside a transaction */
1651 Assert(s->prevSecContext == 0);
1654 * initialize other subsystems for new transaction
1659 AfterTriggerBeginXact();
1662 * done with start processing, set current transaction state to "in
1665 s->state = TRANS_INPROGRESS;
1667 ShowTransactionState("StartTransaction");
1674 * NB: if you change this routine, better look at PrepareTransaction too!
1677 CommitTransaction(void)
1679 TransactionState s = CurrentTransactionState;
1680 TransactionId latestXid;
1682 ShowTransactionState("CommitTransaction");
1685 * check the current transaction state
1687 if (s->state != TRANS_INPROGRESS)
1688 elog(WARNING, "CommitTransaction while in %s state",
1689 TransStateAsString(s->state));
1690 Assert(s->parent == NULL);
1693 * Do pre-commit processing (most of this stuff requires database access,
1694 * and in fact could still cause an error...)
1696 * It is possible for CommitHoldablePortals to invoke functions that queue
1697 * deferred triggers, and it's also possible that triggers create holdable
1698 * cursors. So we have to loop until there's nothing left to do.
1703 * Fire all currently pending deferred triggers.
1705 AfterTriggerFireDeferred();
1708 * Convert any open holdable cursors into static portals. If there
1709 * weren't any, we are done ... otherwise loop back to check if they
1710 * queued deferred triggers. Lather, rinse, repeat.
1712 if (!CommitHoldablePortals())
1716 /* Now we can shut down the deferred-trigger manager */
1717 AfterTriggerEndXact(true);
1719 /* Close any open regular cursors */
1723 * Let ON COMMIT management do its thing (must happen after closing
1724 * cursors, to avoid dangling-reference problems)
1726 PreCommit_on_commit_actions();
1728 /* close large objects before lower-level cleanup */
1729 AtEOXact_LargeObject(true);
1731 /* NOTIFY commit must come before lower-level cleanup */
1734 /* Prevent cancel/die interrupt while cleaning up */
1738 * set the current transaction state information appropriately during
1741 s->state = TRANS_COMMIT;
1744 * Here is where we really truly commit.
1746 latestXid = RecordTransactionCommit(false);
1748 TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
1751 * Let others know about no transaction in progress by me. Note that this
1752 * must be done _before_ releasing locks we hold and _after_
1753 * RecordTransactionCommit.
1755 ProcArrayEndTransaction(MyProc, latestXid);
1758 * This is all post-commit cleanup. Note that if an error is raised here,
1759 * it's too late to abort the transaction. This should be just
1760 * noncritical resource releasing.
1762 * The ordering of operations is not entirely random. The idea is:
1763 * release resources visible to other backends (eg, files, buffer pins);
1764 * then release locks; then release backend-local resources. We want to
1765 * release locks at the point where any backend waiting for us will see
1766 * our transaction as being fully cleaned up.
1768 * Resources that can be associated with individual queries are handled by
1769 * the ResourceOwner mechanism. The other calls here are for backend-wide
1773 CallXactCallbacks(XACT_EVENT_COMMIT);
1775 ResourceOwnerRelease(TopTransactionResourceOwner,
1776 RESOURCE_RELEASE_BEFORE_LOCKS,
1779 /* Check we've released all buffer pins */
1780 AtEOXact_Buffers(true);
1782 /* Clean up the relation cache */
1783 AtEOXact_RelationCache(true);
1785 /* Clean up the snapshot manager */
1786 AtEarlyCommit_Snapshot();
1789 * Make catalog changes visible to all backends. This has to happen after
1790 * relcache references are dropped (see comments for
1791 * AtEOXact_RelationCache), but before locks are released (if anyone is
1792 * waiting for lock on a relation we've modified, we want them to know
1793 * about the catalog change before they start using the relation).
1795 AtEOXact_Inval(true);
1798 * Likewise, dropping of files deleted during the transaction is best done
1799 * after releasing relcache and buffer pins. (This is not strictly
1800 * necessary during commit, since such pins should have been released
1801 * already, but this ordering is definitely critical during abort.)
1803 smgrDoPendingDeletes(true);
1805 AtEOXact_MultiXact();
1807 ResourceOwnerRelease(TopTransactionResourceOwner,
1808 RESOURCE_RELEASE_LOCKS,
1810 ResourceOwnerRelease(TopTransactionResourceOwner,
1811 RESOURCE_RELEASE_AFTER_LOCKS,
1814 /* Check we've released all catcache entries */
1815 AtEOXact_CatCache(true);
1817 AtEOXact_GUC(true, 1);
1819 AtEOXact_on_commit_actions(true);
1820 AtEOXact_Namespace(true);
1821 /* smgrcommit already done */
1823 AtEOXact_ComboCid();
1824 AtEOXact_HashTables(true);
1825 AtEOXact_PgStat(true);
1826 AtEOXact_Snapshot(true);
1827 pgstat_report_xact_timestamp(0);
1829 CurrentResourceOwner = NULL;
1830 ResourceOwnerDelete(TopTransactionResourceOwner);
1831 s->curTransactionOwner = NULL;
1832 CurTransactionResourceOwner = NULL;
1833 TopTransactionResourceOwner = NULL;
1837 s->transactionId = InvalidTransactionId;
1838 s->subTransactionId = InvalidSubTransactionId;
1839 s->nestingLevel = 0;
1840 s->gucNestLevel = 0;
1841 s->childXids = NULL;
1843 s->maxChildXids = 0;
1846 * done with commit processing, set current transaction state back to
1849 s->state = TRANS_DEFAULT;
1851 RESUME_INTERRUPTS();
1856 * PrepareTransaction
1858 * NB: if you change this routine, better look at CommitTransaction too!
1861 PrepareTransaction(void)
1863 TransactionState s = CurrentTransactionState;
1864 TransactionId xid = GetCurrentTransactionId();
1865 GlobalTransaction gxact;
1866 TimestampTz prepared_at;
1868 ShowTransactionState("PrepareTransaction");
1871 * check the current transaction state
1873 if (s->state != TRANS_INPROGRESS)
1874 elog(WARNING, "PrepareTransaction while in %s state",
1875 TransStateAsString(s->state));
1876 Assert(s->parent == NULL);
1879 * Do pre-commit processing (most of this stuff requires database access,
1880 * and in fact could still cause an error...)
1882 * It is possible for PrepareHoldablePortals to invoke functions that
1883 * queue deferred triggers, and it's also possible that triggers create
1884 * holdable cursors. So we have to loop until there's nothing left to do.
1889 * Fire all currently pending deferred triggers.
1891 AfterTriggerFireDeferred();
1894 * Convert any open holdable cursors into static portals. If there
1895 * weren't any, we are done ... otherwise loop back to check if they
1896 * queued deferred triggers. Lather, rinse, repeat.
1898 if (!PrepareHoldablePortals())
1902 /* Now we can shut down the deferred-trigger manager */
1903 AfterTriggerEndXact(true);
1905 /* Close any open regular cursors */
1909 * Let ON COMMIT management do its thing (must happen after closing
1910 * cursors, to avoid dangling-reference problems)
1912 PreCommit_on_commit_actions();
1914 /* close large objects before lower-level cleanup */
1915 AtEOXact_LargeObject(true);
1917 /* NOTIFY will be handled below */
1920 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
1921 * this transaction. Having the prepared xact hold locks on another
1922 * backend's temp table seems a bad idea --- for instance it would prevent
1923 * the backend from exiting. There are other problems too, such as how to
1924 * clean up the source backend's local buffers and ON COMMIT state if the
1925 * prepared xact includes a DROP of a temp table.
1927 * We must check this after executing any ON COMMIT actions, because they
1928 * might still access a temp relation.
1930 * XXX In principle this could be relaxed to allow some useful special
1931 * cases, such as a temp table created and dropped all within the
1932 * transaction. That seems to require much more bookkeeping though.
1934 if (MyXactAccessedTempRel)
1936 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1937 errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
1939 /* Prevent cancel/die interrupt while cleaning up */
1943 * set the current transaction state information appropriately during
1944 * prepare processing
1946 s->state = TRANS_PREPARE;
1948 prepared_at = GetCurrentTimestamp();
1950 /* Tell bufmgr and smgr to prepare for commit */
1954 * Reserve the GID for this transaction. This could fail if the requested
1955 * GID is invalid or already in use.
1957 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
1958 GetUserId(), MyDatabaseId);
1962 * Collect data for the 2PC state file. Note that in general, no actual
1963 * state change should happen in the called modules during this step,
1964 * since it's still possible to fail before commit, and in that case we
1965 * want transaction abort to be able to clean up. (In particular, the
1966 * AtPrepare routines may error out if they find cases they cannot
1967 * handle.) State cleanup should happen in the PostPrepare routines
1968 * below. However, some modules can go ahead and clear state here because
1969 * they wouldn't do anything with it during abort anyway.
1971 * Note: because the 2PC state file records will be replayed in the same
1972 * order they are made, the order of these calls has to match the order in
1973 * which we want things to happen during COMMIT PREPARED or ROLLBACK
1974 * PREPARED; in particular, pay attention to whether things should happen
1975 * before or after releasing the transaction's locks.
1977 StartPrepare(gxact);
1982 AtPrepare_MultiXact();
1985 * Here is where we really truly prepare.
1987 * We have to record transaction prepares even if we didn't make any
1988 * updates, because the transaction manager might get confused if we lose
1989 * a global transaction.
1994 * Now we clean up backend-internal state and release internal resources.
1997 /* Reset XactLastRecEnd until the next transaction writes something */
1998 XactLastRecEnd.xrecoff = 0;
2001 * Let others know about no transaction in progress by me. This has to be
2002 * done *after* the prepared transaction has been marked valid, else
2003 * someone may think it is unlocked and recyclable.
2005 ProcArrayClearTransaction(MyProc);
2008 * This is all post-transaction cleanup. Note that if an error is raised
2009 * here, it's too late to abort the transaction. This should be just
2010 * noncritical resource releasing. See notes in CommitTransaction.
2013 CallXactCallbacks(XACT_EVENT_PREPARE);
2015 ResourceOwnerRelease(TopTransactionResourceOwner,
2016 RESOURCE_RELEASE_BEFORE_LOCKS,
2019 /* Check we've released all buffer pins */
2020 AtEOXact_Buffers(true);
2022 /* Clean up the relation cache */
2023 AtEOXact_RelationCache(true);
2025 /* Clean up the snapshot manager */
2026 AtEarlyCommit_Snapshot();
2028 /* notify doesn't need a postprepare call */
2030 PostPrepare_PgStat();
2032 PostPrepare_Inval();
2036 PostPrepare_MultiXact(xid);
2038 PostPrepare_Locks(xid);
2040 ResourceOwnerRelease(TopTransactionResourceOwner,
2041 RESOURCE_RELEASE_LOCKS,
2043 ResourceOwnerRelease(TopTransactionResourceOwner,
2044 RESOURCE_RELEASE_AFTER_LOCKS,
2047 /* Check we've released all catcache entries */
2048 AtEOXact_CatCache(true);
2050 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2051 AtEOXact_GUC(true, 1);
2053 AtEOXact_on_commit_actions(true);
2054 AtEOXact_Namespace(true);
2055 /* smgrcommit already done */
2057 AtEOXact_ComboCid();
2058 AtEOXact_HashTables(true);
2059 /* don't call AtEOXact_PgStat here */
2060 AtEOXact_Snapshot(true);
2062 CurrentResourceOwner = NULL;
2063 ResourceOwnerDelete(TopTransactionResourceOwner);
2064 s->curTransactionOwner = NULL;
2065 CurTransactionResourceOwner = NULL;
2066 TopTransactionResourceOwner = NULL;
2070 s->transactionId = InvalidTransactionId;
2071 s->subTransactionId = InvalidSubTransactionId;
2072 s->nestingLevel = 0;
2073 s->gucNestLevel = 0;
2074 s->childXids = NULL;
2076 s->maxChildXids = 0;
2079 * done with 1st phase commit processing, set current transaction state
2082 s->state = TRANS_DEFAULT;
2084 RESUME_INTERRUPTS();
2092 AbortTransaction(void)
2094 TransactionState s = CurrentTransactionState;
2095 TransactionId latestXid;
2097 /* Prevent cancel/die interrupt while cleaning up */
2100 /* Make sure we have a valid memory context and resource owner */
2102 AtAbort_ResourceOwner();
2105 * Release any LW locks we might be holding as quickly as possible.
2106 * (Regular locks, however, must be held till we finish aborting.)
2107 * Releasing LW locks is critical since we might try to grab them again
2108 * while cleaning up!
2112 /* Clean up buffer I/O and buffer context locks, too */
2117 * Also clean up any open wait for lock, since the lock manager will choke
2118 * if we try to wait for another lock before doing this.
2123 * check the current transaction state
2125 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2126 elog(WARNING, "AbortTransaction while in %s state",
2127 TransStateAsString(s->state));
2128 Assert(s->parent == NULL);
2131 * set the current transaction state information appropriately during the
2134 s->state = TRANS_ABORT;
2137 * Reset user ID which might have been changed transiently. We need this
2138 * to clean up in case control escaped out of a SECURITY DEFINER function
2139 * or other local change of CurrentUserId; therefore, the prior value of
2140 * SecurityRestrictionContext also needs to be restored.
2142 * (Note: it is not necessary to restore session authorization or role
2143 * settings here because those can only be changed via GUC, and GUC will
2144 * take care of rolling them back if need be.)
2146 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
2149 * do abort processing
2151 AfterTriggerEndXact(false);
2153 AtEOXact_LargeObject(false); /* 'false' means it's abort */
2157 * Advertise the fact that we aborted in pg_clog (assuming that we got as
2158 * far as assigning an XID to advertise).
2160 latestXid = RecordTransactionAbort(false);
2162 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
2165 * Let others know about no transaction in progress by me. Note that this
2166 * must be done _before_ releasing locks we hold and _after_
2167 * RecordTransactionAbort.
2169 ProcArrayEndTransaction(MyProc, latestXid);
2172 * Post-abort cleanup. See notes in CommitTransaction() concerning
2176 CallXactCallbacks(XACT_EVENT_ABORT);
2178 ResourceOwnerRelease(TopTransactionResourceOwner,
2179 RESOURCE_RELEASE_BEFORE_LOCKS,
2181 AtEOXact_Buffers(false);
2182 AtEOXact_RelationCache(false);
2183 AtEOXact_Inval(false);
2184 smgrDoPendingDeletes(false);
2185 AtEOXact_MultiXact();
2186 ResourceOwnerRelease(TopTransactionResourceOwner,
2187 RESOURCE_RELEASE_LOCKS,
2189 ResourceOwnerRelease(TopTransactionResourceOwner,
2190 RESOURCE_RELEASE_AFTER_LOCKS,
2192 AtEOXact_CatCache(false);
2194 AtEOXact_GUC(false, 1);
2195 AtEOXact_SPI(false);
2196 AtEOXact_on_commit_actions(false);
2197 AtEOXact_Namespace(false);
2199 AtEOXact_ComboCid();
2200 AtEOXact_HashTables(false);
2201 AtEOXact_PgStat(false);
2202 AtEOXact_Snapshot(false);
2203 pgstat_report_xact_timestamp(0);
2206 * State remains TRANS_ABORT until CleanupTransaction().
2208 RESUME_INTERRUPTS();
2212 * CleanupTransaction
2215 CleanupTransaction(void)
2217 TransactionState s = CurrentTransactionState;
2220 * State should still be TRANS_ABORT from AbortTransaction().
2222 if (s->state != TRANS_ABORT)
2223 elog(FATAL, "CleanupTransaction: unexpected state %s",
2224 TransStateAsString(s->state));
2227 * do abort cleanup processing
2229 AtCleanup_Portals(); /* now safe to release portal memory */
2231 CurrentResourceOwner = NULL; /* and resource owner */
2232 if (TopTransactionResourceOwner)
2233 ResourceOwnerDelete(TopTransactionResourceOwner);
2234 s->curTransactionOwner = NULL;
2235 CurTransactionResourceOwner = NULL;
2236 TopTransactionResourceOwner = NULL;
2238 AtCleanup_Memory(); /* and transaction memory */
2240 s->transactionId = InvalidTransactionId;
2241 s->subTransactionId = InvalidSubTransactionId;
2242 s->nestingLevel = 0;
2243 s->gucNestLevel = 0;
2244 s->childXids = NULL;
2246 s->maxChildXids = 0;
2249 * done with abort processing, set current transaction state back to
2252 s->state = TRANS_DEFAULT;
2256 * StartTransactionCommand
2259 StartTransactionCommand(void)
2261 TransactionState s = CurrentTransactionState;
2263 switch (s->blockState)
2266 * if we aren't in a transaction block, we just do our usual start
2269 case TBLOCK_DEFAULT:
2271 s->blockState = TBLOCK_STARTED;
2275 * We are somewhere in a transaction block or subtransaction and
2276 * about to start a new command. For now we do nothing, but
2277 * someday we may do command-local resource initialization. (Note
2278 * that any needed CommandCounterIncrement was done by the
2279 * previous CommitTransactionCommand.)
2281 case TBLOCK_INPROGRESS:
2282 case TBLOCK_SUBINPROGRESS:
2286 * Here we are in a failed transaction block (one of the commands
2287 * caused an abort) so we do nothing but remain in the abort
2288 * state. Eventually we will get a ROLLBACK command which will
2289 * get us out of this state. (It is up to other code to ensure
2290 * that no commands other than ROLLBACK will be processed in these
2294 case TBLOCK_SUBABORT:
2297 /* These cases are invalid. */
2298 case TBLOCK_STARTED:
2300 case TBLOCK_SUBBEGIN:
2303 case TBLOCK_ABORT_END:
2304 case TBLOCK_SUBABORT_END:
2305 case TBLOCK_ABORT_PENDING:
2306 case TBLOCK_SUBABORT_PENDING:
2307 case TBLOCK_SUBRESTART:
2308 case TBLOCK_SUBABORT_RESTART:
2309 case TBLOCK_PREPARE:
2310 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2311 BlockStateAsString(s->blockState));
2316 * We must switch to CurTransactionContext before returning. This is
2317 * already done if we called StartTransaction, otherwise not.
2319 Assert(CurTransactionContext != NULL);
2320 MemoryContextSwitchTo(CurTransactionContext);
2324 * CommitTransactionCommand
2327 CommitTransactionCommand(void)
2329 TransactionState s = CurrentTransactionState;
2331 switch (s->blockState)
2334 * This shouldn't happen, because it means the previous
2335 * StartTransactionCommand didn't set the STARTED state
2338 case TBLOCK_DEFAULT:
2339 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2340 BlockStateAsString(s->blockState));
2344 * If we aren't in a transaction block, just do our usual
2345 * transaction commit, and return to the idle state.
2347 case TBLOCK_STARTED:
2348 CommitTransaction();
2349 s->blockState = TBLOCK_DEFAULT;
2353 * We are completing a "BEGIN TRANSACTION" command, so we change
2354 * to the "transaction block in progress" state and return. (We
2355 * assume the BEGIN did nothing to the database, so we need no
2356 * CommandCounterIncrement.)
2359 s->blockState = TBLOCK_INPROGRESS;
2363 * This is the case when we have finished executing a command
2364 * someplace within a transaction block. We increment the command
2365 * counter and return.
2367 case TBLOCK_INPROGRESS:
2368 case TBLOCK_SUBINPROGRESS:
2369 CommandCounterIncrement();
2373 * We are completing a "COMMIT" command. Do it and return to the
2377 CommitTransaction();
2378 s->blockState = TBLOCK_DEFAULT;
2382 * Here we are in the middle of a transaction block but one of the
2383 * commands caused an abort so we do nothing but remain in the
2384 * abort state. Eventually we will get a ROLLBACK comand.
2387 case TBLOCK_SUBABORT:
2391 * Here we were in an aborted transaction block and we just got
2392 * the ROLLBACK command from the user, so clean up the
2393 * already-aborted transaction and return to the idle state.
2395 case TBLOCK_ABORT_END:
2396 CleanupTransaction();
2397 s->blockState = TBLOCK_DEFAULT;
2401 * Here we were in a perfectly good transaction block but the user
2402 * told us to ROLLBACK anyway. We have to abort the transaction
2403 * and then clean up.
2405 case TBLOCK_ABORT_PENDING:
2407 CleanupTransaction();
2408 s->blockState = TBLOCK_DEFAULT;
2412 * We are completing a "PREPARE TRANSACTION" command. Do it and
2413 * return to the idle state.
2415 case TBLOCK_PREPARE:
2416 PrepareTransaction();
2417 s->blockState = TBLOCK_DEFAULT;
2421 * We were just issued a SAVEPOINT inside a transaction block.
2422 * Start a subtransaction. (DefineSavepoint already did
2423 * PushTransaction, so as to have someplace to put the SUBBEGIN
2426 case TBLOCK_SUBBEGIN:
2427 StartSubTransaction();
2428 s->blockState = TBLOCK_SUBINPROGRESS;
2432 * We were issued a COMMIT or RELEASE command, so we end the
2433 * current subtransaction and return to the parent transaction.
2434 * The parent might be ended too, so repeat till we are all the
2435 * way out or find an INPROGRESS transaction.
2440 CommitSubTransaction();
2441 s = CurrentTransactionState; /* changed by pop */
2442 } while (s->blockState == TBLOCK_SUBEND);
2443 /* If we had a COMMIT command, finish off the main xact too */
2444 if (s->blockState == TBLOCK_END)
2446 Assert(s->parent == NULL);
2447 CommitTransaction();
2448 s->blockState = TBLOCK_DEFAULT;
2450 else if (s->blockState == TBLOCK_PREPARE)
2452 Assert(s->parent == NULL);
2453 PrepareTransaction();
2454 s->blockState = TBLOCK_DEFAULT;
2458 Assert(s->blockState == TBLOCK_INPROGRESS ||
2459 s->blockState == TBLOCK_SUBINPROGRESS);
2464 * The current already-failed subtransaction is ending due to a
2465 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2466 * examine the parent (which could be in any of several states).
2468 case TBLOCK_SUBABORT_END:
2469 CleanupSubTransaction();
2470 CommitTransactionCommand();
2474 * As above, but it's not dead yet, so abort first.
2476 case TBLOCK_SUBABORT_PENDING:
2477 AbortSubTransaction();
2478 CleanupSubTransaction();
2479 CommitTransactionCommand();
2483 * The current subtransaction is the target of a ROLLBACK TO
2484 * command. Abort and pop it, then start a new subtransaction
2485 * with the same name.
2487 case TBLOCK_SUBRESTART:
2492 /* save name and keep Cleanup from freeing it */
2495 savepointLevel = s->savepointLevel;
2497 AbortSubTransaction();
2498 CleanupSubTransaction();
2500 DefineSavepoint(NULL);
2501 s = CurrentTransactionState; /* changed by push */
2503 s->savepointLevel = savepointLevel;
2505 /* This is the same as TBLOCK_SUBBEGIN case */
2506 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2507 StartSubTransaction();
2508 s->blockState = TBLOCK_SUBINPROGRESS;
2513 * Same as above, but the subtransaction had already failed, so we
2514 * don't need AbortSubTransaction.
2516 case TBLOCK_SUBABORT_RESTART:
2521 /* save name and keep Cleanup from freeing it */
2524 savepointLevel = s->savepointLevel;
2526 CleanupSubTransaction();
2528 DefineSavepoint(NULL);
2529 s = CurrentTransactionState; /* changed by push */
2531 s->savepointLevel = savepointLevel;
2533 /* This is the same as TBLOCK_SUBBEGIN case */
2534 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2535 StartSubTransaction();
2536 s->blockState = TBLOCK_SUBINPROGRESS;
2543 * AbortCurrentTransaction
2546 AbortCurrentTransaction(void)
2548 TransactionState s = CurrentTransactionState;
2550 switch (s->blockState)
2552 case TBLOCK_DEFAULT:
2553 if (s->state == TRANS_DEFAULT)
2555 /* we are idle, so nothing to do */
2560 * We can get here after an error during transaction start
2561 * (state will be TRANS_START). Need to clean up the
2562 * incompletely started transaction. First, adjust the
2563 * low-level state to suppress warning message from
2566 if (s->state == TRANS_START)
2567 s->state = TRANS_INPROGRESS;
2569 CleanupTransaction();
2574 * if we aren't in a transaction block, we just do the basic abort
2575 * & cleanup transaction.
2577 case TBLOCK_STARTED:
2579 CleanupTransaction();
2580 s->blockState = TBLOCK_DEFAULT;
2584 * If we are in TBLOCK_BEGIN it means something screwed up right
2585 * after reading "BEGIN TRANSACTION". We assume that the user
2586 * will interpret the error as meaning the BEGIN failed to get him
2587 * into a transaction block, so we should abort and return to idle
2592 CleanupTransaction();
2593 s->blockState = TBLOCK_DEFAULT;
2597 * We are somewhere in a transaction block and we've gotten a
2598 * failure, so we abort the transaction and set up the persistent
2599 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
2601 case TBLOCK_INPROGRESS:
2603 s->blockState = TBLOCK_ABORT;
2604 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
2608 * Here, we failed while trying to COMMIT. Clean up the
2609 * transaction and return to idle state (we do not want to stay in
2614 CleanupTransaction();
2615 s->blockState = TBLOCK_DEFAULT;
2619 * Here, we are already in an aborted transaction state and are
2620 * waiting for a ROLLBACK, but for some reason we failed again! So
2621 * we just remain in the abort state.
2624 case TBLOCK_SUBABORT:
2628 * We are in a failed transaction and we got the ROLLBACK command.
2629 * We have already aborted, we just need to cleanup and go to idle
2632 case TBLOCK_ABORT_END:
2633 CleanupTransaction();
2634 s->blockState = TBLOCK_DEFAULT;
2638 * We are in a live transaction and we got a ROLLBACK command.
2639 * Abort, cleanup, go to idle state.
2641 case TBLOCK_ABORT_PENDING:
2643 CleanupTransaction();
2644 s->blockState = TBLOCK_DEFAULT;
2648 * Here, we failed while trying to PREPARE. Clean up the
2649 * transaction and return to idle state (we do not want to stay in
2652 case TBLOCK_PREPARE:
2654 CleanupTransaction();
2655 s->blockState = TBLOCK_DEFAULT;
2659 * We got an error inside a subtransaction. Abort just the
2660 * subtransaction, and go to the persistent SUBABORT state until
2663 case TBLOCK_SUBINPROGRESS:
2664 AbortSubTransaction();
2665 s->blockState = TBLOCK_SUBABORT;
2669 * If we failed while trying to create a subtransaction, clean up
2670 * the broken subtransaction and abort the parent. The same
2671 * applies if we get a failure while ending a subtransaction.
2673 case TBLOCK_SUBBEGIN:
2675 case TBLOCK_SUBABORT_PENDING:
2676 case TBLOCK_SUBRESTART:
2677 AbortSubTransaction();
2678 CleanupSubTransaction();
2679 AbortCurrentTransaction();
2683 * Same as above, except the Abort() was already done.
2685 case TBLOCK_SUBABORT_END:
2686 case TBLOCK_SUBABORT_RESTART:
2687 CleanupSubTransaction();
2688 AbortCurrentTransaction();
2694 * PreventTransactionChain
2696 * This routine is to be called by statements that must not run inside
2697 * a transaction block, typically because they have non-rollback-able
2698 * side effects or do internal commits.
2700 * If we have already started a transaction block, issue an error; also issue
2701 * an error if we appear to be running inside a user-defined function (which
2702 * could issue more commands and possibly cause a failure after the statement
2703 * completes). Subtransactions are verboten too.
2705 * isTopLevel: passed down from ProcessUtility to determine whether we are
2706 * inside a function or multi-query querystring. (We will always fail if
2707 * this is false, but it's convenient to centralize the check here instead of
2708 * making callers do it.)
2709 * stmtType: statement type name, for error messages.
2712 PreventTransactionChain(bool isTopLevel, const char *stmtType)
2715 * xact block already started?
2717 if (IsTransactionBlock())
2719 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2720 /* translator: %s represents an SQL statement name */
2721 errmsg("%s cannot run inside a transaction block",
2727 if (IsSubTransaction())
2729 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2730 /* translator: %s represents an SQL statement name */
2731 errmsg("%s cannot run inside a subtransaction",
2735 * inside a function call?
2739 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2740 /* translator: %s represents an SQL statement name */
2741 errmsg("%s cannot be executed from a function or multi-command string",
2744 /* If we got past IsTransactionBlock test, should be in default state */
2745 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2746 CurrentTransactionState->blockState != TBLOCK_STARTED)
2747 elog(FATAL, "cannot prevent transaction chain");
2752 * RequireTransactionChain
2754 * This routine is to be called by statements that must run inside
2755 * a transaction block, because they have no effects that persist past
2756 * transaction end (and so calling them outside a transaction block
2757 * is presumably an error). DECLARE CURSOR is an example.
2759 * If we appear to be running inside a user-defined function, we do not
2760 * issue an error, since the function could issue more commands that make
2761 * use of the current statement's results. Likewise subtransactions.
2762 * Thus this is an inverse for PreventTransactionChain.
2764 * isTopLevel: passed down from ProcessUtility to determine whether we are
2765 * inside a function.
2766 * stmtType: statement type name, for error messages.
2769 RequireTransactionChain(bool isTopLevel, const char *stmtType)
2772 * xact block already started?
2774 if (IsTransactionBlock())
2780 if (IsSubTransaction())
2784 * inside a function call?
2790 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2791 /* translator: %s represents an SQL statement name */
2792 errmsg("%s can only be used in transaction blocks",
2797 * IsInTransactionChain
2799 * This routine is for statements that need to behave differently inside
2800 * a transaction block than when running as single commands. ANALYZE is
2801 * currently the only example.
2803 * isTopLevel: passed down from ProcessUtility to determine whether we are
2804 * inside a function.
2807 IsInTransactionChain(bool isTopLevel)
2810 * Return true on same conditions that would make PreventTransactionChain
2813 if (IsTransactionBlock())
2816 if (IsSubTransaction())
2822 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2823 CurrentTransactionState->blockState != TBLOCK_STARTED)
2831 * Register or deregister callback functions for start- and end-of-xact
2834 * These functions are intended for use by dynamically loaded modules.
2835 * For built-in modules we generally just hardwire the appropriate calls
2836 * (mainly because it's easier to control the order that way, where needed).
2838 * At transaction end, the callback occurs post-commit or post-abort, so the
2839 * callback functions can only do noncritical cleanup.
2842 RegisterXactCallback(XactCallback callback, void *arg)
2844 XactCallbackItem *item;
2846 item = (XactCallbackItem *)
2847 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
2848 item->callback = callback;
2850 item->next = Xact_callbacks;
2851 Xact_callbacks = item;
2855 UnregisterXactCallback(XactCallback callback, void *arg)
2857 XactCallbackItem *item;
2858 XactCallbackItem *prev;
2861 for (item = Xact_callbacks; item; prev = item, item = item->next)
2863 if (item->callback == callback && item->arg == arg)
2866 prev->next = item->next;
2868 Xact_callbacks = item->next;
2876 CallXactCallbacks(XactEvent event)
2878 XactCallbackItem *item;
2880 for (item = Xact_callbacks; item; item = item->next)
2881 (*item->callback) (event, item->arg);
2886 * Register or deregister callback functions for start- and end-of-subxact
2889 * Pretty much same as above, but for subtransaction events.
2891 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
2892 * so the callback functions can only do noncritical cleanup. At
2893 * subtransaction start, the callback is called when the subtransaction has
2894 * finished initializing.
2897 RegisterSubXactCallback(SubXactCallback callback, void *arg)
2899 SubXactCallbackItem *item;
2901 item = (SubXactCallbackItem *)
2902 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
2903 item->callback = callback;
2905 item->next = SubXact_callbacks;
2906 SubXact_callbacks = item;
2910 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
2912 SubXactCallbackItem *item;
2913 SubXactCallbackItem *prev;
2916 for (item = SubXact_callbacks; item; prev = item, item = item->next)
2918 if (item->callback == callback && item->arg == arg)
2921 prev->next = item->next;
2923 SubXact_callbacks = item->next;
2931 CallSubXactCallbacks(SubXactEvent event,
2932 SubTransactionId mySubid,
2933 SubTransactionId parentSubid)
2935 SubXactCallbackItem *item;
2937 for (item = SubXact_callbacks; item; item = item->next)
2938 (*item->callback) (event, mySubid, parentSubid, item->arg);
2942 /* ----------------------------------------------------------------
2943 * transaction block support
2944 * ----------------------------------------------------------------
2948 * BeginTransactionBlock
2949 * This executes a BEGIN command.
2952 BeginTransactionBlock(void)
2954 TransactionState s = CurrentTransactionState;
2956 switch (s->blockState)
2959 * We are not inside a transaction block, so allow one to begin.
2961 case TBLOCK_STARTED:
2962 s->blockState = TBLOCK_BEGIN;
2966 * Already a transaction block in progress.
2968 case TBLOCK_INPROGRESS:
2969 case TBLOCK_SUBINPROGRESS:
2971 case TBLOCK_SUBABORT:
2973 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2974 errmsg("there is already a transaction in progress")));
2977 /* These cases are invalid. */
2978 case TBLOCK_DEFAULT:
2980 case TBLOCK_SUBBEGIN:
2983 case TBLOCK_ABORT_END:
2984 case TBLOCK_SUBABORT_END:
2985 case TBLOCK_ABORT_PENDING:
2986 case TBLOCK_SUBABORT_PENDING:
2987 case TBLOCK_SUBRESTART:
2988 case TBLOCK_SUBABORT_RESTART:
2989 case TBLOCK_PREPARE:
2990 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
2991 BlockStateAsString(s->blockState));
2997 * PrepareTransactionBlock
2998 * This executes a PREPARE command.
3000 * Since PREPARE may actually do a ROLLBACK, the result indicates what
3001 * happened: TRUE for PREPARE, FALSE for ROLLBACK.
3003 * Note that we don't actually do anything here except change blockState.
3004 * The real work will be done in the upcoming PrepareTransaction().
3005 * We do it this way because it's not convenient to change memory context,
3006 * resource owner, etc while executing inside a Portal.
3009 PrepareTransactionBlock(char *gid)
3014 /* Set up to commit the current transaction */
3015 result = EndTransactionBlock();
3017 /* If successful, change outer tblock state to PREPARE */
3020 s = CurrentTransactionState;
3022 while (s->parent != NULL)
3025 if (s->blockState == TBLOCK_END)
3027 /* Save GID where PrepareTransaction can find it again */
3028 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
3030 s->blockState = TBLOCK_PREPARE;
3035 * ignore case where we are not in a transaction;
3036 * EndTransactionBlock already issued a warning.
3038 Assert(s->blockState == TBLOCK_STARTED);
3039 /* Don't send back a PREPARE result tag... */
3048 * EndTransactionBlock
3049 * This executes a COMMIT command.
3051 * Since COMMIT may actually do a ROLLBACK, the result indicates what
3052 * happened: TRUE for COMMIT, FALSE for ROLLBACK.
3054 * Note that we don't actually do anything here except change blockState.
3055 * The real work will be done in the upcoming CommitTransactionCommand().
3056 * We do it this way because it's not convenient to change memory context,
3057 * resource owner, etc while executing inside a Portal.
3060 EndTransactionBlock(void)
3062 TransactionState s = CurrentTransactionState;
3063 bool result = false;
3065 switch (s->blockState)
3068 * We are in a transaction block, so tell CommitTransactionCommand
3071 case TBLOCK_INPROGRESS:
3072 s->blockState = TBLOCK_END;
3077 * We are in a failed transaction block. Tell
3078 * CommitTransactionCommand it's time to exit the block.
3081 s->blockState = TBLOCK_ABORT_END;
3085 * We are in a live subtransaction block. Set up to subcommit all
3086 * open subtransactions and then commit the main transaction.
3088 case TBLOCK_SUBINPROGRESS:
3089 while (s->parent != NULL)
3091 if (s->blockState == TBLOCK_SUBINPROGRESS)
3092 s->blockState = TBLOCK_SUBEND;
3094 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3095 BlockStateAsString(s->blockState));
3098 if (s->blockState == TBLOCK_INPROGRESS)
3099 s->blockState = TBLOCK_END;
3101 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3102 BlockStateAsString(s->blockState));
3107 * Here we are inside an aborted subtransaction. Treat the COMMIT
3108 * as ROLLBACK: set up to abort everything and exit the main
3111 case TBLOCK_SUBABORT:
3112 while (s->parent != NULL)
3114 if (s->blockState == TBLOCK_SUBINPROGRESS)
3115 s->blockState = TBLOCK_SUBABORT_PENDING;
3116 else if (s->blockState == TBLOCK_SUBABORT)
3117 s->blockState = TBLOCK_SUBABORT_END;
3119 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3120 BlockStateAsString(s->blockState));
3123 if (s->blockState == TBLOCK_INPROGRESS)
3124 s->blockState = TBLOCK_ABORT_PENDING;
3125 else if (s->blockState == TBLOCK_ABORT)
3126 s->blockState = TBLOCK_ABORT_END;
3128 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3129 BlockStateAsString(s->blockState));
3133 * The user issued COMMIT when not inside a transaction. Issue a
3134 * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
3135 * CommitTransactionCommand() will then close the transaction and
3136 * put us back into the default state.
3138 case TBLOCK_STARTED:
3140 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3141 errmsg("there is no transaction in progress")));
3145 /* These cases are invalid. */
3146 case TBLOCK_DEFAULT:
3148 case TBLOCK_SUBBEGIN:
3151 case TBLOCK_ABORT_END:
3152 case TBLOCK_SUBABORT_END:
3153 case TBLOCK_ABORT_PENDING:
3154 case TBLOCK_SUBABORT_PENDING:
3155 case TBLOCK_SUBRESTART:
3156 case TBLOCK_SUBABORT_RESTART:
3157 case TBLOCK_PREPARE:
3158 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3159 BlockStateAsString(s->blockState));
3167 * UserAbortTransactionBlock
3168 * This executes a ROLLBACK command.
3170 * As above, we don't actually do anything here except change blockState.
3173 UserAbortTransactionBlock(void)
3175 TransactionState s = CurrentTransactionState;
3177 switch (s->blockState)
3180 * We are inside a transaction block and we got a ROLLBACK command
3181 * from the user, so tell CommitTransactionCommand to abort and
3182 * exit the transaction block.
3184 case TBLOCK_INPROGRESS:
3185 s->blockState = TBLOCK_ABORT_PENDING;
3189 * We are inside a failed transaction block and we got a ROLLBACK
3190 * command from the user. Abort processing is already done, so
3191 * CommitTransactionCommand just has to cleanup and go back to
3195 s->blockState = TBLOCK_ABORT_END;
3199 * We are inside a subtransaction. Mark everything up to top
3200 * level as exitable.
3202 case TBLOCK_SUBINPROGRESS:
3203 case TBLOCK_SUBABORT:
3204 while (s->parent != NULL)
3206 if (s->blockState == TBLOCK_SUBINPROGRESS)
3207 s->blockState = TBLOCK_SUBABORT_PENDING;
3208 else if (s->blockState == TBLOCK_SUBABORT)
3209 s->blockState = TBLOCK_SUBABORT_END;
3211 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3212 BlockStateAsString(s->blockState));
3215 if (s->blockState == TBLOCK_INPROGRESS)
3216 s->blockState = TBLOCK_ABORT_PENDING;
3217 else if (s->blockState == TBLOCK_ABORT)
3218 s->blockState = TBLOCK_ABORT_END;
3220 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3221 BlockStateAsString(s->blockState));
3225 * The user issued ABORT when not inside a transaction. Issue a
3226 * WARNING and go to abort state. The upcoming call to
3227 * CommitTransactionCommand() will then put us back into the
3230 case TBLOCK_STARTED:
3232 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3233 errmsg("there is no transaction in progress")));
3234 s->blockState = TBLOCK_ABORT_PENDING;
3237 /* These cases are invalid. */
3238 case TBLOCK_DEFAULT:
3240 case TBLOCK_SUBBEGIN:
3243 case TBLOCK_ABORT_END:
3244 case TBLOCK_SUBABORT_END:
3245 case TBLOCK_ABORT_PENDING:
3246 case TBLOCK_SUBABORT_PENDING:
3247 case TBLOCK_SUBRESTART:
3248 case TBLOCK_SUBABORT_RESTART:
3249 case TBLOCK_PREPARE:
3250 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3251 BlockStateAsString(s->blockState));
3258 * This executes a SAVEPOINT command.
3261 DefineSavepoint(char *name)
3263 TransactionState s = CurrentTransactionState;
3265 switch (s->blockState)
3267 case TBLOCK_INPROGRESS:
3268 case TBLOCK_SUBINPROGRESS:
3269 /* Normal subtransaction start */
3271 s = CurrentTransactionState; /* changed by push */
3274 * Savepoint names, like the TransactionState block itself, live
3275 * in TopTransactionContext.
3278 s->name = MemoryContextStrdup(TopTransactionContext, name);
3281 /* These cases are invalid. */
3282 case TBLOCK_DEFAULT:
3283 case TBLOCK_STARTED:
3285 case TBLOCK_SUBBEGIN:
3289 case TBLOCK_SUBABORT:
3290 case TBLOCK_ABORT_END:
3291 case TBLOCK_SUBABORT_END:
3292 case TBLOCK_ABORT_PENDING:
3293 case TBLOCK_SUBABORT_PENDING:
3294 case TBLOCK_SUBRESTART:
3295 case TBLOCK_SUBABORT_RESTART:
3296 case TBLOCK_PREPARE:
3297 elog(FATAL, "DefineSavepoint: unexpected state %s",
3298 BlockStateAsString(s->blockState));
3305 * This executes a RELEASE command.
3307 * As above, we don't actually do anything here except change blockState.
3310 ReleaseSavepoint(List *options)
3312 TransactionState s = CurrentTransactionState;
3313 TransactionState target,
3318 switch (s->blockState)
3321 * We can't rollback to a savepoint if there is no savepoint
3324 case TBLOCK_INPROGRESS:
3326 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3327 errmsg("no such savepoint")));
3331 * We are in a non-aborted subtransaction. This is the only valid
3334 case TBLOCK_SUBINPROGRESS:
3337 /* These cases are invalid. */
3338 case TBLOCK_DEFAULT:
3339 case TBLOCK_STARTED:
3341 case TBLOCK_SUBBEGIN:
3345 case TBLOCK_SUBABORT:
3346 case TBLOCK_ABORT_END:
3347 case TBLOCK_SUBABORT_END:
3348 case TBLOCK_ABORT_PENDING:
3349 case TBLOCK_SUBABORT_PENDING:
3350 case TBLOCK_SUBRESTART:
3351 case TBLOCK_SUBABORT_RESTART:
3352 case TBLOCK_PREPARE:
3353 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3354 BlockStateAsString(s->blockState));
3358 foreach(cell, options)
3360 DefElem *elem = lfirst(cell);
3362 if (strcmp(elem->defname, "savepoint_name") == 0)
3363 name = strVal(elem->arg);
3366 Assert(PointerIsValid(name));
3368 for (target = s; PointerIsValid(target); target = target->parent)
3370 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3374 if (!PointerIsValid(target))
3376 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3377 errmsg("no such savepoint")));
3379 /* disallow crossing savepoint level boundaries */
3380 if (target->savepointLevel != s->savepointLevel)
3382 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3383 errmsg("no such savepoint")));
3386 * Mark "commit pending" all subtransactions up to the target
3387 * subtransaction. The actual commits will happen when control gets to
3388 * CommitTransactionCommand.
3390 xact = CurrentTransactionState;
3393 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3394 xact->blockState = TBLOCK_SUBEND;
3397 xact = xact->parent;
3398 Assert(PointerIsValid(xact));
3403 * RollbackToSavepoint
3404 * This executes a ROLLBACK TO <savepoint> command.
3406 * As above, we don't actually do anything here except change blockState.
3409 RollbackToSavepoint(List *options)
3411 TransactionState s = CurrentTransactionState;
3412 TransactionState target,
3417 switch (s->blockState)
3420 * We can't rollback to a savepoint if there is no savepoint
3423 case TBLOCK_INPROGRESS:
3426 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3427 errmsg("no such savepoint")));
3431 * There is at least one savepoint, so proceed.
3433 case TBLOCK_SUBINPROGRESS:
3434 case TBLOCK_SUBABORT:
3437 /* These cases are invalid. */
3438 case TBLOCK_DEFAULT:
3439 case TBLOCK_STARTED:
3441 case TBLOCK_SUBBEGIN:
3444 case TBLOCK_ABORT_END:
3445 case TBLOCK_SUBABORT_END:
3446 case TBLOCK_ABORT_PENDING:
3447 case TBLOCK_SUBABORT_PENDING:
3448 case TBLOCK_SUBRESTART:
3449 case TBLOCK_SUBABORT_RESTART:
3450 case TBLOCK_PREPARE:
3451 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3452 BlockStateAsString(s->blockState));
3456 foreach(cell, options)
3458 DefElem *elem = lfirst(cell);
3460 if (strcmp(elem->defname, "savepoint_name") == 0)
3461 name = strVal(elem->arg);
3464 Assert(PointerIsValid(name));
3466 for (target = s; PointerIsValid(target); target = target->parent)
3468 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3472 if (!PointerIsValid(target))
3474 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3475 errmsg("no such savepoint")));
3477 /* disallow crossing savepoint level boundaries */
3478 if (target->savepointLevel != s->savepointLevel)
3480 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3481 errmsg("no such savepoint")));
3484 * Mark "abort pending" all subtransactions up to the target
3485 * subtransaction. The actual aborts will happen when control gets to
3486 * CommitTransactionCommand.
3488 xact = CurrentTransactionState;
3493 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3494 xact->blockState = TBLOCK_SUBABORT_PENDING;
3495 else if (xact->blockState == TBLOCK_SUBABORT)
3496 xact->blockState = TBLOCK_SUBABORT_END;
3498 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3499 BlockStateAsString(xact->blockState));
3500 xact = xact->parent;
3501 Assert(PointerIsValid(xact));
3504 /* And mark the target as "restart pending" */
3505 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3506 xact->blockState = TBLOCK_SUBRESTART;
3507 else if (xact->blockState == TBLOCK_SUBABORT)
3508 xact->blockState = TBLOCK_SUBABORT_RESTART;
3510 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3511 BlockStateAsString(xact->blockState));
3515 * BeginInternalSubTransaction
3516 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
3517 * TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
3518 * used in functions that might be called when not inside a BEGIN block
3519 * or when running deferred triggers at COMMIT/PREPARE time. Also, it
3520 * automatically does CommitTransactionCommand/StartTransactionCommand
3521 * instead of expecting the caller to do it.
3524 BeginInternalSubTransaction(char *name)
3526 TransactionState s = CurrentTransactionState;
3528 switch (s->blockState)
3530 case TBLOCK_STARTED:
3531 case TBLOCK_INPROGRESS:
3533 case TBLOCK_PREPARE:
3534 case TBLOCK_SUBINPROGRESS:
3535 /* Normal subtransaction start */
3537 s = CurrentTransactionState; /* changed by push */
3540 * Savepoint names, like the TransactionState block itself, live
3541 * in TopTransactionContext.
3544 s->name = MemoryContextStrdup(TopTransactionContext, name);
3547 /* These cases are invalid. */
3548 case TBLOCK_DEFAULT:
3550 case TBLOCK_SUBBEGIN:
3553 case TBLOCK_SUBABORT:
3554 case TBLOCK_ABORT_END:
3555 case TBLOCK_SUBABORT_END:
3556 case TBLOCK_ABORT_PENDING:
3557 case TBLOCK_SUBABORT_PENDING:
3558 case TBLOCK_SUBRESTART:
3559 case TBLOCK_SUBABORT_RESTART:
3560 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
3561 BlockStateAsString(s->blockState));
3565 CommitTransactionCommand();
3566 StartTransactionCommand();
3570 * ReleaseCurrentSubTransaction
3572 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
3573 * savepoint name (if any).
3574 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3577 ReleaseCurrentSubTransaction(void)
3579 TransactionState s = CurrentTransactionState;
3581 if (s->blockState != TBLOCK_SUBINPROGRESS)
3582 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
3583 BlockStateAsString(s->blockState));
3584 Assert(s->state == TRANS_INPROGRESS);
3585 MemoryContextSwitchTo(CurTransactionContext);
3586 CommitSubTransaction();
3587 s = CurrentTransactionState; /* changed by pop */
3588 Assert(s->state == TRANS_INPROGRESS);
3592 * RollbackAndReleaseCurrentSubTransaction
3594 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
3595 * of its savepoint name (if any).
3596 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3599 RollbackAndReleaseCurrentSubTransaction(void)
3601 TransactionState s = CurrentTransactionState;
3603 switch (s->blockState)
3605 /* Must be in a subtransaction */
3606 case TBLOCK_SUBINPROGRESS:
3607 case TBLOCK_SUBABORT:
3610 /* These cases are invalid. */
3611 case TBLOCK_DEFAULT:
3612 case TBLOCK_STARTED:
3614 case TBLOCK_SUBBEGIN:
3615 case TBLOCK_INPROGRESS:
3619 case TBLOCK_ABORT_END:
3620 case TBLOCK_SUBABORT_END:
3621 case TBLOCK_ABORT_PENDING:
3622 case TBLOCK_SUBABORT_PENDING:
3623 case TBLOCK_SUBRESTART:
3624 case TBLOCK_SUBABORT_RESTART:
3625 case TBLOCK_PREPARE:
3626 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
3627 BlockStateAsString(s->blockState));
3632 * Abort the current subtransaction, if needed.
3634 if (s->blockState == TBLOCK_SUBINPROGRESS)
3635 AbortSubTransaction();
3637 /* And clean it up, too */
3638 CleanupSubTransaction();
3640 s = CurrentTransactionState; /* changed by pop */
3641 AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
3642 s->blockState == TBLOCK_INPROGRESS ||
3643 s->blockState == TBLOCK_STARTED);
3647 * AbortOutOfAnyTransaction
3649 * This routine is provided for error recovery purposes. It aborts any
3650 * active transaction or transaction block, leaving the system in a known
3654 AbortOutOfAnyTransaction(void)
3656 TransactionState s = CurrentTransactionState;
3659 * Get out of any transaction or nested transaction
3663 switch (s->blockState)
3665 case TBLOCK_DEFAULT:
3666 /* Not in a transaction, do nothing */
3668 case TBLOCK_STARTED:
3670 case TBLOCK_INPROGRESS:
3672 case TBLOCK_ABORT_PENDING:
3673 case TBLOCK_PREPARE:
3674 /* In a transaction, so clean up */
3676 CleanupTransaction();
3677 s->blockState = TBLOCK_DEFAULT;
3680 case TBLOCK_ABORT_END:
3681 /* AbortTransaction already done, still need Cleanup */
3682 CleanupTransaction();
3683 s->blockState = TBLOCK_DEFAULT;
3687 * In a subtransaction, so clean it up and abort parent too
3689 case TBLOCK_SUBBEGIN:
3690 case TBLOCK_SUBINPROGRESS:
3692 case TBLOCK_SUBABORT_PENDING:
3693 case TBLOCK_SUBRESTART:
3694 AbortSubTransaction();
3695 CleanupSubTransaction();
3696 s = CurrentTransactionState; /* changed by pop */
3699 case TBLOCK_SUBABORT:
3700 case TBLOCK_SUBABORT_END:
3701 case TBLOCK_SUBABORT_RESTART:
3702 /* As above, but AbortSubTransaction already done */
3703 CleanupSubTransaction();
3704 s = CurrentTransactionState; /* changed by pop */
3707 } while (s->blockState != TBLOCK_DEFAULT);
3709 /* Should be out of all subxacts now */
3710 Assert(s->parent == NULL);
3714 * IsTransactionBlock --- are we within a transaction block?
3717 IsTransactionBlock(void)
3719 TransactionState s = CurrentTransactionState;
3721 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
3728 * IsTransactionOrTransactionBlock --- are we within either a transaction
3729 * or a transaction block? (The backend is only really "idle" when this
3732 * This should match up with IsTransactionBlock and IsTransactionState.
3735 IsTransactionOrTransactionBlock(void)
3737 TransactionState s = CurrentTransactionState;
3739 if (s->blockState == TBLOCK_DEFAULT)
3746 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
3749 TransactionBlockStatusCode(void)
3751 TransactionState s = CurrentTransactionState;
3753 switch (s->blockState)
3755 case TBLOCK_DEFAULT:
3756 case TBLOCK_STARTED:
3757 return 'I'; /* idle --- not in transaction */
3759 case TBLOCK_SUBBEGIN:
3760 case TBLOCK_INPROGRESS:
3761 case TBLOCK_SUBINPROGRESS:
3764 case TBLOCK_PREPARE:
3765 return 'T'; /* in transaction */
3767 case TBLOCK_SUBABORT:
3768 case TBLOCK_ABORT_END:
3769 case TBLOCK_SUBABORT_END:
3770 case TBLOCK_ABORT_PENDING:
3771 case TBLOCK_SUBABORT_PENDING:
3772 case TBLOCK_SUBRESTART:
3773 case TBLOCK_SUBABORT_RESTART:
3774 return 'E'; /* in failed transaction */
3777 /* should never get here */
3778 elog(FATAL, "invalid transaction block state: %s",
3779 BlockStateAsString(s->blockState));
3780 return 0; /* keep compiler quiet */
3787 IsSubTransaction(void)
3789 TransactionState s = CurrentTransactionState;
3791 if (s->nestingLevel >= 2)
3798 * StartSubTransaction
3800 * If you're wondering why this is separate from PushTransaction: it's because
3801 * we can't conveniently do this stuff right inside DefineSavepoint. The
3802 * SAVEPOINT utility command will be executed inside a Portal, and if we
3803 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
3804 * the Portal will undo those settings. So we make DefineSavepoint just
3805 * push a dummy transaction block, and when control returns to the main
3806 * idle loop, CommitTransactionCommand will be called, and we'll come here
3807 * to finish starting the subtransaction.
3810 StartSubTransaction(void)
3812 TransactionState s = CurrentTransactionState;
3814 if (s->state != TRANS_DEFAULT)
3815 elog(WARNING, "StartSubTransaction while in %s state",
3816 TransStateAsString(s->state));
3818 s->state = TRANS_START;
3821 * Initialize subsystems for new subtransaction
3823 * must initialize resource-management stuff first
3825 AtSubStart_Memory();
3826 AtSubStart_ResourceOwner();
3828 AtSubStart_Notify();
3829 AfterTriggerBeginSubXact();
3831 s->state = TRANS_INPROGRESS;
3834 * Call start-of-subxact callbacks
3836 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
3837 s->parent->subTransactionId);
3839 ShowTransactionState("StartSubTransaction");
3843 * CommitSubTransaction
3845 * The caller has to make sure to always reassign CurrentTransactionState
3846 * if it has a local pointer to it after calling this function.
3849 CommitSubTransaction(void)
3851 TransactionState s = CurrentTransactionState;
3853 ShowTransactionState("CommitSubTransaction");
3855 if (s->state != TRANS_INPROGRESS)
3856 elog(WARNING, "CommitSubTransaction while in %s state",
3857 TransStateAsString(s->state));
3859 /* Pre-commit processing goes here -- nothing to do at the moment */
3861 s->state = TRANS_COMMIT;
3863 /* Must CCI to ensure commands of subtransaction are seen as done */
3864 CommandCounterIncrement();
3867 * Prior to 8.4 we marked subcommit in clog at this point. We now only
3868 * perform that step, if required, as part of the atomic update of the
3869 * whole transaction tree at top level commit or abort.
3872 /* Post-commit cleanup */
3873 if (TransactionIdIsValid(s->transactionId))
3874 AtSubCommit_childXids();
3875 AfterTriggerEndSubXact(true);
3876 AtSubCommit_Portals(s->subTransactionId,
3877 s->parent->subTransactionId,
3878 s->parent->curTransactionOwner);
3879 AtEOSubXact_LargeObject(true, s->subTransactionId,
3880 s->parent->subTransactionId);
3881 AtSubCommit_Notify();
3883 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
3884 s->parent->subTransactionId);
3886 ResourceOwnerRelease(s->curTransactionOwner,
3887 RESOURCE_RELEASE_BEFORE_LOCKS,
3889 AtEOSubXact_RelationCache(true, s->subTransactionId,
3890 s->parent->subTransactionId);
3891 AtEOSubXact_Inval(true);
3895 * The only lock we actually release here is the subtransaction XID lock.
3896 * The rest just get transferred to the parent resource owner.
3898 CurrentResourceOwner = s->curTransactionOwner;
3899 if (TransactionIdIsValid(s->transactionId))
3900 XactLockTableDelete(s->transactionId);
3902 ResourceOwnerRelease(s->curTransactionOwner,
3903 RESOURCE_RELEASE_LOCKS,
3905 ResourceOwnerRelease(s->curTransactionOwner,
3906 RESOURCE_RELEASE_AFTER_LOCKS,
3909 AtEOXact_GUC(true, s->gucNestLevel);
3910 AtEOSubXact_SPI(true, s->subTransactionId);
3911 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
3912 s->parent->subTransactionId);
3913 AtEOSubXact_Namespace(true, s->subTransactionId,
3914 s->parent->subTransactionId);
3915 AtEOSubXact_Files(true, s->subTransactionId,
3916 s->parent->subTransactionId);
3917 AtEOSubXact_HashTables(true, s->nestingLevel);
3918 AtEOSubXact_PgStat(true, s->nestingLevel);
3919 AtSubCommit_Snapshot(s->nestingLevel);
3922 * We need to restore the upper transaction's read-only state, in case the
3923 * upper is read-write while the child is read-only; GUC will incorrectly
3924 * think it should leave the child state in place.
3926 XactReadOnly = s->prevXactReadOnly;
3928 CurrentResourceOwner = s->parent->curTransactionOwner;
3929 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3930 ResourceOwnerDelete(s->curTransactionOwner);
3931 s->curTransactionOwner = NULL;
3933 AtSubCommit_Memory();
3935 s->state = TRANS_DEFAULT;
3941 * AbortSubTransaction
3944 AbortSubTransaction(void)
3946 TransactionState s = CurrentTransactionState;
3948 /* Prevent cancel/die interrupt while cleaning up */
3951 /* Make sure we have a valid memory context and resource owner */
3952 AtSubAbort_Memory();
3953 AtSubAbort_ResourceOwner();
3956 * Release any LW locks we might be holding as quickly as possible.
3957 * (Regular locks, however, must be held till we finish aborting.)
3958 * Releasing LW locks is critical since we might try to grab them again
3959 * while cleaning up!
3961 * FIXME This may be incorrect --- Are there some locks we should keep?
3962 * Buffer locks, for example? I don't think so but I'm not sure.
3972 * check the current transaction state
3974 ShowTransactionState("AbortSubTransaction");
3976 if (s->state != TRANS_INPROGRESS)
3977 elog(WARNING, "AbortSubTransaction while in %s state",
3978 TransStateAsString(s->state));
3980 s->state = TRANS_ABORT;
3983 * Reset user ID which might have been changed transiently. (See notes in
3984 * AbortTransaction.)
3986 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
3989 * We can skip all this stuff if the subxact failed before creating a
3992 if (s->curTransactionOwner)
3994 AfterTriggerEndSubXact(false);
3995 AtSubAbort_Portals(s->subTransactionId,
3996 s->parent->subTransactionId,
3997 s->parent->curTransactionOwner);
3998 AtEOSubXact_LargeObject(false, s->subTransactionId,
3999 s->parent->subTransactionId);
4000 AtSubAbort_Notify();
4002 /* Advertise the fact that we aborted in pg_clog. */
4003 (void) RecordTransactionAbort(true);
4005 /* Post-abort cleanup */
4006 if (TransactionIdIsValid(s->transactionId))
4007 AtSubAbort_childXids();
4009 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
4010 s->parent->subTransactionId);
4012 ResourceOwnerRelease(s->curTransactionOwner,
4013 RESOURCE_RELEASE_BEFORE_LOCKS,
4015 AtEOSubXact_RelationCache(false, s->subTransactionId,
4016 s->parent->subTransactionId);
4017 AtEOSubXact_Inval(false);
4019 ResourceOwnerRelease(s->curTransactionOwner,
4020 RESOURCE_RELEASE_LOCKS,
4022 ResourceOwnerRelease(s->curTransactionOwner,
4023 RESOURCE_RELEASE_AFTER_LOCKS,
4026 AtEOXact_GUC(false, s->gucNestLevel);
4027 AtEOSubXact_SPI(false, s->subTransactionId);
4028 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
4029 s->parent->subTransactionId);
4030 AtEOSubXact_Namespace(false, s->subTransactionId,
4031 s->parent->subTransactionId);
4032 AtEOSubXact_Files(false, s->subTransactionId,
4033 s->parent->subTransactionId);
4034 AtEOSubXact_HashTables(false, s->nestingLevel);
4035 AtEOSubXact_PgStat(false, s->nestingLevel);
4036 AtSubAbort_Snapshot(s->nestingLevel);
4040 * Restore the upper transaction's read-only state, too. This should be
4041 * redundant with GUC's cleanup but we may as well do it for consistency
4042 * with the commit case.
4044 XactReadOnly = s->prevXactReadOnly;
4046 RESUME_INTERRUPTS();
4050 * CleanupSubTransaction
4052 * The caller has to make sure to always reassign CurrentTransactionState
4053 * if it has a local pointer to it after calling this function.
4056 CleanupSubTransaction(void)
4058 TransactionState s = CurrentTransactionState;
4060 ShowTransactionState("CleanupSubTransaction");
4062 if (s->state != TRANS_ABORT)
4063 elog(WARNING, "CleanupSubTransaction while in %s state",
4064 TransStateAsString(s->state));
4066 AtSubCleanup_Portals(s->subTransactionId);
4068 CurrentResourceOwner = s->parent->curTransactionOwner;
4069 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4070 if (s->curTransactionOwner)
4071 ResourceOwnerDelete(s->curTransactionOwner);
4072 s->curTransactionOwner = NULL;
4074 AtSubCleanup_Memory();
4076 s->state = TRANS_DEFAULT;
4083 * Create transaction state stack entry for a subtransaction
4085 * The caller has to make sure to always reassign CurrentTransactionState
4086 * if it has a local pointer to it after calling this function.
4089 PushTransaction(void)
4091 TransactionState p = CurrentTransactionState;
4095 * We keep subtransaction state nodes in TopTransactionContext.
4097 s = (TransactionState)
4098 MemoryContextAllocZero(TopTransactionContext,
4099 sizeof(TransactionStateData));
4102 * Assign a subtransaction ID, watching out for counter wraparound.
4104 currentSubTransactionId += 1;
4105 if (currentSubTransactionId == InvalidSubTransactionId)
4107 currentSubTransactionId -= 1;
4110 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
4111 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
4115 * We can now stack a minimally valid subtransaction without fear of
4118 s->transactionId = InvalidTransactionId; /* until assigned */
4119 s->subTransactionId = currentSubTransactionId;
4121 s->nestingLevel = p->nestingLevel + 1;
4122 s->gucNestLevel = NewGUCNestLevel();
4123 s->savepointLevel = p->savepointLevel;
4124 s->state = TRANS_DEFAULT;
4125 s->blockState = TBLOCK_SUBBEGIN;
4126 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
4127 s->prevXactReadOnly = XactReadOnly;
4129 CurrentTransactionState = s;
4132 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
4133 * with the subtransaction from here on out; in particular they should not
4134 * assume that it necessarily has a transaction context, resource owner,
4141 * Pop back to parent transaction state
4143 * The caller has to make sure to always reassign CurrentTransactionState
4144 * if it has a local pointer to it after calling this function.
4147 PopTransaction(void)
4149 TransactionState s = CurrentTransactionState;
4151 if (s->state != TRANS_DEFAULT)
4152 elog(WARNING, "PopTransaction while in %s state",
4153 TransStateAsString(s->state));
4155 if (s->parent == NULL)
4156 elog(FATAL, "PopTransaction with no parent");
4158 CurrentTransactionState = s->parent;
4160 /* Let's just make sure CurTransactionContext is good */
4161 CurTransactionContext = s->parent->curTransactionContext;
4162 MemoryContextSwitchTo(CurTransactionContext);
4164 /* Ditto for ResourceOwner links */
4165 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4166 CurrentResourceOwner = s->parent->curTransactionOwner;
4168 /* Free the old child structure */
4175 * ShowTransactionState
4179 ShowTransactionState(const char *str)
4181 /* skip work if message will definitely not be printed */
4182 if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
4184 elog(DEBUG3, "%s", str);
4185 ShowTransactionStateRec(CurrentTransactionState);
4190 * ShowTransactionStateRec
4191 * Recursive subroutine for ShowTransactionState
4194 ShowTransactionStateRec(TransactionState s)
4198 initStringInfo(&buf);
4200 if (s->nChildXids > 0)
4204 appendStringInfo(&buf, "%u", s->childXids[0]);
4205 for (i = 1; i < s->nChildXids; i++)
4206 appendStringInfo(&buf, " %u", s->childXids[i]);
4210 ShowTransactionStateRec(s->parent);
4212 /* use ereport to suppress computation if msg will not be printed */
4214 (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u%s, nestlvl: %d, children: %s",
4215 PointerIsValid(s->name) ? s->name : "unnamed",
4216 BlockStateAsString(s->blockState),
4217 TransStateAsString(s->state),
4218 (unsigned int) s->transactionId,
4219 (unsigned int) s->subTransactionId,
4220 (unsigned int) currentCommandId,
4221 currentCommandIdUsed ? " (used)" : "",
4222 s->nestingLevel, buf.data)));
4228 * BlockStateAsString
4232 BlockStateAsString(TBlockState blockState)
4236 case TBLOCK_DEFAULT:
4238 case TBLOCK_STARTED:
4242 case TBLOCK_INPROGRESS:
4243 return "INPROGRESS";
4248 case TBLOCK_ABORT_END:
4250 case TBLOCK_ABORT_PENDING:
4251 return "ABORT PEND";
4252 case TBLOCK_PREPARE:
4254 case TBLOCK_SUBBEGIN:
4256 case TBLOCK_SUBINPROGRESS:
4257 return "SUB INPROGRS";
4260 case TBLOCK_SUBABORT:
4262 case TBLOCK_SUBABORT_END:
4263 return "SUB ABORT END";
4264 case TBLOCK_SUBABORT_PENDING:
4265 return "SUB ABRT PEND";
4266 case TBLOCK_SUBRESTART:
4267 return "SUB RESTART";
4268 case TBLOCK_SUBABORT_RESTART:
4269 return "SUB AB RESTRT";
4271 return "UNRECOGNIZED";
4275 * TransStateAsString
4279 TransStateAsString(TransState state)
4287 case TRANS_INPROGRESS:
4296 return "UNRECOGNIZED";
4300 * xactGetCommittedChildren
4302 * Gets the list of committed children of the current transaction. The return
4303 * value is the number of child transactions. *ptr is set to point to an
4304 * array of TransactionIds. The array is allocated in TopTransactionContext;
4305 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
4306 * If there are no subxacts, *ptr is set to NULL.
4309 xactGetCommittedChildren(TransactionId **ptr)
4311 TransactionState s = CurrentTransactionState;
4313 if (s->nChildXids == 0)
4316 *ptr = s->childXids;
4318 return s->nChildXids;
4322 * XLOG support routines
4326 * Before 8.5 this was a fairly short function, but now it performs many
4327 * actions for which the order of execution is critical.
4330 xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid, XLogRecPtr lsn)
4332 TransactionId *sub_xids;
4333 SharedInvalidationMessage *inval_msgs;
4334 TransactionId max_xid;
4337 /* subxid array follows relfilenodes */
4338 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4339 /* invalidation messages array follows subxids */
4340 inval_msgs = (SharedInvalidationMessage *) &(sub_xids[xlrec->nsubxacts]);
4342 max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
4345 * Make sure nextXid is beyond any XID mentioned in the record.
4347 * We don't expect anyone else to modify nextXid, hence we
4348 * don't need to hold a lock while checking this. We still acquire
4349 * the lock to modify it, though.
4351 if (TransactionIdFollowsOrEquals(max_xid,
4352 ShmemVariableCache->nextXid))
4354 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4355 ShmemVariableCache->nextXid = max_xid;
4356 TransactionIdAdvance(ShmemVariableCache->nextXid);
4357 LWLockRelease(XidGenLock);
4360 if (!InHotStandby || XactCompletionVacuumFull(xlrec))
4363 * Mark the transaction committed in pg_clog.
4365 * If InHotStandby and this is the first commit of a VACUUM FULL INPLACE
4366 * we perform only the actual commit to clog. Strangely, there are two
4367 * commits that share the same xid for every VFI, so we need to skip
4368 * some steps for the first commit. It's OK to repeat the clog update
4369 * when we see the second commit on a VFI.
4371 TransactionIdCommitTree(xid, xlrec->nsubxacts, sub_xids);
4376 * If a transaction completion record arrives that has as-yet unobserved
4377 * subtransactions then this will not have been fully handled by the call
4378 * to RecordKnownAssignedTransactionIds() in the main recovery loop in
4379 * xlog.c. So we need to do bookkeeping again to cover that case. This is
4380 * confusing and it is easy to think this call is irrelevant, which has
4381 * happened three times in development already. Leave it in.
4383 RecordKnownAssignedTransactionIds(max_xid);
4386 * Mark the transaction committed in pg_clog. We use async commit
4387 * protocol during recovery to provide information on database
4388 * consistency for when users try to set hint bits. It is important
4389 * that we do not set hint bits until the minRecoveryPoint is past
4390 * this commit record. This ensures that if we crash we don't see
4391 * hint bits set on changes made by transactions that haven't yet
4392 * recovered. It's unlikely but it's good to be safe.
4394 TransactionIdAsyncCommitTree(xid, xlrec->nsubxacts, sub_xids, lsn);
4397 * We must mark clog before we update the ProcArray.
4399 ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids);
4402 * Send any cache invalidations attached to the commit. We must
4403 * maintain the same order of invalidation then release locks
4406 ProcessCommittedInvalidationMessages(inval_msgs, xlrec->nmsgs,
4407 XactCompletionRelcacheInitFileInval(xlrec));
4410 * Release locks, if any. We do this for both two phase and normal
4411 * one phase transactions. In effect we are ignoring the prepare
4412 * phase and just going straight to lock release.
4414 StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
4417 /* Make sure files supposed to be dropped are dropped */
4418 for (i = 0; i < xlrec->nrels; i++)
4420 SMgrRelation srel = smgropen(xlrec->xnodes[i]);
4423 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4425 if (smgrexists(srel, fork))
4427 XLogDropRelation(xlrec->xnodes[i], fork);
4428 smgrdounlink(srel, fork, false, true);
4435 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit() in
4436 * normal operation. For example, in DROP DATABASE, we delete all the files
4437 * belonging to the database, and then commit the transaction. If we crash
4438 * after all the files have been deleted but before the commit, you have an
4439 * entry in pg_database without any files. To minimize the window for that,
4440 * we use ForceSyncCommit() to rush the commit record to disk as quick as
4441 * possible. We have the same window during recovery, and forcing an
4442 * XLogFlush() (which updates minRecoveryPoint during recovery) helps
4443 * to reduce that problem window, for any user that requested ForceSyncCommit().
4445 if (XactCompletionForceSyncCommit(xlrec))
4450 * Be careful with the order of execution, as with xact_redo_commit().
4451 * The two functions are similar but differ in key places.
4453 * Note also that an abort can be for a subtransaction and its children,
4454 * not just for a top level abort. That means we have to consider
4455 * topxid != xid, whereas in commit we would find topxid == xid always
4456 * because subtransaction commit is never WAL logged.
4459 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
4461 TransactionId *sub_xids;
4462 TransactionId max_xid;
4465 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4466 max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
4468 /* Make sure nextXid is beyond any XID mentioned in the record */
4469 /* We don't expect anyone else to modify nextXid, hence we
4470 * don't need to hold a lock while checking this. We still acquire
4471 * the lock to modify it, though.
4473 if (TransactionIdFollowsOrEquals(max_xid,
4474 ShmemVariableCache->nextXid))
4476 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4477 ShmemVariableCache->nextXid = max_xid;
4478 TransactionIdAdvance(ShmemVariableCache->nextXid);
4479 LWLockRelease(XidGenLock);
4485 * If a transaction completion record arrives that has as-yet unobserved
4486 * subtransactions then this will not have been fully handled by the call
4487 * to RecordKnownAssignedTransactionIds() in the main recovery loop in
4488 * xlog.c. So we need to do bookkeeping again to cover that case. This is
4489 * confusing and it is easy to think this call is irrelevant, which has
4490 * happened three times in development already. Leave it in.
4492 RecordKnownAssignedTransactionIds(max_xid);
4495 /* Mark the transaction aborted in pg_clog, no need for async stuff */
4496 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4501 * We must mark clog before we update the ProcArray.
4503 ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids);
4506 * There are no flat files that need updating, nor invalidation
4507 * messages to send or undo.
4511 * Release locks, if any. There are no invalidations to send.
4513 StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
4516 /* Make sure files supposed to be dropped are dropped */
4517 for (i = 0; i < xlrec->nrels; i++)
4519 SMgrRelation srel = smgropen(xlrec->xnodes[i]);
4522 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4524 if (smgrexists(srel, fork))
4526 XLogDropRelation(xlrec->xnodes[i], fork);
4527 smgrdounlink(srel, fork, false, true);
4535 xact_redo(XLogRecPtr lsn, XLogRecord *record)
4537 uint8 info = record->xl_info & ~XLR_INFO_MASK;
4539 /* Backup blocks are not used in xact records */
4540 Assert(!(record->xl_info & XLR_BKP_BLOCK_MASK));
4542 if (info == XLOG_XACT_COMMIT)
4544 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
4546 xact_redo_commit(xlrec, record->xl_xid, lsn);
4548 else if (info == XLOG_XACT_ABORT)
4550 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
4552 xact_redo_abort(xlrec, record->xl_xid);
4554 else if (info == XLOG_XACT_PREPARE)
4556 /* the record contents are exactly the 2PC file */
4557 RecreateTwoPhaseFile(record->xl_xid,
4558 XLogRecGetData(record), record->xl_len);
4560 else if (info == XLOG_XACT_COMMIT_PREPARED)
4562 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
4564 xact_redo_commit(&xlrec->crec, xlrec->xid, lsn);
4565 RemoveTwoPhaseFile(xlrec->xid, false);
4567 else if (info == XLOG_XACT_ABORT_PREPARED)
4569 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
4571 xact_redo_abort(&xlrec->arec, xlrec->xid);
4572 RemoveTwoPhaseFile(xlrec->xid, false);
4574 else if (info == XLOG_XACT_ASSIGNMENT)
4576 xl_xact_assignment *xlrec = (xl_xact_assignment *) XLogRecGetData(record);
4579 ProcArrayApplyXidAssignment(xlrec->xtop,
4580 xlrec->nsubxacts, xlrec->xsub);
4583 elog(PANIC, "xact_redo: unknown op code %u", info);
4587 xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
4590 TransactionId *xacts;
4591 SharedInvalidationMessage *msgs;
4593 xacts = (TransactionId *) &xlrec->xnodes[xlrec->nrels];
4594 msgs = (SharedInvalidationMessage *) &xacts[xlrec->nsubxacts];
4596 if (XactCompletionRelcacheInitFileInval(xlrec))
4597 appendStringInfo(buf, "; relcache init file inval");
4599 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4600 if (xlrec->nrels > 0)
4602 appendStringInfo(buf, "; rels:");
4603 for (i = 0; i < xlrec->nrels; i++)
4605 char *path = relpath(xlrec->xnodes[i], MAIN_FORKNUM);
4607 appendStringInfo(buf, " %s", path);
4611 if (xlrec->nsubxacts > 0)
4613 appendStringInfo(buf, "; subxacts:");
4614 for (i = 0; i < xlrec->nsubxacts; i++)
4615 appendStringInfo(buf, " %u", xacts[i]);
4617 if (xlrec->nmsgs > 0)
4619 appendStringInfo(buf, "; inval msgs:");
4620 for (i = 0; i < xlrec->nmsgs; i++)
4622 SharedInvalidationMessage *msg = &msgs[i];
4625 appendStringInfo(buf, "catcache id%d ", msg->id);
4626 else if (msg->id == SHAREDINVALRELCACHE_ID)
4627 appendStringInfo(buf, "relcache ");
4628 else if (msg->id == SHAREDINVALSMGR_ID)
4629 appendStringInfo(buf, "smgr ");
4635 xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
4639 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4640 if (xlrec->nrels > 0)
4642 appendStringInfo(buf, "; rels:");
4643 for (i = 0; i < xlrec->nrels; i++)
4645 char *path = relpath(xlrec->xnodes[i], MAIN_FORKNUM);
4647 appendStringInfo(buf, " %s", path);
4651 if (xlrec->nsubxacts > 0)
4653 TransactionId *xacts = (TransactionId *)
4654 &xlrec->xnodes[xlrec->nrels];
4656 appendStringInfo(buf, "; subxacts:");
4657 for (i = 0; i < xlrec->nsubxacts; i++)
4658 appendStringInfo(buf, " %u", xacts[i]);
4663 xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
4667 appendStringInfo(buf, "subxacts:");
4669 for (i = 0; i < xlrec->nsubxacts; i++)
4670 appendStringInfo(buf, " %u", xlrec->xsub[i]);
4674 xact_desc(StringInfo buf, uint8 xl_info, char *rec)
4676 uint8 info = xl_info & ~XLR_INFO_MASK;
4678 if (info == XLOG_XACT_COMMIT)
4680 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
4682 appendStringInfo(buf, "commit: ");
4683 xact_desc_commit(buf, xlrec);
4685 else if (info == XLOG_XACT_ABORT)
4687 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
4689 appendStringInfo(buf, "abort: ");
4690 xact_desc_abort(buf, xlrec);
4692 else if (info == XLOG_XACT_PREPARE)
4694 appendStringInfo(buf, "prepare");
4696 else if (info == XLOG_XACT_COMMIT_PREPARED)
4698 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
4700 appendStringInfo(buf, "commit prepared %u: ", xlrec->xid);
4701 xact_desc_commit(buf, &xlrec->crec);
4703 else if (info == XLOG_XACT_ABORT_PREPARED)
4705 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
4707 appendStringInfo(buf, "abort prepared %u: ", xlrec->xid);
4708 xact_desc_abort(buf, &xlrec->arec);
4710 else if (info == XLOG_XACT_ASSIGNMENT)
4712 xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
4715 * Note that we ignore the WAL record's xid, since we're more
4716 * interested in the top-level xid that issued the record
4717 * and which xids are being reported here.
4719 appendStringInfo(buf, "xid assignment xtop %u: ", xlrec->xtop);
4720 xact_desc_assignment(buf, xlrec);
4723 appendStringInfo(buf, "UNKNOWN");