Improve comment about GetWALAvailability's WALAVAIL_REMOVED code.
[pgsql.git] / src / backend / access / transam / xact.c
blobd85e31390823c0e4de4c45907f90c199352211ed
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-2023, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
12 * IDENTIFICATION
13 * src/backend/access/transam/xact.c
15 *-------------------------------------------------------------------------
18 #include "postgres.h"
20 #include <time.h>
21 #include <unistd.h>
23 #include "access/commit_ts.h"
24 #include "access/multixact.h"
25 #include "access/parallel.h"
26 #include "access/subtrans.h"
27 #include "access/transam.h"
28 #include "access/twophase.h"
29 #include "access/xact.h"
30 #include "access/xlog.h"
31 #include "access/xloginsert.h"
32 #include "access/xlogrecovery.h"
33 #include "access/xlogutils.h"
34 #include "catalog/index.h"
35 #include "catalog/namespace.h"
36 #include "catalog/pg_enum.h"
37 #include "catalog/storage.h"
38 #include "commands/async.h"
39 #include "commands/tablecmds.h"
40 #include "commands/trigger.h"
41 #include "common/pg_prng.h"
42 #include "executor/spi.h"
43 #include "libpq/be-fsstubs.h"
44 #include "libpq/pqsignal.h"
45 #include "miscadmin.h"
46 #include "pg_trace.h"
47 #include "pgstat.h"
48 #include "replication/logical.h"
49 #include "replication/logicallauncher.h"
50 #include "replication/logicalworker.h"
51 #include "replication/origin.h"
52 #include "replication/snapbuild.h"
53 #include "replication/syncrep.h"
54 #include "replication/walsender.h"
55 #include "storage/condition_variable.h"
56 #include "storage/fd.h"
57 #include "storage/lmgr.h"
58 #include "storage/md.h"
59 #include "storage/predicate.h"
60 #include "storage/proc.h"
61 #include "storage/procarray.h"
62 #include "storage/sinvaladt.h"
63 #include "storage/smgr.h"
64 #include "utils/builtins.h"
65 #include "utils/catcache.h"
66 #include "utils/combocid.h"
67 #include "utils/guc.h"
68 #include "utils/inval.h"
69 #include "utils/memutils.h"
70 #include "utils/relmapper.h"
71 #include "utils/snapmgr.h"
72 #include "utils/timeout.h"
73 #include "utils/timestamp.h"
76 * User-tweakable parameters
78 int DefaultXactIsoLevel = XACT_READ_COMMITTED;
79 int XactIsoLevel = XACT_READ_COMMITTED;
81 bool DefaultXactReadOnly = false;
82 bool XactReadOnly;
84 bool DefaultXactDeferrable = false;
85 bool XactDeferrable;
87 int synchronous_commit = SYNCHRONOUS_COMMIT_ON;
90 * CheckXidAlive is a xid value pointing to a possibly ongoing (sub)
91 * transaction. Currently, it is used in logical decoding. It's possible
92 * that such transactions can get aborted while the decoding is ongoing in
93 * which case we skip decoding that particular transaction. To ensure that we
94 * check whether the CheckXidAlive is aborted after fetching the tuple from
95 * system tables. We also ensure that during logical decoding we never
96 * directly access the tableam or heap APIs because we are checking for the
97 * concurrent aborts only in systable_* APIs.
99 TransactionId CheckXidAlive = InvalidTransactionId;
100 bool bsysscan = false;
103 * When running as a parallel worker, we place only a single
104 * TransactionStateData on the parallel worker's state stack, and the XID
105 * reflected there will be that of the *innermost* currently-active
106 * subtransaction in the backend that initiated parallelism. However,
107 * GetTopTransactionId() and TransactionIdIsCurrentTransactionId()
108 * need to return the same answers in the parallel worker as they would have
109 * in the user backend, so we need some additional bookkeeping.
111 * XactTopFullTransactionId stores the XID of our toplevel transaction, which
112 * will be the same as TopTransactionStateData.fullTransactionId in an
113 * ordinary backend; but in a parallel backend, which does not have the entire
114 * transaction state, it will instead be copied from the backend that started
115 * the parallel operation.
117 * nParallelCurrentXids will be 0 and ParallelCurrentXids NULL in an ordinary
118 * backend, but in a parallel backend, nParallelCurrentXids will contain the
119 * number of XIDs that need to be considered current, and ParallelCurrentXids
120 * will contain the XIDs themselves. This includes all XIDs that were current
121 * or sub-committed in the parent at the time the parallel operation began.
122 * The XIDs are stored sorted in numerical order (not logical order) to make
123 * lookups as fast as possible.
125 static FullTransactionId XactTopFullTransactionId = {InvalidTransactionId};
126 static int nParallelCurrentXids = 0;
127 static TransactionId *ParallelCurrentXids;
130 * Miscellaneous flag bits to record events which occur on the top level
131 * transaction. These flags are only persisted in MyXactFlags and are intended
132 * so we remember to do certain things later on in the transaction. This is
133 * globally accessible, so can be set from anywhere in the code that requires
134 * recording flags.
136 int MyXactFlags;
139 * transaction states - transaction state from server perspective
141 typedef enum TransState
143 TRANS_DEFAULT, /* idle */
144 TRANS_START, /* transaction starting */
145 TRANS_INPROGRESS, /* inside a valid transaction */
146 TRANS_COMMIT, /* commit in progress */
147 TRANS_ABORT, /* abort in progress */
148 TRANS_PREPARE /* prepare in progress */
149 } TransState;
152 * transaction block states - transaction state of client queries
154 * Note: the subtransaction states are used only for non-topmost
155 * transactions; the others appear only in the topmost transaction.
157 typedef enum TBlockState
159 /* not-in-transaction-block states */
160 TBLOCK_DEFAULT, /* idle */
161 TBLOCK_STARTED, /* running single-query transaction */
163 /* transaction block states */
164 TBLOCK_BEGIN, /* starting transaction block */
165 TBLOCK_INPROGRESS, /* live transaction */
166 TBLOCK_IMPLICIT_INPROGRESS, /* live transaction after implicit BEGIN */
167 TBLOCK_PARALLEL_INPROGRESS, /* live transaction inside parallel worker */
168 TBLOCK_END, /* COMMIT received */
169 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
170 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
171 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
172 TBLOCK_PREPARE, /* live xact, PREPARE received */
174 /* subtransaction states */
175 TBLOCK_SUBBEGIN, /* starting a subtransaction */
176 TBLOCK_SUBINPROGRESS, /* live subtransaction */
177 TBLOCK_SUBRELEASE, /* RELEASE received */
178 TBLOCK_SUBCOMMIT, /* COMMIT received while TBLOCK_SUBINPROGRESS */
179 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
180 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
181 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
182 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
183 TBLOCK_SUBABORT_RESTART /* failed subxact, ROLLBACK TO received */
184 } TBlockState;
187 * transaction state structure
189 typedef struct TransactionStateData
191 FullTransactionId fullTransactionId; /* my FullTransactionId */
192 SubTransactionId subTransactionId; /* my subxact ID */
193 char *name; /* savepoint name, if any */
194 int savepointLevel; /* savepoint level */
195 TransState state; /* low-level state */
196 TBlockState blockState; /* high-level state */
197 int nestingLevel; /* transaction nesting depth */
198 int gucNestLevel; /* GUC context nesting depth */
199 MemoryContext curTransactionContext; /* my xact-lifetime context */
200 ResourceOwner curTransactionOwner; /* my query resources */
201 TransactionId *childXids; /* subcommitted child XIDs, in XID order */
202 int nChildXids; /* # of subcommitted child XIDs */
203 int maxChildXids; /* allocated size of childXids[] */
204 Oid prevUser; /* previous CurrentUserId setting */
205 int prevSecContext; /* previous SecurityRestrictionContext */
206 bool prevXactReadOnly; /* entry-time xact r/o state */
207 bool startedInRecovery; /* did we start in recovery? */
208 bool didLogXid; /* has xid been included in WAL record? */
209 int parallelModeLevel; /* Enter/ExitParallelMode counter */
210 bool chain; /* start a new block after this one */
211 bool topXidLogged; /* for a subxact: is top-level XID logged? */
212 struct TransactionStateData *parent; /* back link to parent */
213 } TransactionStateData;
215 typedef TransactionStateData *TransactionState;
218 * Serialized representation used to transmit transaction state to parallel
219 * workers through shared memory.
221 typedef struct SerializedTransactionState
223 int xactIsoLevel;
224 bool xactDeferrable;
225 FullTransactionId topFullTransactionId;
226 FullTransactionId currentFullTransactionId;
227 CommandId currentCommandId;
228 int nParallelCurrentXids;
229 TransactionId parallelCurrentXids[FLEXIBLE_ARRAY_MEMBER];
230 } SerializedTransactionState;
232 /* The size of SerializedTransactionState, not including the final array. */
233 #define SerializedTransactionStateHeaderSize \
234 offsetof(SerializedTransactionState, parallelCurrentXids)
237 * CurrentTransactionState always points to the current transaction state
238 * block. It will point to TopTransactionStateData when not in a
239 * transaction at all, or when in a top-level transaction.
241 static TransactionStateData TopTransactionStateData = {
242 .state = TRANS_DEFAULT,
243 .blockState = TBLOCK_DEFAULT,
244 .topXidLogged = false,
248 * unreportedXids holds XIDs of all subtransactions that have not yet been
249 * reported in an XLOG_XACT_ASSIGNMENT record.
251 static int nUnreportedXids;
252 static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS];
254 static TransactionState CurrentTransactionState = &TopTransactionStateData;
257 * The subtransaction ID and command ID assignment counters are global
258 * to a whole transaction, so we do not keep them in the state stack.
260 static SubTransactionId currentSubTransactionId;
261 static CommandId currentCommandId;
262 static bool currentCommandIdUsed;
265 * xactStartTimestamp is the value of transaction_timestamp().
266 * stmtStartTimestamp is the value of statement_timestamp().
267 * xactStopTimestamp is the time at which we log a commit / abort WAL record,
268 * or if that was skipped, the time of the first subsequent
269 * GetCurrentTransactionStopTimestamp() call.
271 * These do not change as we enter and exit subtransactions, so we don't
272 * keep them inside the TransactionState stack.
274 static TimestampTz xactStartTimestamp;
275 static TimestampTz stmtStartTimestamp;
276 static TimestampTz xactStopTimestamp;
279 * GID to be used for preparing the current transaction. This is also
280 * global to a whole transaction, so we don't keep it in the state stack.
282 static char *prepareGID;
285 * Some commands want to force synchronous commit.
287 static bool forceSyncCommit = false;
289 /* Flag for logging statements in a transaction. */
290 bool xact_is_sampled = false;
293 * Private context for transaction-abort work --- we reserve space for this
294 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
295 * when we've run out of memory.
297 static MemoryContext TransactionAbortContext = NULL;
300 * List of add-on start- and end-of-xact callbacks
302 typedef struct XactCallbackItem
304 struct XactCallbackItem *next;
305 XactCallback callback;
306 void *arg;
307 } XactCallbackItem;
309 static XactCallbackItem *Xact_callbacks = NULL;
312 * List of add-on start- and end-of-subxact callbacks
314 typedef struct SubXactCallbackItem
316 struct SubXactCallbackItem *next;
317 SubXactCallback callback;
318 void *arg;
319 } SubXactCallbackItem;
321 static SubXactCallbackItem *SubXact_callbacks = NULL;
324 /* local function prototypes */
325 static void AssignTransactionId(TransactionState s);
326 static void AbortTransaction(void);
327 static void AtAbort_Memory(void);
328 static void AtCleanup_Memory(void);
329 static void AtAbort_ResourceOwner(void);
330 static void AtCCI_LocalCache(void);
331 static void AtCommit_Memory(void);
332 static void AtStart_Cache(void);
333 static void AtStart_Memory(void);
334 static void AtStart_ResourceOwner(void);
335 static void CallXactCallbacks(XactEvent event);
336 static void CallSubXactCallbacks(SubXactEvent event,
337 SubTransactionId mySubid,
338 SubTransactionId parentSubid);
339 static void CleanupTransaction(void);
340 static void CheckTransactionBlock(bool isTopLevel, bool throwError,
341 const char *stmtType);
342 static void CommitTransaction(void);
343 static TransactionId RecordTransactionAbort(bool isSubXact);
344 static void StartTransaction(void);
346 static void StartSubTransaction(void);
347 static void CommitSubTransaction(void);
348 static void AbortSubTransaction(void);
349 static void CleanupSubTransaction(void);
350 static void PushTransaction(void);
351 static void PopTransaction(void);
353 static void AtSubAbort_Memory(void);
354 static void AtSubCleanup_Memory(void);
355 static void AtSubAbort_ResourceOwner(void);
356 static void AtSubCommit_Memory(void);
357 static void AtSubStart_Memory(void);
358 static void AtSubStart_ResourceOwner(void);
360 static void ShowTransactionState(const char *str);
361 static void ShowTransactionStateRec(const char *str, TransactionState s);
362 static const char *BlockStateAsString(TBlockState blockState);
363 static const char *TransStateAsString(TransState state);
366 /* ----------------------------------------------------------------
367 * transaction state accessors
368 * ----------------------------------------------------------------
372 * IsTransactionState
374 * This returns true if we are inside a valid transaction; that is,
375 * it is safe to initiate database access, take heavyweight locks, etc.
377 bool
378 IsTransactionState(void)
380 TransactionState s = CurrentTransactionState;
383 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
384 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
385 * TRANS_PREPARE since it might be too soon or too late within those
386 * transition states to do anything interesting. Hence, the only "valid"
387 * state is TRANS_INPROGRESS.
389 return (s->state == TRANS_INPROGRESS);
393 * IsAbortedTransactionBlockState
395 * This returns true if we are within an aborted transaction block.
397 bool
398 IsAbortedTransactionBlockState(void)
400 TransactionState s = CurrentTransactionState;
402 if (s->blockState == TBLOCK_ABORT ||
403 s->blockState == TBLOCK_SUBABORT)
404 return true;
406 return false;
411 * GetTopTransactionId
413 * This will return the XID of the main transaction, assigning one if
414 * it's not yet set. Be careful to call this only inside a valid xact.
416 TransactionId
417 GetTopTransactionId(void)
419 if (!FullTransactionIdIsValid(XactTopFullTransactionId))
420 AssignTransactionId(&TopTransactionStateData);
421 return XidFromFullTransactionId(XactTopFullTransactionId);
425 * GetTopTransactionIdIfAny
427 * This will return the XID of the main transaction, if one is assigned.
428 * It will return InvalidTransactionId if we are not currently inside a
429 * transaction, or inside a transaction that hasn't yet been assigned an XID.
431 TransactionId
432 GetTopTransactionIdIfAny(void)
434 return XidFromFullTransactionId(XactTopFullTransactionId);
438 * GetCurrentTransactionId
440 * This will return the XID of the current transaction (main or sub
441 * transaction), assigning one if it's not yet set. Be careful to call this
442 * only inside a valid xact.
444 TransactionId
445 GetCurrentTransactionId(void)
447 TransactionState s = CurrentTransactionState;
449 if (!FullTransactionIdIsValid(s->fullTransactionId))
450 AssignTransactionId(s);
451 return XidFromFullTransactionId(s->fullTransactionId);
455 * GetCurrentTransactionIdIfAny
457 * This will return the XID of the current sub xact, if one is assigned.
458 * It will return InvalidTransactionId if we are not currently inside a
459 * transaction, or inside a transaction that hasn't been assigned an XID yet.
461 TransactionId
462 GetCurrentTransactionIdIfAny(void)
464 return XidFromFullTransactionId(CurrentTransactionState->fullTransactionId);
468 * GetTopFullTransactionId
470 * This will return the FullTransactionId of the main transaction, assigning
471 * one if it's not yet set. Be careful to call this only inside a valid xact.
473 FullTransactionId
474 GetTopFullTransactionId(void)
476 if (!FullTransactionIdIsValid(XactTopFullTransactionId))
477 AssignTransactionId(&TopTransactionStateData);
478 return XactTopFullTransactionId;
482 * GetTopFullTransactionIdIfAny
484 * This will return the FullTransactionId of the main transaction, if one is
485 * assigned. It will return InvalidFullTransactionId if we are not currently
486 * inside a transaction, or inside a transaction that hasn't yet been assigned
487 * one.
489 FullTransactionId
490 GetTopFullTransactionIdIfAny(void)
492 return XactTopFullTransactionId;
496 * GetCurrentFullTransactionId
498 * This will return the FullTransactionId of the current transaction (main or
499 * sub transaction), assigning one if it's not yet set. Be careful to call
500 * this only inside a valid xact.
502 FullTransactionId
503 GetCurrentFullTransactionId(void)
505 TransactionState s = CurrentTransactionState;
507 if (!FullTransactionIdIsValid(s->fullTransactionId))
508 AssignTransactionId(s);
509 return s->fullTransactionId;
513 * GetCurrentFullTransactionIdIfAny
515 * This will return the FullTransactionId of the current sub xact, if one is
516 * assigned. It will return InvalidFullTransactionId if we are not currently
517 * inside a transaction, or inside a transaction that hasn't been assigned one
518 * yet.
520 FullTransactionId
521 GetCurrentFullTransactionIdIfAny(void)
523 return CurrentTransactionState->fullTransactionId;
527 * MarkCurrentTransactionIdLoggedIfAny
529 * Remember that the current xid - if it is assigned - now has been wal logged.
531 void
532 MarkCurrentTransactionIdLoggedIfAny(void)
534 if (FullTransactionIdIsValid(CurrentTransactionState->fullTransactionId))
535 CurrentTransactionState->didLogXid = true;
539 * IsSubxactTopXidLogPending
541 * This is used to decide whether we need to WAL log the top-level XID for
542 * operation in a subtransaction. We require that for logical decoding, see
543 * LogicalDecodingProcessRecord.
545 * This returns true if wal_level >= logical and we are inside a valid
546 * subtransaction, for which the assignment was not yet written to any WAL
547 * record.
549 bool
550 IsSubxactTopXidLogPending(void)
552 /* check whether it is already logged */
553 if (CurrentTransactionState->topXidLogged)
554 return false;
556 /* wal_level has to be logical */
557 if (!XLogLogicalInfoActive())
558 return false;
560 /* we need to be in a transaction state */
561 if (!IsTransactionState())
562 return false;
564 /* it has to be a subtransaction */
565 if (!IsSubTransaction())
566 return false;
568 /* the subtransaction has to have a XID assigned */
569 if (!TransactionIdIsValid(GetCurrentTransactionIdIfAny()))
570 return false;
572 return true;
576 * MarkSubxactTopXidLogged
578 * Remember that the top transaction id for the current subtransaction is WAL
579 * logged now.
581 void
582 MarkSubxactTopXidLogged(void)
584 Assert(IsSubxactTopXidLogPending());
586 CurrentTransactionState->topXidLogged = true;
590 * GetStableLatestTransactionId
592 * Get the transaction's XID if it has one, else read the next-to-be-assigned
593 * XID. Once we have a value, return that same value for the remainder of the
594 * current transaction. This is meant to provide the reference point for the
595 * age(xid) function, but might be useful for other maintenance tasks as well.
597 TransactionId
598 GetStableLatestTransactionId(void)
600 static LocalTransactionId lxid = InvalidLocalTransactionId;
601 static TransactionId stablexid = InvalidTransactionId;
603 if (lxid != MyProc->lxid)
605 lxid = MyProc->lxid;
606 stablexid = GetTopTransactionIdIfAny();
607 if (!TransactionIdIsValid(stablexid))
608 stablexid = ReadNextTransactionId();
611 Assert(TransactionIdIsValid(stablexid));
613 return stablexid;
617 * AssignTransactionId
619 * Assigns a new permanent FullTransactionId to the given TransactionState.
620 * We do not assign XIDs to transactions until/unless this is called.
621 * Also, any parent TransactionStates that don't yet have XIDs are assigned
622 * one; this maintains the invariant that a child transaction has an XID
623 * following its parent's.
625 static void
626 AssignTransactionId(TransactionState s)
628 bool isSubXact = (s->parent != NULL);
629 ResourceOwner currentOwner;
630 bool log_unknown_top = false;
632 /* Assert that caller didn't screw up */
633 Assert(!FullTransactionIdIsValid(s->fullTransactionId));
634 Assert(s->state == TRANS_INPROGRESS);
637 * Workers synchronize transaction state at the beginning of each parallel
638 * operation, so we can't account for new XIDs at this point.
640 if (IsInParallelMode() || IsParallelWorker())
641 elog(ERROR, "cannot assign XIDs during a parallel operation");
644 * Ensure parent(s) have XIDs, so that a child always has an XID later
645 * than its parent. Mustn't recurse here, or we might get a stack
646 * overflow if we're at the bottom of a huge stack of subtransactions none
647 * of which have XIDs yet.
649 if (isSubXact && !FullTransactionIdIsValid(s->parent->fullTransactionId))
651 TransactionState p = s->parent;
652 TransactionState *parents;
653 size_t parentOffset = 0;
655 parents = palloc(sizeof(TransactionState) * s->nestingLevel);
656 while (p != NULL && !FullTransactionIdIsValid(p->fullTransactionId))
658 parents[parentOffset++] = p;
659 p = p->parent;
663 * This is technically a recursive call, but the recursion will never
664 * be more than one layer deep.
666 while (parentOffset != 0)
667 AssignTransactionId(parents[--parentOffset]);
669 pfree(parents);
673 * When wal_level=logical, guarantee that a subtransaction's xid can only
674 * be seen in the WAL stream if its toplevel xid has been logged before.
675 * If necessary we log an xact_assignment record with fewer than
676 * PGPROC_MAX_CACHED_SUBXIDS. Note that it is fine if didLogXid isn't set
677 * for a transaction even though it appears in a WAL record, we just might
678 * superfluously log something. That can happen when an xid is included
679 * somewhere inside a wal record, but not in XLogRecord->xl_xid, like in
680 * xl_standby_locks.
682 if (isSubXact && XLogLogicalInfoActive() &&
683 !TopTransactionStateData.didLogXid)
684 log_unknown_top = true;
687 * Generate a new FullTransactionId and record its xid in PGPROC and
688 * pg_subtrans.
690 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
691 * shared storage other than PGPROC; because if there's no room for it in
692 * PGPROC, the subtrans entry is needed to ensure that other backends see
693 * the Xid as "running". See GetNewTransactionId.
695 s->fullTransactionId = GetNewTransactionId(isSubXact);
696 if (!isSubXact)
697 XactTopFullTransactionId = s->fullTransactionId;
699 if (isSubXact)
700 SubTransSetParent(XidFromFullTransactionId(s->fullTransactionId),
701 XidFromFullTransactionId(s->parent->fullTransactionId));
704 * If it's a top-level transaction, the predicate locking system needs to
705 * be told about it too.
707 if (!isSubXact)
708 RegisterPredicateLockingXid(XidFromFullTransactionId(s->fullTransactionId));
711 * Acquire lock on the transaction XID. (We assume this cannot block.) We
712 * have to ensure that the lock is assigned to the transaction's own
713 * ResourceOwner.
715 currentOwner = CurrentResourceOwner;
716 CurrentResourceOwner = s->curTransactionOwner;
718 XactLockTableInsert(XidFromFullTransactionId(s->fullTransactionId));
720 CurrentResourceOwner = currentOwner;
723 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
724 * top-level transaction we issue a WAL record for the assignment. We
725 * include the top-level xid and all the subxids that have not yet been
726 * reported using XLOG_XACT_ASSIGNMENT records.
728 * This is required to limit the amount of shared memory required in a hot
729 * standby server to keep track of in-progress XIDs. See notes for
730 * RecordKnownAssignedTransactionIds().
732 * We don't keep track of the immediate parent of each subxid, only the
733 * top-level transaction that each subxact belongs to. This is correct in
734 * recovery only because aborted subtransactions are separately WAL
735 * logged.
737 * This is correct even for the case where several levels above us didn't
738 * have an xid assigned as we recursed up to them beforehand.
740 if (isSubXact && XLogStandbyInfoActive())
742 unreportedXids[nUnreportedXids] = XidFromFullTransactionId(s->fullTransactionId);
743 nUnreportedXids++;
746 * ensure this test matches similar one in
747 * RecoverPreparedTransactions()
749 if (nUnreportedXids >= PGPROC_MAX_CACHED_SUBXIDS ||
750 log_unknown_top)
752 xl_xact_assignment xlrec;
755 * xtop is always set by now because we recurse up transaction
756 * stack to the highest unassigned xid and then come back down
758 xlrec.xtop = GetTopTransactionId();
759 Assert(TransactionIdIsValid(xlrec.xtop));
760 xlrec.nsubxacts = nUnreportedXids;
762 XLogBeginInsert();
763 XLogRegisterData((char *) &xlrec, MinSizeOfXactAssignment);
764 XLogRegisterData((char *) unreportedXids,
765 nUnreportedXids * sizeof(TransactionId));
767 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT);
769 nUnreportedXids = 0;
770 /* mark top, not current xact as having been logged */
771 TopTransactionStateData.didLogXid = true;
777 * GetCurrentSubTransactionId
779 SubTransactionId
780 GetCurrentSubTransactionId(void)
782 TransactionState s = CurrentTransactionState;
784 return s->subTransactionId;
788 * SubTransactionIsActive
790 * Test if the specified subxact ID is still active. Note caller is
791 * responsible for checking whether this ID is relevant to the current xact.
793 bool
794 SubTransactionIsActive(SubTransactionId subxid)
796 TransactionState s;
798 for (s = CurrentTransactionState; s != NULL; s = s->parent)
800 if (s->state == TRANS_ABORT)
801 continue;
802 if (s->subTransactionId == subxid)
803 return true;
805 return false;
810 * GetCurrentCommandId
812 * "used" must be true if the caller intends to use the command ID to mark
813 * inserted/updated/deleted tuples. false means the ID is being fetched
814 * for read-only purposes (ie, as a snapshot validity cutoff). See
815 * CommandCounterIncrement() for discussion.
817 CommandId
818 GetCurrentCommandId(bool used)
820 /* this is global to a transaction, not subtransaction-local */
821 if (used)
824 * Forbid setting currentCommandIdUsed in a parallel worker, because
825 * we have no provision for communicating this back to the leader. We
826 * could relax this restriction when currentCommandIdUsed was already
827 * true at the start of the parallel operation.
829 Assert(!IsParallelWorker());
830 currentCommandIdUsed = true;
832 return currentCommandId;
836 * SetParallelStartTimestamps
838 * In a parallel worker, we should inherit the parent transaction's
839 * timestamps rather than setting our own. The parallel worker
840 * infrastructure must call this to provide those values before
841 * calling StartTransaction() or SetCurrentStatementStartTimestamp().
843 void
844 SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts)
846 Assert(IsParallelWorker());
847 xactStartTimestamp = xact_ts;
848 stmtStartTimestamp = stmt_ts;
852 * GetCurrentTransactionStartTimestamp
854 TimestampTz
855 GetCurrentTransactionStartTimestamp(void)
857 return xactStartTimestamp;
861 * GetCurrentStatementStartTimestamp
863 TimestampTz
864 GetCurrentStatementStartTimestamp(void)
866 return stmtStartTimestamp;
870 * GetCurrentTransactionStopTimestamp
872 * If the transaction stop time hasn't already been set, which can happen if
873 * we decided we don't need to log an XLOG record, set xactStopTimestamp.
875 TimestampTz
876 GetCurrentTransactionStopTimestamp(void)
878 TransactionState s PG_USED_FOR_ASSERTS_ONLY = CurrentTransactionState;
880 /* should only be called after commit / abort processing */
881 Assert(s->state == TRANS_DEFAULT ||
882 s->state == TRANS_COMMIT ||
883 s->state == TRANS_ABORT ||
884 s->state == TRANS_PREPARE);
886 if (xactStopTimestamp == 0)
887 xactStopTimestamp = GetCurrentTimestamp();
889 return xactStopTimestamp;
893 * SetCurrentStatementStartTimestamp
895 * In a parallel worker, this should already have been provided by a call
896 * to SetParallelStartTimestamps().
898 void
899 SetCurrentStatementStartTimestamp(void)
901 if (!IsParallelWorker())
902 stmtStartTimestamp = GetCurrentTimestamp();
903 else
904 Assert(stmtStartTimestamp != 0);
908 * GetCurrentTransactionNestLevel
910 * Note: this will return zero when not inside any transaction, one when
911 * inside a top-level transaction, etc.
914 GetCurrentTransactionNestLevel(void)
916 TransactionState s = CurrentTransactionState;
918 return s->nestingLevel;
923 * TransactionIdIsCurrentTransactionId
925 bool
926 TransactionIdIsCurrentTransactionId(TransactionId xid)
928 TransactionState s;
931 * We always say that BootstrapTransactionId is "not my transaction ID"
932 * even when it is (ie, during bootstrap). Along with the fact that
933 * transam.c always treats BootstrapTransactionId as already committed,
934 * this causes the heapam_visibility.c routines to see all tuples as
935 * committed, which is what we need during bootstrap. (Bootstrap mode
936 * only inserts tuples, it never updates or deletes them, so all tuples
937 * can be presumed good immediately.)
939 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
940 * not my transaction ID, so we can just return "false" immediately for
941 * any non-normal XID.
943 if (!TransactionIdIsNormal(xid))
944 return false;
946 if (TransactionIdEquals(xid, GetTopTransactionIdIfAny()))
947 return true;
950 * In parallel workers, the XIDs we must consider as current are stored in
951 * ParallelCurrentXids rather than the transaction-state stack. Note that
952 * the XIDs in this array are sorted numerically rather than according to
953 * transactionIdPrecedes order.
955 if (nParallelCurrentXids > 0)
957 int low,
958 high;
960 low = 0;
961 high = nParallelCurrentXids - 1;
962 while (low <= high)
964 int middle;
965 TransactionId probe;
967 middle = low + (high - low) / 2;
968 probe = ParallelCurrentXids[middle];
969 if (probe == xid)
970 return true;
971 else if (probe < xid)
972 low = middle + 1;
973 else
974 high = middle - 1;
976 return false;
980 * We will return true for the Xid of the current subtransaction, any of
981 * its subcommitted children, any of its parents, or any of their
982 * previously subcommitted children. However, a transaction being aborted
983 * is no longer "current", even though it may still have an entry on the
984 * state stack.
986 for (s = CurrentTransactionState; s != NULL; s = s->parent)
988 int low,
989 high;
991 if (s->state == TRANS_ABORT)
992 continue;
993 if (!FullTransactionIdIsValid(s->fullTransactionId))
994 continue; /* it can't have any child XIDs either */
995 if (TransactionIdEquals(xid, XidFromFullTransactionId(s->fullTransactionId)))
996 return true;
997 /* As the childXids array is ordered, we can use binary search */
998 low = 0;
999 high = s->nChildXids - 1;
1000 while (low <= high)
1002 int middle;
1003 TransactionId probe;
1005 middle = low + (high - low) / 2;
1006 probe = s->childXids[middle];
1007 if (TransactionIdEquals(probe, xid))
1008 return true;
1009 else if (TransactionIdPrecedes(probe, xid))
1010 low = middle + 1;
1011 else
1012 high = middle - 1;
1016 return false;
1020 * TransactionStartedDuringRecovery
1022 * Returns true if the current transaction started while recovery was still
1023 * in progress. Recovery might have ended since so RecoveryInProgress() might
1024 * return false already.
1026 bool
1027 TransactionStartedDuringRecovery(void)
1029 return CurrentTransactionState->startedInRecovery;
1033 * EnterParallelMode
1035 void
1036 EnterParallelMode(void)
1038 TransactionState s = CurrentTransactionState;
1040 Assert(s->parallelModeLevel >= 0);
1042 ++s->parallelModeLevel;
1046 * ExitParallelMode
1048 void
1049 ExitParallelMode(void)
1051 TransactionState s = CurrentTransactionState;
1053 Assert(s->parallelModeLevel > 0);
1054 Assert(s->parallelModeLevel > 1 || !ParallelContextActive());
1056 --s->parallelModeLevel;
1060 * IsInParallelMode
1062 * Are we in a parallel operation, as either the leader or a worker? Check
1063 * this to prohibit operations that change backend-local state expected to
1064 * match across all workers. Mere caches usually don't require such a
1065 * restriction. State modified in a strict push/pop fashion, such as the
1066 * active snapshot stack, is often fine.
1068 bool
1069 IsInParallelMode(void)
1071 return CurrentTransactionState->parallelModeLevel != 0;
1075 * CommandCounterIncrement
1077 void
1078 CommandCounterIncrement(void)
1081 * If the current value of the command counter hasn't been "used" to mark
1082 * tuples, we need not increment it, since there's no need to distinguish
1083 * a read-only command from others. This helps postpone command counter
1084 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
1086 if (currentCommandIdUsed)
1089 * Workers synchronize transaction state at the beginning of each
1090 * parallel operation, so we can't account for new commands after that
1091 * point.
1093 if (IsInParallelMode() || IsParallelWorker())
1094 elog(ERROR, "cannot start commands during a parallel operation");
1096 currentCommandId += 1;
1097 if (currentCommandId == InvalidCommandId)
1099 currentCommandId -= 1;
1100 ereport(ERROR,
1101 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1102 errmsg("cannot have more than 2^32-2 commands in a transaction")));
1104 currentCommandIdUsed = false;
1106 /* Propagate new command ID into static snapshots */
1107 SnapshotSetCommandId(currentCommandId);
1110 * Make any catalog changes done by the just-completed command visible
1111 * in the local syscache. We obviously don't need to do this after a
1112 * read-only command. (But see hacks in inval.c to make real sure we
1113 * don't think a command that queued inval messages was read-only.)
1115 AtCCI_LocalCache();
1120 * ForceSyncCommit
1122 * Interface routine to allow commands to force a synchronous commit of the
1123 * current top-level transaction. Currently, two-phase commit does not
1124 * persist and restore this variable. So long as all callers use
1125 * PreventInTransactionBlock(), that omission has no consequences.
1127 void
1128 ForceSyncCommit(void)
1130 forceSyncCommit = true;
1134 /* ----------------------------------------------------------------
1135 * StartTransaction stuff
1136 * ----------------------------------------------------------------
1140 * AtStart_Cache
1142 static void
1143 AtStart_Cache(void)
1145 AcceptInvalidationMessages();
1149 * AtStart_Memory
1151 static void
1152 AtStart_Memory(void)
1154 TransactionState s = CurrentTransactionState;
1157 * If this is the first time through, create a private context for
1158 * AbortTransaction to work in. By reserving some space now, we can
1159 * insulate AbortTransaction from out-of-memory scenarios. Like
1160 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1161 * size, so that space will be reserved immediately.
1163 if (TransactionAbortContext == NULL)
1164 TransactionAbortContext =
1165 AllocSetContextCreate(TopMemoryContext,
1166 "TransactionAbortContext",
1167 32 * 1024,
1168 32 * 1024,
1169 32 * 1024);
1172 * We shouldn't have a transaction context already.
1174 Assert(TopTransactionContext == NULL);
1177 * Create a toplevel context for the transaction.
1179 TopTransactionContext =
1180 AllocSetContextCreate(TopMemoryContext,
1181 "TopTransactionContext",
1182 ALLOCSET_DEFAULT_SIZES);
1185 * In a top-level transaction, CurTransactionContext is the same as
1186 * TopTransactionContext.
1188 CurTransactionContext = TopTransactionContext;
1189 s->curTransactionContext = CurTransactionContext;
1191 /* Make the CurTransactionContext active. */
1192 MemoryContextSwitchTo(CurTransactionContext);
1196 * AtStart_ResourceOwner
1198 static void
1199 AtStart_ResourceOwner(void)
1201 TransactionState s = CurrentTransactionState;
1204 * We shouldn't have a transaction resource owner already.
1206 Assert(TopTransactionResourceOwner == NULL);
1209 * Create a toplevel resource owner for the transaction.
1211 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1213 TopTransactionResourceOwner = s->curTransactionOwner;
1214 CurTransactionResourceOwner = s->curTransactionOwner;
1215 CurrentResourceOwner = s->curTransactionOwner;
1218 /* ----------------------------------------------------------------
1219 * StartSubTransaction stuff
1220 * ----------------------------------------------------------------
1224 * AtSubStart_Memory
1226 static void
1227 AtSubStart_Memory(void)
1229 TransactionState s = CurrentTransactionState;
1231 Assert(CurTransactionContext != NULL);
1234 * Create a CurTransactionContext, which will be used to hold data that
1235 * survives subtransaction commit but disappears on subtransaction abort.
1236 * We make it a child of the immediate parent's CurTransactionContext.
1238 CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
1239 "CurTransactionContext",
1240 ALLOCSET_DEFAULT_SIZES);
1241 s->curTransactionContext = CurTransactionContext;
1243 /* Make the CurTransactionContext active. */
1244 MemoryContextSwitchTo(CurTransactionContext);
1248 * AtSubStart_ResourceOwner
1250 static void
1251 AtSubStart_ResourceOwner(void)
1253 TransactionState s = CurrentTransactionState;
1255 Assert(s->parent != NULL);
1258 * Create a resource owner for the subtransaction. We make it a child of
1259 * the immediate parent's resource owner.
1261 s->curTransactionOwner =
1262 ResourceOwnerCreate(s->parent->curTransactionOwner,
1263 "SubTransaction");
1265 CurTransactionResourceOwner = s->curTransactionOwner;
1266 CurrentResourceOwner = s->curTransactionOwner;
1269 /* ----------------------------------------------------------------
1270 * CommitTransaction stuff
1271 * ----------------------------------------------------------------
1275 * RecordTransactionCommit
1277 * Returns latest XID among xact and its children, or InvalidTransactionId
1278 * if the xact has no XID. (We compute that here just because it's easier.)
1280 * If you change this function, see RecordTransactionCommitPrepared also.
1282 static TransactionId
1283 RecordTransactionCommit(void)
1285 TransactionId xid = GetTopTransactionIdIfAny();
1286 bool markXidCommitted = TransactionIdIsValid(xid);
1287 TransactionId latestXid = InvalidTransactionId;
1288 int nrels;
1289 RelFileLocator *rels;
1290 int nchildren;
1291 TransactionId *children;
1292 int ndroppedstats = 0;
1293 xl_xact_stats_item *droppedstats = NULL;
1294 int nmsgs = 0;
1295 SharedInvalidationMessage *invalMessages = NULL;
1296 bool RelcacheInitFileInval = false;
1297 bool wrote_xlog;
1300 * Log pending invalidations for logical decoding of in-progress
1301 * transactions. Normally for DDLs, we log this at each command end,
1302 * however, for certain cases where we directly update the system table
1303 * without a transaction block, the invalidations are not logged till this
1304 * time.
1306 if (XLogLogicalInfoActive())
1307 LogLogicalInvalidations();
1309 /* Get data needed for commit record */
1310 nrels = smgrGetPendingDeletes(true, &rels);
1311 nchildren = xactGetCommittedChildren(&children);
1312 ndroppedstats = pgstat_get_transactional_drops(true, &droppedstats);
1313 if (XLogStandbyInfoActive())
1314 nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
1315 &RelcacheInitFileInval);
1316 wrote_xlog = (XactLastRecEnd != 0);
1319 * If we haven't been assigned an XID yet, we neither can, nor do we want
1320 * to write a COMMIT record.
1322 if (!markXidCommitted)
1325 * We expect that every RelationDropStorage is followed by a catalog
1326 * update, and hence XID assignment, so we shouldn't get here with any
1327 * pending deletes. Same is true for dropping stats.
1329 * Use a real test not just an Assert to check this, since it's a bit
1330 * fragile.
1332 if (nrels != 0 || ndroppedstats != 0)
1333 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
1335 /* Can't have child XIDs either; AssignTransactionId enforces this */
1336 Assert(nchildren == 0);
1339 * Transactions without an assigned xid can contain invalidation
1340 * messages (e.g. explicit relcache invalidations or catcache
1341 * invalidations for inplace updates); standbys need to process those.
1342 * We can't emit a commit record without an xid, and we don't want to
1343 * force assigning an xid, because that'd be problematic for e.g.
1344 * vacuum. Hence we emit a bespoke record for the invalidations. We
1345 * don't want to use that in case a commit record is emitted, so they
1346 * happen synchronously with commits (besides not wanting to emit more
1347 * WAL records).
1349 if (nmsgs != 0)
1351 LogStandbyInvalidations(nmsgs, invalMessages,
1352 RelcacheInitFileInval);
1353 wrote_xlog = true; /* not strictly necessary */
1357 * If we didn't create XLOG entries, we're done here; otherwise we
1358 * should trigger flushing those entries the same as a commit record
1359 * would. This will primarily happen for HOT pruning and the like; we
1360 * want these to be flushed to disk in due time.
1362 if (!wrote_xlog)
1363 goto cleanup;
1365 else
1367 bool replorigin;
1370 * Are we using the replication origins feature? Or, in other words,
1371 * are we replaying remote actions?
1373 replorigin = (replorigin_session_origin != InvalidRepOriginId &&
1374 replorigin_session_origin != DoNotReplicateId);
1377 * Begin commit critical section and insert the commit XLOG record.
1379 /* Tell bufmgr and smgr to prepare for commit */
1380 BufmgrCommit();
1383 * Mark ourselves as within our "commit critical section". This
1384 * forces any concurrent checkpoint to wait until we've updated
1385 * pg_xact. Without this, it is possible for the checkpoint to set
1386 * REDO after the XLOG record but fail to flush the pg_xact update to
1387 * disk, leading to loss of the transaction commit if the system
1388 * crashes a little later.
1390 * Note: we could, but don't bother to, set this flag in
1391 * RecordTransactionAbort. That's because loss of a transaction abort
1392 * is noncritical; the presumption would be that it aborted, anyway.
1394 * It's safe to change the delayChkptFlags flag of our own backend
1395 * without holding the ProcArrayLock, since we're the only one
1396 * modifying it. This makes checkpoint's determination of which xacts
1397 * are delaying the checkpoint a bit fuzzy, but it doesn't matter.
1399 Assert((MyProc->delayChkptFlags & DELAY_CHKPT_START) == 0);
1400 START_CRIT_SECTION();
1401 MyProc->delayChkptFlags |= DELAY_CHKPT_START;
1403 XactLogCommitRecord(GetCurrentTransactionStopTimestamp(),
1404 nchildren, children, nrels, rels,
1405 ndroppedstats, droppedstats,
1406 nmsgs, invalMessages,
1407 RelcacheInitFileInval,
1408 MyXactFlags,
1409 InvalidTransactionId, NULL /* plain commit */ );
1411 if (replorigin)
1412 /* Move LSNs forward for this replication origin */
1413 replorigin_session_advance(replorigin_session_origin_lsn,
1414 XactLastRecEnd);
1417 * Record commit timestamp. The value comes from plain commit
1418 * timestamp if there's no replication origin; otherwise, the
1419 * timestamp was already set in replorigin_session_origin_timestamp by
1420 * replication.
1422 * We don't need to WAL-log anything here, as the commit record
1423 * written above already contains the data.
1426 if (!replorigin || replorigin_session_origin_timestamp == 0)
1427 replorigin_session_origin_timestamp = GetCurrentTransactionStopTimestamp();
1429 TransactionTreeSetCommitTsData(xid, nchildren, children,
1430 replorigin_session_origin_timestamp,
1431 replorigin_session_origin);
1435 * Check if we want to commit asynchronously. We can allow the XLOG flush
1436 * to happen asynchronously if synchronous_commit=off, or if the current
1437 * transaction has not performed any WAL-logged operation or didn't assign
1438 * an xid. The transaction can end up not writing any WAL, even if it has
1439 * an xid, if it only wrote to temporary and/or unlogged tables. It can
1440 * end up having written WAL without an xid if it did HOT pruning. In
1441 * case of a crash, the loss of such a transaction will be irrelevant;
1442 * temp tables will be lost anyway, unlogged tables will be truncated and
1443 * HOT pruning will be done again later. (Given the foregoing, you might
1444 * think that it would be unnecessary to emit the XLOG record at all in
1445 * this case, but we don't currently try to do that. It would certainly
1446 * cause problems at least in Hot Standby mode, where the
1447 * KnownAssignedXids machinery requires tracking every XID assignment. It
1448 * might be OK to skip it only when wal_level < replica, but for now we
1449 * don't.)
1451 * However, if we're doing cleanup of any non-temp rels or committing any
1452 * command that wanted to force sync commit, then we must flush XLOG
1453 * immediately. (We must not allow asynchronous commit if there are any
1454 * non-temp tables to be deleted, because we might delete the files before
1455 * the COMMIT record is flushed to disk. We do allow asynchronous commit
1456 * if all to-be-deleted tables are temporary though, since they are lost
1457 * anyway if we crash.)
1459 if ((wrote_xlog && markXidCommitted &&
1460 synchronous_commit > SYNCHRONOUS_COMMIT_OFF) ||
1461 forceSyncCommit || nrels > 0)
1463 XLogFlush(XactLastRecEnd);
1466 * Now we may update the CLOG, if we wrote a COMMIT record above
1468 if (markXidCommitted)
1469 TransactionIdCommitTree(xid, nchildren, children);
1471 else
1474 * Asynchronous commit case:
1476 * This enables possible committed transaction loss in the case of a
1477 * postmaster crash because WAL buffers are left unwritten. Ideally we
1478 * could issue the WAL write without the fsync, but some
1479 * wal_sync_methods do not allow separate write/fsync.
1481 * Report the latest async commit LSN, so that the WAL writer knows to
1482 * flush this commit.
1484 XLogSetAsyncXactLSN(XactLastRecEnd);
1487 * We must not immediately update the CLOG, since we didn't flush the
1488 * XLOG. Instead, we store the LSN up to which the XLOG must be
1489 * flushed before the CLOG may be updated.
1491 if (markXidCommitted)
1492 TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1496 * If we entered a commit critical section, leave it now, and let
1497 * checkpoints proceed.
1499 if (markXidCommitted)
1501 MyProc->delayChkptFlags &= ~DELAY_CHKPT_START;
1502 END_CRIT_SECTION();
1505 /* Compute latestXid while we have the child XIDs handy */
1506 latestXid = TransactionIdLatest(xid, nchildren, children);
1509 * Wait for synchronous replication, if required. Similar to the decision
1510 * above about using committing asynchronously we only want to wait if
1511 * this backend assigned an xid and wrote WAL. No need to wait if an xid
1512 * was assigned due to temporary/unlogged tables or due to HOT pruning.
1514 * Note that at this stage we have marked clog, but still show as running
1515 * in the procarray and continue to hold locks.
1517 if (wrote_xlog && markXidCommitted)
1518 SyncRepWaitForLSN(XactLastRecEnd, true);
1520 /* remember end of last commit record */
1521 XactLastCommitEnd = XactLastRecEnd;
1523 /* Reset XactLastRecEnd until the next transaction writes something */
1524 XactLastRecEnd = 0;
1525 cleanup:
1526 /* Clean up local data */
1527 if (rels)
1528 pfree(rels);
1529 if (ndroppedstats)
1530 pfree(droppedstats);
1532 return latestXid;
1537 * AtCCI_LocalCache
1539 static void
1540 AtCCI_LocalCache(void)
1543 * Make any pending relation map changes visible. We must do this before
1544 * processing local sinval messages, so that the map changes will get
1545 * reflected into the relcache when relcache invals are processed.
1547 AtCCI_RelationMap();
1550 * Make catalog changes visible to me for the next command.
1552 CommandEndInvalidationMessages();
1556 * AtCommit_Memory
1558 static void
1559 AtCommit_Memory(void)
1562 * Now that we're "out" of a transaction, have the system allocate things
1563 * in the top memory context instead of per-transaction contexts.
1565 MemoryContextSwitchTo(TopMemoryContext);
1568 * Release all transaction-local memory.
1570 Assert(TopTransactionContext != NULL);
1571 MemoryContextDelete(TopTransactionContext);
1572 TopTransactionContext = NULL;
1573 CurTransactionContext = NULL;
1574 CurrentTransactionState->curTransactionContext = NULL;
1577 /* ----------------------------------------------------------------
1578 * CommitSubTransaction stuff
1579 * ----------------------------------------------------------------
1583 * AtSubCommit_Memory
1585 static void
1586 AtSubCommit_Memory(void)
1588 TransactionState s = CurrentTransactionState;
1590 Assert(s->parent != NULL);
1592 /* Return to parent transaction level's memory context. */
1593 CurTransactionContext = s->parent->curTransactionContext;
1594 MemoryContextSwitchTo(CurTransactionContext);
1597 * Ordinarily we cannot throw away the child's CurTransactionContext,
1598 * since the data it contains will be needed at upper commit. However, if
1599 * there isn't actually anything in it, we can throw it away. This avoids
1600 * a small memory leak in the common case of "trivial" subxacts.
1602 if (MemoryContextIsEmpty(s->curTransactionContext))
1604 MemoryContextDelete(s->curTransactionContext);
1605 s->curTransactionContext = NULL;
1610 * AtSubCommit_childXids
1612 * Pass my own XID and my child XIDs up to my parent as committed children.
1614 static void
1615 AtSubCommit_childXids(void)
1617 TransactionState s = CurrentTransactionState;
1618 int new_nChildXids;
1620 Assert(s->parent != NULL);
1623 * The parent childXids array will need to hold my XID and all my
1624 * childXids, in addition to the XIDs already there.
1626 new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1628 /* Allocate or enlarge the parent array if necessary */
1629 if (s->parent->maxChildXids < new_nChildXids)
1631 int new_maxChildXids;
1632 TransactionId *new_childXids;
1635 * Make it 2x what's needed right now, to avoid having to enlarge it
1636 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1637 * is what ensures that we don't need to worry about integer overflow
1638 * here or in the calculation of new_nChildXids.)
1640 new_maxChildXids = Min(new_nChildXids * 2,
1641 (int) (MaxAllocSize / sizeof(TransactionId)));
1643 if (new_maxChildXids < new_nChildXids)
1644 ereport(ERROR,
1645 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1646 errmsg("maximum number of committed subtransactions (%d) exceeded",
1647 (int) (MaxAllocSize / sizeof(TransactionId)))));
1650 * We keep the child-XID arrays in TopTransactionContext; this avoids
1651 * setting up child-transaction contexts for what might be just a few
1652 * bytes of grandchild XIDs.
1654 if (s->parent->childXids == NULL)
1655 new_childXids =
1656 MemoryContextAlloc(TopTransactionContext,
1657 new_maxChildXids * sizeof(TransactionId));
1658 else
1659 new_childXids = repalloc(s->parent->childXids,
1660 new_maxChildXids * sizeof(TransactionId));
1662 s->parent->childXids = new_childXids;
1663 s->parent->maxChildXids = new_maxChildXids;
1667 * Copy all my XIDs to parent's array.
1669 * Note: We rely on the fact that the XID of a child always follows that
1670 * of its parent. By copying the XID of this subtransaction before the
1671 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1672 * all XIDs already in the array belong to subtransactions started and
1673 * subcommitted before us, so their XIDs must precede ours.
1675 s->parent->childXids[s->parent->nChildXids] = XidFromFullTransactionId(s->fullTransactionId);
1677 if (s->nChildXids > 0)
1678 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1679 s->childXids,
1680 s->nChildXids * sizeof(TransactionId));
1682 s->parent->nChildXids = new_nChildXids;
1684 /* Release child's array to avoid leakage */
1685 if (s->childXids != NULL)
1686 pfree(s->childXids);
1687 /* We must reset these to avoid double-free if fail later in commit */
1688 s->childXids = NULL;
1689 s->nChildXids = 0;
1690 s->maxChildXids = 0;
1693 /* ----------------------------------------------------------------
1694 * AbortTransaction stuff
1695 * ----------------------------------------------------------------
1699 * RecordTransactionAbort
1701 * Returns latest XID among xact and its children, or InvalidTransactionId
1702 * if the xact has no XID. (We compute that here just because it's easier.)
1704 static TransactionId
1705 RecordTransactionAbort(bool isSubXact)
1707 TransactionId xid = GetCurrentTransactionIdIfAny();
1708 TransactionId latestXid;
1709 int nrels;
1710 RelFileLocator *rels;
1711 int ndroppedstats = 0;
1712 xl_xact_stats_item *droppedstats = NULL;
1713 int nchildren;
1714 TransactionId *children;
1715 TimestampTz xact_time;
1716 bool replorigin;
1719 * If we haven't been assigned an XID, nobody will care whether we aborted
1720 * or not. Hence, we're done in that case. It does not matter if we have
1721 * rels to delete (note that this routine is not responsible for actually
1722 * deleting 'em). We cannot have any child XIDs, either.
1724 if (!TransactionIdIsValid(xid))
1726 /* Reset XactLastRecEnd until the next transaction writes something */
1727 if (!isSubXact)
1728 XactLastRecEnd = 0;
1729 return InvalidTransactionId;
1733 * We have a valid XID, so we should write an ABORT record for it.
1735 * We do not flush XLOG to disk here, since the default assumption after a
1736 * crash would be that we aborted, anyway. For the same reason, we don't
1737 * need to worry about interlocking against checkpoint start.
1741 * Check that we haven't aborted halfway through RecordTransactionCommit.
1743 if (TransactionIdDidCommit(xid))
1744 elog(PANIC, "cannot abort transaction %u, it was already committed",
1745 xid);
1748 * Are we using the replication origins feature? Or, in other words, are
1749 * we replaying remote actions?
1751 replorigin = (replorigin_session_origin != InvalidRepOriginId &&
1752 replorigin_session_origin != DoNotReplicateId);
1754 /* Fetch the data we need for the abort record */
1755 nrels = smgrGetPendingDeletes(false, &rels);
1756 nchildren = xactGetCommittedChildren(&children);
1757 ndroppedstats = pgstat_get_transactional_drops(false, &droppedstats);
1759 /* XXX do we really need a critical section here? */
1760 START_CRIT_SECTION();
1762 /* Write the ABORT record */
1763 if (isSubXact)
1764 xact_time = GetCurrentTimestamp();
1765 else
1767 xact_time = GetCurrentTransactionStopTimestamp();
1770 XactLogAbortRecord(xact_time,
1771 nchildren, children,
1772 nrels, rels,
1773 ndroppedstats, droppedstats,
1774 MyXactFlags, InvalidTransactionId,
1775 NULL);
1777 if (replorigin)
1778 /* Move LSNs forward for this replication origin */
1779 replorigin_session_advance(replorigin_session_origin_lsn,
1780 XactLastRecEnd);
1783 * Report the latest async abort LSN, so that the WAL writer knows to
1784 * flush this abort. There's nothing to be gained by delaying this, since
1785 * WALWriter may as well do this when it can. This is important with
1786 * streaming replication because if we don't flush WAL regularly we will
1787 * find that large aborts leave us with a long backlog for when commits
1788 * occur after the abort, increasing our window of data loss should
1789 * problems occur at that point.
1791 if (!isSubXact)
1792 XLogSetAsyncXactLSN(XactLastRecEnd);
1795 * Mark the transaction aborted in clog. This is not absolutely necessary
1796 * but we may as well do it while we are here; also, in the subxact case
1797 * it is helpful because XactLockTableWait makes use of it to avoid
1798 * waiting for already-aborted subtransactions. It is OK to do it without
1799 * having flushed the ABORT record to disk, because in event of a crash
1800 * we'd be assumed to have aborted anyway.
1802 TransactionIdAbortTree(xid, nchildren, children);
1804 END_CRIT_SECTION();
1806 /* Compute latestXid while we have the child XIDs handy */
1807 latestXid = TransactionIdLatest(xid, nchildren, children);
1810 * If we're aborting a subtransaction, we can immediately remove failed
1811 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1812 * subxacts, because we already have the child XID array at hand. For
1813 * main xacts, the equivalent happens just after this function returns.
1815 if (isSubXact)
1816 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1818 /* Reset XactLastRecEnd until the next transaction writes something */
1819 if (!isSubXact)
1820 XactLastRecEnd = 0;
1822 /* And clean up local data */
1823 if (rels)
1824 pfree(rels);
1825 if (ndroppedstats)
1826 pfree(droppedstats);
1828 return latestXid;
1832 * AtAbort_Memory
1834 static void
1835 AtAbort_Memory(void)
1838 * Switch into TransactionAbortContext, which should have some free space
1839 * even if nothing else does. We'll work in this context until we've
1840 * finished cleaning up.
1842 * It is barely possible to get here when we've not been able to create
1843 * TransactionAbortContext yet; if so use TopMemoryContext.
1845 if (TransactionAbortContext != NULL)
1846 MemoryContextSwitchTo(TransactionAbortContext);
1847 else
1848 MemoryContextSwitchTo(TopMemoryContext);
1852 * AtSubAbort_Memory
1854 static void
1855 AtSubAbort_Memory(void)
1857 Assert(TransactionAbortContext != NULL);
1859 MemoryContextSwitchTo(TransactionAbortContext);
1864 * AtAbort_ResourceOwner
1866 static void
1867 AtAbort_ResourceOwner(void)
1870 * Make sure we have a valid ResourceOwner, if possible (else it will be
1871 * NULL, which is OK)
1873 CurrentResourceOwner = TopTransactionResourceOwner;
1877 * AtSubAbort_ResourceOwner
1879 static void
1880 AtSubAbort_ResourceOwner(void)
1882 TransactionState s = CurrentTransactionState;
1884 /* Make sure we have a valid ResourceOwner */
1885 CurrentResourceOwner = s->curTransactionOwner;
1890 * AtSubAbort_childXids
1892 static void
1893 AtSubAbort_childXids(void)
1895 TransactionState s = CurrentTransactionState;
1898 * We keep the child-XID arrays in TopTransactionContext (see
1899 * AtSubCommit_childXids). This means we'd better free the array
1900 * explicitly at abort to avoid leakage.
1902 if (s->childXids != NULL)
1903 pfree(s->childXids);
1904 s->childXids = NULL;
1905 s->nChildXids = 0;
1906 s->maxChildXids = 0;
1909 * We could prune the unreportedXids array here. But we don't bother. That
1910 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1911 * would likely introduce more CPU time into the more common paths, so we
1912 * choose not to do that.
1916 /* ----------------------------------------------------------------
1917 * CleanupTransaction stuff
1918 * ----------------------------------------------------------------
1922 * AtCleanup_Memory
1924 static void
1925 AtCleanup_Memory(void)
1927 Assert(CurrentTransactionState->parent == NULL);
1930 * Now that we're "out" of a transaction, have the system allocate things
1931 * in the top memory context instead of per-transaction contexts.
1933 MemoryContextSwitchTo(TopMemoryContext);
1936 * Clear the special abort context for next time.
1938 if (TransactionAbortContext != NULL)
1939 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1942 * Release all transaction-local memory.
1944 if (TopTransactionContext != NULL)
1945 MemoryContextDelete(TopTransactionContext);
1946 TopTransactionContext = NULL;
1947 CurTransactionContext = NULL;
1948 CurrentTransactionState->curTransactionContext = NULL;
1952 /* ----------------------------------------------------------------
1953 * CleanupSubTransaction stuff
1954 * ----------------------------------------------------------------
1958 * AtSubCleanup_Memory
1960 static void
1961 AtSubCleanup_Memory(void)
1963 TransactionState s = CurrentTransactionState;
1965 Assert(s->parent != NULL);
1967 /* Make sure we're not in an about-to-be-deleted context */
1968 MemoryContextSwitchTo(s->parent->curTransactionContext);
1969 CurTransactionContext = s->parent->curTransactionContext;
1972 * Clear the special abort context for next time.
1974 if (TransactionAbortContext != NULL)
1975 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1978 * Delete the subxact local memory contexts. Its CurTransactionContext can
1979 * go too (note this also kills CurTransactionContexts from any children
1980 * of the subxact).
1982 if (s->curTransactionContext)
1983 MemoryContextDelete(s->curTransactionContext);
1984 s->curTransactionContext = NULL;
1987 /* ----------------------------------------------------------------
1988 * interface routines
1989 * ----------------------------------------------------------------
1993 * StartTransaction
1995 static void
1996 StartTransaction(void)
1998 TransactionState s;
1999 VirtualTransactionId vxid;
2002 * Let's just make sure the state stack is empty
2004 s = &TopTransactionStateData;
2005 CurrentTransactionState = s;
2007 Assert(!FullTransactionIdIsValid(XactTopFullTransactionId));
2009 /* check the current transaction state */
2010 Assert(s->state == TRANS_DEFAULT);
2013 * Set the current transaction state information appropriately during
2014 * start processing. Note that once the transaction status is switched
2015 * this process cannot fail until the user ID and the security context
2016 * flags are fetched below.
2018 s->state = TRANS_START;
2019 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
2021 /* Determine if statements are logged in this transaction */
2022 xact_is_sampled = log_xact_sample_rate != 0 &&
2023 (log_xact_sample_rate == 1 ||
2024 pg_prng_double(&pg_global_prng_state) <= log_xact_sample_rate);
2027 * initialize current transaction state fields
2029 * note: prevXactReadOnly is not used at the outermost level
2031 s->nestingLevel = 1;
2032 s->gucNestLevel = 1;
2033 s->childXids = NULL;
2034 s->nChildXids = 0;
2035 s->maxChildXids = 0;
2038 * Once the current user ID and the security context flags are fetched,
2039 * both will be properly reset even if transaction startup fails.
2041 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
2043 /* SecurityRestrictionContext should never be set outside a transaction */
2044 Assert(s->prevSecContext == 0);
2047 * Make sure we've reset xact state variables
2049 * If recovery is still in progress, mark this transaction as read-only.
2050 * We have lower level defences in XLogInsert and elsewhere to stop us
2051 * from modifying data during recovery, but this gives the normal
2052 * indication to the user that the transaction is read-only.
2054 if (RecoveryInProgress())
2056 s->startedInRecovery = true;
2057 XactReadOnly = true;
2059 else
2061 s->startedInRecovery = false;
2062 XactReadOnly = DefaultXactReadOnly;
2064 XactDeferrable = DefaultXactDeferrable;
2065 XactIsoLevel = DefaultXactIsoLevel;
2066 forceSyncCommit = false;
2067 MyXactFlags = 0;
2070 * reinitialize within-transaction counters
2072 s->subTransactionId = TopSubTransactionId;
2073 currentSubTransactionId = TopSubTransactionId;
2074 currentCommandId = FirstCommandId;
2075 currentCommandIdUsed = false;
2078 * initialize reported xid accounting
2080 nUnreportedXids = 0;
2081 s->didLogXid = false;
2084 * must initialize resource-management stuff first
2086 AtStart_Memory();
2087 AtStart_ResourceOwner();
2090 * Assign a new LocalTransactionId, and combine it with the backendId to
2091 * form a virtual transaction id.
2093 vxid.backendId = MyBackendId;
2094 vxid.localTransactionId = GetNextLocalTransactionId();
2097 * Lock the virtual transaction id before we announce it in the proc array
2099 VirtualXactLockTableInsert(vxid);
2102 * Advertise it in the proc array. We assume assignment of
2103 * localTransactionId is atomic, and the backendId should be set already.
2105 Assert(MyProc->backendId == vxid.backendId);
2106 MyProc->lxid = vxid.localTransactionId;
2108 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
2111 * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2112 * be the same as the first command's statement_timestamp(), so don't do a
2113 * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2114 * for transactions started inside procedures (i.e., nonatomic SPI
2115 * contexts), we do need to advance the timestamp. Also, in a parallel
2116 * worker, the timestamp should already have been provided by a call to
2117 * SetParallelStartTimestamps().
2119 if (!IsParallelWorker())
2121 if (!SPI_inside_nonatomic_context())
2122 xactStartTimestamp = stmtStartTimestamp;
2123 else
2124 xactStartTimestamp = GetCurrentTimestamp();
2126 else
2127 Assert(xactStartTimestamp != 0);
2128 pgstat_report_xact_timestamp(xactStartTimestamp);
2129 /* Mark xactStopTimestamp as unset. */
2130 xactStopTimestamp = 0;
2133 * initialize other subsystems for new transaction
2135 AtStart_GUC();
2136 AtStart_Cache();
2137 AfterTriggerBeginXact();
2140 * done with start processing, set current transaction state to "in
2141 * progress"
2143 s->state = TRANS_INPROGRESS;
2145 ShowTransactionState("StartTransaction");
2150 * CommitTransaction
2152 * NB: if you change this routine, better look at PrepareTransaction too!
2154 static void
2155 CommitTransaction(void)
2157 TransactionState s = CurrentTransactionState;
2158 TransactionId latestXid;
2159 bool is_parallel_worker;
2161 is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2163 /* Enforce parallel mode restrictions during parallel worker commit. */
2164 if (is_parallel_worker)
2165 EnterParallelMode();
2167 ShowTransactionState("CommitTransaction");
2170 * check the current transaction state
2172 if (s->state != TRANS_INPROGRESS)
2173 elog(WARNING, "CommitTransaction while in %s state",
2174 TransStateAsString(s->state));
2175 Assert(s->parent == NULL);
2178 * Do pre-commit processing that involves calling user-defined code, such
2179 * as triggers. SECURITY_RESTRICTED_OPERATION contexts must not queue an
2180 * action that would run here, because that would bypass the sandbox.
2181 * Since closing cursors could queue trigger actions, triggers could open
2182 * cursors, etc, we have to keep looping until there's nothing left to do.
2184 for (;;)
2187 * Fire all currently pending deferred triggers.
2189 AfterTriggerFireDeferred();
2192 * Close open portals (converting holdable ones into static portals).
2193 * If there weren't any, we are done ... otherwise loop back to check
2194 * if they queued deferred triggers. Lather, rinse, repeat.
2196 if (!PreCommit_Portals(false))
2197 break;
2201 * The remaining actions cannot call any user-defined code, so it's safe
2202 * to start shutting down within-transaction services. But note that most
2203 * of this stuff could still throw an error, which would switch us into
2204 * the transaction-abort path.
2207 CallXactCallbacks(is_parallel_worker ? XACT_EVENT_PARALLEL_PRE_COMMIT
2208 : XACT_EVENT_PRE_COMMIT);
2210 /* If we might have parallel workers, clean them up now. */
2211 if (IsInParallelMode())
2212 AtEOXact_Parallel(true);
2214 /* Shut down the deferred-trigger manager */
2215 AfterTriggerEndXact(true);
2218 * Let ON COMMIT management do its thing (must happen after closing
2219 * cursors, to avoid dangling-reference problems)
2221 PreCommit_on_commit_actions();
2224 * Synchronize files that are created and not WAL-logged during this
2225 * transaction. This must happen before AtEOXact_RelationMap(), so that we
2226 * don't see committed-but-broken files after a crash.
2228 smgrDoPendingSyncs(true, is_parallel_worker);
2230 /* close large objects before lower-level cleanup */
2231 AtEOXact_LargeObject(true);
2234 * Insert notifications sent by NOTIFY commands into the queue. This
2235 * should be late in the pre-commit sequence to minimize time spent
2236 * holding the notify-insertion lock. However, this could result in
2237 * creating a snapshot, so we must do it before serializable cleanup.
2239 PreCommit_Notify();
2242 * Mark serializable transaction as complete for predicate locking
2243 * purposes. This should be done as late as we can put it and still allow
2244 * errors to be raised for failure patterns found at commit. This is not
2245 * appropriate in a parallel worker however, because we aren't committing
2246 * the leader's transaction and its serializable state will live on.
2248 if (!is_parallel_worker)
2249 PreCommit_CheckForSerializationFailure();
2251 /* Prevent cancel/die interrupt while cleaning up */
2252 HOLD_INTERRUPTS();
2254 /* Commit updates to the relation map --- do this as late as possible */
2255 AtEOXact_RelationMap(true, is_parallel_worker);
2258 * set the current transaction state information appropriately during
2259 * commit processing
2261 s->state = TRANS_COMMIT;
2262 s->parallelModeLevel = 0;
2264 if (!is_parallel_worker)
2267 * We need to mark our XIDs as committed in pg_xact. This is where we
2268 * durably commit.
2270 latestXid = RecordTransactionCommit();
2272 else
2275 * We must not mark our XID committed; the parallel leader is
2276 * responsible for that.
2278 latestXid = InvalidTransactionId;
2281 * Make sure the leader will know about any WAL we wrote before it
2282 * commits.
2284 ParallelWorkerReportLastRecEnd(XactLastRecEnd);
2287 TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
2290 * Let others know about no transaction in progress by me. Note that this
2291 * must be done _before_ releasing locks we hold and _after_
2292 * RecordTransactionCommit.
2294 ProcArrayEndTransaction(MyProc, latestXid);
2297 * This is all post-commit cleanup. Note that if an error is raised here,
2298 * it's too late to abort the transaction. This should be just
2299 * noncritical resource releasing.
2301 * The ordering of operations is not entirely random. The idea is:
2302 * release resources visible to other backends (eg, files, buffer pins);
2303 * then release locks; then release backend-local resources. We want to
2304 * release locks at the point where any backend waiting for us will see
2305 * our transaction as being fully cleaned up.
2307 * Resources that can be associated with individual queries are handled by
2308 * the ResourceOwner mechanism. The other calls here are for backend-wide
2309 * state.
2312 CallXactCallbacks(is_parallel_worker ? XACT_EVENT_PARALLEL_COMMIT
2313 : XACT_EVENT_COMMIT);
2315 ResourceOwnerRelease(TopTransactionResourceOwner,
2316 RESOURCE_RELEASE_BEFORE_LOCKS,
2317 true, true);
2319 /* Check we've released all buffer pins */
2320 AtEOXact_Buffers(true);
2322 /* Clean up the relation cache */
2323 AtEOXact_RelationCache(true);
2326 * Make catalog changes visible to all backends. This has to happen after
2327 * relcache references are dropped (see comments for
2328 * AtEOXact_RelationCache), but before locks are released (if anyone is
2329 * waiting for lock on a relation we've modified, we want them to know
2330 * about the catalog change before they start using the relation).
2332 AtEOXact_Inval(true);
2334 AtEOXact_MultiXact();
2336 ResourceOwnerRelease(TopTransactionResourceOwner,
2337 RESOURCE_RELEASE_LOCKS,
2338 true, true);
2339 ResourceOwnerRelease(TopTransactionResourceOwner,
2340 RESOURCE_RELEASE_AFTER_LOCKS,
2341 true, true);
2344 * Likewise, dropping of files deleted during the transaction is best done
2345 * after releasing relcache and buffer pins. (This is not strictly
2346 * necessary during commit, since such pins should have been released
2347 * already, but this ordering is definitely critical during abort.) Since
2348 * this may take many seconds, also delay until after releasing locks.
2349 * Other backends will observe the attendant catalog changes and not
2350 * attempt to access affected files.
2352 smgrDoPendingDeletes(true);
2355 * Send out notification signals to other backends (and do other
2356 * post-commit NOTIFY cleanup). This must not happen until after our
2357 * transaction is fully done from the viewpoint of other backends.
2359 AtCommit_Notify();
2362 * Everything after this should be purely internal-to-this-backend
2363 * cleanup.
2365 AtEOXact_GUC(true, 1);
2366 AtEOXact_SPI(true);
2367 AtEOXact_Enum();
2368 AtEOXact_on_commit_actions(true);
2369 AtEOXact_Namespace(true, is_parallel_worker);
2370 AtEOXact_SMgr();
2371 AtEOXact_Files(true);
2372 AtEOXact_ComboCid();
2373 AtEOXact_HashTables(true);
2374 AtEOXact_PgStat(true, is_parallel_worker);
2375 AtEOXact_Snapshot(true, false);
2376 AtEOXact_ApplyLauncher(true);
2377 AtEOXact_LogicalRepWorkers(true);
2378 pgstat_report_xact_timestamp(0);
2380 CurrentResourceOwner = NULL;
2381 ResourceOwnerDelete(TopTransactionResourceOwner);
2382 s->curTransactionOwner = NULL;
2383 CurTransactionResourceOwner = NULL;
2384 TopTransactionResourceOwner = NULL;
2386 AtCommit_Memory();
2388 s->fullTransactionId = InvalidFullTransactionId;
2389 s->subTransactionId = InvalidSubTransactionId;
2390 s->nestingLevel = 0;
2391 s->gucNestLevel = 0;
2392 s->childXids = NULL;
2393 s->nChildXids = 0;
2394 s->maxChildXids = 0;
2396 XactTopFullTransactionId = InvalidFullTransactionId;
2397 nParallelCurrentXids = 0;
2400 * done with commit processing, set current transaction state back to
2401 * default
2403 s->state = TRANS_DEFAULT;
2405 RESUME_INTERRUPTS();
2410 * PrepareTransaction
2412 * NB: if you change this routine, better look at CommitTransaction too!
2414 static void
2415 PrepareTransaction(void)
2417 TransactionState s = CurrentTransactionState;
2418 TransactionId xid = GetCurrentTransactionId();
2419 GlobalTransaction gxact;
2420 TimestampTz prepared_at;
2422 Assert(!IsInParallelMode());
2424 ShowTransactionState("PrepareTransaction");
2427 * check the current transaction state
2429 if (s->state != TRANS_INPROGRESS)
2430 elog(WARNING, "PrepareTransaction while in %s state",
2431 TransStateAsString(s->state));
2432 Assert(s->parent == NULL);
2435 * Do pre-commit processing that involves calling user-defined code, such
2436 * as triggers. Since closing cursors could queue trigger actions,
2437 * triggers could open cursors, etc, we have to keep looping until there's
2438 * nothing left to do.
2440 for (;;)
2443 * Fire all currently pending deferred triggers.
2445 AfterTriggerFireDeferred();
2448 * Close open portals (converting holdable ones into static portals).
2449 * If there weren't any, we are done ... otherwise loop back to check
2450 * if they queued deferred triggers. Lather, rinse, repeat.
2452 if (!PreCommit_Portals(true))
2453 break;
2456 CallXactCallbacks(XACT_EVENT_PRE_PREPARE);
2459 * The remaining actions cannot call any user-defined code, so it's safe
2460 * to start shutting down within-transaction services. But note that most
2461 * of this stuff could still throw an error, which would switch us into
2462 * the transaction-abort path.
2465 /* Shut down the deferred-trigger manager */
2466 AfterTriggerEndXact(true);
2469 * Let ON COMMIT management do its thing (must happen after closing
2470 * cursors, to avoid dangling-reference problems)
2472 PreCommit_on_commit_actions();
2475 * Synchronize files that are created and not WAL-logged during this
2476 * transaction. This must happen before EndPrepare(), so that we don't see
2477 * committed-but-broken files after a crash and COMMIT PREPARED.
2479 smgrDoPendingSyncs(true, false);
2481 /* close large objects before lower-level cleanup */
2482 AtEOXact_LargeObject(true);
2484 /* NOTIFY requires no work at this point */
2487 * Mark serializable transaction as complete for predicate locking
2488 * purposes. This should be done as late as we can put it and still allow
2489 * errors to be raised for failure patterns found at commit.
2491 PreCommit_CheckForSerializationFailure();
2494 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2495 * this transaction. Having the prepared xact hold locks on another
2496 * backend's temp table seems a bad idea --- for instance it would prevent
2497 * the backend from exiting. There are other problems too, such as how to
2498 * clean up the source backend's local buffers and ON COMMIT state if the
2499 * prepared xact includes a DROP of a temp table.
2501 * Other objects types, like functions, operators or extensions, share the
2502 * same restriction as they should not be created, locked or dropped as
2503 * this can mess up with this session or even a follow-up session trying
2504 * to use the same temporary namespace.
2506 * We must check this after executing any ON COMMIT actions, because they
2507 * might still access a temp relation.
2509 * XXX In principle this could be relaxed to allow some useful special
2510 * cases, such as a temp table created and dropped all within the
2511 * transaction. That seems to require much more bookkeeping though.
2513 if ((MyXactFlags & XACT_FLAGS_ACCESSEDTEMPNAMESPACE))
2514 ereport(ERROR,
2515 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2516 errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2519 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2520 * supported if we added cleanup logic to twophase.c, but for now it
2521 * doesn't seem worth the trouble.
2523 if (XactHasExportedSnapshots())
2524 ereport(ERROR,
2525 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2526 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2528 /* Prevent cancel/die interrupt while cleaning up */
2529 HOLD_INTERRUPTS();
2532 * set the current transaction state information appropriately during
2533 * prepare processing
2535 s->state = TRANS_PREPARE;
2537 prepared_at = GetCurrentTimestamp();
2539 /* Tell bufmgr and smgr to prepare for commit */
2540 BufmgrCommit();
2543 * Reserve the GID for this transaction. This could fail if the requested
2544 * GID is invalid or already in use.
2546 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
2547 GetUserId(), MyDatabaseId);
2548 prepareGID = NULL;
2551 * Collect data for the 2PC state file. Note that in general, no actual
2552 * state change should happen in the called modules during this step,
2553 * since it's still possible to fail before commit, and in that case we
2554 * want transaction abort to be able to clean up. (In particular, the
2555 * AtPrepare routines may error out if they find cases they cannot
2556 * handle.) State cleanup should happen in the PostPrepare routines
2557 * below. However, some modules can go ahead and clear state here because
2558 * they wouldn't do anything with it during abort anyway.
2560 * Note: because the 2PC state file records will be replayed in the same
2561 * order they are made, the order of these calls has to match the order in
2562 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2563 * PREPARED; in particular, pay attention to whether things should happen
2564 * before or after releasing the transaction's locks.
2566 StartPrepare(gxact);
2568 AtPrepare_Notify();
2569 AtPrepare_Locks();
2570 AtPrepare_PredicateLocks();
2571 AtPrepare_PgStat();
2572 AtPrepare_MultiXact();
2573 AtPrepare_RelationMap();
2576 * Here is where we really truly prepare.
2578 * We have to record transaction prepares even if we didn't make any
2579 * updates, because the transaction manager might get confused if we lose
2580 * a global transaction.
2582 EndPrepare(gxact);
2585 * Now we clean up backend-internal state and release internal resources.
2588 /* Reset XactLastRecEnd until the next transaction writes something */
2589 XactLastRecEnd = 0;
2592 * Transfer our locks to a dummy PGPROC. This has to be done before
2593 * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2594 * conclude "xact already committed or aborted" for our locks.
2596 PostPrepare_Locks(xid);
2599 * Let others know about no transaction in progress by me. This has to be
2600 * done *after* the prepared transaction has been marked valid, else
2601 * someone may think it is unlocked and recyclable.
2603 ProcArrayClearTransaction(MyProc);
2606 * In normal commit-processing, this is all non-critical post-transaction
2607 * cleanup. When the transaction is prepared, however, it's important
2608 * that the locks and other per-backend resources are transferred to the
2609 * prepared transaction's PGPROC entry. Note that if an error is raised
2610 * here, it's too late to abort the transaction. XXX: This probably should
2611 * be in a critical section, to force a PANIC if any of this fails, but
2612 * that cure could be worse than the disease.
2615 CallXactCallbacks(XACT_EVENT_PREPARE);
2617 ResourceOwnerRelease(TopTransactionResourceOwner,
2618 RESOURCE_RELEASE_BEFORE_LOCKS,
2619 true, true);
2621 /* Check we've released all buffer pins */
2622 AtEOXact_Buffers(true);
2624 /* Clean up the relation cache */
2625 AtEOXact_RelationCache(true);
2627 /* notify doesn't need a postprepare call */
2629 PostPrepare_PgStat();
2631 PostPrepare_Inval();
2633 PostPrepare_smgr();
2635 PostPrepare_MultiXact(xid);
2637 PostPrepare_PredicateLocks(xid);
2639 ResourceOwnerRelease(TopTransactionResourceOwner,
2640 RESOURCE_RELEASE_LOCKS,
2641 true, true);
2642 ResourceOwnerRelease(TopTransactionResourceOwner,
2643 RESOURCE_RELEASE_AFTER_LOCKS,
2644 true, true);
2647 * Allow another backend to finish the transaction. After
2648 * PostPrepare_Twophase(), the transaction is completely detached from our
2649 * backend. The rest is just non-critical cleanup of backend-local state.
2651 PostPrepare_Twophase();
2653 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2654 AtEOXact_GUC(true, 1);
2655 AtEOXact_SPI(true);
2656 AtEOXact_Enum();
2657 AtEOXact_on_commit_actions(true);
2658 AtEOXact_Namespace(true, false);
2659 AtEOXact_SMgr();
2660 AtEOXact_Files(true);
2661 AtEOXact_ComboCid();
2662 AtEOXact_HashTables(true);
2663 /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2664 AtEOXact_Snapshot(true, true);
2665 /* we treat PREPARE as ROLLBACK so far as waking workers goes */
2666 AtEOXact_ApplyLauncher(false);
2667 AtEOXact_LogicalRepWorkers(false);
2668 pgstat_report_xact_timestamp(0);
2670 CurrentResourceOwner = NULL;
2671 ResourceOwnerDelete(TopTransactionResourceOwner);
2672 s->curTransactionOwner = NULL;
2673 CurTransactionResourceOwner = NULL;
2674 TopTransactionResourceOwner = NULL;
2676 AtCommit_Memory();
2678 s->fullTransactionId = InvalidFullTransactionId;
2679 s->subTransactionId = InvalidSubTransactionId;
2680 s->nestingLevel = 0;
2681 s->gucNestLevel = 0;
2682 s->childXids = NULL;
2683 s->nChildXids = 0;
2684 s->maxChildXids = 0;
2686 XactTopFullTransactionId = InvalidFullTransactionId;
2687 nParallelCurrentXids = 0;
2690 * done with 1st phase commit processing, set current transaction state
2691 * back to default
2693 s->state = TRANS_DEFAULT;
2695 RESUME_INTERRUPTS();
2700 * AbortTransaction
2702 static void
2703 AbortTransaction(void)
2705 TransactionState s = CurrentTransactionState;
2706 TransactionId latestXid;
2707 bool is_parallel_worker;
2709 /* Prevent cancel/die interrupt while cleaning up */
2710 HOLD_INTERRUPTS();
2712 /* Make sure we have a valid memory context and resource owner */
2713 AtAbort_Memory();
2714 AtAbort_ResourceOwner();
2717 * Release any LW locks we might be holding as quickly as possible.
2718 * (Regular locks, however, must be held till we finish aborting.)
2719 * Releasing LW locks is critical since we might try to grab them again
2720 * while cleaning up!
2722 LWLockReleaseAll();
2724 /* Clear wait information and command progress indicator */
2725 pgstat_report_wait_end();
2726 pgstat_progress_end_command();
2728 /* Clean up buffer I/O and buffer context locks, too */
2729 AbortBufferIO();
2730 UnlockBuffers();
2732 /* Reset WAL record construction state */
2733 XLogResetInsertion();
2735 /* Cancel condition variable sleep */
2736 ConditionVariableCancelSleep();
2739 * Also clean up any open wait for lock, since the lock manager will choke
2740 * if we try to wait for another lock before doing this.
2742 LockErrorCleanup();
2745 * If any timeout events are still active, make sure the timeout interrupt
2746 * is scheduled. This covers possible loss of a timeout interrupt due to
2747 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2748 * We delay this till after LockErrorCleanup so that we don't uselessly
2749 * reschedule lock or deadlock check timeouts.
2751 reschedule_timeouts();
2754 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2755 * handler. We do this fairly early in the sequence so that the timeout
2756 * infrastructure will be functional if needed while aborting.
2758 PG_SETMASK(&UnBlockSig);
2761 * check the current transaction state
2763 is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2764 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2765 elog(WARNING, "AbortTransaction while in %s state",
2766 TransStateAsString(s->state));
2767 Assert(s->parent == NULL);
2770 * set the current transaction state information appropriately during the
2771 * abort processing
2773 s->state = TRANS_ABORT;
2776 * Reset user ID which might have been changed transiently. We need this
2777 * to clean up in case control escaped out of a SECURITY DEFINER function
2778 * or other local change of CurrentUserId; therefore, the prior value of
2779 * SecurityRestrictionContext also needs to be restored.
2781 * (Note: it is not necessary to restore session authorization or role
2782 * settings here because those can only be changed via GUC, and GUC will
2783 * take care of rolling them back if need be.)
2785 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
2787 /* Forget about any active REINDEX. */
2788 ResetReindexState(s->nestingLevel);
2790 /* Reset logical streaming state. */
2791 ResetLogicalStreamingState();
2793 /* Reset snapshot export state. */
2794 SnapBuildResetExportedSnapshotState();
2796 /* If in parallel mode, clean up workers and exit parallel mode. */
2797 if (IsInParallelMode())
2799 AtEOXact_Parallel(false);
2800 s->parallelModeLevel = 0;
2804 * do abort processing
2806 AfterTriggerEndXact(false); /* 'false' means it's abort */
2807 AtAbort_Portals();
2808 smgrDoPendingSyncs(false, is_parallel_worker);
2809 AtEOXact_LargeObject(false);
2810 AtAbort_Notify();
2811 AtEOXact_RelationMap(false, is_parallel_worker);
2812 AtAbort_Twophase();
2815 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2816 * far as assigning an XID to advertise). But if we're inside a parallel
2817 * worker, skip this; the user backend must be the one to write the abort
2818 * record.
2820 if (!is_parallel_worker)
2821 latestXid = RecordTransactionAbort(false);
2822 else
2824 latestXid = InvalidTransactionId;
2827 * Since the parallel leader won't get our value of XactLastRecEnd in
2828 * this case, we nudge WAL-writer ourselves in this case. See related
2829 * comments in RecordTransactionAbort for why this matters.
2831 XLogSetAsyncXactLSN(XactLastRecEnd);
2834 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
2837 * Let others know about no transaction in progress by me. Note that this
2838 * must be done _before_ releasing locks we hold and _after_
2839 * RecordTransactionAbort.
2841 ProcArrayEndTransaction(MyProc, latestXid);
2844 * Post-abort cleanup. See notes in CommitTransaction() concerning
2845 * ordering. We can skip all of it if the transaction failed before
2846 * creating a resource owner.
2848 if (TopTransactionResourceOwner != NULL)
2850 if (is_parallel_worker)
2851 CallXactCallbacks(XACT_EVENT_PARALLEL_ABORT);
2852 else
2853 CallXactCallbacks(XACT_EVENT_ABORT);
2855 ResourceOwnerRelease(TopTransactionResourceOwner,
2856 RESOURCE_RELEASE_BEFORE_LOCKS,
2857 false, true);
2858 AtEOXact_Buffers(false);
2859 AtEOXact_RelationCache(false);
2860 AtEOXact_Inval(false);
2861 AtEOXact_MultiXact();
2862 ResourceOwnerRelease(TopTransactionResourceOwner,
2863 RESOURCE_RELEASE_LOCKS,
2864 false, true);
2865 ResourceOwnerRelease(TopTransactionResourceOwner,
2866 RESOURCE_RELEASE_AFTER_LOCKS,
2867 false, true);
2868 smgrDoPendingDeletes(false);
2870 AtEOXact_GUC(false, 1);
2871 AtEOXact_SPI(false);
2872 AtEOXact_Enum();
2873 AtEOXact_on_commit_actions(false);
2874 AtEOXact_Namespace(false, is_parallel_worker);
2875 AtEOXact_SMgr();
2876 AtEOXact_Files(false);
2877 AtEOXact_ComboCid();
2878 AtEOXact_HashTables(false);
2879 AtEOXact_PgStat(false, is_parallel_worker);
2880 AtEOXact_ApplyLauncher(false);
2881 AtEOXact_LogicalRepWorkers(false);
2882 pgstat_report_xact_timestamp(0);
2886 * State remains TRANS_ABORT until CleanupTransaction().
2888 RESUME_INTERRUPTS();
2892 * CleanupTransaction
2894 static void
2895 CleanupTransaction(void)
2897 TransactionState s = CurrentTransactionState;
2900 * State should still be TRANS_ABORT from AbortTransaction().
2902 if (s->state != TRANS_ABORT)
2903 elog(FATAL, "CleanupTransaction: unexpected state %s",
2904 TransStateAsString(s->state));
2907 * do abort cleanup processing
2909 AtCleanup_Portals(); /* now safe to release portal memory */
2910 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
2912 CurrentResourceOwner = NULL; /* and resource owner */
2913 if (TopTransactionResourceOwner)
2914 ResourceOwnerDelete(TopTransactionResourceOwner);
2915 s->curTransactionOwner = NULL;
2916 CurTransactionResourceOwner = NULL;
2917 TopTransactionResourceOwner = NULL;
2919 AtCleanup_Memory(); /* and transaction memory */
2921 s->fullTransactionId = InvalidFullTransactionId;
2922 s->subTransactionId = InvalidSubTransactionId;
2923 s->nestingLevel = 0;
2924 s->gucNestLevel = 0;
2925 s->childXids = NULL;
2926 s->nChildXids = 0;
2927 s->maxChildXids = 0;
2928 s->parallelModeLevel = 0;
2930 XactTopFullTransactionId = InvalidFullTransactionId;
2931 nParallelCurrentXids = 0;
2934 * done with abort processing, set current transaction state back to
2935 * default
2937 s->state = TRANS_DEFAULT;
2941 * StartTransactionCommand
2943 void
2944 StartTransactionCommand(void)
2946 TransactionState s = CurrentTransactionState;
2948 switch (s->blockState)
2951 * if we aren't in a transaction block, we just do our usual start
2952 * transaction.
2954 case TBLOCK_DEFAULT:
2955 StartTransaction();
2956 s->blockState = TBLOCK_STARTED;
2957 break;
2960 * We are somewhere in a transaction block or subtransaction and
2961 * about to start a new command. For now we do nothing, but
2962 * someday we may do command-local resource initialization. (Note
2963 * that any needed CommandCounterIncrement was done by the
2964 * previous CommitTransactionCommand.)
2966 case TBLOCK_INPROGRESS:
2967 case TBLOCK_IMPLICIT_INPROGRESS:
2968 case TBLOCK_SUBINPROGRESS:
2969 break;
2972 * Here we are in a failed transaction block (one of the commands
2973 * caused an abort) so we do nothing but remain in the abort
2974 * state. Eventually we will get a ROLLBACK command which will
2975 * get us out of this state. (It is up to other code to ensure
2976 * that no commands other than ROLLBACK will be processed in these
2977 * states.)
2979 case TBLOCK_ABORT:
2980 case TBLOCK_SUBABORT:
2981 break;
2983 /* These cases are invalid. */
2984 case TBLOCK_STARTED:
2985 case TBLOCK_BEGIN:
2986 case TBLOCK_PARALLEL_INPROGRESS:
2987 case TBLOCK_SUBBEGIN:
2988 case TBLOCK_END:
2989 case TBLOCK_SUBRELEASE:
2990 case TBLOCK_SUBCOMMIT:
2991 case TBLOCK_ABORT_END:
2992 case TBLOCK_SUBABORT_END:
2993 case TBLOCK_ABORT_PENDING:
2994 case TBLOCK_SUBABORT_PENDING:
2995 case TBLOCK_SUBRESTART:
2996 case TBLOCK_SUBABORT_RESTART:
2997 case TBLOCK_PREPARE:
2998 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2999 BlockStateAsString(s->blockState));
3000 break;
3004 * We must switch to CurTransactionContext before returning. This is
3005 * already done if we called StartTransaction, otherwise not.
3007 Assert(CurTransactionContext != NULL);
3008 MemoryContextSwitchTo(CurTransactionContext);
3013 * Simple system for saving and restoring transaction characteristics
3014 * (isolation level, read only, deferrable). We need this for transaction
3015 * chaining, so that we can set the characteristics of the new transaction to
3016 * be the same as the previous one. (We need something like this because the
3017 * GUC system resets the characteristics at transaction end, so for example
3018 * just skipping the reset in StartTransaction() won't work.)
3020 void
3021 SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
3023 s->save_XactIsoLevel = XactIsoLevel;
3024 s->save_XactReadOnly = XactReadOnly;
3025 s->save_XactDeferrable = XactDeferrable;
3028 void
3029 RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
3031 XactIsoLevel = s->save_XactIsoLevel;
3032 XactReadOnly = s->save_XactReadOnly;
3033 XactDeferrable = s->save_XactDeferrable;
3038 * CommitTransactionCommand
3040 void
3041 CommitTransactionCommand(void)
3043 TransactionState s = CurrentTransactionState;
3044 SavedTransactionCharacteristics savetc;
3046 SaveTransactionCharacteristics(&savetc);
3048 switch (s->blockState)
3051 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3052 * StartTransactionCommand didn't set the STARTED state
3053 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3054 * by EndParallelWorkerTransaction(), not this function.
3056 case TBLOCK_DEFAULT:
3057 case TBLOCK_PARALLEL_INPROGRESS:
3058 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3059 BlockStateAsString(s->blockState));
3060 break;
3063 * If we aren't in a transaction block, just do our usual
3064 * transaction commit, and return to the idle state.
3066 case TBLOCK_STARTED:
3067 CommitTransaction();
3068 s->blockState = TBLOCK_DEFAULT;
3069 break;
3072 * We are completing a "BEGIN TRANSACTION" command, so we change
3073 * to the "transaction block in progress" state and return. (We
3074 * assume the BEGIN did nothing to the database, so we need no
3075 * CommandCounterIncrement.)
3077 case TBLOCK_BEGIN:
3078 s->blockState = TBLOCK_INPROGRESS;
3079 break;
3082 * This is the case when we have finished executing a command
3083 * someplace within a transaction block. We increment the command
3084 * counter and return.
3086 case TBLOCK_INPROGRESS:
3087 case TBLOCK_IMPLICIT_INPROGRESS:
3088 case TBLOCK_SUBINPROGRESS:
3089 CommandCounterIncrement();
3090 break;
3093 * We are completing a "COMMIT" command. Do it and return to the
3094 * idle state.
3096 case TBLOCK_END:
3097 CommitTransaction();
3098 s->blockState = TBLOCK_DEFAULT;
3099 if (s->chain)
3101 StartTransaction();
3102 s->blockState = TBLOCK_INPROGRESS;
3103 s->chain = false;
3104 RestoreTransactionCharacteristics(&savetc);
3106 break;
3109 * Here we are in the middle of a transaction block but one of the
3110 * commands caused an abort so we do nothing but remain in the
3111 * abort state. Eventually we will get a ROLLBACK command.
3113 case TBLOCK_ABORT:
3114 case TBLOCK_SUBABORT:
3115 break;
3118 * Here we were in an aborted transaction block and we just got
3119 * the ROLLBACK command from the user, so clean up the
3120 * already-aborted transaction and return to the idle state.
3122 case TBLOCK_ABORT_END:
3123 CleanupTransaction();
3124 s->blockState = TBLOCK_DEFAULT;
3125 if (s->chain)
3127 StartTransaction();
3128 s->blockState = TBLOCK_INPROGRESS;
3129 s->chain = false;
3130 RestoreTransactionCharacteristics(&savetc);
3132 break;
3135 * Here we were in a perfectly good transaction block but the user
3136 * told us to ROLLBACK anyway. We have to abort the transaction
3137 * and then clean up.
3139 case TBLOCK_ABORT_PENDING:
3140 AbortTransaction();
3141 CleanupTransaction();
3142 s->blockState = TBLOCK_DEFAULT;
3143 if (s->chain)
3145 StartTransaction();
3146 s->blockState = TBLOCK_INPROGRESS;
3147 s->chain = false;
3148 RestoreTransactionCharacteristics(&savetc);
3150 break;
3153 * We are completing a "PREPARE TRANSACTION" command. Do it and
3154 * return to the idle state.
3156 case TBLOCK_PREPARE:
3157 PrepareTransaction();
3158 s->blockState = TBLOCK_DEFAULT;
3159 break;
3162 * The user issued a SAVEPOINT inside a transaction block.
3163 * Start a subtransaction. (DefineSavepoint already did
3164 * PushTransaction, so as to have someplace to put the SUBBEGIN
3165 * state.)
3167 case TBLOCK_SUBBEGIN:
3168 StartSubTransaction();
3169 s->blockState = TBLOCK_SUBINPROGRESS;
3170 break;
3173 * The user issued a RELEASE command, so we end the current
3174 * subtransaction and return to the parent transaction. The parent
3175 * might be ended too, so repeat till we find an INPROGRESS
3176 * transaction or subtransaction.
3178 case TBLOCK_SUBRELEASE:
3181 CommitSubTransaction();
3182 s = CurrentTransactionState; /* changed by pop */
3183 } while (s->blockState == TBLOCK_SUBRELEASE);
3185 Assert(s->blockState == TBLOCK_INPROGRESS ||
3186 s->blockState == TBLOCK_SUBINPROGRESS);
3187 break;
3190 * The user issued a COMMIT, so we end the current subtransaction
3191 * hierarchy and perform final commit. We do this by rolling up
3192 * any subtransactions into their parent, which leads to O(N^2)
3193 * operations with respect to resource owners - this isn't that
3194 * bad until we approach a thousands of savepoints but is
3195 * necessary for correctness should after triggers create new
3196 * resource owners.
3198 case TBLOCK_SUBCOMMIT:
3201 CommitSubTransaction();
3202 s = CurrentTransactionState; /* changed by pop */
3203 } while (s->blockState == TBLOCK_SUBCOMMIT);
3204 /* If we had a COMMIT command, finish off the main xact too */
3205 if (s->blockState == TBLOCK_END)
3207 Assert(s->parent == NULL);
3208 CommitTransaction();
3209 s->blockState = TBLOCK_DEFAULT;
3210 if (s->chain)
3212 StartTransaction();
3213 s->blockState = TBLOCK_INPROGRESS;
3214 s->chain = false;
3215 RestoreTransactionCharacteristics(&savetc);
3218 else if (s->blockState == TBLOCK_PREPARE)
3220 Assert(s->parent == NULL);
3221 PrepareTransaction();
3222 s->blockState = TBLOCK_DEFAULT;
3224 else
3225 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3226 BlockStateAsString(s->blockState));
3227 break;
3230 * The current already-failed subtransaction is ending due to a
3231 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3232 * examine the parent (which could be in any of several states).
3234 case TBLOCK_SUBABORT_END:
3235 CleanupSubTransaction();
3236 CommitTransactionCommand();
3237 break;
3240 * As above, but it's not dead yet, so abort first.
3242 case TBLOCK_SUBABORT_PENDING:
3243 AbortSubTransaction();
3244 CleanupSubTransaction();
3245 CommitTransactionCommand();
3246 break;
3249 * The current subtransaction is the target of a ROLLBACK TO
3250 * command. Abort and pop it, then start a new subtransaction
3251 * with the same name.
3253 case TBLOCK_SUBRESTART:
3255 char *name;
3256 int savepointLevel;
3258 /* save name and keep Cleanup from freeing it */
3259 name = s->name;
3260 s->name = NULL;
3261 savepointLevel = s->savepointLevel;
3263 AbortSubTransaction();
3264 CleanupSubTransaction();
3266 DefineSavepoint(NULL);
3267 s = CurrentTransactionState; /* changed by push */
3268 s->name = name;
3269 s->savepointLevel = savepointLevel;
3271 /* This is the same as TBLOCK_SUBBEGIN case */
3272 Assert(s->blockState == TBLOCK_SUBBEGIN);
3273 StartSubTransaction();
3274 s->blockState = TBLOCK_SUBINPROGRESS;
3276 break;
3279 * Same as above, but the subtransaction had already failed, so we
3280 * don't need AbortSubTransaction.
3282 case TBLOCK_SUBABORT_RESTART:
3284 char *name;
3285 int savepointLevel;
3287 /* save name and keep Cleanup from freeing it */
3288 name = s->name;
3289 s->name = NULL;
3290 savepointLevel = s->savepointLevel;
3292 CleanupSubTransaction();
3294 DefineSavepoint(NULL);
3295 s = CurrentTransactionState; /* changed by push */
3296 s->name = name;
3297 s->savepointLevel = savepointLevel;
3299 /* This is the same as TBLOCK_SUBBEGIN case */
3300 Assert(s->blockState == TBLOCK_SUBBEGIN);
3301 StartSubTransaction();
3302 s->blockState = TBLOCK_SUBINPROGRESS;
3304 break;
3309 * AbortCurrentTransaction
3311 void
3312 AbortCurrentTransaction(void)
3314 TransactionState s = CurrentTransactionState;
3316 switch (s->blockState)
3318 case TBLOCK_DEFAULT:
3319 if (s->state == TRANS_DEFAULT)
3321 /* we are idle, so nothing to do */
3323 else
3326 * We can get here after an error during transaction start
3327 * (state will be TRANS_START). Need to clean up the
3328 * incompletely started transaction. First, adjust the
3329 * low-level state to suppress warning message from
3330 * AbortTransaction.
3332 if (s->state == TRANS_START)
3333 s->state = TRANS_INPROGRESS;
3334 AbortTransaction();
3335 CleanupTransaction();
3337 break;
3340 * If we aren't in a transaction block, we just do the basic abort
3341 * & cleanup transaction. For this purpose, we treat an implicit
3342 * transaction block as if it were a simple statement.
3344 case TBLOCK_STARTED:
3345 case TBLOCK_IMPLICIT_INPROGRESS:
3346 AbortTransaction();
3347 CleanupTransaction();
3348 s->blockState = TBLOCK_DEFAULT;
3349 break;
3352 * If we are in TBLOCK_BEGIN it means something screwed up right
3353 * after reading "BEGIN TRANSACTION". We assume that the user
3354 * will interpret the error as meaning the BEGIN failed to get him
3355 * into a transaction block, so we should abort and return to idle
3356 * state.
3358 case TBLOCK_BEGIN:
3359 AbortTransaction();
3360 CleanupTransaction();
3361 s->blockState = TBLOCK_DEFAULT;
3362 break;
3365 * We are somewhere in a transaction block and we've gotten a
3366 * failure, so we abort the transaction and set up the persistent
3367 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3369 case TBLOCK_INPROGRESS:
3370 case TBLOCK_PARALLEL_INPROGRESS:
3371 AbortTransaction();
3372 s->blockState = TBLOCK_ABORT;
3373 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3374 break;
3377 * Here, we failed while trying to COMMIT. Clean up the
3378 * transaction and return to idle state (we do not want to stay in
3379 * the transaction).
3381 case TBLOCK_END:
3382 AbortTransaction();
3383 CleanupTransaction();
3384 s->blockState = TBLOCK_DEFAULT;
3385 break;
3388 * Here, we are already in an aborted transaction state and are
3389 * waiting for a ROLLBACK, but for some reason we failed again! So
3390 * we just remain in the abort state.
3392 case TBLOCK_ABORT:
3393 case TBLOCK_SUBABORT:
3394 break;
3397 * We are in a failed transaction and we got the ROLLBACK command.
3398 * We have already aborted, we just need to cleanup and go to idle
3399 * state.
3401 case TBLOCK_ABORT_END:
3402 CleanupTransaction();
3403 s->blockState = TBLOCK_DEFAULT;
3404 break;
3407 * We are in a live transaction and we got a ROLLBACK command.
3408 * Abort, cleanup, go to idle state.
3410 case TBLOCK_ABORT_PENDING:
3411 AbortTransaction();
3412 CleanupTransaction();
3413 s->blockState = TBLOCK_DEFAULT;
3414 break;
3417 * Here, we failed while trying to PREPARE. Clean up the
3418 * transaction and return to idle state (we do not want to stay in
3419 * the transaction).
3421 case TBLOCK_PREPARE:
3422 AbortTransaction();
3423 CleanupTransaction();
3424 s->blockState = TBLOCK_DEFAULT;
3425 break;
3428 * We got an error inside a subtransaction. Abort just the
3429 * subtransaction, and go to the persistent SUBABORT state until
3430 * we get ROLLBACK.
3432 case TBLOCK_SUBINPROGRESS:
3433 AbortSubTransaction();
3434 s->blockState = TBLOCK_SUBABORT;
3435 break;
3438 * If we failed while trying to create a subtransaction, clean up
3439 * the broken subtransaction and abort the parent. The same
3440 * applies if we get a failure while ending a subtransaction.
3442 case TBLOCK_SUBBEGIN:
3443 case TBLOCK_SUBRELEASE:
3444 case TBLOCK_SUBCOMMIT:
3445 case TBLOCK_SUBABORT_PENDING:
3446 case TBLOCK_SUBRESTART:
3447 AbortSubTransaction();
3448 CleanupSubTransaction();
3449 AbortCurrentTransaction();
3450 break;
3453 * Same as above, except the Abort() was already done.
3455 case TBLOCK_SUBABORT_END:
3456 case TBLOCK_SUBABORT_RESTART:
3457 CleanupSubTransaction();
3458 AbortCurrentTransaction();
3459 break;
3464 * PreventInTransactionBlock
3466 * This routine is to be called by statements that must not run inside
3467 * a transaction block, typically because they have non-rollback-able
3468 * side effects or do internal commits.
3470 * If this routine completes successfully, then the calling statement is
3471 * guaranteed that if it completes without error, its results will be
3472 * committed immediately.
3474 * If we have already started a transaction block, issue an error; also issue
3475 * an error if we appear to be running inside a user-defined function (which
3476 * could issue more commands and possibly cause a failure after the statement
3477 * completes). Subtransactions are verboten too.
3479 * We must also set XACT_FLAGS_NEEDIMMEDIATECOMMIT in MyXactFlags, to ensure
3480 * that postgres.c follows through by committing after the statement is done.
3482 * isTopLevel: passed down from ProcessUtility to determine whether we are
3483 * inside a function. (We will always fail if this is false, but it's
3484 * convenient to centralize the check here instead of making callers do it.)
3485 * stmtType: statement type name, for error messages.
3487 void
3488 PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
3491 * xact block already started?
3493 if (IsTransactionBlock())
3494 ereport(ERROR,
3495 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3496 /* translator: %s represents an SQL statement name */
3497 errmsg("%s cannot run inside a transaction block",
3498 stmtType)));
3501 * subtransaction?
3503 if (IsSubTransaction())
3504 ereport(ERROR,
3505 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3506 /* translator: %s represents an SQL statement name */
3507 errmsg("%s cannot run inside a subtransaction",
3508 stmtType)));
3511 * inside a pipeline that has started an implicit transaction?
3513 if (MyXactFlags & XACT_FLAGS_PIPELINING)
3514 ereport(ERROR,
3515 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3516 /* translator: %s represents an SQL statement name */
3517 errmsg("%s cannot be executed within a pipeline",
3518 stmtType)));
3521 * inside a function call?
3523 if (!isTopLevel)
3524 ereport(ERROR,
3525 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3526 /* translator: %s represents an SQL statement name */
3527 errmsg("%s cannot be executed from a function", stmtType)));
3529 /* If we got past IsTransactionBlock test, should be in default state */
3530 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
3531 CurrentTransactionState->blockState != TBLOCK_STARTED)
3532 elog(FATAL, "cannot prevent transaction chain");
3534 /* All okay. Set the flag to make sure the right thing happens later. */
3535 MyXactFlags |= XACT_FLAGS_NEEDIMMEDIATECOMMIT;
3539 * WarnNoTransactionBlock
3540 * RequireTransactionBlock
3542 * These two functions allow for warnings or errors if a command is executed
3543 * outside of a transaction block. This is useful for commands that have no
3544 * effects that persist past transaction end (and so calling them outside a
3545 * transaction block is presumably an error). DECLARE CURSOR is an example.
3546 * While top-level transaction control commands (BEGIN/COMMIT/ABORT) and SET
3547 * that have no effect issue warnings, all other no-effect commands generate
3548 * errors.
3550 * If we appear to be running inside a user-defined function, we do not
3551 * issue anything, since the function could issue more commands that make
3552 * use of the current statement's results. Likewise subtransactions.
3553 * Thus these are inverses for PreventInTransactionBlock.
3555 * isTopLevel: passed down from ProcessUtility to determine whether we are
3556 * inside a function.
3557 * stmtType: statement type name, for warning or error messages.
3559 void
3560 WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
3562 CheckTransactionBlock(isTopLevel, false, stmtType);
3565 void
3566 RequireTransactionBlock(bool isTopLevel, const char *stmtType)
3568 CheckTransactionBlock(isTopLevel, true, stmtType);
3572 * This is the implementation of the above two.
3574 static void
3575 CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
3578 * xact block already started?
3580 if (IsTransactionBlock())
3581 return;
3584 * subtransaction?
3586 if (IsSubTransaction())
3587 return;
3590 * inside a function call?
3592 if (!isTopLevel)
3593 return;
3595 ereport(throwError ? ERROR : WARNING,
3596 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3597 /* translator: %s represents an SQL statement name */
3598 errmsg("%s can only be used in transaction blocks",
3599 stmtType)));
3603 * IsInTransactionBlock
3605 * This routine is for statements that need to behave differently inside
3606 * a transaction block than when running as single commands. ANALYZE is
3607 * currently the only example.
3609 * If this routine returns "false", then the calling statement is allowed
3610 * to perform internal transaction-commit-and-start cycles; there is not a
3611 * risk of messing up any transaction already in progress. (Note that this
3612 * is not the identical guarantee provided by PreventInTransactionBlock,
3613 * since we will not force a post-statement commit.)
3615 * isTopLevel: passed down from ProcessUtility to determine whether we are
3616 * inside a function.
3618 bool
3619 IsInTransactionBlock(bool isTopLevel)
3622 * Return true on same conditions that would make
3623 * PreventInTransactionBlock error out
3625 if (IsTransactionBlock())
3626 return true;
3628 if (IsSubTransaction())
3629 return true;
3631 if (MyXactFlags & XACT_FLAGS_PIPELINING)
3632 return true;
3634 if (!isTopLevel)
3635 return true;
3637 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
3638 CurrentTransactionState->blockState != TBLOCK_STARTED)
3639 return true;
3641 return false;
3646 * Register or deregister callback functions for start- and end-of-xact
3647 * operations.
3649 * These functions are intended for use by dynamically loaded modules.
3650 * For built-in modules we generally just hardwire the appropriate calls
3651 * (mainly because it's easier to control the order that way, where needed).
3653 * At transaction end, the callback occurs post-commit or post-abort, so the
3654 * callback functions can only do noncritical cleanup.
3656 void
3657 RegisterXactCallback(XactCallback callback, void *arg)
3659 XactCallbackItem *item;
3661 item = (XactCallbackItem *)
3662 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
3663 item->callback = callback;
3664 item->arg = arg;
3665 item->next = Xact_callbacks;
3666 Xact_callbacks = item;
3669 void
3670 UnregisterXactCallback(XactCallback callback, void *arg)
3672 XactCallbackItem *item;
3673 XactCallbackItem *prev;
3675 prev = NULL;
3676 for (item = Xact_callbacks; item; prev = item, item = item->next)
3678 if (item->callback == callback && item->arg == arg)
3680 if (prev)
3681 prev->next = item->next;
3682 else
3683 Xact_callbacks = item->next;
3684 pfree(item);
3685 break;
3690 static void
3691 CallXactCallbacks(XactEvent event)
3693 XactCallbackItem *item;
3694 XactCallbackItem *next;
3696 for (item = Xact_callbacks; item; item = next)
3698 /* allow callbacks to unregister themselves when called */
3699 next = item->next;
3700 item->callback(event, item->arg);
3706 * Register or deregister callback functions for start- and end-of-subxact
3707 * operations.
3709 * Pretty much same as above, but for subtransaction events.
3711 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3712 * so the callback functions can only do noncritical cleanup. At
3713 * subtransaction start, the callback is called when the subtransaction has
3714 * finished initializing.
3716 void
3717 RegisterSubXactCallback(SubXactCallback callback, void *arg)
3719 SubXactCallbackItem *item;
3721 item = (SubXactCallbackItem *)
3722 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
3723 item->callback = callback;
3724 item->arg = arg;
3725 item->next = SubXact_callbacks;
3726 SubXact_callbacks = item;
3729 void
3730 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
3732 SubXactCallbackItem *item;
3733 SubXactCallbackItem *prev;
3735 prev = NULL;
3736 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3738 if (item->callback == callback && item->arg == arg)
3740 if (prev)
3741 prev->next = item->next;
3742 else
3743 SubXact_callbacks = item->next;
3744 pfree(item);
3745 break;
3750 static void
3751 CallSubXactCallbacks(SubXactEvent event,
3752 SubTransactionId mySubid,
3753 SubTransactionId parentSubid)
3755 SubXactCallbackItem *item;
3756 SubXactCallbackItem *next;
3758 for (item = SubXact_callbacks; item; item = next)
3760 /* allow callbacks to unregister themselves when called */
3761 next = item->next;
3762 item->callback(event, mySubid, parentSubid, item->arg);
3767 /* ----------------------------------------------------------------
3768 * transaction block support
3769 * ----------------------------------------------------------------
3773 * BeginTransactionBlock
3774 * This executes a BEGIN command.
3776 void
3777 BeginTransactionBlock(void)
3779 TransactionState s = CurrentTransactionState;
3781 switch (s->blockState)
3784 * We are not inside a transaction block, so allow one to begin.
3786 case TBLOCK_STARTED:
3787 s->blockState = TBLOCK_BEGIN;
3788 break;
3791 * BEGIN converts an implicit transaction block to a regular one.
3792 * (Note that we allow this even if we've already done some
3793 * commands, which is a bit odd but matches historical practice.)
3795 case TBLOCK_IMPLICIT_INPROGRESS:
3796 s->blockState = TBLOCK_BEGIN;
3797 break;
3800 * Already a transaction block in progress.
3802 case TBLOCK_INPROGRESS:
3803 case TBLOCK_PARALLEL_INPROGRESS:
3804 case TBLOCK_SUBINPROGRESS:
3805 case TBLOCK_ABORT:
3806 case TBLOCK_SUBABORT:
3807 ereport(WARNING,
3808 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3809 errmsg("there is already a transaction in progress")));
3810 break;
3812 /* These cases are invalid. */
3813 case TBLOCK_DEFAULT:
3814 case TBLOCK_BEGIN:
3815 case TBLOCK_SUBBEGIN:
3816 case TBLOCK_END:
3817 case TBLOCK_SUBRELEASE:
3818 case TBLOCK_SUBCOMMIT:
3819 case TBLOCK_ABORT_END:
3820 case TBLOCK_SUBABORT_END:
3821 case TBLOCK_ABORT_PENDING:
3822 case TBLOCK_SUBABORT_PENDING:
3823 case TBLOCK_SUBRESTART:
3824 case TBLOCK_SUBABORT_RESTART:
3825 case TBLOCK_PREPARE:
3826 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3827 BlockStateAsString(s->blockState));
3828 break;
3833 * PrepareTransactionBlock
3834 * This executes a PREPARE command.
3836 * Since PREPARE may actually do a ROLLBACK, the result indicates what
3837 * happened: true for PREPARE, false for ROLLBACK.
3839 * Note that we don't actually do anything here except change blockState.
3840 * The real work will be done in the upcoming PrepareTransaction().
3841 * We do it this way because it's not convenient to change memory context,
3842 * resource owner, etc while executing inside a Portal.
3844 bool
3845 PrepareTransactionBlock(const char *gid)
3847 TransactionState s;
3848 bool result;
3850 /* Set up to commit the current transaction */
3851 result = EndTransactionBlock(false);
3853 /* If successful, change outer tblock state to PREPARE */
3854 if (result)
3856 s = CurrentTransactionState;
3858 while (s->parent != NULL)
3859 s = s->parent;
3861 if (s->blockState == TBLOCK_END)
3863 /* Save GID where PrepareTransaction can find it again */
3864 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
3866 s->blockState = TBLOCK_PREPARE;
3868 else
3871 * ignore case where we are not in a transaction;
3872 * EndTransactionBlock already issued a warning.
3874 Assert(s->blockState == TBLOCK_STARTED ||
3875 s->blockState == TBLOCK_IMPLICIT_INPROGRESS);
3876 /* Don't send back a PREPARE result tag... */
3877 result = false;
3881 return result;
3885 * EndTransactionBlock
3886 * This executes a COMMIT command.
3888 * Since COMMIT may actually do a ROLLBACK, the result indicates what
3889 * happened: true for COMMIT, false for ROLLBACK.
3891 * Note that we don't actually do anything here except change blockState.
3892 * The real work will be done in the upcoming CommitTransactionCommand().
3893 * We do it this way because it's not convenient to change memory context,
3894 * resource owner, etc while executing inside a Portal.
3896 bool
3897 EndTransactionBlock(bool chain)
3899 TransactionState s = CurrentTransactionState;
3900 bool result = false;
3902 switch (s->blockState)
3905 * We are in a transaction block, so tell CommitTransactionCommand
3906 * to COMMIT.
3908 case TBLOCK_INPROGRESS:
3909 s->blockState = TBLOCK_END;
3910 result = true;
3911 break;
3914 * We are in an implicit transaction block. If AND CHAIN was
3915 * specified, error. Otherwise commit, but issue a warning
3916 * because there was no explicit BEGIN before this.
3918 case TBLOCK_IMPLICIT_INPROGRESS:
3919 if (chain)
3920 ereport(ERROR,
3921 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3922 /* translator: %s represents an SQL statement name */
3923 errmsg("%s can only be used in transaction blocks",
3924 "COMMIT AND CHAIN")));
3925 else
3926 ereport(WARNING,
3927 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3928 errmsg("there is no transaction in progress")));
3929 s->blockState = TBLOCK_END;
3930 result = true;
3931 break;
3934 * We are in a failed transaction block. Tell
3935 * CommitTransactionCommand it's time to exit the block.
3937 case TBLOCK_ABORT:
3938 s->blockState = TBLOCK_ABORT_END;
3939 break;
3942 * We are in a live subtransaction block. Set up to subcommit all
3943 * open subtransactions and then commit the main transaction.
3945 case TBLOCK_SUBINPROGRESS:
3946 while (s->parent != NULL)
3948 if (s->blockState == TBLOCK_SUBINPROGRESS)
3949 s->blockState = TBLOCK_SUBCOMMIT;
3950 else
3951 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3952 BlockStateAsString(s->blockState));
3953 s = s->parent;
3955 if (s->blockState == TBLOCK_INPROGRESS)
3956 s->blockState = TBLOCK_END;
3957 else
3958 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3959 BlockStateAsString(s->blockState));
3960 result = true;
3961 break;
3964 * Here we are inside an aborted subtransaction. Treat the COMMIT
3965 * as ROLLBACK: set up to abort everything and exit the main
3966 * transaction.
3968 case TBLOCK_SUBABORT:
3969 while (s->parent != NULL)
3971 if (s->blockState == TBLOCK_SUBINPROGRESS)
3972 s->blockState = TBLOCK_SUBABORT_PENDING;
3973 else if (s->blockState == TBLOCK_SUBABORT)
3974 s->blockState = TBLOCK_SUBABORT_END;
3975 else
3976 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3977 BlockStateAsString(s->blockState));
3978 s = s->parent;
3980 if (s->blockState == TBLOCK_INPROGRESS)
3981 s->blockState = TBLOCK_ABORT_PENDING;
3982 else if (s->blockState == TBLOCK_ABORT)
3983 s->blockState = TBLOCK_ABORT_END;
3984 else
3985 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3986 BlockStateAsString(s->blockState));
3987 break;
3990 * The user issued COMMIT when not inside a transaction. For
3991 * COMMIT without CHAIN, issue a WARNING, staying in
3992 * TBLOCK_STARTED state. The upcoming call to
3993 * CommitTransactionCommand() will then close the transaction and
3994 * put us back into the default state. For COMMIT AND CHAIN,
3995 * error.
3997 case TBLOCK_STARTED:
3998 if (chain)
3999 ereport(ERROR,
4000 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4001 /* translator: %s represents an SQL statement name */
4002 errmsg("%s can only be used in transaction blocks",
4003 "COMMIT AND CHAIN")));
4004 else
4005 ereport(WARNING,
4006 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4007 errmsg("there is no transaction in progress")));
4008 result = true;
4009 break;
4012 * The user issued a COMMIT that somehow ran inside a parallel
4013 * worker. We can't cope with that.
4015 case TBLOCK_PARALLEL_INPROGRESS:
4016 ereport(FATAL,
4017 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4018 errmsg("cannot commit during a parallel operation")));
4019 break;
4021 /* These cases are invalid. */
4022 case TBLOCK_DEFAULT:
4023 case TBLOCK_BEGIN:
4024 case TBLOCK_SUBBEGIN:
4025 case TBLOCK_END:
4026 case TBLOCK_SUBRELEASE:
4027 case TBLOCK_SUBCOMMIT:
4028 case TBLOCK_ABORT_END:
4029 case TBLOCK_SUBABORT_END:
4030 case TBLOCK_ABORT_PENDING:
4031 case TBLOCK_SUBABORT_PENDING:
4032 case TBLOCK_SUBRESTART:
4033 case TBLOCK_SUBABORT_RESTART:
4034 case TBLOCK_PREPARE:
4035 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4036 BlockStateAsString(s->blockState));
4037 break;
4040 Assert(s->blockState == TBLOCK_STARTED ||
4041 s->blockState == TBLOCK_END ||
4042 s->blockState == TBLOCK_ABORT_END ||
4043 s->blockState == TBLOCK_ABORT_PENDING);
4045 s->chain = chain;
4047 return result;
4051 * UserAbortTransactionBlock
4052 * This executes a ROLLBACK command.
4054 * As above, we don't actually do anything here except change blockState.
4056 void
4057 UserAbortTransactionBlock(bool chain)
4059 TransactionState s = CurrentTransactionState;
4061 switch (s->blockState)
4064 * We are inside a transaction block and we got a ROLLBACK command
4065 * from the user, so tell CommitTransactionCommand to abort and
4066 * exit the transaction block.
4068 case TBLOCK_INPROGRESS:
4069 s->blockState = TBLOCK_ABORT_PENDING;
4070 break;
4073 * We are inside a failed transaction block and we got a ROLLBACK
4074 * command from the user. Abort processing is already done, so
4075 * CommitTransactionCommand just has to cleanup and go back to
4076 * idle state.
4078 case TBLOCK_ABORT:
4079 s->blockState = TBLOCK_ABORT_END;
4080 break;
4083 * We are inside a subtransaction. Mark everything up to top
4084 * level as exitable.
4086 case TBLOCK_SUBINPROGRESS:
4087 case TBLOCK_SUBABORT:
4088 while (s->parent != NULL)
4090 if (s->blockState == TBLOCK_SUBINPROGRESS)
4091 s->blockState = TBLOCK_SUBABORT_PENDING;
4092 else if (s->blockState == TBLOCK_SUBABORT)
4093 s->blockState = TBLOCK_SUBABORT_END;
4094 else
4095 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4096 BlockStateAsString(s->blockState));
4097 s = s->parent;
4099 if (s->blockState == TBLOCK_INPROGRESS)
4100 s->blockState = TBLOCK_ABORT_PENDING;
4101 else if (s->blockState == TBLOCK_ABORT)
4102 s->blockState = TBLOCK_ABORT_END;
4103 else
4104 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4105 BlockStateAsString(s->blockState));
4106 break;
4109 * The user issued ABORT when not inside a transaction. For
4110 * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4111 * The upcoming call to CommitTransactionCommand() will then put
4112 * us back into the default state. For ROLLBACK AND CHAIN, error.
4114 * We do the same thing with ABORT inside an implicit transaction,
4115 * although in this case we might be rolling back actual database
4116 * state changes. (It's debatable whether we should issue a
4117 * WARNING in this case, but we have done so historically.)
4119 case TBLOCK_STARTED:
4120 case TBLOCK_IMPLICIT_INPROGRESS:
4121 if (chain)
4122 ereport(ERROR,
4123 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4124 /* translator: %s represents an SQL statement name */
4125 errmsg("%s can only be used in transaction blocks",
4126 "ROLLBACK AND CHAIN")));
4127 else
4128 ereport(WARNING,
4129 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4130 errmsg("there is no transaction in progress")));
4131 s->blockState = TBLOCK_ABORT_PENDING;
4132 break;
4135 * The user issued an ABORT that somehow ran inside a parallel
4136 * worker. We can't cope with that.
4138 case TBLOCK_PARALLEL_INPROGRESS:
4139 ereport(FATAL,
4140 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4141 errmsg("cannot abort during a parallel operation")));
4142 break;
4144 /* These cases are invalid. */
4145 case TBLOCK_DEFAULT:
4146 case TBLOCK_BEGIN:
4147 case TBLOCK_SUBBEGIN:
4148 case TBLOCK_END:
4149 case TBLOCK_SUBRELEASE:
4150 case TBLOCK_SUBCOMMIT:
4151 case TBLOCK_ABORT_END:
4152 case TBLOCK_SUBABORT_END:
4153 case TBLOCK_ABORT_PENDING:
4154 case TBLOCK_SUBABORT_PENDING:
4155 case TBLOCK_SUBRESTART:
4156 case TBLOCK_SUBABORT_RESTART:
4157 case TBLOCK_PREPARE:
4158 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4159 BlockStateAsString(s->blockState));
4160 break;
4163 Assert(s->blockState == TBLOCK_ABORT_END ||
4164 s->blockState == TBLOCK_ABORT_PENDING);
4166 s->chain = chain;
4170 * BeginImplicitTransactionBlock
4171 * Start an implicit transaction block if we're not already in one.
4173 * Unlike BeginTransactionBlock, this is called directly from the main loop
4174 * in postgres.c, not within a Portal. So we can just change blockState
4175 * without a lot of ceremony. We do not expect caller to do
4176 * CommitTransactionCommand/StartTransactionCommand.
4178 void
4179 BeginImplicitTransactionBlock(void)
4181 TransactionState s = CurrentTransactionState;
4184 * If we are in STARTED state (that is, no transaction block is open),
4185 * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4186 * block.
4188 * For caller convenience, we consider all other transaction states as
4189 * legal here; otherwise the caller would need its own state check, which
4190 * seems rather pointless.
4192 if (s->blockState == TBLOCK_STARTED)
4193 s->blockState = TBLOCK_IMPLICIT_INPROGRESS;
4197 * EndImplicitTransactionBlock
4198 * End an implicit transaction block, if we're in one.
4200 * Like EndTransactionBlock, we just make any needed blockState change here.
4201 * The real work will be done in the upcoming CommitTransactionCommand().
4203 void
4204 EndImplicitTransactionBlock(void)
4206 TransactionState s = CurrentTransactionState;
4209 * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4210 * allowing CommitTransactionCommand to commit whatever happened during
4211 * the implicit transaction block as though it were a single statement.
4213 * For caller convenience, we consider all other transaction states as
4214 * legal here; otherwise the caller would need its own state check, which
4215 * seems rather pointless.
4217 if (s->blockState == TBLOCK_IMPLICIT_INPROGRESS)
4218 s->blockState = TBLOCK_STARTED;
4222 * DefineSavepoint
4223 * This executes a SAVEPOINT command.
4225 void
4226 DefineSavepoint(const char *name)
4228 TransactionState s = CurrentTransactionState;
4231 * Workers synchronize transaction state at the beginning of each parallel
4232 * operation, so we can't account for new subtransactions after that
4233 * point. (Note that this check will certainly error out if s->blockState
4234 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4235 * below.)
4237 if (IsInParallelMode())
4238 ereport(ERROR,
4239 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4240 errmsg("cannot define savepoints during a parallel operation")));
4242 switch (s->blockState)
4244 case TBLOCK_INPROGRESS:
4245 case TBLOCK_SUBINPROGRESS:
4246 /* Normal subtransaction start */
4247 PushTransaction();
4248 s = CurrentTransactionState; /* changed by push */
4251 * Savepoint names, like the TransactionState block itself, live
4252 * in TopTransactionContext.
4254 if (name)
4255 s->name = MemoryContextStrdup(TopTransactionContext, name);
4256 break;
4259 * We disallow savepoint commands in implicit transaction blocks.
4260 * There would be no great difficulty in allowing them so far as
4261 * this module is concerned, but a savepoint seems inconsistent
4262 * with exec_simple_query's behavior of abandoning the whole query
4263 * string upon error. Also, the point of an implicit transaction
4264 * block (as opposed to a regular one) is to automatically close
4265 * after an error, so it's hard to see how a savepoint would fit
4266 * into that.
4268 * The error messages for this are phrased as if there were no
4269 * active transaction block at all, which is historical but
4270 * perhaps could be improved.
4272 case TBLOCK_IMPLICIT_INPROGRESS:
4273 ereport(ERROR,
4274 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4275 /* translator: %s represents an SQL statement name */
4276 errmsg("%s can only be used in transaction blocks",
4277 "SAVEPOINT")));
4278 break;
4280 /* These cases are invalid. */
4281 case TBLOCK_DEFAULT:
4282 case TBLOCK_STARTED:
4283 case TBLOCK_BEGIN:
4284 case TBLOCK_PARALLEL_INPROGRESS:
4285 case TBLOCK_SUBBEGIN:
4286 case TBLOCK_END:
4287 case TBLOCK_SUBRELEASE:
4288 case TBLOCK_SUBCOMMIT:
4289 case TBLOCK_ABORT:
4290 case TBLOCK_SUBABORT:
4291 case TBLOCK_ABORT_END:
4292 case TBLOCK_SUBABORT_END:
4293 case TBLOCK_ABORT_PENDING:
4294 case TBLOCK_SUBABORT_PENDING:
4295 case TBLOCK_SUBRESTART:
4296 case TBLOCK_SUBABORT_RESTART:
4297 case TBLOCK_PREPARE:
4298 elog(FATAL, "DefineSavepoint: unexpected state %s",
4299 BlockStateAsString(s->blockState));
4300 break;
4305 * ReleaseSavepoint
4306 * This executes a RELEASE command.
4308 * As above, we don't actually do anything here except change blockState.
4310 void
4311 ReleaseSavepoint(const char *name)
4313 TransactionState s = CurrentTransactionState;
4314 TransactionState target,
4315 xact;
4318 * Workers synchronize transaction state at the beginning of each parallel
4319 * operation, so we can't account for transaction state change after that
4320 * point. (Note that this check will certainly error out if s->blockState
4321 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4322 * below.)
4324 if (IsInParallelMode())
4325 ereport(ERROR,
4326 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4327 errmsg("cannot release savepoints during a parallel operation")));
4329 switch (s->blockState)
4332 * We can't release a savepoint if there is no savepoint defined.
4334 case TBLOCK_INPROGRESS:
4335 ereport(ERROR,
4336 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4337 errmsg("savepoint \"%s\" does not exist", name)));
4338 break;
4340 case TBLOCK_IMPLICIT_INPROGRESS:
4341 /* See comment about implicit transactions in DefineSavepoint */
4342 ereport(ERROR,
4343 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4344 /* translator: %s represents an SQL statement name */
4345 errmsg("%s can only be used in transaction blocks",
4346 "RELEASE SAVEPOINT")));
4347 break;
4350 * We are in a non-aborted subtransaction. This is the only valid
4351 * case.
4353 case TBLOCK_SUBINPROGRESS:
4354 break;
4356 /* These cases are invalid. */
4357 case TBLOCK_DEFAULT:
4358 case TBLOCK_STARTED:
4359 case TBLOCK_BEGIN:
4360 case TBLOCK_PARALLEL_INPROGRESS:
4361 case TBLOCK_SUBBEGIN:
4362 case TBLOCK_END:
4363 case TBLOCK_SUBRELEASE:
4364 case TBLOCK_SUBCOMMIT:
4365 case TBLOCK_ABORT:
4366 case TBLOCK_SUBABORT:
4367 case TBLOCK_ABORT_END:
4368 case TBLOCK_SUBABORT_END:
4369 case TBLOCK_ABORT_PENDING:
4370 case TBLOCK_SUBABORT_PENDING:
4371 case TBLOCK_SUBRESTART:
4372 case TBLOCK_SUBABORT_RESTART:
4373 case TBLOCK_PREPARE:
4374 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4375 BlockStateAsString(s->blockState));
4376 break;
4379 for (target = s; PointerIsValid(target); target = target->parent)
4381 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4382 break;
4385 if (!PointerIsValid(target))
4386 ereport(ERROR,
4387 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4388 errmsg("savepoint \"%s\" does not exist", name)));
4390 /* disallow crossing savepoint level boundaries */
4391 if (target->savepointLevel != s->savepointLevel)
4392 ereport(ERROR,
4393 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4394 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4397 * Mark "commit pending" all subtransactions up to the target
4398 * subtransaction. The actual commits will happen when control gets to
4399 * CommitTransactionCommand.
4401 xact = CurrentTransactionState;
4402 for (;;)
4404 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
4405 xact->blockState = TBLOCK_SUBRELEASE;
4406 if (xact == target)
4407 break;
4408 xact = xact->parent;
4409 Assert(PointerIsValid(xact));
4414 * RollbackToSavepoint
4415 * This executes a ROLLBACK TO <savepoint> command.
4417 * As above, we don't actually do anything here except change blockState.
4419 void
4420 RollbackToSavepoint(const char *name)
4422 TransactionState s = CurrentTransactionState;
4423 TransactionState target,
4424 xact;
4427 * Workers synchronize transaction state at the beginning of each parallel
4428 * operation, so we can't account for transaction state change after that
4429 * point. (Note that this check will certainly error out if s->blockState
4430 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4431 * below.)
4433 if (IsInParallelMode())
4434 ereport(ERROR,
4435 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4436 errmsg("cannot rollback to savepoints during a parallel operation")));
4438 switch (s->blockState)
4441 * We can't rollback to a savepoint if there is no savepoint
4442 * defined.
4444 case TBLOCK_INPROGRESS:
4445 case TBLOCK_ABORT:
4446 ereport(ERROR,
4447 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4448 errmsg("savepoint \"%s\" does not exist", name)));
4449 break;
4451 case TBLOCK_IMPLICIT_INPROGRESS:
4452 /* See comment about implicit transactions in DefineSavepoint */
4453 ereport(ERROR,
4454 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4455 /* translator: %s represents an SQL statement name */
4456 errmsg("%s can only be used in transaction blocks",
4457 "ROLLBACK TO SAVEPOINT")));
4458 break;
4461 * There is at least one savepoint, so proceed.
4463 case TBLOCK_SUBINPROGRESS:
4464 case TBLOCK_SUBABORT:
4465 break;
4467 /* These cases are invalid. */
4468 case TBLOCK_DEFAULT:
4469 case TBLOCK_STARTED:
4470 case TBLOCK_BEGIN:
4471 case TBLOCK_PARALLEL_INPROGRESS:
4472 case TBLOCK_SUBBEGIN:
4473 case TBLOCK_END:
4474 case TBLOCK_SUBRELEASE:
4475 case TBLOCK_SUBCOMMIT:
4476 case TBLOCK_ABORT_END:
4477 case TBLOCK_SUBABORT_END:
4478 case TBLOCK_ABORT_PENDING:
4479 case TBLOCK_SUBABORT_PENDING:
4480 case TBLOCK_SUBRESTART:
4481 case TBLOCK_SUBABORT_RESTART:
4482 case TBLOCK_PREPARE:
4483 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4484 BlockStateAsString(s->blockState));
4485 break;
4488 for (target = s; PointerIsValid(target); target = target->parent)
4490 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4491 break;
4494 if (!PointerIsValid(target))
4495 ereport(ERROR,
4496 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4497 errmsg("savepoint \"%s\" does not exist", name)));
4499 /* disallow crossing savepoint level boundaries */
4500 if (target->savepointLevel != s->savepointLevel)
4501 ereport(ERROR,
4502 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4503 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4506 * Mark "abort pending" all subtransactions up to the target
4507 * subtransaction. The actual aborts will happen when control gets to
4508 * CommitTransactionCommand.
4510 xact = CurrentTransactionState;
4511 for (;;)
4513 if (xact == target)
4514 break;
4515 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4516 xact->blockState = TBLOCK_SUBABORT_PENDING;
4517 else if (xact->blockState == TBLOCK_SUBABORT)
4518 xact->blockState = TBLOCK_SUBABORT_END;
4519 else
4520 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4521 BlockStateAsString(xact->blockState));
4522 xact = xact->parent;
4523 Assert(PointerIsValid(xact));
4526 /* And mark the target as "restart pending" */
4527 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4528 xact->blockState = TBLOCK_SUBRESTART;
4529 else if (xact->blockState == TBLOCK_SUBABORT)
4530 xact->blockState = TBLOCK_SUBABORT_RESTART;
4531 else
4532 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4533 BlockStateAsString(xact->blockState));
4537 * BeginInternalSubTransaction
4538 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
4539 * TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_END, and TBLOCK_PREPARE states,
4540 * and therefore it can safely be used in functions that might be called
4541 * when not inside a BEGIN block or when running deferred triggers at
4542 * COMMIT/PREPARE time. Also, it automatically does
4543 * CommitTransactionCommand/StartTransactionCommand instead of expecting
4544 * the caller to do it.
4546 void
4547 BeginInternalSubTransaction(const char *name)
4549 TransactionState s = CurrentTransactionState;
4552 * Workers synchronize transaction state at the beginning of each parallel
4553 * operation, so we can't account for new subtransactions after that
4554 * point. We might be able to make an exception for the type of
4555 * subtransaction established by this function, which is typically used in
4556 * contexts where we're going to release or roll back the subtransaction
4557 * before proceeding further, so that no enduring change to the
4558 * transaction state occurs. For now, however, we prohibit this case along
4559 * with all the others.
4561 if (IsInParallelMode())
4562 ereport(ERROR,
4563 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4564 errmsg("cannot start subtransactions during a parallel operation")));
4566 switch (s->blockState)
4568 case TBLOCK_STARTED:
4569 case TBLOCK_INPROGRESS:
4570 case TBLOCK_IMPLICIT_INPROGRESS:
4571 case TBLOCK_END:
4572 case TBLOCK_PREPARE:
4573 case TBLOCK_SUBINPROGRESS:
4574 /* Normal subtransaction start */
4575 PushTransaction();
4576 s = CurrentTransactionState; /* changed by push */
4579 * Savepoint names, like the TransactionState block itself, live
4580 * in TopTransactionContext.
4582 if (name)
4583 s->name = MemoryContextStrdup(TopTransactionContext, name);
4584 break;
4586 /* These cases are invalid. */
4587 case TBLOCK_DEFAULT:
4588 case TBLOCK_BEGIN:
4589 case TBLOCK_PARALLEL_INPROGRESS:
4590 case TBLOCK_SUBBEGIN:
4591 case TBLOCK_SUBRELEASE:
4592 case TBLOCK_SUBCOMMIT:
4593 case TBLOCK_ABORT:
4594 case TBLOCK_SUBABORT:
4595 case TBLOCK_ABORT_END:
4596 case TBLOCK_SUBABORT_END:
4597 case TBLOCK_ABORT_PENDING:
4598 case TBLOCK_SUBABORT_PENDING:
4599 case TBLOCK_SUBRESTART:
4600 case TBLOCK_SUBABORT_RESTART:
4601 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4602 BlockStateAsString(s->blockState));
4603 break;
4606 CommitTransactionCommand();
4607 StartTransactionCommand();
4611 * ReleaseCurrentSubTransaction
4613 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
4614 * savepoint name (if any).
4615 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4617 void
4618 ReleaseCurrentSubTransaction(void)
4620 TransactionState s = CurrentTransactionState;
4623 * Workers synchronize transaction state at the beginning of each parallel
4624 * operation, so we can't account for commit of subtransactions after that
4625 * point. This should not happen anyway. Code calling this would
4626 * typically have called BeginInternalSubTransaction() first, failing
4627 * there.
4629 if (IsInParallelMode())
4630 ereport(ERROR,
4631 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4632 errmsg("cannot commit subtransactions during a parallel operation")));
4634 if (s->blockState != TBLOCK_SUBINPROGRESS)
4635 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4636 BlockStateAsString(s->blockState));
4637 Assert(s->state == TRANS_INPROGRESS);
4638 MemoryContextSwitchTo(CurTransactionContext);
4639 CommitSubTransaction();
4640 s = CurrentTransactionState; /* changed by pop */
4641 Assert(s->state == TRANS_INPROGRESS);
4645 * RollbackAndReleaseCurrentSubTransaction
4647 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
4648 * of its savepoint name (if any).
4649 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4651 void
4652 RollbackAndReleaseCurrentSubTransaction(void)
4654 TransactionState s = CurrentTransactionState;
4657 * Unlike ReleaseCurrentSubTransaction(), this is nominally permitted
4658 * during parallel operations. That's because we may be in the leader,
4659 * recovering from an error thrown while we were in parallel mode. We
4660 * won't reach here in a worker, because BeginInternalSubTransaction()
4661 * will have failed.
4664 switch (s->blockState)
4666 /* Must be in a subtransaction */
4667 case TBLOCK_SUBINPROGRESS:
4668 case TBLOCK_SUBABORT:
4669 break;
4671 /* These cases are invalid. */
4672 case TBLOCK_DEFAULT:
4673 case TBLOCK_STARTED:
4674 case TBLOCK_BEGIN:
4675 case TBLOCK_IMPLICIT_INPROGRESS:
4676 case TBLOCK_PARALLEL_INPROGRESS:
4677 case TBLOCK_SUBBEGIN:
4678 case TBLOCK_INPROGRESS:
4679 case TBLOCK_END:
4680 case TBLOCK_SUBRELEASE:
4681 case TBLOCK_SUBCOMMIT:
4682 case TBLOCK_ABORT:
4683 case TBLOCK_ABORT_END:
4684 case TBLOCK_SUBABORT_END:
4685 case TBLOCK_ABORT_PENDING:
4686 case TBLOCK_SUBABORT_PENDING:
4687 case TBLOCK_SUBRESTART:
4688 case TBLOCK_SUBABORT_RESTART:
4689 case TBLOCK_PREPARE:
4690 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4691 BlockStateAsString(s->blockState));
4692 break;
4696 * Abort the current subtransaction, if needed.
4698 if (s->blockState == TBLOCK_SUBINPROGRESS)
4699 AbortSubTransaction();
4701 /* And clean it up, too */
4702 CleanupSubTransaction();
4704 s = CurrentTransactionState; /* changed by pop */
4705 Assert(s->blockState == TBLOCK_SUBINPROGRESS ||
4706 s->blockState == TBLOCK_INPROGRESS ||
4707 s->blockState == TBLOCK_IMPLICIT_INPROGRESS ||
4708 s->blockState == TBLOCK_STARTED);
4712 * AbortOutOfAnyTransaction
4714 * This routine is provided for error recovery purposes. It aborts any
4715 * active transaction or transaction block, leaving the system in a known
4716 * idle state.
4718 void
4719 AbortOutOfAnyTransaction(void)
4721 TransactionState s = CurrentTransactionState;
4723 /* Ensure we're not running in a doomed memory context */
4724 AtAbort_Memory();
4727 * Get out of any transaction or nested transaction
4731 switch (s->blockState)
4733 case TBLOCK_DEFAULT:
4734 if (s->state == TRANS_DEFAULT)
4736 /* Not in a transaction, do nothing */
4738 else
4741 * We can get here after an error during transaction start
4742 * (state will be TRANS_START). Need to clean up the
4743 * incompletely started transaction. First, adjust the
4744 * low-level state to suppress warning message from
4745 * AbortTransaction.
4747 if (s->state == TRANS_START)
4748 s->state = TRANS_INPROGRESS;
4749 AbortTransaction();
4750 CleanupTransaction();
4752 break;
4753 case TBLOCK_STARTED:
4754 case TBLOCK_BEGIN:
4755 case TBLOCK_INPROGRESS:
4756 case TBLOCK_IMPLICIT_INPROGRESS:
4757 case TBLOCK_PARALLEL_INPROGRESS:
4758 case TBLOCK_END:
4759 case TBLOCK_ABORT_PENDING:
4760 case TBLOCK_PREPARE:
4761 /* In a transaction, so clean up */
4762 AbortTransaction();
4763 CleanupTransaction();
4764 s->blockState = TBLOCK_DEFAULT;
4765 break;
4766 case TBLOCK_ABORT:
4767 case TBLOCK_ABORT_END:
4770 * AbortTransaction is already done, still need Cleanup.
4771 * However, if we failed partway through running ROLLBACK,
4772 * there will be an active portal running that command, which
4773 * we need to shut down before doing CleanupTransaction.
4775 AtAbort_Portals();
4776 CleanupTransaction();
4777 s->blockState = TBLOCK_DEFAULT;
4778 break;
4781 * In a subtransaction, so clean it up and abort parent too
4783 case TBLOCK_SUBBEGIN:
4784 case TBLOCK_SUBINPROGRESS:
4785 case TBLOCK_SUBRELEASE:
4786 case TBLOCK_SUBCOMMIT:
4787 case TBLOCK_SUBABORT_PENDING:
4788 case TBLOCK_SUBRESTART:
4789 AbortSubTransaction();
4790 CleanupSubTransaction();
4791 s = CurrentTransactionState; /* changed by pop */
4792 break;
4794 case TBLOCK_SUBABORT:
4795 case TBLOCK_SUBABORT_END:
4796 case TBLOCK_SUBABORT_RESTART:
4797 /* As above, but AbortSubTransaction already done */
4798 if (s->curTransactionOwner)
4800 /* As in TBLOCK_ABORT, might have a live portal to zap */
4801 AtSubAbort_Portals(s->subTransactionId,
4802 s->parent->subTransactionId,
4803 s->curTransactionOwner,
4804 s->parent->curTransactionOwner);
4806 CleanupSubTransaction();
4807 s = CurrentTransactionState; /* changed by pop */
4808 break;
4810 } while (s->blockState != TBLOCK_DEFAULT);
4812 /* Should be out of all subxacts now */
4813 Assert(s->parent == NULL);
4815 /* If we didn't actually have anything to do, revert to TopMemoryContext */
4816 AtCleanup_Memory();
4820 * IsTransactionBlock --- are we within a transaction block?
4822 bool
4823 IsTransactionBlock(void)
4825 TransactionState s = CurrentTransactionState;
4827 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
4828 return false;
4830 return true;
4834 * IsTransactionOrTransactionBlock --- are we within either a transaction
4835 * or a transaction block? (The backend is only really "idle" when this
4836 * returns false.)
4838 * This should match up with IsTransactionBlock and IsTransactionState.
4840 bool
4841 IsTransactionOrTransactionBlock(void)
4843 TransactionState s = CurrentTransactionState;
4845 if (s->blockState == TBLOCK_DEFAULT)
4846 return false;
4848 return true;
4852 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
4854 char
4855 TransactionBlockStatusCode(void)
4857 TransactionState s = CurrentTransactionState;
4859 switch (s->blockState)
4861 case TBLOCK_DEFAULT:
4862 case TBLOCK_STARTED:
4863 return 'I'; /* idle --- not in transaction */
4864 case TBLOCK_BEGIN:
4865 case TBLOCK_SUBBEGIN:
4866 case TBLOCK_INPROGRESS:
4867 case TBLOCK_IMPLICIT_INPROGRESS:
4868 case TBLOCK_PARALLEL_INPROGRESS:
4869 case TBLOCK_SUBINPROGRESS:
4870 case TBLOCK_END:
4871 case TBLOCK_SUBRELEASE:
4872 case TBLOCK_SUBCOMMIT:
4873 case TBLOCK_PREPARE:
4874 return 'T'; /* in transaction */
4875 case TBLOCK_ABORT:
4876 case TBLOCK_SUBABORT:
4877 case TBLOCK_ABORT_END:
4878 case TBLOCK_SUBABORT_END:
4879 case TBLOCK_ABORT_PENDING:
4880 case TBLOCK_SUBABORT_PENDING:
4881 case TBLOCK_SUBRESTART:
4882 case TBLOCK_SUBABORT_RESTART:
4883 return 'E'; /* in failed transaction */
4886 /* should never get here */
4887 elog(FATAL, "invalid transaction block state: %s",
4888 BlockStateAsString(s->blockState));
4889 return 0; /* keep compiler quiet */
4893 * IsSubTransaction
4895 bool
4896 IsSubTransaction(void)
4898 TransactionState s = CurrentTransactionState;
4900 if (s->nestingLevel >= 2)
4901 return true;
4903 return false;
4907 * StartSubTransaction
4909 * If you're wondering why this is separate from PushTransaction: it's because
4910 * we can't conveniently do this stuff right inside DefineSavepoint. The
4911 * SAVEPOINT utility command will be executed inside a Portal, and if we
4912 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
4913 * the Portal will undo those settings. So we make DefineSavepoint just
4914 * push a dummy transaction block, and when control returns to the main
4915 * idle loop, CommitTransactionCommand will be called, and we'll come here
4916 * to finish starting the subtransaction.
4918 static void
4919 StartSubTransaction(void)
4921 TransactionState s = CurrentTransactionState;
4923 if (s->state != TRANS_DEFAULT)
4924 elog(WARNING, "StartSubTransaction while in %s state",
4925 TransStateAsString(s->state));
4927 s->state = TRANS_START;
4930 * Initialize subsystems for new subtransaction
4932 * must initialize resource-management stuff first
4934 AtSubStart_Memory();
4935 AtSubStart_ResourceOwner();
4936 AfterTriggerBeginSubXact();
4938 s->state = TRANS_INPROGRESS;
4941 * Call start-of-subxact callbacks
4943 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
4944 s->parent->subTransactionId);
4946 ShowTransactionState("StartSubTransaction");
4950 * CommitSubTransaction
4952 * The caller has to make sure to always reassign CurrentTransactionState
4953 * if it has a local pointer to it after calling this function.
4955 static void
4956 CommitSubTransaction(void)
4958 TransactionState s = CurrentTransactionState;
4960 ShowTransactionState("CommitSubTransaction");
4962 if (s->state != TRANS_INPROGRESS)
4963 elog(WARNING, "CommitSubTransaction while in %s state",
4964 TransStateAsString(s->state));
4966 /* Pre-commit processing goes here */
4968 CallSubXactCallbacks(SUBXACT_EVENT_PRE_COMMIT_SUB, s->subTransactionId,
4969 s->parent->subTransactionId);
4971 /* If in parallel mode, clean up workers and exit parallel mode. */
4972 if (IsInParallelMode())
4974 AtEOSubXact_Parallel(true, s->subTransactionId);
4975 s->parallelModeLevel = 0;
4978 /* Do the actual "commit", such as it is */
4979 s->state = TRANS_COMMIT;
4981 /* Must CCI to ensure commands of subtransaction are seen as done */
4982 CommandCounterIncrement();
4985 * Prior to 8.4 we marked subcommit in clog at this point. We now only
4986 * perform that step, if required, as part of the atomic update of the
4987 * whole transaction tree at top level commit or abort.
4990 /* Post-commit cleanup */
4991 if (FullTransactionIdIsValid(s->fullTransactionId))
4992 AtSubCommit_childXids();
4993 AfterTriggerEndSubXact(true);
4994 AtSubCommit_Portals(s->subTransactionId,
4995 s->parent->subTransactionId,
4996 s->parent->nestingLevel,
4997 s->parent->curTransactionOwner);
4998 AtEOSubXact_LargeObject(true, s->subTransactionId,
4999 s->parent->subTransactionId);
5000 AtSubCommit_Notify();
5002 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
5003 s->parent->subTransactionId);
5005 ResourceOwnerRelease(s->curTransactionOwner,
5006 RESOURCE_RELEASE_BEFORE_LOCKS,
5007 true, false);
5008 AtEOSubXact_RelationCache(true, s->subTransactionId,
5009 s->parent->subTransactionId);
5010 AtEOSubXact_Inval(true);
5011 AtSubCommit_smgr();
5014 * The only lock we actually release here is the subtransaction XID lock.
5016 CurrentResourceOwner = s->curTransactionOwner;
5017 if (FullTransactionIdIsValid(s->fullTransactionId))
5018 XactLockTableDelete(XidFromFullTransactionId(s->fullTransactionId));
5021 * Other locks should get transferred to their parent resource owner.
5023 ResourceOwnerRelease(s->curTransactionOwner,
5024 RESOURCE_RELEASE_LOCKS,
5025 true, false);
5026 ResourceOwnerRelease(s->curTransactionOwner,
5027 RESOURCE_RELEASE_AFTER_LOCKS,
5028 true, false);
5030 AtEOXact_GUC(true, s->gucNestLevel);
5031 AtEOSubXact_SPI(true, s->subTransactionId);
5032 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
5033 s->parent->subTransactionId);
5034 AtEOSubXact_Namespace(true, s->subTransactionId,
5035 s->parent->subTransactionId);
5036 AtEOSubXact_Files(true, s->subTransactionId,
5037 s->parent->subTransactionId);
5038 AtEOSubXact_HashTables(true, s->nestingLevel);
5039 AtEOSubXact_PgStat(true, s->nestingLevel);
5040 AtSubCommit_Snapshot(s->nestingLevel);
5043 * We need to restore the upper transaction's read-only state, in case the
5044 * upper is read-write while the child is read-only; GUC will incorrectly
5045 * think it should leave the child state in place.
5047 XactReadOnly = s->prevXactReadOnly;
5049 CurrentResourceOwner = s->parent->curTransactionOwner;
5050 CurTransactionResourceOwner = s->parent->curTransactionOwner;
5051 ResourceOwnerDelete(s->curTransactionOwner);
5052 s->curTransactionOwner = NULL;
5054 AtSubCommit_Memory();
5056 s->state = TRANS_DEFAULT;
5058 PopTransaction();
5062 * AbortSubTransaction
5064 static void
5065 AbortSubTransaction(void)
5067 TransactionState s = CurrentTransactionState;
5069 /* Prevent cancel/die interrupt while cleaning up */
5070 HOLD_INTERRUPTS();
5072 /* Make sure we have a valid memory context and resource owner */
5073 AtSubAbort_Memory();
5074 AtSubAbort_ResourceOwner();
5077 * Release any LW locks we might be holding as quickly as possible.
5078 * (Regular locks, however, must be held till we finish aborting.)
5079 * Releasing LW locks is critical since we might try to grab them again
5080 * while cleaning up!
5082 * FIXME This may be incorrect --- Are there some locks we should keep?
5083 * Buffer locks, for example? I don't think so but I'm not sure.
5085 LWLockReleaseAll();
5087 pgstat_report_wait_end();
5088 pgstat_progress_end_command();
5089 AbortBufferIO();
5090 UnlockBuffers();
5092 /* Reset WAL record construction state */
5093 XLogResetInsertion();
5095 /* Cancel condition variable sleep */
5096 ConditionVariableCancelSleep();
5099 * Also clean up any open wait for lock, since the lock manager will choke
5100 * if we try to wait for another lock before doing this.
5102 LockErrorCleanup();
5105 * If any timeout events are still active, make sure the timeout interrupt
5106 * is scheduled. This covers possible loss of a timeout interrupt due to
5107 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5108 * We delay this till after LockErrorCleanup so that we don't uselessly
5109 * reschedule lock or deadlock check timeouts.
5111 reschedule_timeouts();
5114 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5115 * handler. We do this fairly early in the sequence so that the timeout
5116 * infrastructure will be functional if needed while aborting.
5118 PG_SETMASK(&UnBlockSig);
5121 * check the current transaction state
5123 ShowTransactionState("AbortSubTransaction");
5125 if (s->state != TRANS_INPROGRESS)
5126 elog(WARNING, "AbortSubTransaction while in %s state",
5127 TransStateAsString(s->state));
5129 s->state = TRANS_ABORT;
5132 * Reset user ID which might have been changed transiently. (See notes in
5133 * AbortTransaction.)
5135 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
5137 /* Forget about any active REINDEX. */
5138 ResetReindexState(s->nestingLevel);
5140 /* Reset logical streaming state. */
5141 ResetLogicalStreamingState();
5144 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5145 * exports are not supported in subtransactions.
5148 /* Exit from parallel mode, if necessary. */
5149 if (IsInParallelMode())
5151 AtEOSubXact_Parallel(false, s->subTransactionId);
5152 s->parallelModeLevel = 0;
5156 * We can skip all this stuff if the subxact failed before creating a
5157 * ResourceOwner...
5159 if (s->curTransactionOwner)
5161 AfterTriggerEndSubXact(false);
5162 AtSubAbort_Portals(s->subTransactionId,
5163 s->parent->subTransactionId,
5164 s->curTransactionOwner,
5165 s->parent->curTransactionOwner);
5166 AtEOSubXact_LargeObject(false, s->subTransactionId,
5167 s->parent->subTransactionId);
5168 AtSubAbort_Notify();
5170 /* Advertise the fact that we aborted in pg_xact. */
5171 (void) RecordTransactionAbort(true);
5173 /* Post-abort cleanup */
5174 if (FullTransactionIdIsValid(s->fullTransactionId))
5175 AtSubAbort_childXids();
5177 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
5178 s->parent->subTransactionId);
5180 ResourceOwnerRelease(s->curTransactionOwner,
5181 RESOURCE_RELEASE_BEFORE_LOCKS,
5182 false, false);
5183 AtEOSubXact_RelationCache(false, s->subTransactionId,
5184 s->parent->subTransactionId);
5185 AtEOSubXact_Inval(false);
5186 ResourceOwnerRelease(s->curTransactionOwner,
5187 RESOURCE_RELEASE_LOCKS,
5188 false, false);
5189 ResourceOwnerRelease(s->curTransactionOwner,
5190 RESOURCE_RELEASE_AFTER_LOCKS,
5191 false, false);
5192 AtSubAbort_smgr();
5194 AtEOXact_GUC(false, s->gucNestLevel);
5195 AtEOSubXact_SPI(false, s->subTransactionId);
5196 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
5197 s->parent->subTransactionId);
5198 AtEOSubXact_Namespace(false, s->subTransactionId,
5199 s->parent->subTransactionId);
5200 AtEOSubXact_Files(false, s->subTransactionId,
5201 s->parent->subTransactionId);
5202 AtEOSubXact_HashTables(false, s->nestingLevel);
5203 AtEOSubXact_PgStat(false, s->nestingLevel);
5204 AtSubAbort_Snapshot(s->nestingLevel);
5208 * Restore the upper transaction's read-only state, too. This should be
5209 * redundant with GUC's cleanup but we may as well do it for consistency
5210 * with the commit case.
5212 XactReadOnly = s->prevXactReadOnly;
5214 RESUME_INTERRUPTS();
5218 * CleanupSubTransaction
5220 * The caller has to make sure to always reassign CurrentTransactionState
5221 * if it has a local pointer to it after calling this function.
5223 static void
5224 CleanupSubTransaction(void)
5226 TransactionState s = CurrentTransactionState;
5228 ShowTransactionState("CleanupSubTransaction");
5230 if (s->state != TRANS_ABORT)
5231 elog(WARNING, "CleanupSubTransaction while in %s state",
5232 TransStateAsString(s->state));
5234 AtSubCleanup_Portals(s->subTransactionId);
5236 CurrentResourceOwner = s->parent->curTransactionOwner;
5237 CurTransactionResourceOwner = s->parent->curTransactionOwner;
5238 if (s->curTransactionOwner)
5239 ResourceOwnerDelete(s->curTransactionOwner);
5240 s->curTransactionOwner = NULL;
5242 AtSubCleanup_Memory();
5244 s->state = TRANS_DEFAULT;
5246 PopTransaction();
5250 * PushTransaction
5251 * Create transaction state stack entry for a subtransaction
5253 * The caller has to make sure to always reassign CurrentTransactionState
5254 * if it has a local pointer to it after calling this function.
5256 static void
5257 PushTransaction(void)
5259 TransactionState p = CurrentTransactionState;
5260 TransactionState s;
5263 * We keep subtransaction state nodes in TopTransactionContext.
5265 s = (TransactionState)
5266 MemoryContextAllocZero(TopTransactionContext,
5267 sizeof(TransactionStateData));
5270 * Assign a subtransaction ID, watching out for counter wraparound.
5272 currentSubTransactionId += 1;
5273 if (currentSubTransactionId == InvalidSubTransactionId)
5275 currentSubTransactionId -= 1;
5276 pfree(s);
5277 ereport(ERROR,
5278 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5279 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5283 * We can now stack a minimally valid subtransaction without fear of
5284 * failure.
5286 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5287 s->subTransactionId = currentSubTransactionId;
5288 s->parent = p;
5289 s->nestingLevel = p->nestingLevel + 1;
5290 s->gucNestLevel = NewGUCNestLevel();
5291 s->savepointLevel = p->savepointLevel;
5292 s->state = TRANS_DEFAULT;
5293 s->blockState = TBLOCK_SUBBEGIN;
5294 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
5295 s->prevXactReadOnly = XactReadOnly;
5296 s->parallelModeLevel = 0;
5297 s->topXidLogged = false;
5299 CurrentTransactionState = s;
5302 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5303 * with the subtransaction from here on out; in particular they should not
5304 * assume that it necessarily has a transaction context, resource owner,
5305 * or XID.
5310 * PopTransaction
5311 * Pop back to parent transaction state
5313 * The caller has to make sure to always reassign CurrentTransactionState
5314 * if it has a local pointer to it after calling this function.
5316 static void
5317 PopTransaction(void)
5319 TransactionState s = CurrentTransactionState;
5321 if (s->state != TRANS_DEFAULT)
5322 elog(WARNING, "PopTransaction while in %s state",
5323 TransStateAsString(s->state));
5325 if (s->parent == NULL)
5326 elog(FATAL, "PopTransaction with no parent");
5328 CurrentTransactionState = s->parent;
5330 /* Let's just make sure CurTransactionContext is good */
5331 CurTransactionContext = s->parent->curTransactionContext;
5332 MemoryContextSwitchTo(CurTransactionContext);
5334 /* Ditto for ResourceOwner links */
5335 CurTransactionResourceOwner = s->parent->curTransactionOwner;
5336 CurrentResourceOwner = s->parent->curTransactionOwner;
5338 /* Free the old child structure */
5339 if (s->name)
5340 pfree(s->name);
5341 pfree(s);
5345 * EstimateTransactionStateSpace
5346 * Estimate the amount of space that will be needed by
5347 * SerializeTransactionState. It would be OK to overestimate slightly,
5348 * but it's simple for us to work out the precise value, so we do.
5350 Size
5351 EstimateTransactionStateSpace(void)
5353 TransactionState s;
5354 Size nxids = 0;
5355 Size size = SerializedTransactionStateHeaderSize;
5357 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5359 if (FullTransactionIdIsValid(s->fullTransactionId))
5360 nxids = add_size(nxids, 1);
5361 nxids = add_size(nxids, s->nChildXids);
5364 return add_size(size, mul_size(sizeof(TransactionId), nxids));
5368 * SerializeTransactionState
5369 * Write out relevant details of our transaction state that will be
5370 * needed by a parallel worker.
5372 * We need to save and restore XactDeferrable, XactIsoLevel, and the XIDs
5373 * associated with this transaction. These are serialized into a
5374 * caller-supplied buffer big enough to hold the number of bytes reported by
5375 * EstimateTransactionStateSpace(). We emit the XIDs in sorted order for the
5376 * convenience of the receiving process.
5378 void
5379 SerializeTransactionState(Size maxsize, char *start_address)
5381 TransactionState s;
5382 Size nxids = 0;
5383 Size i = 0;
5384 TransactionId *workspace;
5385 SerializedTransactionState *result;
5387 result = (SerializedTransactionState *) start_address;
5389 result->xactIsoLevel = XactIsoLevel;
5390 result->xactDeferrable = XactDeferrable;
5391 result->topFullTransactionId = XactTopFullTransactionId;
5392 result->currentFullTransactionId =
5393 CurrentTransactionState->fullTransactionId;
5394 result->currentCommandId = currentCommandId;
5397 * If we're running in a parallel worker and launching a parallel worker
5398 * of our own, we can just pass along the information that was passed to
5399 * us.
5401 if (nParallelCurrentXids > 0)
5403 result->nParallelCurrentXids = nParallelCurrentXids;
5404 memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
5405 nParallelCurrentXids * sizeof(TransactionId));
5406 return;
5410 * OK, we need to generate a sorted list of XIDs that our workers should
5411 * view as current. First, figure out how many there are.
5413 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5415 if (FullTransactionIdIsValid(s->fullTransactionId))
5416 nxids = add_size(nxids, 1);
5417 nxids = add_size(nxids, s->nChildXids);
5419 Assert(SerializedTransactionStateHeaderSize + nxids * sizeof(TransactionId)
5420 <= maxsize);
5422 /* Copy them to our scratch space. */
5423 workspace = palloc(nxids * sizeof(TransactionId));
5424 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5426 if (FullTransactionIdIsValid(s->fullTransactionId))
5427 workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5428 if (s->nChildXids > 0)
5429 memcpy(&workspace[i], s->childXids,
5430 s->nChildXids * sizeof(TransactionId));
5431 i += s->nChildXids;
5433 Assert(i == nxids);
5435 /* Sort them. */
5436 qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5438 /* Copy data into output area. */
5439 result->nParallelCurrentXids = nxids;
5440 memcpy(&result->parallelCurrentXids[0], workspace,
5441 nxids * sizeof(TransactionId));
5445 * StartParallelWorkerTransaction
5446 * Start a parallel worker transaction, restoring the relevant
5447 * transaction state serialized by SerializeTransactionState.
5449 void
5450 StartParallelWorkerTransaction(char *tstatespace)
5452 SerializedTransactionState *tstate;
5454 Assert(CurrentTransactionState->blockState == TBLOCK_DEFAULT);
5455 StartTransaction();
5457 tstate = (SerializedTransactionState *) tstatespace;
5458 XactIsoLevel = tstate->xactIsoLevel;
5459 XactDeferrable = tstate->xactDeferrable;
5460 XactTopFullTransactionId = tstate->topFullTransactionId;
5461 CurrentTransactionState->fullTransactionId =
5462 tstate->currentFullTransactionId;
5463 currentCommandId = tstate->currentCommandId;
5464 nParallelCurrentXids = tstate->nParallelCurrentXids;
5465 ParallelCurrentXids = &tstate->parallelCurrentXids[0];
5467 CurrentTransactionState->blockState = TBLOCK_PARALLEL_INPROGRESS;
5471 * EndParallelWorkerTransaction
5472 * End a parallel worker transaction.
5474 void
5475 EndParallelWorkerTransaction(void)
5477 Assert(CurrentTransactionState->blockState == TBLOCK_PARALLEL_INPROGRESS);
5478 CommitTransaction();
5479 CurrentTransactionState->blockState = TBLOCK_DEFAULT;
5483 * ShowTransactionState
5484 * Debug support
5486 static void
5487 ShowTransactionState(const char *str)
5489 /* skip work if message will definitely not be printed */
5490 if (message_level_is_interesting(DEBUG5))
5491 ShowTransactionStateRec(str, CurrentTransactionState);
5495 * ShowTransactionStateRec
5496 * Recursive subroutine for ShowTransactionState
5498 static void
5499 ShowTransactionStateRec(const char *str, TransactionState s)
5501 StringInfoData buf;
5503 initStringInfo(&buf);
5505 if (s->nChildXids > 0)
5507 int i;
5509 appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5510 for (i = 1; i < s->nChildXids; i++)
5511 appendStringInfo(&buf, " %u", s->childXids[i]);
5514 if (s->parent)
5515 ShowTransactionStateRec(str, s->parent);
5517 ereport(DEBUG5,
5518 (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5519 str, s->nestingLevel,
5520 PointerIsValid(s->name) ? s->name : "unnamed",
5521 BlockStateAsString(s->blockState),
5522 TransStateAsString(s->state),
5523 (unsigned int) XidFromFullTransactionId(s->fullTransactionId),
5524 (unsigned int) s->subTransactionId,
5525 (unsigned int) currentCommandId,
5526 currentCommandIdUsed ? " (used)" : "",
5527 buf.data)));
5529 pfree(buf.data);
5533 * BlockStateAsString
5534 * Debug support
5536 static const char *
5537 BlockStateAsString(TBlockState blockState)
5539 switch (blockState)
5541 case TBLOCK_DEFAULT:
5542 return "DEFAULT";
5543 case TBLOCK_STARTED:
5544 return "STARTED";
5545 case TBLOCK_BEGIN:
5546 return "BEGIN";
5547 case TBLOCK_INPROGRESS:
5548 return "INPROGRESS";
5549 case TBLOCK_IMPLICIT_INPROGRESS:
5550 return "IMPLICIT_INPROGRESS";
5551 case TBLOCK_PARALLEL_INPROGRESS:
5552 return "PARALLEL_INPROGRESS";
5553 case TBLOCK_END:
5554 return "END";
5555 case TBLOCK_ABORT:
5556 return "ABORT";
5557 case TBLOCK_ABORT_END:
5558 return "ABORT_END";
5559 case TBLOCK_ABORT_PENDING:
5560 return "ABORT_PENDING";
5561 case TBLOCK_PREPARE:
5562 return "PREPARE";
5563 case TBLOCK_SUBBEGIN:
5564 return "SUBBEGIN";
5565 case TBLOCK_SUBINPROGRESS:
5566 return "SUBINPROGRESS";
5567 case TBLOCK_SUBRELEASE:
5568 return "SUBRELEASE";
5569 case TBLOCK_SUBCOMMIT:
5570 return "SUBCOMMIT";
5571 case TBLOCK_SUBABORT:
5572 return "SUBABORT";
5573 case TBLOCK_SUBABORT_END:
5574 return "SUBABORT_END";
5575 case TBLOCK_SUBABORT_PENDING:
5576 return "SUBABORT_PENDING";
5577 case TBLOCK_SUBRESTART:
5578 return "SUBRESTART";
5579 case TBLOCK_SUBABORT_RESTART:
5580 return "SUBABORT_RESTART";
5582 return "UNRECOGNIZED";
5586 * TransStateAsString
5587 * Debug support
5589 static const char *
5590 TransStateAsString(TransState state)
5592 switch (state)
5594 case TRANS_DEFAULT:
5595 return "DEFAULT";
5596 case TRANS_START:
5597 return "START";
5598 case TRANS_INPROGRESS:
5599 return "INPROGRESS";
5600 case TRANS_COMMIT:
5601 return "COMMIT";
5602 case TRANS_ABORT:
5603 return "ABORT";
5604 case TRANS_PREPARE:
5605 return "PREPARE";
5607 return "UNRECOGNIZED";
5611 * xactGetCommittedChildren
5613 * Gets the list of committed children of the current transaction. The return
5614 * value is the number of child transactions. *ptr is set to point to an
5615 * array of TransactionIds. The array is allocated in TopTransactionContext;
5616 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
5617 * If there are no subxacts, *ptr is set to NULL.
5620 xactGetCommittedChildren(TransactionId **ptr)
5622 TransactionState s = CurrentTransactionState;
5624 if (s->nChildXids == 0)
5625 *ptr = NULL;
5626 else
5627 *ptr = s->childXids;
5629 return s->nChildXids;
5633 * XLOG support routines
5638 * Log the commit record for a plain or twophase transaction commit.
5640 * A 2pc commit will be emitted when twophase_xid is valid, a plain one
5641 * otherwise.
5643 XLogRecPtr
5644 XactLogCommitRecord(TimestampTz commit_time,
5645 int nsubxacts, TransactionId *subxacts,
5646 int nrels, RelFileLocator *rels,
5647 int ndroppedstats, xl_xact_stats_item *droppedstats,
5648 int nmsgs, SharedInvalidationMessage *msgs,
5649 bool relcacheInval,
5650 int xactflags, TransactionId twophase_xid,
5651 const char *twophase_gid)
5653 xl_xact_commit xlrec;
5654 xl_xact_xinfo xl_xinfo;
5655 xl_xact_dbinfo xl_dbinfo;
5656 xl_xact_subxacts xl_subxacts;
5657 xl_xact_relfilelocators xl_relfilelocators;
5658 xl_xact_stats_items xl_dropped_stats;
5659 xl_xact_invals xl_invals;
5660 xl_xact_twophase xl_twophase;
5661 xl_xact_origin xl_origin;
5662 uint8 info;
5664 Assert(CritSectionCount > 0);
5666 xl_xinfo.xinfo = 0;
5668 /* decide between a plain and 2pc commit */
5669 if (!TransactionIdIsValid(twophase_xid))
5670 info = XLOG_XACT_COMMIT;
5671 else
5672 info = XLOG_XACT_COMMIT_PREPARED;
5674 /* First figure out and collect all the information needed */
5676 xlrec.xact_time = commit_time;
5678 if (relcacheInval)
5679 xl_xinfo.xinfo |= XACT_COMPLETION_UPDATE_RELCACHE_FILE;
5680 if (forceSyncCommit)
5681 xl_xinfo.xinfo |= XACT_COMPLETION_FORCE_SYNC_COMMIT;
5682 if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5683 xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5686 * Check if the caller would like to ask standbys for immediate feedback
5687 * once this commit is applied.
5689 if (synchronous_commit >= SYNCHRONOUS_COMMIT_REMOTE_APPLY)
5690 xl_xinfo.xinfo |= XACT_COMPLETION_APPLY_FEEDBACK;
5693 * Relcache invalidations requires information about the current database
5694 * and so does logical decoding.
5696 if (nmsgs > 0 || XLogLogicalInfoActive())
5698 xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5699 xl_dbinfo.dbId = MyDatabaseId;
5700 xl_dbinfo.tsId = MyDatabaseTableSpace;
5703 if (nsubxacts > 0)
5705 xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5706 xl_subxacts.nsubxacts = nsubxacts;
5709 if (nrels > 0)
5711 xl_xinfo.xinfo |= XACT_XINFO_HAS_RELFILELOCATORS;
5712 xl_relfilelocators.nrels = nrels;
5713 info |= XLR_SPECIAL_REL_UPDATE;
5716 if (ndroppedstats > 0)
5718 xl_xinfo.xinfo |= XACT_XINFO_HAS_DROPPED_STATS;
5719 xl_dropped_stats.nitems = ndroppedstats;
5722 if (nmsgs > 0)
5724 xl_xinfo.xinfo |= XACT_XINFO_HAS_INVALS;
5725 xl_invals.nmsgs = nmsgs;
5728 if (TransactionIdIsValid(twophase_xid))
5730 xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5731 xl_twophase.xid = twophase_xid;
5732 Assert(twophase_gid != NULL);
5734 if (XLogLogicalInfoActive())
5735 xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
5738 /* dump transaction origin information */
5739 if (replorigin_session_origin != InvalidRepOriginId)
5741 xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
5743 xl_origin.origin_lsn = replorigin_session_origin_lsn;
5744 xl_origin.origin_timestamp = replorigin_session_origin_timestamp;
5747 if (xl_xinfo.xinfo != 0)
5748 info |= XLOG_XACT_HAS_INFO;
5750 /* Then include all the collected data into the commit record. */
5752 XLogBeginInsert();
5754 XLogRegisterData((char *) (&xlrec), sizeof(xl_xact_commit));
5756 if (xl_xinfo.xinfo != 0)
5757 XLogRegisterData((char *) (&xl_xinfo.xinfo), sizeof(xl_xinfo.xinfo));
5759 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5760 XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
5762 if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5764 XLogRegisterData((char *) (&xl_subxacts),
5765 MinSizeOfXactSubxacts);
5766 XLogRegisterData((char *) subxacts,
5767 nsubxacts * sizeof(TransactionId));
5770 if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILELOCATORS)
5772 XLogRegisterData((char *) (&xl_relfilelocators),
5773 MinSizeOfXactRelfileLocators);
5774 XLogRegisterData((char *) rels,
5775 nrels * sizeof(RelFileLocator));
5778 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
5780 XLogRegisterData((char *) (&xl_dropped_stats),
5781 MinSizeOfXactStatsItems);
5782 XLogRegisterData((char *) droppedstats,
5783 ndroppedstats * sizeof(xl_xact_stats_item));
5786 if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
5788 XLogRegisterData((char *) (&xl_invals), MinSizeOfXactInvals);
5789 XLogRegisterData((char *) msgs,
5790 nmsgs * sizeof(SharedInvalidationMessage));
5793 if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5795 XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
5796 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
5797 XLogRegisterData(unconstify(char *, twophase_gid), strlen(twophase_gid) + 1);
5800 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5801 XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
5803 /* we allow filtering by xacts */
5804 XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
5806 return XLogInsert(RM_XACT_ID, info);
5810 * Log the commit record for a plain or twophase transaction abort.
5812 * A 2pc abort will be emitted when twophase_xid is valid, a plain one
5813 * otherwise.
5815 XLogRecPtr
5816 XactLogAbortRecord(TimestampTz abort_time,
5817 int nsubxacts, TransactionId *subxacts,
5818 int nrels, RelFileLocator *rels,
5819 int ndroppedstats, xl_xact_stats_item *droppedstats,
5820 int xactflags, TransactionId twophase_xid,
5821 const char *twophase_gid)
5823 xl_xact_abort xlrec;
5824 xl_xact_xinfo xl_xinfo;
5825 xl_xact_subxacts xl_subxacts;
5826 xl_xact_relfilelocators xl_relfilelocators;
5827 xl_xact_stats_items xl_dropped_stats;
5828 xl_xact_twophase xl_twophase;
5829 xl_xact_dbinfo xl_dbinfo;
5830 xl_xact_origin xl_origin;
5832 uint8 info;
5834 Assert(CritSectionCount > 0);
5836 xl_xinfo.xinfo = 0;
5838 /* decide between a plain and 2pc abort */
5839 if (!TransactionIdIsValid(twophase_xid))
5840 info = XLOG_XACT_ABORT;
5841 else
5842 info = XLOG_XACT_ABORT_PREPARED;
5845 /* First figure out and collect all the information needed */
5847 xlrec.xact_time = abort_time;
5849 if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5850 xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5852 if (nsubxacts > 0)
5854 xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5855 xl_subxacts.nsubxacts = nsubxacts;
5858 if (nrels > 0)
5860 xl_xinfo.xinfo |= XACT_XINFO_HAS_RELFILELOCATORS;
5861 xl_relfilelocators.nrels = nrels;
5862 info |= XLR_SPECIAL_REL_UPDATE;
5865 if (ndroppedstats > 0)
5867 xl_xinfo.xinfo |= XACT_XINFO_HAS_DROPPED_STATS;
5868 xl_dropped_stats.nitems = ndroppedstats;
5871 if (TransactionIdIsValid(twophase_xid))
5873 xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5874 xl_twophase.xid = twophase_xid;
5875 Assert(twophase_gid != NULL);
5877 if (XLogLogicalInfoActive())
5878 xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
5881 if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
5883 xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5884 xl_dbinfo.dbId = MyDatabaseId;
5885 xl_dbinfo.tsId = MyDatabaseTableSpace;
5889 * Dump transaction origin information. We need this during recovery to
5890 * update the replication origin progress.
5892 if (replorigin_session_origin != InvalidRepOriginId)
5894 xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
5896 xl_origin.origin_lsn = replorigin_session_origin_lsn;
5897 xl_origin.origin_timestamp = replorigin_session_origin_timestamp;
5900 if (xl_xinfo.xinfo != 0)
5901 info |= XLOG_XACT_HAS_INFO;
5903 /* Then include all the collected data into the abort record. */
5905 XLogBeginInsert();
5907 XLogRegisterData((char *) (&xlrec), MinSizeOfXactAbort);
5909 if (xl_xinfo.xinfo != 0)
5910 XLogRegisterData((char *) (&xl_xinfo), sizeof(xl_xinfo));
5912 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5913 XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
5915 if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5917 XLogRegisterData((char *) (&xl_subxacts),
5918 MinSizeOfXactSubxacts);
5919 XLogRegisterData((char *) subxacts,
5920 nsubxacts * sizeof(TransactionId));
5923 if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILELOCATORS)
5925 XLogRegisterData((char *) (&xl_relfilelocators),
5926 MinSizeOfXactRelfileLocators);
5927 XLogRegisterData((char *) rels,
5928 nrels * sizeof(RelFileLocator));
5931 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
5933 XLogRegisterData((char *) (&xl_dropped_stats),
5934 MinSizeOfXactStatsItems);
5935 XLogRegisterData((char *) droppedstats,
5936 ndroppedstats * sizeof(xl_xact_stats_item));
5939 if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5941 XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
5942 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
5943 XLogRegisterData(unconstify(char *, twophase_gid), strlen(twophase_gid) + 1);
5946 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5947 XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
5949 /* Include the replication origin */
5950 XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
5952 return XLogInsert(RM_XACT_ID, info);
5956 * Before 9.0 this was a fairly short function, but now it performs many
5957 * actions for which the order of execution is critical.
5959 static void
5960 xact_redo_commit(xl_xact_parsed_commit *parsed,
5961 TransactionId xid,
5962 XLogRecPtr lsn,
5963 RepOriginId origin_id)
5965 TransactionId max_xid;
5966 TimestampTz commit_time;
5968 Assert(TransactionIdIsValid(xid));
5970 max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
5972 /* Make sure nextXid is beyond any XID mentioned in the record. */
5973 AdvanceNextFullTransactionIdPastXid(max_xid);
5975 Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) ==
5976 (origin_id == InvalidRepOriginId));
5978 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
5979 commit_time = parsed->origin_timestamp;
5980 else
5981 commit_time = parsed->xact_time;
5983 /* Set the transaction commit timestamp and metadata */
5984 TransactionTreeSetCommitTsData(xid, parsed->nsubxacts, parsed->subxacts,
5985 commit_time, origin_id);
5987 if (standbyState == STANDBY_DISABLED)
5990 * Mark the transaction committed in pg_xact.
5992 TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
5994 else
5997 * If a transaction completion record arrives that has as-yet
5998 * unobserved subtransactions then this will not have been fully
5999 * handled by the call to RecordKnownAssignedTransactionIds() in the
6000 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6001 * cover that case. This is confusing and it is easy to think this
6002 * call is irrelevant, which has happened three times in development
6003 * already. Leave it in.
6005 RecordKnownAssignedTransactionIds(max_xid);
6008 * Mark the transaction committed in pg_xact. We use async commit
6009 * protocol during recovery to provide information on database
6010 * consistency for when users try to set hint bits. It is important
6011 * that we do not set hint bits until the minRecoveryPoint is past
6012 * this commit record. This ensures that if we crash we don't see hint
6013 * bits set on changes made by transactions that haven't yet
6014 * recovered. It's unlikely but it's good to be safe.
6016 TransactionIdAsyncCommitTree(xid, parsed->nsubxacts, parsed->subxacts, lsn);
6019 * We must mark clog before we update the ProcArray.
6021 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6024 * Send any cache invalidations attached to the commit. We must
6025 * maintain the same order of invalidation then release locks as
6026 * occurs in CommitTransaction().
6028 ProcessCommittedInvalidationMessages(parsed->msgs, parsed->nmsgs,
6029 XactCompletionRelcacheInitFileInval(parsed->xinfo),
6030 parsed->dbId, parsed->tsId);
6033 * Release locks, if any. We do this for both two phase and normal one
6034 * phase transactions. In effect we are ignoring the prepare phase and
6035 * just going straight to lock release.
6037 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6038 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6041 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6043 /* recover apply progress */
6044 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6045 false /* backward */ , false /* WAL */ );
6048 /* Make sure files supposed to be dropped are dropped */
6049 if (parsed->nrels > 0)
6052 * First update minimum recovery point to cover this WAL record. Once
6053 * a relation is deleted, there's no going back. The buffer manager
6054 * enforces the WAL-first rule for normal updates to relation files,
6055 * so that the minimum recovery point is always updated before the
6056 * corresponding change in the data file is flushed to disk, but we
6057 * have to do the same here since we're bypassing the buffer manager.
6059 * Doing this before deleting the files means that if a deletion fails
6060 * for some reason, you cannot start up the system even after restart,
6061 * until you fix the underlying situation so that the deletion will
6062 * succeed. Alternatively, we could update the minimum recovery point
6063 * after deletion, but that would leave a small window where the
6064 * WAL-first rule would be violated.
6066 XLogFlush(lsn);
6068 /* Make sure files supposed to be dropped are dropped */
6069 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6072 if (parsed->nstats > 0)
6074 /* see equivalent call for relations above */
6075 XLogFlush(lsn);
6077 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6081 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
6082 * in normal operation. For example, in CREATE DATABASE, we copy all files
6083 * from the template database, and then commit the transaction. If we
6084 * crash after all the files have been copied but before the commit, you
6085 * have files in the data directory without an entry in pg_database. To
6086 * minimize the window for that, we use ForceSyncCommit() to rush the
6087 * commit record to disk as quick as possible. We have the same window
6088 * during recovery, and forcing an XLogFlush() (which updates
6089 * minRecoveryPoint during recovery) helps to reduce that problem window,
6090 * for any user that requested ForceSyncCommit().
6092 if (XactCompletionForceSyncCommit(parsed->xinfo))
6093 XLogFlush(lsn);
6096 * If asked by the primary (because someone is waiting for a synchronous
6097 * commit = remote_apply), we will need to ask walreceiver to send a reply
6098 * immediately.
6100 if (XactCompletionApplyFeedback(parsed->xinfo))
6101 XLogRequestWalReceiverReply();
6105 * Be careful with the order of execution, as with xact_redo_commit().
6106 * The two functions are similar but differ in key places.
6108 * Note also that an abort can be for a subtransaction and its children,
6109 * not just for a top level abort. That means we have to consider
6110 * topxid != xid, whereas in commit we would find topxid == xid always
6111 * because subtransaction commit is never WAL logged.
6113 static void
6114 xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid,
6115 XLogRecPtr lsn, RepOriginId origin_id)
6117 TransactionId max_xid;
6119 Assert(TransactionIdIsValid(xid));
6121 /* Make sure nextXid is beyond any XID mentioned in the record. */
6122 max_xid = TransactionIdLatest(xid,
6123 parsed->nsubxacts,
6124 parsed->subxacts);
6125 AdvanceNextFullTransactionIdPastXid(max_xid);
6127 if (standbyState == STANDBY_DISABLED)
6129 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6130 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6132 else
6135 * If a transaction completion record arrives that has as-yet
6136 * unobserved subtransactions then this will not have been fully
6137 * handled by the call to RecordKnownAssignedTransactionIds() in the
6138 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6139 * cover that case. This is confusing and it is easy to think this
6140 * call is irrelevant, which has happened three times in development
6141 * already. Leave it in.
6143 RecordKnownAssignedTransactionIds(max_xid);
6145 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6146 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6149 * We must update the ProcArray after we have marked clog.
6151 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6154 * There are no invalidation messages to send or undo.
6158 * Release locks, if any. There are no invalidations to send.
6160 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6161 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6164 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6166 /* recover apply progress */
6167 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6168 false /* backward */ , false /* WAL */ );
6171 /* Make sure files supposed to be dropped are dropped */
6172 if (parsed->nrels > 0)
6175 * See comments about update of minimum recovery point on truncation,
6176 * in xact_redo_commit().
6178 XLogFlush(lsn);
6180 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6183 if (parsed->nstats > 0)
6185 /* see equivalent call for relations above */
6186 XLogFlush(lsn);
6188 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6192 void
6193 xact_redo(XLogReaderState *record)
6195 uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6197 /* Backup blocks are not used in xact records */
6198 Assert(!XLogRecHasAnyBlockRefs(record));
6200 if (info == XLOG_XACT_COMMIT)
6202 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6203 xl_xact_parsed_commit parsed;
6205 ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6206 xact_redo_commit(&parsed, XLogRecGetXid(record),
6207 record->EndRecPtr, XLogRecGetOrigin(record));
6209 else if (info == XLOG_XACT_COMMIT_PREPARED)
6211 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6212 xl_xact_parsed_commit parsed;
6214 ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6215 xact_redo_commit(&parsed, parsed.twophase_xid,
6216 record->EndRecPtr, XLogRecGetOrigin(record));
6218 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6219 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6220 PrepareRedoRemove(parsed.twophase_xid, false);
6221 LWLockRelease(TwoPhaseStateLock);
6223 else if (info == XLOG_XACT_ABORT)
6225 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6226 xl_xact_parsed_abort parsed;
6228 ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6229 xact_redo_abort(&parsed, XLogRecGetXid(record),
6230 record->EndRecPtr, XLogRecGetOrigin(record));
6232 else if (info == XLOG_XACT_ABORT_PREPARED)
6234 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6235 xl_xact_parsed_abort parsed;
6237 ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6238 xact_redo_abort(&parsed, parsed.twophase_xid,
6239 record->EndRecPtr, XLogRecGetOrigin(record));
6241 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6242 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6243 PrepareRedoRemove(parsed.twophase_xid, false);
6244 LWLockRelease(TwoPhaseStateLock);
6246 else if (info == XLOG_XACT_PREPARE)
6249 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6250 * gxact entry.
6252 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6253 PrepareRedoAdd(XLogRecGetData(record),
6254 record->ReadRecPtr,
6255 record->EndRecPtr,
6256 XLogRecGetOrigin(record));
6257 LWLockRelease(TwoPhaseStateLock);
6259 else if (info == XLOG_XACT_ASSIGNMENT)
6261 xl_xact_assignment *xlrec = (xl_xact_assignment *) XLogRecGetData(record);
6263 if (standbyState >= STANDBY_INITIALIZED)
6264 ProcArrayApplyXidAssignment(xlrec->xtop,
6265 xlrec->nsubxacts, xlrec->xsub);
6267 else if (info == XLOG_XACT_INVALIDATIONS)
6270 * XXX we do ignore this for now, what matters are invalidations
6271 * written into the commit record.
6274 else
6275 elog(PANIC, "xact_redo: unknown op code %u", info);