Fix xslt_process() to ensure that it inserts a NULL terminator after the
[PostgreSQL.git] / src / backend / access / transam / xact.c
blob117fdabf6b63c07dc339bd6370fa95b425ed020f
1 /*-------------------------------------------------------------------------
3 * xact.c
4 * top level transaction system support routines
6 * See src/backend/access/transam/README for more information.
8 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
12 * IDENTIFICATION
13 * $PostgreSQL$
15 *-------------------------------------------------------------------------
18 #include "postgres.h"
20 #include <time.h>
21 #include <unistd.h>
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"
38 #include "pgstat.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 "utils/combocid.h"
46 #include "utils/flatfiles.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"
52 #include "pg_trace.h"
56 * User-tweakable parameters
58 int DefaultXactIsoLevel = XACT_READ_COMMITTED;
59 int XactIsoLevel;
61 bool DefaultXactReadOnly = false;
62 bool XactReadOnly;
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 */
88 } TransState;
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 */
120 } TBlockState;
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 bool prevSecDefCxt; /* previous SecurityDefinerContext setting */
142 bool prevXactReadOnly; /* entry-time xact r/o state */
143 struct TransactionStateData *parent; /* back link to parent */
144 } TransactionStateData;
146 typedef TransactionStateData *TransactionState;
149 * CurrentTransactionState always points to the current transaction state
150 * block. It will point to TopTransactionStateData when not in a
151 * transaction at all, or when in a top-level transaction.
153 static TransactionStateData TopTransactionStateData = {
154 0, /* transaction id */
155 0, /* subtransaction id */
156 NULL, /* savepoint name */
157 0, /* savepoint level */
158 TRANS_DEFAULT, /* transaction state */
159 TBLOCK_DEFAULT, /* transaction block state from the client
160 * perspective */
161 0, /* transaction nesting depth */
162 0, /* GUC context nesting depth */
163 NULL, /* cur transaction context */
164 NULL, /* cur transaction resource owner */
165 NULL, /* subcommitted child Xids */
166 0, /* # of subcommitted child Xids */
167 0, /* allocated size of childXids[] */
168 InvalidOid, /* previous CurrentUserId setting */
169 false, /* previous SecurityDefinerContext setting */
170 false, /* entry-time xact r/o state */
171 NULL /* link to parent state block */
174 static TransactionState CurrentTransactionState = &TopTransactionStateData;
177 * The subtransaction ID and command ID assignment counters are global
178 * to a whole transaction, so we do not keep them in the state stack.
180 static SubTransactionId currentSubTransactionId;
181 static CommandId currentCommandId;
182 static bool currentCommandIdUsed;
185 * xactStartTimestamp is the value of transaction_timestamp().
186 * stmtStartTimestamp is the value of statement_timestamp().
187 * xactStopTimestamp is the time at which we log a commit or abort WAL record.
188 * These do not change as we enter and exit subtransactions, so we don't
189 * keep them inside the TransactionState stack.
191 static TimestampTz xactStartTimestamp;
192 static TimestampTz stmtStartTimestamp;
193 static TimestampTz xactStopTimestamp;
196 * GID to be used for preparing the current transaction. This is also
197 * global to a whole transaction, so we don't keep it in the state stack.
199 static char *prepareGID;
202 * Some commands want to force synchronous commit.
204 static bool forceSyncCommit = false;
207 * Private context for transaction-abort work --- we reserve space for this
208 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
209 * when we've run out of memory.
211 static MemoryContext TransactionAbortContext = NULL;
214 * List of add-on start- and end-of-xact callbacks
216 typedef struct XactCallbackItem
218 struct XactCallbackItem *next;
219 XactCallback callback;
220 void *arg;
221 } XactCallbackItem;
223 static XactCallbackItem *Xact_callbacks = NULL;
226 * List of add-on start- and end-of-subxact callbacks
228 typedef struct SubXactCallbackItem
230 struct SubXactCallbackItem *next;
231 SubXactCallback callback;
232 void *arg;
233 } SubXactCallbackItem;
235 static SubXactCallbackItem *SubXact_callbacks = NULL;
238 /* local function prototypes */
239 static void AssignTransactionId(TransactionState s);
240 static void AbortTransaction(void);
241 static void AtAbort_Memory(void);
242 static void AtCleanup_Memory(void);
243 static void AtAbort_ResourceOwner(void);
244 static void AtCommit_LocalCache(void);
245 static void AtCommit_Memory(void);
246 static void AtStart_Cache(void);
247 static void AtStart_Memory(void);
248 static void AtStart_ResourceOwner(void);
249 static void CallXactCallbacks(XactEvent event);
250 static void CallSubXactCallbacks(SubXactEvent event,
251 SubTransactionId mySubid,
252 SubTransactionId parentSubid);
253 static void CleanupTransaction(void);
254 static void CommitTransaction(void);
255 static TransactionId RecordTransactionAbort(bool isSubXact);
256 static void StartTransaction(void);
258 static void StartSubTransaction(void);
259 static void CommitSubTransaction(void);
260 static void AbortSubTransaction(void);
261 static void CleanupSubTransaction(void);
262 static void PushTransaction(void);
263 static void PopTransaction(void);
265 static void AtSubAbort_Memory(void);
266 static void AtSubCleanup_Memory(void);
267 static void AtSubAbort_ResourceOwner(void);
268 static void AtSubCommit_Memory(void);
269 static void AtSubStart_Memory(void);
270 static void AtSubStart_ResourceOwner(void);
272 static void ShowTransactionState(const char *str);
273 static void ShowTransactionStateRec(TransactionState state);
274 static const char *BlockStateAsString(TBlockState blockState);
275 static const char *TransStateAsString(TransState state);
278 /* ----------------------------------------------------------------
279 * transaction state accessors
280 * ----------------------------------------------------------------
284 * IsTransactionState
286 * This returns true if we are inside a valid transaction; that is,
287 * it is safe to initiate database access, take heavyweight locks, etc.
289 bool
290 IsTransactionState(void)
292 TransactionState s = CurrentTransactionState;
295 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
296 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
297 * TRANS_PREPARE since it might be too soon or too late within those
298 * transition states to do anything interesting. Hence, the only "valid"
299 * state is TRANS_INPROGRESS.
301 return (s->state == TRANS_INPROGRESS);
305 * IsAbortedTransactionBlockState
307 * This returns true if we are currently running a query
308 * within an aborted transaction block.
310 bool
311 IsAbortedTransactionBlockState(void)
313 TransactionState s = CurrentTransactionState;
315 if (s->blockState == TBLOCK_ABORT ||
316 s->blockState == TBLOCK_SUBABORT)
317 return true;
319 return false;
324 * GetTopTransactionId
326 * This will return the XID of the main transaction, assigning one if
327 * it's not yet set. Be careful to call this only inside a valid xact.
329 TransactionId
330 GetTopTransactionId(void)
332 if (!TransactionIdIsValid(TopTransactionStateData.transactionId))
333 AssignTransactionId(&TopTransactionStateData);
334 return TopTransactionStateData.transactionId;
338 * GetTopTransactionIdIfAny
340 * This will return the XID of the main transaction, if one is assigned.
341 * It will return InvalidTransactionId if we are not currently inside a
342 * transaction, or inside a transaction that hasn't yet been assigned an XID.
344 TransactionId
345 GetTopTransactionIdIfAny(void)
347 return TopTransactionStateData.transactionId;
351 * GetCurrentTransactionId
353 * This will return the XID of the current transaction (main or sub
354 * transaction), assigning one if it's not yet set. Be careful to call this
355 * only inside a valid xact.
357 TransactionId
358 GetCurrentTransactionId(void)
360 TransactionState s = CurrentTransactionState;
362 if (!TransactionIdIsValid(s->transactionId))
363 AssignTransactionId(s);
364 return s->transactionId;
368 * GetCurrentTransactionIdIfAny
370 * This will return the XID of the current sub xact, if one is assigned.
371 * It will return InvalidTransactionId if we are not currently inside a
372 * transaction, or inside a transaction that hasn't been assigned an XID yet.
374 TransactionId
375 GetCurrentTransactionIdIfAny(void)
377 return CurrentTransactionState->transactionId;
382 * AssignTransactionId
384 * Assigns a new permanent XID to the given TransactionState.
385 * We do not assign XIDs to transactions until/unless this is called.
386 * Also, any parent TransactionStates that don't yet have XIDs are assigned
387 * one; this maintains the invariant that a child transaction has an XID
388 * following its parent's.
390 static void
391 AssignTransactionId(TransactionState s)
393 bool isSubXact = (s->parent != NULL);
394 ResourceOwner currentOwner;
396 /* Assert that caller didn't screw up */
397 Assert(!TransactionIdIsValid(s->transactionId));
398 Assert(s->state == TRANS_INPROGRESS);
401 * Ensure parent(s) have XIDs, so that a child always has an XID later
402 * than its parent.
404 if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
405 AssignTransactionId(s->parent);
408 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
410 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
411 * shared storage other than PG_PROC; because if there's no room for it in
412 * PG_PROC, the subtrans entry is needed to ensure that other backends see
413 * the Xid as "running". See GetNewTransactionId.
415 s->transactionId = GetNewTransactionId(isSubXact);
417 if (isSubXact)
418 SubTransSetParent(s->transactionId, s->parent->transactionId);
421 * Acquire lock on the transaction XID. (We assume this cannot block.) We
422 * have to ensure that the lock is assigned to the transaction's own
423 * ResourceOwner.
425 currentOwner = CurrentResourceOwner;
426 PG_TRY();
428 CurrentResourceOwner = s->curTransactionOwner;
429 XactLockTableInsert(s->transactionId);
431 PG_CATCH();
433 /* Ensure CurrentResourceOwner is restored on error */
434 CurrentResourceOwner = currentOwner;
435 PG_RE_THROW();
437 PG_END_TRY();
438 CurrentResourceOwner = currentOwner;
443 * GetCurrentSubTransactionId
445 SubTransactionId
446 GetCurrentSubTransactionId(void)
448 TransactionState s = CurrentTransactionState;
450 return s->subTransactionId;
455 * GetCurrentCommandId
457 * "used" must be TRUE if the caller intends to use the command ID to mark
458 * inserted/updated/deleted tuples. FALSE means the ID is being fetched
459 * for read-only purposes (ie, as a snapshot validity cutoff). See
460 * CommandCounterIncrement() for discussion.
462 CommandId
463 GetCurrentCommandId(bool used)
465 /* this is global to a transaction, not subtransaction-local */
466 if (used)
467 currentCommandIdUsed = true;
468 return currentCommandId;
472 * GetCurrentTransactionStartTimestamp
474 TimestampTz
475 GetCurrentTransactionStartTimestamp(void)
477 return xactStartTimestamp;
481 * GetCurrentStatementStartTimestamp
483 TimestampTz
484 GetCurrentStatementStartTimestamp(void)
486 return stmtStartTimestamp;
490 * GetCurrentTransactionStopTimestamp
492 * We return current time if the transaction stop time hasn't been set
493 * (which can happen if we decide we don't need to log an XLOG record).
495 TimestampTz
496 GetCurrentTransactionStopTimestamp(void)
498 if (xactStopTimestamp != 0)
499 return xactStopTimestamp;
500 return GetCurrentTimestamp();
504 * SetCurrentStatementStartTimestamp
506 void
507 SetCurrentStatementStartTimestamp(void)
509 stmtStartTimestamp = GetCurrentTimestamp();
513 * SetCurrentTransactionStopTimestamp
515 static inline void
516 SetCurrentTransactionStopTimestamp(void)
518 xactStopTimestamp = GetCurrentTimestamp();
522 * GetCurrentTransactionNestLevel
524 * Note: this will return zero when not inside any transaction, one when
525 * inside a top-level transaction, etc.
528 GetCurrentTransactionNestLevel(void)
530 TransactionState s = CurrentTransactionState;
532 return s->nestingLevel;
537 * TransactionIdIsCurrentTransactionId
539 bool
540 TransactionIdIsCurrentTransactionId(TransactionId xid)
542 TransactionState s;
545 * We always say that BootstrapTransactionId is "not my transaction ID"
546 * even when it is (ie, during bootstrap). Along with the fact that
547 * transam.c always treats BootstrapTransactionId as already committed,
548 * this causes the tqual.c routines to see all tuples as committed, which
549 * is what we need during bootstrap. (Bootstrap mode only inserts tuples,
550 * it never updates or deletes them, so all tuples can be presumed good
551 * immediately.)
553 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
554 * not my transaction ID, so we can just return "false" immediately for
555 * any non-normal XID.
557 if (!TransactionIdIsNormal(xid))
558 return false;
561 * We will return true for the Xid of the current subtransaction, any of
562 * its subcommitted children, any of its parents, or any of their
563 * previously subcommitted children. However, a transaction being aborted
564 * is no longer "current", even though it may still have an entry on the
565 * state stack.
567 for (s = CurrentTransactionState; s != NULL; s = s->parent)
569 int low,
570 high;
572 if (s->state == TRANS_ABORT)
573 continue;
574 if (!TransactionIdIsValid(s->transactionId))
575 continue; /* it can't have any child XIDs either */
576 if (TransactionIdEquals(xid, s->transactionId))
577 return true;
578 /* As the childXids array is ordered, we can use binary search */
579 low = 0;
580 high = s->nChildXids - 1;
581 while (low <= high)
583 int middle;
584 TransactionId probe;
586 middle = low + (high - low) / 2;
587 probe = s->childXids[middle];
588 if (TransactionIdEquals(probe, xid))
589 return true;
590 else if (TransactionIdPrecedes(probe, xid))
591 low = middle + 1;
592 else
593 high = middle - 1;
597 return false;
602 * CommandCounterIncrement
604 void
605 CommandCounterIncrement(void)
608 * If the current value of the command counter hasn't been "used" to mark
609 * tuples, we need not increment it, since there's no need to distinguish
610 * a read-only command from others. This helps postpone command counter
611 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
613 if (currentCommandIdUsed)
615 currentCommandId += 1;
616 if (currentCommandId == FirstCommandId) /* check for overflow */
618 currentCommandId -= 1;
619 ereport(ERROR,
620 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
621 errmsg("cannot have more than 2^32-1 commands in a transaction")));
623 currentCommandIdUsed = false;
625 /* Propagate new command ID into static snapshots */
626 SnapshotSetCommandId(currentCommandId);
629 * Make any catalog changes done by the just-completed command visible
630 * in the local syscache. We obviously don't need to do this after a
631 * read-only command. (But see hacks in inval.c to make real sure we
632 * don't think a command that queued inval messages was read-only.)
634 AtCommit_LocalCache();
638 * Make any other backends' catalog changes visible to me.
640 * XXX this is probably in the wrong place: CommandCounterIncrement should
641 * be purely a local operation, most likely. However fooling with this
642 * will affect asynchronous cross-backend interactions, which doesn't seem
643 * like a wise thing to do in late beta, so save improving this for
644 * another day - tgl 2007-11-30
646 AtStart_Cache();
650 * ForceSyncCommit
652 * Interface routine to allow commands to force a synchronous commit of the
653 * current top-level transaction
655 void
656 ForceSyncCommit(void)
658 forceSyncCommit = true;
662 /* ----------------------------------------------------------------
663 * StartTransaction stuff
664 * ----------------------------------------------------------------
668 * AtStart_Cache
670 static void
671 AtStart_Cache(void)
673 AcceptInvalidationMessages();
677 * AtStart_Memory
679 static void
680 AtStart_Memory(void)
682 TransactionState s = CurrentTransactionState;
685 * If this is the first time through, create a private context for
686 * AbortTransaction to work in. By reserving some space now, we can
687 * insulate AbortTransaction from out-of-memory scenarios. Like
688 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
689 * size, so that space will be reserved immediately.
691 if (TransactionAbortContext == NULL)
692 TransactionAbortContext =
693 AllocSetContextCreate(TopMemoryContext,
694 "TransactionAbortContext",
695 32 * 1024,
696 32 * 1024,
697 32 * 1024);
700 * We shouldn't have a transaction context already.
702 Assert(TopTransactionContext == NULL);
705 * Create a toplevel context for the transaction.
707 TopTransactionContext =
708 AllocSetContextCreate(TopMemoryContext,
709 "TopTransactionContext",
710 ALLOCSET_DEFAULT_MINSIZE,
711 ALLOCSET_DEFAULT_INITSIZE,
712 ALLOCSET_DEFAULT_MAXSIZE);
715 * In a top-level transaction, CurTransactionContext is the same as
716 * TopTransactionContext.
718 CurTransactionContext = TopTransactionContext;
719 s->curTransactionContext = CurTransactionContext;
721 /* Make the CurTransactionContext active. */
722 MemoryContextSwitchTo(CurTransactionContext);
726 * AtStart_ResourceOwner
728 static void
729 AtStart_ResourceOwner(void)
731 TransactionState s = CurrentTransactionState;
734 * We shouldn't have a transaction resource owner already.
736 Assert(TopTransactionResourceOwner == NULL);
739 * Create a toplevel resource owner for the transaction.
741 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
743 TopTransactionResourceOwner = s->curTransactionOwner;
744 CurTransactionResourceOwner = s->curTransactionOwner;
745 CurrentResourceOwner = s->curTransactionOwner;
748 /* ----------------------------------------------------------------
749 * StartSubTransaction stuff
750 * ----------------------------------------------------------------
754 * AtSubStart_Memory
756 static void
757 AtSubStart_Memory(void)
759 TransactionState s = CurrentTransactionState;
761 Assert(CurTransactionContext != NULL);
764 * Create a CurTransactionContext, which will be used to hold data that
765 * survives subtransaction commit but disappears on subtransaction abort.
766 * We make it a child of the immediate parent's CurTransactionContext.
768 CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
769 "CurTransactionContext",
770 ALLOCSET_DEFAULT_MINSIZE,
771 ALLOCSET_DEFAULT_INITSIZE,
772 ALLOCSET_DEFAULT_MAXSIZE);
773 s->curTransactionContext = CurTransactionContext;
775 /* Make the CurTransactionContext active. */
776 MemoryContextSwitchTo(CurTransactionContext);
780 * AtSubStart_ResourceOwner
782 static void
783 AtSubStart_ResourceOwner(void)
785 TransactionState s = CurrentTransactionState;
787 Assert(s->parent != NULL);
790 * Create a resource owner for the subtransaction. We make it a child of
791 * the immediate parent's resource owner.
793 s->curTransactionOwner =
794 ResourceOwnerCreate(s->parent->curTransactionOwner,
795 "SubTransaction");
797 CurTransactionResourceOwner = s->curTransactionOwner;
798 CurrentResourceOwner = s->curTransactionOwner;
801 /* ----------------------------------------------------------------
802 * CommitTransaction stuff
803 * ----------------------------------------------------------------
807 * RecordTransactionCommit
809 * Returns latest XID among xact and its children, or InvalidTransactionId
810 * if the xact has no XID. (We compute that here just because it's easier.)
812 * This is exported only to support an ugly hack in VACUUM FULL.
814 TransactionId
815 RecordTransactionCommit(void)
817 TransactionId xid = GetTopTransactionIdIfAny();
818 bool markXidCommitted = TransactionIdIsValid(xid);
819 TransactionId latestXid = InvalidTransactionId;
820 int nrels;
821 RelFileNode *rels;
822 bool haveNonTemp;
823 int nchildren;
824 TransactionId *children;
826 /* Get data needed for commit record */
827 nrels = smgrGetPendingDeletes(true, &rels, &haveNonTemp);
828 nchildren = xactGetCommittedChildren(&children);
831 * If we haven't been assigned an XID yet, we neither can, nor do we want
832 * to write a COMMIT record.
834 if (!markXidCommitted)
837 * We expect that every smgrscheduleunlink is followed by a catalog
838 * update, and hence XID assignment, so we shouldn't get here with any
839 * pending deletes. Use a real test not just an Assert to check this,
840 * since it's a bit fragile.
842 if (nrels != 0)
843 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
845 /* Can't have child XIDs either; AssignTransactionId enforces this */
846 Assert(nchildren == 0);
849 * If we didn't create XLOG entries, we're done here; otherwise we
850 * should flush those entries the same as a commit record. (An
851 * example of a possible record that wouldn't cause an XID to be
852 * assigned is a sequence advance record due to nextval() --- we want
853 * to flush that to disk before reporting commit.)
855 if (XactLastRecEnd.xrecoff == 0)
856 goto cleanup;
858 else
861 * Begin commit critical section and insert the commit XLOG record.
863 XLogRecData rdata[3];
864 int lastrdata = 0;
865 xl_xact_commit xlrec;
867 /* Tell bufmgr and smgr to prepare for commit */
868 BufmgrCommit();
871 * Mark ourselves as within our "commit critical section". This
872 * forces any concurrent checkpoint to wait until we've updated
873 * pg_clog. Without this, it is possible for the checkpoint to set
874 * REDO after the XLOG record but fail to flush the pg_clog update to
875 * disk, leading to loss of the transaction commit if the system
876 * crashes a little later.
878 * Note: we could, but don't bother to, set this flag in
879 * RecordTransactionAbort. That's because loss of a transaction abort
880 * is noncritical; the presumption would be that it aborted, anyway.
882 * It's safe to change the inCommit flag of our own backend without
883 * holding the ProcArrayLock, since we're the only one modifying it.
884 * This makes checkpoint's determination of which xacts are inCommit a
885 * bit fuzzy, but it doesn't matter.
887 START_CRIT_SECTION();
888 MyProc->inCommit = true;
890 SetCurrentTransactionStopTimestamp();
891 xlrec.xact_time = xactStopTimestamp;
892 xlrec.nrels = nrels;
893 xlrec.nsubxacts = nchildren;
894 rdata[0].data = (char *) (&xlrec);
895 rdata[0].len = MinSizeOfXactCommit;
896 rdata[0].buffer = InvalidBuffer;
897 /* dump rels to delete */
898 if (nrels > 0)
900 rdata[0].next = &(rdata[1]);
901 rdata[1].data = (char *) rels;
902 rdata[1].len = nrels * sizeof(RelFileNode);
903 rdata[1].buffer = InvalidBuffer;
904 lastrdata = 1;
906 /* dump committed child Xids */
907 if (nchildren > 0)
909 rdata[lastrdata].next = &(rdata[2]);
910 rdata[2].data = (char *) children;
911 rdata[2].len = nchildren * sizeof(TransactionId);
912 rdata[2].buffer = InvalidBuffer;
913 lastrdata = 2;
915 rdata[lastrdata].next = NULL;
917 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
921 * Check if we want to commit asynchronously. If the user has set
922 * synchronous_commit = off, and we're not doing cleanup of any non-temp
923 * rels nor committing any command that wanted to force sync commit, then
924 * we can defer flushing XLOG. (We must not allow asynchronous commit if
925 * there are any non-temp tables to be deleted, because we might delete
926 * the files before the COMMIT record is flushed to disk. We do allow
927 * asynchronous commit if all to-be-deleted tables are temporary though,
928 * since they are lost anyway if we crash.)
930 if (XactSyncCommit || forceSyncCommit || haveNonTemp)
933 * Synchronous commit case.
935 * Sleep before flush! So we can flush more than one commit records
936 * per single fsync. (The idea is some other backend may do the
937 * XLogFlush while we're sleeping. This needs work still, because on
938 * most Unixen, the minimum select() delay is 10msec or more, which is
939 * way too long.)
941 * We do not sleep if enableFsync is not turned on, nor if there are
942 * fewer than CommitSiblings other backends with active transactions.
944 if (CommitDelay > 0 && enableFsync &&
945 CountActiveBackends() >= CommitSiblings)
946 pg_usleep(CommitDelay);
948 XLogFlush(XactLastRecEnd);
951 * Now we may update the CLOG, if we wrote a COMMIT record above
953 if (markXidCommitted)
954 TransactionIdCommitTree(xid, nchildren, children);
956 else
959 * Asynchronous commit case.
961 * Report the latest async commit LSN, so that the WAL writer knows to
962 * flush this commit.
964 XLogSetAsyncCommitLSN(XactLastRecEnd);
967 * We must not immediately update the CLOG, since we didn't flush the
968 * XLOG. Instead, we store the LSN up to which the XLOG must be
969 * flushed before the CLOG may be updated.
971 if (markXidCommitted)
972 TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
976 * If we entered a commit critical section, leave it now, and let
977 * checkpoints proceed.
979 if (markXidCommitted)
981 MyProc->inCommit = false;
982 END_CRIT_SECTION();
985 /* Compute latestXid while we have the child XIDs handy */
986 latestXid = TransactionIdLatest(xid, nchildren, children);
988 /* Reset XactLastRecEnd until the next transaction writes something */
989 XactLastRecEnd.xrecoff = 0;
991 cleanup:
992 /* Clean up local data */
993 if (rels)
994 pfree(rels);
996 return latestXid;
1001 * AtCommit_LocalCache
1003 static void
1004 AtCommit_LocalCache(void)
1007 * Make catalog changes visible to me for the next command.
1009 CommandEndInvalidationMessages();
1013 * AtCommit_Memory
1015 static void
1016 AtCommit_Memory(void)
1019 * Now that we're "out" of a transaction, have the system allocate things
1020 * in the top memory context instead of per-transaction contexts.
1022 MemoryContextSwitchTo(TopMemoryContext);
1025 * Release all transaction-local memory.
1027 Assert(TopTransactionContext != NULL);
1028 MemoryContextDelete(TopTransactionContext);
1029 TopTransactionContext = NULL;
1030 CurTransactionContext = NULL;
1031 CurrentTransactionState->curTransactionContext = NULL;
1034 /* ----------------------------------------------------------------
1035 * CommitSubTransaction stuff
1036 * ----------------------------------------------------------------
1040 * AtSubCommit_Memory
1042 static void
1043 AtSubCommit_Memory(void)
1045 TransactionState s = CurrentTransactionState;
1047 Assert(s->parent != NULL);
1049 /* Return to parent transaction level's memory context. */
1050 CurTransactionContext = s->parent->curTransactionContext;
1051 MemoryContextSwitchTo(CurTransactionContext);
1054 * Ordinarily we cannot throw away the child's CurTransactionContext,
1055 * since the data it contains will be needed at upper commit. However, if
1056 * there isn't actually anything in it, we can throw it away. This avoids
1057 * a small memory leak in the common case of "trivial" subxacts.
1059 if (MemoryContextIsEmpty(s->curTransactionContext))
1061 MemoryContextDelete(s->curTransactionContext);
1062 s->curTransactionContext = NULL;
1067 * AtSubCommit_childXids
1069 * Pass my own XID and my child XIDs up to my parent as committed children.
1071 static void
1072 AtSubCommit_childXids(void)
1074 TransactionState s = CurrentTransactionState;
1075 int new_nChildXids;
1077 Assert(s->parent != NULL);
1080 * The parent childXids array will need to hold my XID and all my
1081 * childXids, in addition to the XIDs already there.
1083 new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1085 /* Allocate or enlarge the parent array if necessary */
1086 if (s->parent->maxChildXids < new_nChildXids)
1088 int new_maxChildXids;
1089 TransactionId *new_childXids;
1092 * Make it 2x what's needed right now, to avoid having to enlarge it
1093 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1094 * is what ensures that we don't need to worry about integer overflow
1095 * here or in the calculation of new_nChildXids.)
1097 new_maxChildXids = Min(new_nChildXids * 2,
1098 (int) (MaxAllocSize / sizeof(TransactionId)));
1100 if (new_maxChildXids < new_nChildXids)
1101 ereport(ERROR,
1102 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1103 errmsg("maximum number of committed subtransactions (%d) exceeded",
1104 (int) (MaxAllocSize / sizeof(TransactionId)))));
1107 * We keep the child-XID arrays in TopTransactionContext; this avoids
1108 * setting up child-transaction contexts for what might be just a few
1109 * bytes of grandchild XIDs.
1111 if (s->parent->childXids == NULL)
1112 new_childXids =
1113 MemoryContextAlloc(TopTransactionContext,
1114 new_maxChildXids * sizeof(TransactionId));
1115 else
1116 new_childXids = repalloc(s->parent->childXids,
1117 new_maxChildXids * sizeof(TransactionId));
1119 s->parent->childXids = new_childXids;
1120 s->parent->maxChildXids = new_maxChildXids;
1124 * Copy all my XIDs to parent's array.
1126 * Note: We rely on the fact that the XID of a child always follows that
1127 * of its parent. By copying the XID of this subtransaction before the
1128 * XIDs of its children, we ensure that the array stays ordered.
1129 * Likewise, all XIDs already in the array belong to subtransactions
1130 * started and subcommitted before us, so their XIDs must precede ours.
1132 s->parent->childXids[s->parent->nChildXids] = s->transactionId;
1134 if (s->nChildXids > 0)
1135 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1136 s->childXids,
1137 s->nChildXids * sizeof(TransactionId));
1139 s->parent->nChildXids = new_nChildXids;
1141 /* Release child's array to avoid leakage */
1142 if (s->childXids != NULL)
1143 pfree(s->childXids);
1144 /* We must reset these to avoid double-free if fail later in commit */
1145 s->childXids = NULL;
1146 s->nChildXids = 0;
1147 s->maxChildXids = 0;
1150 /* ----------------------------------------------------------------
1151 * AbortTransaction stuff
1152 * ----------------------------------------------------------------
1156 * RecordTransactionAbort
1158 * Returns latest XID among xact and its children, or InvalidTransactionId
1159 * if the xact has no XID. (We compute that here just because it's easier.)
1161 static TransactionId
1162 RecordTransactionAbort(bool isSubXact)
1164 TransactionId xid = GetCurrentTransactionIdIfAny();
1165 TransactionId latestXid;
1166 int nrels;
1167 RelFileNode *rels;
1168 int nchildren;
1169 TransactionId *children;
1170 XLogRecData rdata[3];
1171 int lastrdata = 0;
1172 xl_xact_abort xlrec;
1175 * If we haven't been assigned an XID, nobody will care whether we aborted
1176 * or not. Hence, we're done in that case. It does not matter if we have
1177 * rels to delete (note that this routine is not responsible for actually
1178 * deleting 'em). We cannot have any child XIDs, either.
1180 if (!TransactionIdIsValid(xid))
1182 /* Reset XactLastRecEnd until the next transaction writes something */
1183 if (!isSubXact)
1184 XactLastRecEnd.xrecoff = 0;
1185 return InvalidTransactionId;
1189 * We have a valid XID, so we should write an ABORT record for it.
1191 * We do not flush XLOG to disk here, since the default assumption after a
1192 * crash would be that we aborted, anyway. For the same reason, we don't
1193 * need to worry about interlocking against checkpoint start.
1197 * Check that we haven't aborted halfway through RecordTransactionCommit.
1199 if (TransactionIdDidCommit(xid))
1200 elog(PANIC, "cannot abort transaction %u, it was already committed",
1201 xid);
1203 /* Fetch the data we need for the abort record */
1204 nrels = smgrGetPendingDeletes(false, &rels, NULL);
1205 nchildren = xactGetCommittedChildren(&children);
1207 /* XXX do we really need a critical section here? */
1208 START_CRIT_SECTION();
1210 /* Write the ABORT record */
1211 if (isSubXact)
1212 xlrec.xact_time = GetCurrentTimestamp();
1213 else
1215 SetCurrentTransactionStopTimestamp();
1216 xlrec.xact_time = xactStopTimestamp;
1218 xlrec.nrels = nrels;
1219 xlrec.nsubxacts = nchildren;
1220 rdata[0].data = (char *) (&xlrec);
1221 rdata[0].len = MinSizeOfXactAbort;
1222 rdata[0].buffer = InvalidBuffer;
1223 /* dump rels to delete */
1224 if (nrels > 0)
1226 rdata[0].next = &(rdata[1]);
1227 rdata[1].data = (char *) rels;
1228 rdata[1].len = nrels * sizeof(RelFileNode);
1229 rdata[1].buffer = InvalidBuffer;
1230 lastrdata = 1;
1232 /* dump committed child Xids */
1233 if (nchildren > 0)
1235 rdata[lastrdata].next = &(rdata[2]);
1236 rdata[2].data = (char *) children;
1237 rdata[2].len = nchildren * sizeof(TransactionId);
1238 rdata[2].buffer = InvalidBuffer;
1239 lastrdata = 2;
1241 rdata[lastrdata].next = NULL;
1243 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, rdata);
1246 * Mark the transaction aborted in clog. This is not absolutely necessary
1247 * but we may as well do it while we are here; also, in the subxact case
1248 * it is helpful because XactLockTableWait makes use of it to avoid
1249 * waiting for already-aborted subtransactions. It is OK to do it without
1250 * having flushed the ABORT record to disk, because in event of a crash
1251 * we'd be assumed to have aborted anyway.
1253 TransactionIdAbortTree(xid, nchildren, children);
1255 END_CRIT_SECTION();
1257 /* Compute latestXid while we have the child XIDs handy */
1258 latestXid = TransactionIdLatest(xid, nchildren, children);
1261 * If we're aborting a subtransaction, we can immediately remove failed
1262 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1263 * subxacts, because we already have the child XID array at hand. For
1264 * main xacts, the equivalent happens just after this function returns.
1266 if (isSubXact)
1267 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1269 /* Reset XactLastRecEnd until the next transaction writes something */
1270 if (!isSubXact)
1271 XactLastRecEnd.xrecoff = 0;
1273 /* And clean up local data */
1274 if (rels)
1275 pfree(rels);
1277 return latestXid;
1281 * AtAbort_Memory
1283 static void
1284 AtAbort_Memory(void)
1287 * Switch into TransactionAbortContext, which should have some free space
1288 * even if nothing else does. We'll work in this context until we've
1289 * finished cleaning up.
1291 * It is barely possible to get here when we've not been able to create
1292 * TransactionAbortContext yet; if so use TopMemoryContext.
1294 if (TransactionAbortContext != NULL)
1295 MemoryContextSwitchTo(TransactionAbortContext);
1296 else
1297 MemoryContextSwitchTo(TopMemoryContext);
1301 * AtSubAbort_Memory
1303 static void
1304 AtSubAbort_Memory(void)
1306 Assert(TransactionAbortContext != NULL);
1308 MemoryContextSwitchTo(TransactionAbortContext);
1313 * AtAbort_ResourceOwner
1315 static void
1316 AtAbort_ResourceOwner(void)
1319 * Make sure we have a valid ResourceOwner, if possible (else it will be
1320 * NULL, which is OK)
1322 CurrentResourceOwner = TopTransactionResourceOwner;
1326 * AtSubAbort_ResourceOwner
1328 static void
1329 AtSubAbort_ResourceOwner(void)
1331 TransactionState s = CurrentTransactionState;
1333 /* Make sure we have a valid ResourceOwner */
1334 CurrentResourceOwner = s->curTransactionOwner;
1339 * AtSubAbort_childXids
1341 static void
1342 AtSubAbort_childXids(void)
1344 TransactionState s = CurrentTransactionState;
1347 * We keep the child-XID arrays in TopTransactionContext (see
1348 * AtSubCommit_childXids). This means we'd better free the array
1349 * explicitly at abort to avoid leakage.
1351 if (s->childXids != NULL)
1352 pfree(s->childXids);
1353 s->childXids = NULL;
1354 s->nChildXids = 0;
1355 s->maxChildXids = 0;
1358 /* ----------------------------------------------------------------
1359 * CleanupTransaction stuff
1360 * ----------------------------------------------------------------
1364 * AtCleanup_Memory
1366 static void
1367 AtCleanup_Memory(void)
1369 Assert(CurrentTransactionState->parent == NULL);
1372 * Now that we're "out" of a transaction, have the system allocate things
1373 * in the top memory context instead of per-transaction contexts.
1375 MemoryContextSwitchTo(TopMemoryContext);
1378 * Clear the special abort context for next time.
1380 if (TransactionAbortContext != NULL)
1381 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1384 * Release all transaction-local memory.
1386 if (TopTransactionContext != NULL)
1387 MemoryContextDelete(TopTransactionContext);
1388 TopTransactionContext = NULL;
1389 CurTransactionContext = NULL;
1390 CurrentTransactionState->curTransactionContext = NULL;
1394 /* ----------------------------------------------------------------
1395 * CleanupSubTransaction stuff
1396 * ----------------------------------------------------------------
1400 * AtSubCleanup_Memory
1402 static void
1403 AtSubCleanup_Memory(void)
1405 TransactionState s = CurrentTransactionState;
1407 Assert(s->parent != NULL);
1409 /* Make sure we're not in an about-to-be-deleted context */
1410 MemoryContextSwitchTo(s->parent->curTransactionContext);
1411 CurTransactionContext = s->parent->curTransactionContext;
1414 * Clear the special abort context for next time.
1416 if (TransactionAbortContext != NULL)
1417 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1420 * Delete the subxact local memory contexts. Its CurTransactionContext can
1421 * go too (note this also kills CurTransactionContexts from any children
1422 * of the subxact).
1424 if (s->curTransactionContext)
1425 MemoryContextDelete(s->curTransactionContext);
1426 s->curTransactionContext = NULL;
1429 /* ----------------------------------------------------------------
1430 * interface routines
1431 * ----------------------------------------------------------------
1435 * StartTransaction
1437 static void
1438 StartTransaction(void)
1440 TransactionState s;
1441 VirtualTransactionId vxid;
1444 * Let's just make sure the state stack is empty
1446 s = &TopTransactionStateData;
1447 CurrentTransactionState = s;
1450 * check the current transaction state
1452 if (s->state != TRANS_DEFAULT)
1453 elog(WARNING, "StartTransaction while in %s state",
1454 TransStateAsString(s->state));
1457 * set the current transaction state information appropriately during
1458 * start processing
1460 s->state = TRANS_START;
1461 s->transactionId = InvalidTransactionId; /* until assigned */
1464 * Make sure we've reset xact state variables
1466 XactIsoLevel = DefaultXactIsoLevel;
1467 XactReadOnly = DefaultXactReadOnly;
1468 forceSyncCommit = false;
1469 MyXactAccessedTempRel = false;
1472 * reinitialize within-transaction counters
1474 s->subTransactionId = TopSubTransactionId;
1475 currentSubTransactionId = TopSubTransactionId;
1476 currentCommandId = FirstCommandId;
1477 currentCommandIdUsed = false;
1480 * must initialize resource-management stuff first
1482 AtStart_Memory();
1483 AtStart_ResourceOwner();
1486 * Assign a new LocalTransactionId, and combine it with the backendId to
1487 * form a virtual transaction id.
1489 vxid.backendId = MyBackendId;
1490 vxid.localTransactionId = GetNextLocalTransactionId();
1493 * Lock the virtual transaction id before we announce it in the proc array
1495 VirtualXactLockTableInsert(vxid);
1498 * Advertise it in the proc array. We assume assignment of
1499 * LocalTransactionID is atomic, and the backendId should be set already.
1501 Assert(MyProc->backendId == vxid.backendId);
1502 MyProc->lxid = vxid.localTransactionId;
1504 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
1507 * set transaction_timestamp() (a/k/a now()). We want this to be the same
1508 * as the first command's statement_timestamp(), so don't do a fresh
1509 * GetCurrentTimestamp() call (which'd be expensive anyway). Also, mark
1510 * xactStopTimestamp as unset.
1512 xactStartTimestamp = stmtStartTimestamp;
1513 xactStopTimestamp = 0;
1514 pgstat_report_xact_timestamp(xactStartTimestamp);
1517 * initialize current transaction state fields
1519 * note: prevXactReadOnly is not used at the outermost level
1521 s->nestingLevel = 1;
1522 s->gucNestLevel = 1;
1523 s->childXids = NULL;
1524 s->nChildXids = 0;
1525 s->maxChildXids = 0;
1526 GetUserIdAndContext(&s->prevUser, &s->prevSecDefCxt);
1527 /* SecurityDefinerContext should never be set outside a transaction */
1528 Assert(!s->prevSecDefCxt);
1531 * initialize other subsystems for new transaction
1533 AtStart_GUC();
1534 AtStart_Inval();
1535 AtStart_Cache();
1536 AfterTriggerBeginXact();
1539 * done with start processing, set current transaction state to "in
1540 * progress"
1542 s->state = TRANS_INPROGRESS;
1544 ShowTransactionState("StartTransaction");
1549 * CommitTransaction
1551 * NB: if you change this routine, better look at PrepareTransaction too!
1553 static void
1554 CommitTransaction(void)
1556 TransactionState s = CurrentTransactionState;
1557 TransactionId latestXid;
1559 ShowTransactionState("CommitTransaction");
1562 * check the current transaction state
1564 if (s->state != TRANS_INPROGRESS)
1565 elog(WARNING, "CommitTransaction while in %s state",
1566 TransStateAsString(s->state));
1567 Assert(s->parent == NULL);
1570 * Do pre-commit processing (most of this stuff requires database access,
1571 * and in fact could still cause an error...)
1573 * It is possible for CommitHoldablePortals to invoke functions that queue
1574 * deferred triggers, and it's also possible that triggers create holdable
1575 * cursors. So we have to loop until there's nothing left to do.
1577 for (;;)
1580 * Fire all currently pending deferred triggers.
1582 AfterTriggerFireDeferred();
1585 * Convert any open holdable cursors into static portals. If there
1586 * weren't any, we are done ... otherwise loop back to check if they
1587 * queued deferred triggers. Lather, rinse, repeat.
1589 if (!CommitHoldablePortals())
1590 break;
1593 /* Now we can shut down the deferred-trigger manager */
1594 AfterTriggerEndXact(true);
1596 /* Close any open regular cursors */
1597 AtCommit_Portals();
1600 * Let ON COMMIT management do its thing (must happen after closing
1601 * cursors, to avoid dangling-reference problems)
1603 PreCommit_on_commit_actions();
1605 /* close large objects before lower-level cleanup */
1606 AtEOXact_LargeObject(true);
1608 /* NOTIFY commit must come before lower-level cleanup */
1609 AtCommit_Notify();
1612 * Update flat files if we changed pg_database, pg_authid or
1613 * pg_auth_members. This should be the last step before commit.
1615 AtEOXact_UpdateFlatFiles(true);
1617 /* Prevent cancel/die interrupt while cleaning up */
1618 HOLD_INTERRUPTS();
1621 * set the current transaction state information appropriately during
1622 * commit processing
1624 s->state = TRANS_COMMIT;
1627 * Here is where we really truly commit.
1629 latestXid = RecordTransactionCommit();
1631 TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
1634 * Let others know about no transaction in progress by me. Note that this
1635 * must be done _before_ releasing locks we hold and _after_
1636 * RecordTransactionCommit.
1638 ProcArrayEndTransaction(MyProc, latestXid);
1641 * This is all post-commit cleanup. Note that if an error is raised here,
1642 * it's too late to abort the transaction. This should be just
1643 * noncritical resource releasing.
1645 * The ordering of operations is not entirely random. The idea is:
1646 * release resources visible to other backends (eg, files, buffer pins);
1647 * then release locks; then release backend-local resources. We want to
1648 * release locks at the point where any backend waiting for us will see
1649 * our transaction as being fully cleaned up.
1651 * Resources that can be associated with individual queries are handled by
1652 * the ResourceOwner mechanism. The other calls here are for backend-wide
1653 * state.
1656 CallXactCallbacks(XACT_EVENT_COMMIT);
1658 ResourceOwnerRelease(TopTransactionResourceOwner,
1659 RESOURCE_RELEASE_BEFORE_LOCKS,
1660 true, true);
1662 /* Check we've released all buffer pins */
1663 AtEOXact_Buffers(true);
1665 /* Clean up the relation cache */
1666 AtEOXact_RelationCache(true);
1668 /* Clean up the snapshot manager */
1669 AtEarlyCommit_Snapshot();
1672 * Make catalog changes visible to all backends. This has to happen after
1673 * relcache references are dropped (see comments for
1674 * AtEOXact_RelationCache), but before locks are released (if anyone is
1675 * waiting for lock on a relation we've modified, we want them to know
1676 * about the catalog change before they start using the relation).
1678 AtEOXact_Inval(true);
1681 * Likewise, dropping of files deleted during the transaction is best done
1682 * after releasing relcache and buffer pins. (This is not strictly
1683 * necessary during commit, since such pins should have been released
1684 * already, but this ordering is definitely critical during abort.)
1686 smgrDoPendingDeletes(true);
1688 AtEOXact_MultiXact();
1690 ResourceOwnerRelease(TopTransactionResourceOwner,
1691 RESOURCE_RELEASE_LOCKS,
1692 true, true);
1693 ResourceOwnerRelease(TopTransactionResourceOwner,
1694 RESOURCE_RELEASE_AFTER_LOCKS,
1695 true, true);
1697 /* Check we've released all catcache entries */
1698 AtEOXact_CatCache(true);
1700 AtEOXact_GUC(true, 1);
1701 AtEOXact_SPI(true);
1702 AtEOXact_on_commit_actions(true);
1703 AtEOXact_Namespace(true);
1704 /* smgrcommit already done */
1705 AtEOXact_Files();
1706 AtEOXact_ComboCid();
1707 AtEOXact_HashTables(true);
1708 AtEOXact_PgStat(true);
1709 AtEOXact_Snapshot(true);
1710 pgstat_report_xact_timestamp(0);
1712 CurrentResourceOwner = NULL;
1713 ResourceOwnerDelete(TopTransactionResourceOwner);
1714 s->curTransactionOwner = NULL;
1715 CurTransactionResourceOwner = NULL;
1716 TopTransactionResourceOwner = NULL;
1718 AtCommit_Memory();
1720 s->transactionId = InvalidTransactionId;
1721 s->subTransactionId = InvalidSubTransactionId;
1722 s->nestingLevel = 0;
1723 s->gucNestLevel = 0;
1724 s->childXids = NULL;
1725 s->nChildXids = 0;
1726 s->maxChildXids = 0;
1729 * done with commit processing, set current transaction state back to
1730 * default
1732 s->state = TRANS_DEFAULT;
1734 RESUME_INTERRUPTS();
1739 * PrepareTransaction
1741 * NB: if you change this routine, better look at CommitTransaction too!
1743 static void
1744 PrepareTransaction(void)
1746 TransactionState s = CurrentTransactionState;
1747 TransactionId xid = GetCurrentTransactionId();
1748 GlobalTransaction gxact;
1749 TimestampTz prepared_at;
1751 ShowTransactionState("PrepareTransaction");
1754 * check the current transaction state
1756 if (s->state != TRANS_INPROGRESS)
1757 elog(WARNING, "PrepareTransaction while in %s state",
1758 TransStateAsString(s->state));
1759 Assert(s->parent == NULL);
1762 * Do pre-commit processing (most of this stuff requires database access,
1763 * and in fact could still cause an error...)
1765 * It is possible for PrepareHoldablePortals to invoke functions that
1766 * queue deferred triggers, and it's also possible that triggers create
1767 * holdable cursors. So we have to loop until there's nothing left to do.
1769 for (;;)
1772 * Fire all currently pending deferred triggers.
1774 AfterTriggerFireDeferred();
1777 * Convert any open holdable cursors into static portals. If there
1778 * weren't any, we are done ... otherwise loop back to check if they
1779 * queued deferred triggers. Lather, rinse, repeat.
1781 if (!PrepareHoldablePortals())
1782 break;
1785 /* Now we can shut down the deferred-trigger manager */
1786 AfterTriggerEndXact(true);
1788 /* Close any open regular cursors */
1789 AtCommit_Portals();
1792 * Let ON COMMIT management do its thing (must happen after closing
1793 * cursors, to avoid dangling-reference problems)
1795 PreCommit_on_commit_actions();
1797 /* close large objects before lower-level cleanup */
1798 AtEOXact_LargeObject(true);
1800 /* NOTIFY and flatfiles will be handled below */
1803 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
1804 * this transaction. Having the prepared xact hold locks on another
1805 * backend's temp table seems a bad idea --- for instance it would prevent
1806 * the backend from exiting. There are other problems too, such as how to
1807 * clean up the source backend's local buffers and ON COMMIT state if the
1808 * prepared xact includes a DROP of a temp table.
1810 * We must check this after executing any ON COMMIT actions, because they
1811 * might still access a temp relation.
1813 * XXX In principle this could be relaxed to allow some useful special
1814 * cases, such as a temp table created and dropped all within the
1815 * transaction. That seems to require much more bookkeeping though.
1817 if (MyXactAccessedTempRel)
1818 ereport(ERROR,
1819 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1820 errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
1822 /* Prevent cancel/die interrupt while cleaning up */
1823 HOLD_INTERRUPTS();
1826 * set the current transaction state information appropriately during
1827 * prepare processing
1829 s->state = TRANS_PREPARE;
1831 prepared_at = GetCurrentTimestamp();
1833 /* Tell bufmgr and smgr to prepare for commit */
1834 BufmgrCommit();
1837 * Reserve the GID for this transaction. This could fail if the requested
1838 * GID is invalid or already in use.
1840 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
1841 GetUserId(), MyDatabaseId);
1842 prepareGID = NULL;
1845 * Collect data for the 2PC state file. Note that in general, no actual
1846 * state change should happen in the called modules during this step,
1847 * since it's still possible to fail before commit, and in that case we
1848 * want transaction abort to be able to clean up. (In particular, the
1849 * AtPrepare routines may error out if they find cases they cannot
1850 * handle.) State cleanup should happen in the PostPrepare routines
1851 * below. However, some modules can go ahead and clear state here because
1852 * they wouldn't do anything with it during abort anyway.
1854 * Note: because the 2PC state file records will be replayed in the same
1855 * order they are made, the order of these calls has to match the order in
1856 * which we want things to happen during COMMIT PREPARED or ROLLBACK
1857 * PREPARED; in particular, pay attention to whether things should happen
1858 * before or after releasing the transaction's locks.
1860 StartPrepare(gxact);
1862 AtPrepare_Notify();
1863 AtPrepare_UpdateFlatFiles();
1864 AtPrepare_Inval();
1865 AtPrepare_Locks();
1866 AtPrepare_PgStat();
1869 * Here is where we really truly prepare.
1871 * We have to record transaction prepares even if we didn't make any
1872 * updates, because the transaction manager might get confused if we lose
1873 * a global transaction.
1875 EndPrepare(gxact);
1878 * Now we clean up backend-internal state and release internal resources.
1881 /* Reset XactLastRecEnd until the next transaction writes something */
1882 XactLastRecEnd.xrecoff = 0;
1885 * Let others know about no transaction in progress by me. This has to be
1886 * done *after* the prepared transaction has been marked valid, else
1887 * someone may think it is unlocked and recyclable.
1889 ProcArrayClearTransaction(MyProc);
1892 * This is all post-transaction cleanup. Note that if an error is raised
1893 * here, it's too late to abort the transaction. This should be just
1894 * noncritical resource releasing. See notes in CommitTransaction.
1897 CallXactCallbacks(XACT_EVENT_PREPARE);
1899 ResourceOwnerRelease(TopTransactionResourceOwner,
1900 RESOURCE_RELEASE_BEFORE_LOCKS,
1901 true, true);
1903 /* Check we've released all buffer pins */
1904 AtEOXact_Buffers(true);
1906 /* Clean up the relation cache */
1907 AtEOXact_RelationCache(true);
1909 /* Clean up the snapshot manager */
1910 AtEarlyCommit_Snapshot();
1912 /* notify and flatfiles don't need a postprepare call */
1914 PostPrepare_PgStat();
1916 PostPrepare_Inval();
1918 PostPrepare_smgr();
1920 AtEOXact_MultiXact();
1922 PostPrepare_Locks(xid);
1924 ResourceOwnerRelease(TopTransactionResourceOwner,
1925 RESOURCE_RELEASE_LOCKS,
1926 true, true);
1927 ResourceOwnerRelease(TopTransactionResourceOwner,
1928 RESOURCE_RELEASE_AFTER_LOCKS,
1929 true, true);
1931 /* Check we've released all catcache entries */
1932 AtEOXact_CatCache(true);
1934 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
1935 AtEOXact_GUC(true, 1);
1936 AtEOXact_SPI(true);
1937 AtEOXact_on_commit_actions(true);
1938 AtEOXact_Namespace(true);
1939 /* smgrcommit already done */
1940 AtEOXact_Files();
1941 AtEOXact_ComboCid();
1942 AtEOXact_HashTables(true);
1943 /* don't call AtEOXact_PgStat here */
1944 AtEOXact_Snapshot(true);
1946 CurrentResourceOwner = NULL;
1947 ResourceOwnerDelete(TopTransactionResourceOwner);
1948 s->curTransactionOwner = NULL;
1949 CurTransactionResourceOwner = NULL;
1950 TopTransactionResourceOwner = NULL;
1952 AtCommit_Memory();
1954 s->transactionId = InvalidTransactionId;
1955 s->subTransactionId = InvalidSubTransactionId;
1956 s->nestingLevel = 0;
1957 s->gucNestLevel = 0;
1958 s->childXids = NULL;
1959 s->nChildXids = 0;
1960 s->maxChildXids = 0;
1963 * done with 1st phase commit processing, set current transaction state
1964 * back to default
1966 s->state = TRANS_DEFAULT;
1968 RESUME_INTERRUPTS();
1973 * AbortTransaction
1975 static void
1976 AbortTransaction(void)
1978 TransactionState s = CurrentTransactionState;
1979 TransactionId latestXid;
1981 /* Prevent cancel/die interrupt while cleaning up */
1982 HOLD_INTERRUPTS();
1984 /* Make sure we have a valid memory context and resource owner */
1985 AtAbort_Memory();
1986 AtAbort_ResourceOwner();
1989 * Release any LW locks we might be holding as quickly as possible.
1990 * (Regular locks, however, must be held till we finish aborting.)
1991 * Releasing LW locks is critical since we might try to grab them again
1992 * while cleaning up!
1994 LWLockReleaseAll();
1996 /* Clean up buffer I/O and buffer context locks, too */
1997 AbortBufferIO();
1998 UnlockBuffers();
2001 * Also clean up any open wait for lock, since the lock manager will choke
2002 * if we try to wait for another lock before doing this.
2004 LockWaitCancel();
2007 * check the current transaction state
2009 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2010 elog(WARNING, "AbortTransaction while in %s state",
2011 TransStateAsString(s->state));
2012 Assert(s->parent == NULL);
2015 * set the current transaction state information appropriately during the
2016 * abort processing
2018 s->state = TRANS_ABORT;
2021 * Reset user ID which might have been changed transiently. We need this
2022 * to clean up in case control escaped out of a SECURITY DEFINER function
2023 * or other local change of CurrentUserId; therefore, the prior value of
2024 * SecurityDefinerContext also needs to be restored.
2026 * (Note: it is not necessary to restore session authorization or role
2027 * settings here because those can only be changed via GUC, and GUC will
2028 * take care of rolling them back if need be.)
2030 SetUserIdAndContext(s->prevUser, s->prevSecDefCxt);
2033 * do abort processing
2035 AfterTriggerEndXact(false);
2036 AtAbort_Portals();
2037 AtEOXact_LargeObject(false); /* 'false' means it's abort */
2038 AtAbort_Notify();
2039 AtEOXact_UpdateFlatFiles(false);
2042 * Advertise the fact that we aborted in pg_clog (assuming that we got as
2043 * far as assigning an XID to advertise).
2045 latestXid = RecordTransactionAbort(false);
2047 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
2050 * Let others know about no transaction in progress by me. Note that this
2051 * must be done _before_ releasing locks we hold and _after_
2052 * RecordTransactionAbort.
2054 ProcArrayEndTransaction(MyProc, latestXid);
2057 * Post-abort cleanup. See notes in CommitTransaction() concerning
2058 * ordering.
2061 CallXactCallbacks(XACT_EVENT_ABORT);
2063 ResourceOwnerRelease(TopTransactionResourceOwner,
2064 RESOURCE_RELEASE_BEFORE_LOCKS,
2065 false, true);
2066 AtEOXact_Buffers(false);
2067 AtEOXact_RelationCache(false);
2068 AtEOXact_Inval(false);
2069 smgrDoPendingDeletes(false);
2070 AtEOXact_MultiXact();
2071 ResourceOwnerRelease(TopTransactionResourceOwner,
2072 RESOURCE_RELEASE_LOCKS,
2073 false, true);
2074 ResourceOwnerRelease(TopTransactionResourceOwner,
2075 RESOURCE_RELEASE_AFTER_LOCKS,
2076 false, true);
2077 AtEOXact_CatCache(false);
2079 AtEOXact_GUC(false, 1);
2080 AtEOXact_SPI(false);
2081 AtEOXact_on_commit_actions(false);
2082 AtEOXact_Namespace(false);
2083 AtEOXact_Files();
2084 AtEOXact_ComboCid();
2085 AtEOXact_HashTables(false);
2086 AtEOXact_PgStat(false);
2087 AtEOXact_Snapshot(false);
2088 pgstat_report_xact_timestamp(0);
2091 * State remains TRANS_ABORT until CleanupTransaction().
2093 RESUME_INTERRUPTS();
2097 * CleanupTransaction
2099 static void
2100 CleanupTransaction(void)
2102 TransactionState s = CurrentTransactionState;
2105 * State should still be TRANS_ABORT from AbortTransaction().
2107 if (s->state != TRANS_ABORT)
2108 elog(FATAL, "CleanupTransaction: unexpected state %s",
2109 TransStateAsString(s->state));
2112 * do abort cleanup processing
2114 AtCleanup_Portals(); /* now safe to release portal memory */
2116 CurrentResourceOwner = NULL; /* and resource owner */
2117 if (TopTransactionResourceOwner)
2118 ResourceOwnerDelete(TopTransactionResourceOwner);
2119 s->curTransactionOwner = NULL;
2120 CurTransactionResourceOwner = NULL;
2121 TopTransactionResourceOwner = NULL;
2123 AtCleanup_Memory(); /* and transaction memory */
2125 s->transactionId = InvalidTransactionId;
2126 s->subTransactionId = InvalidSubTransactionId;
2127 s->nestingLevel = 0;
2128 s->gucNestLevel = 0;
2129 s->childXids = NULL;
2130 s->nChildXids = 0;
2131 s->maxChildXids = 0;
2134 * done with abort processing, set current transaction state back to
2135 * default
2137 s->state = TRANS_DEFAULT;
2141 * StartTransactionCommand
2143 void
2144 StartTransactionCommand(void)
2146 TransactionState s = CurrentTransactionState;
2148 switch (s->blockState)
2151 * if we aren't in a transaction block, we just do our usual start
2152 * transaction.
2154 case TBLOCK_DEFAULT:
2155 StartTransaction();
2156 s->blockState = TBLOCK_STARTED;
2157 break;
2160 * We are somewhere in a transaction block or subtransaction and
2161 * about to start a new command. For now we do nothing, but
2162 * someday we may do command-local resource initialization. (Note
2163 * that any needed CommandCounterIncrement was done by the
2164 * previous CommitTransactionCommand.)
2166 case TBLOCK_INPROGRESS:
2167 case TBLOCK_SUBINPROGRESS:
2168 break;
2171 * Here we are in a failed transaction block (one of the commands
2172 * caused an abort) so we do nothing but remain in the abort
2173 * state. Eventually we will get a ROLLBACK command which will
2174 * get us out of this state. (It is up to other code to ensure
2175 * that no commands other than ROLLBACK will be processed in these
2176 * states.)
2178 case TBLOCK_ABORT:
2179 case TBLOCK_SUBABORT:
2180 break;
2182 /* These cases are invalid. */
2183 case TBLOCK_STARTED:
2184 case TBLOCK_BEGIN:
2185 case TBLOCK_SUBBEGIN:
2186 case TBLOCK_END:
2187 case TBLOCK_SUBEND:
2188 case TBLOCK_ABORT_END:
2189 case TBLOCK_SUBABORT_END:
2190 case TBLOCK_ABORT_PENDING:
2191 case TBLOCK_SUBABORT_PENDING:
2192 case TBLOCK_SUBRESTART:
2193 case TBLOCK_SUBABORT_RESTART:
2194 case TBLOCK_PREPARE:
2195 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2196 BlockStateAsString(s->blockState));
2197 break;
2201 * We must switch to CurTransactionContext before returning. This is
2202 * already done if we called StartTransaction, otherwise not.
2204 Assert(CurTransactionContext != NULL);
2205 MemoryContextSwitchTo(CurTransactionContext);
2209 * CommitTransactionCommand
2211 void
2212 CommitTransactionCommand(void)
2214 TransactionState s = CurrentTransactionState;
2216 switch (s->blockState)
2219 * This shouldn't happen, because it means the previous
2220 * StartTransactionCommand didn't set the STARTED state
2221 * appropriately.
2223 case TBLOCK_DEFAULT:
2224 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2225 BlockStateAsString(s->blockState));
2226 break;
2229 * If we aren't in a transaction block, just do our usual
2230 * transaction commit, and return to the idle state.
2232 case TBLOCK_STARTED:
2233 CommitTransaction();
2234 s->blockState = TBLOCK_DEFAULT;
2235 break;
2238 * We are completing a "BEGIN TRANSACTION" command, so we change
2239 * to the "transaction block in progress" state and return. (We
2240 * assume the BEGIN did nothing to the database, so we need no
2241 * CommandCounterIncrement.)
2243 case TBLOCK_BEGIN:
2244 s->blockState = TBLOCK_INPROGRESS;
2245 break;
2248 * This is the case when we have finished executing a command
2249 * someplace within a transaction block. We increment the command
2250 * counter and return.
2252 case TBLOCK_INPROGRESS:
2253 case TBLOCK_SUBINPROGRESS:
2254 CommandCounterIncrement();
2255 break;
2258 * We are completing a "COMMIT" command. Do it and return to the
2259 * idle state.
2261 case TBLOCK_END:
2262 CommitTransaction();
2263 s->blockState = TBLOCK_DEFAULT;
2264 break;
2267 * Here we are in the middle of a transaction block but one of the
2268 * commands caused an abort so we do nothing but remain in the
2269 * abort state. Eventually we will get a ROLLBACK comand.
2271 case TBLOCK_ABORT:
2272 case TBLOCK_SUBABORT:
2273 break;
2276 * Here we were in an aborted transaction block and we just got
2277 * the ROLLBACK command from the user, so clean up the
2278 * already-aborted transaction and return to the idle state.
2280 case TBLOCK_ABORT_END:
2281 CleanupTransaction();
2282 s->blockState = TBLOCK_DEFAULT;
2283 break;
2286 * Here we were in a perfectly good transaction block but the user
2287 * told us to ROLLBACK anyway. We have to abort the transaction
2288 * and then clean up.
2290 case TBLOCK_ABORT_PENDING:
2291 AbortTransaction();
2292 CleanupTransaction();
2293 s->blockState = TBLOCK_DEFAULT;
2294 break;
2297 * We are completing a "PREPARE TRANSACTION" command. Do it and
2298 * return to the idle state.
2300 case TBLOCK_PREPARE:
2301 PrepareTransaction();
2302 s->blockState = TBLOCK_DEFAULT;
2303 break;
2306 * We were just issued a SAVEPOINT inside a transaction block.
2307 * Start a subtransaction. (DefineSavepoint already did
2308 * PushTransaction, so as to have someplace to put the SUBBEGIN
2309 * state.)
2311 case TBLOCK_SUBBEGIN:
2312 StartSubTransaction();
2313 s->blockState = TBLOCK_SUBINPROGRESS;
2314 break;
2317 * We were issued a COMMIT or RELEASE command, so we end the
2318 * current subtransaction and return to the parent transaction.
2319 * The parent might be ended too, so repeat till we are all the
2320 * way out or find an INPROGRESS transaction.
2322 case TBLOCK_SUBEND:
2325 CommitSubTransaction();
2326 s = CurrentTransactionState; /* changed by pop */
2327 } while (s->blockState == TBLOCK_SUBEND);
2328 /* If we had a COMMIT command, finish off the main xact too */
2329 if (s->blockState == TBLOCK_END)
2331 Assert(s->parent == NULL);
2332 CommitTransaction();
2333 s->blockState = TBLOCK_DEFAULT;
2335 else if (s->blockState == TBLOCK_PREPARE)
2337 Assert(s->parent == NULL);
2338 PrepareTransaction();
2339 s->blockState = TBLOCK_DEFAULT;
2341 else
2343 Assert(s->blockState == TBLOCK_INPROGRESS ||
2344 s->blockState == TBLOCK_SUBINPROGRESS);
2346 break;
2349 * The current already-failed subtransaction is ending due to a
2350 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2351 * examine the parent (which could be in any of several states).
2353 case TBLOCK_SUBABORT_END:
2354 CleanupSubTransaction();
2355 CommitTransactionCommand();
2356 break;
2359 * As above, but it's not dead yet, so abort first.
2361 case TBLOCK_SUBABORT_PENDING:
2362 AbortSubTransaction();
2363 CleanupSubTransaction();
2364 CommitTransactionCommand();
2365 break;
2368 * The current subtransaction is the target of a ROLLBACK TO
2369 * command. Abort and pop it, then start a new subtransaction
2370 * with the same name.
2372 case TBLOCK_SUBRESTART:
2374 char *name;
2375 int savepointLevel;
2377 /* save name and keep Cleanup from freeing it */
2378 name = s->name;
2379 s->name = NULL;
2380 savepointLevel = s->savepointLevel;
2382 AbortSubTransaction();
2383 CleanupSubTransaction();
2385 DefineSavepoint(NULL);
2386 s = CurrentTransactionState; /* changed by push */
2387 s->name = name;
2388 s->savepointLevel = savepointLevel;
2390 /* This is the same as TBLOCK_SUBBEGIN case */
2391 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2392 StartSubTransaction();
2393 s->blockState = TBLOCK_SUBINPROGRESS;
2395 break;
2398 * Same as above, but the subtransaction had already failed, so we
2399 * don't need AbortSubTransaction.
2401 case TBLOCK_SUBABORT_RESTART:
2403 char *name;
2404 int savepointLevel;
2406 /* save name and keep Cleanup from freeing it */
2407 name = s->name;
2408 s->name = NULL;
2409 savepointLevel = s->savepointLevel;
2411 CleanupSubTransaction();
2413 DefineSavepoint(NULL);
2414 s = CurrentTransactionState; /* changed by push */
2415 s->name = name;
2416 s->savepointLevel = savepointLevel;
2418 /* This is the same as TBLOCK_SUBBEGIN case */
2419 AssertState(s->blockState == TBLOCK_SUBBEGIN);
2420 StartSubTransaction();
2421 s->blockState = TBLOCK_SUBINPROGRESS;
2423 break;
2428 * AbortCurrentTransaction
2430 void
2431 AbortCurrentTransaction(void)
2433 TransactionState s = CurrentTransactionState;
2435 switch (s->blockState)
2437 case TBLOCK_DEFAULT:
2438 if (s->state == TRANS_DEFAULT)
2440 /* we are idle, so nothing to do */
2442 else
2445 * We can get here after an error during transaction start
2446 * (state will be TRANS_START). Need to clean up the
2447 * incompletely started transaction. First, adjust the
2448 * low-level state to suppress warning message from
2449 * AbortTransaction.
2451 if (s->state == TRANS_START)
2452 s->state = TRANS_INPROGRESS;
2453 AbortTransaction();
2454 CleanupTransaction();
2456 break;
2459 * if we aren't in a transaction block, we just do the basic abort
2460 * & cleanup transaction.
2462 case TBLOCK_STARTED:
2463 AbortTransaction();
2464 CleanupTransaction();
2465 s->blockState = TBLOCK_DEFAULT;
2466 break;
2469 * If we are in TBLOCK_BEGIN it means something screwed up right
2470 * after reading "BEGIN TRANSACTION". We assume that the user
2471 * will interpret the error as meaning the BEGIN failed to get him
2472 * into a transaction block, so we should abort and return to idle
2473 * state.
2475 case TBLOCK_BEGIN:
2476 AbortTransaction();
2477 CleanupTransaction();
2478 s->blockState = TBLOCK_DEFAULT;
2479 break;
2482 * We are somewhere in a transaction block and we've gotten a
2483 * failure, so we abort the transaction and set up the persistent
2484 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
2486 case TBLOCK_INPROGRESS:
2487 AbortTransaction();
2488 s->blockState = TBLOCK_ABORT;
2489 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
2490 break;
2493 * Here, we failed while trying to COMMIT. Clean up the
2494 * transaction and return to idle state (we do not want to stay in
2495 * the transaction).
2497 case TBLOCK_END:
2498 AbortTransaction();
2499 CleanupTransaction();
2500 s->blockState = TBLOCK_DEFAULT;
2501 break;
2504 * Here, we are already in an aborted transaction state and are
2505 * waiting for a ROLLBACK, but for some reason we failed again! So
2506 * we just remain in the abort state.
2508 case TBLOCK_ABORT:
2509 case TBLOCK_SUBABORT:
2510 break;
2513 * We are in a failed transaction and we got the ROLLBACK command.
2514 * We have already aborted, we just need to cleanup and go to idle
2515 * state.
2517 case TBLOCK_ABORT_END:
2518 CleanupTransaction();
2519 s->blockState = TBLOCK_DEFAULT;
2520 break;
2523 * We are in a live transaction and we got a ROLLBACK command.
2524 * Abort, cleanup, go to idle state.
2526 case TBLOCK_ABORT_PENDING:
2527 AbortTransaction();
2528 CleanupTransaction();
2529 s->blockState = TBLOCK_DEFAULT;
2530 break;
2533 * Here, we failed while trying to PREPARE. Clean up the
2534 * transaction and return to idle state (we do not want to stay in
2535 * the transaction).
2537 case TBLOCK_PREPARE:
2538 AbortTransaction();
2539 CleanupTransaction();
2540 s->blockState = TBLOCK_DEFAULT;
2541 break;
2544 * We got an error inside a subtransaction. Abort just the
2545 * subtransaction, and go to the persistent SUBABORT state until
2546 * we get ROLLBACK.
2548 case TBLOCK_SUBINPROGRESS:
2549 AbortSubTransaction();
2550 s->blockState = TBLOCK_SUBABORT;
2551 break;
2554 * If we failed while trying to create a subtransaction, clean up
2555 * the broken subtransaction and abort the parent. The same
2556 * applies if we get a failure while ending a subtransaction.
2558 case TBLOCK_SUBBEGIN:
2559 case TBLOCK_SUBEND:
2560 case TBLOCK_SUBABORT_PENDING:
2561 case TBLOCK_SUBRESTART:
2562 AbortSubTransaction();
2563 CleanupSubTransaction();
2564 AbortCurrentTransaction();
2565 break;
2568 * Same as above, except the Abort() was already done.
2570 case TBLOCK_SUBABORT_END:
2571 case TBLOCK_SUBABORT_RESTART:
2572 CleanupSubTransaction();
2573 AbortCurrentTransaction();
2574 break;
2579 * PreventTransactionChain
2581 * This routine is to be called by statements that must not run inside
2582 * a transaction block, typically because they have non-rollback-able
2583 * side effects or do internal commits.
2585 * If we have already started a transaction block, issue an error; also issue
2586 * an error if we appear to be running inside a user-defined function (which
2587 * could issue more commands and possibly cause a failure after the statement
2588 * completes). Subtransactions are verboten too.
2590 * isTopLevel: passed down from ProcessUtility to determine whether we are
2591 * inside a function or multi-query querystring. (We will always fail if
2592 * this is false, but it's convenient to centralize the check here instead of
2593 * making callers do it.)
2594 * stmtType: statement type name, for error messages.
2596 void
2597 PreventTransactionChain(bool isTopLevel, const char *stmtType)
2600 * xact block already started?
2602 if (IsTransactionBlock())
2603 ereport(ERROR,
2604 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2605 /* translator: %s represents an SQL statement name */
2606 errmsg("%s cannot run inside a transaction block",
2607 stmtType)));
2610 * subtransaction?
2612 if (IsSubTransaction())
2613 ereport(ERROR,
2614 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2615 /* translator: %s represents an SQL statement name */
2616 errmsg("%s cannot run inside a subtransaction",
2617 stmtType)));
2620 * inside a function call?
2622 if (!isTopLevel)
2623 ereport(ERROR,
2624 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2625 /* translator: %s represents an SQL statement name */
2626 errmsg("%s cannot be executed from a function or multi-command string",
2627 stmtType)));
2629 /* If we got past IsTransactionBlock test, should be in default state */
2630 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2631 CurrentTransactionState->blockState != TBLOCK_STARTED)
2632 elog(FATAL, "cannot prevent transaction chain");
2633 /* all okay */
2637 * RequireTransactionChain
2639 * This routine is to be called by statements that must run inside
2640 * a transaction block, because they have no effects that persist past
2641 * transaction end (and so calling them outside a transaction block
2642 * is presumably an error). DECLARE CURSOR is an example.
2644 * If we appear to be running inside a user-defined function, we do not
2645 * issue an error, since the function could issue more commands that make
2646 * use of the current statement's results. Likewise subtransactions.
2647 * Thus this is an inverse for PreventTransactionChain.
2649 * isTopLevel: passed down from ProcessUtility to determine whether we are
2650 * inside a function.
2651 * stmtType: statement type name, for error messages.
2653 void
2654 RequireTransactionChain(bool isTopLevel, const char *stmtType)
2657 * xact block already started?
2659 if (IsTransactionBlock())
2660 return;
2663 * subtransaction?
2665 if (IsSubTransaction())
2666 return;
2669 * inside a function call?
2671 if (!isTopLevel)
2672 return;
2674 ereport(ERROR,
2675 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
2676 /* translator: %s represents an SQL statement name */
2677 errmsg("%s can only be used in transaction blocks",
2678 stmtType)));
2682 * IsInTransactionChain
2684 * This routine is for statements that need to behave differently inside
2685 * a transaction block than when running as single commands. ANALYZE is
2686 * currently the only example.
2688 * isTopLevel: passed down from ProcessUtility to determine whether we are
2689 * inside a function.
2691 bool
2692 IsInTransactionChain(bool isTopLevel)
2695 * Return true on same conditions that would make PreventTransactionChain
2696 * error out
2698 if (IsTransactionBlock())
2699 return true;
2701 if (IsSubTransaction())
2702 return true;
2704 if (!isTopLevel)
2705 return true;
2707 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
2708 CurrentTransactionState->blockState != TBLOCK_STARTED)
2709 return true;
2711 return false;
2716 * Register or deregister callback functions for start- and end-of-xact
2717 * operations.
2719 * These functions are intended for use by dynamically loaded modules.
2720 * For built-in modules we generally just hardwire the appropriate calls
2721 * (mainly because it's easier to control the order that way, where needed).
2723 * At transaction end, the callback occurs post-commit or post-abort, so the
2724 * callback functions can only do noncritical cleanup.
2726 void
2727 RegisterXactCallback(XactCallback callback, void *arg)
2729 XactCallbackItem *item;
2731 item = (XactCallbackItem *)
2732 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
2733 item->callback = callback;
2734 item->arg = arg;
2735 item->next = Xact_callbacks;
2736 Xact_callbacks = item;
2739 void
2740 UnregisterXactCallback(XactCallback callback, void *arg)
2742 XactCallbackItem *item;
2743 XactCallbackItem *prev;
2745 prev = NULL;
2746 for (item = Xact_callbacks; item; prev = item, item = item->next)
2748 if (item->callback == callback && item->arg == arg)
2750 if (prev)
2751 prev->next = item->next;
2752 else
2753 Xact_callbacks = item->next;
2754 pfree(item);
2755 break;
2760 static void
2761 CallXactCallbacks(XactEvent event)
2763 XactCallbackItem *item;
2765 for (item = Xact_callbacks; item; item = item->next)
2766 (*item->callback) (event, item->arg);
2771 * Register or deregister callback functions for start- and end-of-subxact
2772 * operations.
2774 * Pretty much same as above, but for subtransaction events.
2776 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
2777 * so the callback functions can only do noncritical cleanup. At
2778 * subtransaction start, the callback is called when the subtransaction has
2779 * finished initializing.
2781 void
2782 RegisterSubXactCallback(SubXactCallback callback, void *arg)
2784 SubXactCallbackItem *item;
2786 item = (SubXactCallbackItem *)
2787 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
2788 item->callback = callback;
2789 item->arg = arg;
2790 item->next = SubXact_callbacks;
2791 SubXact_callbacks = item;
2794 void
2795 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
2797 SubXactCallbackItem *item;
2798 SubXactCallbackItem *prev;
2800 prev = NULL;
2801 for (item = SubXact_callbacks; item; prev = item, item = item->next)
2803 if (item->callback == callback && item->arg == arg)
2805 if (prev)
2806 prev->next = item->next;
2807 else
2808 SubXact_callbacks = item->next;
2809 pfree(item);
2810 break;
2815 static void
2816 CallSubXactCallbacks(SubXactEvent event,
2817 SubTransactionId mySubid,
2818 SubTransactionId parentSubid)
2820 SubXactCallbackItem *item;
2822 for (item = SubXact_callbacks; item; item = item->next)
2823 (*item->callback) (event, mySubid, parentSubid, item->arg);
2827 /* ----------------------------------------------------------------
2828 * transaction block support
2829 * ----------------------------------------------------------------
2833 * BeginTransactionBlock
2834 * This executes a BEGIN command.
2836 void
2837 BeginTransactionBlock(void)
2839 TransactionState s = CurrentTransactionState;
2841 switch (s->blockState)
2844 * We are not inside a transaction block, so allow one to begin.
2846 case TBLOCK_STARTED:
2847 s->blockState = TBLOCK_BEGIN;
2848 break;
2851 * Already a transaction block in progress.
2853 case TBLOCK_INPROGRESS:
2854 case TBLOCK_SUBINPROGRESS:
2855 case TBLOCK_ABORT:
2856 case TBLOCK_SUBABORT:
2857 ereport(WARNING,
2858 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
2859 errmsg("there is already a transaction in progress")));
2860 break;
2862 /* These cases are invalid. */
2863 case TBLOCK_DEFAULT:
2864 case TBLOCK_BEGIN:
2865 case TBLOCK_SUBBEGIN:
2866 case TBLOCK_END:
2867 case TBLOCK_SUBEND:
2868 case TBLOCK_ABORT_END:
2869 case TBLOCK_SUBABORT_END:
2870 case TBLOCK_ABORT_PENDING:
2871 case TBLOCK_SUBABORT_PENDING:
2872 case TBLOCK_SUBRESTART:
2873 case TBLOCK_SUBABORT_RESTART:
2874 case TBLOCK_PREPARE:
2875 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
2876 BlockStateAsString(s->blockState));
2877 break;
2882 * PrepareTransactionBlock
2883 * This executes a PREPARE command.
2885 * Since PREPARE may actually do a ROLLBACK, the result indicates what
2886 * happened: TRUE for PREPARE, FALSE for ROLLBACK.
2888 * Note that we don't actually do anything here except change blockState.
2889 * The real work will be done in the upcoming PrepareTransaction().
2890 * We do it this way because it's not convenient to change memory context,
2891 * resource owner, etc while executing inside a Portal.
2893 bool
2894 PrepareTransactionBlock(char *gid)
2896 TransactionState s;
2897 bool result;
2899 /* Set up to commit the current transaction */
2900 result = EndTransactionBlock();
2902 /* If successful, change outer tblock state to PREPARE */
2903 if (result)
2905 s = CurrentTransactionState;
2907 while (s->parent != NULL)
2908 s = s->parent;
2910 if (s->blockState == TBLOCK_END)
2912 /* Save GID where PrepareTransaction can find it again */
2913 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
2915 s->blockState = TBLOCK_PREPARE;
2917 else
2920 * ignore case where we are not in a transaction;
2921 * EndTransactionBlock already issued a warning.
2923 Assert(s->blockState == TBLOCK_STARTED);
2924 /* Don't send back a PREPARE result tag... */
2925 result = false;
2929 return result;
2933 * EndTransactionBlock
2934 * This executes a COMMIT command.
2936 * Since COMMIT may actually do a ROLLBACK, the result indicates what
2937 * happened: TRUE for COMMIT, FALSE for ROLLBACK.
2939 * Note that we don't actually do anything here except change blockState.
2940 * The real work will be done in the upcoming CommitTransactionCommand().
2941 * We do it this way because it's not convenient to change memory context,
2942 * resource owner, etc while executing inside a Portal.
2944 bool
2945 EndTransactionBlock(void)
2947 TransactionState s = CurrentTransactionState;
2948 bool result = false;
2950 switch (s->blockState)
2953 * We are in a transaction block, so tell CommitTransactionCommand
2954 * to COMMIT.
2956 case TBLOCK_INPROGRESS:
2957 s->blockState = TBLOCK_END;
2958 result = true;
2959 break;
2962 * We are in a failed transaction block. Tell
2963 * CommitTransactionCommand it's time to exit the block.
2965 case TBLOCK_ABORT:
2966 s->blockState = TBLOCK_ABORT_END;
2967 break;
2970 * We are in a live subtransaction block. Set up to subcommit all
2971 * open subtransactions and then commit the main transaction.
2973 case TBLOCK_SUBINPROGRESS:
2974 while (s->parent != NULL)
2976 if (s->blockState == TBLOCK_SUBINPROGRESS)
2977 s->blockState = TBLOCK_SUBEND;
2978 else
2979 elog(FATAL, "EndTransactionBlock: unexpected state %s",
2980 BlockStateAsString(s->blockState));
2981 s = s->parent;
2983 if (s->blockState == TBLOCK_INPROGRESS)
2984 s->blockState = TBLOCK_END;
2985 else
2986 elog(FATAL, "EndTransactionBlock: unexpected state %s",
2987 BlockStateAsString(s->blockState));
2988 result = true;
2989 break;
2992 * Here we are inside an aborted subtransaction. Treat the COMMIT
2993 * as ROLLBACK: set up to abort everything and exit the main
2994 * transaction.
2996 case TBLOCK_SUBABORT:
2997 while (s->parent != NULL)
2999 if (s->blockState == TBLOCK_SUBINPROGRESS)
3000 s->blockState = TBLOCK_SUBABORT_PENDING;
3001 else if (s->blockState == TBLOCK_SUBABORT)
3002 s->blockState = TBLOCK_SUBABORT_END;
3003 else
3004 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3005 BlockStateAsString(s->blockState));
3006 s = s->parent;
3008 if (s->blockState == TBLOCK_INPROGRESS)
3009 s->blockState = TBLOCK_ABORT_PENDING;
3010 else if (s->blockState == TBLOCK_ABORT)
3011 s->blockState = TBLOCK_ABORT_END;
3012 else
3013 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3014 BlockStateAsString(s->blockState));
3015 break;
3018 * The user issued COMMIT when not inside a transaction. Issue a
3019 * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
3020 * CommitTransactionCommand() will then close the transaction and
3021 * put us back into the default state.
3023 case TBLOCK_STARTED:
3024 ereport(WARNING,
3025 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3026 errmsg("there is no transaction in progress")));
3027 result = true;
3028 break;
3030 /* These cases are invalid. */
3031 case TBLOCK_DEFAULT:
3032 case TBLOCK_BEGIN:
3033 case TBLOCK_SUBBEGIN:
3034 case TBLOCK_END:
3035 case TBLOCK_SUBEND:
3036 case TBLOCK_ABORT_END:
3037 case TBLOCK_SUBABORT_END:
3038 case TBLOCK_ABORT_PENDING:
3039 case TBLOCK_SUBABORT_PENDING:
3040 case TBLOCK_SUBRESTART:
3041 case TBLOCK_SUBABORT_RESTART:
3042 case TBLOCK_PREPARE:
3043 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3044 BlockStateAsString(s->blockState));
3045 break;
3048 return result;
3052 * UserAbortTransactionBlock
3053 * This executes a ROLLBACK command.
3055 * As above, we don't actually do anything here except change blockState.
3057 void
3058 UserAbortTransactionBlock(void)
3060 TransactionState s = CurrentTransactionState;
3062 switch (s->blockState)
3065 * We are inside a transaction block and we got a ROLLBACK command
3066 * from the user, so tell CommitTransactionCommand to abort and
3067 * exit the transaction block.
3069 case TBLOCK_INPROGRESS:
3070 s->blockState = TBLOCK_ABORT_PENDING;
3071 break;
3074 * We are inside a failed transaction block and we got a ROLLBACK
3075 * command from the user. Abort processing is already done, so
3076 * CommitTransactionCommand just has to cleanup and go back to
3077 * idle state.
3079 case TBLOCK_ABORT:
3080 s->blockState = TBLOCK_ABORT_END;
3081 break;
3084 * We are inside a subtransaction. Mark everything up to top
3085 * level as exitable.
3087 case TBLOCK_SUBINPROGRESS:
3088 case TBLOCK_SUBABORT:
3089 while (s->parent != NULL)
3091 if (s->blockState == TBLOCK_SUBINPROGRESS)
3092 s->blockState = TBLOCK_SUBABORT_PENDING;
3093 else if (s->blockState == TBLOCK_SUBABORT)
3094 s->blockState = TBLOCK_SUBABORT_END;
3095 else
3096 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3097 BlockStateAsString(s->blockState));
3098 s = s->parent;
3100 if (s->blockState == TBLOCK_INPROGRESS)
3101 s->blockState = TBLOCK_ABORT_PENDING;
3102 else if (s->blockState == TBLOCK_ABORT)
3103 s->blockState = TBLOCK_ABORT_END;
3104 else
3105 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3106 BlockStateAsString(s->blockState));
3107 break;
3110 * The user issued ABORT when not inside a transaction. Issue a
3111 * WARNING and go to abort state. The upcoming call to
3112 * CommitTransactionCommand() will then put us back into the
3113 * default state.
3115 case TBLOCK_STARTED:
3116 ereport(NOTICE,
3117 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3118 errmsg("there is no transaction in progress")));
3119 s->blockState = TBLOCK_ABORT_PENDING;
3120 break;
3122 /* These cases are invalid. */
3123 case TBLOCK_DEFAULT:
3124 case TBLOCK_BEGIN:
3125 case TBLOCK_SUBBEGIN:
3126 case TBLOCK_END:
3127 case TBLOCK_SUBEND:
3128 case TBLOCK_ABORT_END:
3129 case TBLOCK_SUBABORT_END:
3130 case TBLOCK_ABORT_PENDING:
3131 case TBLOCK_SUBABORT_PENDING:
3132 case TBLOCK_SUBRESTART:
3133 case TBLOCK_SUBABORT_RESTART:
3134 case TBLOCK_PREPARE:
3135 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3136 BlockStateAsString(s->blockState));
3137 break;
3142 * DefineSavepoint
3143 * This executes a SAVEPOINT command.
3145 void
3146 DefineSavepoint(char *name)
3148 TransactionState s = CurrentTransactionState;
3150 switch (s->blockState)
3152 case TBLOCK_INPROGRESS:
3153 case TBLOCK_SUBINPROGRESS:
3154 /* Normal subtransaction start */
3155 PushTransaction();
3156 s = CurrentTransactionState; /* changed by push */
3159 * Savepoint names, like the TransactionState block itself, live
3160 * in TopTransactionContext.
3162 if (name)
3163 s->name = MemoryContextStrdup(TopTransactionContext, name);
3164 break;
3166 /* These cases are invalid. */
3167 case TBLOCK_DEFAULT:
3168 case TBLOCK_STARTED:
3169 case TBLOCK_BEGIN:
3170 case TBLOCK_SUBBEGIN:
3171 case TBLOCK_END:
3172 case TBLOCK_SUBEND:
3173 case TBLOCK_ABORT:
3174 case TBLOCK_SUBABORT:
3175 case TBLOCK_ABORT_END:
3176 case TBLOCK_SUBABORT_END:
3177 case TBLOCK_ABORT_PENDING:
3178 case TBLOCK_SUBABORT_PENDING:
3179 case TBLOCK_SUBRESTART:
3180 case TBLOCK_SUBABORT_RESTART:
3181 case TBLOCK_PREPARE:
3182 elog(FATAL, "DefineSavepoint: unexpected state %s",
3183 BlockStateAsString(s->blockState));
3184 break;
3189 * ReleaseSavepoint
3190 * This executes a RELEASE command.
3192 * As above, we don't actually do anything here except change blockState.
3194 void
3195 ReleaseSavepoint(List *options)
3197 TransactionState s = CurrentTransactionState;
3198 TransactionState target,
3199 xact;
3200 ListCell *cell;
3201 char *name = NULL;
3203 switch (s->blockState)
3206 * We can't rollback to a savepoint if there is no savepoint
3207 * defined.
3209 case TBLOCK_INPROGRESS:
3210 ereport(ERROR,
3211 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3212 errmsg("no such savepoint")));
3213 break;
3216 * We are in a non-aborted subtransaction. This is the only valid
3217 * case.
3219 case TBLOCK_SUBINPROGRESS:
3220 break;
3222 /* These cases are invalid. */
3223 case TBLOCK_DEFAULT:
3224 case TBLOCK_STARTED:
3225 case TBLOCK_BEGIN:
3226 case TBLOCK_SUBBEGIN:
3227 case TBLOCK_END:
3228 case TBLOCK_SUBEND:
3229 case TBLOCK_ABORT:
3230 case TBLOCK_SUBABORT:
3231 case TBLOCK_ABORT_END:
3232 case TBLOCK_SUBABORT_END:
3233 case TBLOCK_ABORT_PENDING:
3234 case TBLOCK_SUBABORT_PENDING:
3235 case TBLOCK_SUBRESTART:
3236 case TBLOCK_SUBABORT_RESTART:
3237 case TBLOCK_PREPARE:
3238 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3239 BlockStateAsString(s->blockState));
3240 break;
3243 foreach(cell, options)
3245 DefElem *elem = lfirst(cell);
3247 if (strcmp(elem->defname, "savepoint_name") == 0)
3248 name = strVal(elem->arg);
3251 Assert(PointerIsValid(name));
3253 for (target = s; PointerIsValid(target); target = target->parent)
3255 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3256 break;
3259 if (!PointerIsValid(target))
3260 ereport(ERROR,
3261 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3262 errmsg("no such savepoint")));
3264 /* disallow crossing savepoint level boundaries */
3265 if (target->savepointLevel != s->savepointLevel)
3266 ereport(ERROR,
3267 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3268 errmsg("no such savepoint")));
3271 * Mark "commit pending" all subtransactions up to the target
3272 * subtransaction. The actual commits will happen when control gets to
3273 * CommitTransactionCommand.
3275 xact = CurrentTransactionState;
3276 for (;;)
3278 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3279 xact->blockState = TBLOCK_SUBEND;
3280 if (xact == target)
3281 break;
3282 xact = xact->parent;
3283 Assert(PointerIsValid(xact));
3288 * RollbackToSavepoint
3289 * This executes a ROLLBACK TO <savepoint> command.
3291 * As above, we don't actually do anything here except change blockState.
3293 void
3294 RollbackToSavepoint(List *options)
3296 TransactionState s = CurrentTransactionState;
3297 TransactionState target,
3298 xact;
3299 ListCell *cell;
3300 char *name = NULL;
3302 switch (s->blockState)
3305 * We can't rollback to a savepoint if there is no savepoint
3306 * defined.
3308 case TBLOCK_INPROGRESS:
3309 case TBLOCK_ABORT:
3310 ereport(ERROR,
3311 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3312 errmsg("no such savepoint")));
3313 break;
3316 * There is at least one savepoint, so proceed.
3318 case TBLOCK_SUBINPROGRESS:
3319 case TBLOCK_SUBABORT:
3320 break;
3322 /* These cases are invalid. */
3323 case TBLOCK_DEFAULT:
3324 case TBLOCK_STARTED:
3325 case TBLOCK_BEGIN:
3326 case TBLOCK_SUBBEGIN:
3327 case TBLOCK_END:
3328 case TBLOCK_SUBEND:
3329 case TBLOCK_ABORT_END:
3330 case TBLOCK_SUBABORT_END:
3331 case TBLOCK_ABORT_PENDING:
3332 case TBLOCK_SUBABORT_PENDING:
3333 case TBLOCK_SUBRESTART:
3334 case TBLOCK_SUBABORT_RESTART:
3335 case TBLOCK_PREPARE:
3336 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3337 BlockStateAsString(s->blockState));
3338 break;
3341 foreach(cell, options)
3343 DefElem *elem = lfirst(cell);
3345 if (strcmp(elem->defname, "savepoint_name") == 0)
3346 name = strVal(elem->arg);
3349 Assert(PointerIsValid(name));
3351 for (target = s; PointerIsValid(target); target = target->parent)
3353 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3354 break;
3357 if (!PointerIsValid(target))
3358 ereport(ERROR,
3359 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3360 errmsg("no such savepoint")));
3362 /* disallow crossing savepoint level boundaries */
3363 if (target->savepointLevel != s->savepointLevel)
3364 ereport(ERROR,
3365 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3366 errmsg("no such savepoint")));
3369 * Mark "abort pending" all subtransactions up to the target
3370 * subtransaction. The actual aborts will happen when control gets to
3371 * CommitTransactionCommand.
3373 xact = CurrentTransactionState;
3374 for (;;)
3376 if (xact == target)
3377 break;
3378 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3379 xact->blockState = TBLOCK_SUBABORT_PENDING;
3380 else if (xact->blockState == TBLOCK_SUBABORT)
3381 xact->blockState = TBLOCK_SUBABORT_END;
3382 else
3383 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3384 BlockStateAsString(xact->blockState));
3385 xact = xact->parent;
3386 Assert(PointerIsValid(xact));
3389 /* And mark the target as "restart pending" */
3390 if (xact->blockState == TBLOCK_SUBINPROGRESS)
3391 xact->blockState = TBLOCK_SUBRESTART;
3392 else if (xact->blockState == TBLOCK_SUBABORT)
3393 xact->blockState = TBLOCK_SUBABORT_RESTART;
3394 else
3395 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
3396 BlockStateAsString(xact->blockState));
3400 * BeginInternalSubTransaction
3401 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
3402 * TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
3403 * used in functions that might be called when not inside a BEGIN block
3404 * or when running deferred triggers at COMMIT/PREPARE time. Also, it
3405 * automatically does CommitTransactionCommand/StartTransactionCommand
3406 * instead of expecting the caller to do it.
3408 void
3409 BeginInternalSubTransaction(char *name)
3411 TransactionState s = CurrentTransactionState;
3413 switch (s->blockState)
3415 case TBLOCK_STARTED:
3416 case TBLOCK_INPROGRESS:
3417 case TBLOCK_END:
3418 case TBLOCK_PREPARE:
3419 case TBLOCK_SUBINPROGRESS:
3420 /* Normal subtransaction start */
3421 PushTransaction();
3422 s = CurrentTransactionState; /* changed by push */
3425 * Savepoint names, like the TransactionState block itself, live
3426 * in TopTransactionContext.
3428 if (name)
3429 s->name = MemoryContextStrdup(TopTransactionContext, name);
3430 break;
3432 /* These cases are invalid. */
3433 case TBLOCK_DEFAULT:
3434 case TBLOCK_BEGIN:
3435 case TBLOCK_SUBBEGIN:
3436 case TBLOCK_SUBEND:
3437 case TBLOCK_ABORT:
3438 case TBLOCK_SUBABORT:
3439 case TBLOCK_ABORT_END:
3440 case TBLOCK_SUBABORT_END:
3441 case TBLOCK_ABORT_PENDING:
3442 case TBLOCK_SUBABORT_PENDING:
3443 case TBLOCK_SUBRESTART:
3444 case TBLOCK_SUBABORT_RESTART:
3445 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
3446 BlockStateAsString(s->blockState));
3447 break;
3450 CommitTransactionCommand();
3451 StartTransactionCommand();
3455 * ReleaseCurrentSubTransaction
3457 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
3458 * savepoint name (if any).
3459 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3461 void
3462 ReleaseCurrentSubTransaction(void)
3464 TransactionState s = CurrentTransactionState;
3466 if (s->blockState != TBLOCK_SUBINPROGRESS)
3467 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
3468 BlockStateAsString(s->blockState));
3469 Assert(s->state == TRANS_INPROGRESS);
3470 MemoryContextSwitchTo(CurTransactionContext);
3471 CommitSubTransaction();
3472 s = CurrentTransactionState; /* changed by pop */
3473 Assert(s->state == TRANS_INPROGRESS);
3477 * RollbackAndReleaseCurrentSubTransaction
3479 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
3480 * of its savepoint name (if any).
3481 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
3483 void
3484 RollbackAndReleaseCurrentSubTransaction(void)
3486 TransactionState s = CurrentTransactionState;
3488 switch (s->blockState)
3490 /* Must be in a subtransaction */
3491 case TBLOCK_SUBINPROGRESS:
3492 case TBLOCK_SUBABORT:
3493 break;
3495 /* These cases are invalid. */
3496 case TBLOCK_DEFAULT:
3497 case TBLOCK_STARTED:
3498 case TBLOCK_BEGIN:
3499 case TBLOCK_SUBBEGIN:
3500 case TBLOCK_INPROGRESS:
3501 case TBLOCK_END:
3502 case TBLOCK_SUBEND:
3503 case TBLOCK_ABORT:
3504 case TBLOCK_ABORT_END:
3505 case TBLOCK_SUBABORT_END:
3506 case TBLOCK_ABORT_PENDING:
3507 case TBLOCK_SUBABORT_PENDING:
3508 case TBLOCK_SUBRESTART:
3509 case TBLOCK_SUBABORT_RESTART:
3510 case TBLOCK_PREPARE:
3511 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
3512 BlockStateAsString(s->blockState));
3513 break;
3517 * Abort the current subtransaction, if needed.
3519 if (s->blockState == TBLOCK_SUBINPROGRESS)
3520 AbortSubTransaction();
3522 /* And clean it up, too */
3523 CleanupSubTransaction();
3525 s = CurrentTransactionState; /* changed by pop */
3526 AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
3527 s->blockState == TBLOCK_INPROGRESS ||
3528 s->blockState == TBLOCK_STARTED);
3532 * AbortOutOfAnyTransaction
3534 * This routine is provided for error recovery purposes. It aborts any
3535 * active transaction or transaction block, leaving the system in a known
3536 * idle state.
3538 void
3539 AbortOutOfAnyTransaction(void)
3541 TransactionState s = CurrentTransactionState;
3544 * Get out of any transaction or nested transaction
3548 switch (s->blockState)
3550 case TBLOCK_DEFAULT:
3551 /* Not in a transaction, do nothing */
3552 break;
3553 case TBLOCK_STARTED:
3554 case TBLOCK_BEGIN:
3555 case TBLOCK_INPROGRESS:
3556 case TBLOCK_END:
3557 case TBLOCK_ABORT_PENDING:
3558 case TBLOCK_PREPARE:
3559 /* In a transaction, so clean up */
3560 AbortTransaction();
3561 CleanupTransaction();
3562 s->blockState = TBLOCK_DEFAULT;
3563 break;
3564 case TBLOCK_ABORT:
3565 case TBLOCK_ABORT_END:
3566 /* AbortTransaction already done, still need Cleanup */
3567 CleanupTransaction();
3568 s->blockState = TBLOCK_DEFAULT;
3569 break;
3572 * In a subtransaction, so clean it up and abort parent too
3574 case TBLOCK_SUBBEGIN:
3575 case TBLOCK_SUBINPROGRESS:
3576 case TBLOCK_SUBEND:
3577 case TBLOCK_SUBABORT_PENDING:
3578 case TBLOCK_SUBRESTART:
3579 AbortSubTransaction();
3580 CleanupSubTransaction();
3581 s = CurrentTransactionState; /* changed by pop */
3582 break;
3584 case TBLOCK_SUBABORT:
3585 case TBLOCK_SUBABORT_END:
3586 case TBLOCK_SUBABORT_RESTART:
3587 /* As above, but AbortSubTransaction already done */
3588 CleanupSubTransaction();
3589 s = CurrentTransactionState; /* changed by pop */
3590 break;
3592 } while (s->blockState != TBLOCK_DEFAULT);
3594 /* Should be out of all subxacts now */
3595 Assert(s->parent == NULL);
3599 * IsTransactionBlock --- are we within a transaction block?
3601 bool
3602 IsTransactionBlock(void)
3604 TransactionState s = CurrentTransactionState;
3606 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
3607 return false;
3609 return true;
3613 * IsTransactionOrTransactionBlock --- are we within either a transaction
3614 * or a transaction block? (The backend is only really "idle" when this
3615 * returns false.)
3617 * This should match up with IsTransactionBlock and IsTransactionState.
3619 bool
3620 IsTransactionOrTransactionBlock(void)
3622 TransactionState s = CurrentTransactionState;
3624 if (s->blockState == TBLOCK_DEFAULT)
3625 return false;
3627 return true;
3631 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
3633 char
3634 TransactionBlockStatusCode(void)
3636 TransactionState s = CurrentTransactionState;
3638 switch (s->blockState)
3640 case TBLOCK_DEFAULT:
3641 case TBLOCK_STARTED:
3642 return 'I'; /* idle --- not in transaction */
3643 case TBLOCK_BEGIN:
3644 case TBLOCK_SUBBEGIN:
3645 case TBLOCK_INPROGRESS:
3646 case TBLOCK_SUBINPROGRESS:
3647 case TBLOCK_END:
3648 case TBLOCK_SUBEND:
3649 case TBLOCK_PREPARE:
3650 return 'T'; /* in transaction */
3651 case TBLOCK_ABORT:
3652 case TBLOCK_SUBABORT:
3653 case TBLOCK_ABORT_END:
3654 case TBLOCK_SUBABORT_END:
3655 case TBLOCK_ABORT_PENDING:
3656 case TBLOCK_SUBABORT_PENDING:
3657 case TBLOCK_SUBRESTART:
3658 case TBLOCK_SUBABORT_RESTART:
3659 return 'E'; /* in failed transaction */
3662 /* should never get here */
3663 elog(FATAL, "invalid transaction block state: %s",
3664 BlockStateAsString(s->blockState));
3665 return 0; /* keep compiler quiet */
3669 * IsSubTransaction
3671 bool
3672 IsSubTransaction(void)
3674 TransactionState s = CurrentTransactionState;
3676 if (s->nestingLevel >= 2)
3677 return true;
3679 return false;
3683 * StartSubTransaction
3685 * If you're wondering why this is separate from PushTransaction: it's because
3686 * we can't conveniently do this stuff right inside DefineSavepoint. The
3687 * SAVEPOINT utility command will be executed inside a Portal, and if we
3688 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
3689 * the Portal will undo those settings. So we make DefineSavepoint just
3690 * push a dummy transaction block, and when control returns to the main
3691 * idle loop, CommitTransactionCommand will be called, and we'll come here
3692 * to finish starting the subtransaction.
3694 static void
3695 StartSubTransaction(void)
3697 TransactionState s = CurrentTransactionState;
3699 if (s->state != TRANS_DEFAULT)
3700 elog(WARNING, "StartSubTransaction while in %s state",
3701 TransStateAsString(s->state));
3703 s->state = TRANS_START;
3706 * Initialize subsystems for new subtransaction
3708 * must initialize resource-management stuff first
3710 AtSubStart_Memory();
3711 AtSubStart_ResourceOwner();
3712 AtSubStart_Inval();
3713 AtSubStart_Notify();
3714 AfterTriggerBeginSubXact();
3716 s->state = TRANS_INPROGRESS;
3719 * Call start-of-subxact callbacks
3721 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
3722 s->parent->subTransactionId);
3724 ShowTransactionState("StartSubTransaction");
3728 * CommitSubTransaction
3730 * The caller has to make sure to always reassign CurrentTransactionState
3731 * if it has a local pointer to it after calling this function.
3733 static void
3734 CommitSubTransaction(void)
3736 TransactionState s = CurrentTransactionState;
3738 ShowTransactionState("CommitSubTransaction");
3740 if (s->state != TRANS_INPROGRESS)
3741 elog(WARNING, "CommitSubTransaction while in %s state",
3742 TransStateAsString(s->state));
3744 /* Pre-commit processing goes here -- nothing to do at the moment */
3746 s->state = TRANS_COMMIT;
3748 /* Must CCI to ensure commands of subtransaction are seen as done */
3749 CommandCounterIncrement();
3752 * Prior to 8.4 we marked subcommit in clog at this point. We now only
3753 * perform that step, if required, as part of the atomic update of the
3754 * whole transaction tree at top level commit or abort.
3757 /* Post-commit cleanup */
3758 if (TransactionIdIsValid(s->transactionId))
3759 AtSubCommit_childXids();
3760 AfterTriggerEndSubXact(true);
3761 AtSubCommit_Portals(s->subTransactionId,
3762 s->parent->subTransactionId,
3763 s->parent->curTransactionOwner);
3764 AtEOSubXact_LargeObject(true, s->subTransactionId,
3765 s->parent->subTransactionId);
3766 AtSubCommit_Notify();
3767 AtEOSubXact_UpdateFlatFiles(true, s->subTransactionId,
3768 s->parent->subTransactionId);
3770 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
3771 s->parent->subTransactionId);
3773 ResourceOwnerRelease(s->curTransactionOwner,
3774 RESOURCE_RELEASE_BEFORE_LOCKS,
3775 true, false);
3776 AtEOSubXact_RelationCache(true, s->subTransactionId,
3777 s->parent->subTransactionId);
3778 AtEOSubXact_Inval(true);
3779 AtSubCommit_smgr();
3782 * The only lock we actually release here is the subtransaction XID lock.
3783 * The rest just get transferred to the parent resource owner.
3785 CurrentResourceOwner = s->curTransactionOwner;
3786 if (TransactionIdIsValid(s->transactionId))
3787 XactLockTableDelete(s->transactionId);
3789 ResourceOwnerRelease(s->curTransactionOwner,
3790 RESOURCE_RELEASE_LOCKS,
3791 true, false);
3792 ResourceOwnerRelease(s->curTransactionOwner,
3793 RESOURCE_RELEASE_AFTER_LOCKS,
3794 true, false);
3796 AtEOXact_GUC(true, s->gucNestLevel);
3797 AtEOSubXact_SPI(true, s->subTransactionId);
3798 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
3799 s->parent->subTransactionId);
3800 AtEOSubXact_Namespace(true, s->subTransactionId,
3801 s->parent->subTransactionId);
3802 AtEOSubXact_Files(true, s->subTransactionId,
3803 s->parent->subTransactionId);
3804 AtEOSubXact_HashTables(true, s->nestingLevel);
3805 AtEOSubXact_PgStat(true, s->nestingLevel);
3806 AtSubCommit_Snapshot(s->nestingLevel);
3809 * We need to restore the upper transaction's read-only state, in case the
3810 * upper is read-write while the child is read-only; GUC will incorrectly
3811 * think it should leave the child state in place.
3813 XactReadOnly = s->prevXactReadOnly;
3815 CurrentResourceOwner = s->parent->curTransactionOwner;
3816 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3817 ResourceOwnerDelete(s->curTransactionOwner);
3818 s->curTransactionOwner = NULL;
3820 AtSubCommit_Memory();
3822 s->state = TRANS_DEFAULT;
3824 PopTransaction();
3828 * AbortSubTransaction
3830 static void
3831 AbortSubTransaction(void)
3833 TransactionState s = CurrentTransactionState;
3835 /* Prevent cancel/die interrupt while cleaning up */
3836 HOLD_INTERRUPTS();
3838 /* Make sure we have a valid memory context and resource owner */
3839 AtSubAbort_Memory();
3840 AtSubAbort_ResourceOwner();
3843 * Release any LW locks we might be holding as quickly as possible.
3844 * (Regular locks, however, must be held till we finish aborting.)
3845 * Releasing LW locks is critical since we might try to grab them again
3846 * while cleaning up!
3848 * FIXME This may be incorrect --- Are there some locks we should keep?
3849 * Buffer locks, for example? I don't think so but I'm not sure.
3851 LWLockReleaseAll();
3853 AbortBufferIO();
3854 UnlockBuffers();
3856 LockWaitCancel();
3859 * check the current transaction state
3861 ShowTransactionState("AbortSubTransaction");
3863 if (s->state != TRANS_INPROGRESS)
3864 elog(WARNING, "AbortSubTransaction while in %s state",
3865 TransStateAsString(s->state));
3867 s->state = TRANS_ABORT;
3870 * Reset user ID which might have been changed transiently. (See notes in
3871 * AbortTransaction.)
3873 SetUserIdAndContext(s->prevUser, s->prevSecDefCxt);
3876 * We can skip all this stuff if the subxact failed before creating a
3877 * ResourceOwner...
3879 if (s->curTransactionOwner)
3881 AfterTriggerEndSubXact(false);
3882 AtSubAbort_Portals(s->subTransactionId,
3883 s->parent->subTransactionId,
3884 s->parent->curTransactionOwner);
3885 AtEOSubXact_LargeObject(false, s->subTransactionId,
3886 s->parent->subTransactionId);
3887 AtSubAbort_Notify();
3888 AtEOSubXact_UpdateFlatFiles(false, s->subTransactionId,
3889 s->parent->subTransactionId);
3891 /* Advertise the fact that we aborted in pg_clog. */
3892 (void) RecordTransactionAbort(true);
3894 /* Post-abort cleanup */
3895 if (TransactionIdIsValid(s->transactionId))
3896 AtSubAbort_childXids();
3898 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
3899 s->parent->subTransactionId);
3901 ResourceOwnerRelease(s->curTransactionOwner,
3902 RESOURCE_RELEASE_BEFORE_LOCKS,
3903 false, false);
3904 AtEOSubXact_RelationCache(false, s->subTransactionId,
3905 s->parent->subTransactionId);
3906 AtEOSubXact_Inval(false);
3907 AtSubAbort_smgr();
3908 ResourceOwnerRelease(s->curTransactionOwner,
3909 RESOURCE_RELEASE_LOCKS,
3910 false, false);
3911 ResourceOwnerRelease(s->curTransactionOwner,
3912 RESOURCE_RELEASE_AFTER_LOCKS,
3913 false, false);
3915 AtEOXact_GUC(false, s->gucNestLevel);
3916 AtEOSubXact_SPI(false, s->subTransactionId);
3917 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
3918 s->parent->subTransactionId);
3919 AtEOSubXact_Namespace(false, s->subTransactionId,
3920 s->parent->subTransactionId);
3921 AtEOSubXact_Files(false, s->subTransactionId,
3922 s->parent->subTransactionId);
3923 AtEOSubXact_HashTables(false, s->nestingLevel);
3924 AtEOSubXact_PgStat(false, s->nestingLevel);
3925 AtSubAbort_Snapshot(s->nestingLevel);
3929 * Restore the upper transaction's read-only state, too. This should be
3930 * redundant with GUC's cleanup but we may as well do it for consistency
3931 * with the commit case.
3933 XactReadOnly = s->prevXactReadOnly;
3935 RESUME_INTERRUPTS();
3939 * CleanupSubTransaction
3941 * The caller has to make sure to always reassign CurrentTransactionState
3942 * if it has a local pointer to it after calling this function.
3944 static void
3945 CleanupSubTransaction(void)
3947 TransactionState s = CurrentTransactionState;
3949 ShowTransactionState("CleanupSubTransaction");
3951 if (s->state != TRANS_ABORT)
3952 elog(WARNING, "CleanupSubTransaction while in %s state",
3953 TransStateAsString(s->state));
3955 AtSubCleanup_Portals(s->subTransactionId);
3957 CurrentResourceOwner = s->parent->curTransactionOwner;
3958 CurTransactionResourceOwner = s->parent->curTransactionOwner;
3959 if (s->curTransactionOwner)
3960 ResourceOwnerDelete(s->curTransactionOwner);
3961 s->curTransactionOwner = NULL;
3963 AtSubCleanup_Memory();
3965 s->state = TRANS_DEFAULT;
3967 PopTransaction();
3971 * PushTransaction
3972 * Create transaction state stack entry for a subtransaction
3974 * The caller has to make sure to always reassign CurrentTransactionState
3975 * if it has a local pointer to it after calling this function.
3977 static void
3978 PushTransaction(void)
3980 TransactionState p = CurrentTransactionState;
3981 TransactionState s;
3984 * We keep subtransaction state nodes in TopTransactionContext.
3986 s = (TransactionState)
3987 MemoryContextAllocZero(TopTransactionContext,
3988 sizeof(TransactionStateData));
3991 * Assign a subtransaction ID, watching out for counter wraparound.
3993 currentSubTransactionId += 1;
3994 if (currentSubTransactionId == InvalidSubTransactionId)
3996 currentSubTransactionId -= 1;
3997 pfree(s);
3998 ereport(ERROR,
3999 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
4000 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
4004 * We can now stack a minimally valid subtransaction without fear of
4005 * failure.
4007 s->transactionId = InvalidTransactionId; /* until assigned */
4008 s->subTransactionId = currentSubTransactionId;
4009 s->parent = p;
4010 s->nestingLevel = p->nestingLevel + 1;
4011 s->gucNestLevel = NewGUCNestLevel();
4012 s->savepointLevel = p->savepointLevel;
4013 s->state = TRANS_DEFAULT;
4014 s->blockState = TBLOCK_SUBBEGIN;
4015 GetUserIdAndContext(&s->prevUser, &s->prevSecDefCxt);
4016 s->prevXactReadOnly = XactReadOnly;
4018 CurrentTransactionState = s;
4021 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
4022 * with the subtransaction from here on out; in particular they should not
4023 * assume that it necessarily has a transaction context, resource owner,
4024 * or XID.
4029 * PopTransaction
4030 * Pop back to parent transaction state
4032 * The caller has to make sure to always reassign CurrentTransactionState
4033 * if it has a local pointer to it after calling this function.
4035 static void
4036 PopTransaction(void)
4038 TransactionState s = CurrentTransactionState;
4040 if (s->state != TRANS_DEFAULT)
4041 elog(WARNING, "PopTransaction while in %s state",
4042 TransStateAsString(s->state));
4044 if (s->parent == NULL)
4045 elog(FATAL, "PopTransaction with no parent");
4047 CurrentTransactionState = s->parent;
4049 /* Let's just make sure CurTransactionContext is good */
4050 CurTransactionContext = s->parent->curTransactionContext;
4051 MemoryContextSwitchTo(CurTransactionContext);
4053 /* Ditto for ResourceOwner links */
4054 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4055 CurrentResourceOwner = s->parent->curTransactionOwner;
4057 /* Free the old child structure */
4058 if (s->name)
4059 pfree(s->name);
4060 pfree(s);
4064 * ShowTransactionState
4065 * Debug support
4067 static void
4068 ShowTransactionState(const char *str)
4070 /* skip work if message will definitely not be printed */
4071 if (log_min_messages <= DEBUG3 || client_min_messages <= DEBUG3)
4073 elog(DEBUG3, "%s", str);
4074 ShowTransactionStateRec(CurrentTransactionState);
4079 * ShowTransactionStateRec
4080 * Recursive subroutine for ShowTransactionState
4082 static void
4083 ShowTransactionStateRec(TransactionState s)
4085 StringInfoData buf;
4087 initStringInfo(&buf);
4089 if (s->nChildXids > 0)
4091 int i;
4093 appendStringInfo(&buf, "%u", s->childXids[0]);
4094 for (i = 1; i < s->nChildXids; i++)
4095 appendStringInfo(&buf, " %u", s->childXids[i]);
4098 if (s->parent)
4099 ShowTransactionStateRec(s->parent);
4101 /* use ereport to suppress computation if msg will not be printed */
4102 ereport(DEBUG3,
4103 (errmsg_internal("name: %s; blockState: %13s; state: %7s, xid/subid/cid: %u/%u/%u%s, nestlvl: %d, children: %s",
4104 PointerIsValid(s->name) ? s->name : "unnamed",
4105 BlockStateAsString(s->blockState),
4106 TransStateAsString(s->state),
4107 (unsigned int) s->transactionId,
4108 (unsigned int) s->subTransactionId,
4109 (unsigned int) currentCommandId,
4110 currentCommandIdUsed ? " (used)" : "",
4111 s->nestingLevel, buf.data)));
4113 pfree(buf.data);
4117 * BlockStateAsString
4118 * Debug support
4120 static const char *
4121 BlockStateAsString(TBlockState blockState)
4123 switch (blockState)
4125 case TBLOCK_DEFAULT:
4126 return "DEFAULT";
4127 case TBLOCK_STARTED:
4128 return "STARTED";
4129 case TBLOCK_BEGIN:
4130 return "BEGIN";
4131 case TBLOCK_INPROGRESS:
4132 return "INPROGRESS";
4133 case TBLOCK_END:
4134 return "END";
4135 case TBLOCK_ABORT:
4136 return "ABORT";
4137 case TBLOCK_ABORT_END:
4138 return "ABORT END";
4139 case TBLOCK_ABORT_PENDING:
4140 return "ABORT PEND";
4141 case TBLOCK_PREPARE:
4142 return "PREPARE";
4143 case TBLOCK_SUBBEGIN:
4144 return "SUB BEGIN";
4145 case TBLOCK_SUBINPROGRESS:
4146 return "SUB INPROGRS";
4147 case TBLOCK_SUBEND:
4148 return "SUB END";
4149 case TBLOCK_SUBABORT:
4150 return "SUB ABORT";
4151 case TBLOCK_SUBABORT_END:
4152 return "SUB ABORT END";
4153 case TBLOCK_SUBABORT_PENDING:
4154 return "SUB ABRT PEND";
4155 case TBLOCK_SUBRESTART:
4156 return "SUB RESTART";
4157 case TBLOCK_SUBABORT_RESTART:
4158 return "SUB AB RESTRT";
4160 return "UNRECOGNIZED";
4164 * TransStateAsString
4165 * Debug support
4167 static const char *
4168 TransStateAsString(TransState state)
4170 switch (state)
4172 case TRANS_DEFAULT:
4173 return "DEFAULT";
4174 case TRANS_START:
4175 return "START";
4176 case TRANS_INPROGRESS:
4177 return "INPROGR";
4178 case TRANS_COMMIT:
4179 return "COMMIT";
4180 case TRANS_ABORT:
4181 return "ABORT";
4182 case TRANS_PREPARE:
4183 return "PREPARE";
4185 return "UNRECOGNIZED";
4189 * xactGetCommittedChildren
4191 * Gets the list of committed children of the current transaction. The return
4192 * value is the number of child transactions. *ptr is set to point to an
4193 * array of TransactionIds. The array is allocated in TopTransactionContext;
4194 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
4195 * If there are no subxacts, *ptr is set to NULL.
4198 xactGetCommittedChildren(TransactionId **ptr)
4200 TransactionState s = CurrentTransactionState;
4202 if (s->nChildXids == 0)
4203 *ptr = NULL;
4204 else
4205 *ptr = s->childXids;
4207 return s->nChildXids;
4211 * XLOG support routines
4214 static void
4215 xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid)
4217 TransactionId *sub_xids;
4218 TransactionId max_xid;
4219 int i;
4221 /* Mark the transaction committed in pg_clog */
4222 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4223 TransactionIdCommitTree(xid, xlrec->nsubxacts, sub_xids);
4225 /* Make sure nextXid is beyond any XID mentioned in the record */
4226 max_xid = xid;
4227 for (i = 0; i < xlrec->nsubxacts; i++)
4229 if (TransactionIdPrecedes(max_xid, sub_xids[i]))
4230 max_xid = sub_xids[i];
4232 if (TransactionIdFollowsOrEquals(max_xid,
4233 ShmemVariableCache->nextXid))
4235 ShmemVariableCache->nextXid = max_xid;
4236 TransactionIdAdvance(ShmemVariableCache->nextXid);
4239 /* Make sure files supposed to be dropped are dropped */
4240 for (i = 0; i < xlrec->nrels; i++)
4242 SMgrRelation srel = smgropen(xlrec->xnodes[i]);
4243 ForkNumber fork;
4245 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4247 if (smgrexists(srel, fork))
4249 XLogDropRelation(xlrec->xnodes[i], fork);
4250 smgrdounlink(srel, fork, false, true);
4253 smgrclose(srel);
4257 static void
4258 xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
4260 TransactionId *sub_xids;
4261 TransactionId max_xid;
4262 int i;
4264 /* Mark the transaction aborted in pg_clog */
4265 sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
4266 TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids);
4268 /* Make sure nextXid is beyond any XID mentioned in the record */
4269 max_xid = xid;
4270 for (i = 0; i < xlrec->nsubxacts; i++)
4272 if (TransactionIdPrecedes(max_xid, sub_xids[i]))
4273 max_xid = sub_xids[i];
4275 if (TransactionIdFollowsOrEquals(max_xid,
4276 ShmemVariableCache->nextXid))
4278 ShmemVariableCache->nextXid = max_xid;
4279 TransactionIdAdvance(ShmemVariableCache->nextXid);
4282 /* Make sure files supposed to be dropped are dropped */
4283 for (i = 0; i < xlrec->nrels; i++)
4285 SMgrRelation srel = smgropen(xlrec->xnodes[i]);
4286 ForkNumber fork;
4288 for (fork = 0; fork <= MAX_FORKNUM; fork++)
4290 if (smgrexists(srel, fork))
4292 XLogDropRelation(xlrec->xnodes[i], fork);
4293 smgrdounlink(srel, fork, false, true);
4296 smgrclose(srel);
4300 void
4301 xact_redo(XLogRecPtr lsn, XLogRecord *record)
4303 uint8 info = record->xl_info & ~XLR_INFO_MASK;
4305 /* Backup blocks are not used in xact records */
4306 Assert(!(record->xl_info & XLR_BKP_BLOCK_MASK));
4308 if (info == XLOG_XACT_COMMIT)
4310 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
4312 xact_redo_commit(xlrec, record->xl_xid);
4314 else if (info == XLOG_XACT_ABORT)
4316 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
4318 xact_redo_abort(xlrec, record->xl_xid);
4320 else if (info == XLOG_XACT_PREPARE)
4322 /* the record contents are exactly the 2PC file */
4323 RecreateTwoPhaseFile(record->xl_xid,
4324 XLogRecGetData(record), record->xl_len);
4326 else if (info == XLOG_XACT_COMMIT_PREPARED)
4328 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) XLogRecGetData(record);
4330 xact_redo_commit(&xlrec->crec, xlrec->xid);
4331 RemoveTwoPhaseFile(xlrec->xid, false);
4333 else if (info == XLOG_XACT_ABORT_PREPARED)
4335 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) XLogRecGetData(record);
4337 xact_redo_abort(&xlrec->arec, xlrec->xid);
4338 RemoveTwoPhaseFile(xlrec->xid, false);
4340 else
4341 elog(PANIC, "xact_redo: unknown op code %u", info);
4344 static void
4345 xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
4347 int i;
4349 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4350 if (xlrec->nrels > 0)
4352 appendStringInfo(buf, "; rels:");
4353 for (i = 0; i < xlrec->nrels; i++)
4355 char *path = relpath(xlrec->xnodes[i], MAIN_FORKNUM);
4357 appendStringInfo(buf, " %s", path);
4358 pfree(path);
4361 if (xlrec->nsubxacts > 0)
4363 TransactionId *xacts = (TransactionId *)
4364 &xlrec->xnodes[xlrec->nrels];
4366 appendStringInfo(buf, "; subxacts:");
4367 for (i = 0; i < xlrec->nsubxacts; i++)
4368 appendStringInfo(buf, " %u", xacts[i]);
4372 static void
4373 xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
4375 int i;
4377 appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
4378 if (xlrec->nrels > 0)
4380 appendStringInfo(buf, "; rels:");
4381 for (i = 0; i < xlrec->nrels; i++)
4383 char *path = relpath(xlrec->xnodes[i], MAIN_FORKNUM);
4385 appendStringInfo(buf, " %s", path);
4386 pfree(path);
4389 if (xlrec->nsubxacts > 0)
4391 TransactionId *xacts = (TransactionId *)
4392 &xlrec->xnodes[xlrec->nrels];
4394 appendStringInfo(buf, "; subxacts:");
4395 for (i = 0; i < xlrec->nsubxacts; i++)
4396 appendStringInfo(buf, " %u", xacts[i]);
4400 void
4401 xact_desc(StringInfo buf, uint8 xl_info, char *rec)
4403 uint8 info = xl_info & ~XLR_INFO_MASK;
4405 if (info == XLOG_XACT_COMMIT)
4407 xl_xact_commit *xlrec = (xl_xact_commit *) rec;
4409 appendStringInfo(buf, "commit: ");
4410 xact_desc_commit(buf, xlrec);
4412 else if (info == XLOG_XACT_ABORT)
4414 xl_xact_abort *xlrec = (xl_xact_abort *) rec;
4416 appendStringInfo(buf, "abort: ");
4417 xact_desc_abort(buf, xlrec);
4419 else if (info == XLOG_XACT_PREPARE)
4421 appendStringInfo(buf, "prepare");
4423 else if (info == XLOG_XACT_COMMIT_PREPARED)
4425 xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec;
4427 appendStringInfo(buf, "commit %u: ", xlrec->xid);
4428 xact_desc_commit(buf, &xlrec->crec);
4430 else if (info == XLOG_XACT_ABORT_PREPARED)
4432 xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec;
4434 appendStringInfo(buf, "abort %u: ", xlrec->xid);
4435 xact_desc_abort(buf, &xlrec->arec);
4437 else
4438 appendStringInfo(buf, "UNKNOWN");