Update copyright for 2022
[pgsql.git] / src / backend / access / transam / xact.c
blobc9516e03faee70171b5f718bd5b7d4c5e291ae4f
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-2022, 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/xlogutils.h"
33 #include "catalog/index.h"
34 #include "catalog/namespace.h"
35 #include "catalog/pg_enum.h"
36 #include "catalog/storage.h"
37 #include "commands/async.h"
38 #include "commands/tablecmds.h"
39 #include "commands/trigger.h"
40 #include "common/pg_prng.h"
41 #include "executor/spi.h"
42 #include "libpq/be-fsstubs.h"
43 #include "libpq/pqsignal.h"
44 #include "miscadmin.h"
45 #include "pg_trace.h"
46 #include "pgstat.h"
47 #include "replication/logical.h"
48 #include "replication/logicallauncher.h"
49 #include "replication/origin.h"
50 #include "replication/snapbuild.h"
51 #include "replication/syncrep.h"
52 #include "replication/walsender.h"
53 #include "storage/condition_variable.h"
54 #include "storage/fd.h"
55 #include "storage/lmgr.h"
56 #include "storage/md.h"
57 #include "storage/predicate.h"
58 #include "storage/proc.h"
59 #include "storage/procarray.h"
60 #include "storage/sinvaladt.h"
61 #include "storage/smgr.h"
62 #include "utils/builtins.h"
63 #include "utils/catcache.h"
64 #include "utils/combocid.h"
65 #include "utils/guc.h"
66 #include "utils/inval.h"
67 #include "utils/memutils.h"
68 #include "utils/relmapper.h"
69 #include "utils/snapmgr.h"
70 #include "utils/timeout.h"
71 #include "utils/timestamp.h"
74 * User-tweakable parameters
76 int DefaultXactIsoLevel = XACT_READ_COMMITTED;
77 int XactIsoLevel;
79 bool DefaultXactReadOnly = false;
80 bool XactReadOnly;
82 bool DefaultXactDeferrable = false;
83 bool XactDeferrable;
85 int synchronous_commit = SYNCHRONOUS_COMMIT_ON;
88 * CheckXidAlive is a xid value pointing to a possibly ongoing (sub)
89 * transaction. Currently, it is used in logical decoding. It's possible
90 * that such transactions can get aborted while the decoding is ongoing in
91 * which case we skip decoding that particular transaction. To ensure that we
92 * check whether the CheckXidAlive is aborted after fetching the tuple from
93 * system tables. We also ensure that during logical decoding we never
94 * directly access the tableam or heap APIs because we are checking for the
95 * concurrent aborts only in systable_* APIs.
97 TransactionId CheckXidAlive = InvalidTransactionId;
98 bool bsysscan = false;
101 * When running as a parallel worker, we place only a single
102 * TransactionStateData on the parallel worker's state stack, and the XID
103 * reflected there will be that of the *innermost* currently-active
104 * subtransaction in the backend that initiated parallelism. However,
105 * GetTopTransactionId() and TransactionIdIsCurrentTransactionId()
106 * need to return the same answers in the parallel worker as they would have
107 * in the user backend, so we need some additional bookkeeping.
109 * XactTopFullTransactionId stores the XID of our toplevel transaction, which
110 * will be the same as TopTransactionStateData.fullTransactionId in an
111 * ordinary backend; but in a parallel backend, which does not have the entire
112 * transaction state, it will instead be copied from the backend that started
113 * the parallel operation.
115 * nParallelCurrentXids will be 0 and ParallelCurrentXids NULL in an ordinary
116 * backend, but in a parallel backend, nParallelCurrentXids will contain the
117 * number of XIDs that need to be considered current, and ParallelCurrentXids
118 * will contain the XIDs themselves. This includes all XIDs that were current
119 * or sub-committed in the parent at the time the parallel operation began.
120 * The XIDs are stored sorted in numerical order (not logical order) to make
121 * lookups as fast as possible.
123 FullTransactionId XactTopFullTransactionId = {InvalidTransactionId};
124 int nParallelCurrentXids = 0;
125 TransactionId *ParallelCurrentXids;
128 * Miscellaneous flag bits to record events which occur on the top level
129 * transaction. These flags are only persisted in MyXactFlags and are intended
130 * so we remember to do certain things later on in the transaction. This is
131 * globally accessible, so can be set from anywhere in the code that requires
132 * recording flags.
134 int MyXactFlags;
137 * transaction states - transaction state from server perspective
139 typedef enum TransState
141 TRANS_DEFAULT, /* idle */
142 TRANS_START, /* transaction starting */
143 TRANS_INPROGRESS, /* inside a valid transaction */
144 TRANS_COMMIT, /* commit in progress */
145 TRANS_ABORT, /* abort in progress */
146 TRANS_PREPARE /* prepare in progress */
147 } TransState;
150 * transaction block states - transaction state of client queries
152 * Note: the subtransaction states are used only for non-topmost
153 * transactions; the others appear only in the topmost transaction.
155 typedef enum TBlockState
157 /* not-in-transaction-block states */
158 TBLOCK_DEFAULT, /* idle */
159 TBLOCK_STARTED, /* running single-query transaction */
161 /* transaction block states */
162 TBLOCK_BEGIN, /* starting transaction block */
163 TBLOCK_INPROGRESS, /* live transaction */
164 TBLOCK_IMPLICIT_INPROGRESS, /* live transaction after implicit BEGIN */
165 TBLOCK_PARALLEL_INPROGRESS, /* live transaction inside parallel worker */
166 TBLOCK_END, /* COMMIT received */
167 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
168 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
169 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
170 TBLOCK_PREPARE, /* live xact, PREPARE received */
172 /* subtransaction states */
173 TBLOCK_SUBBEGIN, /* starting a subtransaction */
174 TBLOCK_SUBINPROGRESS, /* live subtransaction */
175 TBLOCK_SUBRELEASE, /* RELEASE received */
176 TBLOCK_SUBCOMMIT, /* COMMIT received while TBLOCK_SUBINPROGRESS */
177 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
178 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
179 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
180 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
181 TBLOCK_SUBABORT_RESTART /* failed subxact, ROLLBACK TO received */
182 } TBlockState;
185 * transaction state structure
187 typedef struct TransactionStateData
189 FullTransactionId fullTransactionId; /* my FullTransactionId */
190 SubTransactionId subTransactionId; /* my subxact ID */
191 char *name; /* savepoint name, if any */
192 int savepointLevel; /* savepoint level */
193 TransState state; /* low-level state */
194 TBlockState blockState; /* high-level state */
195 int nestingLevel; /* transaction nesting depth */
196 int gucNestLevel; /* GUC context nesting depth */
197 MemoryContext curTransactionContext; /* my xact-lifetime context */
198 ResourceOwner curTransactionOwner; /* my query resources */
199 TransactionId *childXids; /* subcommitted child XIDs, in XID order */
200 int nChildXids; /* # of subcommitted child XIDs */
201 int maxChildXids; /* allocated size of childXids[] */
202 Oid prevUser; /* previous CurrentUserId setting */
203 int prevSecContext; /* previous SecurityRestrictionContext */
204 bool prevXactReadOnly; /* entry-time xact r/o state */
205 bool startedInRecovery; /* did we start in recovery? */
206 bool didLogXid; /* has xid been included in WAL record? */
207 int parallelModeLevel; /* Enter/ExitParallelMode counter */
208 bool chain; /* start a new block after this one */
209 bool topXidLogged; /* for a subxact: is top-level XID logged? */
210 struct TransactionStateData *parent; /* back link to parent */
211 } TransactionStateData;
213 typedef TransactionStateData *TransactionState;
216 * Serialized representation used to transmit transaction state to parallel
217 * workers through shared memory.
219 typedef struct SerializedTransactionState
221 int xactIsoLevel;
222 bool xactDeferrable;
223 FullTransactionId topFullTransactionId;
224 FullTransactionId currentFullTransactionId;
225 CommandId currentCommandId;
226 int nParallelCurrentXids;
227 TransactionId parallelCurrentXids[FLEXIBLE_ARRAY_MEMBER];
228 } SerializedTransactionState;
230 /* The size of SerializedTransactionState, not including the final array. */
231 #define SerializedTransactionStateHeaderSize \
232 offsetof(SerializedTransactionState, parallelCurrentXids)
235 * CurrentTransactionState always points to the current transaction state
236 * block. It will point to TopTransactionStateData when not in a
237 * transaction at all, or when in a top-level transaction.
239 static TransactionStateData TopTransactionStateData = {
240 .state = TRANS_DEFAULT,
241 .blockState = TBLOCK_DEFAULT,
242 .topXidLogged = false,
246 * unreportedXids holds XIDs of all subtransactions that have not yet been
247 * reported in an XLOG_XACT_ASSIGNMENT record.
249 static int nUnreportedXids;
250 static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS];
252 static TransactionState CurrentTransactionState = &TopTransactionStateData;
255 * The subtransaction ID and command ID assignment counters are global
256 * to a whole transaction, so we do not keep them in the state stack.
258 static SubTransactionId currentSubTransactionId;
259 static CommandId currentCommandId;
260 static bool currentCommandIdUsed;
263 * xactStartTimestamp is the value of transaction_timestamp().
264 * stmtStartTimestamp is the value of statement_timestamp().
265 * xactStopTimestamp is the time at which we log a commit or abort WAL record.
266 * These do not change as we enter and exit subtransactions, so we don't
267 * keep them inside the TransactionState stack.
269 static TimestampTz xactStartTimestamp;
270 static TimestampTz stmtStartTimestamp;
271 static TimestampTz xactStopTimestamp;
274 * GID to be used for preparing the current transaction. This is also
275 * global to a whole transaction, so we don't keep it in the state stack.
277 static char *prepareGID;
280 * Some commands want to force synchronous commit.
282 static bool forceSyncCommit = false;
284 /* Flag for logging statements in a transaction. */
285 bool xact_is_sampled = false;
288 * Private context for transaction-abort work --- we reserve space for this
289 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
290 * when we've run out of memory.
292 static MemoryContext TransactionAbortContext = NULL;
295 * List of add-on start- and end-of-xact callbacks
297 typedef struct XactCallbackItem
299 struct XactCallbackItem *next;
300 XactCallback callback;
301 void *arg;
302 } XactCallbackItem;
304 static XactCallbackItem *Xact_callbacks = NULL;
307 * List of add-on start- and end-of-subxact callbacks
309 typedef struct SubXactCallbackItem
311 struct SubXactCallbackItem *next;
312 SubXactCallback callback;
313 void *arg;
314 } SubXactCallbackItem;
316 static SubXactCallbackItem *SubXact_callbacks = NULL;
319 /* local function prototypes */
320 static void AssignTransactionId(TransactionState s);
321 static void AbortTransaction(void);
322 static void AtAbort_Memory(void);
323 static void AtCleanup_Memory(void);
324 static void AtAbort_ResourceOwner(void);
325 static void AtCCI_LocalCache(void);
326 static void AtCommit_Memory(void);
327 static void AtStart_Cache(void);
328 static void AtStart_Memory(void);
329 static void AtStart_ResourceOwner(void);
330 static void CallXactCallbacks(XactEvent event);
331 static void CallSubXactCallbacks(SubXactEvent event,
332 SubTransactionId mySubid,
333 SubTransactionId parentSubid);
334 static void CleanupTransaction(void);
335 static void CheckTransactionBlock(bool isTopLevel, bool throwError,
336 const char *stmtType);
337 static void CommitTransaction(void);
338 static TransactionId RecordTransactionAbort(bool isSubXact);
339 static void StartTransaction(void);
341 static void StartSubTransaction(void);
342 static void CommitSubTransaction(void);
343 static void AbortSubTransaction(void);
344 static void CleanupSubTransaction(void);
345 static void PushTransaction(void);
346 static void PopTransaction(void);
348 static void AtSubAbort_Memory(void);
349 static void AtSubCleanup_Memory(void);
350 static void AtSubAbort_ResourceOwner(void);
351 static void AtSubCommit_Memory(void);
352 static void AtSubStart_Memory(void);
353 static void AtSubStart_ResourceOwner(void);
355 static void ShowTransactionState(const char *str);
356 static void ShowTransactionStateRec(const char *str, TransactionState state);
357 static const char *BlockStateAsString(TBlockState blockState);
358 static const char *TransStateAsString(TransState state);
361 /* ----------------------------------------------------------------
362 * transaction state accessors
363 * ----------------------------------------------------------------
367 * IsTransactionState
369 * This returns true if we are inside a valid transaction; that is,
370 * it is safe to initiate database access, take heavyweight locks, etc.
372 bool
373 IsTransactionState(void)
375 TransactionState s = CurrentTransactionState;
378 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
379 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
380 * TRANS_PREPARE since it might be too soon or too late within those
381 * transition states to do anything interesting. Hence, the only "valid"
382 * state is TRANS_INPROGRESS.
384 return (s->state == TRANS_INPROGRESS);
388 * IsAbortedTransactionBlockState
390 * This returns true if we are within an aborted transaction block.
392 bool
393 IsAbortedTransactionBlockState(void)
395 TransactionState s = CurrentTransactionState;
397 if (s->blockState == TBLOCK_ABORT ||
398 s->blockState == TBLOCK_SUBABORT)
399 return true;
401 return false;
406 * GetTopTransactionId
408 * This will return the XID of the main transaction, assigning one if
409 * it's not yet set. Be careful to call this only inside a valid xact.
411 TransactionId
412 GetTopTransactionId(void)
414 if (!FullTransactionIdIsValid(XactTopFullTransactionId))
415 AssignTransactionId(&TopTransactionStateData);
416 return XidFromFullTransactionId(XactTopFullTransactionId);
420 * GetTopTransactionIdIfAny
422 * This will return the XID of the main transaction, if one is assigned.
423 * It will return InvalidTransactionId if we are not currently inside a
424 * transaction, or inside a transaction that hasn't yet been assigned an XID.
426 TransactionId
427 GetTopTransactionIdIfAny(void)
429 return XidFromFullTransactionId(XactTopFullTransactionId);
433 * GetCurrentTransactionId
435 * This will return the XID of the current transaction (main or sub
436 * transaction), assigning one if it's not yet set. Be careful to call this
437 * only inside a valid xact.
439 TransactionId
440 GetCurrentTransactionId(void)
442 TransactionState s = CurrentTransactionState;
444 if (!FullTransactionIdIsValid(s->fullTransactionId))
445 AssignTransactionId(s);
446 return XidFromFullTransactionId(s->fullTransactionId);
450 * GetCurrentTransactionIdIfAny
452 * This will return the XID of the current sub xact, if one is assigned.
453 * It will return InvalidTransactionId if we are not currently inside a
454 * transaction, or inside a transaction that hasn't been assigned an XID yet.
456 TransactionId
457 GetCurrentTransactionIdIfAny(void)
459 return XidFromFullTransactionId(CurrentTransactionState->fullTransactionId);
463 * GetTopFullTransactionId
465 * This will return the FullTransactionId of the main transaction, assigning
466 * one if it's not yet set. Be careful to call this only inside a valid xact.
468 FullTransactionId
469 GetTopFullTransactionId(void)
471 if (!FullTransactionIdIsValid(XactTopFullTransactionId))
472 AssignTransactionId(&TopTransactionStateData);
473 return XactTopFullTransactionId;
477 * GetTopFullTransactionIdIfAny
479 * This will return the FullTransactionId of the main transaction, if one is
480 * assigned. It will return InvalidFullTransactionId if we are not currently
481 * inside a transaction, or inside a transaction that hasn't yet been assigned
482 * one.
484 FullTransactionId
485 GetTopFullTransactionIdIfAny(void)
487 return XactTopFullTransactionId;
491 * GetCurrentFullTransactionId
493 * This will return the FullTransactionId of the current transaction (main or
494 * sub transaction), assigning one if it's not yet set. Be careful to call
495 * this only inside a valid xact.
497 FullTransactionId
498 GetCurrentFullTransactionId(void)
500 TransactionState s = CurrentTransactionState;
502 if (!FullTransactionIdIsValid(s->fullTransactionId))
503 AssignTransactionId(s);
504 return s->fullTransactionId;
508 * GetCurrentFullTransactionIdIfAny
510 * This will return the FullTransactionId of the current sub xact, if one is
511 * assigned. It will return InvalidFullTransactionId if we are not currently
512 * inside a transaction, or inside a transaction that hasn't been assigned one
513 * yet.
515 FullTransactionId
516 GetCurrentFullTransactionIdIfAny(void)
518 return CurrentTransactionState->fullTransactionId;
522 * MarkCurrentTransactionIdLoggedIfAny
524 * Remember that the current xid - if it is assigned - now has been wal logged.
526 void
527 MarkCurrentTransactionIdLoggedIfAny(void)
529 if (FullTransactionIdIsValid(CurrentTransactionState->fullTransactionId))
530 CurrentTransactionState->didLogXid = true;
534 * IsSubxactTopXidLogPending
536 * This is used to decide whether we need to WAL log the top-level XID for
537 * operation in a subtransaction. We require that for logical decoding, see
538 * LogicalDecodingProcessRecord.
540 * This returns true if wal_level >= logical and we are inside a valid
541 * subtransaction, for which the assignment was not yet written to any WAL
542 * record.
544 bool
545 IsSubxactTopXidLogPending(void)
547 /* check whether it is already logged */
548 if (CurrentTransactionState->topXidLogged)
549 return false;
551 /* wal_level has to be logical */
552 if (!XLogLogicalInfoActive())
553 return false;
555 /* we need to be in a transaction state */
556 if (!IsTransactionState())
557 return false;
559 /* it has to be a subtransaction */
560 if (!IsSubTransaction())
561 return false;
563 /* the subtransaction has to have a XID assigned */
564 if (!TransactionIdIsValid(GetCurrentTransactionIdIfAny()))
565 return false;
567 return true;
571 * MarkSubxactTopXidLogged
573 * Remember that the top transaction id for the current subtransaction is WAL
574 * logged now.
576 void
577 MarkSubxactTopXidLogged(void)
579 Assert(IsSubxactTopXidLogPending());
581 CurrentTransactionState->topXidLogged = true;
585 * GetStableLatestTransactionId
587 * Get the transaction's XID if it has one, else read the next-to-be-assigned
588 * XID. Once we have a value, return that same value for the remainder of the
589 * current transaction. This is meant to provide the reference point for the
590 * age(xid) function, but might be useful for other maintenance tasks as well.
592 TransactionId
593 GetStableLatestTransactionId(void)
595 static LocalTransactionId lxid = InvalidLocalTransactionId;
596 static TransactionId stablexid = InvalidTransactionId;
598 if (lxid != MyProc->lxid)
600 lxid = MyProc->lxid;
601 stablexid = GetTopTransactionIdIfAny();
602 if (!TransactionIdIsValid(stablexid))
603 stablexid = ReadNextTransactionId();
606 Assert(TransactionIdIsValid(stablexid));
608 return stablexid;
612 * AssignTransactionId
614 * Assigns a new permanent FullTransactionId to the given TransactionState.
615 * We do not assign XIDs to transactions until/unless this is called.
616 * Also, any parent TransactionStates that don't yet have XIDs are assigned
617 * one; this maintains the invariant that a child transaction has an XID
618 * following its parent's.
620 static void
621 AssignTransactionId(TransactionState s)
623 bool isSubXact = (s->parent != NULL);
624 ResourceOwner currentOwner;
625 bool log_unknown_top = false;
627 /* Assert that caller didn't screw up */
628 Assert(!FullTransactionIdIsValid(s->fullTransactionId));
629 Assert(s->state == TRANS_INPROGRESS);
632 * Workers synchronize transaction state at the beginning of each parallel
633 * operation, so we can't account for new XIDs at this point.
635 if (IsInParallelMode() || IsParallelWorker())
636 elog(ERROR, "cannot assign XIDs during a parallel operation");
639 * Ensure parent(s) have XIDs, so that a child always has an XID later
640 * than its parent. Mustn't recurse here, or we might get a stack
641 * overflow if we're at the bottom of a huge stack of subtransactions none
642 * of which have XIDs yet.
644 if (isSubXact && !FullTransactionIdIsValid(s->parent->fullTransactionId))
646 TransactionState p = s->parent;
647 TransactionState *parents;
648 size_t parentOffset = 0;
650 parents = palloc(sizeof(TransactionState) * s->nestingLevel);
651 while (p != NULL && !FullTransactionIdIsValid(p->fullTransactionId))
653 parents[parentOffset++] = p;
654 p = p->parent;
658 * This is technically a recursive call, but the recursion will never
659 * be more than one layer deep.
661 while (parentOffset != 0)
662 AssignTransactionId(parents[--parentOffset]);
664 pfree(parents);
668 * When wal_level=logical, guarantee that a subtransaction's xid can only
669 * be seen in the WAL stream if its toplevel xid has been logged before.
670 * If necessary we log an xact_assignment record with fewer than
671 * PGPROC_MAX_CACHED_SUBXIDS. Note that it is fine if didLogXid isn't set
672 * for a transaction even though it appears in a WAL record, we just might
673 * superfluously log something. That can happen when an xid is included
674 * somewhere inside a wal record, but not in XLogRecord->xl_xid, like in
675 * xl_standby_locks.
677 if (isSubXact && XLogLogicalInfoActive() &&
678 !TopTransactionStateData.didLogXid)
679 log_unknown_top = true;
682 * Generate a new FullTransactionId and record its xid in PG_PROC and
683 * pg_subtrans.
685 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
686 * shared storage other than PG_PROC; because if there's no room for it in
687 * PG_PROC, the subtrans entry is needed to ensure that other backends see
688 * the Xid as "running". See GetNewTransactionId.
690 s->fullTransactionId = GetNewTransactionId(isSubXact);
691 if (!isSubXact)
692 XactTopFullTransactionId = s->fullTransactionId;
694 if (isSubXact)
695 SubTransSetParent(XidFromFullTransactionId(s->fullTransactionId),
696 XidFromFullTransactionId(s->parent->fullTransactionId));
699 * If it's a top-level transaction, the predicate locking system needs to
700 * be told about it too.
702 if (!isSubXact)
703 RegisterPredicateLockingXid(XidFromFullTransactionId(s->fullTransactionId));
706 * Acquire lock on the transaction XID. (We assume this cannot block.) We
707 * have to ensure that the lock is assigned to the transaction's own
708 * ResourceOwner.
710 currentOwner = CurrentResourceOwner;
711 CurrentResourceOwner = s->curTransactionOwner;
713 XactLockTableInsert(XidFromFullTransactionId(s->fullTransactionId));
715 CurrentResourceOwner = currentOwner;
718 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
719 * top-level transaction we issue a WAL record for the assignment. We
720 * include the top-level xid and all the subxids that have not yet been
721 * reported using XLOG_XACT_ASSIGNMENT records.
723 * This is required to limit the amount of shared memory required in a hot
724 * standby server to keep track of in-progress XIDs. See notes for
725 * RecordKnownAssignedTransactionIds().
727 * We don't keep track of the immediate parent of each subxid, only the
728 * top-level transaction that each subxact belongs to. This is correct in
729 * recovery only because aborted subtransactions are separately WAL
730 * logged.
732 * This is correct even for the case where several levels above us didn't
733 * have an xid assigned as we recursed up to them beforehand.
735 if (isSubXact && XLogStandbyInfoActive())
737 unreportedXids[nUnreportedXids] = XidFromFullTransactionId(s->fullTransactionId);
738 nUnreportedXids++;
741 * ensure this test matches similar one in
742 * RecoverPreparedTransactions()
744 if (nUnreportedXids >= PGPROC_MAX_CACHED_SUBXIDS ||
745 log_unknown_top)
747 xl_xact_assignment xlrec;
750 * xtop is always set by now because we recurse up transaction
751 * stack to the highest unassigned xid and then come back down
753 xlrec.xtop = GetTopTransactionId();
754 Assert(TransactionIdIsValid(xlrec.xtop));
755 xlrec.nsubxacts = nUnreportedXids;
757 XLogBeginInsert();
758 XLogRegisterData((char *) &xlrec, MinSizeOfXactAssignment);
759 XLogRegisterData((char *) unreportedXids,
760 nUnreportedXids * sizeof(TransactionId));
762 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT);
764 nUnreportedXids = 0;
765 /* mark top, not current xact as having been logged */
766 TopTransactionStateData.didLogXid = true;
772 * GetCurrentSubTransactionId
774 SubTransactionId
775 GetCurrentSubTransactionId(void)
777 TransactionState s = CurrentTransactionState;
779 return s->subTransactionId;
783 * SubTransactionIsActive
785 * Test if the specified subxact ID is still active. Note caller is
786 * responsible for checking whether this ID is relevant to the current xact.
788 bool
789 SubTransactionIsActive(SubTransactionId subxid)
791 TransactionState s;
793 for (s = CurrentTransactionState; s != NULL; s = s->parent)
795 if (s->state == TRANS_ABORT)
796 continue;
797 if (s->subTransactionId == subxid)
798 return true;
800 return false;
805 * GetCurrentCommandId
807 * "used" must be true if the caller intends to use the command ID to mark
808 * inserted/updated/deleted tuples. false means the ID is being fetched
809 * for read-only purposes (ie, as a snapshot validity cutoff). See
810 * CommandCounterIncrement() for discussion.
812 CommandId
813 GetCurrentCommandId(bool used)
815 /* this is global to a transaction, not subtransaction-local */
816 if (used)
819 * Forbid setting currentCommandIdUsed in a parallel worker, because
820 * we have no provision for communicating this back to the leader. We
821 * could relax this restriction when currentCommandIdUsed was already
822 * true at the start of the parallel operation.
824 Assert(!IsParallelWorker());
825 currentCommandIdUsed = true;
827 return currentCommandId;
831 * SetParallelStartTimestamps
833 * In a parallel worker, we should inherit the parent transaction's
834 * timestamps rather than setting our own. The parallel worker
835 * infrastructure must call this to provide those values before
836 * calling StartTransaction() or SetCurrentStatementStartTimestamp().
838 void
839 SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts)
841 Assert(IsParallelWorker());
842 xactStartTimestamp = xact_ts;
843 stmtStartTimestamp = stmt_ts;
847 * GetCurrentTransactionStartTimestamp
849 TimestampTz
850 GetCurrentTransactionStartTimestamp(void)
852 return xactStartTimestamp;
856 * GetCurrentStatementStartTimestamp
858 TimestampTz
859 GetCurrentStatementStartTimestamp(void)
861 return stmtStartTimestamp;
865 * GetCurrentTransactionStopTimestamp
867 * We return current time if the transaction stop time hasn't been set
868 * (which can happen if we decide we don't need to log an XLOG record).
870 TimestampTz
871 GetCurrentTransactionStopTimestamp(void)
873 if (xactStopTimestamp != 0)
874 return xactStopTimestamp;
875 return GetCurrentTimestamp();
879 * SetCurrentStatementStartTimestamp
881 * In a parallel worker, this should already have been provided by a call
882 * to SetParallelStartTimestamps().
884 void
885 SetCurrentStatementStartTimestamp(void)
887 if (!IsParallelWorker())
888 stmtStartTimestamp = GetCurrentTimestamp();
889 else
890 Assert(stmtStartTimestamp != 0);
894 * SetCurrentTransactionStopTimestamp
896 static inline void
897 SetCurrentTransactionStopTimestamp(void)
899 xactStopTimestamp = GetCurrentTimestamp();
903 * GetCurrentTransactionNestLevel
905 * Note: this will return zero when not inside any transaction, one when
906 * inside a top-level transaction, etc.
909 GetCurrentTransactionNestLevel(void)
911 TransactionState s = CurrentTransactionState;
913 return s->nestingLevel;
918 * TransactionIdIsCurrentTransactionId
920 bool
921 TransactionIdIsCurrentTransactionId(TransactionId xid)
923 TransactionState s;
926 * We always say that BootstrapTransactionId is "not my transaction ID"
927 * even when it is (ie, during bootstrap). Along with the fact that
928 * transam.c always treats BootstrapTransactionId as already committed,
929 * this causes the heapam_visibility.c routines to see all tuples as
930 * committed, which is what we need during bootstrap. (Bootstrap mode
931 * only inserts tuples, it never updates or deletes them, so all tuples
932 * can be presumed good immediately.)
934 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
935 * not my transaction ID, so we can just return "false" immediately for
936 * any non-normal XID.
938 if (!TransactionIdIsNormal(xid))
939 return false;
941 if (TransactionIdEquals(xid, GetTopTransactionIdIfAny()))
942 return true;
945 * In parallel workers, the XIDs we must consider as current are stored in
946 * ParallelCurrentXids rather than the transaction-state stack. Note that
947 * the XIDs in this array are sorted numerically rather than according to
948 * transactionIdPrecedes order.
950 if (nParallelCurrentXids > 0)
952 int low,
953 high;
955 low = 0;
956 high = nParallelCurrentXids - 1;
957 while (low <= high)
959 int middle;
960 TransactionId probe;
962 middle = low + (high - low) / 2;
963 probe = ParallelCurrentXids[middle];
964 if (probe == xid)
965 return true;
966 else if (probe < xid)
967 low = middle + 1;
968 else
969 high = middle - 1;
971 return false;
975 * We will return true for the Xid of the current subtransaction, any of
976 * its subcommitted children, any of its parents, or any of their
977 * previously subcommitted children. However, a transaction being aborted
978 * is no longer "current", even though it may still have an entry on the
979 * state stack.
981 for (s = CurrentTransactionState; s != NULL; s = s->parent)
983 int low,
984 high;
986 if (s->state == TRANS_ABORT)
987 continue;
988 if (!FullTransactionIdIsValid(s->fullTransactionId))
989 continue; /* it can't have any child XIDs either */
990 if (TransactionIdEquals(xid, XidFromFullTransactionId(s->fullTransactionId)))
991 return true;
992 /* As the childXids array is ordered, we can use binary search */
993 low = 0;
994 high = s->nChildXids - 1;
995 while (low <= high)
997 int middle;
998 TransactionId probe;
1000 middle = low + (high - low) / 2;
1001 probe = s->childXids[middle];
1002 if (TransactionIdEquals(probe, xid))
1003 return true;
1004 else if (TransactionIdPrecedes(probe, xid))
1005 low = middle + 1;
1006 else
1007 high = middle - 1;
1011 return false;
1015 * TransactionStartedDuringRecovery
1017 * Returns true if the current transaction started while recovery was still
1018 * in progress. Recovery might have ended since so RecoveryInProgress() might
1019 * return false already.
1021 bool
1022 TransactionStartedDuringRecovery(void)
1024 return CurrentTransactionState->startedInRecovery;
1028 * EnterParallelMode
1030 void
1031 EnterParallelMode(void)
1033 TransactionState s = CurrentTransactionState;
1035 Assert(s->parallelModeLevel >= 0);
1037 ++s->parallelModeLevel;
1041 * ExitParallelMode
1043 void
1044 ExitParallelMode(void)
1046 TransactionState s = CurrentTransactionState;
1048 Assert(s->parallelModeLevel > 0);
1049 Assert(s->parallelModeLevel > 1 || !ParallelContextActive());
1051 --s->parallelModeLevel;
1055 * IsInParallelMode
1057 * Are we in a parallel operation, as either the leader or a worker? Check
1058 * this to prohibit operations that change backend-local state expected to
1059 * match across all workers. Mere caches usually don't require such a
1060 * restriction. State modified in a strict push/pop fashion, such as the
1061 * active snapshot stack, is often fine.
1063 bool
1064 IsInParallelMode(void)
1066 return CurrentTransactionState->parallelModeLevel != 0;
1070 * CommandCounterIncrement
1072 void
1073 CommandCounterIncrement(void)
1076 * If the current value of the command counter hasn't been "used" to mark
1077 * tuples, we need not increment it, since there's no need to distinguish
1078 * a read-only command from others. This helps postpone command counter
1079 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
1081 if (currentCommandIdUsed)
1084 * Workers synchronize transaction state at the beginning of each
1085 * parallel operation, so we can't account for new commands after that
1086 * point.
1088 if (IsInParallelMode() || IsParallelWorker())
1089 elog(ERROR, "cannot start commands during a parallel operation");
1091 currentCommandId += 1;
1092 if (currentCommandId == InvalidCommandId)
1094 currentCommandId -= 1;
1095 ereport(ERROR,
1096 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1097 errmsg("cannot have more than 2^32-2 commands in a transaction")));
1099 currentCommandIdUsed = false;
1101 /* Propagate new command ID into static snapshots */
1102 SnapshotSetCommandId(currentCommandId);
1105 * Make any catalog changes done by the just-completed command visible
1106 * in the local syscache. We obviously don't need to do this after a
1107 * read-only command. (But see hacks in inval.c to make real sure we
1108 * don't think a command that queued inval messages was read-only.)
1110 AtCCI_LocalCache();
1115 * ForceSyncCommit
1117 * Interface routine to allow commands to force a synchronous commit of the
1118 * current top-level transaction. Currently, two-phase commit does not
1119 * persist and restore this variable. So long as all callers use
1120 * PreventInTransactionBlock(), that omission has no consequences.
1122 void
1123 ForceSyncCommit(void)
1125 forceSyncCommit = true;
1129 /* ----------------------------------------------------------------
1130 * StartTransaction stuff
1131 * ----------------------------------------------------------------
1135 * AtStart_Cache
1137 static void
1138 AtStart_Cache(void)
1140 AcceptInvalidationMessages();
1144 * AtStart_Memory
1146 static void
1147 AtStart_Memory(void)
1149 TransactionState s = CurrentTransactionState;
1152 * If this is the first time through, create a private context for
1153 * AbortTransaction to work in. By reserving some space now, we can
1154 * insulate AbortTransaction from out-of-memory scenarios. Like
1155 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1156 * size, so that space will be reserved immediately.
1158 if (TransactionAbortContext == NULL)
1159 TransactionAbortContext =
1160 AllocSetContextCreate(TopMemoryContext,
1161 "TransactionAbortContext",
1162 32 * 1024,
1163 32 * 1024,
1164 32 * 1024);
1167 * We shouldn't have a transaction context already.
1169 Assert(TopTransactionContext == NULL);
1172 * Create a toplevel context for the transaction.
1174 TopTransactionContext =
1175 AllocSetContextCreate(TopMemoryContext,
1176 "TopTransactionContext",
1177 ALLOCSET_DEFAULT_SIZES);
1180 * In a top-level transaction, CurTransactionContext is the same as
1181 * TopTransactionContext.
1183 CurTransactionContext = TopTransactionContext;
1184 s->curTransactionContext = CurTransactionContext;
1186 /* Make the CurTransactionContext active. */
1187 MemoryContextSwitchTo(CurTransactionContext);
1191 * AtStart_ResourceOwner
1193 static void
1194 AtStart_ResourceOwner(void)
1196 TransactionState s = CurrentTransactionState;
1199 * We shouldn't have a transaction resource owner already.
1201 Assert(TopTransactionResourceOwner == NULL);
1204 * Create a toplevel resource owner for the transaction.
1206 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1208 TopTransactionResourceOwner = s->curTransactionOwner;
1209 CurTransactionResourceOwner = s->curTransactionOwner;
1210 CurrentResourceOwner = s->curTransactionOwner;
1213 /* ----------------------------------------------------------------
1214 * StartSubTransaction stuff
1215 * ----------------------------------------------------------------
1219 * AtSubStart_Memory
1221 static void
1222 AtSubStart_Memory(void)
1224 TransactionState s = CurrentTransactionState;
1226 Assert(CurTransactionContext != NULL);
1229 * Create a CurTransactionContext, which will be used to hold data that
1230 * survives subtransaction commit but disappears on subtransaction abort.
1231 * We make it a child of the immediate parent's CurTransactionContext.
1233 CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
1234 "CurTransactionContext",
1235 ALLOCSET_DEFAULT_SIZES);
1236 s->curTransactionContext = CurTransactionContext;
1238 /* Make the CurTransactionContext active. */
1239 MemoryContextSwitchTo(CurTransactionContext);
1243 * AtSubStart_ResourceOwner
1245 static void
1246 AtSubStart_ResourceOwner(void)
1248 TransactionState s = CurrentTransactionState;
1250 Assert(s->parent != NULL);
1253 * Create a resource owner for the subtransaction. We make it a child of
1254 * the immediate parent's resource owner.
1256 s->curTransactionOwner =
1257 ResourceOwnerCreate(s->parent->curTransactionOwner,
1258 "SubTransaction");
1260 CurTransactionResourceOwner = s->curTransactionOwner;
1261 CurrentResourceOwner = s->curTransactionOwner;
1264 /* ----------------------------------------------------------------
1265 * CommitTransaction stuff
1266 * ----------------------------------------------------------------
1270 * RecordTransactionCommit
1272 * Returns latest XID among xact and its children, or InvalidTransactionId
1273 * if the xact has no XID. (We compute that here just because it's easier.)
1275 * If you change this function, see RecordTransactionCommitPrepared also.
1277 static TransactionId
1278 RecordTransactionCommit(void)
1280 TransactionId xid = GetTopTransactionIdIfAny();
1281 bool markXidCommitted = TransactionIdIsValid(xid);
1282 TransactionId latestXid = InvalidTransactionId;
1283 int nrels;
1284 RelFileNode *rels;
1285 int nchildren;
1286 TransactionId *children;
1287 int nmsgs = 0;
1288 SharedInvalidationMessage *invalMessages = NULL;
1289 bool RelcacheInitFileInval = false;
1290 bool wrote_xlog;
1293 * Log pending invalidations for logical decoding of in-progress
1294 * transactions. Normally for DDLs, we log this at each command end,
1295 * however, for certain cases where we directly update the system table
1296 * without a transaction block, the invalidations are not logged till this
1297 * time.
1299 if (XLogLogicalInfoActive())
1300 LogLogicalInvalidations();
1302 /* Get data needed for commit record */
1303 nrels = smgrGetPendingDeletes(true, &rels);
1304 nchildren = xactGetCommittedChildren(&children);
1305 if (XLogStandbyInfoActive())
1306 nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
1307 &RelcacheInitFileInval);
1308 wrote_xlog = (XactLastRecEnd != 0);
1311 * If we haven't been assigned an XID yet, we neither can, nor do we want
1312 * to write a COMMIT record.
1314 if (!markXidCommitted)
1317 * We expect that every RelationDropStorage is followed by a catalog
1318 * update, and hence XID assignment, so we shouldn't get here with any
1319 * pending deletes. Use a real test not just an Assert to check this,
1320 * since it's a bit fragile.
1322 if (nrels != 0)
1323 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
1325 /* Can't have child XIDs either; AssignTransactionId enforces this */
1326 Assert(nchildren == 0);
1329 * Transactions without an assigned xid can contain invalidation
1330 * messages (e.g. explicit relcache invalidations or catcache
1331 * invalidations for inplace updates); standbys need to process those.
1332 * We can't emit a commit record without an xid, and we don't want to
1333 * force assigning an xid, because that'd be problematic for e.g.
1334 * vacuum. Hence we emit a bespoke record for the invalidations. We
1335 * don't want to use that in case a commit record is emitted, so they
1336 * happen synchronously with commits (besides not wanting to emit more
1337 * WAL records).
1339 if (nmsgs != 0)
1341 LogStandbyInvalidations(nmsgs, invalMessages,
1342 RelcacheInitFileInval);
1343 wrote_xlog = true; /* not strictly necessary */
1347 * If we didn't create XLOG entries, we're done here; otherwise we
1348 * should trigger flushing those entries the same as a commit record
1349 * would. This will primarily happen for HOT pruning and the like; we
1350 * want these to be flushed to disk in due time.
1352 if (!wrote_xlog)
1353 goto cleanup;
1355 else
1357 bool replorigin;
1360 * Are we using the replication origins feature? Or, in other words,
1361 * are we replaying remote actions?
1363 replorigin = (replorigin_session_origin != InvalidRepOriginId &&
1364 replorigin_session_origin != DoNotReplicateId);
1367 * Begin commit critical section and insert the commit XLOG record.
1369 /* Tell bufmgr and smgr to prepare for commit */
1370 BufmgrCommit();
1373 * Mark ourselves as within our "commit critical section". This
1374 * forces any concurrent checkpoint to wait until we've updated
1375 * pg_xact. Without this, it is possible for the checkpoint to set
1376 * REDO after the XLOG record but fail to flush the pg_xact update to
1377 * disk, leading to loss of the transaction commit if the system
1378 * crashes a little later.
1380 * Note: we could, but don't bother to, set this flag in
1381 * RecordTransactionAbort. That's because loss of a transaction abort
1382 * is noncritical; the presumption would be that it aborted, anyway.
1384 * It's safe to change the delayChkpt flag of our own backend without
1385 * holding the ProcArrayLock, since we're the only one modifying it.
1386 * This makes checkpoint's determination of which xacts are delayChkpt
1387 * a bit fuzzy, but it doesn't matter.
1389 START_CRIT_SECTION();
1390 MyProc->delayChkpt = true;
1392 SetCurrentTransactionStopTimestamp();
1394 XactLogCommitRecord(xactStopTimestamp,
1395 nchildren, children, nrels, rels,
1396 nmsgs, invalMessages,
1397 RelcacheInitFileInval,
1398 MyXactFlags,
1399 InvalidTransactionId, NULL /* plain commit */ );
1401 if (replorigin)
1402 /* Move LSNs forward for this replication origin */
1403 replorigin_session_advance(replorigin_session_origin_lsn,
1404 XactLastRecEnd);
1407 * Record commit timestamp. The value comes from plain commit
1408 * timestamp if there's no replication origin; otherwise, the
1409 * timestamp was already set in replorigin_session_origin_timestamp by
1410 * replication.
1412 * We don't need to WAL-log anything here, as the commit record
1413 * written above already contains the data.
1416 if (!replorigin || replorigin_session_origin_timestamp == 0)
1417 replorigin_session_origin_timestamp = xactStopTimestamp;
1419 TransactionTreeSetCommitTsData(xid, nchildren, children,
1420 replorigin_session_origin_timestamp,
1421 replorigin_session_origin);
1425 * Check if we want to commit asynchronously. We can allow the XLOG flush
1426 * to happen asynchronously if synchronous_commit=off, or if the current
1427 * transaction has not performed any WAL-logged operation or didn't assign
1428 * an xid. The transaction can end up not writing any WAL, even if it has
1429 * an xid, if it only wrote to temporary and/or unlogged tables. It can
1430 * end up having written WAL without an xid if it did HOT pruning. In
1431 * case of a crash, the loss of such a transaction will be irrelevant;
1432 * temp tables will be lost anyway, unlogged tables will be truncated and
1433 * HOT pruning will be done again later. (Given the foregoing, you might
1434 * think that it would be unnecessary to emit the XLOG record at all in
1435 * this case, but we don't currently try to do that. It would certainly
1436 * cause problems at least in Hot Standby mode, where the
1437 * KnownAssignedXids machinery requires tracking every XID assignment. It
1438 * might be OK to skip it only when wal_level < replica, but for now we
1439 * don't.)
1441 * However, if we're doing cleanup of any non-temp rels or committing any
1442 * command that wanted to force sync commit, then we must flush XLOG
1443 * immediately. (We must not allow asynchronous commit if there are any
1444 * non-temp tables to be deleted, because we might delete the files before
1445 * the COMMIT record is flushed to disk. We do allow asynchronous commit
1446 * if all to-be-deleted tables are temporary though, since they are lost
1447 * anyway if we crash.)
1449 if ((wrote_xlog && markXidCommitted &&
1450 synchronous_commit > SYNCHRONOUS_COMMIT_OFF) ||
1451 forceSyncCommit || nrels > 0)
1453 XLogFlush(XactLastRecEnd);
1456 * Now we may update the CLOG, if we wrote a COMMIT record above
1458 if (markXidCommitted)
1459 TransactionIdCommitTree(xid, nchildren, children);
1461 else
1464 * Asynchronous commit case:
1466 * This enables possible committed transaction loss in the case of a
1467 * postmaster crash because WAL buffers are left unwritten. Ideally we
1468 * could issue the WAL write without the fsync, but some
1469 * wal_sync_methods do not allow separate write/fsync.
1471 * Report the latest async commit LSN, so that the WAL writer knows to
1472 * flush this commit.
1474 XLogSetAsyncXactLSN(XactLastRecEnd);
1477 * We must not immediately update the CLOG, since we didn't flush the
1478 * XLOG. Instead, we store the LSN up to which the XLOG must be
1479 * flushed before the CLOG may be updated.
1481 if (markXidCommitted)
1482 TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1486 * If we entered a commit critical section, leave it now, and let
1487 * checkpoints proceed.
1489 if (markXidCommitted)
1491 MyProc->delayChkpt = false;
1492 END_CRIT_SECTION();
1495 /* Compute latestXid while we have the child XIDs handy */
1496 latestXid = TransactionIdLatest(xid, nchildren, children);
1499 * Wait for synchronous replication, if required. Similar to the decision
1500 * above about using committing asynchronously we only want to wait if
1501 * this backend assigned an xid and wrote WAL. No need to wait if an xid
1502 * was assigned due to temporary/unlogged tables or due to HOT pruning.
1504 * Note that at this stage we have marked clog, but still show as running
1505 * in the procarray and continue to hold locks.
1507 if (wrote_xlog && markXidCommitted)
1508 SyncRepWaitForLSN(XactLastRecEnd, true);
1510 /* remember end of last commit record */
1511 XactLastCommitEnd = XactLastRecEnd;
1513 /* Reset XactLastRecEnd until the next transaction writes something */
1514 XactLastRecEnd = 0;
1515 cleanup:
1516 /* Clean up local data */
1517 if (rels)
1518 pfree(rels);
1520 return latestXid;
1525 * AtCCI_LocalCache
1527 static void
1528 AtCCI_LocalCache(void)
1531 * Make any pending relation map changes visible. We must do this before
1532 * processing local sinval messages, so that the map changes will get
1533 * reflected into the relcache when relcache invals are processed.
1535 AtCCI_RelationMap();
1538 * Make catalog changes visible to me for the next command.
1540 CommandEndInvalidationMessages();
1544 * AtCommit_Memory
1546 static void
1547 AtCommit_Memory(void)
1550 * Now that we're "out" of a transaction, have the system allocate things
1551 * in the top memory context instead of per-transaction contexts.
1553 MemoryContextSwitchTo(TopMemoryContext);
1556 * Release all transaction-local memory.
1558 Assert(TopTransactionContext != NULL);
1559 MemoryContextDelete(TopTransactionContext);
1560 TopTransactionContext = NULL;
1561 CurTransactionContext = NULL;
1562 CurrentTransactionState->curTransactionContext = NULL;
1565 /* ----------------------------------------------------------------
1566 * CommitSubTransaction stuff
1567 * ----------------------------------------------------------------
1571 * AtSubCommit_Memory
1573 static void
1574 AtSubCommit_Memory(void)
1576 TransactionState s = CurrentTransactionState;
1578 Assert(s->parent != NULL);
1580 /* Return to parent transaction level's memory context. */
1581 CurTransactionContext = s->parent->curTransactionContext;
1582 MemoryContextSwitchTo(CurTransactionContext);
1585 * Ordinarily we cannot throw away the child's CurTransactionContext,
1586 * since the data it contains will be needed at upper commit. However, if
1587 * there isn't actually anything in it, we can throw it away. This avoids
1588 * a small memory leak in the common case of "trivial" subxacts.
1590 if (MemoryContextIsEmpty(s->curTransactionContext))
1592 MemoryContextDelete(s->curTransactionContext);
1593 s->curTransactionContext = NULL;
1598 * AtSubCommit_childXids
1600 * Pass my own XID and my child XIDs up to my parent as committed children.
1602 static void
1603 AtSubCommit_childXids(void)
1605 TransactionState s = CurrentTransactionState;
1606 int new_nChildXids;
1608 Assert(s->parent != NULL);
1611 * The parent childXids array will need to hold my XID and all my
1612 * childXids, in addition to the XIDs already there.
1614 new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1616 /* Allocate or enlarge the parent array if necessary */
1617 if (s->parent->maxChildXids < new_nChildXids)
1619 int new_maxChildXids;
1620 TransactionId *new_childXids;
1623 * Make it 2x what's needed right now, to avoid having to enlarge it
1624 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1625 * is what ensures that we don't need to worry about integer overflow
1626 * here or in the calculation of new_nChildXids.)
1628 new_maxChildXids = Min(new_nChildXids * 2,
1629 (int) (MaxAllocSize / sizeof(TransactionId)));
1631 if (new_maxChildXids < new_nChildXids)
1632 ereport(ERROR,
1633 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1634 errmsg("maximum number of committed subtransactions (%d) exceeded",
1635 (int) (MaxAllocSize / sizeof(TransactionId)))));
1638 * We keep the child-XID arrays in TopTransactionContext; this avoids
1639 * setting up child-transaction contexts for what might be just a few
1640 * bytes of grandchild XIDs.
1642 if (s->parent->childXids == NULL)
1643 new_childXids =
1644 MemoryContextAlloc(TopTransactionContext,
1645 new_maxChildXids * sizeof(TransactionId));
1646 else
1647 new_childXids = repalloc(s->parent->childXids,
1648 new_maxChildXids * sizeof(TransactionId));
1650 s->parent->childXids = new_childXids;
1651 s->parent->maxChildXids = new_maxChildXids;
1655 * Copy all my XIDs to parent's array.
1657 * Note: We rely on the fact that the XID of a child always follows that
1658 * of its parent. By copying the XID of this subtransaction before the
1659 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1660 * all XIDs already in the array belong to subtransactions started and
1661 * subcommitted before us, so their XIDs must precede ours.
1663 s->parent->childXids[s->parent->nChildXids] = XidFromFullTransactionId(s->fullTransactionId);
1665 if (s->nChildXids > 0)
1666 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1667 s->childXids,
1668 s->nChildXids * sizeof(TransactionId));
1670 s->parent->nChildXids = new_nChildXids;
1672 /* Release child's array to avoid leakage */
1673 if (s->childXids != NULL)
1674 pfree(s->childXids);
1675 /* We must reset these to avoid double-free if fail later in commit */
1676 s->childXids = NULL;
1677 s->nChildXids = 0;
1678 s->maxChildXids = 0;
1681 /* ----------------------------------------------------------------
1682 * AbortTransaction stuff
1683 * ----------------------------------------------------------------
1687 * RecordTransactionAbort
1689 * Returns latest XID among xact and its children, or InvalidTransactionId
1690 * if the xact has no XID. (We compute that here just because it's easier.)
1692 static TransactionId
1693 RecordTransactionAbort(bool isSubXact)
1695 TransactionId xid = GetCurrentTransactionIdIfAny();
1696 TransactionId latestXid;
1697 int nrels;
1698 RelFileNode *rels;
1699 int nchildren;
1700 TransactionId *children;
1701 TimestampTz xact_time;
1704 * If we haven't been assigned an XID, nobody will care whether we aborted
1705 * or not. Hence, we're done in that case. It does not matter if we have
1706 * rels to delete (note that this routine is not responsible for actually
1707 * deleting 'em). We cannot have any child XIDs, either.
1709 if (!TransactionIdIsValid(xid))
1711 /* Reset XactLastRecEnd until the next transaction writes something */
1712 if (!isSubXact)
1713 XactLastRecEnd = 0;
1714 return InvalidTransactionId;
1718 * We have a valid XID, so we should write an ABORT record for it.
1720 * We do not flush XLOG to disk here, since the default assumption after a
1721 * crash would be that we aborted, anyway. For the same reason, we don't
1722 * need to worry about interlocking against checkpoint start.
1726 * Check that we haven't aborted halfway through RecordTransactionCommit.
1728 if (TransactionIdDidCommit(xid))
1729 elog(PANIC, "cannot abort transaction %u, it was already committed",
1730 xid);
1732 /* Fetch the data we need for the abort record */
1733 nrels = smgrGetPendingDeletes(false, &rels);
1734 nchildren = xactGetCommittedChildren(&children);
1736 /* XXX do we really need a critical section here? */
1737 START_CRIT_SECTION();
1739 /* Write the ABORT record */
1740 if (isSubXact)
1741 xact_time = GetCurrentTimestamp();
1742 else
1744 SetCurrentTransactionStopTimestamp();
1745 xact_time = xactStopTimestamp;
1748 XactLogAbortRecord(xact_time,
1749 nchildren, children,
1750 nrels, rels,
1751 MyXactFlags, InvalidTransactionId,
1752 NULL);
1755 * Report the latest async abort LSN, so that the WAL writer knows to
1756 * flush this abort. There's nothing to be gained by delaying this, since
1757 * WALWriter may as well do this when it can. This is important with
1758 * streaming replication because if we don't flush WAL regularly we will
1759 * find that large aborts leave us with a long backlog for when commits
1760 * occur after the abort, increasing our window of data loss should
1761 * problems occur at that point.
1763 if (!isSubXact)
1764 XLogSetAsyncXactLSN(XactLastRecEnd);
1767 * Mark the transaction aborted in clog. This is not absolutely necessary
1768 * but we may as well do it while we are here; also, in the subxact case
1769 * it is helpful because XactLockTableWait makes use of it to avoid
1770 * waiting for already-aborted subtransactions. It is OK to do it without
1771 * having flushed the ABORT record to disk, because in event of a crash
1772 * we'd be assumed to have aborted anyway.
1774 TransactionIdAbortTree(xid, nchildren, children);
1776 END_CRIT_SECTION();
1778 /* Compute latestXid while we have the child XIDs handy */
1779 latestXid = TransactionIdLatest(xid, nchildren, children);
1782 * If we're aborting a subtransaction, we can immediately remove failed
1783 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1784 * subxacts, because we already have the child XID array at hand. For
1785 * main xacts, the equivalent happens just after this function returns.
1787 if (isSubXact)
1788 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1790 /* Reset XactLastRecEnd until the next transaction writes something */
1791 if (!isSubXact)
1792 XactLastRecEnd = 0;
1794 /* And clean up local data */
1795 if (rels)
1796 pfree(rels);
1798 return latestXid;
1802 * AtAbort_Memory
1804 static void
1805 AtAbort_Memory(void)
1808 * Switch into TransactionAbortContext, which should have some free space
1809 * even if nothing else does. We'll work in this context until we've
1810 * finished cleaning up.
1812 * It is barely possible to get here when we've not been able to create
1813 * TransactionAbortContext yet; if so use TopMemoryContext.
1815 if (TransactionAbortContext != NULL)
1816 MemoryContextSwitchTo(TransactionAbortContext);
1817 else
1818 MemoryContextSwitchTo(TopMemoryContext);
1822 * AtSubAbort_Memory
1824 static void
1825 AtSubAbort_Memory(void)
1827 Assert(TransactionAbortContext != NULL);
1829 MemoryContextSwitchTo(TransactionAbortContext);
1834 * AtAbort_ResourceOwner
1836 static void
1837 AtAbort_ResourceOwner(void)
1840 * Make sure we have a valid ResourceOwner, if possible (else it will be
1841 * NULL, which is OK)
1843 CurrentResourceOwner = TopTransactionResourceOwner;
1847 * AtSubAbort_ResourceOwner
1849 static void
1850 AtSubAbort_ResourceOwner(void)
1852 TransactionState s = CurrentTransactionState;
1854 /* Make sure we have a valid ResourceOwner */
1855 CurrentResourceOwner = s->curTransactionOwner;
1860 * AtSubAbort_childXids
1862 static void
1863 AtSubAbort_childXids(void)
1865 TransactionState s = CurrentTransactionState;
1868 * We keep the child-XID arrays in TopTransactionContext (see
1869 * AtSubCommit_childXids). This means we'd better free the array
1870 * explicitly at abort to avoid leakage.
1872 if (s->childXids != NULL)
1873 pfree(s->childXids);
1874 s->childXids = NULL;
1875 s->nChildXids = 0;
1876 s->maxChildXids = 0;
1879 * We could prune the unreportedXids array here. But we don't bother. That
1880 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1881 * would likely introduce more CPU time into the more common paths, so we
1882 * choose not to do that.
1886 /* ----------------------------------------------------------------
1887 * CleanupTransaction stuff
1888 * ----------------------------------------------------------------
1892 * AtCleanup_Memory
1894 static void
1895 AtCleanup_Memory(void)
1897 Assert(CurrentTransactionState->parent == NULL);
1900 * Now that we're "out" of a transaction, have the system allocate things
1901 * in the top memory context instead of per-transaction contexts.
1903 MemoryContextSwitchTo(TopMemoryContext);
1906 * Clear the special abort context for next time.
1908 if (TransactionAbortContext != NULL)
1909 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1912 * Release all transaction-local memory.
1914 if (TopTransactionContext != NULL)
1915 MemoryContextDelete(TopTransactionContext);
1916 TopTransactionContext = NULL;
1917 CurTransactionContext = NULL;
1918 CurrentTransactionState->curTransactionContext = NULL;
1922 /* ----------------------------------------------------------------
1923 * CleanupSubTransaction stuff
1924 * ----------------------------------------------------------------
1928 * AtSubCleanup_Memory
1930 static void
1931 AtSubCleanup_Memory(void)
1933 TransactionState s = CurrentTransactionState;
1935 Assert(s->parent != NULL);
1937 /* Make sure we're not in an about-to-be-deleted context */
1938 MemoryContextSwitchTo(s->parent->curTransactionContext);
1939 CurTransactionContext = s->parent->curTransactionContext;
1942 * Clear the special abort context for next time.
1944 if (TransactionAbortContext != NULL)
1945 MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1948 * Delete the subxact local memory contexts. Its CurTransactionContext can
1949 * go too (note this also kills CurTransactionContexts from any children
1950 * of the subxact).
1952 if (s->curTransactionContext)
1953 MemoryContextDelete(s->curTransactionContext);
1954 s->curTransactionContext = NULL;
1957 /* ----------------------------------------------------------------
1958 * interface routines
1959 * ----------------------------------------------------------------
1963 * StartTransaction
1965 static void
1966 StartTransaction(void)
1968 TransactionState s;
1969 VirtualTransactionId vxid;
1972 * Let's just make sure the state stack is empty
1974 s = &TopTransactionStateData;
1975 CurrentTransactionState = s;
1977 Assert(!FullTransactionIdIsValid(XactTopFullTransactionId));
1979 /* check the current transaction state */
1980 Assert(s->state == TRANS_DEFAULT);
1983 * Set the current transaction state information appropriately during
1984 * start processing. Note that once the transaction status is switched
1985 * this process cannot fail until the user ID and the security context
1986 * flags are fetched below.
1988 s->state = TRANS_START;
1989 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
1991 /* Determine if statements are logged in this transaction */
1992 xact_is_sampled = log_xact_sample_rate != 0 &&
1993 (log_xact_sample_rate == 1 ||
1994 pg_prng_double(&pg_global_prng_state) <= log_xact_sample_rate);
1997 * initialize current transaction state fields
1999 * note: prevXactReadOnly is not used at the outermost level
2001 s->nestingLevel = 1;
2002 s->gucNestLevel = 1;
2003 s->childXids = NULL;
2004 s->nChildXids = 0;
2005 s->maxChildXids = 0;
2008 * Once the current user ID and the security context flags are fetched,
2009 * both will be properly reset even if transaction startup fails.
2011 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
2013 /* SecurityRestrictionContext should never be set outside a transaction */
2014 Assert(s->prevSecContext == 0);
2017 * Make sure we've reset xact state variables
2019 * If recovery is still in progress, mark this transaction as read-only.
2020 * We have lower level defences in XLogInsert and elsewhere to stop us
2021 * from modifying data during recovery, but this gives the normal
2022 * indication to the user that the transaction is read-only.
2024 if (RecoveryInProgress())
2026 s->startedInRecovery = true;
2027 XactReadOnly = true;
2029 else
2031 s->startedInRecovery = false;
2032 XactReadOnly = DefaultXactReadOnly;
2034 XactDeferrable = DefaultXactDeferrable;
2035 XactIsoLevel = DefaultXactIsoLevel;
2036 forceSyncCommit = false;
2037 MyXactFlags = 0;
2040 * reinitialize within-transaction counters
2042 s->subTransactionId = TopSubTransactionId;
2043 currentSubTransactionId = TopSubTransactionId;
2044 currentCommandId = FirstCommandId;
2045 currentCommandIdUsed = false;
2048 * initialize reported xid accounting
2050 nUnreportedXids = 0;
2051 s->didLogXid = false;
2054 * must initialize resource-management stuff first
2056 AtStart_Memory();
2057 AtStart_ResourceOwner();
2060 * Assign a new LocalTransactionId, and combine it with the backendId to
2061 * form a virtual transaction id.
2063 vxid.backendId = MyBackendId;
2064 vxid.localTransactionId = GetNextLocalTransactionId();
2067 * Lock the virtual transaction id before we announce it in the proc array
2069 VirtualXactLockTableInsert(vxid);
2072 * Advertise it in the proc array. We assume assignment of
2073 * localTransactionId is atomic, and the backendId should be set already.
2075 Assert(MyProc->backendId == vxid.backendId);
2076 MyProc->lxid = vxid.localTransactionId;
2078 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
2081 * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2082 * be the same as the first command's statement_timestamp(), so don't do a
2083 * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2084 * for transactions started inside procedures (i.e., nonatomic SPI
2085 * contexts), we do need to advance the timestamp. Also, in a parallel
2086 * worker, the timestamp should already have been provided by a call to
2087 * SetParallelStartTimestamps().
2089 if (!IsParallelWorker())
2091 if (!SPI_inside_nonatomic_context())
2092 xactStartTimestamp = stmtStartTimestamp;
2093 else
2094 xactStartTimestamp = GetCurrentTimestamp();
2096 else
2097 Assert(xactStartTimestamp != 0);
2098 pgstat_report_xact_timestamp(xactStartTimestamp);
2099 /* Mark xactStopTimestamp as unset. */
2100 xactStopTimestamp = 0;
2103 * initialize other subsystems for new transaction
2105 AtStart_GUC();
2106 AtStart_Cache();
2107 AfterTriggerBeginXact();
2110 * done with start processing, set current transaction state to "in
2111 * progress"
2113 s->state = TRANS_INPROGRESS;
2115 ShowTransactionState("StartTransaction");
2120 * CommitTransaction
2122 * NB: if you change this routine, better look at PrepareTransaction too!
2124 static void
2125 CommitTransaction(void)
2127 TransactionState s = CurrentTransactionState;
2128 TransactionId latestXid;
2129 bool is_parallel_worker;
2131 is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2133 /* Enforce parallel mode restrictions during parallel worker commit. */
2134 if (is_parallel_worker)
2135 EnterParallelMode();
2137 ShowTransactionState("CommitTransaction");
2140 * check the current transaction state
2142 if (s->state != TRANS_INPROGRESS)
2143 elog(WARNING, "CommitTransaction while in %s state",
2144 TransStateAsString(s->state));
2145 Assert(s->parent == NULL);
2148 * Do pre-commit processing that involves calling user-defined code, such
2149 * as triggers. SECURITY_RESTRICTED_OPERATION contexts must not queue an
2150 * action that would run here, because that would bypass the sandbox.
2151 * Since closing cursors could queue trigger actions, triggers could open
2152 * cursors, etc, we have to keep looping until there's nothing left to do.
2154 for (;;)
2157 * Fire all currently pending deferred triggers.
2159 AfterTriggerFireDeferred();
2162 * Close open portals (converting holdable ones into static portals).
2163 * If there weren't any, we are done ... otherwise loop back to check
2164 * if they queued deferred triggers. Lather, rinse, repeat.
2166 if (!PreCommit_Portals(false))
2167 break;
2171 * The remaining actions cannot call any user-defined code, so it's safe
2172 * to start shutting down within-transaction services. But note that most
2173 * of this stuff could still throw an error, which would switch us into
2174 * the transaction-abort path.
2177 CallXactCallbacks(is_parallel_worker ? XACT_EVENT_PARALLEL_PRE_COMMIT
2178 : XACT_EVENT_PRE_COMMIT);
2180 /* If we might have parallel workers, clean them up now. */
2181 if (IsInParallelMode())
2182 AtEOXact_Parallel(true);
2184 /* Shut down the deferred-trigger manager */
2185 AfterTriggerEndXact(true);
2188 * Let ON COMMIT management do its thing (must happen after closing
2189 * cursors, to avoid dangling-reference problems)
2191 PreCommit_on_commit_actions();
2194 * Synchronize files that are created and not WAL-logged during this
2195 * transaction. This must happen before AtEOXact_RelationMap(), so that we
2196 * don't see committed-but-broken files after a crash.
2198 smgrDoPendingSyncs(true, is_parallel_worker);
2200 /* close large objects before lower-level cleanup */
2201 AtEOXact_LargeObject(true);
2204 * Insert notifications sent by NOTIFY commands into the queue. This
2205 * should be late in the pre-commit sequence to minimize time spent
2206 * holding the notify-insertion lock. However, this could result in
2207 * creating a snapshot, so we must do it before serializable cleanup.
2209 PreCommit_Notify();
2212 * Mark serializable transaction as complete for predicate locking
2213 * purposes. This should be done as late as we can put it and still allow
2214 * errors to be raised for failure patterns found at commit. This is not
2215 * appropriate in a parallel worker however, because we aren't committing
2216 * the leader's transaction and its serializable state will live on.
2218 if (!is_parallel_worker)
2219 PreCommit_CheckForSerializationFailure();
2221 /* Prevent cancel/die interrupt while cleaning up */
2222 HOLD_INTERRUPTS();
2224 /* Commit updates to the relation map --- do this as late as possible */
2225 AtEOXact_RelationMap(true, is_parallel_worker);
2228 * set the current transaction state information appropriately during
2229 * commit processing
2231 s->state = TRANS_COMMIT;
2232 s->parallelModeLevel = 0;
2234 if (!is_parallel_worker)
2237 * We need to mark our XIDs as committed in pg_xact. This is where we
2238 * durably commit.
2240 latestXid = RecordTransactionCommit();
2242 else
2245 * We must not mark our XID committed; the parallel leader is
2246 * responsible for that.
2248 latestXid = InvalidTransactionId;
2251 * Make sure the leader will know about any WAL we wrote before it
2252 * commits.
2254 ParallelWorkerReportLastRecEnd(XactLastRecEnd);
2257 TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
2260 * Let others know about no transaction in progress by me. Note that this
2261 * must be done _before_ releasing locks we hold and _after_
2262 * RecordTransactionCommit.
2264 ProcArrayEndTransaction(MyProc, latestXid);
2267 * This is all post-commit cleanup. Note that if an error is raised here,
2268 * it's too late to abort the transaction. This should be just
2269 * noncritical resource releasing.
2271 * The ordering of operations is not entirely random. The idea is:
2272 * release resources visible to other backends (eg, files, buffer pins);
2273 * then release locks; then release backend-local resources. We want to
2274 * release locks at the point where any backend waiting for us will see
2275 * our transaction as being fully cleaned up.
2277 * Resources that can be associated with individual queries are handled by
2278 * the ResourceOwner mechanism. The other calls here are for backend-wide
2279 * state.
2282 CallXactCallbacks(is_parallel_worker ? XACT_EVENT_PARALLEL_COMMIT
2283 : XACT_EVENT_COMMIT);
2285 ResourceOwnerRelease(TopTransactionResourceOwner,
2286 RESOURCE_RELEASE_BEFORE_LOCKS,
2287 true, true);
2289 /* Check we've released all buffer pins */
2290 AtEOXact_Buffers(true);
2292 /* Clean up the relation cache */
2293 AtEOXact_RelationCache(true);
2296 * Make catalog changes visible to all backends. This has to happen after
2297 * relcache references are dropped (see comments for
2298 * AtEOXact_RelationCache), but before locks are released (if anyone is
2299 * waiting for lock on a relation we've modified, we want them to know
2300 * about the catalog change before they start using the relation).
2302 AtEOXact_Inval(true);
2304 AtEOXact_MultiXact();
2306 ResourceOwnerRelease(TopTransactionResourceOwner,
2307 RESOURCE_RELEASE_LOCKS,
2308 true, true);
2309 ResourceOwnerRelease(TopTransactionResourceOwner,
2310 RESOURCE_RELEASE_AFTER_LOCKS,
2311 true, true);
2314 * Likewise, dropping of files deleted during the transaction is best done
2315 * after releasing relcache and buffer pins. (This is not strictly
2316 * necessary during commit, since such pins should have been released
2317 * already, but this ordering is definitely critical during abort.) Since
2318 * this may take many seconds, also delay until after releasing locks.
2319 * Other backends will observe the attendant catalog changes and not
2320 * attempt to access affected files.
2322 smgrDoPendingDeletes(true);
2325 * Send out notification signals to other backends (and do other
2326 * post-commit NOTIFY cleanup). This must not happen until after our
2327 * transaction is fully done from the viewpoint of other backends.
2329 AtCommit_Notify();
2332 * Everything after this should be purely internal-to-this-backend
2333 * cleanup.
2335 AtEOXact_GUC(true, 1);
2336 AtEOXact_SPI(true);
2337 AtEOXact_Enum();
2338 AtEOXact_on_commit_actions(true);
2339 AtEOXact_Namespace(true, is_parallel_worker);
2340 AtEOXact_SMgr();
2341 AtEOXact_Files(true);
2342 AtEOXact_ComboCid();
2343 AtEOXact_HashTables(true);
2344 AtEOXact_PgStat(true, is_parallel_worker);
2345 AtEOXact_Snapshot(true, false);
2346 AtEOXact_ApplyLauncher(true);
2347 pgstat_report_xact_timestamp(0);
2349 CurrentResourceOwner = NULL;
2350 ResourceOwnerDelete(TopTransactionResourceOwner);
2351 s->curTransactionOwner = NULL;
2352 CurTransactionResourceOwner = NULL;
2353 TopTransactionResourceOwner = NULL;
2355 AtCommit_Memory();
2357 s->fullTransactionId = InvalidFullTransactionId;
2358 s->subTransactionId = InvalidSubTransactionId;
2359 s->nestingLevel = 0;
2360 s->gucNestLevel = 0;
2361 s->childXids = NULL;
2362 s->nChildXids = 0;
2363 s->maxChildXids = 0;
2365 XactTopFullTransactionId = InvalidFullTransactionId;
2366 nParallelCurrentXids = 0;
2369 * done with commit processing, set current transaction state back to
2370 * default
2372 s->state = TRANS_DEFAULT;
2374 RESUME_INTERRUPTS();
2379 * PrepareTransaction
2381 * NB: if you change this routine, better look at CommitTransaction too!
2383 static void
2384 PrepareTransaction(void)
2386 TransactionState s = CurrentTransactionState;
2387 TransactionId xid = GetCurrentTransactionId();
2388 GlobalTransaction gxact;
2389 TimestampTz prepared_at;
2391 Assert(!IsInParallelMode());
2393 ShowTransactionState("PrepareTransaction");
2396 * check the current transaction state
2398 if (s->state != TRANS_INPROGRESS)
2399 elog(WARNING, "PrepareTransaction while in %s state",
2400 TransStateAsString(s->state));
2401 Assert(s->parent == NULL);
2404 * Do pre-commit processing that involves calling user-defined code, such
2405 * as triggers. Since closing cursors could queue trigger actions,
2406 * triggers could open cursors, etc, we have to keep looping until there's
2407 * nothing left to do.
2409 for (;;)
2412 * Fire all currently pending deferred triggers.
2414 AfterTriggerFireDeferred();
2417 * Close open portals (converting holdable ones into static portals).
2418 * If there weren't any, we are done ... otherwise loop back to check
2419 * if they queued deferred triggers. Lather, rinse, repeat.
2421 if (!PreCommit_Portals(true))
2422 break;
2425 CallXactCallbacks(XACT_EVENT_PRE_PREPARE);
2428 * The remaining actions cannot call any user-defined code, so it's safe
2429 * to start shutting down within-transaction services. But note that most
2430 * of this stuff could still throw an error, which would switch us into
2431 * the transaction-abort path.
2434 /* Shut down the deferred-trigger manager */
2435 AfterTriggerEndXact(true);
2438 * Let ON COMMIT management do its thing (must happen after closing
2439 * cursors, to avoid dangling-reference problems)
2441 PreCommit_on_commit_actions();
2444 * Synchronize files that are created and not WAL-logged during this
2445 * transaction. This must happen before EndPrepare(), so that we don't see
2446 * committed-but-broken files after a crash and COMMIT PREPARED.
2448 smgrDoPendingSyncs(true, false);
2450 /* close large objects before lower-level cleanup */
2451 AtEOXact_LargeObject(true);
2453 /* NOTIFY requires no work at this point */
2456 * Mark serializable transaction as complete for predicate locking
2457 * purposes. This should be done as late as we can put it and still allow
2458 * errors to be raised for failure patterns found at commit.
2460 PreCommit_CheckForSerializationFailure();
2463 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2464 * this transaction. Having the prepared xact hold locks on another
2465 * backend's temp table seems a bad idea --- for instance it would prevent
2466 * the backend from exiting. There are other problems too, such as how to
2467 * clean up the source backend's local buffers and ON COMMIT state if the
2468 * prepared xact includes a DROP of a temp table.
2470 * Other objects types, like functions, operators or extensions, share the
2471 * same restriction as they should not be created, locked or dropped as
2472 * this can mess up with this session or even a follow-up session trying
2473 * to use the same temporary namespace.
2475 * We must check this after executing any ON COMMIT actions, because they
2476 * might still access a temp relation.
2478 * XXX In principle this could be relaxed to allow some useful special
2479 * cases, such as a temp table created and dropped all within the
2480 * transaction. That seems to require much more bookkeeping though.
2482 if ((MyXactFlags & XACT_FLAGS_ACCESSEDTEMPNAMESPACE))
2483 ereport(ERROR,
2484 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2485 errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2488 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2489 * supported if we added cleanup logic to twophase.c, but for now it
2490 * doesn't seem worth the trouble.
2492 if (XactHasExportedSnapshots())
2493 ereport(ERROR,
2494 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2495 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2497 /* Prevent cancel/die interrupt while cleaning up */
2498 HOLD_INTERRUPTS();
2501 * set the current transaction state information appropriately during
2502 * prepare processing
2504 s->state = TRANS_PREPARE;
2506 prepared_at = GetCurrentTimestamp();
2508 /* Tell bufmgr and smgr to prepare for commit */
2509 BufmgrCommit();
2512 * Reserve the GID for this transaction. This could fail if the requested
2513 * GID is invalid or already in use.
2515 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
2516 GetUserId(), MyDatabaseId);
2517 prepareGID = NULL;
2520 * Collect data for the 2PC state file. Note that in general, no actual
2521 * state change should happen in the called modules during this step,
2522 * since it's still possible to fail before commit, and in that case we
2523 * want transaction abort to be able to clean up. (In particular, the
2524 * AtPrepare routines may error out if they find cases they cannot
2525 * handle.) State cleanup should happen in the PostPrepare routines
2526 * below. However, some modules can go ahead and clear state here because
2527 * they wouldn't do anything with it during abort anyway.
2529 * Note: because the 2PC state file records will be replayed in the same
2530 * order they are made, the order of these calls has to match the order in
2531 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2532 * PREPARED; in particular, pay attention to whether things should happen
2533 * before or after releasing the transaction's locks.
2535 StartPrepare(gxact);
2537 AtPrepare_Notify();
2538 AtPrepare_Locks();
2539 AtPrepare_PredicateLocks();
2540 AtPrepare_PgStat();
2541 AtPrepare_MultiXact();
2542 AtPrepare_RelationMap();
2545 * Here is where we really truly prepare.
2547 * We have to record transaction prepares even if we didn't make any
2548 * updates, because the transaction manager might get confused if we lose
2549 * a global transaction.
2551 EndPrepare(gxact);
2554 * Now we clean up backend-internal state and release internal resources.
2557 /* Reset XactLastRecEnd until the next transaction writes something */
2558 XactLastRecEnd = 0;
2561 * Transfer our locks to a dummy PGPROC. This has to be done before
2562 * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2563 * conclude "xact already committed or aborted" for our locks.
2565 PostPrepare_Locks(xid);
2568 * Let others know about no transaction in progress by me. This has to be
2569 * done *after* the prepared transaction has been marked valid, else
2570 * someone may think it is unlocked and recyclable.
2572 ProcArrayClearTransaction(MyProc);
2575 * In normal commit-processing, this is all non-critical post-transaction
2576 * cleanup. When the transaction is prepared, however, it's important
2577 * that the locks and other per-backend resources are transferred to the
2578 * prepared transaction's PGPROC entry. Note that if an error is raised
2579 * here, it's too late to abort the transaction. XXX: This probably should
2580 * be in a critical section, to force a PANIC if any of this fails, but
2581 * that cure could be worse than the disease.
2584 CallXactCallbacks(XACT_EVENT_PREPARE);
2586 ResourceOwnerRelease(TopTransactionResourceOwner,
2587 RESOURCE_RELEASE_BEFORE_LOCKS,
2588 true, true);
2590 /* Check we've released all buffer pins */
2591 AtEOXact_Buffers(true);
2593 /* Clean up the relation cache */
2594 AtEOXact_RelationCache(true);
2596 /* notify doesn't need a postprepare call */
2598 PostPrepare_PgStat();
2600 PostPrepare_Inval();
2602 PostPrepare_smgr();
2604 PostPrepare_MultiXact(xid);
2606 PostPrepare_PredicateLocks(xid);
2608 ResourceOwnerRelease(TopTransactionResourceOwner,
2609 RESOURCE_RELEASE_LOCKS,
2610 true, true);
2611 ResourceOwnerRelease(TopTransactionResourceOwner,
2612 RESOURCE_RELEASE_AFTER_LOCKS,
2613 true, true);
2616 * Allow another backend to finish the transaction. After
2617 * PostPrepare_Twophase(), the transaction is completely detached from our
2618 * backend. The rest is just non-critical cleanup of backend-local state.
2620 PostPrepare_Twophase();
2622 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2623 AtEOXact_GUC(true, 1);
2624 AtEOXact_SPI(true);
2625 AtEOXact_Enum();
2626 AtEOXact_on_commit_actions(true);
2627 AtEOXact_Namespace(true, false);
2628 AtEOXact_SMgr();
2629 AtEOXact_Files(true);
2630 AtEOXact_ComboCid();
2631 AtEOXact_HashTables(true);
2632 /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2633 AtEOXact_Snapshot(true, true);
2634 pgstat_report_xact_timestamp(0);
2636 CurrentResourceOwner = NULL;
2637 ResourceOwnerDelete(TopTransactionResourceOwner);
2638 s->curTransactionOwner = NULL;
2639 CurTransactionResourceOwner = NULL;
2640 TopTransactionResourceOwner = NULL;
2642 AtCommit_Memory();
2644 s->fullTransactionId = InvalidFullTransactionId;
2645 s->subTransactionId = InvalidSubTransactionId;
2646 s->nestingLevel = 0;
2647 s->gucNestLevel = 0;
2648 s->childXids = NULL;
2649 s->nChildXids = 0;
2650 s->maxChildXids = 0;
2652 XactTopFullTransactionId = InvalidFullTransactionId;
2653 nParallelCurrentXids = 0;
2656 * done with 1st phase commit processing, set current transaction state
2657 * back to default
2659 s->state = TRANS_DEFAULT;
2661 RESUME_INTERRUPTS();
2666 * AbortTransaction
2668 static void
2669 AbortTransaction(void)
2671 TransactionState s = CurrentTransactionState;
2672 TransactionId latestXid;
2673 bool is_parallel_worker;
2675 /* Prevent cancel/die interrupt while cleaning up */
2676 HOLD_INTERRUPTS();
2678 /* Make sure we have a valid memory context and resource owner */
2679 AtAbort_Memory();
2680 AtAbort_ResourceOwner();
2683 * Release any LW locks we might be holding as quickly as possible.
2684 * (Regular locks, however, must be held till we finish aborting.)
2685 * Releasing LW locks is critical since we might try to grab them again
2686 * while cleaning up!
2688 LWLockReleaseAll();
2690 /* Clear wait information and command progress indicator */
2691 pgstat_report_wait_end();
2692 pgstat_progress_end_command();
2694 /* Clean up buffer I/O and buffer context locks, too */
2695 AbortBufferIO();
2696 UnlockBuffers();
2698 /* Reset WAL record construction state */
2699 XLogResetInsertion();
2701 /* Cancel condition variable sleep */
2702 ConditionVariableCancelSleep();
2705 * Also clean up any open wait for lock, since the lock manager will choke
2706 * if we try to wait for another lock before doing this.
2708 LockErrorCleanup();
2711 * If any timeout events are still active, make sure the timeout interrupt
2712 * is scheduled. This covers possible loss of a timeout interrupt due to
2713 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2714 * We delay this till after LockErrorCleanup so that we don't uselessly
2715 * reschedule lock or deadlock check timeouts.
2717 reschedule_timeouts();
2720 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2721 * handler. We do this fairly early in the sequence so that the timeout
2722 * infrastructure will be functional if needed while aborting.
2724 PG_SETMASK(&UnBlockSig);
2727 * check the current transaction state
2729 is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2730 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2731 elog(WARNING, "AbortTransaction while in %s state",
2732 TransStateAsString(s->state));
2733 Assert(s->parent == NULL);
2736 * set the current transaction state information appropriately during the
2737 * abort processing
2739 s->state = TRANS_ABORT;
2742 * Reset user ID which might have been changed transiently. We need this
2743 * to clean up in case control escaped out of a SECURITY DEFINER function
2744 * or other local change of CurrentUserId; therefore, the prior value of
2745 * SecurityRestrictionContext also needs to be restored.
2747 * (Note: it is not necessary to restore session authorization or role
2748 * settings here because those can only be changed via GUC, and GUC will
2749 * take care of rolling them back if need be.)
2751 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
2753 /* Forget about any active REINDEX. */
2754 ResetReindexState(s->nestingLevel);
2756 /* Reset logical streaming state. */
2757 ResetLogicalStreamingState();
2759 /* Reset snapshot export state. */
2760 SnapBuildResetExportedSnapshotState();
2762 /* If in parallel mode, clean up workers and exit parallel mode. */
2763 if (IsInParallelMode())
2765 AtEOXact_Parallel(false);
2766 s->parallelModeLevel = 0;
2770 * do abort processing
2772 AfterTriggerEndXact(false); /* 'false' means it's abort */
2773 AtAbort_Portals();
2774 smgrDoPendingSyncs(false, is_parallel_worker);
2775 AtEOXact_LargeObject(false);
2776 AtAbort_Notify();
2777 AtEOXact_RelationMap(false, is_parallel_worker);
2778 AtAbort_Twophase();
2781 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2782 * far as assigning an XID to advertise). But if we're inside a parallel
2783 * worker, skip this; the user backend must be the one to write the abort
2784 * record.
2786 if (!is_parallel_worker)
2787 latestXid = RecordTransactionAbort(false);
2788 else
2790 latestXid = InvalidTransactionId;
2793 * Since the parallel leader won't get our value of XactLastRecEnd in
2794 * this case, we nudge WAL-writer ourselves in this case. See related
2795 * comments in RecordTransactionAbort for why this matters.
2797 XLogSetAsyncXactLSN(XactLastRecEnd);
2800 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
2803 * Let others know about no transaction in progress by me. Note that this
2804 * must be done _before_ releasing locks we hold and _after_
2805 * RecordTransactionAbort.
2807 ProcArrayEndTransaction(MyProc, latestXid);
2810 * Post-abort cleanup. See notes in CommitTransaction() concerning
2811 * ordering. We can skip all of it if the transaction failed before
2812 * creating a resource owner.
2814 if (TopTransactionResourceOwner != NULL)
2816 if (is_parallel_worker)
2817 CallXactCallbacks(XACT_EVENT_PARALLEL_ABORT);
2818 else
2819 CallXactCallbacks(XACT_EVENT_ABORT);
2821 ResourceOwnerRelease(TopTransactionResourceOwner,
2822 RESOURCE_RELEASE_BEFORE_LOCKS,
2823 false, true);
2824 AtEOXact_Buffers(false);
2825 AtEOXact_RelationCache(false);
2826 AtEOXact_Inval(false);
2827 AtEOXact_MultiXact();
2828 ResourceOwnerRelease(TopTransactionResourceOwner,
2829 RESOURCE_RELEASE_LOCKS,
2830 false, true);
2831 ResourceOwnerRelease(TopTransactionResourceOwner,
2832 RESOURCE_RELEASE_AFTER_LOCKS,
2833 false, true);
2834 smgrDoPendingDeletes(false);
2836 AtEOXact_GUC(false, 1);
2837 AtEOXact_SPI(false);
2838 AtEOXact_Enum();
2839 AtEOXact_on_commit_actions(false);
2840 AtEOXact_Namespace(false, is_parallel_worker);
2841 AtEOXact_SMgr();
2842 AtEOXact_Files(false);
2843 AtEOXact_ComboCid();
2844 AtEOXact_HashTables(false);
2845 AtEOXact_PgStat(false, is_parallel_worker);
2846 AtEOXact_ApplyLauncher(false);
2847 pgstat_report_xact_timestamp(0);
2851 * State remains TRANS_ABORT until CleanupTransaction().
2853 RESUME_INTERRUPTS();
2857 * CleanupTransaction
2859 static void
2860 CleanupTransaction(void)
2862 TransactionState s = CurrentTransactionState;
2865 * State should still be TRANS_ABORT from AbortTransaction().
2867 if (s->state != TRANS_ABORT)
2868 elog(FATAL, "CleanupTransaction: unexpected state %s",
2869 TransStateAsString(s->state));
2872 * do abort cleanup processing
2874 AtCleanup_Portals(); /* now safe to release portal memory */
2875 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
2877 CurrentResourceOwner = NULL; /* and resource owner */
2878 if (TopTransactionResourceOwner)
2879 ResourceOwnerDelete(TopTransactionResourceOwner);
2880 s->curTransactionOwner = NULL;
2881 CurTransactionResourceOwner = NULL;
2882 TopTransactionResourceOwner = NULL;
2884 AtCleanup_Memory(); /* and transaction memory */
2886 s->fullTransactionId = InvalidFullTransactionId;
2887 s->subTransactionId = InvalidSubTransactionId;
2888 s->nestingLevel = 0;
2889 s->gucNestLevel = 0;
2890 s->childXids = NULL;
2891 s->nChildXids = 0;
2892 s->maxChildXids = 0;
2893 s->parallelModeLevel = 0;
2895 XactTopFullTransactionId = InvalidFullTransactionId;
2896 nParallelCurrentXids = 0;
2899 * done with abort processing, set current transaction state back to
2900 * default
2902 s->state = TRANS_DEFAULT;
2906 * StartTransactionCommand
2908 void
2909 StartTransactionCommand(void)
2911 TransactionState s = CurrentTransactionState;
2913 switch (s->blockState)
2916 * if we aren't in a transaction block, we just do our usual start
2917 * transaction.
2919 case TBLOCK_DEFAULT:
2920 StartTransaction();
2921 s->blockState = TBLOCK_STARTED;
2922 break;
2925 * We are somewhere in a transaction block or subtransaction and
2926 * about to start a new command. For now we do nothing, but
2927 * someday we may do command-local resource initialization. (Note
2928 * that any needed CommandCounterIncrement was done by the
2929 * previous CommitTransactionCommand.)
2931 case TBLOCK_INPROGRESS:
2932 case TBLOCK_IMPLICIT_INPROGRESS:
2933 case TBLOCK_SUBINPROGRESS:
2934 break;
2937 * Here we are in a failed transaction block (one of the commands
2938 * caused an abort) so we do nothing but remain in the abort
2939 * state. Eventually we will get a ROLLBACK command which will
2940 * get us out of this state. (It is up to other code to ensure
2941 * that no commands other than ROLLBACK will be processed in these
2942 * states.)
2944 case TBLOCK_ABORT:
2945 case TBLOCK_SUBABORT:
2946 break;
2948 /* These cases are invalid. */
2949 case TBLOCK_STARTED:
2950 case TBLOCK_BEGIN:
2951 case TBLOCK_PARALLEL_INPROGRESS:
2952 case TBLOCK_SUBBEGIN:
2953 case TBLOCK_END:
2954 case TBLOCK_SUBRELEASE:
2955 case TBLOCK_SUBCOMMIT:
2956 case TBLOCK_ABORT_END:
2957 case TBLOCK_SUBABORT_END:
2958 case TBLOCK_ABORT_PENDING:
2959 case TBLOCK_SUBABORT_PENDING:
2960 case TBLOCK_SUBRESTART:
2961 case TBLOCK_SUBABORT_RESTART:
2962 case TBLOCK_PREPARE:
2963 elog(ERROR, "StartTransactionCommand: unexpected state %s",
2964 BlockStateAsString(s->blockState));
2965 break;
2969 * We must switch to CurTransactionContext before returning. This is
2970 * already done if we called StartTransaction, otherwise not.
2972 Assert(CurTransactionContext != NULL);
2973 MemoryContextSwitchTo(CurTransactionContext);
2978 * Simple system for saving and restoring transaction characteristics
2979 * (isolation level, read only, deferrable). We need this for transaction
2980 * chaining, so that we can set the characteristics of the new transaction to
2981 * be the same as the previous one. (We need something like this because the
2982 * GUC system resets the characteristics at transaction end, so for example
2983 * just skipping the reset in StartTransaction() won't work.)
2985 static int save_XactIsoLevel;
2986 static bool save_XactReadOnly;
2987 static bool save_XactDeferrable;
2989 void
2990 SaveTransactionCharacteristics(void)
2992 save_XactIsoLevel = XactIsoLevel;
2993 save_XactReadOnly = XactReadOnly;
2994 save_XactDeferrable = XactDeferrable;
2997 void
2998 RestoreTransactionCharacteristics(void)
3000 XactIsoLevel = save_XactIsoLevel;
3001 XactReadOnly = save_XactReadOnly;
3002 XactDeferrable = save_XactDeferrable;
3007 * CommitTransactionCommand
3009 void
3010 CommitTransactionCommand(void)
3012 TransactionState s = CurrentTransactionState;
3014 if (s->chain)
3015 SaveTransactionCharacteristics();
3017 switch (s->blockState)
3020 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3021 * StartTransactionCommand didn't set the STARTED state
3022 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3023 * by EndParallelWorkerTransaction(), not this function.
3025 case TBLOCK_DEFAULT:
3026 case TBLOCK_PARALLEL_INPROGRESS:
3027 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3028 BlockStateAsString(s->blockState));
3029 break;
3032 * If we aren't in a transaction block, just do our usual
3033 * transaction commit, and return to the idle state.
3035 case TBLOCK_STARTED:
3036 CommitTransaction();
3037 s->blockState = TBLOCK_DEFAULT;
3038 break;
3041 * We are completing a "BEGIN TRANSACTION" command, so we change
3042 * to the "transaction block in progress" state and return. (We
3043 * assume the BEGIN did nothing to the database, so we need no
3044 * CommandCounterIncrement.)
3046 case TBLOCK_BEGIN:
3047 s->blockState = TBLOCK_INPROGRESS;
3048 break;
3051 * This is the case when we have finished executing a command
3052 * someplace within a transaction block. We increment the command
3053 * counter and return.
3055 case TBLOCK_INPROGRESS:
3056 case TBLOCK_IMPLICIT_INPROGRESS:
3057 case TBLOCK_SUBINPROGRESS:
3058 CommandCounterIncrement();
3059 break;
3062 * We are completing a "COMMIT" command. Do it and return to the
3063 * idle state.
3065 case TBLOCK_END:
3066 CommitTransaction();
3067 s->blockState = TBLOCK_DEFAULT;
3068 if (s->chain)
3070 StartTransaction();
3071 s->blockState = TBLOCK_INPROGRESS;
3072 s->chain = false;
3073 RestoreTransactionCharacteristics();
3075 break;
3078 * Here we are in the middle of a transaction block but one of the
3079 * commands caused an abort so we do nothing but remain in the
3080 * abort state. Eventually we will get a ROLLBACK command.
3082 case TBLOCK_ABORT:
3083 case TBLOCK_SUBABORT:
3084 break;
3087 * Here we were in an aborted transaction block and we just got
3088 * the ROLLBACK command from the user, so clean up the
3089 * already-aborted transaction and return to the idle state.
3091 case TBLOCK_ABORT_END:
3092 CleanupTransaction();
3093 s->blockState = TBLOCK_DEFAULT;
3094 if (s->chain)
3096 StartTransaction();
3097 s->blockState = TBLOCK_INPROGRESS;
3098 s->chain = false;
3099 RestoreTransactionCharacteristics();
3101 break;
3104 * Here we were in a perfectly good transaction block but the user
3105 * told us to ROLLBACK anyway. We have to abort the transaction
3106 * and then clean up.
3108 case TBLOCK_ABORT_PENDING:
3109 AbortTransaction();
3110 CleanupTransaction();
3111 s->blockState = TBLOCK_DEFAULT;
3112 if (s->chain)
3114 StartTransaction();
3115 s->blockState = TBLOCK_INPROGRESS;
3116 s->chain = false;
3117 RestoreTransactionCharacteristics();
3119 break;
3122 * We are completing a "PREPARE TRANSACTION" command. Do it and
3123 * return to the idle state.
3125 case TBLOCK_PREPARE:
3126 PrepareTransaction();
3127 s->blockState = TBLOCK_DEFAULT;
3128 break;
3131 * We were just issued a SAVEPOINT inside a transaction block.
3132 * Start a subtransaction. (DefineSavepoint already did
3133 * PushTransaction, so as to have someplace to put the SUBBEGIN
3134 * state.)
3136 case TBLOCK_SUBBEGIN:
3137 StartSubTransaction();
3138 s->blockState = TBLOCK_SUBINPROGRESS;
3139 break;
3142 * We were issued a RELEASE command, so we end the current
3143 * subtransaction and return to the parent transaction. The parent
3144 * might be ended too, so repeat till we find an INPROGRESS
3145 * transaction or subtransaction.
3147 case TBLOCK_SUBRELEASE:
3150 CommitSubTransaction();
3151 s = CurrentTransactionState; /* changed by pop */
3152 } while (s->blockState == TBLOCK_SUBRELEASE);
3154 Assert(s->blockState == TBLOCK_INPROGRESS ||
3155 s->blockState == TBLOCK_SUBINPROGRESS);
3156 break;
3159 * We were issued a COMMIT, so we end the current subtransaction
3160 * hierarchy and perform final commit. We do this by rolling up
3161 * any subtransactions into their parent, which leads to O(N^2)
3162 * operations with respect to resource owners - this isn't that
3163 * bad until we approach a thousands of savepoints but is
3164 * necessary for correctness should after triggers create new
3165 * resource owners.
3167 case TBLOCK_SUBCOMMIT:
3170 CommitSubTransaction();
3171 s = CurrentTransactionState; /* changed by pop */
3172 } while (s->blockState == TBLOCK_SUBCOMMIT);
3173 /* If we had a COMMIT command, finish off the main xact too */
3174 if (s->blockState == TBLOCK_END)
3176 Assert(s->parent == NULL);
3177 CommitTransaction();
3178 s->blockState = TBLOCK_DEFAULT;
3179 if (s->chain)
3181 StartTransaction();
3182 s->blockState = TBLOCK_INPROGRESS;
3183 s->chain = false;
3184 RestoreTransactionCharacteristics();
3187 else if (s->blockState == TBLOCK_PREPARE)
3189 Assert(s->parent == NULL);
3190 PrepareTransaction();
3191 s->blockState = TBLOCK_DEFAULT;
3193 else
3194 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3195 BlockStateAsString(s->blockState));
3196 break;
3199 * The current already-failed subtransaction is ending due to a
3200 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3201 * examine the parent (which could be in any of several states).
3203 case TBLOCK_SUBABORT_END:
3204 CleanupSubTransaction();
3205 CommitTransactionCommand();
3206 break;
3209 * As above, but it's not dead yet, so abort first.
3211 case TBLOCK_SUBABORT_PENDING:
3212 AbortSubTransaction();
3213 CleanupSubTransaction();
3214 CommitTransactionCommand();
3215 break;
3218 * The current subtransaction is the target of a ROLLBACK TO
3219 * command. Abort and pop it, then start a new subtransaction
3220 * with the same name.
3222 case TBLOCK_SUBRESTART:
3224 char *name;
3225 int savepointLevel;
3227 /* save name and keep Cleanup from freeing it */
3228 name = s->name;
3229 s->name = NULL;
3230 savepointLevel = s->savepointLevel;
3232 AbortSubTransaction();
3233 CleanupSubTransaction();
3235 DefineSavepoint(NULL);
3236 s = CurrentTransactionState; /* changed by push */
3237 s->name = name;
3238 s->savepointLevel = savepointLevel;
3240 /* This is the same as TBLOCK_SUBBEGIN case */
3241 AssertState(s->blockState == TBLOCK_SUBBEGIN);
3242 StartSubTransaction();
3243 s->blockState = TBLOCK_SUBINPROGRESS;
3245 break;
3248 * Same as above, but the subtransaction had already failed, so we
3249 * don't need AbortSubTransaction.
3251 case TBLOCK_SUBABORT_RESTART:
3253 char *name;
3254 int savepointLevel;
3256 /* save name and keep Cleanup from freeing it */
3257 name = s->name;
3258 s->name = NULL;
3259 savepointLevel = s->savepointLevel;
3261 CleanupSubTransaction();
3263 DefineSavepoint(NULL);
3264 s = CurrentTransactionState; /* changed by push */
3265 s->name = name;
3266 s->savepointLevel = savepointLevel;
3268 /* This is the same as TBLOCK_SUBBEGIN case */
3269 AssertState(s->blockState == TBLOCK_SUBBEGIN);
3270 StartSubTransaction();
3271 s->blockState = TBLOCK_SUBINPROGRESS;
3273 break;
3278 * AbortCurrentTransaction
3280 void
3281 AbortCurrentTransaction(void)
3283 TransactionState s = CurrentTransactionState;
3285 switch (s->blockState)
3287 case TBLOCK_DEFAULT:
3288 if (s->state == TRANS_DEFAULT)
3290 /* we are idle, so nothing to do */
3292 else
3295 * We can get here after an error during transaction start
3296 * (state will be TRANS_START). Need to clean up the
3297 * incompletely started transaction. First, adjust the
3298 * low-level state to suppress warning message from
3299 * AbortTransaction.
3301 if (s->state == TRANS_START)
3302 s->state = TRANS_INPROGRESS;
3303 AbortTransaction();
3304 CleanupTransaction();
3306 break;
3309 * If we aren't in a transaction block, we just do the basic abort
3310 * & cleanup transaction. For this purpose, we treat an implicit
3311 * transaction block as if it were a simple statement.
3313 case TBLOCK_STARTED:
3314 case TBLOCK_IMPLICIT_INPROGRESS:
3315 AbortTransaction();
3316 CleanupTransaction();
3317 s->blockState = TBLOCK_DEFAULT;
3318 break;
3321 * If we are in TBLOCK_BEGIN it means something screwed up right
3322 * after reading "BEGIN TRANSACTION". We assume that the user
3323 * will interpret the error as meaning the BEGIN failed to get him
3324 * into a transaction block, so we should abort and return to idle
3325 * state.
3327 case TBLOCK_BEGIN:
3328 AbortTransaction();
3329 CleanupTransaction();
3330 s->blockState = TBLOCK_DEFAULT;
3331 break;
3334 * We are somewhere in a transaction block and we've gotten a
3335 * failure, so we abort the transaction and set up the persistent
3336 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3338 case TBLOCK_INPROGRESS:
3339 case TBLOCK_PARALLEL_INPROGRESS:
3340 AbortTransaction();
3341 s->blockState = TBLOCK_ABORT;
3342 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3343 break;
3346 * Here, we failed while trying to COMMIT. Clean up the
3347 * transaction and return to idle state (we do not want to stay in
3348 * the transaction).
3350 case TBLOCK_END:
3351 AbortTransaction();
3352 CleanupTransaction();
3353 s->blockState = TBLOCK_DEFAULT;
3354 break;
3357 * Here, we are already in an aborted transaction state and are
3358 * waiting for a ROLLBACK, but for some reason we failed again! So
3359 * we just remain in the abort state.
3361 case TBLOCK_ABORT:
3362 case TBLOCK_SUBABORT:
3363 break;
3366 * We are in a failed transaction and we got the ROLLBACK command.
3367 * We have already aborted, we just need to cleanup and go to idle
3368 * state.
3370 case TBLOCK_ABORT_END:
3371 CleanupTransaction();
3372 s->blockState = TBLOCK_DEFAULT;
3373 break;
3376 * We are in a live transaction and we got a ROLLBACK command.
3377 * Abort, cleanup, go to idle state.
3379 case TBLOCK_ABORT_PENDING:
3380 AbortTransaction();
3381 CleanupTransaction();
3382 s->blockState = TBLOCK_DEFAULT;
3383 break;
3386 * Here, we failed while trying to PREPARE. Clean up the
3387 * transaction and return to idle state (we do not want to stay in
3388 * the transaction).
3390 case TBLOCK_PREPARE:
3391 AbortTransaction();
3392 CleanupTransaction();
3393 s->blockState = TBLOCK_DEFAULT;
3394 break;
3397 * We got an error inside a subtransaction. Abort just the
3398 * subtransaction, and go to the persistent SUBABORT state until
3399 * we get ROLLBACK.
3401 case TBLOCK_SUBINPROGRESS:
3402 AbortSubTransaction();
3403 s->blockState = TBLOCK_SUBABORT;
3404 break;
3407 * If we failed while trying to create a subtransaction, clean up
3408 * the broken subtransaction and abort the parent. The same
3409 * applies if we get a failure while ending a subtransaction.
3411 case TBLOCK_SUBBEGIN:
3412 case TBLOCK_SUBRELEASE:
3413 case TBLOCK_SUBCOMMIT:
3414 case TBLOCK_SUBABORT_PENDING:
3415 case TBLOCK_SUBRESTART:
3416 AbortSubTransaction();
3417 CleanupSubTransaction();
3418 AbortCurrentTransaction();
3419 break;
3422 * Same as above, except the Abort() was already done.
3424 case TBLOCK_SUBABORT_END:
3425 case TBLOCK_SUBABORT_RESTART:
3426 CleanupSubTransaction();
3427 AbortCurrentTransaction();
3428 break;
3433 * PreventInTransactionBlock
3435 * This routine is to be called by statements that must not run inside
3436 * a transaction block, typically because they have non-rollback-able
3437 * side effects or do internal commits.
3439 * If we have already started a transaction block, issue an error; also issue
3440 * an error if we appear to be running inside a user-defined function (which
3441 * could issue more commands and possibly cause a failure after the statement
3442 * completes). Subtransactions are verboten too.
3444 * isTopLevel: passed down from ProcessUtility to determine whether we are
3445 * inside a function. (We will always fail if this is false, but it's
3446 * convenient to centralize the check here instead of making callers do it.)
3447 * stmtType: statement type name, for error messages.
3449 void
3450 PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
3453 * xact block already started?
3455 if (IsTransactionBlock())
3456 ereport(ERROR,
3457 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3458 /* translator: %s represents an SQL statement name */
3459 errmsg("%s cannot run inside a transaction block",
3460 stmtType)));
3463 * subtransaction?
3465 if (IsSubTransaction())
3466 ereport(ERROR,
3467 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3468 /* translator: %s represents an SQL statement name */
3469 errmsg("%s cannot run inside a subtransaction",
3470 stmtType)));
3473 * inside a function call?
3475 if (!isTopLevel)
3476 ereport(ERROR,
3477 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3478 /* translator: %s represents an SQL statement name */
3479 errmsg("%s cannot be executed from a function", stmtType)));
3481 /* If we got past IsTransactionBlock test, should be in default state */
3482 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
3483 CurrentTransactionState->blockState != TBLOCK_STARTED)
3484 elog(FATAL, "cannot prevent transaction chain");
3485 /* all okay */
3489 * WarnNoTransactionBlock
3490 * RequireTransactionBlock
3492 * These two functions allow for warnings or errors if a command is executed
3493 * outside of a transaction block. This is useful for commands that have no
3494 * effects that persist past transaction end (and so calling them outside a
3495 * transaction block is presumably an error). DECLARE CURSOR is an example.
3496 * While top-level transaction control commands (BEGIN/COMMIT/ABORT) and SET
3497 * that have no effect issue warnings, all other no-effect commands generate
3498 * errors.
3500 * If we appear to be running inside a user-defined function, we do not
3501 * issue anything, since the function could issue more commands that make
3502 * use of the current statement's results. Likewise subtransactions.
3503 * Thus these are inverses for PreventInTransactionBlock.
3505 * isTopLevel: passed down from ProcessUtility to determine whether we are
3506 * inside a function.
3507 * stmtType: statement type name, for warning or error messages.
3509 void
3510 WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
3512 CheckTransactionBlock(isTopLevel, false, stmtType);
3515 void
3516 RequireTransactionBlock(bool isTopLevel, const char *stmtType)
3518 CheckTransactionBlock(isTopLevel, true, stmtType);
3522 * This is the implementation of the above two.
3524 static void
3525 CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
3528 * xact block already started?
3530 if (IsTransactionBlock())
3531 return;
3534 * subtransaction?
3536 if (IsSubTransaction())
3537 return;
3540 * inside a function call?
3542 if (!isTopLevel)
3543 return;
3545 ereport(throwError ? ERROR : WARNING,
3546 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3547 /* translator: %s represents an SQL statement name */
3548 errmsg("%s can only be used in transaction blocks",
3549 stmtType)));
3553 * IsInTransactionBlock
3555 * This routine is for statements that need to behave differently inside
3556 * a transaction block than when running as single commands. ANALYZE is
3557 * currently the only example.
3559 * isTopLevel: passed down from ProcessUtility to determine whether we are
3560 * inside a function.
3562 bool
3563 IsInTransactionBlock(bool isTopLevel)
3566 * Return true on same conditions that would make
3567 * PreventInTransactionBlock error out
3569 if (IsTransactionBlock())
3570 return true;
3572 if (IsSubTransaction())
3573 return true;
3575 if (!isTopLevel)
3576 return true;
3578 if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
3579 CurrentTransactionState->blockState != TBLOCK_STARTED)
3580 return true;
3582 return false;
3587 * Register or deregister callback functions for start- and end-of-xact
3588 * operations.
3590 * These functions are intended for use by dynamically loaded modules.
3591 * For built-in modules we generally just hardwire the appropriate calls
3592 * (mainly because it's easier to control the order that way, where needed).
3594 * At transaction end, the callback occurs post-commit or post-abort, so the
3595 * callback functions can only do noncritical cleanup.
3597 void
3598 RegisterXactCallback(XactCallback callback, void *arg)
3600 XactCallbackItem *item;
3602 item = (XactCallbackItem *)
3603 MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
3604 item->callback = callback;
3605 item->arg = arg;
3606 item->next = Xact_callbacks;
3607 Xact_callbacks = item;
3610 void
3611 UnregisterXactCallback(XactCallback callback, void *arg)
3613 XactCallbackItem *item;
3614 XactCallbackItem *prev;
3616 prev = NULL;
3617 for (item = Xact_callbacks; item; prev = item, item = item->next)
3619 if (item->callback == callback && item->arg == arg)
3621 if (prev)
3622 prev->next = item->next;
3623 else
3624 Xact_callbacks = item->next;
3625 pfree(item);
3626 break;
3631 static void
3632 CallXactCallbacks(XactEvent event)
3634 XactCallbackItem *item;
3636 for (item = Xact_callbacks; item; item = item->next)
3637 item->callback(event, item->arg);
3642 * Register or deregister callback functions for start- and end-of-subxact
3643 * operations.
3645 * Pretty much same as above, but for subtransaction events.
3647 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3648 * so the callback functions can only do noncritical cleanup. At
3649 * subtransaction start, the callback is called when the subtransaction has
3650 * finished initializing.
3652 void
3653 RegisterSubXactCallback(SubXactCallback callback, void *arg)
3655 SubXactCallbackItem *item;
3657 item = (SubXactCallbackItem *)
3658 MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
3659 item->callback = callback;
3660 item->arg = arg;
3661 item->next = SubXact_callbacks;
3662 SubXact_callbacks = item;
3665 void
3666 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
3668 SubXactCallbackItem *item;
3669 SubXactCallbackItem *prev;
3671 prev = NULL;
3672 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3674 if (item->callback == callback && item->arg == arg)
3676 if (prev)
3677 prev->next = item->next;
3678 else
3679 SubXact_callbacks = item->next;
3680 pfree(item);
3681 break;
3686 static void
3687 CallSubXactCallbacks(SubXactEvent event,
3688 SubTransactionId mySubid,
3689 SubTransactionId parentSubid)
3691 SubXactCallbackItem *item;
3693 for (item = SubXact_callbacks; item; item = item->next)
3694 item->callback(event, mySubid, parentSubid, item->arg);
3698 /* ----------------------------------------------------------------
3699 * transaction block support
3700 * ----------------------------------------------------------------
3704 * BeginTransactionBlock
3705 * This executes a BEGIN command.
3707 void
3708 BeginTransactionBlock(void)
3710 TransactionState s = CurrentTransactionState;
3712 switch (s->blockState)
3715 * We are not inside a transaction block, so allow one to begin.
3717 case TBLOCK_STARTED:
3718 s->blockState = TBLOCK_BEGIN;
3719 break;
3722 * BEGIN converts an implicit transaction block to a regular one.
3723 * (Note that we allow this even if we've already done some
3724 * commands, which is a bit odd but matches historical practice.)
3726 case TBLOCK_IMPLICIT_INPROGRESS:
3727 s->blockState = TBLOCK_BEGIN;
3728 break;
3731 * Already a transaction block in progress.
3733 case TBLOCK_INPROGRESS:
3734 case TBLOCK_PARALLEL_INPROGRESS:
3735 case TBLOCK_SUBINPROGRESS:
3736 case TBLOCK_ABORT:
3737 case TBLOCK_SUBABORT:
3738 ereport(WARNING,
3739 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3740 errmsg("there is already a transaction in progress")));
3741 break;
3743 /* These cases are invalid. */
3744 case TBLOCK_DEFAULT:
3745 case TBLOCK_BEGIN:
3746 case TBLOCK_SUBBEGIN:
3747 case TBLOCK_END:
3748 case TBLOCK_SUBRELEASE:
3749 case TBLOCK_SUBCOMMIT:
3750 case TBLOCK_ABORT_END:
3751 case TBLOCK_SUBABORT_END:
3752 case TBLOCK_ABORT_PENDING:
3753 case TBLOCK_SUBABORT_PENDING:
3754 case TBLOCK_SUBRESTART:
3755 case TBLOCK_SUBABORT_RESTART:
3756 case TBLOCK_PREPARE:
3757 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3758 BlockStateAsString(s->blockState));
3759 break;
3764 * PrepareTransactionBlock
3765 * This executes a PREPARE command.
3767 * Since PREPARE may actually do a ROLLBACK, the result indicates what
3768 * happened: true for PREPARE, false for ROLLBACK.
3770 * Note that we don't actually do anything here except change blockState.
3771 * The real work will be done in the upcoming PrepareTransaction().
3772 * We do it this way because it's not convenient to change memory context,
3773 * resource owner, etc while executing inside a Portal.
3775 bool
3776 PrepareTransactionBlock(const char *gid)
3778 TransactionState s;
3779 bool result;
3781 /* Set up to commit the current transaction */
3782 result = EndTransactionBlock(false);
3784 /* If successful, change outer tblock state to PREPARE */
3785 if (result)
3787 s = CurrentTransactionState;
3789 while (s->parent != NULL)
3790 s = s->parent;
3792 if (s->blockState == TBLOCK_END)
3794 /* Save GID where PrepareTransaction can find it again */
3795 prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
3797 s->blockState = TBLOCK_PREPARE;
3799 else
3802 * ignore case where we are not in a transaction;
3803 * EndTransactionBlock already issued a warning.
3805 Assert(s->blockState == TBLOCK_STARTED ||
3806 s->blockState == TBLOCK_IMPLICIT_INPROGRESS);
3807 /* Don't send back a PREPARE result tag... */
3808 result = false;
3812 return result;
3816 * EndTransactionBlock
3817 * This executes a COMMIT command.
3819 * Since COMMIT may actually do a ROLLBACK, the result indicates what
3820 * happened: true for COMMIT, false for ROLLBACK.
3822 * Note that we don't actually do anything here except change blockState.
3823 * The real work will be done in the upcoming CommitTransactionCommand().
3824 * We do it this way because it's not convenient to change memory context,
3825 * resource owner, etc while executing inside a Portal.
3827 bool
3828 EndTransactionBlock(bool chain)
3830 TransactionState s = CurrentTransactionState;
3831 bool result = false;
3833 switch (s->blockState)
3836 * We are in a transaction block, so tell CommitTransactionCommand
3837 * to COMMIT.
3839 case TBLOCK_INPROGRESS:
3840 s->blockState = TBLOCK_END;
3841 result = true;
3842 break;
3845 * We are in an implicit transaction block. If AND CHAIN was
3846 * specified, error. Otherwise commit, but issue a warning
3847 * because there was no explicit BEGIN before this.
3849 case TBLOCK_IMPLICIT_INPROGRESS:
3850 if (chain)
3851 ereport(ERROR,
3852 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3853 /* translator: %s represents an SQL statement name */
3854 errmsg("%s can only be used in transaction blocks",
3855 "COMMIT AND CHAIN")));
3856 else
3857 ereport(WARNING,
3858 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3859 errmsg("there is no transaction in progress")));
3860 s->blockState = TBLOCK_END;
3861 result = true;
3862 break;
3865 * We are in a failed transaction block. Tell
3866 * CommitTransactionCommand it's time to exit the block.
3868 case TBLOCK_ABORT:
3869 s->blockState = TBLOCK_ABORT_END;
3870 break;
3873 * We are in a live subtransaction block. Set up to subcommit all
3874 * open subtransactions and then commit the main transaction.
3876 case TBLOCK_SUBINPROGRESS:
3877 while (s->parent != NULL)
3879 if (s->blockState == TBLOCK_SUBINPROGRESS)
3880 s->blockState = TBLOCK_SUBCOMMIT;
3881 else
3882 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3883 BlockStateAsString(s->blockState));
3884 s = s->parent;
3886 if (s->blockState == TBLOCK_INPROGRESS)
3887 s->blockState = TBLOCK_END;
3888 else
3889 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3890 BlockStateAsString(s->blockState));
3891 result = true;
3892 break;
3895 * Here we are inside an aborted subtransaction. Treat the COMMIT
3896 * as ROLLBACK: set up to abort everything and exit the main
3897 * transaction.
3899 case TBLOCK_SUBABORT:
3900 while (s->parent != NULL)
3902 if (s->blockState == TBLOCK_SUBINPROGRESS)
3903 s->blockState = TBLOCK_SUBABORT_PENDING;
3904 else if (s->blockState == TBLOCK_SUBABORT)
3905 s->blockState = TBLOCK_SUBABORT_END;
3906 else
3907 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3908 BlockStateAsString(s->blockState));
3909 s = s->parent;
3911 if (s->blockState == TBLOCK_INPROGRESS)
3912 s->blockState = TBLOCK_ABORT_PENDING;
3913 else if (s->blockState == TBLOCK_ABORT)
3914 s->blockState = TBLOCK_ABORT_END;
3915 else
3916 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3917 BlockStateAsString(s->blockState));
3918 break;
3921 * The user issued COMMIT when not inside a transaction. For
3922 * COMMIT without CHAIN, issue a WARNING, staying in
3923 * TBLOCK_STARTED state. The upcoming call to
3924 * CommitTransactionCommand() will then close the transaction and
3925 * put us back into the default state. For COMMIT AND CHAIN,
3926 * error.
3928 case TBLOCK_STARTED:
3929 if (chain)
3930 ereport(ERROR,
3931 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3932 /* translator: %s represents an SQL statement name */
3933 errmsg("%s can only be used in transaction blocks",
3934 "COMMIT AND CHAIN")));
3935 else
3936 ereport(WARNING,
3937 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3938 errmsg("there is no transaction in progress")));
3939 result = true;
3940 break;
3943 * The user issued a COMMIT that somehow ran inside a parallel
3944 * worker. We can't cope with that.
3946 case TBLOCK_PARALLEL_INPROGRESS:
3947 ereport(FATAL,
3948 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3949 errmsg("cannot commit during a parallel operation")));
3950 break;
3952 /* These cases are invalid. */
3953 case TBLOCK_DEFAULT:
3954 case TBLOCK_BEGIN:
3955 case TBLOCK_SUBBEGIN:
3956 case TBLOCK_END:
3957 case TBLOCK_SUBRELEASE:
3958 case TBLOCK_SUBCOMMIT:
3959 case TBLOCK_ABORT_END:
3960 case TBLOCK_SUBABORT_END:
3961 case TBLOCK_ABORT_PENDING:
3962 case TBLOCK_SUBABORT_PENDING:
3963 case TBLOCK_SUBRESTART:
3964 case TBLOCK_SUBABORT_RESTART:
3965 case TBLOCK_PREPARE:
3966 elog(FATAL, "EndTransactionBlock: unexpected state %s",
3967 BlockStateAsString(s->blockState));
3968 break;
3971 Assert(s->blockState == TBLOCK_STARTED ||
3972 s->blockState == TBLOCK_END ||
3973 s->blockState == TBLOCK_ABORT_END ||
3974 s->blockState == TBLOCK_ABORT_PENDING);
3976 s->chain = chain;
3978 return result;
3982 * UserAbortTransactionBlock
3983 * This executes a ROLLBACK command.
3985 * As above, we don't actually do anything here except change blockState.
3987 void
3988 UserAbortTransactionBlock(bool chain)
3990 TransactionState s = CurrentTransactionState;
3992 switch (s->blockState)
3995 * We are inside a transaction block and we got a ROLLBACK command
3996 * from the user, so tell CommitTransactionCommand to abort and
3997 * exit the transaction block.
3999 case TBLOCK_INPROGRESS:
4000 s->blockState = TBLOCK_ABORT_PENDING;
4001 break;
4004 * We are inside a failed transaction block and we got a ROLLBACK
4005 * command from the user. Abort processing is already done, so
4006 * CommitTransactionCommand just has to cleanup and go back to
4007 * idle state.
4009 case TBLOCK_ABORT:
4010 s->blockState = TBLOCK_ABORT_END;
4011 break;
4014 * We are inside a subtransaction. Mark everything up to top
4015 * level as exitable.
4017 case TBLOCK_SUBINPROGRESS:
4018 case TBLOCK_SUBABORT:
4019 while (s->parent != NULL)
4021 if (s->blockState == TBLOCK_SUBINPROGRESS)
4022 s->blockState = TBLOCK_SUBABORT_PENDING;
4023 else if (s->blockState == TBLOCK_SUBABORT)
4024 s->blockState = TBLOCK_SUBABORT_END;
4025 else
4026 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4027 BlockStateAsString(s->blockState));
4028 s = s->parent;
4030 if (s->blockState == TBLOCK_INPROGRESS)
4031 s->blockState = TBLOCK_ABORT_PENDING;
4032 else if (s->blockState == TBLOCK_ABORT)
4033 s->blockState = TBLOCK_ABORT_END;
4034 else
4035 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4036 BlockStateAsString(s->blockState));
4037 break;
4040 * The user issued ABORT when not inside a transaction. For
4041 * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4042 * The upcoming call to CommitTransactionCommand() will then put
4043 * us back into the default state. For ROLLBACK AND CHAIN, error.
4045 * We do the same thing with ABORT inside an implicit transaction,
4046 * although in this case we might be rolling back actual database
4047 * state changes. (It's debatable whether we should issue a
4048 * WARNING in this case, but we have done so historically.)
4050 case TBLOCK_STARTED:
4051 case TBLOCK_IMPLICIT_INPROGRESS:
4052 if (chain)
4053 ereport(ERROR,
4054 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4055 /* translator: %s represents an SQL statement name */
4056 errmsg("%s can only be used in transaction blocks",
4057 "ROLLBACK AND CHAIN")));
4058 else
4059 ereport(WARNING,
4060 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4061 errmsg("there is no transaction in progress")));
4062 s->blockState = TBLOCK_ABORT_PENDING;
4063 break;
4066 * The user issued an ABORT that somehow ran inside a parallel
4067 * worker. We can't cope with that.
4069 case TBLOCK_PARALLEL_INPROGRESS:
4070 ereport(FATAL,
4071 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4072 errmsg("cannot abort during a parallel operation")));
4073 break;
4075 /* These cases are invalid. */
4076 case TBLOCK_DEFAULT:
4077 case TBLOCK_BEGIN:
4078 case TBLOCK_SUBBEGIN:
4079 case TBLOCK_END:
4080 case TBLOCK_SUBRELEASE:
4081 case TBLOCK_SUBCOMMIT:
4082 case TBLOCK_ABORT_END:
4083 case TBLOCK_SUBABORT_END:
4084 case TBLOCK_ABORT_PENDING:
4085 case TBLOCK_SUBABORT_PENDING:
4086 case TBLOCK_SUBRESTART:
4087 case TBLOCK_SUBABORT_RESTART:
4088 case TBLOCK_PREPARE:
4089 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4090 BlockStateAsString(s->blockState));
4091 break;
4094 Assert(s->blockState == TBLOCK_ABORT_END ||
4095 s->blockState == TBLOCK_ABORT_PENDING);
4097 s->chain = chain;
4101 * BeginImplicitTransactionBlock
4102 * Start an implicit transaction block if we're not already in one.
4104 * Unlike BeginTransactionBlock, this is called directly from the main loop
4105 * in postgres.c, not within a Portal. So we can just change blockState
4106 * without a lot of ceremony. We do not expect caller to do
4107 * CommitTransactionCommand/StartTransactionCommand.
4109 void
4110 BeginImplicitTransactionBlock(void)
4112 TransactionState s = CurrentTransactionState;
4115 * If we are in STARTED state (that is, no transaction block is open),
4116 * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4117 * block.
4119 * For caller convenience, we consider all other transaction states as
4120 * legal here; otherwise the caller would need its own state check, which
4121 * seems rather pointless.
4123 if (s->blockState == TBLOCK_STARTED)
4124 s->blockState = TBLOCK_IMPLICIT_INPROGRESS;
4128 * EndImplicitTransactionBlock
4129 * End an implicit transaction block, if we're in one.
4131 * Like EndTransactionBlock, we just make any needed blockState change here.
4132 * The real work will be done in the upcoming CommitTransactionCommand().
4134 void
4135 EndImplicitTransactionBlock(void)
4137 TransactionState s = CurrentTransactionState;
4140 * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4141 * allowing CommitTransactionCommand to commit whatever happened during
4142 * the implicit transaction block as though it were a single statement.
4144 * For caller convenience, we consider all other transaction states as
4145 * legal here; otherwise the caller would need its own state check, which
4146 * seems rather pointless.
4148 if (s->blockState == TBLOCK_IMPLICIT_INPROGRESS)
4149 s->blockState = TBLOCK_STARTED;
4153 * DefineSavepoint
4154 * This executes a SAVEPOINT command.
4156 void
4157 DefineSavepoint(const char *name)
4159 TransactionState s = CurrentTransactionState;
4162 * Workers synchronize transaction state at the beginning of each parallel
4163 * operation, so we can't account for new subtransactions after that
4164 * point. (Note that this check will certainly error out if s->blockState
4165 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4166 * below.)
4168 if (IsInParallelMode())
4169 ereport(ERROR,
4170 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4171 errmsg("cannot define savepoints during a parallel operation")));
4173 switch (s->blockState)
4175 case TBLOCK_INPROGRESS:
4176 case TBLOCK_SUBINPROGRESS:
4177 /* Normal subtransaction start */
4178 PushTransaction();
4179 s = CurrentTransactionState; /* changed by push */
4182 * Savepoint names, like the TransactionState block itself, live
4183 * in TopTransactionContext.
4185 if (name)
4186 s->name = MemoryContextStrdup(TopTransactionContext, name);
4187 break;
4190 * We disallow savepoint commands in implicit transaction blocks.
4191 * There would be no great difficulty in allowing them so far as
4192 * this module is concerned, but a savepoint seems inconsistent
4193 * with exec_simple_query's behavior of abandoning the whole query
4194 * string upon error. Also, the point of an implicit transaction
4195 * block (as opposed to a regular one) is to automatically close
4196 * after an error, so it's hard to see how a savepoint would fit
4197 * into that.
4199 * The error messages for this are phrased as if there were no
4200 * active transaction block at all, which is historical but
4201 * perhaps could be improved.
4203 case TBLOCK_IMPLICIT_INPROGRESS:
4204 ereport(ERROR,
4205 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4206 /* translator: %s represents an SQL statement name */
4207 errmsg("%s can only be used in transaction blocks",
4208 "SAVEPOINT")));
4209 break;
4211 /* These cases are invalid. */
4212 case TBLOCK_DEFAULT:
4213 case TBLOCK_STARTED:
4214 case TBLOCK_BEGIN:
4215 case TBLOCK_PARALLEL_INPROGRESS:
4216 case TBLOCK_SUBBEGIN:
4217 case TBLOCK_END:
4218 case TBLOCK_SUBRELEASE:
4219 case TBLOCK_SUBCOMMIT:
4220 case TBLOCK_ABORT:
4221 case TBLOCK_SUBABORT:
4222 case TBLOCK_ABORT_END:
4223 case TBLOCK_SUBABORT_END:
4224 case TBLOCK_ABORT_PENDING:
4225 case TBLOCK_SUBABORT_PENDING:
4226 case TBLOCK_SUBRESTART:
4227 case TBLOCK_SUBABORT_RESTART:
4228 case TBLOCK_PREPARE:
4229 elog(FATAL, "DefineSavepoint: unexpected state %s",
4230 BlockStateAsString(s->blockState));
4231 break;
4236 * ReleaseSavepoint
4237 * This executes a RELEASE command.
4239 * As above, we don't actually do anything here except change blockState.
4241 void
4242 ReleaseSavepoint(const char *name)
4244 TransactionState s = CurrentTransactionState;
4245 TransactionState target,
4246 xact;
4249 * Workers synchronize transaction state at the beginning of each parallel
4250 * operation, so we can't account for transaction state change after that
4251 * point. (Note that this check will certainly error out if s->blockState
4252 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4253 * below.)
4255 if (IsInParallelMode())
4256 ereport(ERROR,
4257 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4258 errmsg("cannot release savepoints during a parallel operation")));
4260 switch (s->blockState)
4263 * We can't release a savepoint if there is no savepoint defined.
4265 case TBLOCK_INPROGRESS:
4266 ereport(ERROR,
4267 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4268 errmsg("savepoint \"%s\" does not exist", name)));
4269 break;
4271 case TBLOCK_IMPLICIT_INPROGRESS:
4272 /* See comment about implicit transactions in DefineSavepoint */
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 "RELEASE SAVEPOINT")));
4278 break;
4281 * We are in a non-aborted subtransaction. This is the only valid
4282 * case.
4284 case TBLOCK_SUBINPROGRESS:
4285 break;
4287 /* These cases are invalid. */
4288 case TBLOCK_DEFAULT:
4289 case TBLOCK_STARTED:
4290 case TBLOCK_BEGIN:
4291 case TBLOCK_PARALLEL_INPROGRESS:
4292 case TBLOCK_SUBBEGIN:
4293 case TBLOCK_END:
4294 case TBLOCK_SUBRELEASE:
4295 case TBLOCK_SUBCOMMIT:
4296 case TBLOCK_ABORT:
4297 case TBLOCK_SUBABORT:
4298 case TBLOCK_ABORT_END:
4299 case TBLOCK_SUBABORT_END:
4300 case TBLOCK_ABORT_PENDING:
4301 case TBLOCK_SUBABORT_PENDING:
4302 case TBLOCK_SUBRESTART:
4303 case TBLOCK_SUBABORT_RESTART:
4304 case TBLOCK_PREPARE:
4305 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4306 BlockStateAsString(s->blockState));
4307 break;
4310 for (target = s; PointerIsValid(target); target = target->parent)
4312 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4313 break;
4316 if (!PointerIsValid(target))
4317 ereport(ERROR,
4318 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4319 errmsg("savepoint \"%s\" does not exist", name)));
4321 /* disallow crossing savepoint level boundaries */
4322 if (target->savepointLevel != s->savepointLevel)
4323 ereport(ERROR,
4324 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4325 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4328 * Mark "commit pending" all subtransactions up to the target
4329 * subtransaction. The actual commits will happen when control gets to
4330 * CommitTransactionCommand.
4332 xact = CurrentTransactionState;
4333 for (;;)
4335 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
4336 xact->blockState = TBLOCK_SUBRELEASE;
4337 if (xact == target)
4338 break;
4339 xact = xact->parent;
4340 Assert(PointerIsValid(xact));
4345 * RollbackToSavepoint
4346 * This executes a ROLLBACK TO <savepoint> command.
4348 * As above, we don't actually do anything here except change blockState.
4350 void
4351 RollbackToSavepoint(const char *name)
4353 TransactionState s = CurrentTransactionState;
4354 TransactionState target,
4355 xact;
4358 * Workers synchronize transaction state at the beginning of each parallel
4359 * operation, so we can't account for transaction state change after that
4360 * point. (Note that this check will certainly error out if s->blockState
4361 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4362 * below.)
4364 if (IsInParallelMode())
4365 ereport(ERROR,
4366 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4367 errmsg("cannot rollback to savepoints during a parallel operation")));
4369 switch (s->blockState)
4372 * We can't rollback to a savepoint if there is no savepoint
4373 * defined.
4375 case TBLOCK_INPROGRESS:
4376 case TBLOCK_ABORT:
4377 ereport(ERROR,
4378 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4379 errmsg("savepoint \"%s\" does not exist", name)));
4380 break;
4382 case TBLOCK_IMPLICIT_INPROGRESS:
4383 /* See comment about implicit transactions in DefineSavepoint */
4384 ereport(ERROR,
4385 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4386 /* translator: %s represents an SQL statement name */
4387 errmsg("%s can only be used in transaction blocks",
4388 "ROLLBACK TO SAVEPOINT")));
4389 break;
4392 * There is at least one savepoint, so proceed.
4394 case TBLOCK_SUBINPROGRESS:
4395 case TBLOCK_SUBABORT:
4396 break;
4398 /* These cases are invalid. */
4399 case TBLOCK_DEFAULT:
4400 case TBLOCK_STARTED:
4401 case TBLOCK_BEGIN:
4402 case TBLOCK_PARALLEL_INPROGRESS:
4403 case TBLOCK_SUBBEGIN:
4404 case TBLOCK_END:
4405 case TBLOCK_SUBRELEASE:
4406 case TBLOCK_SUBCOMMIT:
4407 case TBLOCK_ABORT_END:
4408 case TBLOCK_SUBABORT_END:
4409 case TBLOCK_ABORT_PENDING:
4410 case TBLOCK_SUBABORT_PENDING:
4411 case TBLOCK_SUBRESTART:
4412 case TBLOCK_SUBABORT_RESTART:
4413 case TBLOCK_PREPARE:
4414 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4415 BlockStateAsString(s->blockState));
4416 break;
4419 for (target = s; PointerIsValid(target); target = target->parent)
4421 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4422 break;
4425 if (!PointerIsValid(target))
4426 ereport(ERROR,
4427 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4428 errmsg("savepoint \"%s\" does not exist", name)));
4430 /* disallow crossing savepoint level boundaries */
4431 if (target->savepointLevel != s->savepointLevel)
4432 ereport(ERROR,
4433 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4434 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4437 * Mark "abort pending" all subtransactions up to the target
4438 * subtransaction. The actual aborts will happen when control gets to
4439 * CommitTransactionCommand.
4441 xact = CurrentTransactionState;
4442 for (;;)
4444 if (xact == target)
4445 break;
4446 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4447 xact->blockState = TBLOCK_SUBABORT_PENDING;
4448 else if (xact->blockState == TBLOCK_SUBABORT)
4449 xact->blockState = TBLOCK_SUBABORT_END;
4450 else
4451 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4452 BlockStateAsString(xact->blockState));
4453 xact = xact->parent;
4454 Assert(PointerIsValid(xact));
4457 /* And mark the target as "restart pending" */
4458 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4459 xact->blockState = TBLOCK_SUBRESTART;
4460 else if (xact->blockState == TBLOCK_SUBABORT)
4461 xact->blockState = TBLOCK_SUBABORT_RESTART;
4462 else
4463 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4464 BlockStateAsString(xact->blockState));
4468 * BeginInternalSubTransaction
4469 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
4470 * TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_END, and TBLOCK_PREPARE states,
4471 * and therefore it can safely be used in functions that might be called
4472 * when not inside a BEGIN block or when running deferred triggers at
4473 * COMMIT/PREPARE time. Also, it automatically does
4474 * CommitTransactionCommand/StartTransactionCommand instead of expecting
4475 * the caller to do it.
4477 void
4478 BeginInternalSubTransaction(const char *name)
4480 TransactionState s = CurrentTransactionState;
4483 * Workers synchronize transaction state at the beginning of each parallel
4484 * operation, so we can't account for new subtransactions after that
4485 * point. We might be able to make an exception for the type of
4486 * subtransaction established by this function, which is typically used in
4487 * contexts where we're going to release or roll back the subtransaction
4488 * before proceeding further, so that no enduring change to the
4489 * transaction state occurs. For now, however, we prohibit this case along
4490 * with all the others.
4492 if (IsInParallelMode())
4493 ereport(ERROR,
4494 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4495 errmsg("cannot start subtransactions during a parallel operation")));
4497 switch (s->blockState)
4499 case TBLOCK_STARTED:
4500 case TBLOCK_INPROGRESS:
4501 case TBLOCK_IMPLICIT_INPROGRESS:
4502 case TBLOCK_END:
4503 case TBLOCK_PREPARE:
4504 case TBLOCK_SUBINPROGRESS:
4505 /* Normal subtransaction start */
4506 PushTransaction();
4507 s = CurrentTransactionState; /* changed by push */
4510 * Savepoint names, like the TransactionState block itself, live
4511 * in TopTransactionContext.
4513 if (name)
4514 s->name = MemoryContextStrdup(TopTransactionContext, name);
4515 break;
4517 /* These cases are invalid. */
4518 case TBLOCK_DEFAULT:
4519 case TBLOCK_BEGIN:
4520 case TBLOCK_PARALLEL_INPROGRESS:
4521 case TBLOCK_SUBBEGIN:
4522 case TBLOCK_SUBRELEASE:
4523 case TBLOCK_SUBCOMMIT:
4524 case TBLOCK_ABORT:
4525 case TBLOCK_SUBABORT:
4526 case TBLOCK_ABORT_END:
4527 case TBLOCK_SUBABORT_END:
4528 case TBLOCK_ABORT_PENDING:
4529 case TBLOCK_SUBABORT_PENDING:
4530 case TBLOCK_SUBRESTART:
4531 case TBLOCK_SUBABORT_RESTART:
4532 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4533 BlockStateAsString(s->blockState));
4534 break;
4537 CommitTransactionCommand();
4538 StartTransactionCommand();
4542 * ReleaseCurrentSubTransaction
4544 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
4545 * savepoint name (if any).
4546 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4548 void
4549 ReleaseCurrentSubTransaction(void)
4551 TransactionState s = CurrentTransactionState;
4554 * Workers synchronize transaction state at the beginning of each parallel
4555 * operation, so we can't account for commit of subtransactions after that
4556 * point. This should not happen anyway. Code calling this would
4557 * typically have called BeginInternalSubTransaction() first, failing
4558 * there.
4560 if (IsInParallelMode())
4561 ereport(ERROR,
4562 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4563 errmsg("cannot commit subtransactions during a parallel operation")));
4565 if (s->blockState != TBLOCK_SUBINPROGRESS)
4566 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4567 BlockStateAsString(s->blockState));
4568 Assert(s->state == TRANS_INPROGRESS);
4569 MemoryContextSwitchTo(CurTransactionContext);
4570 CommitSubTransaction();
4571 s = CurrentTransactionState; /* changed by pop */
4572 Assert(s->state == TRANS_INPROGRESS);
4576 * RollbackAndReleaseCurrentSubTransaction
4578 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
4579 * of its savepoint name (if any).
4580 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4582 void
4583 RollbackAndReleaseCurrentSubTransaction(void)
4585 TransactionState s = CurrentTransactionState;
4588 * Unlike ReleaseCurrentSubTransaction(), this is nominally permitted
4589 * during parallel operations. That's because we may be in the leader,
4590 * recovering from an error thrown while we were in parallel mode. We
4591 * won't reach here in a worker, because BeginInternalSubTransaction()
4592 * will have failed.
4595 switch (s->blockState)
4597 /* Must be in a subtransaction */
4598 case TBLOCK_SUBINPROGRESS:
4599 case TBLOCK_SUBABORT:
4600 break;
4602 /* These cases are invalid. */
4603 case TBLOCK_DEFAULT:
4604 case TBLOCK_STARTED:
4605 case TBLOCK_BEGIN:
4606 case TBLOCK_IMPLICIT_INPROGRESS:
4607 case TBLOCK_PARALLEL_INPROGRESS:
4608 case TBLOCK_SUBBEGIN:
4609 case TBLOCK_INPROGRESS:
4610 case TBLOCK_END:
4611 case TBLOCK_SUBRELEASE:
4612 case TBLOCK_SUBCOMMIT:
4613 case TBLOCK_ABORT:
4614 case TBLOCK_ABORT_END:
4615 case TBLOCK_SUBABORT_END:
4616 case TBLOCK_ABORT_PENDING:
4617 case TBLOCK_SUBABORT_PENDING:
4618 case TBLOCK_SUBRESTART:
4619 case TBLOCK_SUBABORT_RESTART:
4620 case TBLOCK_PREPARE:
4621 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4622 BlockStateAsString(s->blockState));
4623 break;
4627 * Abort the current subtransaction, if needed.
4629 if (s->blockState == TBLOCK_SUBINPROGRESS)
4630 AbortSubTransaction();
4632 /* And clean it up, too */
4633 CleanupSubTransaction();
4635 s = CurrentTransactionState; /* changed by pop */
4636 AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
4637 s->blockState == TBLOCK_INPROGRESS ||
4638 s->blockState == TBLOCK_IMPLICIT_INPROGRESS ||
4639 s->blockState == TBLOCK_STARTED);
4643 * AbortOutOfAnyTransaction
4645 * This routine is provided for error recovery purposes. It aborts any
4646 * active transaction or transaction block, leaving the system in a known
4647 * idle state.
4649 void
4650 AbortOutOfAnyTransaction(void)
4652 TransactionState s = CurrentTransactionState;
4654 /* Ensure we're not running in a doomed memory context */
4655 AtAbort_Memory();
4658 * Get out of any transaction or nested transaction
4662 switch (s->blockState)
4664 case TBLOCK_DEFAULT:
4665 if (s->state == TRANS_DEFAULT)
4667 /* Not in a transaction, do nothing */
4669 else
4672 * We can get here after an error during transaction start
4673 * (state will be TRANS_START). Need to clean up the
4674 * incompletely started transaction. First, adjust the
4675 * low-level state to suppress warning message from
4676 * AbortTransaction.
4678 if (s->state == TRANS_START)
4679 s->state = TRANS_INPROGRESS;
4680 AbortTransaction();
4681 CleanupTransaction();
4683 break;
4684 case TBLOCK_STARTED:
4685 case TBLOCK_BEGIN:
4686 case TBLOCK_INPROGRESS:
4687 case TBLOCK_IMPLICIT_INPROGRESS:
4688 case TBLOCK_PARALLEL_INPROGRESS:
4689 case TBLOCK_END:
4690 case TBLOCK_ABORT_PENDING:
4691 case TBLOCK_PREPARE:
4692 /* In a transaction, so clean up */
4693 AbortTransaction();
4694 CleanupTransaction();
4695 s->blockState = TBLOCK_DEFAULT;
4696 break;
4697 case TBLOCK_ABORT:
4698 case TBLOCK_ABORT_END:
4701 * AbortTransaction is already done, still need Cleanup.
4702 * However, if we failed partway through running ROLLBACK,
4703 * there will be an active portal running that command, which
4704 * we need to shut down before doing CleanupTransaction.
4706 AtAbort_Portals();
4707 CleanupTransaction();
4708 s->blockState = TBLOCK_DEFAULT;
4709 break;
4712 * In a subtransaction, so clean it up and abort parent too
4714 case TBLOCK_SUBBEGIN:
4715 case TBLOCK_SUBINPROGRESS:
4716 case TBLOCK_SUBRELEASE:
4717 case TBLOCK_SUBCOMMIT:
4718 case TBLOCK_SUBABORT_PENDING:
4719 case TBLOCK_SUBRESTART:
4720 AbortSubTransaction();
4721 CleanupSubTransaction();
4722 s = CurrentTransactionState; /* changed by pop */
4723 break;
4725 case TBLOCK_SUBABORT:
4726 case TBLOCK_SUBABORT_END:
4727 case TBLOCK_SUBABORT_RESTART:
4728 /* As above, but AbortSubTransaction already done */
4729 if (s->curTransactionOwner)
4731 /* As in TBLOCK_ABORT, might have a live portal to zap */
4732 AtSubAbort_Portals(s->subTransactionId,
4733 s->parent->subTransactionId,
4734 s->curTransactionOwner,
4735 s->parent->curTransactionOwner);
4737 CleanupSubTransaction();
4738 s = CurrentTransactionState; /* changed by pop */
4739 break;
4741 } while (s->blockState != TBLOCK_DEFAULT);
4743 /* Should be out of all subxacts now */
4744 Assert(s->parent == NULL);
4746 /* If we didn't actually have anything to do, revert to TopMemoryContext */
4747 AtCleanup_Memory();
4751 * IsTransactionBlock --- are we within a transaction block?
4753 bool
4754 IsTransactionBlock(void)
4756 TransactionState s = CurrentTransactionState;
4758 if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
4759 return false;
4761 return true;
4765 * IsTransactionOrTransactionBlock --- are we within either a transaction
4766 * or a transaction block? (The backend is only really "idle" when this
4767 * returns false.)
4769 * This should match up with IsTransactionBlock and IsTransactionState.
4771 bool
4772 IsTransactionOrTransactionBlock(void)
4774 TransactionState s = CurrentTransactionState;
4776 if (s->blockState == TBLOCK_DEFAULT)
4777 return false;
4779 return true;
4783 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
4785 char
4786 TransactionBlockStatusCode(void)
4788 TransactionState s = CurrentTransactionState;
4790 switch (s->blockState)
4792 case TBLOCK_DEFAULT:
4793 case TBLOCK_STARTED:
4794 return 'I'; /* idle --- not in transaction */
4795 case TBLOCK_BEGIN:
4796 case TBLOCK_SUBBEGIN:
4797 case TBLOCK_INPROGRESS:
4798 case TBLOCK_IMPLICIT_INPROGRESS:
4799 case TBLOCK_PARALLEL_INPROGRESS:
4800 case TBLOCK_SUBINPROGRESS:
4801 case TBLOCK_END:
4802 case TBLOCK_SUBRELEASE:
4803 case TBLOCK_SUBCOMMIT:
4804 case TBLOCK_PREPARE:
4805 return 'T'; /* in transaction */
4806 case TBLOCK_ABORT:
4807 case TBLOCK_SUBABORT:
4808 case TBLOCK_ABORT_END:
4809 case TBLOCK_SUBABORT_END:
4810 case TBLOCK_ABORT_PENDING:
4811 case TBLOCK_SUBABORT_PENDING:
4812 case TBLOCK_SUBRESTART:
4813 case TBLOCK_SUBABORT_RESTART:
4814 return 'E'; /* in failed transaction */
4817 /* should never get here */
4818 elog(FATAL, "invalid transaction block state: %s",
4819 BlockStateAsString(s->blockState));
4820 return 0; /* keep compiler quiet */
4824 * IsSubTransaction
4826 bool
4827 IsSubTransaction(void)
4829 TransactionState s = CurrentTransactionState;
4831 if (s->nestingLevel >= 2)
4832 return true;
4834 return false;
4838 * StartSubTransaction
4840 * If you're wondering why this is separate from PushTransaction: it's because
4841 * we can't conveniently do this stuff right inside DefineSavepoint. The
4842 * SAVEPOINT utility command will be executed inside a Portal, and if we
4843 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
4844 * the Portal will undo those settings. So we make DefineSavepoint just
4845 * push a dummy transaction block, and when control returns to the main
4846 * idle loop, CommitTransactionCommand will be called, and we'll come here
4847 * to finish starting the subtransaction.
4849 static void
4850 StartSubTransaction(void)
4852 TransactionState s = CurrentTransactionState;
4854 if (s->state != TRANS_DEFAULT)
4855 elog(WARNING, "StartSubTransaction while in %s state",
4856 TransStateAsString(s->state));
4858 s->state = TRANS_START;
4861 * Initialize subsystems for new subtransaction
4863 * must initialize resource-management stuff first
4865 AtSubStart_Memory();
4866 AtSubStart_ResourceOwner();
4867 AfterTriggerBeginSubXact();
4869 s->state = TRANS_INPROGRESS;
4872 * Call start-of-subxact callbacks
4874 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
4875 s->parent->subTransactionId);
4877 ShowTransactionState("StartSubTransaction");
4881 * CommitSubTransaction
4883 * The caller has to make sure to always reassign CurrentTransactionState
4884 * if it has a local pointer to it after calling this function.
4886 static void
4887 CommitSubTransaction(void)
4889 TransactionState s = CurrentTransactionState;
4891 ShowTransactionState("CommitSubTransaction");
4893 if (s->state != TRANS_INPROGRESS)
4894 elog(WARNING, "CommitSubTransaction while in %s state",
4895 TransStateAsString(s->state));
4897 /* Pre-commit processing goes here */
4899 CallSubXactCallbacks(SUBXACT_EVENT_PRE_COMMIT_SUB, s->subTransactionId,
4900 s->parent->subTransactionId);
4902 /* If in parallel mode, clean up workers and exit parallel mode. */
4903 if (IsInParallelMode())
4905 AtEOSubXact_Parallel(true, s->subTransactionId);
4906 s->parallelModeLevel = 0;
4909 /* Do the actual "commit", such as it is */
4910 s->state = TRANS_COMMIT;
4912 /* Must CCI to ensure commands of subtransaction are seen as done */
4913 CommandCounterIncrement();
4916 * Prior to 8.4 we marked subcommit in clog at this point. We now only
4917 * perform that step, if required, as part of the atomic update of the
4918 * whole transaction tree at top level commit or abort.
4921 /* Post-commit cleanup */
4922 if (FullTransactionIdIsValid(s->fullTransactionId))
4923 AtSubCommit_childXids();
4924 AfterTriggerEndSubXact(true);
4925 AtSubCommit_Portals(s->subTransactionId,
4926 s->parent->subTransactionId,
4927 s->parent->nestingLevel,
4928 s->parent->curTransactionOwner);
4929 AtEOSubXact_LargeObject(true, s->subTransactionId,
4930 s->parent->subTransactionId);
4931 AtSubCommit_Notify();
4933 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
4934 s->parent->subTransactionId);
4936 ResourceOwnerRelease(s->curTransactionOwner,
4937 RESOURCE_RELEASE_BEFORE_LOCKS,
4938 true, false);
4939 AtEOSubXact_RelationCache(true, s->subTransactionId,
4940 s->parent->subTransactionId);
4941 AtEOSubXact_Inval(true);
4942 AtSubCommit_smgr();
4945 * The only lock we actually release here is the subtransaction XID lock.
4947 CurrentResourceOwner = s->curTransactionOwner;
4948 if (FullTransactionIdIsValid(s->fullTransactionId))
4949 XactLockTableDelete(XidFromFullTransactionId(s->fullTransactionId));
4952 * Other locks should get transferred to their parent resource owner.
4954 ResourceOwnerRelease(s->curTransactionOwner,
4955 RESOURCE_RELEASE_LOCKS,
4956 true, false);
4957 ResourceOwnerRelease(s->curTransactionOwner,
4958 RESOURCE_RELEASE_AFTER_LOCKS,
4959 true, false);
4961 AtEOXact_GUC(true, s->gucNestLevel);
4962 AtEOSubXact_SPI(true, s->subTransactionId);
4963 AtEOSubXact_on_commit_actions(true, s->subTransactionId,
4964 s->parent->subTransactionId);
4965 AtEOSubXact_Namespace(true, s->subTransactionId,
4966 s->parent->subTransactionId);
4967 AtEOSubXact_Files(true, s->subTransactionId,
4968 s->parent->subTransactionId);
4969 AtEOSubXact_HashTables(true, s->nestingLevel);
4970 AtEOSubXact_PgStat(true, s->nestingLevel);
4971 AtSubCommit_Snapshot(s->nestingLevel);
4974 * We need to restore the upper transaction's read-only state, in case the
4975 * upper is read-write while the child is read-only; GUC will incorrectly
4976 * think it should leave the child state in place.
4978 XactReadOnly = s->prevXactReadOnly;
4980 CurrentResourceOwner = s->parent->curTransactionOwner;
4981 CurTransactionResourceOwner = s->parent->curTransactionOwner;
4982 ResourceOwnerDelete(s->curTransactionOwner);
4983 s->curTransactionOwner = NULL;
4985 AtSubCommit_Memory();
4987 s->state = TRANS_DEFAULT;
4989 PopTransaction();
4993 * AbortSubTransaction
4995 static void
4996 AbortSubTransaction(void)
4998 TransactionState s = CurrentTransactionState;
5000 /* Prevent cancel/die interrupt while cleaning up */
5001 HOLD_INTERRUPTS();
5003 /* Make sure we have a valid memory context and resource owner */
5004 AtSubAbort_Memory();
5005 AtSubAbort_ResourceOwner();
5008 * Release any LW locks we might be holding as quickly as possible.
5009 * (Regular locks, however, must be held till we finish aborting.)
5010 * Releasing LW locks is critical since we might try to grab them again
5011 * while cleaning up!
5013 * FIXME This may be incorrect --- Are there some locks we should keep?
5014 * Buffer locks, for example? I don't think so but I'm not sure.
5016 LWLockReleaseAll();
5018 pgstat_report_wait_end();
5019 pgstat_progress_end_command();
5020 AbortBufferIO();
5021 UnlockBuffers();
5023 /* Reset WAL record construction state */
5024 XLogResetInsertion();
5026 /* Cancel condition variable sleep */
5027 ConditionVariableCancelSleep();
5030 * Also clean up any open wait for lock, since the lock manager will choke
5031 * if we try to wait for another lock before doing this.
5033 LockErrorCleanup();
5036 * If any timeout events are still active, make sure the timeout interrupt
5037 * is scheduled. This covers possible loss of a timeout interrupt due to
5038 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5039 * We delay this till after LockErrorCleanup so that we don't uselessly
5040 * reschedule lock or deadlock check timeouts.
5042 reschedule_timeouts();
5045 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5046 * handler. We do this fairly early in the sequence so that the timeout
5047 * infrastructure will be functional if needed while aborting.
5049 PG_SETMASK(&UnBlockSig);
5052 * check the current transaction state
5054 ShowTransactionState("AbortSubTransaction");
5056 if (s->state != TRANS_INPROGRESS)
5057 elog(WARNING, "AbortSubTransaction while in %s state",
5058 TransStateAsString(s->state));
5060 s->state = TRANS_ABORT;
5063 * Reset user ID which might have been changed transiently. (See notes in
5064 * AbortTransaction.)
5066 SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
5068 /* Forget about any active REINDEX. */
5069 ResetReindexState(s->nestingLevel);
5071 /* Reset logical streaming state. */
5072 ResetLogicalStreamingState();
5075 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5076 * exports are not supported in subtransactions.
5079 /* Exit from parallel mode, if necessary. */
5080 if (IsInParallelMode())
5082 AtEOSubXact_Parallel(false, s->subTransactionId);
5083 s->parallelModeLevel = 0;
5087 * We can skip all this stuff if the subxact failed before creating a
5088 * ResourceOwner...
5090 if (s->curTransactionOwner)
5092 AfterTriggerEndSubXact(false);
5093 AtSubAbort_Portals(s->subTransactionId,
5094 s->parent->subTransactionId,
5095 s->curTransactionOwner,
5096 s->parent->curTransactionOwner);
5097 AtEOSubXact_LargeObject(false, s->subTransactionId,
5098 s->parent->subTransactionId);
5099 AtSubAbort_Notify();
5101 /* Advertise the fact that we aborted in pg_xact. */
5102 (void) RecordTransactionAbort(true);
5104 /* Post-abort cleanup */
5105 if (FullTransactionIdIsValid(s->fullTransactionId))
5106 AtSubAbort_childXids();
5108 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
5109 s->parent->subTransactionId);
5111 ResourceOwnerRelease(s->curTransactionOwner,
5112 RESOURCE_RELEASE_BEFORE_LOCKS,
5113 false, false);
5114 AtEOSubXact_RelationCache(false, s->subTransactionId,
5115 s->parent->subTransactionId);
5116 AtEOSubXact_Inval(false);
5117 ResourceOwnerRelease(s->curTransactionOwner,
5118 RESOURCE_RELEASE_LOCKS,
5119 false, false);
5120 ResourceOwnerRelease(s->curTransactionOwner,
5121 RESOURCE_RELEASE_AFTER_LOCKS,
5122 false, false);
5123 AtSubAbort_smgr();
5125 AtEOXact_GUC(false, s->gucNestLevel);
5126 AtEOSubXact_SPI(false, s->subTransactionId);
5127 AtEOSubXact_on_commit_actions(false, s->subTransactionId,
5128 s->parent->subTransactionId);
5129 AtEOSubXact_Namespace(false, s->subTransactionId,
5130 s->parent->subTransactionId);
5131 AtEOSubXact_Files(false, s->subTransactionId,
5132 s->parent->subTransactionId);
5133 AtEOSubXact_HashTables(false, s->nestingLevel);
5134 AtEOSubXact_PgStat(false, s->nestingLevel);
5135 AtSubAbort_Snapshot(s->nestingLevel);
5139 * Restore the upper transaction's read-only state, too. This should be
5140 * redundant with GUC's cleanup but we may as well do it for consistency
5141 * with the commit case.
5143 XactReadOnly = s->prevXactReadOnly;
5145 RESUME_INTERRUPTS();
5149 * CleanupSubTransaction
5151 * The caller has to make sure to always reassign CurrentTransactionState
5152 * if it has a local pointer to it after calling this function.
5154 static void
5155 CleanupSubTransaction(void)
5157 TransactionState s = CurrentTransactionState;
5159 ShowTransactionState("CleanupSubTransaction");
5161 if (s->state != TRANS_ABORT)
5162 elog(WARNING, "CleanupSubTransaction while in %s state",
5163 TransStateAsString(s->state));
5165 AtSubCleanup_Portals(s->subTransactionId);
5167 CurrentResourceOwner = s->parent->curTransactionOwner;
5168 CurTransactionResourceOwner = s->parent->curTransactionOwner;
5169 if (s->curTransactionOwner)
5170 ResourceOwnerDelete(s->curTransactionOwner);
5171 s->curTransactionOwner = NULL;
5173 AtSubCleanup_Memory();
5175 s->state = TRANS_DEFAULT;
5177 PopTransaction();
5181 * PushTransaction
5182 * Create transaction state stack entry for a subtransaction
5184 * The caller has to make sure to always reassign CurrentTransactionState
5185 * if it has a local pointer to it after calling this function.
5187 static void
5188 PushTransaction(void)
5190 TransactionState p = CurrentTransactionState;
5191 TransactionState s;
5194 * We keep subtransaction state nodes in TopTransactionContext.
5196 s = (TransactionState)
5197 MemoryContextAllocZero(TopTransactionContext,
5198 sizeof(TransactionStateData));
5201 * Assign a subtransaction ID, watching out for counter wraparound.
5203 currentSubTransactionId += 1;
5204 if (currentSubTransactionId == InvalidSubTransactionId)
5206 currentSubTransactionId -= 1;
5207 pfree(s);
5208 ereport(ERROR,
5209 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5210 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5214 * We can now stack a minimally valid subtransaction without fear of
5215 * failure.
5217 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5218 s->subTransactionId = currentSubTransactionId;
5219 s->parent = p;
5220 s->nestingLevel = p->nestingLevel + 1;
5221 s->gucNestLevel = NewGUCNestLevel();
5222 s->savepointLevel = p->savepointLevel;
5223 s->state = TRANS_DEFAULT;
5224 s->blockState = TBLOCK_SUBBEGIN;
5225 GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
5226 s->prevXactReadOnly = XactReadOnly;
5227 s->parallelModeLevel = 0;
5228 s->topXidLogged = false;
5230 CurrentTransactionState = s;
5233 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5234 * with the subtransaction from here on out; in particular they should not
5235 * assume that it necessarily has a transaction context, resource owner,
5236 * or XID.
5241 * PopTransaction
5242 * Pop back to parent transaction state
5244 * The caller has to make sure to always reassign CurrentTransactionState
5245 * if it has a local pointer to it after calling this function.
5247 static void
5248 PopTransaction(void)
5250 TransactionState s = CurrentTransactionState;
5252 if (s->state != TRANS_DEFAULT)
5253 elog(WARNING, "PopTransaction while in %s state",
5254 TransStateAsString(s->state));
5256 if (s->parent == NULL)
5257 elog(FATAL, "PopTransaction with no parent");
5259 CurrentTransactionState = s->parent;
5261 /* Let's just make sure CurTransactionContext is good */
5262 CurTransactionContext = s->parent->curTransactionContext;
5263 MemoryContextSwitchTo(CurTransactionContext);
5265 /* Ditto for ResourceOwner links */
5266 CurTransactionResourceOwner = s->parent->curTransactionOwner;
5267 CurrentResourceOwner = s->parent->curTransactionOwner;
5269 /* Free the old child structure */
5270 if (s->name)
5271 pfree(s->name);
5272 pfree(s);
5276 * EstimateTransactionStateSpace
5277 * Estimate the amount of space that will be needed by
5278 * SerializeTransactionState. It would be OK to overestimate slightly,
5279 * but it's simple for us to work out the precise value, so we do.
5281 Size
5282 EstimateTransactionStateSpace(void)
5284 TransactionState s;
5285 Size nxids = 0;
5286 Size size = SerializedTransactionStateHeaderSize;
5288 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5290 if (FullTransactionIdIsValid(s->fullTransactionId))
5291 nxids = add_size(nxids, 1);
5292 nxids = add_size(nxids, s->nChildXids);
5295 return add_size(size, mul_size(sizeof(TransactionId), nxids));
5299 * SerializeTransactionState
5300 * Write out relevant details of our transaction state that will be
5301 * needed by a parallel worker.
5303 * We need to save and restore XactDeferrable, XactIsoLevel, and the XIDs
5304 * associated with this transaction. These are serialized into a
5305 * caller-supplied buffer big enough to hold the number of bytes reported by
5306 * EstimateTransactionStateSpace(). We emit the XIDs in sorted order for the
5307 * convenience of the receiving process.
5309 void
5310 SerializeTransactionState(Size maxsize, char *start_address)
5312 TransactionState s;
5313 Size nxids = 0;
5314 Size i = 0;
5315 TransactionId *workspace;
5316 SerializedTransactionState *result;
5318 result = (SerializedTransactionState *) start_address;
5320 result->xactIsoLevel = XactIsoLevel;
5321 result->xactDeferrable = XactDeferrable;
5322 result->topFullTransactionId = XactTopFullTransactionId;
5323 result->currentFullTransactionId =
5324 CurrentTransactionState->fullTransactionId;
5325 result->currentCommandId = currentCommandId;
5328 * If we're running in a parallel worker and launching a parallel worker
5329 * of our own, we can just pass along the information that was passed to
5330 * us.
5332 if (nParallelCurrentXids > 0)
5334 result->nParallelCurrentXids = nParallelCurrentXids;
5335 memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
5336 nParallelCurrentXids * sizeof(TransactionId));
5337 return;
5341 * OK, we need to generate a sorted list of XIDs that our workers should
5342 * view as current. First, figure out how many there are.
5344 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5346 if (FullTransactionIdIsValid(s->fullTransactionId))
5347 nxids = add_size(nxids, 1);
5348 nxids = add_size(nxids, s->nChildXids);
5350 Assert(SerializedTransactionStateHeaderSize + nxids * sizeof(TransactionId)
5351 <= maxsize);
5353 /* Copy them to our scratch space. */
5354 workspace = palloc(nxids * sizeof(TransactionId));
5355 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5357 if (FullTransactionIdIsValid(s->fullTransactionId))
5358 workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5359 memcpy(&workspace[i], s->childXids,
5360 s->nChildXids * sizeof(TransactionId));
5361 i += s->nChildXids;
5363 Assert(i == nxids);
5365 /* Sort them. */
5366 qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5368 /* Copy data into output area. */
5369 result->nParallelCurrentXids = nxids;
5370 memcpy(&result->parallelCurrentXids[0], workspace,
5371 nxids * sizeof(TransactionId));
5375 * StartParallelWorkerTransaction
5376 * Start a parallel worker transaction, restoring the relevant
5377 * transaction state serialized by SerializeTransactionState.
5379 void
5380 StartParallelWorkerTransaction(char *tstatespace)
5382 SerializedTransactionState *tstate;
5384 Assert(CurrentTransactionState->blockState == TBLOCK_DEFAULT);
5385 StartTransaction();
5387 tstate = (SerializedTransactionState *) tstatespace;
5388 XactIsoLevel = tstate->xactIsoLevel;
5389 XactDeferrable = tstate->xactDeferrable;
5390 XactTopFullTransactionId = tstate->topFullTransactionId;
5391 CurrentTransactionState->fullTransactionId =
5392 tstate->currentFullTransactionId;
5393 currentCommandId = tstate->currentCommandId;
5394 nParallelCurrentXids = tstate->nParallelCurrentXids;
5395 ParallelCurrentXids = &tstate->parallelCurrentXids[0];
5397 CurrentTransactionState->blockState = TBLOCK_PARALLEL_INPROGRESS;
5401 * EndParallelWorkerTransaction
5402 * End a parallel worker transaction.
5404 void
5405 EndParallelWorkerTransaction(void)
5407 Assert(CurrentTransactionState->blockState == TBLOCK_PARALLEL_INPROGRESS);
5408 CommitTransaction();
5409 CurrentTransactionState->blockState = TBLOCK_DEFAULT;
5413 * ShowTransactionState
5414 * Debug support
5416 static void
5417 ShowTransactionState(const char *str)
5419 /* skip work if message will definitely not be printed */
5420 if (message_level_is_interesting(DEBUG5))
5421 ShowTransactionStateRec(str, CurrentTransactionState);
5425 * ShowTransactionStateRec
5426 * Recursive subroutine for ShowTransactionState
5428 static void
5429 ShowTransactionStateRec(const char *str, TransactionState s)
5431 StringInfoData buf;
5433 initStringInfo(&buf);
5435 if (s->nChildXids > 0)
5437 int i;
5439 appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5440 for (i = 1; i < s->nChildXids; i++)
5441 appendStringInfo(&buf, " %u", s->childXids[i]);
5444 if (s->parent)
5445 ShowTransactionStateRec(str, s->parent);
5447 ereport(DEBUG5,
5448 (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5449 str, s->nestingLevel,
5450 PointerIsValid(s->name) ? s->name : "unnamed",
5451 BlockStateAsString(s->blockState),
5452 TransStateAsString(s->state),
5453 (unsigned int) XidFromFullTransactionId(s->fullTransactionId),
5454 (unsigned int) s->subTransactionId,
5455 (unsigned int) currentCommandId,
5456 currentCommandIdUsed ? " (used)" : "",
5457 buf.data)));
5459 pfree(buf.data);
5463 * BlockStateAsString
5464 * Debug support
5466 static const char *
5467 BlockStateAsString(TBlockState blockState)
5469 switch (blockState)
5471 case TBLOCK_DEFAULT:
5472 return "DEFAULT";
5473 case TBLOCK_STARTED:
5474 return "STARTED";
5475 case TBLOCK_BEGIN:
5476 return "BEGIN";
5477 case TBLOCK_INPROGRESS:
5478 return "INPROGRESS";
5479 case TBLOCK_IMPLICIT_INPROGRESS:
5480 return "IMPLICIT_INPROGRESS";
5481 case TBLOCK_PARALLEL_INPROGRESS:
5482 return "PARALLEL_INPROGRESS";
5483 case TBLOCK_END:
5484 return "END";
5485 case TBLOCK_ABORT:
5486 return "ABORT";
5487 case TBLOCK_ABORT_END:
5488 return "ABORT_END";
5489 case TBLOCK_ABORT_PENDING:
5490 return "ABORT_PENDING";
5491 case TBLOCK_PREPARE:
5492 return "PREPARE";
5493 case TBLOCK_SUBBEGIN:
5494 return "SUBBEGIN";
5495 case TBLOCK_SUBINPROGRESS:
5496 return "SUBINPROGRESS";
5497 case TBLOCK_SUBRELEASE:
5498 return "SUBRELEASE";
5499 case TBLOCK_SUBCOMMIT:
5500 return "SUBCOMMIT";
5501 case TBLOCK_SUBABORT:
5502 return "SUBABORT";
5503 case TBLOCK_SUBABORT_END:
5504 return "SUBABORT_END";
5505 case TBLOCK_SUBABORT_PENDING:
5506 return "SUBABORT_PENDING";
5507 case TBLOCK_SUBRESTART:
5508 return "SUBRESTART";
5509 case TBLOCK_SUBABORT_RESTART:
5510 return "SUBABORT_RESTART";
5512 return "UNRECOGNIZED";
5516 * TransStateAsString
5517 * Debug support
5519 static const char *
5520 TransStateAsString(TransState state)
5522 switch (state)
5524 case TRANS_DEFAULT:
5525 return "DEFAULT";
5526 case TRANS_START:
5527 return "START";
5528 case TRANS_INPROGRESS:
5529 return "INPROGRESS";
5530 case TRANS_COMMIT:
5531 return "COMMIT";
5532 case TRANS_ABORT:
5533 return "ABORT";
5534 case TRANS_PREPARE:
5535 return "PREPARE";
5537 return "UNRECOGNIZED";
5541 * xactGetCommittedChildren
5543 * Gets the list of committed children of the current transaction. The return
5544 * value is the number of child transactions. *ptr is set to point to an
5545 * array of TransactionIds. The array is allocated in TopTransactionContext;
5546 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
5547 * If there are no subxacts, *ptr is set to NULL.
5550 xactGetCommittedChildren(TransactionId **ptr)
5552 TransactionState s = CurrentTransactionState;
5554 if (s->nChildXids == 0)
5555 *ptr = NULL;
5556 else
5557 *ptr = s->childXids;
5559 return s->nChildXids;
5563 * XLOG support routines
5568 * Log the commit record for a plain or twophase transaction commit.
5570 * A 2pc commit will be emitted when twophase_xid is valid, a plain one
5571 * otherwise.
5573 XLogRecPtr
5574 XactLogCommitRecord(TimestampTz commit_time,
5575 int nsubxacts, TransactionId *subxacts,
5576 int nrels, RelFileNode *rels,
5577 int nmsgs, SharedInvalidationMessage *msgs,
5578 bool relcacheInval,
5579 int xactflags, TransactionId twophase_xid,
5580 const char *twophase_gid)
5582 xl_xact_commit xlrec;
5583 xl_xact_xinfo xl_xinfo;
5584 xl_xact_dbinfo xl_dbinfo;
5585 xl_xact_subxacts xl_subxacts;
5586 xl_xact_relfilenodes xl_relfilenodes;
5587 xl_xact_invals xl_invals;
5588 xl_xact_twophase xl_twophase;
5589 xl_xact_origin xl_origin;
5590 uint8 info;
5592 Assert(CritSectionCount > 0);
5594 xl_xinfo.xinfo = 0;
5596 /* decide between a plain and 2pc commit */
5597 if (!TransactionIdIsValid(twophase_xid))
5598 info = XLOG_XACT_COMMIT;
5599 else
5600 info = XLOG_XACT_COMMIT_PREPARED;
5602 /* First figure out and collect all the information needed */
5604 xlrec.xact_time = commit_time;
5606 if (relcacheInval)
5607 xl_xinfo.xinfo |= XACT_COMPLETION_UPDATE_RELCACHE_FILE;
5608 if (forceSyncCommit)
5609 xl_xinfo.xinfo |= XACT_COMPLETION_FORCE_SYNC_COMMIT;
5610 if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5611 xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5614 * Check if the caller would like to ask standbys for immediate feedback
5615 * once this commit is applied.
5617 if (synchronous_commit >= SYNCHRONOUS_COMMIT_REMOTE_APPLY)
5618 xl_xinfo.xinfo |= XACT_COMPLETION_APPLY_FEEDBACK;
5621 * Relcache invalidations requires information about the current database
5622 * and so does logical decoding.
5624 if (nmsgs > 0 || XLogLogicalInfoActive())
5626 xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5627 xl_dbinfo.dbId = MyDatabaseId;
5628 xl_dbinfo.tsId = MyDatabaseTableSpace;
5631 if (nsubxacts > 0)
5633 xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5634 xl_subxacts.nsubxacts = nsubxacts;
5637 if (nrels > 0)
5639 xl_xinfo.xinfo |= XACT_XINFO_HAS_RELFILENODES;
5640 xl_relfilenodes.nrels = nrels;
5641 info |= XLR_SPECIAL_REL_UPDATE;
5644 if (nmsgs > 0)
5646 xl_xinfo.xinfo |= XACT_XINFO_HAS_INVALS;
5647 xl_invals.nmsgs = nmsgs;
5650 if (TransactionIdIsValid(twophase_xid))
5652 xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5653 xl_twophase.xid = twophase_xid;
5654 Assert(twophase_gid != NULL);
5656 if (XLogLogicalInfoActive())
5657 xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
5660 /* dump transaction origin information */
5661 if (replorigin_session_origin != InvalidRepOriginId)
5663 xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
5665 xl_origin.origin_lsn = replorigin_session_origin_lsn;
5666 xl_origin.origin_timestamp = replorigin_session_origin_timestamp;
5669 if (xl_xinfo.xinfo != 0)
5670 info |= XLOG_XACT_HAS_INFO;
5672 /* Then include all the collected data into the commit record. */
5674 XLogBeginInsert();
5676 XLogRegisterData((char *) (&xlrec), sizeof(xl_xact_commit));
5678 if (xl_xinfo.xinfo != 0)
5679 XLogRegisterData((char *) (&xl_xinfo.xinfo), sizeof(xl_xinfo.xinfo));
5681 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5682 XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
5684 if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5686 XLogRegisterData((char *) (&xl_subxacts),
5687 MinSizeOfXactSubxacts);
5688 XLogRegisterData((char *) subxacts,
5689 nsubxacts * sizeof(TransactionId));
5692 if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILENODES)
5694 XLogRegisterData((char *) (&xl_relfilenodes),
5695 MinSizeOfXactRelfilenodes);
5696 XLogRegisterData((char *) rels,
5697 nrels * sizeof(RelFileNode));
5700 if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
5702 XLogRegisterData((char *) (&xl_invals), MinSizeOfXactInvals);
5703 XLogRegisterData((char *) msgs,
5704 nmsgs * sizeof(SharedInvalidationMessage));
5707 if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5709 XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
5710 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
5711 XLogRegisterData(unconstify(char *, twophase_gid), strlen(twophase_gid) + 1);
5714 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5715 XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
5717 /* we allow filtering by xacts */
5718 XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
5720 return XLogInsert(RM_XACT_ID, info);
5724 * Log the commit record for a plain or twophase transaction abort.
5726 * A 2pc abort will be emitted when twophase_xid is valid, a plain one
5727 * otherwise.
5729 XLogRecPtr
5730 XactLogAbortRecord(TimestampTz abort_time,
5731 int nsubxacts, TransactionId *subxacts,
5732 int nrels, RelFileNode *rels,
5733 int xactflags, TransactionId twophase_xid,
5734 const char *twophase_gid)
5736 xl_xact_abort xlrec;
5737 xl_xact_xinfo xl_xinfo;
5738 xl_xact_subxacts xl_subxacts;
5739 xl_xact_relfilenodes xl_relfilenodes;
5740 xl_xact_twophase xl_twophase;
5741 xl_xact_dbinfo xl_dbinfo;
5742 xl_xact_origin xl_origin;
5744 uint8 info;
5746 Assert(CritSectionCount > 0);
5748 xl_xinfo.xinfo = 0;
5750 /* decide between a plain and 2pc abort */
5751 if (!TransactionIdIsValid(twophase_xid))
5752 info = XLOG_XACT_ABORT;
5753 else
5754 info = XLOG_XACT_ABORT_PREPARED;
5757 /* First figure out and collect all the information needed */
5759 xlrec.xact_time = abort_time;
5761 if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5762 xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5764 if (nsubxacts > 0)
5766 xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5767 xl_subxacts.nsubxacts = nsubxacts;
5770 if (nrels > 0)
5772 xl_xinfo.xinfo |= XACT_XINFO_HAS_RELFILENODES;
5773 xl_relfilenodes.nrels = nrels;
5774 info |= XLR_SPECIAL_REL_UPDATE;
5777 if (TransactionIdIsValid(twophase_xid))
5779 xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5780 xl_twophase.xid = twophase_xid;
5781 Assert(twophase_gid != NULL);
5783 if (XLogLogicalInfoActive())
5784 xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
5787 if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
5789 xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5790 xl_dbinfo.dbId = MyDatabaseId;
5791 xl_dbinfo.tsId = MyDatabaseTableSpace;
5795 * Dump transaction origin information only for abort prepared. We need
5796 * this during recovery to update the replication origin progress.
5798 if ((replorigin_session_origin != InvalidRepOriginId) &&
5799 TransactionIdIsValid(twophase_xid))
5801 xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
5803 xl_origin.origin_lsn = replorigin_session_origin_lsn;
5804 xl_origin.origin_timestamp = replorigin_session_origin_timestamp;
5807 if (xl_xinfo.xinfo != 0)
5808 info |= XLOG_XACT_HAS_INFO;
5810 /* Then include all the collected data into the abort record. */
5812 XLogBeginInsert();
5814 XLogRegisterData((char *) (&xlrec), MinSizeOfXactAbort);
5816 if (xl_xinfo.xinfo != 0)
5817 XLogRegisterData((char *) (&xl_xinfo), sizeof(xl_xinfo));
5819 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5820 XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
5822 if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5824 XLogRegisterData((char *) (&xl_subxacts),
5825 MinSizeOfXactSubxacts);
5826 XLogRegisterData((char *) subxacts,
5827 nsubxacts * sizeof(TransactionId));
5830 if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILENODES)
5832 XLogRegisterData((char *) (&xl_relfilenodes),
5833 MinSizeOfXactRelfilenodes);
5834 XLogRegisterData((char *) rels,
5835 nrels * sizeof(RelFileNode));
5838 if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5840 XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
5841 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
5842 XLogRegisterData(unconstify(char *, twophase_gid), strlen(twophase_gid) + 1);
5845 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5846 XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
5848 if (TransactionIdIsValid(twophase_xid))
5849 XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
5851 return XLogInsert(RM_XACT_ID, info);
5855 * Before 9.0 this was a fairly short function, but now it performs many
5856 * actions for which the order of execution is critical.
5858 static void
5859 xact_redo_commit(xl_xact_parsed_commit *parsed,
5860 TransactionId xid,
5861 XLogRecPtr lsn,
5862 RepOriginId origin_id)
5864 TransactionId max_xid;
5865 TimestampTz commit_time;
5867 Assert(TransactionIdIsValid(xid));
5869 max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
5871 /* Make sure nextXid is beyond any XID mentioned in the record. */
5872 AdvanceNextFullTransactionIdPastXid(max_xid);
5874 Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) ==
5875 (origin_id == InvalidRepOriginId));
5877 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
5878 commit_time = parsed->origin_timestamp;
5879 else
5880 commit_time = parsed->xact_time;
5882 /* Set the transaction commit timestamp and metadata */
5883 TransactionTreeSetCommitTsData(xid, parsed->nsubxacts, parsed->subxacts,
5884 commit_time, origin_id);
5886 if (standbyState == STANDBY_DISABLED)
5889 * Mark the transaction committed in pg_xact.
5891 TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
5893 else
5896 * If a transaction completion record arrives that has as-yet
5897 * unobserved subtransactions then this will not have been fully
5898 * handled by the call to RecordKnownAssignedTransactionIds() in the
5899 * main recovery loop in xlog.c. So we need to do bookkeeping again to
5900 * cover that case. This is confusing and it is easy to think this
5901 * call is irrelevant, which has happened three times in development
5902 * already. Leave it in.
5904 RecordKnownAssignedTransactionIds(max_xid);
5907 * Mark the transaction committed in pg_xact. We use async commit
5908 * protocol during recovery to provide information on database
5909 * consistency for when users try to set hint bits. It is important
5910 * that we do not set hint bits until the minRecoveryPoint is past
5911 * this commit record. This ensures that if we crash we don't see hint
5912 * bits set on changes made by transactions that haven't yet
5913 * recovered. It's unlikely but it's good to be safe.
5915 TransactionIdAsyncCommitTree(xid, parsed->nsubxacts, parsed->subxacts, lsn);
5918 * We must mark clog before we update the ProcArray.
5920 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
5923 * Send any cache invalidations attached to the commit. We must
5924 * maintain the same order of invalidation then release locks as
5925 * occurs in CommitTransaction().
5927 ProcessCommittedInvalidationMessages(parsed->msgs, parsed->nmsgs,
5928 XactCompletionRelcacheInitFileInval(parsed->xinfo),
5929 parsed->dbId, parsed->tsId);
5932 * Release locks, if any. We do this for both two phase and normal one
5933 * phase transactions. In effect we are ignoring the prepare phase and
5934 * just going straight to lock release.
5936 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
5937 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
5940 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
5942 /* recover apply progress */
5943 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
5944 false /* backward */ , false /* WAL */ );
5947 /* Make sure files supposed to be dropped are dropped */
5948 if (parsed->nrels > 0)
5951 * First update minimum recovery point to cover this WAL record. Once
5952 * a relation is deleted, there's no going back. The buffer manager
5953 * enforces the WAL-first rule for normal updates to relation files,
5954 * so that the minimum recovery point is always updated before the
5955 * corresponding change in the data file is flushed to disk, but we
5956 * have to do the same here since we're bypassing the buffer manager.
5958 * Doing this before deleting the files means that if a deletion fails
5959 * for some reason, you cannot start up the system even after restart,
5960 * until you fix the underlying situation so that the deletion will
5961 * succeed. Alternatively, we could update the minimum recovery point
5962 * after deletion, but that would leave a small window where the
5963 * WAL-first rule would be violated.
5965 XLogFlush(lsn);
5967 /* Make sure files supposed to be dropped are dropped */
5968 DropRelationFiles(parsed->xnodes, parsed->nrels, true);
5972 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
5973 * in normal operation. For example, in CREATE DATABASE, we copy all files
5974 * from the template database, and then commit the transaction. If we
5975 * crash after all the files have been copied but before the commit, you
5976 * have files in the data directory without an entry in pg_database. To
5977 * minimize the window for that, we use ForceSyncCommit() to rush the
5978 * commit record to disk as quick as possible. We have the same window
5979 * during recovery, and forcing an XLogFlush() (which updates
5980 * minRecoveryPoint during recovery) helps to reduce that problem window,
5981 * for any user that requested ForceSyncCommit().
5983 if (XactCompletionForceSyncCommit(parsed->xinfo))
5984 XLogFlush(lsn);
5987 * If asked by the primary (because someone is waiting for a synchronous
5988 * commit = remote_apply), we will need to ask walreceiver to send a reply
5989 * immediately.
5991 if (XactCompletionApplyFeedback(parsed->xinfo))
5992 XLogRequestWalReceiverReply();
5996 * Be careful with the order of execution, as with xact_redo_commit().
5997 * The two functions are similar but differ in key places.
5999 * Note also that an abort can be for a subtransaction and its children,
6000 * not just for a top level abort. That means we have to consider
6001 * topxid != xid, whereas in commit we would find topxid == xid always
6002 * because subtransaction commit is never WAL logged.
6004 static void
6005 xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid,
6006 XLogRecPtr lsn, RepOriginId origin_id)
6008 TransactionId max_xid;
6010 Assert(TransactionIdIsValid(xid));
6012 /* Make sure nextXid is beyond any XID mentioned in the record. */
6013 max_xid = TransactionIdLatest(xid,
6014 parsed->nsubxacts,
6015 parsed->subxacts);
6016 AdvanceNextFullTransactionIdPastXid(max_xid);
6018 if (standbyState == STANDBY_DISABLED)
6020 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6021 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6023 else
6026 * If a transaction completion record arrives that has as-yet
6027 * unobserved subtransactions then this will not have been fully
6028 * handled by the call to RecordKnownAssignedTransactionIds() in the
6029 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6030 * cover that case. This is confusing and it is easy to think this
6031 * call is irrelevant, which has happened three times in development
6032 * already. Leave it in.
6034 RecordKnownAssignedTransactionIds(max_xid);
6036 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6037 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6040 * We must update the ProcArray after we have marked clog.
6042 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6045 * There are no invalidation messages to send or undo.
6049 * Release locks, if any. There are no invalidations to send.
6051 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6052 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6055 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6057 /* recover apply progress */
6058 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6059 false /* backward */ , false /* WAL */ );
6062 /* Make sure files supposed to be dropped are dropped */
6063 if (parsed->nrels > 0)
6066 * See comments about update of minimum recovery point on truncation,
6067 * in xact_redo_commit().
6069 XLogFlush(lsn);
6071 DropRelationFiles(parsed->xnodes, parsed->nrels, true);
6075 void
6076 xact_redo(XLogReaderState *record)
6078 uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6080 /* Backup blocks are not used in xact records */
6081 Assert(!XLogRecHasAnyBlockRefs(record));
6083 if (info == XLOG_XACT_COMMIT)
6085 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6086 xl_xact_parsed_commit parsed;
6088 ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6089 xact_redo_commit(&parsed, XLogRecGetXid(record),
6090 record->EndRecPtr, XLogRecGetOrigin(record));
6092 else if (info == XLOG_XACT_COMMIT_PREPARED)
6094 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6095 xl_xact_parsed_commit parsed;
6097 ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6098 xact_redo_commit(&parsed, parsed.twophase_xid,
6099 record->EndRecPtr, XLogRecGetOrigin(record));
6101 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6102 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6103 PrepareRedoRemove(parsed.twophase_xid, false);
6104 LWLockRelease(TwoPhaseStateLock);
6106 else if (info == XLOG_XACT_ABORT)
6108 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6109 xl_xact_parsed_abort parsed;
6111 ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6112 xact_redo_abort(&parsed, XLogRecGetXid(record),
6113 record->EndRecPtr, XLogRecGetOrigin(record));
6115 else if (info == XLOG_XACT_ABORT_PREPARED)
6117 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6118 xl_xact_parsed_abort parsed;
6120 ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6121 xact_redo_abort(&parsed, parsed.twophase_xid,
6122 record->EndRecPtr, XLogRecGetOrigin(record));
6124 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6125 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6126 PrepareRedoRemove(parsed.twophase_xid, false);
6127 LWLockRelease(TwoPhaseStateLock);
6129 else if (info == XLOG_XACT_PREPARE)
6132 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6133 * gxact entry.
6135 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6136 PrepareRedoAdd(XLogRecGetData(record),
6137 record->ReadRecPtr,
6138 record->EndRecPtr,
6139 XLogRecGetOrigin(record));
6140 LWLockRelease(TwoPhaseStateLock);
6142 else if (info == XLOG_XACT_ASSIGNMENT)
6144 xl_xact_assignment *xlrec = (xl_xact_assignment *) XLogRecGetData(record);
6146 if (standbyState >= STANDBY_INITIALIZED)
6147 ProcArrayApplyXidAssignment(xlrec->xtop,
6148 xlrec->nsubxacts, xlrec->xsub);
6150 else if (info == XLOG_XACT_INVALIDATIONS)
6153 * XXX we do ignore this for now, what matters are invalidations
6154 * written into the commit record.
6157 else
6158 elog(PANIC, "xact_redo: unknown op code %u", info);