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.282 2010/01/24 21:49:17 tgl Exp $
15 *-------------------------------------------------------------------------
23 #include "access/multixact.h"
24 #include "access/subtrans.h"
25 #include "access/transam.h"
26 #include "access/twophase.h"
27 #include "access/xact.h"
28 #include "access/xlogutils.h"
29 #include "catalog/catalog.h"
30 #include "catalog/namespace.h"
31 #include "catalog/storage.h"
32 #include "commands/async.h"
33 #include "commands/tablecmds.h"
34 #include "commands/trigger.h"
35 #include "executor/spi.h"
36 #include "libpq/be-fsstubs.h"
37 #include "miscadmin.h"
39 #include "storage/bufmgr.h"
40 #include "storage/fd.h"
41 #include "storage/lmgr.h"
42 #include "storage/procarray.h"
43 #include "storage/sinvaladt.h"
44 #include "storage/smgr.h"
45 #include "storage/standby.h"
46 #include "utils/combocid.h"
47 #include "utils/guc.h"
48 #include "utils/inval.h"
49 #include "utils/memutils.h"
50 #include "utils/relcache.h"
51 #include "utils/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
2173 * ordering. We can skip all of it if the transaction failed before
2174 * creating a resource owner.
2176 if (TopTransactionResourceOwner != NULL)
2178 CallXactCallbacks(XACT_EVENT_ABORT);
2180 ResourceOwnerRelease(TopTransactionResourceOwner,
2181 RESOURCE_RELEASE_BEFORE_LOCKS,
2183 AtEOXact_Buffers(false);
2184 AtEOXact_RelationCache(false);
2185 AtEOXact_Inval(false);
2186 smgrDoPendingDeletes(false);
2187 AtEOXact_MultiXact();
2188 ResourceOwnerRelease(TopTransactionResourceOwner,
2189 RESOURCE_RELEASE_LOCKS,
2191 ResourceOwnerRelease(TopTransactionResourceOwner,
2192 RESOURCE_RELEASE_AFTER_LOCKS,
2194 AtEOXact_CatCache(false);
2196 AtEOXact_GUC(false, 1);
2197 AtEOXact_SPI(false);
2198 AtEOXact_on_commit_actions(false);
2199 AtEOXact_Namespace(false);
2201 AtEOXact_ComboCid();
2202 AtEOXact_HashTables(false);
2203 AtEOXact_PgStat(false);
2204 AtEOXact_Snapshot(false);
2205 pgstat_report_xact_timestamp(0);
2209 * State remains TRANS_ABORT until CleanupTransaction().
2211 RESUME_INTERRUPTS();
2215 * CleanupTransaction
2218 CleanupTransaction(void)
2220 TransactionState s = CurrentTransactionState;
2223 * State should still be TRANS_ABORT from AbortTransaction().
2225 if (s->state != TRANS_ABORT)
2226 elog(FATAL, "CleanupTransaction: unexpected state %s",
2227 TransStateAsString(s->state));
2230 * do abort cleanup processing
2232 AtCleanup_Portals(); /* now safe to release portal memory */
2234 CurrentResourceOwner = NULL; /* and resource owner */
2235 if (TopTransactionResourceOwner)
2236 ResourceOwnerDelete(TopTransactionResourceOwner);
2237 s->curTransactionOwner = NULL;
2238 CurTransactionResourceOwner = NULL;
2239 TopTransactionResourceOwner = NULL;
2241 AtCleanup_Memory(); /* and transaction memory */
2243 s->transactionId = InvalidTransactionId;
2244 s->subTransactionId = InvalidSubTransactionId;
2245 s->nestingLevel = 0;
2246 s->gucNestLevel = 0;
2247 s->childXids = NULL;
2249 s->maxChildXids = 0;
2252 * done with abort processing, set current transaction state back to
2255 s->state = TRANS_DEFAULT;
2259 * StartTransactionCommand
2262 StartTransactionCommand(void)
2264 TransactionState s = CurrentTransactionState;
2266 switch (s->blockState)
2269 * if we aren't in a transaction block, we just do our usual start
2272 case TBLOCK_DEFAULT:
2274 s->blockState = TBLOCK_STARTED;
2278 * We are somewhere in a transaction block or subtransaction and
2279 * about to start a new command. For now we do nothing, but
2280 * someday we may do command-local resource initialization. (Note
2281 * that any needed CommandCounterIncrement was done by the
2282 * previous CommitTransactionCommand.)
2284 case TBLOCK_INPROGRESS:
2285 case TBLOCK_SUBINPROGRESS:
2289 * Here we are in a failed transaction block (one of the commands
2290 * caused an abort) so we do nothing but remain in the abort
2291 * state. Eventually we will get a ROLLBACK command which will
2292 * get us out of this state. (It is up to other code to ensure
2293 * that no commands other than ROLLBACK will be processed in these
2297 case TBLOCK_SUBABORT:
2300 /* These cases are invalid. */
2301 case TBLOCK_STARTED:
2303 case TBLOCK_SUBBEGIN:
2306 case TBLOCK_ABORT_END:
2307 case TBLOCK_SUBABORT_END:
2308 case TBLOCK_ABORT_PENDING:
2309 case TBLOCK_SUBABORT_PENDING:
2310 case TBLOCK_SUBRESTART:
2311 case TBLOCK_SUBABORT_RESTART:
2312 case TBLOCK_PREPARE:
2313 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2314 BlockStateAsString(s->blockState));
2319 * We must switch to CurTransactionContext before returning. This is
2320 * already done if we called StartTransaction, otherwise not.
2322 Assert(CurTransactionContext != NULL);
2323 MemoryContextSwitchTo(CurTransactionContext);
2327 * CommitTransactionCommand
2330 CommitTransactionCommand(void)
2332 TransactionState s = CurrentTransactionState;
2334 switch (s->blockState)
2337 * This shouldn't happen, because it means the previous
2338 * StartTransactionCommand didn't set the STARTED state
2341 case TBLOCK_DEFAULT:
2342 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2343 BlockStateAsString(s->blockState));
2347 * If we aren't in a transaction block, just do our usual
2348 * transaction commit, and return to the idle state.
2350 case TBLOCK_STARTED:
2351 CommitTransaction();
2352 s->blockState = TBLOCK_DEFAULT;
2356 * We are completing a "BEGIN TRANSACTION" command, so we change
2357 * to the "transaction block in progress" state and return. (We
2358 * assume the BEGIN did nothing to the database, so we need no
2359 * CommandCounterIncrement.)
2362 s->blockState = TBLOCK_INPROGRESS;
2366 * This is the case when we have finished executing a command
2367 * someplace within a transaction block. We increment the command
2368 * counter and return.
2370 case TBLOCK_INPROGRESS:
2371 case TBLOCK_SUBINPROGRESS:
2372 CommandCounterIncrement();
2376 * We are completing a "COMMIT" command. Do it and return to the
2380 CommitTransaction();
2381 s->blockState = TBLOCK_DEFAULT;
2385 * Here we are in the middle of a transaction block but one of the
2386 * commands caused an abort so we do nothing but remain in the
2387 * abort state. Eventually we will get a ROLLBACK comand.
2390 case TBLOCK_SUBABORT:
2394 * Here we were in an aborted transaction block and we just got
2395 * the ROLLBACK command from the user, so clean up the
2396 * already-aborted transaction and return to the idle state.
2398 case TBLOCK_ABORT_END:
2399 CleanupTransaction();
2400 s->blockState = TBLOCK_DEFAULT;
2404 * Here we were in a perfectly good transaction block but the user
2405 * told us to ROLLBACK anyway. We have to abort the transaction
2406 * and then clean up.
2408 case TBLOCK_ABORT_PENDING:
2410 CleanupTransaction();
2411 s->blockState = TBLOCK_DEFAULT;
2415 * We are completing a "PREPARE TRANSACTION" command. Do it and
2416 * return to the idle state.
2418 case TBLOCK_PREPARE:
2419 PrepareTransaction();
2420 s->blockState = TBLOCK_DEFAULT;
2424 * We were just issued a SAVEPOINT inside a transaction block.
2425 * Start a subtransaction. (DefineSavepoint already did
2426 * PushTransaction, so as to have someplace to put the SUBBEGIN
2429 case TBLOCK_SUBBEGIN:
2430 StartSubTransaction();
2431 s->blockState = TBLOCK_SUBINPROGRESS;
2435 * We were issued a COMMIT or RELEASE command, so we end the
2436 * current subtransaction and return to the parent transaction.
2437 * The parent might be ended too, so repeat till we are all the
2438 * way out or find an INPROGRESS transaction.
2443 CommitSubTransaction();
2444 s = CurrentTransactionState; /* changed by pop */
2445 } while (s->blockState == TBLOCK_SUBEND);
2446 /* If we had a COMMIT command, finish off the main xact too */
2447 if (s->blockState == TBLOCK_END)
2449 Assert(s->parent == NULL);
2450 CommitTransaction();
2451 s->blockState = TBLOCK_DEFAULT;
2453 else if (s->blockState == TBLOCK_PREPARE)
2455 Assert(s->parent == NULL);
2456 PrepareTransaction();
2457 s->blockState = TBLOCK_DEFAULT;
2461 Assert(s->blockState == TBLOCK_INPROGRESS ||
2462 s->blockState == TBLOCK_SUBINPROGRESS);
2467 * The current already-failed subtransaction is ending due to a
2468 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2469 * examine the parent (which could be in any of several states).
2471 case TBLOCK_SUBABORT_END:
2472 CleanupSubTransaction();
2473 CommitTransactionCommand();
2477 * As above, but it's not dead yet, so abort first.
2479 case TBLOCK_SUBABORT_PENDING:
2480 AbortSubTransaction();
2481 CleanupSubTransaction();
2482 CommitTransactionCommand();
2486 * The current subtransaction is the target of a ROLLBACK TO
2487 * command. Abort and pop it, then start a new subtransaction
2488 * with the same name.
2490 case TBLOCK_SUBRESTART:
2495 /* save name and keep Cleanup from freeing it */
2498 savepointLevel = s->savepointLevel;
2500 AbortSubTransaction();
2501 CleanupSubTransaction();
2503 DefineSavepoint(NULL);
2504 s = CurrentTransactionState; /* changed by push */
2506 s->savepointLevel = savepointLevel;
2508 /* This is the same as TBLOCK_SUBBEGIN case */
2509 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2510 StartSubTransaction();
2511 s->blockState = TBLOCK_SUBINPROGRESS;
2516 * Same as above, but the subtransaction had already failed, so we
2517 * don't need AbortSubTransaction.
2519 case TBLOCK_SUBABORT_RESTART:
2524 /* save name and keep Cleanup from freeing it */
2527 savepointLevel = s->savepointLevel;
2529 CleanupSubTransaction();
2531 DefineSavepoint(NULL);
2532 s = CurrentTransactionState; /* changed by push */
2534 s->savepointLevel = savepointLevel;
2536 /* This is the same as TBLOCK_SUBBEGIN case */
2537 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2538 StartSubTransaction();
2539 s->blockState = TBLOCK_SUBINPROGRESS;
2546 * AbortCurrentTransaction
2549 AbortCurrentTransaction(void)
2551 TransactionState s = CurrentTransactionState;
2553 switch (s->blockState)
2555 case TBLOCK_DEFAULT:
2556 if (s->state == TRANS_DEFAULT)
2558 /* we are idle, so nothing to do */
2563 * We can get here after an error during transaction start
2564 * (state will be TRANS_START). Need to clean up the
2565 * incompletely started transaction. First, adjust the
2566 * low-level state to suppress warning message from
2569 if (s->state == TRANS_START)
2570 s->state = TRANS_INPROGRESS;
2572 CleanupTransaction();
2577 * if we aren't in a transaction block, we just do the basic abort
2578 * & cleanup transaction.
2580 case TBLOCK_STARTED:
2582 CleanupTransaction();
2583 s->blockState = TBLOCK_DEFAULT;
2587 * If we are in TBLOCK_BEGIN it means something screwed up right
2588 * after reading "BEGIN TRANSACTION". We assume that the user
2589 * will interpret the error as meaning the BEGIN failed to get him
2590 * into a transaction block, so we should abort and return to idle
2595 CleanupTransaction();
2596 s->blockState = TBLOCK_DEFAULT;
2600 * We are somewhere in a transaction block and we've gotten a
2601 * failure, so we abort the transaction and set up the persistent
2602 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
2604 case TBLOCK_INPROGRESS:
2606 s->blockState = TBLOCK_ABORT;
2607 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
2611 * Here, we failed while trying to COMMIT. Clean up the
2612 * transaction and return to idle state (we do not want to stay in
2617 CleanupTransaction();
2618 s->blockState = TBLOCK_DEFAULT;
2622 * Here, we are already in an aborted transaction state and are
2623 * waiting for a ROLLBACK, but for some reason we failed again! So
2624 * we just remain in the abort state.
2627 case TBLOCK_SUBABORT:
2631 * We are in a failed transaction and we got the ROLLBACK command.
2632 * We have already aborted, we just need to cleanup and go to idle
2635 case TBLOCK_ABORT_END:
2636 CleanupTransaction();
2637 s->blockState = TBLOCK_DEFAULT;
2641 * We are in a live transaction and we got a ROLLBACK command.
2642 * Abort, cleanup, go to idle state.
2644 case TBLOCK_ABORT_PENDING:
2646 CleanupTransaction();
2647 s->blockState = TBLOCK_DEFAULT;
2651 * Here, we failed while trying to PREPARE. Clean up the
2652 * transaction and return to idle state (we do not want to stay in
2655 case TBLOCK_PREPARE:
2657 CleanupTransaction();
2658 s->blockState = TBLOCK_DEFAULT;
2662 * We got an error inside a subtransaction. Abort just the
2663 * subtransaction, and go to the persistent SUBABORT state until
2666 case TBLOCK_SUBINPROGRESS:
2667 AbortSubTransaction();
2668 s->blockState = TBLOCK_SUBABORT;
2672 * If we failed while trying to create a subtransaction, clean up
2673 * the broken subtransaction and abort the parent. The same
2674 * applies if we get a failure while ending a subtransaction.
2676 case TBLOCK_SUBBEGIN:
2678 case TBLOCK_SUBABORT_PENDING:
2679 case TBLOCK_SUBRESTART:
2680 AbortSubTransaction();
2681 CleanupSubTransaction();
2682 AbortCurrentTransaction();
2686 * Same as above, except the Abort() was already done.
2688 case TBLOCK_SUBABORT_END:
2689 case TBLOCK_SUBABORT_RESTART:
2690 CleanupSubTransaction();
2691 AbortCurrentTransaction();
2697 * PreventTransactionChain
2699 * This routine is to be called by statements that must not run inside
2700 * a transaction block, typically because they have non-rollback-able
2701 * side effects or do internal commits.
2703 * If we have already started a transaction block, issue an error; also issue
2704 * an error if we appear to be running inside a user-defined function (which
2705 * could issue more commands and possibly cause a failure after the statement
2706 * completes). Subtransactions are verboten too.
2708 * isTopLevel: passed down from ProcessUtility to determine whether we are
2709 * inside a function or multi-query querystring. (We will always fail if
2710 * this is false, but it's convenient to centralize the check here instead of
2711 * making callers do it.)
2712 * stmtType: statement type name, for error messages.
2715 PreventTransactionChain(bool isTopLevel, const char *stmtType)
2718 * xact block already started?
2720 if (IsTransactionBlock())
2722 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2723 /* translator: %s represents an SQL statement name */
2724 errmsg("%s cannot run inside a transaction block",
2730 if (IsSubTransaction())
2732 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2733 /* translator: %s represents an SQL statement name */
2734 errmsg("%s cannot run inside a subtransaction",
2738 * inside a function call?
2742 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2743 /* translator: %s represents an SQL statement name */
2744 errmsg("%s cannot be executed from a function or multi-command string",
2747 /* If we got past IsTransactionBlock test, should be in default state */
2748 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2749 CurrentTransactionState->blockState != TBLOCK_STARTED)
2750 elog(FATAL, "cannot prevent transaction chain");
2755 * RequireTransactionChain
2757 * This routine is to be called by statements that must run inside
2758 * a transaction block, because they have no effects that persist past
2759 * transaction end (and so calling them outside a transaction block
2760 * is presumably an error). DECLARE CURSOR is an example.
2762 * If we appear to be running inside a user-defined function, we do not
2763 * issue an error, since the function could issue more commands that make
2764 * use of the current statement's results. Likewise subtransactions.
2765 * Thus this is an inverse for PreventTransactionChain.
2767 * isTopLevel: passed down from ProcessUtility to determine whether we are
2768 * inside a function.
2769 * stmtType: statement type name, for error messages.
2772 RequireTransactionChain(bool isTopLevel, const char *stmtType)
2775 * xact block already started?
2777 if (IsTransactionBlock())
2783 if (IsSubTransaction())
2787 * inside a function call?
2793 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2794 /* translator: %s represents an SQL statement name */
2795 errmsg("%s can only be used in transaction blocks",
2800 * IsInTransactionChain
2802 * This routine is for statements that need to behave differently inside
2803 * a transaction block than when running as single commands. ANALYZE is
2804 * currently the only example.
2806 * isTopLevel: passed down from ProcessUtility to determine whether we are
2807 * inside a function.
2810 IsInTransactionChain(bool isTopLevel)
2813 * Return true on same conditions that would make PreventTransactionChain
2816 if (IsTransactionBlock())
2819 if (IsSubTransaction())
2825 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2826 CurrentTransactionState->blockState != TBLOCK_STARTED)
2834 * Register or deregister callback functions for start- and end-of-xact
2837 * These functions are intended for use by dynamically loaded modules.
2838 * For built-in modules we generally just hardwire the appropriate calls
2839 * (mainly because it's easier to control the order that way, where needed).
2841 * At transaction end, the callback occurs post-commit or post-abort, so the
2842 * callback functions can only do noncritical cleanup.
2845 RegisterXactCallback(XactCallback callback, void *arg)
2847 XactCallbackItem *item;
2849 item = (XactCallbackItem *)
2850 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
2851 item->callback = callback;
2853 item->next = Xact_callbacks;
2854 Xact_callbacks = item;
2858 UnregisterXactCallback(XactCallback callback, void *arg)
2860 XactCallbackItem *item;
2861 XactCallbackItem *prev;
2864 for (item = Xact_callbacks; item; prev = item, item = item->next)
2866 if (item->callback == callback && item->arg == arg)
2869 prev->next = item->next;
2871 Xact_callbacks = item->next;
2879 CallXactCallbacks(XactEvent event)
2881 XactCallbackItem *item;
2883 for (item = Xact_callbacks; item; item = item->next)
2884 (*item->callback) (event, item->arg);
2889 * Register or deregister callback functions for start- and end-of-subxact
2892 * Pretty much same as above, but for subtransaction events.
2894 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
2895 * so the callback functions can only do noncritical cleanup. At
2896 * subtransaction start, the callback is called when the subtransaction has
2897 * finished initializing.
2900 RegisterSubXactCallback(SubXactCallback callback, void *arg)
2902 SubXactCallbackItem *item;
2904 item = (SubXactCallbackItem *)
2905 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
2906 item->callback = callback;
2908 item->next = SubXact_callbacks;
2909 SubXact_callbacks = item;
2913 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
2915 SubXactCallbackItem *item;
2916 SubXactCallbackItem *prev;
2919 for (item = SubXact_callbacks; item; prev = item, item = item->next)
2921 if (item->callback == callback && item->arg == arg)
2924 prev->next = item->next;
2926 SubXact_callbacks = item->next;
2934 CallSubXactCallbacks(SubXactEvent event,
2935 SubTransactionId mySubid,
2936 SubTransactionId parentSubid)
2938 SubXactCallbackItem *item;
2940 for (item = SubXact_callbacks; item; item = item->next)
2941 (*item->callback) (event, mySubid, parentSubid, item->arg);
2945 /* ----------------------------------------------------------------
2946 * transaction block support
2947 * ----------------------------------------------------------------
2951 * BeginTransactionBlock
2952 * This executes a BEGIN command.
2955 BeginTransactionBlock(void)
2957 TransactionState s = CurrentTransactionState;
2959 switch (s->blockState)
2962 * We are not inside a transaction block, so allow one to begin.
2964 case TBLOCK_STARTED:
2965 s->blockState = TBLOCK_BEGIN;
2969 * Already a transaction block in progress.
2971 case TBLOCK_INPROGRESS:
2972 case TBLOCK_SUBINPROGRESS:
2974 case TBLOCK_SUBABORT:
2976 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2977 errmsg("there is already a transaction in progress")));
2980 /* These cases are invalid. */
2981 case TBLOCK_DEFAULT:
2983 case TBLOCK_SUBBEGIN:
2986 case TBLOCK_ABORT_END:
2987 case TBLOCK_SUBABORT_END:
2988 case TBLOCK_ABORT_PENDING:
2989 case TBLOCK_SUBABORT_PENDING:
2990 case TBLOCK_SUBRESTART:
2991 case TBLOCK_SUBABORT_RESTART:
2992 case TBLOCK_PREPARE:
2993 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
2994 BlockStateAsString(s->blockState));
3000 * PrepareTransactionBlock
3001 * This executes a PREPARE command.
3003 * Since PREPARE may actually do a ROLLBACK, the result indicates what
3004 * happened: TRUE for PREPARE, FALSE for ROLLBACK.
3006 * Note that we don't actually do anything here except change blockState.
3007 * The real work will be done in the upcoming PrepareTransaction().
3008 * We do it this way because it's not convenient to change memory context,
3009 * resource owner, etc while executing inside a Portal.
3012 PrepareTransactionBlock(char *gid)
3017 /* Set up to commit the current transaction */
3018 result = EndTransactionBlock();
3020 /* If successful, change outer tblock state to PREPARE */
3023 s = CurrentTransactionState;
3025 while (s->parent != NULL)
3028 if (s->blockState == TBLOCK_END)
3030 /* Save GID where PrepareTransaction can find it again */
3031 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
3033 s->blockState = TBLOCK_PREPARE;
3038 * ignore case where we are not in a transaction;
3039 * EndTransactionBlock already issued a warning.
3041 Assert(s->blockState == TBLOCK_STARTED);
3042 /* Don't send back a PREPARE result tag... */
3051 * EndTransactionBlock
3052 * This executes a COMMIT command.
3054 * Since COMMIT may actually do a ROLLBACK, the result indicates what
3055 * happened: TRUE for COMMIT, FALSE for ROLLBACK.
3057 * Note that we don't actually do anything here except change blockState.
3058 * The real work will be done in the upcoming CommitTransactionCommand().
3059 * We do it this way because it's not convenient to change memory context,
3060 * resource owner, etc while executing inside a Portal.
3063 EndTransactionBlock(void)
3065 TransactionState s = CurrentTransactionState;
3066 bool result = false;
3068 switch (s->blockState)
3071 * We are in a transaction block, so tell CommitTransactionCommand
3074 case TBLOCK_INPROGRESS:
3075 s->blockState = TBLOCK_END;
3080 * We are in a failed transaction block. Tell
3081 * CommitTransactionCommand it's time to exit the block.
3084 s->blockState = TBLOCK_ABORT_END;
3088 * We are in a live subtransaction block. Set up to subcommit all
3089 * open subtransactions and then commit the main transaction.
3091 case TBLOCK_SUBINPROGRESS:
3092 while (s->parent != NULL)
3094 if (s->blockState == TBLOCK_SUBINPROGRESS)
3095 s->blockState = TBLOCK_SUBEND;
3097 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3098 BlockStateAsString(s->blockState));
3101 if (s->blockState == TBLOCK_INPROGRESS)
3102 s->blockState = TBLOCK_END;
3104 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3105 BlockStateAsString(s->blockState));
3110 * Here we are inside an aborted subtransaction. Treat the COMMIT
3111 * as ROLLBACK: set up to abort everything and exit the main
3114 case TBLOCK_SUBABORT:
3115 while (s->parent != NULL)
3117 if (s->blockState == TBLOCK_SUBINPROGRESS)
3118 s->blockState = TBLOCK_SUBABORT_PENDING;
3119 else if (s->blockState == TBLOCK_SUBABORT)
3120 s->blockState = TBLOCK_SUBABORT_END;
3122 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3123 BlockStateAsString(s->blockState));
3126 if (s->blockState == TBLOCK_INPROGRESS)
3127 s->blockState = TBLOCK_ABORT_PENDING;
3128 else if (s->blockState == TBLOCK_ABORT)
3129 s->blockState = TBLOCK_ABORT_END;
3131 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3132 BlockStateAsString(s->blockState));
3136 * The user issued COMMIT when not inside a transaction. Issue a
3137 * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
3138 * CommitTransactionCommand() will then close the transaction and
3139 * put us back into the default state.
3141 case TBLOCK_STARTED:
3143 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3144 errmsg("there is no transaction in progress")));
3148 /* These cases are invalid. */
3149 case TBLOCK_DEFAULT:
3151 case TBLOCK_SUBBEGIN:
3154 case TBLOCK_ABORT_END:
3155 case TBLOCK_SUBABORT_END:
3156 case TBLOCK_ABORT_PENDING:
3157 case TBLOCK_SUBABORT_PENDING:
3158 case TBLOCK_SUBRESTART:
3159 case TBLOCK_SUBABORT_RESTART:
3160 case TBLOCK_PREPARE:
3161 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3162 BlockStateAsString(s->blockState));
3170 * UserAbortTransactionBlock
3171 * This executes a ROLLBACK command.
3173 * As above, we don't actually do anything here except change blockState.
3176 UserAbortTransactionBlock(void)
3178 TransactionState s = CurrentTransactionState;
3180 switch (s->blockState)
3183 * We are inside a transaction block and we got a ROLLBACK command
3184 * from the user, so tell CommitTransactionCommand to abort and
3185 * exit the transaction block.
3187 case TBLOCK_INPROGRESS:
3188 s->blockState = TBLOCK_ABORT_PENDING;
3192 * We are inside a failed transaction block and we got a ROLLBACK
3193 * command from the user. Abort processing is already done, so
3194 * CommitTransactionCommand just has to cleanup and go back to
3198 s->blockState = TBLOCK_ABORT_END;
3202 * We are inside a subtransaction. Mark everything up to top
3203 * level as exitable.
3205 case TBLOCK_SUBINPROGRESS:
3206 case TBLOCK_SUBABORT:
3207 while (s->parent != NULL)
3209 if (s->blockState == TBLOCK_SUBINPROGRESS)
3210 s->blockState = TBLOCK_SUBABORT_PENDING;
3211 else if (s->blockState == TBLOCK_SUBABORT)
3212 s->blockState = TBLOCK_SUBABORT_END;
3214 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3215 BlockStateAsString(s->blockState));
3218 if (s->blockState == TBLOCK_INPROGRESS)
3219 s->blockState = TBLOCK_ABORT_PENDING;
3220 else if (s->blockState == TBLOCK_ABORT)
3221 s->blockState = TBLOCK_ABORT_END;
3223 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3224 BlockStateAsString(s->blockState));
3228 * The user issued ABORT when not inside a transaction. Issue a
3229 * WARNING and go to abort state. The upcoming call to
3230 * CommitTransactionCommand() will then put us back into the
3233 case TBLOCK_STARTED:
3235 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3236 errmsg("there is no transaction in progress")));
3237 s->blockState = TBLOCK_ABORT_PENDING;
3240 /* These cases are invalid. */
3241 case TBLOCK_DEFAULT:
3243 case TBLOCK_SUBBEGIN:
3246 case TBLOCK_ABORT_END:
3247 case TBLOCK_SUBABORT_END:
3248 case TBLOCK_ABORT_PENDING:
3249 case TBLOCK_SUBABORT_PENDING:
3250 case TBLOCK_SUBRESTART:
3251 case TBLOCK_SUBABORT_RESTART:
3252 case TBLOCK_PREPARE:
3253 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3254 BlockStateAsString(s->blockState));
3261 * This executes a SAVEPOINT command.
3264 DefineSavepoint(char *name)
3266 TransactionState s = CurrentTransactionState;
3268 switch (s->blockState)
3270 case TBLOCK_INPROGRESS:
3271 case TBLOCK_SUBINPROGRESS:
3272 /* Normal subtransaction start */
3274 s = CurrentTransactionState; /* changed by push */
3277 * Savepoint names, like the TransactionState block itself, live
3278 * in TopTransactionContext.
3281 s->name = MemoryContextStrdup(TopTransactionContext, name);
3284 /* These cases are invalid. */
3285 case TBLOCK_DEFAULT:
3286 case TBLOCK_STARTED:
3288 case TBLOCK_SUBBEGIN:
3292 case TBLOCK_SUBABORT:
3293 case TBLOCK_ABORT_END:
3294 case TBLOCK_SUBABORT_END:
3295 case TBLOCK_ABORT_PENDING:
3296 case TBLOCK_SUBABORT_PENDING:
3297 case TBLOCK_SUBRESTART:
3298 case TBLOCK_SUBABORT_RESTART:
3299 case TBLOCK_PREPARE:
3300 elog(FATAL, "DefineSavepoint: unexpected state %s",
3301 BlockStateAsString(s->blockState));
3308 * This executes a RELEASE command.
3310 * As above, we don't actually do anything here except change blockState.
3313 ReleaseSavepoint(List *options)
3315 TransactionState s = CurrentTransactionState;
3316 TransactionState target,
3321 switch (s->blockState)
3324 * We can't rollback to a savepoint if there is no savepoint
3327 case TBLOCK_INPROGRESS:
3329 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3330 errmsg("no such savepoint")));
3334 * We are in a non-aborted subtransaction. This is the only valid
3337 case TBLOCK_SUBINPROGRESS:
3340 /* These cases are invalid. */
3341 case TBLOCK_DEFAULT:
3342 case TBLOCK_STARTED:
3344 case TBLOCK_SUBBEGIN:
3348 case TBLOCK_SUBABORT:
3349 case TBLOCK_ABORT_END:
3350 case TBLOCK_SUBABORT_END:
3351 case TBLOCK_ABORT_PENDING:
3352 case TBLOCK_SUBABORT_PENDING:
3353 case TBLOCK_SUBRESTART:
3354 case TBLOCK_SUBABORT_RESTART:
3355 case TBLOCK_PREPARE:
3356 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3357 BlockStateAsString(s->blockState));
3361 foreach(cell, options)
3363 DefElem *elem = lfirst(cell);
3365 if (strcmp(elem->defname, "savepoint_name") == 0)
3366 name = strVal(elem->arg);
3369 Assert(PointerIsValid(name));
3371 for (target = s; PointerIsValid(target); target = target->parent)
3373 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3377 if (!PointerIsValid(target))
3379 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3380 errmsg("no such savepoint")));
3382 /* disallow crossing savepoint level boundaries */
3383 if (target->savepointLevel != s->savepointLevel)
3385 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3386 errmsg("no such savepoint")));
3389 * Mark "commit pending" all subtransactions up to the target
3390 * subtransaction. The actual commits will happen when control gets to
3391 * CommitTransactionCommand.
3393 xact = CurrentTransactionState;
3396 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3397 xact->blockState = TBLOCK_SUBEND;
3400 xact = xact->parent;
3401 Assert(PointerIsValid(xact));
3406 * RollbackToSavepoint
3407 * This executes a ROLLBACK TO <savepoint> command.
3409 * As above, we don't actually do anything here except change blockState.
3412 RollbackToSavepoint(List *options)
3414 TransactionState s = CurrentTransactionState;
3415 TransactionState target,
3420 switch (s->blockState)
3423 * We can't rollback to a savepoint if there is no savepoint
3426 case TBLOCK_INPROGRESS:
3429 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3430 errmsg("no such savepoint")));
3434 * There is at least one savepoint, so proceed.
3436 case TBLOCK_SUBINPROGRESS:
3437 case TBLOCK_SUBABORT:
3440 /* These cases are invalid. */
3441 case TBLOCK_DEFAULT:
3442 case TBLOCK_STARTED:
3444 case TBLOCK_SUBBEGIN:
3447 case TBLOCK_ABORT_END:
3448 case TBLOCK_SUBABORT_END:
3449 case TBLOCK_ABORT_PENDING:
3450 case TBLOCK_SUBABORT_PENDING:
3451 case TBLOCK_SUBRESTART:
3452 case TBLOCK_SUBABORT_RESTART:
3453 case TBLOCK_PREPARE:
3454 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3455 BlockStateAsString(s->blockState));
3459 foreach(cell, options)
3461 DefElem *elem = lfirst(cell);
3463 if (strcmp(elem->defname, "savepoint_name") == 0)
3464 name = strVal(elem->arg);
3467 Assert(PointerIsValid(name));
3469 for (target = s; PointerIsValid(target); target = target->parent)
3471 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3475 if (!PointerIsValid(target))
3477 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3478 errmsg("no such savepoint")));
3480 /* disallow crossing savepoint level boundaries */
3481 if (target->savepointLevel != s->savepointLevel)
3483 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3484 errmsg("no such savepoint")));
3487 * Mark "abort pending" all subtransactions up to the target
3488 * subtransaction. The actual aborts will happen when control gets to
3489 * CommitTransactionCommand.
3491 xact = CurrentTransactionState;
3496 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3497 xact->blockState = TBLOCK_SUBABORT_PENDING;
3498 else if (xact->blockState == TBLOCK_SUBABORT)
3499 xact->blockState = TBLOCK_SUBABORT_END;
3501 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3502 BlockStateAsString(xact->blockState));
3503 xact = xact->parent;
3504 Assert(PointerIsValid(xact));
3507 /* And mark the target as "restart pending" */
3508 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3509 xact->blockState = TBLOCK_SUBRESTART;
3510 else if (xact->blockState == TBLOCK_SUBABORT)
3511 xact->blockState = TBLOCK_SUBABORT_RESTART;
3513 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3514 BlockStateAsString(xact->blockState));
3518 * BeginInternalSubTransaction
3519 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
3520 * TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
3521 * used in functions that might be called when not inside a BEGIN block
3522 * or when running deferred triggers at COMMIT/PREPARE time. Also, it
3523 * automatically does CommitTransactionCommand/StartTransactionCommand
3524 * instead of expecting the caller to do it.
3527 BeginInternalSubTransaction(char *name)
3529 TransactionState s = CurrentTransactionState;
3531 switch (s->blockState)
3533 case TBLOCK_STARTED:
3534 case TBLOCK_INPROGRESS:
3536 case TBLOCK_PREPARE:
3537 case TBLOCK_SUBINPROGRESS:
3538 /* Normal subtransaction start */
3540 s = CurrentTransactionState; /* changed by push */
3543 * Savepoint names, like the TransactionState block itself, live
3544 * in TopTransactionContext.
3547 s->name = MemoryContextStrdup(TopTransactionContext, name);
3550 /* These cases are invalid. */
3551 case TBLOCK_DEFAULT:
3553 case TBLOCK_SUBBEGIN:
3556 case TBLOCK_SUBABORT:
3557 case TBLOCK_ABORT_END:
3558 case TBLOCK_SUBABORT_END:
3559 case TBLOCK_ABORT_PENDING:
3560 case TBLOCK_SUBABORT_PENDING:
3561 case TBLOCK_SUBRESTART:
3562 case TBLOCK_SUBABORT_RESTART:
3563 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
3564 BlockStateAsString(s->blockState));
3568 CommitTransactionCommand();
3569 StartTransactionCommand();
3573 * ReleaseCurrentSubTransaction
3575 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
3576 * savepoint name (if any).
3577 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3580 ReleaseCurrentSubTransaction(void)
3582 TransactionState s = CurrentTransactionState;
3584 if (s->blockState != TBLOCK_SUBINPROGRESS)
3585 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
3586 BlockStateAsString(s->blockState));
3587 Assert(s->state == TRANS_INPROGRESS);
3588 MemoryContextSwitchTo(CurTransactionContext);
3589 CommitSubTransaction();
3590 s = CurrentTransactionState; /* changed by pop */
3591 Assert(s->state == TRANS_INPROGRESS);
3595 * RollbackAndReleaseCurrentSubTransaction
3597 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
3598 * of its savepoint name (if any).
3599 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3602 RollbackAndReleaseCurrentSubTransaction(void)
3604 TransactionState s = CurrentTransactionState;
3606 switch (s->blockState)
3608 /* Must be in a subtransaction */
3609 case TBLOCK_SUBINPROGRESS:
3610 case TBLOCK_SUBABORT:
3613 /* These cases are invalid. */
3614 case TBLOCK_DEFAULT:
3615 case TBLOCK_STARTED:
3617 case TBLOCK_SUBBEGIN:
3618 case TBLOCK_INPROGRESS:
3622 case TBLOCK_ABORT_END:
3623 case TBLOCK_SUBABORT_END:
3624 case TBLOCK_ABORT_PENDING:
3625 case TBLOCK_SUBABORT_PENDING:
3626 case TBLOCK_SUBRESTART:
3627 case TBLOCK_SUBABORT_RESTART:
3628 case TBLOCK_PREPARE:
3629 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
3630 BlockStateAsString(s->blockState));
3635 * Abort the current subtransaction, if needed.
3637 if (s->blockState == TBLOCK_SUBINPROGRESS)
3638 AbortSubTransaction();
3640 /* And clean it up, too */
3641 CleanupSubTransaction();
3643 s = CurrentTransactionState; /* changed by pop */
3644 AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
3645 s->blockState == TBLOCK_INPROGRESS ||
3646 s->blockState == TBLOCK_STARTED);
3650 * AbortOutOfAnyTransaction
3652 * This routine is provided for error recovery purposes. It aborts any
3653 * active transaction or transaction block, leaving the system in a known
3657 AbortOutOfAnyTransaction(void)
3659 TransactionState s = CurrentTransactionState;
3662 * Get out of any transaction or nested transaction
3666 switch (s->blockState)
3668 case TBLOCK_DEFAULT:
3669 /* Not in a transaction, do nothing */
3671 case TBLOCK_STARTED:
3673 case TBLOCK_INPROGRESS:
3675 case TBLOCK_ABORT_PENDING:
3676 case TBLOCK_PREPARE:
3677 /* In a transaction, so clean up */
3679 CleanupTransaction();
3680 s->blockState = TBLOCK_DEFAULT;
3683 case TBLOCK_ABORT_END:
3684 /* AbortTransaction already done, still need Cleanup */
3685 CleanupTransaction();
3686 s->blockState = TBLOCK_DEFAULT;
3690 * In a subtransaction, so clean it up and abort parent too
3692 case TBLOCK_SUBBEGIN:
3693 case TBLOCK_SUBINPROGRESS:
3695 case TBLOCK_SUBABORT_PENDING:
3696 case TBLOCK_SUBRESTART:
3697 AbortSubTransaction();
3698 CleanupSubTransaction();
3699 s = CurrentTransactionState; /* changed by pop */
3702 case TBLOCK_SUBABORT:
3703 case TBLOCK_SUBABORT_END:
3704 case TBLOCK_SUBABORT_RESTART:
3705 /* As above, but AbortSubTransaction already done */
3706 CleanupSubTransaction();
3707 s = CurrentTransactionState; /* changed by pop */
3710 } while (s->blockState != TBLOCK_DEFAULT);
3712 /* Should be out of all subxacts now */
3713 Assert(s->parent == NULL);
3717 * IsTransactionBlock --- are we within a transaction block?
3720 IsTransactionBlock(void)
3722 TransactionState s = CurrentTransactionState;
3724 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
3731 * IsTransactionOrTransactionBlock --- are we within either a transaction
3732 * or a transaction block? (The backend is only really "idle" when this
3735 * This should match up with IsTransactionBlock and IsTransactionState.
3738 IsTransactionOrTransactionBlock(void)
3740 TransactionState s = CurrentTransactionState;
3742 if (s->blockState == TBLOCK_DEFAULT)
3749 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
3752 TransactionBlockStatusCode(void)
3754 TransactionState s = CurrentTransactionState;
3756 switch (s->blockState)
3758 case TBLOCK_DEFAULT:
3759 case TBLOCK_STARTED:
3760 return 'I'; /* idle --- not in transaction */
3762 case TBLOCK_SUBBEGIN:
3763 case TBLOCK_INPROGRESS:
3764 case TBLOCK_SUBINPROGRESS:
3767 case TBLOCK_PREPARE:
3768 return 'T'; /* in transaction */
3770 case TBLOCK_SUBABORT:
3771 case TBLOCK_ABORT_END:
3772 case TBLOCK_SUBABORT_END:
3773 case TBLOCK_ABORT_PENDING:
3774 case TBLOCK_SUBABORT_PENDING:
3775 case TBLOCK_SUBRESTART:
3776 case TBLOCK_SUBABORT_RESTART:
3777 return 'E'; /* in failed transaction */
3780 /* should never get here */
3781 elog(FATAL, "invalid transaction block state: %s",
3782 BlockStateAsString(s->blockState));
3783 return 0; /* keep compiler quiet */
3790 IsSubTransaction(void)
3792 TransactionState s = CurrentTransactionState;
3794 if (s->nestingLevel >= 2)
3801 * StartSubTransaction
3803 * If you're wondering why this is separate from PushTransaction: it's because
3804 * we can't conveniently do this stuff right inside DefineSavepoint. The
3805 * SAVEPOINT utility command will be executed inside a Portal, and if we
3806 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
3807 * the Portal will undo those settings. So we make DefineSavepoint just
3808 * push a dummy transaction block, and when control returns to the main
3809 * idle loop, CommitTransactionCommand will be called, and we'll come here
3810 * to finish starting the subtransaction.
3813 StartSubTransaction(void)
3815 TransactionState s = CurrentTransactionState;
3817 if (s->state != TRANS_DEFAULT)
3818 elog(WARNING, "StartSubTransaction while in %s state",
3819 TransStateAsString(s->state));
3821 s->state = TRANS_START;
3824 * Initialize subsystems for new subtransaction
3826 * must initialize resource-management stuff first
3828 AtSubStart_Memory();
3829 AtSubStart_ResourceOwner();
3831 AtSubStart_Notify();
3832 AfterTriggerBeginSubXact();
3834 s->state = TRANS_INPROGRESS;
3837 * Call start-of-subxact callbacks
3839 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
3840 s->parent->subTransactionId);
3842 ShowTransactionState("StartSubTransaction");
3846 * CommitSubTransaction
3848 * The caller has to make sure to always reassign CurrentTransactionState
3849 * if it has a local pointer to it after calling this function.
3852 CommitSubTransaction(void)
3854 TransactionState s = CurrentTransactionState;
3856 ShowTransactionState("CommitSubTransaction");
3858 if (s->state != TRANS_INPROGRESS)
3859 elog(WARNING, "CommitSubTransaction while in %s state",
3860 TransStateAsString(s->state));
3862 /* Pre-commit processing goes here -- nothing to do at the moment */
3864 s->state = TRANS_COMMIT;
3866 /* Must CCI to ensure commands of subtransaction are seen as done */
3867 CommandCounterIncrement();
3870 * Prior to 8.4 we marked subcommit in clog at this point. We now only
3871 * perform that step, if required, as part of the atomic update of the
3872 * whole transaction tree at top level commit or abort.
3875 /* Post-commit cleanup */
3876 if (TransactionIdIsValid(s->transactionId))
3877 AtSubCommit_childXids();
3878 AfterTriggerEndSubXact(true);
3879 AtSubCommit_Portals(s->subTransactionId,
3880 s->parent->subTransactionId,
3881 s->parent->curTransactionOwner);
3882 AtEOSubXact_LargeObject(true, s->subTransactionId,
3883 s->parent->subTransactionId);
3884 AtSubCommit_Notify();
3886 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
3887 s->parent->subTransactionId);
3889 ResourceOwnerRelease(s->curTransactionOwner,
3890 RESOURCE_RELEASE_BEFORE_LOCKS,
3892 AtEOSubXact_RelationCache(true, s->subTransactionId,
3893 s->parent->subTransactionId);
3894 AtEOSubXact_Inval(true);
3898 * The only lock we actually release here is the subtransaction XID lock.
3899 * The rest just get transferred to the parent resource owner.
3901 CurrentResourceOwner = s->curTransactionOwner;
3902 if (TransactionIdIsValid(s->transactionId))
3903 XactLockTableDelete(s->transactionId);
3905 ResourceOwnerRelease(s->curTransactionOwner,
3906 RESOURCE_RELEASE_LOCKS,
3908 ResourceOwnerRelease(s->curTransactionOwner,
3909 RESOURCE_RELEASE_AFTER_LOCKS,
3912 AtEOXact_GUC(true, s->gucNestLevel);
3913 AtEOSubXact_SPI(true, s->subTransactionId);
3914 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
3915 s->parent->subTransactionId);
3916 AtEOSubXact_Namespace(true, s->subTransactionId,
3917 s->parent->subTransactionId);
3918 AtEOSubXact_Files(true, s->subTransactionId,
3919 s->parent->subTransactionId);
3920 AtEOSubXact_HashTables(true, s->nestingLevel);
3921 AtEOSubXact_PgStat(true, s->nestingLevel);
3922 AtSubCommit_Snapshot(s->nestingLevel);
3925 * We need to restore the upper transaction's read-only state, in case the
3926 * upper is read-write while the child is read-only; GUC will incorrectly
3927 * think it should leave the child state in place.
3929 XactReadOnly = s->prevXactReadOnly;
3931 CurrentResourceOwner = s->parent->curTransactionOwner;
3932 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3933 ResourceOwnerDelete(s->curTransactionOwner);
3934 s->curTransactionOwner = NULL;
3936 AtSubCommit_Memory();
3938 s->state = TRANS_DEFAULT;
3944 * AbortSubTransaction
3947 AbortSubTransaction(void)
3949 TransactionState s = CurrentTransactionState;
3951 /* Prevent cancel/die interrupt while cleaning up */
3954 /* Make sure we have a valid memory context and resource owner */
3955 AtSubAbort_Memory();
3956 AtSubAbort_ResourceOwner();
3959 * Release any LW locks we might be holding as quickly as possible.
3960 * (Regular locks, however, must be held till we finish aborting.)
3961 * Releasing LW locks is critical since we might try to grab them again
3962 * while cleaning up!
3964 * FIXME This may be incorrect --- Are there some locks we should keep?
3965 * Buffer locks, for example? I don't think so but I'm not sure.
3975 * check the current transaction state
3977 ShowTransactionState("AbortSubTransaction");
3979 if (s->state != TRANS_INPROGRESS)
3980 elog(WARNING, "AbortSubTransaction while in %s state",
3981 TransStateAsString(s->state));
3983 s->state = TRANS_ABORT;
3986 * Reset user ID which might have been changed transiently. (See notes in
3987 * AbortTransaction.)
3989 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
3992 * We can skip all this stuff if the subxact failed before creating a
3995 if (s->curTransactionOwner)
3997 AfterTriggerEndSubXact(false);
3998 AtSubAbort_Portals(s->subTransactionId,
3999 s->parent->subTransactionId,
4000 s->parent->curTransactionOwner);
4001 AtEOSubXact_LargeObject(false, s->subTransactionId,
4002 s->parent->subTransactionId);
4003 AtSubAbort_Notify();
4005 /* Advertise the fact that we aborted in pg_clog. */
4006 (void) RecordTransactionAbort(true);
4008 /* Post-abort cleanup */
4009 if (TransactionIdIsValid(s->transactionId))
4010 AtSubAbort_childXids();
4012 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
4013 s->parent->subTransactionId);
4015 ResourceOwnerRelease(s->curTransactionOwner,
4016 RESOURCE_RELEASE_BEFORE_LOCKS,
4018 AtEOSubXact_RelationCache(false, s->subTransactionId,
4019 s->parent->subTransactionId);
4020 AtEOSubXact_Inval(false);
4022 ResourceOwnerRelease(s->curTransactionOwner,
4023 RESOURCE_RELEASE_LOCKS,
4025 ResourceOwnerRelease(s->curTransactionOwner,
4026 RESOURCE_RELEASE_AFTER_LOCKS,
4029 AtEOXact_GUC(false, s->gucNestLevel);
4030 AtEOSubXact_SPI(false, s->subTransactionId);
4031 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
4032 s->parent->subTransactionId);
4033 AtEOSubXact_Namespace(false, s->subTransactionId,
4034 s->parent->subTransactionId);
4035 AtEOSubXact_Files(false, s->subTransactionId,
4036 s->parent->subTransactionId);
4037 AtEOSubXact_HashTables(false, s->nestingLevel);
4038 AtEOSubXact_PgStat(false, s->nestingLevel);
4039 AtSubAbort_Snapshot(s->nestingLevel);
4043 * Restore the upper transaction's read-only state, too. This should be
4044 * redundant with GUC's cleanup but we may as well do it for consistency
4045 * with the commit case.
4047 XactReadOnly = s->prevXactReadOnly;
4049 RESUME_INTERRUPTS();
4053 * CleanupSubTransaction
4055 * The caller has to make sure to always reassign CurrentTransactionState
4056 * if it has a local pointer to it after calling this function.
4059 CleanupSubTransaction(void)
4061 TransactionState s = CurrentTransactionState;
4063 ShowTransactionState("CleanupSubTransaction");
4065 if (s->state != TRANS_ABORT)
4066 elog(WARNING, "CleanupSubTransaction while in %s state",
4067 TransStateAsString(s->state));
4069 AtSubCleanup_Portals(s->subTransactionId);
4071 CurrentResourceOwner = s->parent->curTransactionOwner;
4072 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4073 if (s->curTransactionOwner)
4074 ResourceOwnerDelete(s->curTransactionOwner);
4075 s->curTransactionOwner = NULL;
4077 AtSubCleanup_Memory();
4079 s->state = TRANS_DEFAULT;
4086 * Create transaction state stack entry for a subtransaction
4088 * The caller has to make sure to always reassign CurrentTransactionState
4089 * if it has a local pointer to it after calling this function.
4092 PushTransaction(void)
4094 TransactionState p = CurrentTransactionState;
4098 * We keep subtransaction state nodes in TopTransactionContext.
4100 s = (TransactionState)
4101 MemoryContextAllocZero(TopTransactionContext,
4102 sizeof(TransactionStateData));
4105 * Assign a subtransaction ID, watching out for counter wraparound.
4107 currentSubTransactionId += 1;
4108 if (currentSubTransactionId == InvalidSubTransactionId)
4110 currentSubTransactionId -= 1;
4113 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
4114 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
4118 * We can now stack a minimally valid subtransaction without fear of
4121 s->transactionId = InvalidTransactionId; /* until assigned */
4122 s->subTransactionId = currentSubTransactionId;
4124 s->nestingLevel = p->nestingLevel + 1;
4125 s->gucNestLevel = NewGUCNestLevel();
4126 s->savepointLevel = p->savepointLevel;
4127 s->state = TRANS_DEFAULT;
4128 s->blockState = TBLOCK_SUBBEGIN;
4129 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
4130 s->prevXactReadOnly = XactReadOnly;
4132 CurrentTransactionState = s;
4135 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
4136 * with the subtransaction from here on out; in particular they should not
4137 * assume that it necessarily has a transaction context, resource owner,
4144 * Pop back to parent transaction state
4146 * The caller has to make sure to always reassign CurrentTransactionState
4147 * if it has a local pointer to it after calling this function.
4150 PopTransaction(void)
4152 TransactionState s = CurrentTransactionState;
4154 if (s->state != TRANS_DEFAULT)
4155 elog(WARNING, "PopTransaction while in %s state",
4156 TransStateAsString(s->state));
4158 if (s->parent == NULL)
4159 elog(FATAL, "PopTransaction with no parent");
4161 CurrentTransactionState = s->parent;
4163 /* Let's just make sure CurTransactionContext is good */
4164 CurTransactionContext = s->parent->curTransactionContext;
4165 MemoryContextSwitchTo(CurTransactionContext);
4167 /* Ditto for ResourceOwner links */
4168 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4169 CurrentResourceOwner = s->parent->curTransactionOwner;
4171 /* Free the old child structure */
4178 * ShowTransactionState
4182 ShowTransactionState(const char *str)
4184 /* skip work if message will definitely not be printed */
4185 if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
4187 elog(DEBUG3, "%s", str);
4188 ShowTransactionStateRec(CurrentTransactionState);
4193 * ShowTransactionStateRec
4194 * Recursive subroutine for ShowTransactionState
4197 ShowTransactionStateRec(TransactionState s)
4201 initStringInfo(&buf);
4203 if (s->nChildXids > 0)
4207 appendStringInfo(&buf, "%u", s->childXids[0]);
4208 for (i = 1; i < s->nChildXids; i++)
4209 appendStringInfo(&buf, " %u", s->childXids[i]);
4213 ShowTransactionStateRec(s->parent);
4215 /* use ereport to suppress computation if msg will not be printed */
4217 (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u%s, nestlvl: %d, children: %s",
4218 PointerIsValid(s->name) ? s->name : "unnamed",
4219 BlockStateAsString(s->blockState),
4220 TransStateAsString(s->state),
4221 (unsigned int) s->transactionId,
4222 (unsigned int) s->subTransactionId,
4223 (unsigned int) currentCommandId,
4224 currentCommandIdUsed ? " (used)" : "",
4225 s->nestingLevel, buf.data)));
4231 * BlockStateAsString
4235 BlockStateAsString(TBlockState blockState)
4239 case TBLOCK_DEFAULT:
4241 case TBLOCK_STARTED:
4245 case TBLOCK_INPROGRESS:
4246 return "INPROGRESS";
4251 case TBLOCK_ABORT_END:
4253 case TBLOCK_ABORT_PENDING:
4254 return "ABORT PEND";
4255 case TBLOCK_PREPARE:
4257 case TBLOCK_SUBBEGIN:
4259 case TBLOCK_SUBINPROGRESS:
4260 return "SUB INPROGRS";
4263 case TBLOCK_SUBABORT:
4265 case TBLOCK_SUBABORT_END:
4266 return "SUB ABORT END";
4267 case TBLOCK_SUBABORT_PENDING:
4268 return "SUB ABRT PEND";
4269 case TBLOCK_SUBRESTART:
4270 return "SUB RESTART";
4271 case TBLOCK_SUBABORT_RESTART:
4272 return "SUB AB RESTRT";
4274 return "UNRECOGNIZED";
4278 * TransStateAsString
4282 TransStateAsString(TransState state)
4290 case TRANS_INPROGRESS:
4299 return "UNRECOGNIZED";
4303 * xactGetCommittedChildren
4305 * Gets the list of committed children of the current transaction. The return
4306 * value is the number of child transactions. *ptr is set to point to an
4307 * array of TransactionIds. The array is allocated in TopTransactionContext;
4308 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
4309 * If there are no subxacts, *ptr is set to NULL.
4312 xactGetCommittedChildren(TransactionId **ptr)
4314 TransactionState s = CurrentTransactionState;
4316 if (s->nChildXids == 0)
4319 *ptr = s->childXids;
4321 return s->nChildXids;
4325 * XLOG support routines
4329 * Before 8.5 this was a fairly short function, but now it performs many
4330 * actions for which the order of execution is critical.
4333 xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid, XLogRecPtr lsn)
4335 TransactionId *sub_xids;
4336 SharedInvalidationMessage *inval_msgs;
4337 TransactionId max_xid;
4340 /* subxid array follows relfilenodes */
4341 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4342 /* invalidation messages array follows subxids */
4343 inval_msgs = (SharedInvalidationMessage *) &(sub_xids[xlrec->nsubxacts]);
4345 max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
4348 * Make sure nextXid is beyond any XID mentioned in the record.
4350 * We don't expect anyone else to modify nextXid, hence we
4351 * don't need to hold a lock while checking this. We still acquire
4352 * the lock to modify it, though.
4354 if (TransactionIdFollowsOrEquals(max_xid,
4355 ShmemVariableCache->nextXid))
4357 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4358 ShmemVariableCache->nextXid = max_xid;
4359 TransactionIdAdvance(ShmemVariableCache->nextXid);
4360 LWLockRelease(XidGenLock);
4363 if (!InHotStandby || XactCompletionVacuumFull(xlrec))
4366 * Mark the transaction committed in pg_clog.
4368 * If InHotStandby and this is the first commit of a VACUUM FULL INPLACE
4369 * we perform only the actual commit to clog. Strangely, there are two
4370 * commits that share the same xid for every VFI, so we need to skip
4371 * some steps for the first commit. It's OK to repeat the clog update
4372 * when we see the second commit on a VFI.
4374 TransactionIdCommitTree(xid, xlrec->nsubxacts, sub_xids);
4379 * If a transaction completion record arrives that has as-yet unobserved
4380 * subtransactions then this will not have been fully handled by the call
4381 * to RecordKnownAssignedTransactionIds() in the main recovery loop in
4382 * xlog.c. So we need to do bookkeeping again to cover that case. This is
4383 * confusing and it is easy to think this call is irrelevant, which has
4384 * happened three times in development already. Leave it in.
4386 RecordKnownAssignedTransactionIds(max_xid);
4389 * Mark the transaction committed in pg_clog. We use async commit
4390 * protocol during recovery to provide information on database
4391 * consistency for when users try to set hint bits. It is important
4392 * that we do not set hint bits until the minRecoveryPoint is past
4393 * this commit record. This ensures that if we crash we don't see
4394 * hint bits set on changes made by transactions that haven't yet
4395 * recovered. It's unlikely but it's good to be safe.
4397 TransactionIdAsyncCommitTree(xid, xlrec->nsubxacts, sub_xids, lsn);
4400 * We must mark clog before we update the ProcArray.
4402 ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids);
4405 * Send any cache invalidations attached to the commit. We must
4406 * maintain the same order of invalidation then release locks
4409 ProcessCommittedInvalidationMessages(inval_msgs, xlrec->nmsgs,
4410 XactCompletionRelcacheInitFileInval(xlrec));
4413 * Release locks, if any. We do this for both two phase and normal
4414 * one phase transactions. In effect we are ignoring the prepare
4415 * phase and just going straight to lock release.
4417 StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
4420 /* Make sure files supposed to be dropped are dropped */
4421 for (i = 0; i < xlrec->nrels; i++)
4423 SMgrRelation srel = smgropen(xlrec->xnodes[i]);
4426 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4428 if (smgrexists(srel, fork))
4430 XLogDropRelation(xlrec->xnodes[i], fork);
4431 smgrdounlink(srel, fork, false, true);
4438 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit() in
4439 * normal operation. For example, in DROP DATABASE, we delete all the files
4440 * belonging to the database, and then commit the transaction. If we crash
4441 * after all the files have been deleted but before the commit, you have an
4442 * entry in pg_database without any files. To minimize the window for that,
4443 * we use ForceSyncCommit() to rush the commit record to disk as quick as
4444 * possible. We have the same window during recovery, and forcing an
4445 * XLogFlush() (which updates minRecoveryPoint during recovery) helps
4446 * to reduce that problem window, for any user that requested ForceSyncCommit().
4448 if (XactCompletionForceSyncCommit(xlrec))
4453 * Be careful with the order of execution, as with xact_redo_commit().
4454 * The two functions are similar but differ in key places.
4456 * Note also that an abort can be for a subtransaction and its children,
4457 * not just for a top level abort. That means we have to consider
4458 * topxid != xid, whereas in commit we would find topxid == xid always
4459 * because subtransaction commit is never WAL logged.
4462 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
4464 TransactionId *sub_xids;
4465 TransactionId max_xid;
4468 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4469 max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
4471 /* Make sure nextXid is beyond any XID mentioned in the record */
4472 /* We don't expect anyone else to modify nextXid, hence we
4473 * don't need to hold a lock while checking this. We still acquire
4474 * the lock to modify it, though.
4476 if (TransactionIdFollowsOrEquals(max_xid,
4477 ShmemVariableCache->nextXid))
4479 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
4480 ShmemVariableCache->nextXid = max_xid;
4481 TransactionIdAdvance(ShmemVariableCache->nextXid);
4482 LWLockRelease(XidGenLock);
4488 * If a transaction completion record arrives that has as-yet unobserved
4489 * subtransactions then this will not have been fully handled by the call
4490 * to RecordKnownAssignedTransactionIds() in the main recovery loop in
4491 * xlog.c. So we need to do bookkeeping again to cover that case. This is
4492 * confusing and it is easy to think this call is irrelevant, which has
4493 * happened three times in development already. Leave it in.
4495 RecordKnownAssignedTransactionIds(max_xid);
4498 /* Mark the transaction aborted in pg_clog, no need for async stuff */
4499 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4504 * We must mark clog before we update the ProcArray.
4506 ExpireTreeKnownAssignedTransactionIds(xid, xlrec->nsubxacts, sub_xids);
4509 * There are no flat files that need updating, nor invalidation
4510 * messages to send or undo.
4514 * Release locks, if any. There are no invalidations to send.
4516 StandbyReleaseLockTree(xid, xlrec->nsubxacts, sub_xids);
4519 /* Make sure files supposed to be dropped are dropped */
4520 for (i = 0; i < xlrec->nrels; i++)
4522 SMgrRelation srel = smgropen(xlrec->xnodes[i]);
4525 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4527 if (smgrexists(srel, fork))
4529 XLogDropRelation(xlrec->xnodes[i], fork);
4530 smgrdounlink(srel, fork, false, true);
4538 xact_redo(XLogRecPtr lsn, XLogRecord *record)
4540 uint8 info = record->xl_info & ~XLR_INFO_MASK;
4542 /* Backup blocks are not used in xact records */
4543 Assert(!(record->xl_info & XLR_BKP_BLOCK_MASK));
4545 if (info == XLOG_XACT_COMMIT)
4547 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
4549 xact_redo_commit(xlrec, record->xl_xid, lsn);
4551 else if (info == XLOG_XACT_ABORT)
4553 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
4555 xact_redo_abort(xlrec, record->xl_xid);
4557 else if (info == XLOG_XACT_PREPARE)
4559 /* the record contents are exactly the 2PC file */
4560 RecreateTwoPhaseFile(record->xl_xid,
4561 XLogRecGetData(record), record->xl_len);
4563 else if (info == XLOG_XACT_COMMIT_PREPARED)
4565 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
4567 xact_redo_commit(&xlrec->crec, xlrec->xid, lsn);
4568 RemoveTwoPhaseFile(xlrec->xid, false);
4570 else if (info == XLOG_XACT_ABORT_PREPARED)
4572 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
4574 xact_redo_abort(&xlrec->arec, xlrec->xid);
4575 RemoveTwoPhaseFile(xlrec->xid, false);
4577 else if (info == XLOG_XACT_ASSIGNMENT)
4579 xl_xact_assignment *xlrec = (xl_xact_assignment *) XLogRecGetData(record);
4582 ProcArrayApplyXidAssignment(xlrec->xtop,
4583 xlrec->nsubxacts, xlrec->xsub);
4586 elog(PANIC, "xact_redo: unknown op code %u", info);
4590 xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
4593 TransactionId *xacts;
4594 SharedInvalidationMessage *msgs;
4596 xacts = (TransactionId *) &xlrec->xnodes[xlrec->nrels];
4597 msgs = (SharedInvalidationMessage *) &xacts[xlrec->nsubxacts];
4599 if (XactCompletionRelcacheInitFileInval(xlrec))
4600 appendStringInfo(buf, "; relcache init file inval");
4602 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4603 if (xlrec->nrels > 0)
4605 appendStringInfo(buf, "; rels:");
4606 for (i = 0; i < xlrec->nrels; i++)
4608 char *path = relpath(xlrec->xnodes[i], MAIN_FORKNUM);
4610 appendStringInfo(buf, " %s", path);
4614 if (xlrec->nsubxacts > 0)
4616 appendStringInfo(buf, "; subxacts:");
4617 for (i = 0; i < xlrec->nsubxacts; i++)
4618 appendStringInfo(buf, " %u", xacts[i]);
4620 if (xlrec->nmsgs > 0)
4622 appendStringInfo(buf, "; inval msgs:");
4623 for (i = 0; i < xlrec->nmsgs; i++)
4625 SharedInvalidationMessage *msg = &msgs[i];
4628 appendStringInfo(buf, "catcache id%d ", msg->id);
4629 else if (msg->id == SHAREDINVALRELCACHE_ID)
4630 appendStringInfo(buf, "relcache ");
4631 else if (msg->id == SHAREDINVALSMGR_ID)
4632 appendStringInfo(buf, "smgr ");
4638 xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
4642 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4643 if (xlrec->nrels > 0)
4645 appendStringInfo(buf, "; rels:");
4646 for (i = 0; i < xlrec->nrels; i++)
4648 char *path = relpath(xlrec->xnodes[i], MAIN_FORKNUM);
4650 appendStringInfo(buf, " %s", path);
4654 if (xlrec->nsubxacts > 0)
4656 TransactionId *xacts = (TransactionId *)
4657 &xlrec->xnodes[xlrec->nrels];
4659 appendStringInfo(buf, "; subxacts:");
4660 for (i = 0; i < xlrec->nsubxacts; i++)
4661 appendStringInfo(buf, " %u", xacts[i]);
4666 xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
4670 appendStringInfo(buf, "subxacts:");
4672 for (i = 0; i < xlrec->nsubxacts; i++)
4673 appendStringInfo(buf, " %u", xlrec->xsub[i]);
4677 xact_desc(StringInfo buf, uint8 xl_info, char *rec)
4679 uint8 info = xl_info & ~XLR_INFO_MASK;
4681 if (info == XLOG_XACT_COMMIT)
4683 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
4685 appendStringInfo(buf, "commit: ");
4686 xact_desc_commit(buf, xlrec);
4688 else if (info == XLOG_XACT_ABORT)
4690 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
4692 appendStringInfo(buf, "abort: ");
4693 xact_desc_abort(buf, xlrec);
4695 else if (info == XLOG_XACT_PREPARE)
4697 appendStringInfo(buf, "prepare");
4699 else if (info == XLOG_XACT_COMMIT_PREPARED)
4701 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
4703 appendStringInfo(buf, "commit prepared %u: ", xlrec->xid);
4704 xact_desc_commit(buf, &xlrec->crec);
4706 else if (info == XLOG_XACT_ABORT_PREPARED)
4708 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
4710 appendStringInfo(buf, "abort prepared %u: ", xlrec->xid);
4711 xact_desc_abort(buf, &xlrec->arec);
4713 else if (info == XLOG_XACT_ASSIGNMENT)
4715 xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
4718 * Note that we ignore the WAL record's xid, since we're more
4719 * interested in the top-level xid that issued the record
4720 * and which xids are being reported here.
4722 appendStringInfo(buf, "xid assignment xtop %u: ", xlrec->xtop);
4723 xact_desc_assignment(buf, xlrec);
4726 appendStringInfo(buf, "UNKNOWN");