1 /*-------------------------------------------------------------------------
4 * top level transaction system support routines
6 * See src/backend/access/transam/README for more information.
8 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
13 * src/backend/access/transam/xact.c
15 *-------------------------------------------------------------------------
23 #include "access/commit_ts.h"
24 #include "access/multixact.h"
25 #include "access/parallel.h"
26 #include "access/subtrans.h"
27 #include "access/transam.h"
28 #include "access/twophase.h"
29 #include "access/xact.h"
30 #include "access/xlog.h"
31 #include "access/xloginsert.h"
32 #include "access/xlogrecovery.h"
33 #include "access/xlogutils.h"
34 #include "catalog/index.h"
35 #include "catalog/namespace.h"
36 #include "catalog/pg_enum.h"
37 #include "catalog/storage.h"
38 #include "commands/async.h"
39 #include "commands/tablecmds.h"
40 #include "commands/trigger.h"
41 #include "common/pg_prng.h"
42 #include "executor/spi.h"
43 #include "libpq/be-fsstubs.h"
44 #include "libpq/pqsignal.h"
45 #include "miscadmin.h"
48 #include "replication/logical.h"
49 #include "replication/logicallauncher.h"
50 #include "replication/logicalworker.h"
51 #include "replication/origin.h"
52 #include "replication/snapbuild.h"
53 #include "replication/syncrep.h"
54 #include "storage/condition_variable.h"
55 #include "storage/fd.h"
56 #include "storage/lmgr.h"
57 #include "storage/md.h"
58 #include "storage/predicate.h"
59 #include "storage/proc.h"
60 #include "storage/procarray.h"
61 #include "storage/sinvaladt.h"
62 #include "storage/smgr.h"
63 #include "utils/builtins.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"
72 #include "utils/typcache.h"
75 * User-tweakable parameters
77 int DefaultXactIsoLevel
= XACT_READ_COMMITTED
;
78 int XactIsoLevel
= XACT_READ_COMMITTED
;
80 bool DefaultXactReadOnly
= false;
83 bool DefaultXactDeferrable
= false;
86 int synchronous_commit
= SYNCHRONOUS_COMMIT_ON
;
89 * CheckXidAlive is a xid value pointing to a possibly ongoing (sub)
90 * transaction. Currently, it is used in logical decoding. It's possible
91 * that such transactions can get aborted while the decoding is ongoing in
92 * which case we skip decoding that particular transaction. To ensure that we
93 * check whether the CheckXidAlive is aborted after fetching the tuple from
94 * system tables. We also ensure that during logical decoding we never
95 * directly access the tableam or heap APIs because we are checking for the
96 * concurrent aborts only in systable_* APIs.
98 TransactionId CheckXidAlive
= InvalidTransactionId
;
99 bool bsysscan
= false;
102 * When running as a parallel worker, we place only a single
103 * TransactionStateData on the parallel worker's state stack, and the XID
104 * reflected there will be that of the *innermost* currently-active
105 * subtransaction in the backend that initiated parallelism. However,
106 * GetTopTransactionId() and TransactionIdIsCurrentTransactionId()
107 * need to return the same answers in the parallel worker as they would have
108 * in the user backend, so we need some additional bookkeeping.
110 * XactTopFullTransactionId stores the XID of our toplevel transaction, which
111 * will be the same as TopTransactionStateData.fullTransactionId in an
112 * ordinary backend; but in a parallel backend, which does not have the entire
113 * transaction state, it will instead be copied from the backend that started
114 * the parallel operation.
116 * nParallelCurrentXids will be 0 and ParallelCurrentXids NULL in an ordinary
117 * backend, but in a parallel backend, nParallelCurrentXids will contain the
118 * number of XIDs that need to be considered current, and ParallelCurrentXids
119 * will contain the XIDs themselves. This includes all XIDs that were current
120 * or sub-committed in the parent at the time the parallel operation began.
121 * The XIDs are stored sorted in numerical order (not logical order) to make
122 * lookups as fast as possible.
124 static FullTransactionId XactTopFullTransactionId
= {InvalidTransactionId
};
125 static int nParallelCurrentXids
= 0;
126 static TransactionId
*ParallelCurrentXids
;
129 * Miscellaneous flag bits to record events which occur on the top level
130 * transaction. These flags are only persisted in MyXactFlags and are intended
131 * so we remember to do certain things later on in the transaction. This is
132 * globally accessible, so can be set from anywhere in the code that requires
138 * transaction states - transaction state from server perspective
140 typedef enum TransState
142 TRANS_DEFAULT
, /* idle */
143 TRANS_START
, /* transaction starting */
144 TRANS_INPROGRESS
, /* inside a valid transaction */
145 TRANS_COMMIT
, /* commit in progress */
146 TRANS_ABORT
, /* abort in progress */
147 TRANS_PREPARE
, /* prepare in progress */
151 * transaction block states - transaction state of client queries
153 * Note: the subtransaction states are used only for non-topmost
154 * transactions; the others appear only in the topmost transaction.
156 typedef enum TBlockState
158 /* not-in-transaction-block states */
159 TBLOCK_DEFAULT
, /* idle */
160 TBLOCK_STARTED
, /* running single-query transaction */
162 /* transaction block states */
163 TBLOCK_BEGIN
, /* starting transaction block */
164 TBLOCK_INPROGRESS
, /* live transaction */
165 TBLOCK_IMPLICIT_INPROGRESS
, /* live transaction after implicit BEGIN */
166 TBLOCK_PARALLEL_INPROGRESS
, /* live transaction inside parallel worker */
167 TBLOCK_END
, /* COMMIT received */
168 TBLOCK_ABORT
, /* failed xact, awaiting ROLLBACK */
169 TBLOCK_ABORT_END
, /* failed xact, ROLLBACK received */
170 TBLOCK_ABORT_PENDING
, /* live xact, ROLLBACK received */
171 TBLOCK_PREPARE
, /* live xact, PREPARE received */
173 /* subtransaction states */
174 TBLOCK_SUBBEGIN
, /* starting a subtransaction */
175 TBLOCK_SUBINPROGRESS
, /* live subtransaction */
176 TBLOCK_SUBRELEASE
, /* RELEASE received */
177 TBLOCK_SUBCOMMIT
, /* COMMIT received while TBLOCK_SUBINPROGRESS */
178 TBLOCK_SUBABORT
, /* failed subxact, awaiting ROLLBACK */
179 TBLOCK_SUBABORT_END
, /* failed subxact, ROLLBACK received */
180 TBLOCK_SUBABORT_PENDING
, /* live subxact, ROLLBACK received */
181 TBLOCK_SUBRESTART
, /* live subxact, ROLLBACK TO received */
182 TBLOCK_SUBABORT_RESTART
, /* failed subxact, ROLLBACK TO received */
186 * transaction state structure
188 * Note: parallelModeLevel counts the number of unmatched EnterParallelMode
189 * calls done at this transaction level. parallelChildXact is true if any
190 * upper transaction level has nonzero parallelModeLevel.
192 typedef struct TransactionStateData
194 FullTransactionId fullTransactionId
; /* my FullTransactionId */
195 SubTransactionId subTransactionId
; /* my subxact ID */
196 char *name
; /* savepoint name, if any */
197 int savepointLevel
; /* savepoint level */
198 TransState state
; /* low-level state */
199 TBlockState blockState
; /* high-level state */
200 int nestingLevel
; /* transaction nesting depth */
201 int gucNestLevel
; /* GUC context nesting depth */
202 MemoryContext curTransactionContext
; /* my xact-lifetime context */
203 ResourceOwner curTransactionOwner
; /* my query resources */
204 MemoryContext priorContext
; /* CurrentMemoryContext before xact started */
205 TransactionId
*childXids
; /* subcommitted child XIDs, in XID order */
206 int nChildXids
; /* # of subcommitted child XIDs */
207 int maxChildXids
; /* allocated size of childXids[] */
208 Oid prevUser
; /* previous CurrentUserId setting */
209 int prevSecContext
; /* previous SecurityRestrictionContext */
210 bool prevXactReadOnly
; /* entry-time xact r/o state */
211 bool startedInRecovery
; /* did we start in recovery? */
212 bool didLogXid
; /* has xid been included in WAL record? */
213 int parallelModeLevel
; /* Enter/ExitParallelMode counter */
214 bool parallelChildXact
; /* is any parent transaction parallel? */
215 bool chain
; /* start a new block after this one */
216 bool topXidLogged
; /* for a subxact: is top-level XID logged? */
217 struct TransactionStateData
*parent
; /* back link to parent */
218 } TransactionStateData
;
220 typedef TransactionStateData
*TransactionState
;
223 * Serialized representation used to transmit transaction state to parallel
224 * workers through shared memory.
226 typedef struct SerializedTransactionState
230 FullTransactionId topFullTransactionId
;
231 FullTransactionId currentFullTransactionId
;
232 CommandId currentCommandId
;
233 int nParallelCurrentXids
;
234 TransactionId parallelCurrentXids
[FLEXIBLE_ARRAY_MEMBER
];
235 } SerializedTransactionState
;
237 /* The size of SerializedTransactionState, not including the final array. */
238 #define SerializedTransactionStateHeaderSize \
239 offsetof(SerializedTransactionState, parallelCurrentXids)
242 * CurrentTransactionState always points to the current transaction state
243 * block. It will point to TopTransactionStateData when not in a
244 * transaction at all, or when in a top-level transaction.
246 static TransactionStateData TopTransactionStateData
= {
247 .state
= TRANS_DEFAULT
,
248 .blockState
= TBLOCK_DEFAULT
,
249 .topXidLogged
= false,
253 * unreportedXids holds XIDs of all subtransactions that have not yet been
254 * reported in an XLOG_XACT_ASSIGNMENT record.
256 static int nUnreportedXids
;
257 static TransactionId unreportedXids
[PGPROC_MAX_CACHED_SUBXIDS
];
259 static TransactionState CurrentTransactionState
= &TopTransactionStateData
;
262 * The subtransaction ID and command ID assignment counters are global
263 * to a whole transaction, so we do not keep them in the state stack.
265 static SubTransactionId currentSubTransactionId
;
266 static CommandId currentCommandId
;
267 static bool currentCommandIdUsed
;
270 * xactStartTimestamp is the value of transaction_timestamp().
271 * stmtStartTimestamp is the value of statement_timestamp().
272 * xactStopTimestamp is the time at which we log a commit / abort WAL record,
273 * or if that was skipped, the time of the first subsequent
274 * GetCurrentTransactionStopTimestamp() call.
276 * These do not change as we enter and exit subtransactions, so we don't
277 * keep them inside the TransactionState stack.
279 static TimestampTz xactStartTimestamp
;
280 static TimestampTz stmtStartTimestamp
;
281 static TimestampTz xactStopTimestamp
;
284 * GID to be used for preparing the current transaction. This is also
285 * global to a whole transaction, so we don't keep it in the state stack.
287 static char *prepareGID
;
290 * Some commands want to force synchronous commit.
292 static bool forceSyncCommit
= false;
294 /* Flag for logging statements in a transaction. */
295 bool xact_is_sampled
= false;
298 * Private context for transaction-abort work --- we reserve space for this
299 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
300 * when we've run out of memory.
302 static MemoryContext TransactionAbortContext
= NULL
;
305 * List of add-on start- and end-of-xact callbacks
307 typedef struct XactCallbackItem
309 struct XactCallbackItem
*next
;
310 XactCallback callback
;
314 static XactCallbackItem
*Xact_callbacks
= NULL
;
317 * List of add-on start- and end-of-subxact callbacks
319 typedef struct SubXactCallbackItem
321 struct SubXactCallbackItem
*next
;
322 SubXactCallback callback
;
324 } SubXactCallbackItem
;
326 static SubXactCallbackItem
*SubXact_callbacks
= NULL
;
329 /* local function prototypes */
330 static void AssignTransactionId(TransactionState s
);
331 static void AbortTransaction(void);
332 static void AtAbort_Memory(void);
333 static void AtCleanup_Memory(void);
334 static void AtAbort_ResourceOwner(void);
335 static void AtCCI_LocalCache(void);
336 static void AtCommit_Memory(void);
337 static void AtStart_Cache(void);
338 static void AtStart_Memory(void);
339 static void AtStart_ResourceOwner(void);
340 static void CallXactCallbacks(XactEvent event
);
341 static void CallSubXactCallbacks(SubXactEvent event
,
342 SubTransactionId mySubid
,
343 SubTransactionId parentSubid
);
344 static void CleanupTransaction(void);
345 static void CheckTransactionBlock(bool isTopLevel
, bool throwError
,
346 const char *stmtType
);
347 static void CommitTransaction(void);
348 static TransactionId
RecordTransactionAbort(bool isSubXact
);
349 static void StartTransaction(void);
351 static bool CommitTransactionCommandInternal(void);
352 static bool AbortCurrentTransactionInternal(void);
354 static void StartSubTransaction(void);
355 static void CommitSubTransaction(void);
356 static void AbortSubTransaction(void);
357 static void CleanupSubTransaction(void);
358 static void PushTransaction(void);
359 static void PopTransaction(void);
361 static void AtSubAbort_Memory(void);
362 static void AtSubCleanup_Memory(void);
363 static void AtSubAbort_ResourceOwner(void);
364 static void AtSubCommit_Memory(void);
365 static void AtSubStart_Memory(void);
366 static void AtSubStart_ResourceOwner(void);
368 static void ShowTransactionState(const char *str
);
369 static void ShowTransactionStateRec(const char *str
, TransactionState s
);
370 static const char *BlockStateAsString(TBlockState blockState
);
371 static const char *TransStateAsString(TransState state
);
374 /* ----------------------------------------------------------------
375 * transaction state accessors
376 * ----------------------------------------------------------------
382 * This returns true if we are inside a valid transaction; that is,
383 * it is safe to initiate database access, take heavyweight locks, etc.
386 IsTransactionState(void)
388 TransactionState s
= CurrentTransactionState
;
391 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
392 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
393 * TRANS_PREPARE since it might be too soon or too late within those
394 * transition states to do anything interesting. Hence, the only "valid"
395 * state is TRANS_INPROGRESS.
397 return (s
->state
== TRANS_INPROGRESS
);
401 * IsAbortedTransactionBlockState
403 * This returns true if we are within an aborted transaction block.
406 IsAbortedTransactionBlockState(void)
408 TransactionState s
= CurrentTransactionState
;
410 if (s
->blockState
== TBLOCK_ABORT
||
411 s
->blockState
== TBLOCK_SUBABORT
)
419 * GetTopTransactionId
421 * This will return the XID of the main transaction, assigning one if
422 * it's not yet set. Be careful to call this only inside a valid xact.
425 GetTopTransactionId(void)
427 if (!FullTransactionIdIsValid(XactTopFullTransactionId
))
428 AssignTransactionId(&TopTransactionStateData
);
429 return XidFromFullTransactionId(XactTopFullTransactionId
);
433 * GetTopTransactionIdIfAny
435 * This will return the XID of the main transaction, if one is assigned.
436 * It will return InvalidTransactionId if we are not currently inside a
437 * transaction, or inside a transaction that hasn't yet been assigned an XID.
440 GetTopTransactionIdIfAny(void)
442 return XidFromFullTransactionId(XactTopFullTransactionId
);
446 * GetCurrentTransactionId
448 * This will return the XID of the current transaction (main or sub
449 * transaction), assigning one if it's not yet set. Be careful to call this
450 * only inside a valid xact.
453 GetCurrentTransactionId(void)
455 TransactionState s
= CurrentTransactionState
;
457 if (!FullTransactionIdIsValid(s
->fullTransactionId
))
458 AssignTransactionId(s
);
459 return XidFromFullTransactionId(s
->fullTransactionId
);
463 * GetCurrentTransactionIdIfAny
465 * This will return the XID of the current sub xact, if one is assigned.
466 * It will return InvalidTransactionId if we are not currently inside a
467 * transaction, or inside a transaction that hasn't been assigned an XID yet.
470 GetCurrentTransactionIdIfAny(void)
472 return XidFromFullTransactionId(CurrentTransactionState
->fullTransactionId
);
476 * GetTopFullTransactionId
478 * This will return the FullTransactionId of the main transaction, assigning
479 * one if it's not yet set. Be careful to call this only inside a valid xact.
482 GetTopFullTransactionId(void)
484 if (!FullTransactionIdIsValid(XactTopFullTransactionId
))
485 AssignTransactionId(&TopTransactionStateData
);
486 return XactTopFullTransactionId
;
490 * GetTopFullTransactionIdIfAny
492 * This will return the FullTransactionId of the main transaction, if one is
493 * assigned. It will return InvalidFullTransactionId if we are not currently
494 * inside a transaction, or inside a transaction that hasn't yet been assigned
498 GetTopFullTransactionIdIfAny(void)
500 return XactTopFullTransactionId
;
504 * GetCurrentFullTransactionId
506 * This will return the FullTransactionId of the current transaction (main or
507 * sub transaction), assigning one if it's not yet set. Be careful to call
508 * this only inside a valid xact.
511 GetCurrentFullTransactionId(void)
513 TransactionState s
= CurrentTransactionState
;
515 if (!FullTransactionIdIsValid(s
->fullTransactionId
))
516 AssignTransactionId(s
);
517 return s
->fullTransactionId
;
521 * GetCurrentFullTransactionIdIfAny
523 * This will return the FullTransactionId of the current sub xact, if one is
524 * assigned. It will return InvalidFullTransactionId if we are not currently
525 * inside a transaction, or inside a transaction that hasn't been assigned one
529 GetCurrentFullTransactionIdIfAny(void)
531 return CurrentTransactionState
->fullTransactionId
;
535 * MarkCurrentTransactionIdLoggedIfAny
537 * Remember that the current xid - if it is assigned - now has been wal logged.
540 MarkCurrentTransactionIdLoggedIfAny(void)
542 if (FullTransactionIdIsValid(CurrentTransactionState
->fullTransactionId
))
543 CurrentTransactionState
->didLogXid
= true;
547 * IsSubxactTopXidLogPending
549 * This is used to decide whether we need to WAL log the top-level XID for
550 * operation in a subtransaction. We require that for logical decoding, see
551 * LogicalDecodingProcessRecord.
553 * This returns true if wal_level >= logical and we are inside a valid
554 * subtransaction, for which the assignment was not yet written to any WAL
558 IsSubxactTopXidLogPending(void)
560 /* check whether it is already logged */
561 if (CurrentTransactionState
->topXidLogged
)
564 /* wal_level has to be logical */
565 if (!XLogLogicalInfoActive())
568 /* we need to be in a transaction state */
569 if (!IsTransactionState())
572 /* it has to be a subtransaction */
573 if (!IsSubTransaction())
576 /* the subtransaction has to have a XID assigned */
577 if (!TransactionIdIsValid(GetCurrentTransactionIdIfAny()))
584 * MarkSubxactTopXidLogged
586 * Remember that the top transaction id for the current subtransaction is WAL
590 MarkSubxactTopXidLogged(void)
592 Assert(IsSubxactTopXidLogPending());
594 CurrentTransactionState
->topXidLogged
= true;
598 * GetStableLatestTransactionId
600 * Get the transaction's XID if it has one, else read the next-to-be-assigned
601 * XID. Once we have a value, return that same value for the remainder of the
602 * current transaction. This is meant to provide the reference point for the
603 * age(xid) function, but might be useful for other maintenance tasks as well.
606 GetStableLatestTransactionId(void)
608 static LocalTransactionId lxid
= InvalidLocalTransactionId
;
609 static TransactionId stablexid
= InvalidTransactionId
;
611 if (lxid
!= MyProc
->vxid
.lxid
)
613 lxid
= MyProc
->vxid
.lxid
;
614 stablexid
= GetTopTransactionIdIfAny();
615 if (!TransactionIdIsValid(stablexid
))
616 stablexid
= ReadNextTransactionId();
619 Assert(TransactionIdIsValid(stablexid
));
625 * AssignTransactionId
627 * Assigns a new permanent FullTransactionId to the given TransactionState.
628 * We do not assign XIDs to transactions until/unless this is called.
629 * Also, any parent TransactionStates that don't yet have XIDs are assigned
630 * one; this maintains the invariant that a child transaction has an XID
631 * following its parent's.
634 AssignTransactionId(TransactionState s
)
636 bool isSubXact
= (s
->parent
!= NULL
);
637 ResourceOwner currentOwner
;
638 bool log_unknown_top
= false;
640 /* Assert that caller didn't screw up */
641 Assert(!FullTransactionIdIsValid(s
->fullTransactionId
));
642 Assert(s
->state
== TRANS_INPROGRESS
);
645 * Workers synchronize transaction state at the beginning of each parallel
646 * operation, so we can't account for new XIDs at this point.
648 if (IsInParallelMode() || IsParallelWorker())
650 (errcode(ERRCODE_INVALID_TRANSACTION_STATE
),
651 errmsg("cannot assign transaction IDs during a parallel operation")));
654 * Ensure parent(s) have XIDs, so that a child always has an XID later
655 * than its parent. Mustn't recurse here, or we might get a stack
656 * overflow if we're at the bottom of a huge stack of subtransactions none
657 * of which have XIDs yet.
659 if (isSubXact
&& !FullTransactionIdIsValid(s
->parent
->fullTransactionId
))
661 TransactionState p
= s
->parent
;
662 TransactionState
*parents
;
663 size_t parentOffset
= 0;
665 parents
= palloc(sizeof(TransactionState
) * s
->nestingLevel
);
666 while (p
!= NULL
&& !FullTransactionIdIsValid(p
->fullTransactionId
))
668 parents
[parentOffset
++] = p
;
673 * This is technically a recursive call, but the recursion will never
674 * be more than one layer deep.
676 while (parentOffset
!= 0)
677 AssignTransactionId(parents
[--parentOffset
]);
683 * When wal_level=logical, guarantee that a subtransaction's xid can only
684 * be seen in the WAL stream if its toplevel xid has been logged before.
685 * If necessary we log an xact_assignment record with fewer than
686 * PGPROC_MAX_CACHED_SUBXIDS. Note that it is fine if didLogXid isn't set
687 * for a transaction even though it appears in a WAL record, we just might
688 * superfluously log something. That can happen when an xid is included
689 * somewhere inside a wal record, but not in XLogRecord->xl_xid, like in
692 if (isSubXact
&& XLogLogicalInfoActive() &&
693 !TopTransactionStateData
.didLogXid
)
694 log_unknown_top
= true;
697 * Generate a new FullTransactionId and record its xid in PGPROC and
700 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
701 * shared storage other than PGPROC; because if there's no room for it in
702 * PGPROC, the subtrans entry is needed to ensure that other backends see
703 * the Xid as "running". See GetNewTransactionId.
705 s
->fullTransactionId
= GetNewTransactionId(isSubXact
);
707 XactTopFullTransactionId
= s
->fullTransactionId
;
710 SubTransSetParent(XidFromFullTransactionId(s
->fullTransactionId
),
711 XidFromFullTransactionId(s
->parent
->fullTransactionId
));
714 * If it's a top-level transaction, the predicate locking system needs to
715 * be told about it too.
718 RegisterPredicateLockingXid(XidFromFullTransactionId(s
->fullTransactionId
));
721 * Acquire lock on the transaction XID. (We assume this cannot block.) We
722 * have to ensure that the lock is assigned to the transaction's own
725 currentOwner
= CurrentResourceOwner
;
726 CurrentResourceOwner
= s
->curTransactionOwner
;
728 XactLockTableInsert(XidFromFullTransactionId(s
->fullTransactionId
));
730 CurrentResourceOwner
= currentOwner
;
733 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
734 * top-level transaction we issue a WAL record for the assignment. We
735 * include the top-level xid and all the subxids that have not yet been
736 * reported using XLOG_XACT_ASSIGNMENT records.
738 * This is required to limit the amount of shared memory required in a hot
739 * standby server to keep track of in-progress XIDs. See notes for
740 * RecordKnownAssignedTransactionIds().
742 * We don't keep track of the immediate parent of each subxid, only the
743 * top-level transaction that each subxact belongs to. This is correct in
744 * recovery only because aborted subtransactions are separately WAL
747 * This is correct even for the case where several levels above us didn't
748 * have an xid assigned as we recursed up to them beforehand.
750 if (isSubXact
&& XLogStandbyInfoActive())
752 unreportedXids
[nUnreportedXids
] = XidFromFullTransactionId(s
->fullTransactionId
);
756 * ensure this test matches similar one in
757 * RecoverPreparedTransactions()
759 if (nUnreportedXids
>= PGPROC_MAX_CACHED_SUBXIDS
||
762 xl_xact_assignment xlrec
;
765 * xtop is always set by now because we recurse up transaction
766 * stack to the highest unassigned xid and then come back down
768 xlrec
.xtop
= GetTopTransactionId();
769 Assert(TransactionIdIsValid(xlrec
.xtop
));
770 xlrec
.nsubxacts
= nUnreportedXids
;
773 XLogRegisterData((char *) &xlrec
, MinSizeOfXactAssignment
);
774 XLogRegisterData((char *) unreportedXids
,
775 nUnreportedXids
* sizeof(TransactionId
));
777 (void) XLogInsert(RM_XACT_ID
, XLOG_XACT_ASSIGNMENT
);
780 /* mark top, not current xact as having been logged */
781 TopTransactionStateData
.didLogXid
= true;
787 * GetCurrentSubTransactionId
790 GetCurrentSubTransactionId(void)
792 TransactionState s
= CurrentTransactionState
;
794 return s
->subTransactionId
;
798 * SubTransactionIsActive
800 * Test if the specified subxact ID is still active. Note caller is
801 * responsible for checking whether this ID is relevant to the current xact.
804 SubTransactionIsActive(SubTransactionId subxid
)
808 for (s
= CurrentTransactionState
; s
!= NULL
; s
= s
->parent
)
810 if (s
->state
== TRANS_ABORT
)
812 if (s
->subTransactionId
== subxid
)
820 * GetCurrentCommandId
822 * "used" must be true if the caller intends to use the command ID to mark
823 * inserted/updated/deleted tuples. false means the ID is being fetched
824 * for read-only purposes (ie, as a snapshot validity cutoff). See
825 * CommandCounterIncrement() for discussion.
828 GetCurrentCommandId(bool used
)
830 /* this is global to a transaction, not subtransaction-local */
834 * Forbid setting currentCommandIdUsed in a parallel worker, because
835 * we have no provision for communicating this back to the leader. We
836 * could relax this restriction when currentCommandIdUsed was already
837 * true at the start of the parallel operation.
839 if (IsParallelWorker())
841 (errcode(ERRCODE_INVALID_TRANSACTION_STATE
),
842 errmsg("cannot modify data in a parallel worker")));
844 currentCommandIdUsed
= true;
846 return currentCommandId
;
850 * SetParallelStartTimestamps
852 * In a parallel worker, we should inherit the parent transaction's
853 * timestamps rather than setting our own. The parallel worker
854 * infrastructure must call this to provide those values before
855 * calling StartTransaction() or SetCurrentStatementStartTimestamp().
858 SetParallelStartTimestamps(TimestampTz xact_ts
, TimestampTz stmt_ts
)
860 Assert(IsParallelWorker());
861 xactStartTimestamp
= xact_ts
;
862 stmtStartTimestamp
= stmt_ts
;
866 * GetCurrentTransactionStartTimestamp
869 GetCurrentTransactionStartTimestamp(void)
871 return xactStartTimestamp
;
875 * GetCurrentStatementStartTimestamp
878 GetCurrentStatementStartTimestamp(void)
880 return stmtStartTimestamp
;
884 * GetCurrentTransactionStopTimestamp
886 * If the transaction stop time hasn't already been set, which can happen if
887 * we decided we don't need to log an XLOG record, set xactStopTimestamp.
890 GetCurrentTransactionStopTimestamp(void)
892 TransactionState s PG_USED_FOR_ASSERTS_ONLY
= CurrentTransactionState
;
894 /* should only be called after commit / abort processing */
895 Assert(s
->state
== TRANS_DEFAULT
||
896 s
->state
== TRANS_COMMIT
||
897 s
->state
== TRANS_ABORT
||
898 s
->state
== TRANS_PREPARE
);
900 if (xactStopTimestamp
== 0)
901 xactStopTimestamp
= GetCurrentTimestamp();
903 return xactStopTimestamp
;
907 * SetCurrentStatementStartTimestamp
909 * In a parallel worker, this should already have been provided by a call
910 * to SetParallelStartTimestamps().
913 SetCurrentStatementStartTimestamp(void)
915 if (!IsParallelWorker())
916 stmtStartTimestamp
= GetCurrentTimestamp();
918 Assert(stmtStartTimestamp
!= 0);
922 * GetCurrentTransactionNestLevel
924 * Note: this will return zero when not inside any transaction, one when
925 * inside a top-level transaction, etc.
928 GetCurrentTransactionNestLevel(void)
930 TransactionState s
= CurrentTransactionState
;
932 return s
->nestingLevel
;
937 * TransactionIdIsCurrentTransactionId
940 TransactionIdIsCurrentTransactionId(TransactionId xid
)
945 * We always say that BootstrapTransactionId is "not my transaction ID"
946 * even when it is (ie, during bootstrap). Along with the fact that
947 * transam.c always treats BootstrapTransactionId as already committed,
948 * this causes the heapam_visibility.c routines to see all tuples as
949 * committed, which is what we need during bootstrap. (Bootstrap mode
950 * only inserts tuples, it never updates or deletes them, so all tuples
951 * can be presumed good immediately.)
953 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
954 * not my transaction ID, so we can just return "false" immediately for
955 * any non-normal XID.
957 if (!TransactionIdIsNormal(xid
))
960 if (TransactionIdEquals(xid
, GetTopTransactionIdIfAny()))
964 * In parallel workers, the XIDs we must consider as current are stored in
965 * ParallelCurrentXids rather than the transaction-state stack. Note that
966 * the XIDs in this array are sorted numerically rather than according to
967 * transactionIdPrecedes order.
969 if (nParallelCurrentXids
> 0)
975 high
= nParallelCurrentXids
- 1;
981 middle
= low
+ (high
- low
) / 2;
982 probe
= ParallelCurrentXids
[middle
];
985 else if (probe
< xid
)
994 * We will return true for the Xid of the current subtransaction, any of
995 * its subcommitted children, any of its parents, or any of their
996 * previously subcommitted children. However, a transaction being aborted
997 * is no longer "current", even though it may still have an entry on the
1000 for (s
= CurrentTransactionState
; s
!= NULL
; s
= s
->parent
)
1005 if (s
->state
== TRANS_ABORT
)
1007 if (!FullTransactionIdIsValid(s
->fullTransactionId
))
1008 continue; /* it can't have any child XIDs either */
1009 if (TransactionIdEquals(xid
, XidFromFullTransactionId(s
->fullTransactionId
)))
1011 /* As the childXids array is ordered, we can use binary search */
1013 high
= s
->nChildXids
- 1;
1017 TransactionId probe
;
1019 middle
= low
+ (high
- low
) / 2;
1020 probe
= s
->childXids
[middle
];
1021 if (TransactionIdEquals(probe
, xid
))
1023 else if (TransactionIdPrecedes(probe
, xid
))
1034 * TransactionStartedDuringRecovery
1036 * Returns true if the current transaction started while recovery was still
1037 * in progress. Recovery might have ended since so RecoveryInProgress() might
1038 * return false already.
1041 TransactionStartedDuringRecovery(void)
1043 return CurrentTransactionState
->startedInRecovery
;
1050 EnterParallelMode(void)
1052 TransactionState s
= CurrentTransactionState
;
1054 Assert(s
->parallelModeLevel
>= 0);
1056 ++s
->parallelModeLevel
;
1063 ExitParallelMode(void)
1065 TransactionState s
= CurrentTransactionState
;
1067 Assert(s
->parallelModeLevel
> 0);
1068 Assert(s
->parallelModeLevel
> 1 || s
->parallelChildXact
||
1069 !ParallelContextActive());
1071 --s
->parallelModeLevel
;
1077 * Are we in a parallel operation, as either the leader or a worker? Check
1078 * this to prohibit operations that change backend-local state expected to
1079 * match across all workers. Mere caches usually don't require such a
1080 * restriction. State modified in a strict push/pop fashion, such as the
1081 * active snapshot stack, is often fine.
1083 * We say we are in parallel mode if we are in a subxact of a transaction
1084 * that's initiated a parallel operation; for most purposes that context
1085 * has all the same restrictions.
1088 IsInParallelMode(void)
1090 TransactionState s
= CurrentTransactionState
;
1092 return s
->parallelModeLevel
!= 0 || s
->parallelChildXact
;
1096 * CommandCounterIncrement
1099 CommandCounterIncrement(void)
1102 * If the current value of the command counter hasn't been "used" to mark
1103 * tuples, we need not increment it, since there's no need to distinguish
1104 * a read-only command from others. This helps postpone command counter
1105 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
1107 if (currentCommandIdUsed
)
1110 * Workers synchronize transaction state at the beginning of each
1111 * parallel operation, so we can't account for new commands after that
1114 if (IsInParallelMode() || IsParallelWorker())
1116 (errcode(ERRCODE_INVALID_TRANSACTION_STATE
),
1117 errmsg("cannot start commands during a parallel operation")));
1119 currentCommandId
+= 1;
1120 if (currentCommandId
== InvalidCommandId
)
1122 currentCommandId
-= 1;
1124 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED
),
1125 errmsg("cannot have more than 2^32-2 commands in a transaction")));
1127 currentCommandIdUsed
= false;
1129 /* Propagate new command ID into static snapshots */
1130 SnapshotSetCommandId(currentCommandId
);
1133 * Make any catalog changes done by the just-completed command visible
1134 * in the local syscache. We obviously don't need to do this after a
1135 * read-only command. (But see hacks in inval.c to make real sure we
1136 * don't think a command that queued inval messages was read-only.)
1145 * Interface routine to allow commands to force a synchronous commit of the
1146 * current top-level transaction. Currently, two-phase commit does not
1147 * persist and restore this variable. So long as all callers use
1148 * PreventInTransactionBlock(), that omission has no consequences.
1151 ForceSyncCommit(void)
1153 forceSyncCommit
= true;
1157 /* ----------------------------------------------------------------
1158 * StartTransaction stuff
1159 * ----------------------------------------------------------------
1168 AcceptInvalidationMessages();
1175 AtStart_Memory(void)
1177 TransactionState s
= CurrentTransactionState
;
1180 * Remember the memory context that was active prior to transaction start.
1182 s
->priorContext
= CurrentMemoryContext
;
1185 * If this is the first time through, create a private context for
1186 * AbortTransaction to work in. By reserving some space now, we can
1187 * insulate AbortTransaction from out-of-memory scenarios. Like
1188 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1189 * size, so that space will be reserved immediately.
1191 if (TransactionAbortContext
== NULL
)
1192 TransactionAbortContext
=
1193 AllocSetContextCreate(TopMemoryContext
,
1194 "TransactionAbortContext",
1200 * Likewise, if this is the first time through, create a top-level context
1201 * for transaction-local data. This context will be reset at transaction
1202 * end, and then re-used in later transactions.
1204 if (TopTransactionContext
== NULL
)
1205 TopTransactionContext
=
1206 AllocSetContextCreate(TopMemoryContext
,
1207 "TopTransactionContext",
1208 ALLOCSET_DEFAULT_SIZES
);
1211 * In a top-level transaction, CurTransactionContext is the same as
1212 * TopTransactionContext.
1214 CurTransactionContext
= TopTransactionContext
;
1215 s
->curTransactionContext
= CurTransactionContext
;
1217 /* Make the CurTransactionContext active. */
1218 MemoryContextSwitchTo(CurTransactionContext
);
1222 * AtStart_ResourceOwner
1225 AtStart_ResourceOwner(void)
1227 TransactionState s
= CurrentTransactionState
;
1230 * We shouldn't have a transaction resource owner already.
1232 Assert(TopTransactionResourceOwner
== NULL
);
1235 * Create a toplevel resource owner for the transaction.
1237 s
->curTransactionOwner
= ResourceOwnerCreate(NULL
, "TopTransaction");
1239 TopTransactionResourceOwner
= s
->curTransactionOwner
;
1240 CurTransactionResourceOwner
= s
->curTransactionOwner
;
1241 CurrentResourceOwner
= s
->curTransactionOwner
;
1244 /* ----------------------------------------------------------------
1245 * StartSubTransaction stuff
1246 * ----------------------------------------------------------------
1253 AtSubStart_Memory(void)
1255 TransactionState s
= CurrentTransactionState
;
1257 Assert(CurTransactionContext
!= NULL
);
1260 * Remember the context that was active prior to subtransaction start.
1262 s
->priorContext
= CurrentMemoryContext
;
1265 * Create a CurTransactionContext, which will be used to hold data that
1266 * survives subtransaction commit but disappears on subtransaction abort.
1267 * We make it a child of the immediate parent's CurTransactionContext.
1269 CurTransactionContext
= AllocSetContextCreate(CurTransactionContext
,
1270 "CurTransactionContext",
1271 ALLOCSET_DEFAULT_SIZES
);
1272 s
->curTransactionContext
= CurTransactionContext
;
1274 /* Make the CurTransactionContext active. */
1275 MemoryContextSwitchTo(CurTransactionContext
);
1279 * AtSubStart_ResourceOwner
1282 AtSubStart_ResourceOwner(void)
1284 TransactionState s
= CurrentTransactionState
;
1286 Assert(s
->parent
!= NULL
);
1289 * Create a resource owner for the subtransaction. We make it a child of
1290 * the immediate parent's resource owner.
1292 s
->curTransactionOwner
=
1293 ResourceOwnerCreate(s
->parent
->curTransactionOwner
,
1296 CurTransactionResourceOwner
= s
->curTransactionOwner
;
1297 CurrentResourceOwner
= s
->curTransactionOwner
;
1300 /* ----------------------------------------------------------------
1301 * CommitTransaction stuff
1302 * ----------------------------------------------------------------
1306 * RecordTransactionCommit
1308 * Returns latest XID among xact and its children, or InvalidTransactionId
1309 * if the xact has no XID. (We compute that here just because it's easier.)
1311 * If you change this function, see RecordTransactionCommitPrepared also.
1313 static TransactionId
1314 RecordTransactionCommit(void)
1316 TransactionId xid
= GetTopTransactionIdIfAny();
1317 bool markXidCommitted
= TransactionIdIsValid(xid
);
1318 TransactionId latestXid
= InvalidTransactionId
;
1320 RelFileLocator
*rels
;
1322 TransactionId
*children
;
1323 int ndroppedstats
= 0;
1324 xl_xact_stats_item
*droppedstats
= NULL
;
1326 SharedInvalidationMessage
*invalMessages
= NULL
;
1327 bool RelcacheInitFileInval
= false;
1331 * Log pending invalidations for logical decoding of in-progress
1332 * transactions. Normally for DDLs, we log this at each command end,
1333 * however, for certain cases where we directly update the system table
1334 * without a transaction block, the invalidations are not logged till this
1337 if (XLogLogicalInfoActive())
1338 LogLogicalInvalidations();
1340 /* Get data needed for commit record */
1341 nrels
= smgrGetPendingDeletes(true, &rels
);
1342 nchildren
= xactGetCommittedChildren(&children
);
1343 ndroppedstats
= pgstat_get_transactional_drops(true, &droppedstats
);
1344 if (XLogStandbyInfoActive())
1345 nmsgs
= xactGetCommittedInvalidationMessages(&invalMessages
,
1346 &RelcacheInitFileInval
);
1347 wrote_xlog
= (XactLastRecEnd
!= 0);
1350 * If we haven't been assigned an XID yet, we neither can, nor do we want
1351 * to write a COMMIT record.
1353 if (!markXidCommitted
)
1356 * We expect that every RelationDropStorage is followed by a catalog
1357 * update, and hence XID assignment, so we shouldn't get here with any
1358 * pending deletes. Same is true for dropping stats.
1360 * Use a real test not just an Assert to check this, since it's a bit
1363 if (nrels
!= 0 || ndroppedstats
!= 0)
1364 elog(ERROR
, "cannot commit a transaction that deleted files but has no xid");
1366 /* Can't have child XIDs either; AssignTransactionId enforces this */
1367 Assert(nchildren
== 0);
1370 * Transactions without an assigned xid can contain invalidation
1371 * messages. While inplace updates do this, this is not known to be
1372 * necessary; see comment at inplace CacheInvalidateHeapTuple().
1373 * Extensions might still rely on this capability, and standbys may
1374 * need to process those invals. We can't emit a commit record
1375 * without an xid, and we don't want to force assigning an xid,
1376 * because that'd be problematic for e.g. vacuum. Hence we emit a
1377 * bespoke record for the invalidations. We don't want to use that in
1378 * case a commit record is emitted, so they happen synchronously with
1379 * commits (besides not wanting to emit more WAL records).
1381 * XXX Every known use of this capability is a defect. Since an XID
1382 * isn't controlling visibility of the change that prompted invals,
1383 * other sessions need the inval even if this transactions aborts.
1385 * ON COMMIT DELETE ROWS does a nontransactional index_build(), which
1386 * queues a relcache inval, including in transactions without an xid
1387 * that had read the (empty) table. Standbys don't need any ON COMMIT
1388 * DELETE ROWS invals, but we've not done the work to withhold them.
1392 LogStandbyInvalidations(nmsgs
, invalMessages
,
1393 RelcacheInitFileInval
);
1394 wrote_xlog
= true; /* not strictly necessary */
1398 * If we didn't create XLOG entries, we're done here; otherwise we
1399 * should trigger flushing those entries the same as a commit record
1400 * would. This will primarily happen for HOT pruning and the like; we
1401 * want these to be flushed to disk in due time.
1411 * Are we using the replication origins feature? Or, in other words,
1412 * are we replaying remote actions?
1414 replorigin
= (replorigin_session_origin
!= InvalidRepOriginId
&&
1415 replorigin_session_origin
!= DoNotReplicateId
);
1418 * Mark ourselves as within our "commit critical section". This
1419 * forces any concurrent checkpoint to wait until we've updated
1420 * pg_xact. Without this, it is possible for the checkpoint to set
1421 * REDO after the XLOG record but fail to flush the pg_xact update to
1422 * disk, leading to loss of the transaction commit if the system
1423 * crashes a little later.
1425 * Note: we could, but don't bother to, set this flag in
1426 * RecordTransactionAbort. That's because loss of a transaction abort
1427 * is noncritical; the presumption would be that it aborted, anyway.
1429 * It's safe to change the delayChkptFlags flag of our own backend
1430 * without holding the ProcArrayLock, since we're the only one
1431 * modifying it. This makes checkpoint's determination of which xacts
1432 * are delaying the checkpoint a bit fuzzy, but it doesn't matter.
1434 Assert((MyProc
->delayChkptFlags
& DELAY_CHKPT_START
) == 0);
1435 START_CRIT_SECTION();
1436 MyProc
->delayChkptFlags
|= DELAY_CHKPT_START
;
1439 * Insert the commit XLOG record.
1441 XactLogCommitRecord(GetCurrentTransactionStopTimestamp(),
1442 nchildren
, children
, nrels
, rels
,
1443 ndroppedstats
, droppedstats
,
1444 nmsgs
, invalMessages
,
1445 RelcacheInitFileInval
,
1447 InvalidTransactionId
, NULL
/* plain commit */ );
1450 /* Move LSNs forward for this replication origin */
1451 replorigin_session_advance(replorigin_session_origin_lsn
,
1455 * Record commit timestamp. The value comes from plain commit
1456 * timestamp if there's no replication origin; otherwise, the
1457 * timestamp was already set in replorigin_session_origin_timestamp by
1460 * We don't need to WAL-log anything here, as the commit record
1461 * written above already contains the data.
1464 if (!replorigin
|| replorigin_session_origin_timestamp
== 0)
1465 replorigin_session_origin_timestamp
= GetCurrentTransactionStopTimestamp();
1467 TransactionTreeSetCommitTsData(xid
, nchildren
, children
,
1468 replorigin_session_origin_timestamp
,
1469 replorigin_session_origin
);
1473 * Check if we want to commit asynchronously. We can allow the XLOG flush
1474 * to happen asynchronously if synchronous_commit=off, or if the current
1475 * transaction has not performed any WAL-logged operation or didn't assign
1476 * an xid. The transaction can end up not writing any WAL, even if it has
1477 * an xid, if it only wrote to temporary and/or unlogged tables. It can
1478 * end up having written WAL without an xid if it did HOT pruning. In
1479 * case of a crash, the loss of such a transaction will be irrelevant;
1480 * temp tables will be lost anyway, unlogged tables will be truncated and
1481 * HOT pruning will be done again later. (Given the foregoing, you might
1482 * think that it would be unnecessary to emit the XLOG record at all in
1483 * this case, but we don't currently try to do that. It would certainly
1484 * cause problems at least in Hot Standby mode, where the
1485 * KnownAssignedXids machinery requires tracking every XID assignment. It
1486 * might be OK to skip it only when wal_level < replica, but for now we
1489 * However, if we're doing cleanup of any non-temp rels or committing any
1490 * command that wanted to force sync commit, then we must flush XLOG
1491 * immediately. (We must not allow asynchronous commit if there are any
1492 * non-temp tables to be deleted, because we might delete the files before
1493 * the COMMIT record is flushed to disk. We do allow asynchronous commit
1494 * if all to-be-deleted tables are temporary though, since they are lost
1495 * anyway if we crash.)
1497 if ((wrote_xlog
&& markXidCommitted
&&
1498 synchronous_commit
> SYNCHRONOUS_COMMIT_OFF
) ||
1499 forceSyncCommit
|| nrels
> 0)
1501 XLogFlush(XactLastRecEnd
);
1504 * Now we may update the CLOG, if we wrote a COMMIT record above
1506 if (markXidCommitted
)
1507 TransactionIdCommitTree(xid
, nchildren
, children
);
1512 * Asynchronous commit case:
1514 * This enables possible committed transaction loss in the case of a
1515 * postmaster crash because WAL buffers are left unwritten. Ideally we
1516 * could issue the WAL write without the fsync, but some
1517 * wal_sync_methods do not allow separate write/fsync.
1519 * Report the latest async commit LSN, so that the WAL writer knows to
1520 * flush this commit.
1522 XLogSetAsyncXactLSN(XactLastRecEnd
);
1525 * We must not immediately update the CLOG, since we didn't flush the
1526 * XLOG. Instead, we store the LSN up to which the XLOG must be
1527 * flushed before the CLOG may be updated.
1529 if (markXidCommitted
)
1530 TransactionIdAsyncCommitTree(xid
, nchildren
, children
, XactLastRecEnd
);
1534 * If we entered a commit critical section, leave it now, and let
1535 * checkpoints proceed.
1537 if (markXidCommitted
)
1539 MyProc
->delayChkptFlags
&= ~DELAY_CHKPT_START
;
1543 /* Compute latestXid while we have the child XIDs handy */
1544 latestXid
= TransactionIdLatest(xid
, nchildren
, children
);
1547 * Wait for synchronous replication, if required. Similar to the decision
1548 * above about using committing asynchronously we only want to wait if
1549 * this backend assigned an xid and wrote WAL. No need to wait if an xid
1550 * was assigned due to temporary/unlogged tables or due to HOT pruning.
1552 * Note that at this stage we have marked clog, but still show as running
1553 * in the procarray and continue to hold locks.
1555 if (wrote_xlog
&& markXidCommitted
)
1556 SyncRepWaitForLSN(XactLastRecEnd
, true);
1558 /* remember end of last commit record */
1559 XactLastCommitEnd
= XactLastRecEnd
;
1561 /* Reset XactLastRecEnd until the next transaction writes something */
1564 /* Clean up local data */
1568 pfree(droppedstats
);
1578 AtCCI_LocalCache(void)
1581 * Make any pending relation map changes visible. We must do this before
1582 * processing local sinval messages, so that the map changes will get
1583 * reflected into the relcache when relcache invals are processed.
1585 AtCCI_RelationMap();
1588 * Make catalog changes visible to me for the next command.
1590 CommandEndInvalidationMessages();
1597 AtCommit_Memory(void)
1599 TransactionState s
= CurrentTransactionState
;
1602 * Return to the memory context that was current before we started the
1603 * transaction. (In principle, this could not be any of the contexts we
1604 * are about to delete. If it somehow is, assertions in mcxt.c will
1607 MemoryContextSwitchTo(s
->priorContext
);
1610 * Release all transaction-local memory. TopTransactionContext survives
1611 * but becomes empty; any sub-contexts go away.
1613 Assert(TopTransactionContext
!= NULL
);
1614 MemoryContextReset(TopTransactionContext
);
1617 * Clear these pointers as a pro-forma matter. (Notionally, while
1618 * TopTransactionContext still exists, it's currently not associated with
1619 * this TransactionState struct.)
1621 CurTransactionContext
= NULL
;
1622 s
->curTransactionContext
= NULL
;
1625 /* ----------------------------------------------------------------
1626 * CommitSubTransaction stuff
1627 * ----------------------------------------------------------------
1631 * AtSubCommit_Memory
1634 AtSubCommit_Memory(void)
1636 TransactionState s
= CurrentTransactionState
;
1638 Assert(s
->parent
!= NULL
);
1640 /* Return to parent transaction level's memory context. */
1641 CurTransactionContext
= s
->parent
->curTransactionContext
;
1642 MemoryContextSwitchTo(CurTransactionContext
);
1645 * Ordinarily we cannot throw away the child's CurTransactionContext,
1646 * since the data it contains will be needed at upper commit. However, if
1647 * there isn't actually anything in it, we can throw it away. This avoids
1648 * a small memory leak in the common case of "trivial" subxacts.
1650 if (MemoryContextIsEmpty(s
->curTransactionContext
))
1652 MemoryContextDelete(s
->curTransactionContext
);
1653 s
->curTransactionContext
= NULL
;
1658 * AtSubCommit_childXids
1660 * Pass my own XID and my child XIDs up to my parent as committed children.
1663 AtSubCommit_childXids(void)
1665 TransactionState s
= CurrentTransactionState
;
1668 Assert(s
->parent
!= NULL
);
1671 * The parent childXids array will need to hold my XID and all my
1672 * childXids, in addition to the XIDs already there.
1674 new_nChildXids
= s
->parent
->nChildXids
+ s
->nChildXids
+ 1;
1676 /* Allocate or enlarge the parent array if necessary */
1677 if (s
->parent
->maxChildXids
< new_nChildXids
)
1679 int new_maxChildXids
;
1680 TransactionId
*new_childXids
;
1683 * Make it 2x what's needed right now, to avoid having to enlarge it
1684 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1685 * is what ensures that we don't need to worry about integer overflow
1686 * here or in the calculation of new_nChildXids.)
1688 new_maxChildXids
= Min(new_nChildXids
* 2,
1689 (int) (MaxAllocSize
/ sizeof(TransactionId
)));
1691 if (new_maxChildXids
< new_nChildXids
)
1693 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED
),
1694 errmsg("maximum number of committed subtransactions (%d) exceeded",
1695 (int) (MaxAllocSize
/ sizeof(TransactionId
)))));
1698 * We keep the child-XID arrays in TopTransactionContext; this avoids
1699 * setting up child-transaction contexts for what might be just a few
1700 * bytes of grandchild XIDs.
1702 if (s
->parent
->childXids
== NULL
)
1704 MemoryContextAlloc(TopTransactionContext
,
1705 new_maxChildXids
* sizeof(TransactionId
));
1707 new_childXids
= repalloc(s
->parent
->childXids
,
1708 new_maxChildXids
* sizeof(TransactionId
));
1710 s
->parent
->childXids
= new_childXids
;
1711 s
->parent
->maxChildXids
= new_maxChildXids
;
1715 * Copy all my XIDs to parent's array.
1717 * Note: We rely on the fact that the XID of a child always follows that
1718 * of its parent. By copying the XID of this subtransaction before the
1719 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1720 * all XIDs already in the array belong to subtransactions started and
1721 * subcommitted before us, so their XIDs must precede ours.
1723 s
->parent
->childXids
[s
->parent
->nChildXids
] = XidFromFullTransactionId(s
->fullTransactionId
);
1725 if (s
->nChildXids
> 0)
1726 memcpy(&s
->parent
->childXids
[s
->parent
->nChildXids
+ 1],
1728 s
->nChildXids
* sizeof(TransactionId
));
1730 s
->parent
->nChildXids
= new_nChildXids
;
1732 /* Release child's array to avoid leakage */
1733 if (s
->childXids
!= NULL
)
1734 pfree(s
->childXids
);
1735 /* We must reset these to avoid double-free if fail later in commit */
1736 s
->childXids
= NULL
;
1738 s
->maxChildXids
= 0;
1741 /* ----------------------------------------------------------------
1742 * AbortTransaction stuff
1743 * ----------------------------------------------------------------
1747 * RecordTransactionAbort
1749 * Returns latest XID among xact and its children, or InvalidTransactionId
1750 * if the xact has no XID. (We compute that here just because it's easier.)
1752 static TransactionId
1753 RecordTransactionAbort(bool isSubXact
)
1755 TransactionId xid
= GetCurrentTransactionIdIfAny();
1756 TransactionId latestXid
;
1758 RelFileLocator
*rels
;
1759 int ndroppedstats
= 0;
1760 xl_xact_stats_item
*droppedstats
= NULL
;
1762 TransactionId
*children
;
1763 TimestampTz xact_time
;
1767 * If we haven't been assigned an XID, nobody will care whether we aborted
1768 * or not. Hence, we're done in that case. It does not matter if we have
1769 * rels to delete (note that this routine is not responsible for actually
1770 * deleting 'em). We cannot have any child XIDs, either.
1772 if (!TransactionIdIsValid(xid
))
1774 /* Reset XactLastRecEnd until the next transaction writes something */
1777 return InvalidTransactionId
;
1781 * We have a valid XID, so we should write an ABORT record for it.
1783 * We do not flush XLOG to disk here, since the default assumption after a
1784 * crash would be that we aborted, anyway. For the same reason, we don't
1785 * need to worry about interlocking against checkpoint start.
1789 * Check that we haven't aborted halfway through RecordTransactionCommit.
1791 if (TransactionIdDidCommit(xid
))
1792 elog(PANIC
, "cannot abort transaction %u, it was already committed",
1796 * Are we using the replication origins feature? Or, in other words, are
1797 * we replaying remote actions?
1799 replorigin
= (replorigin_session_origin
!= InvalidRepOriginId
&&
1800 replorigin_session_origin
!= DoNotReplicateId
);
1802 /* Fetch the data we need for the abort record */
1803 nrels
= smgrGetPendingDeletes(false, &rels
);
1804 nchildren
= xactGetCommittedChildren(&children
);
1805 ndroppedstats
= pgstat_get_transactional_drops(false, &droppedstats
);
1807 /* XXX do we really need a critical section here? */
1808 START_CRIT_SECTION();
1810 /* Write the ABORT record */
1812 xact_time
= GetCurrentTimestamp();
1815 xact_time
= GetCurrentTransactionStopTimestamp();
1818 XactLogAbortRecord(xact_time
,
1819 nchildren
, children
,
1821 ndroppedstats
, droppedstats
,
1822 MyXactFlags
, InvalidTransactionId
,
1826 /* Move LSNs forward for this replication origin */
1827 replorigin_session_advance(replorigin_session_origin_lsn
,
1831 * Report the latest async abort LSN, so that the WAL writer knows to
1832 * flush this abort. There's nothing to be gained by delaying this, since
1833 * WALWriter may as well do this when it can. This is important with
1834 * streaming replication because if we don't flush WAL regularly we will
1835 * find that large aborts leave us with a long backlog for when commits
1836 * occur after the abort, increasing our window of data loss should
1837 * problems occur at that point.
1840 XLogSetAsyncXactLSN(XactLastRecEnd
);
1843 * Mark the transaction aborted in clog. This is not absolutely necessary
1844 * but we may as well do it while we are here; also, in the subxact case
1845 * it is helpful because XactLockTableWait makes use of it to avoid
1846 * waiting for already-aborted subtransactions. It is OK to do it without
1847 * having flushed the ABORT record to disk, because in event of a crash
1848 * we'd be assumed to have aborted anyway.
1850 TransactionIdAbortTree(xid
, nchildren
, children
);
1854 /* Compute latestXid while we have the child XIDs handy */
1855 latestXid
= TransactionIdLatest(xid
, nchildren
, children
);
1858 * If we're aborting a subtransaction, we can immediately remove failed
1859 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1860 * subxacts, because we already have the child XID array at hand. For
1861 * main xacts, the equivalent happens just after this function returns.
1864 XidCacheRemoveRunningXids(xid
, nchildren
, children
, latestXid
);
1866 /* Reset XactLastRecEnd until the next transaction writes something */
1870 /* And clean up local data */
1874 pfree(droppedstats
);
1883 AtAbort_Memory(void)
1886 * Switch into TransactionAbortContext, which should have some free space
1887 * even if nothing else does. We'll work in this context until we've
1888 * finished cleaning up.
1890 * It is barely possible to get here when we've not been able to create
1891 * TransactionAbortContext yet; if so use TopMemoryContext.
1893 if (TransactionAbortContext
!= NULL
)
1894 MemoryContextSwitchTo(TransactionAbortContext
);
1896 MemoryContextSwitchTo(TopMemoryContext
);
1903 AtSubAbort_Memory(void)
1905 Assert(TransactionAbortContext
!= NULL
);
1907 MemoryContextSwitchTo(TransactionAbortContext
);
1912 * AtAbort_ResourceOwner
1915 AtAbort_ResourceOwner(void)
1918 * Make sure we have a valid ResourceOwner, if possible (else it will be
1919 * NULL, which is OK)
1921 CurrentResourceOwner
= TopTransactionResourceOwner
;
1925 * AtSubAbort_ResourceOwner
1928 AtSubAbort_ResourceOwner(void)
1930 TransactionState s
= CurrentTransactionState
;
1932 /* Make sure we have a valid ResourceOwner */
1933 CurrentResourceOwner
= s
->curTransactionOwner
;
1938 * AtSubAbort_childXids
1941 AtSubAbort_childXids(void)
1943 TransactionState s
= CurrentTransactionState
;
1946 * We keep the child-XID arrays in TopTransactionContext (see
1947 * AtSubCommit_childXids). This means we'd better free the array
1948 * explicitly at abort to avoid leakage.
1950 if (s
->childXids
!= NULL
)
1951 pfree(s
->childXids
);
1952 s
->childXids
= NULL
;
1954 s
->maxChildXids
= 0;
1957 * We could prune the unreportedXids array here. But we don't bother. That
1958 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1959 * would likely introduce more CPU time into the more common paths, so we
1960 * choose not to do that.
1964 /* ----------------------------------------------------------------
1965 * CleanupTransaction stuff
1966 * ----------------------------------------------------------------
1973 AtCleanup_Memory(void)
1975 TransactionState s
= CurrentTransactionState
;
1977 /* Should be at top level */
1978 Assert(s
->parent
== NULL
);
1981 * Return to the memory context that was current before we started the
1982 * transaction. (In principle, this could not be any of the contexts we
1983 * are about to delete. If it somehow is, assertions in mcxt.c will
1986 MemoryContextSwitchTo(s
->priorContext
);
1989 * Clear the special abort context for next time.
1991 if (TransactionAbortContext
!= NULL
)
1992 MemoryContextReset(TransactionAbortContext
);
1995 * Release all transaction-local memory, the same as in AtCommit_Memory,
1996 * except we must cope with the possibility that we didn't get as far as
1997 * creating TopTransactionContext.
1999 if (TopTransactionContext
!= NULL
)
2000 MemoryContextReset(TopTransactionContext
);
2003 * Clear these pointers as a pro-forma matter. (Notionally, while
2004 * TopTransactionContext still exists, it's currently not associated with
2005 * this TransactionState struct.)
2007 CurTransactionContext
= NULL
;
2008 s
->curTransactionContext
= NULL
;
2012 /* ----------------------------------------------------------------
2013 * CleanupSubTransaction stuff
2014 * ----------------------------------------------------------------
2018 * AtSubCleanup_Memory
2021 AtSubCleanup_Memory(void)
2023 TransactionState s
= CurrentTransactionState
;
2025 Assert(s
->parent
!= NULL
);
2028 * Return to the memory context that was current before we started the
2029 * subtransaction. (In principle, this could not be any of the contexts
2030 * we are about to delete. If it somehow is, assertions in mcxt.c will
2033 MemoryContextSwitchTo(s
->priorContext
);
2035 /* Update CurTransactionContext (might not be same as priorContext) */
2036 CurTransactionContext
= s
->parent
->curTransactionContext
;
2039 * Clear the special abort context for next time.
2041 if (TransactionAbortContext
!= NULL
)
2042 MemoryContextReset(TransactionAbortContext
);
2045 * Delete the subxact local memory contexts. Its CurTransactionContext can
2046 * go too (note this also kills CurTransactionContexts from any children
2049 if (s
->curTransactionContext
)
2050 MemoryContextDelete(s
->curTransactionContext
);
2051 s
->curTransactionContext
= NULL
;
2054 /* ----------------------------------------------------------------
2055 * interface routines
2056 * ----------------------------------------------------------------
2063 StartTransaction(void)
2066 VirtualTransactionId vxid
;
2069 * Let's just make sure the state stack is empty
2071 s
= &TopTransactionStateData
;
2072 CurrentTransactionState
= s
;
2074 Assert(!FullTransactionIdIsValid(XactTopFullTransactionId
));
2076 /* check the current transaction state */
2077 Assert(s
->state
== TRANS_DEFAULT
);
2080 * Set the current transaction state information appropriately during
2081 * start processing. Note that once the transaction status is switched
2082 * this process cannot fail until the user ID and the security context
2083 * flags are fetched below.
2085 s
->state
= TRANS_START
;
2086 s
->fullTransactionId
= InvalidFullTransactionId
; /* until assigned */
2088 /* Determine if statements are logged in this transaction */
2089 xact_is_sampled
= log_xact_sample_rate
!= 0 &&
2090 (log_xact_sample_rate
== 1 ||
2091 pg_prng_double(&pg_global_prng_state
) <= log_xact_sample_rate
);
2094 * initialize current transaction state fields
2096 * note: prevXactReadOnly is not used at the outermost level
2098 s
->nestingLevel
= 1;
2099 s
->gucNestLevel
= 1;
2100 s
->childXids
= NULL
;
2102 s
->maxChildXids
= 0;
2105 * Once the current user ID and the security context flags are fetched,
2106 * both will be properly reset even if transaction startup fails.
2108 GetUserIdAndSecContext(&s
->prevUser
, &s
->prevSecContext
);
2110 /* SecurityRestrictionContext should never be set outside a transaction */
2111 Assert(s
->prevSecContext
== 0);
2114 * Make sure we've reset xact state variables
2116 * If recovery is still in progress, mark this transaction as read-only.
2117 * We have lower level defences in XLogInsert and elsewhere to stop us
2118 * from modifying data during recovery, but this gives the normal
2119 * indication to the user that the transaction is read-only.
2121 if (RecoveryInProgress())
2123 s
->startedInRecovery
= true;
2124 XactReadOnly
= true;
2128 s
->startedInRecovery
= false;
2129 XactReadOnly
= DefaultXactReadOnly
;
2131 XactDeferrable
= DefaultXactDeferrable
;
2132 XactIsoLevel
= DefaultXactIsoLevel
;
2133 forceSyncCommit
= false;
2137 * reinitialize within-transaction counters
2139 s
->subTransactionId
= TopSubTransactionId
;
2140 currentSubTransactionId
= TopSubTransactionId
;
2141 currentCommandId
= FirstCommandId
;
2142 currentCommandIdUsed
= false;
2145 * initialize reported xid accounting
2147 nUnreportedXids
= 0;
2148 s
->didLogXid
= false;
2151 * must initialize resource-management stuff first
2154 AtStart_ResourceOwner();
2157 * Assign a new LocalTransactionId, and combine it with the proc number to
2158 * form a virtual transaction id.
2160 vxid
.procNumber
= MyProcNumber
;
2161 vxid
.localTransactionId
= GetNextLocalTransactionId();
2164 * Lock the virtual transaction id before we announce it in the proc array
2166 VirtualXactLockTableInsert(vxid
);
2169 * Advertise it in the proc array. We assume assignment of
2170 * localTransactionId is atomic, and the proc number should be set
2173 Assert(MyProc
->vxid
.procNumber
== vxid
.procNumber
);
2174 MyProc
->vxid
.lxid
= vxid
.localTransactionId
;
2176 TRACE_POSTGRESQL_TRANSACTION_START(vxid
.localTransactionId
);
2179 * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2180 * be the same as the first command's statement_timestamp(), so don't do a
2181 * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2182 * for transactions started inside procedures (i.e., nonatomic SPI
2183 * contexts), we do need to advance the timestamp. Also, in a parallel
2184 * worker, the timestamp should already have been provided by a call to
2185 * SetParallelStartTimestamps().
2187 if (!IsParallelWorker())
2189 if (!SPI_inside_nonatomic_context())
2190 xactStartTimestamp
= stmtStartTimestamp
;
2192 xactStartTimestamp
= GetCurrentTimestamp();
2195 Assert(xactStartTimestamp
!= 0);
2196 pgstat_report_xact_timestamp(xactStartTimestamp
);
2197 /* Mark xactStopTimestamp as unset. */
2198 xactStopTimestamp
= 0;
2201 * initialize other subsystems for new transaction
2205 AfterTriggerBeginXact();
2208 * done with start processing, set current transaction state to "in
2211 s
->state
= TRANS_INPROGRESS
;
2213 /* Schedule transaction timeout */
2214 if (TransactionTimeout
> 0)
2215 enable_timeout_after(TRANSACTION_TIMEOUT
, TransactionTimeout
);
2217 ShowTransactionState("StartTransaction");
2224 * NB: if you change this routine, better look at PrepareTransaction too!
2227 CommitTransaction(void)
2229 TransactionState s
= CurrentTransactionState
;
2230 TransactionId latestXid
;
2231 bool is_parallel_worker
;
2233 is_parallel_worker
= (s
->blockState
== TBLOCK_PARALLEL_INPROGRESS
);
2235 /* Enforce parallel mode restrictions during parallel worker commit. */
2236 if (is_parallel_worker
)
2237 EnterParallelMode();
2239 ShowTransactionState("CommitTransaction");
2242 * check the current transaction state
2244 if (s
->state
!= TRANS_INPROGRESS
)
2245 elog(WARNING
, "CommitTransaction while in %s state",
2246 TransStateAsString(s
->state
));
2247 Assert(s
->parent
== NULL
);
2250 * Do pre-commit processing that involves calling user-defined code, such
2251 * as triggers. SECURITY_RESTRICTED_OPERATION contexts must not queue an
2252 * action that would run here, because that would bypass the sandbox.
2253 * Since closing cursors could queue trigger actions, triggers could open
2254 * cursors, etc, we have to keep looping until there's nothing left to do.
2259 * Fire all currently pending deferred triggers.
2261 AfterTriggerFireDeferred();
2264 * Close open portals (converting holdable ones into static portals).
2265 * If there weren't any, we are done ... otherwise loop back to check
2266 * if they queued deferred triggers. Lather, rinse, repeat.
2268 if (!PreCommit_Portals(false))
2273 * The remaining actions cannot call any user-defined code, so it's safe
2274 * to start shutting down within-transaction services. But note that most
2275 * of this stuff could still throw an error, which would switch us into
2276 * the transaction-abort path.
2279 CallXactCallbacks(is_parallel_worker
? XACT_EVENT_PARALLEL_PRE_COMMIT
2280 : XACT_EVENT_PRE_COMMIT
);
2283 * If this xact has started any unfinished parallel operation, clean up
2284 * its workers, warning about leaked resources. (But we don't actually
2285 * reset parallelModeLevel till entering TRANS_COMMIT, a bit below. This
2286 * keeps parallel mode restrictions active as long as possible in a
2289 AtEOXact_Parallel(true);
2290 if (is_parallel_worker
)
2292 if (s
->parallelModeLevel
!= 1)
2293 elog(WARNING
, "parallelModeLevel is %d not 1 at end of parallel worker transaction",
2294 s
->parallelModeLevel
);
2298 if (s
->parallelModeLevel
!= 0)
2299 elog(WARNING
, "parallelModeLevel is %d not 0 at end of transaction",
2300 s
->parallelModeLevel
);
2303 /* Shut down the deferred-trigger manager */
2304 AfterTriggerEndXact(true);
2307 * Let ON COMMIT management do its thing (must happen after closing
2308 * cursors, to avoid dangling-reference problems)
2310 PreCommit_on_commit_actions();
2313 * Synchronize files that are created and not WAL-logged during this
2314 * transaction. This must happen before AtEOXact_RelationMap(), so that we
2315 * don't see committed-but-broken files after a crash.
2317 smgrDoPendingSyncs(true, is_parallel_worker
);
2319 /* close large objects before lower-level cleanup */
2320 AtEOXact_LargeObject(true);
2323 * Insert notifications sent by NOTIFY commands into the queue. This
2324 * should be late in the pre-commit sequence to minimize time spent
2325 * holding the notify-insertion lock. However, this could result in
2326 * creating a snapshot, so we must do it before serializable cleanup.
2331 * Mark serializable transaction as complete for predicate locking
2332 * purposes. This should be done as late as we can put it and still allow
2333 * errors to be raised for failure patterns found at commit. This is not
2334 * appropriate in a parallel worker however, because we aren't committing
2335 * the leader's transaction and its serializable state will live on.
2337 if (!is_parallel_worker
)
2338 PreCommit_CheckForSerializationFailure();
2340 /* Prevent cancel/die interrupt while cleaning up */
2343 /* Commit updates to the relation map --- do this as late as possible */
2344 AtEOXact_RelationMap(true, is_parallel_worker
);
2347 * set the current transaction state information appropriately during
2350 s
->state
= TRANS_COMMIT
;
2351 s
->parallelModeLevel
= 0;
2352 s
->parallelChildXact
= false; /* should be false already */
2354 /* Disable transaction timeout */
2355 if (TransactionTimeout
> 0)
2356 disable_timeout(TRANSACTION_TIMEOUT
, false);
2358 if (!is_parallel_worker
)
2361 * We need to mark our XIDs as committed in pg_xact. This is where we
2364 latestXid
= RecordTransactionCommit();
2369 * We must not mark our XID committed; the parallel leader is
2370 * responsible for that.
2372 latestXid
= InvalidTransactionId
;
2375 * Make sure the leader will know about any WAL we wrote before it
2378 ParallelWorkerReportLastRecEnd(XactLastRecEnd
);
2381 TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc
->vxid
.lxid
);
2384 * Let others know about no transaction in progress by me. Note that this
2385 * must be done _before_ releasing locks we hold and _after_
2386 * RecordTransactionCommit.
2388 ProcArrayEndTransaction(MyProc
, latestXid
);
2391 * This is all post-commit cleanup. Note that if an error is raised here,
2392 * it's too late to abort the transaction. This should be just
2393 * noncritical resource releasing.
2395 * The ordering of operations is not entirely random. The idea is:
2396 * release resources visible to other backends (eg, files, buffer pins);
2397 * then release locks; then release backend-local resources. We want to
2398 * release locks at the point where any backend waiting for us will see
2399 * our transaction as being fully cleaned up.
2401 * Resources that can be associated with individual queries are handled by
2402 * the ResourceOwner mechanism. The other calls here are for backend-wide
2406 CallXactCallbacks(is_parallel_worker
? XACT_EVENT_PARALLEL_COMMIT
2407 : XACT_EVENT_COMMIT
);
2409 CurrentResourceOwner
= NULL
;
2410 ResourceOwnerRelease(TopTransactionResourceOwner
,
2411 RESOURCE_RELEASE_BEFORE_LOCKS
,
2414 /* Check we've released all buffer pins */
2415 AtEOXact_Buffers(true);
2417 /* Clean up the relation cache */
2418 AtEOXact_RelationCache(true);
2420 /* Clean up the type cache */
2421 AtEOXact_TypeCache();
2424 * Make catalog changes visible to all backends. This has to happen after
2425 * relcache references are dropped (see comments for
2426 * AtEOXact_RelationCache), but before locks are released (if anyone is
2427 * waiting for lock on a relation we've modified, we want them to know
2428 * about the catalog change before they start using the relation).
2430 AtEOXact_Inval(true);
2432 AtEOXact_MultiXact();
2434 ResourceOwnerRelease(TopTransactionResourceOwner
,
2435 RESOURCE_RELEASE_LOCKS
,
2437 ResourceOwnerRelease(TopTransactionResourceOwner
,
2438 RESOURCE_RELEASE_AFTER_LOCKS
,
2442 * Likewise, dropping of files deleted during the transaction is best done
2443 * after releasing relcache and buffer pins. (This is not strictly
2444 * necessary during commit, since such pins should have been released
2445 * already, but this ordering is definitely critical during abort.) Since
2446 * this may take many seconds, also delay until after releasing locks.
2447 * Other backends will observe the attendant catalog changes and not
2448 * attempt to access affected files.
2450 smgrDoPendingDeletes(true);
2453 * Send out notification signals to other backends (and do other
2454 * post-commit NOTIFY cleanup). This must not happen until after our
2455 * transaction is fully done from the viewpoint of other backends.
2460 * Everything after this should be purely internal-to-this-backend
2463 AtEOXact_GUC(true, 1);
2466 AtEOXact_on_commit_actions(true);
2467 AtEOXact_Namespace(true, is_parallel_worker
);
2469 AtEOXact_Files(true);
2470 AtEOXact_ComboCid();
2471 AtEOXact_HashTables(true);
2472 AtEOXact_PgStat(true, is_parallel_worker
);
2473 AtEOXact_Snapshot(true, false);
2474 AtEOXact_ApplyLauncher(true);
2475 AtEOXact_LogicalRepWorkers(true);
2476 pgstat_report_xact_timestamp(0);
2478 ResourceOwnerDelete(TopTransactionResourceOwner
);
2479 s
->curTransactionOwner
= NULL
;
2480 CurTransactionResourceOwner
= NULL
;
2481 TopTransactionResourceOwner
= NULL
;
2485 s
->fullTransactionId
= InvalidFullTransactionId
;
2486 s
->subTransactionId
= InvalidSubTransactionId
;
2487 s
->nestingLevel
= 0;
2488 s
->gucNestLevel
= 0;
2489 s
->childXids
= NULL
;
2491 s
->maxChildXids
= 0;
2493 XactTopFullTransactionId
= InvalidFullTransactionId
;
2494 nParallelCurrentXids
= 0;
2497 * done with commit processing, set current transaction state back to
2500 s
->state
= TRANS_DEFAULT
;
2502 RESUME_INTERRUPTS();
2507 * PrepareTransaction
2509 * NB: if you change this routine, better look at CommitTransaction too!
2512 PrepareTransaction(void)
2514 TransactionState s
= CurrentTransactionState
;
2515 TransactionId xid
= GetCurrentTransactionId();
2516 GlobalTransaction gxact
;
2517 TimestampTz prepared_at
;
2519 Assert(!IsInParallelMode());
2521 ShowTransactionState("PrepareTransaction");
2524 * check the current transaction state
2526 if (s
->state
!= TRANS_INPROGRESS
)
2527 elog(WARNING
, "PrepareTransaction while in %s state",
2528 TransStateAsString(s
->state
));
2529 Assert(s
->parent
== NULL
);
2532 * Do pre-commit processing that involves calling user-defined code, such
2533 * as triggers. Since closing cursors could queue trigger actions,
2534 * triggers could open cursors, etc, we have to keep looping until there's
2535 * nothing left to do.
2540 * Fire all currently pending deferred triggers.
2542 AfterTriggerFireDeferred();
2545 * Close open portals (converting holdable ones into static portals).
2546 * If there weren't any, we are done ... otherwise loop back to check
2547 * if they queued deferred triggers. Lather, rinse, repeat.
2549 if (!PreCommit_Portals(true))
2553 CallXactCallbacks(XACT_EVENT_PRE_PREPARE
);
2556 * The remaining actions cannot call any user-defined code, so it's safe
2557 * to start shutting down within-transaction services. But note that most
2558 * of this stuff could still throw an error, which would switch us into
2559 * the transaction-abort path.
2562 /* Shut down the deferred-trigger manager */
2563 AfterTriggerEndXact(true);
2566 * Let ON COMMIT management do its thing (must happen after closing
2567 * cursors, to avoid dangling-reference problems)
2569 PreCommit_on_commit_actions();
2572 * Synchronize files that are created and not WAL-logged during this
2573 * transaction. This must happen before EndPrepare(), so that we don't see
2574 * committed-but-broken files after a crash and COMMIT PREPARED.
2576 smgrDoPendingSyncs(true, false);
2578 /* close large objects before lower-level cleanup */
2579 AtEOXact_LargeObject(true);
2581 /* NOTIFY requires no work at this point */
2584 * Mark serializable transaction as complete for predicate locking
2585 * purposes. This should be done as late as we can put it and still allow
2586 * errors to be raised for failure patterns found at commit.
2588 PreCommit_CheckForSerializationFailure();
2591 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2592 * this transaction. Having the prepared xact hold locks on another
2593 * backend's temp table seems a bad idea --- for instance it would prevent
2594 * the backend from exiting. There are other problems too, such as how to
2595 * clean up the source backend's local buffers and ON COMMIT state if the
2596 * prepared xact includes a DROP of a temp table.
2598 * Other objects types, like functions, operators or extensions, share the
2599 * same restriction as they should not be created, locked or dropped as
2600 * this can mess up with this session or even a follow-up session trying
2601 * to use the same temporary namespace.
2603 * We must check this after executing any ON COMMIT actions, because they
2604 * might still access a temp relation.
2606 * XXX In principle this could be relaxed to allow some useful special
2607 * cases, such as a temp table created and dropped all within the
2608 * transaction. That seems to require much more bookkeeping though.
2610 if ((MyXactFlags
& XACT_FLAGS_ACCESSEDTEMPNAMESPACE
))
2612 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
2613 errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2616 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2617 * supported if we added cleanup logic to twophase.c, but for now it
2618 * doesn't seem worth the trouble.
2620 if (XactHasExportedSnapshots())
2622 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
2623 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2625 /* Prevent cancel/die interrupt while cleaning up */
2629 * set the current transaction state information appropriately during
2630 * prepare processing
2632 s
->state
= TRANS_PREPARE
;
2634 /* Disable transaction timeout */
2635 if (TransactionTimeout
> 0)
2636 disable_timeout(TRANSACTION_TIMEOUT
, false);
2638 prepared_at
= GetCurrentTimestamp();
2641 * Reserve the GID for this transaction. This could fail if the requested
2642 * GID is invalid or already in use.
2644 gxact
= MarkAsPreparing(xid
, prepareGID
, prepared_at
,
2645 GetUserId(), MyDatabaseId
);
2649 * Collect data for the 2PC state file. Note that in general, no actual
2650 * state change should happen in the called modules during this step,
2651 * since it's still possible to fail before commit, and in that case we
2652 * want transaction abort to be able to clean up. (In particular, the
2653 * AtPrepare routines may error out if they find cases they cannot
2654 * handle.) State cleanup should happen in the PostPrepare routines
2655 * below. However, some modules can go ahead and clear state here because
2656 * they wouldn't do anything with it during abort anyway.
2658 * Note: because the 2PC state file records will be replayed in the same
2659 * order they are made, the order of these calls has to match the order in
2660 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2661 * PREPARED; in particular, pay attention to whether things should happen
2662 * before or after releasing the transaction's locks.
2664 StartPrepare(gxact
);
2668 AtPrepare_PredicateLocks();
2670 AtPrepare_MultiXact();
2671 AtPrepare_RelationMap();
2674 * Here is where we really truly prepare.
2676 * We have to record transaction prepares even if we didn't make any
2677 * updates, because the transaction manager might get confused if we lose
2678 * a global transaction.
2683 * Now we clean up backend-internal state and release internal resources.
2686 /* Reset XactLastRecEnd until the next transaction writes something */
2690 * Transfer our locks to a dummy PGPROC. This has to be done before
2691 * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2692 * conclude "xact already committed or aborted" for our locks.
2694 PostPrepare_Locks(xid
);
2697 * Let others know about no transaction in progress by me. This has to be
2698 * done *after* the prepared transaction has been marked valid, else
2699 * someone may think it is unlocked and recyclable.
2701 ProcArrayClearTransaction(MyProc
);
2704 * In normal commit-processing, this is all non-critical post-transaction
2705 * cleanup. When the transaction is prepared, however, it's important
2706 * that the locks and other per-backend resources are transferred to the
2707 * prepared transaction's PGPROC entry. Note that if an error is raised
2708 * here, it's too late to abort the transaction. XXX: This probably should
2709 * be in a critical section, to force a PANIC if any of this fails, but
2710 * that cure could be worse than the disease.
2713 CallXactCallbacks(XACT_EVENT_PREPARE
);
2715 ResourceOwnerRelease(TopTransactionResourceOwner
,
2716 RESOURCE_RELEASE_BEFORE_LOCKS
,
2719 /* Check we've released all buffer pins */
2720 AtEOXact_Buffers(true);
2722 /* Clean up the relation cache */
2723 AtEOXact_RelationCache(true);
2725 /* Clean up the type cache */
2726 AtEOXact_TypeCache();
2728 /* notify doesn't need a postprepare call */
2730 PostPrepare_PgStat();
2732 PostPrepare_Inval();
2736 PostPrepare_MultiXact(xid
);
2738 PostPrepare_PredicateLocks(xid
);
2740 ResourceOwnerRelease(TopTransactionResourceOwner
,
2741 RESOURCE_RELEASE_LOCKS
,
2743 ResourceOwnerRelease(TopTransactionResourceOwner
,
2744 RESOURCE_RELEASE_AFTER_LOCKS
,
2748 * Allow another backend to finish the transaction. After
2749 * PostPrepare_Twophase(), the transaction is completely detached from our
2750 * backend. The rest is just non-critical cleanup of backend-local state.
2752 PostPrepare_Twophase();
2754 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2755 AtEOXact_GUC(true, 1);
2758 AtEOXact_on_commit_actions(true);
2759 AtEOXact_Namespace(true, false);
2761 AtEOXact_Files(true);
2762 AtEOXact_ComboCid();
2763 AtEOXact_HashTables(true);
2764 /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2765 AtEOXact_Snapshot(true, true);
2766 /* we treat PREPARE as ROLLBACK so far as waking workers goes */
2767 AtEOXact_ApplyLauncher(false);
2768 AtEOXact_LogicalRepWorkers(false);
2769 pgstat_report_xact_timestamp(0);
2771 CurrentResourceOwner
= NULL
;
2772 ResourceOwnerDelete(TopTransactionResourceOwner
);
2773 s
->curTransactionOwner
= NULL
;
2774 CurTransactionResourceOwner
= NULL
;
2775 TopTransactionResourceOwner
= NULL
;
2779 s
->fullTransactionId
= InvalidFullTransactionId
;
2780 s
->subTransactionId
= InvalidSubTransactionId
;
2781 s
->nestingLevel
= 0;
2782 s
->gucNestLevel
= 0;
2783 s
->childXids
= NULL
;
2785 s
->maxChildXids
= 0;
2787 XactTopFullTransactionId
= InvalidFullTransactionId
;
2788 nParallelCurrentXids
= 0;
2791 * done with 1st phase commit processing, set current transaction state
2794 s
->state
= TRANS_DEFAULT
;
2796 RESUME_INTERRUPTS();
2804 AbortTransaction(void)
2806 TransactionState s
= CurrentTransactionState
;
2807 TransactionId latestXid
;
2808 bool is_parallel_worker
;
2810 /* Prevent cancel/die interrupt while cleaning up */
2813 /* Disable transaction timeout */
2814 if (TransactionTimeout
> 0)
2815 disable_timeout(TRANSACTION_TIMEOUT
, false);
2817 /* Make sure we have a valid memory context and resource owner */
2819 AtAbort_ResourceOwner();
2822 * Release any LW locks we might be holding as quickly as possible.
2823 * (Regular locks, however, must be held till we finish aborting.)
2824 * Releasing LW locks is critical since we might try to grab them again
2825 * while cleaning up!
2829 /* Clear wait information and command progress indicator */
2830 pgstat_report_wait_end();
2831 pgstat_progress_end_command();
2833 /* Clean up buffer content locks, too */
2836 /* Reset WAL record construction state */
2837 XLogResetInsertion();
2839 /* Cancel condition variable sleep */
2840 ConditionVariableCancelSleep();
2843 * Also clean up any open wait for lock, since the lock manager will choke
2844 * if we try to wait for another lock before doing this.
2849 * If any timeout events are still active, make sure the timeout interrupt
2850 * is scheduled. This covers possible loss of a timeout interrupt due to
2851 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2852 * We delay this till after LockErrorCleanup so that we don't uselessly
2853 * reschedule lock or deadlock check timeouts.
2855 reschedule_timeouts();
2858 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2859 * handler. We do this fairly early in the sequence so that the timeout
2860 * infrastructure will be functional if needed while aborting.
2862 sigprocmask(SIG_SETMASK
, &UnBlockSig
, NULL
);
2865 * check the current transaction state
2867 is_parallel_worker
= (s
->blockState
== TBLOCK_PARALLEL_INPROGRESS
);
2868 if (s
->state
!= TRANS_INPROGRESS
&& s
->state
!= TRANS_PREPARE
)
2869 elog(WARNING
, "AbortTransaction while in %s state",
2870 TransStateAsString(s
->state
));
2871 Assert(s
->parent
== NULL
);
2874 * set the current transaction state information appropriately during the
2877 s
->state
= TRANS_ABORT
;
2880 * Reset user ID which might have been changed transiently. We need this
2881 * to clean up in case control escaped out of a SECURITY DEFINER function
2882 * or other local change of CurrentUserId; therefore, the prior value of
2883 * SecurityRestrictionContext also needs to be restored.
2885 * (Note: it is not necessary to restore session authorization or role
2886 * settings here because those can only be changed via GUC, and GUC will
2887 * take care of rolling them back if need be.)
2889 SetUserIdAndSecContext(s
->prevUser
, s
->prevSecContext
);
2891 /* Forget about any active REINDEX. */
2892 ResetReindexState(s
->nestingLevel
);
2894 /* Reset logical streaming state. */
2895 ResetLogicalStreamingState();
2897 /* Reset snapshot export state. */
2898 SnapBuildResetExportedSnapshotState();
2901 * If this xact has started any unfinished parallel operation, clean up
2902 * its workers and exit parallel mode. Don't warn about leaked resources.
2904 AtEOXact_Parallel(false);
2905 s
->parallelModeLevel
= 0;
2906 s
->parallelChildXact
= false; /* should be false already */
2909 * do abort processing
2911 AfterTriggerEndXact(false); /* 'false' means it's abort */
2913 smgrDoPendingSyncs(false, is_parallel_worker
);
2914 AtEOXact_LargeObject(false);
2916 AtEOXact_RelationMap(false, is_parallel_worker
);
2920 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2921 * far as assigning an XID to advertise). But if we're inside a parallel
2922 * worker, skip this; the user backend must be the one to write the abort
2925 if (!is_parallel_worker
)
2926 latestXid
= RecordTransactionAbort(false);
2929 latestXid
= InvalidTransactionId
;
2932 * Since the parallel leader won't get our value of XactLastRecEnd in
2933 * this case, we nudge WAL-writer ourselves in this case. See related
2934 * comments in RecordTransactionAbort for why this matters.
2936 XLogSetAsyncXactLSN(XactLastRecEnd
);
2939 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc
->vxid
.lxid
);
2942 * Let others know about no transaction in progress by me. Note that this
2943 * must be done _before_ releasing locks we hold and _after_
2944 * RecordTransactionAbort.
2946 ProcArrayEndTransaction(MyProc
, latestXid
);
2949 * Post-abort cleanup. See notes in CommitTransaction() concerning
2950 * ordering. We can skip all of it if the transaction failed before
2951 * creating a resource owner.
2953 if (TopTransactionResourceOwner
!= NULL
)
2955 if (is_parallel_worker
)
2956 CallXactCallbacks(XACT_EVENT_PARALLEL_ABORT
);
2958 CallXactCallbacks(XACT_EVENT_ABORT
);
2960 ResourceOwnerRelease(TopTransactionResourceOwner
,
2961 RESOURCE_RELEASE_BEFORE_LOCKS
,
2963 AtEOXact_Buffers(false);
2964 AtEOXact_RelationCache(false);
2965 AtEOXact_TypeCache();
2966 AtEOXact_Inval(false);
2967 AtEOXact_MultiXact();
2968 ResourceOwnerRelease(TopTransactionResourceOwner
,
2969 RESOURCE_RELEASE_LOCKS
,
2971 ResourceOwnerRelease(TopTransactionResourceOwner
,
2972 RESOURCE_RELEASE_AFTER_LOCKS
,
2974 smgrDoPendingDeletes(false);
2976 AtEOXact_GUC(false, 1);
2977 AtEOXact_SPI(false);
2979 AtEOXact_on_commit_actions(false);
2980 AtEOXact_Namespace(false, is_parallel_worker
);
2982 AtEOXact_Files(false);
2983 AtEOXact_ComboCid();
2984 AtEOXact_HashTables(false);
2985 AtEOXact_PgStat(false, is_parallel_worker
);
2986 AtEOXact_ApplyLauncher(false);
2987 AtEOXact_LogicalRepWorkers(false);
2988 pgstat_report_xact_timestamp(0);
2992 * State remains TRANS_ABORT until CleanupTransaction().
2994 RESUME_INTERRUPTS();
2998 * CleanupTransaction
3001 CleanupTransaction(void)
3003 TransactionState s
= CurrentTransactionState
;
3006 * State should still be TRANS_ABORT from AbortTransaction().
3008 if (s
->state
!= TRANS_ABORT
)
3009 elog(FATAL
, "CleanupTransaction: unexpected state %s",
3010 TransStateAsString(s
->state
));
3013 * do abort cleanup processing
3015 AtCleanup_Portals(); /* now safe to release portal memory */
3016 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
3018 CurrentResourceOwner
= NULL
; /* and resource owner */
3019 if (TopTransactionResourceOwner
)
3020 ResourceOwnerDelete(TopTransactionResourceOwner
);
3021 s
->curTransactionOwner
= NULL
;
3022 CurTransactionResourceOwner
= NULL
;
3023 TopTransactionResourceOwner
= NULL
;
3025 AtCleanup_Memory(); /* and transaction memory */
3027 s
->fullTransactionId
= InvalidFullTransactionId
;
3028 s
->subTransactionId
= InvalidSubTransactionId
;
3029 s
->nestingLevel
= 0;
3030 s
->gucNestLevel
= 0;
3031 s
->childXids
= NULL
;
3033 s
->maxChildXids
= 0;
3034 s
->parallelModeLevel
= 0;
3035 s
->parallelChildXact
= false;
3037 XactTopFullTransactionId
= InvalidFullTransactionId
;
3038 nParallelCurrentXids
= 0;
3041 * done with abort processing, set current transaction state back to
3044 s
->state
= TRANS_DEFAULT
;
3048 * StartTransactionCommand
3051 StartTransactionCommand(void)
3053 TransactionState s
= CurrentTransactionState
;
3055 switch (s
->blockState
)
3058 * if we aren't in a transaction block, we just do our usual start
3061 case TBLOCK_DEFAULT
:
3063 s
->blockState
= TBLOCK_STARTED
;
3067 * We are somewhere in a transaction block or subtransaction and
3068 * about to start a new command. For now we do nothing, but
3069 * someday we may do command-local resource initialization. (Note
3070 * that any needed CommandCounterIncrement was done by the
3071 * previous CommitTransactionCommand.)
3073 case TBLOCK_INPROGRESS
:
3074 case TBLOCK_IMPLICIT_INPROGRESS
:
3075 case TBLOCK_SUBINPROGRESS
:
3079 * Here we are in a failed transaction block (one of the commands
3080 * caused an abort) so we do nothing but remain in the abort
3081 * state. Eventually we will get a ROLLBACK command which will
3082 * get us out of this state. (It is up to other code to ensure
3083 * that no commands other than ROLLBACK will be processed in these
3087 case TBLOCK_SUBABORT
:
3090 /* These cases are invalid. */
3091 case TBLOCK_STARTED
:
3093 case TBLOCK_PARALLEL_INPROGRESS
:
3094 case TBLOCK_SUBBEGIN
:
3096 case TBLOCK_SUBRELEASE
:
3097 case TBLOCK_SUBCOMMIT
:
3098 case TBLOCK_ABORT_END
:
3099 case TBLOCK_SUBABORT_END
:
3100 case TBLOCK_ABORT_PENDING
:
3101 case TBLOCK_SUBABORT_PENDING
:
3102 case TBLOCK_SUBRESTART
:
3103 case TBLOCK_SUBABORT_RESTART
:
3104 case TBLOCK_PREPARE
:
3105 elog(ERROR
, "StartTransactionCommand: unexpected state %s",
3106 BlockStateAsString(s
->blockState
));
3111 * We must switch to CurTransactionContext before returning. This is
3112 * already done if we called StartTransaction, otherwise not.
3114 Assert(CurTransactionContext
!= NULL
);
3115 MemoryContextSwitchTo(CurTransactionContext
);
3120 * Simple system for saving and restoring transaction characteristics
3121 * (isolation level, read only, deferrable). We need this for transaction
3122 * chaining, so that we can set the characteristics of the new transaction to
3123 * be the same as the previous one. (We need something like this because the
3124 * GUC system resets the characteristics at transaction end, so for example
3125 * just skipping the reset in StartTransaction() won't work.)
3128 SaveTransactionCharacteristics(SavedTransactionCharacteristics
*s
)
3130 s
->save_XactIsoLevel
= XactIsoLevel
;
3131 s
->save_XactReadOnly
= XactReadOnly
;
3132 s
->save_XactDeferrable
= XactDeferrable
;
3136 RestoreTransactionCharacteristics(const SavedTransactionCharacteristics
*s
)
3138 XactIsoLevel
= s
->save_XactIsoLevel
;
3139 XactReadOnly
= s
->save_XactReadOnly
;
3140 XactDeferrable
= s
->save_XactDeferrable
;
3144 * CommitTransactionCommand -- a wrapper function handling the
3145 * loop over subtransactions to avoid a potentially dangerous recursion
3146 * in CommitTransactionCommandInternal().
3149 CommitTransactionCommand(void)
3152 * Repeatedly call CommitTransactionCommandInternal() until all the work
3155 while (!CommitTransactionCommandInternal())
3161 * CommitTransactionCommandInternal - a function doing an iteration of work
3162 * regarding handling the commit transaction command. In the case of
3163 * subtransactions more than one iterations could be required. Returns
3164 * true when no more iterations required, false otherwise.
3167 CommitTransactionCommandInternal(void)
3169 TransactionState s
= CurrentTransactionState
;
3170 SavedTransactionCharacteristics savetc
;
3172 /* Must save in case we need to restore below */
3173 SaveTransactionCharacteristics(&savetc
);
3175 switch (s
->blockState
)
3178 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3179 * StartTransactionCommand didn't set the STARTED state
3180 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3181 * by EndParallelWorkerTransaction(), not this function.
3183 case TBLOCK_DEFAULT
:
3184 case TBLOCK_PARALLEL_INPROGRESS
:
3185 elog(FATAL
, "CommitTransactionCommand: unexpected state %s",
3186 BlockStateAsString(s
->blockState
));
3190 * If we aren't in a transaction block, just do our usual
3191 * transaction commit, and return to the idle state.
3193 case TBLOCK_STARTED
:
3194 CommitTransaction();
3195 s
->blockState
= TBLOCK_DEFAULT
;
3199 * We are completing a "BEGIN TRANSACTION" command, so we change
3200 * to the "transaction block in progress" state and return. (We
3201 * assume the BEGIN did nothing to the database, so we need no
3202 * CommandCounterIncrement.)
3205 s
->blockState
= TBLOCK_INPROGRESS
;
3209 * This is the case when we have finished executing a command
3210 * someplace within a transaction block. We increment the command
3211 * counter and return.
3213 case TBLOCK_INPROGRESS
:
3214 case TBLOCK_IMPLICIT_INPROGRESS
:
3215 case TBLOCK_SUBINPROGRESS
:
3216 CommandCounterIncrement();
3220 * We are completing a "COMMIT" command. Do it and return to the
3224 CommitTransaction();
3225 s
->blockState
= TBLOCK_DEFAULT
;
3229 s
->blockState
= TBLOCK_INPROGRESS
;
3231 RestoreTransactionCharacteristics(&savetc
);
3236 * Here we are in the middle of a transaction block but one of the
3237 * commands caused an abort so we do nothing but remain in the
3238 * abort state. Eventually we will get a ROLLBACK command.
3241 case TBLOCK_SUBABORT
:
3245 * Here we were in an aborted transaction block and we just got
3246 * the ROLLBACK command from the user, so clean up the
3247 * already-aborted transaction and return to the idle state.
3249 case TBLOCK_ABORT_END
:
3250 CleanupTransaction();
3251 s
->blockState
= TBLOCK_DEFAULT
;
3255 s
->blockState
= TBLOCK_INPROGRESS
;
3257 RestoreTransactionCharacteristics(&savetc
);
3262 * Here we were in a perfectly good transaction block but the user
3263 * told us to ROLLBACK anyway. We have to abort the transaction
3264 * and then clean up.
3266 case TBLOCK_ABORT_PENDING
:
3268 CleanupTransaction();
3269 s
->blockState
= TBLOCK_DEFAULT
;
3273 s
->blockState
= TBLOCK_INPROGRESS
;
3275 RestoreTransactionCharacteristics(&savetc
);
3280 * We are completing a "PREPARE TRANSACTION" command. Do it and
3281 * return to the idle state.
3283 case TBLOCK_PREPARE
:
3284 PrepareTransaction();
3285 s
->blockState
= TBLOCK_DEFAULT
;
3289 * The user issued a SAVEPOINT inside a transaction block. Start a
3290 * subtransaction. (DefineSavepoint already did PushTransaction,
3291 * so as to have someplace to put the SUBBEGIN state.)
3293 case TBLOCK_SUBBEGIN
:
3294 StartSubTransaction();
3295 s
->blockState
= TBLOCK_SUBINPROGRESS
;
3299 * The user issued a RELEASE command, so we end the current
3300 * subtransaction and return to the parent transaction. The parent
3301 * might be ended too, so repeat till we find an INPROGRESS
3302 * transaction or subtransaction.
3304 case TBLOCK_SUBRELEASE
:
3307 CommitSubTransaction();
3308 s
= CurrentTransactionState
; /* changed by pop */
3309 } while (s
->blockState
== TBLOCK_SUBRELEASE
);
3311 Assert(s
->blockState
== TBLOCK_INPROGRESS
||
3312 s
->blockState
== TBLOCK_SUBINPROGRESS
);
3316 * The user issued a COMMIT, so we end the current subtransaction
3317 * hierarchy and perform final commit. We do this by rolling up
3318 * any subtransactions into their parent, which leads to O(N^2)
3319 * operations with respect to resource owners - this isn't that
3320 * bad until we approach a thousands of savepoints but is
3321 * necessary for correctness should after triggers create new
3324 case TBLOCK_SUBCOMMIT
:
3327 CommitSubTransaction();
3328 s
= CurrentTransactionState
; /* changed by pop */
3329 } while (s
->blockState
== TBLOCK_SUBCOMMIT
);
3330 /* If we had a COMMIT command, finish off the main xact too */
3331 if (s
->blockState
== TBLOCK_END
)
3333 Assert(s
->parent
== NULL
);
3334 CommitTransaction();
3335 s
->blockState
= TBLOCK_DEFAULT
;
3339 s
->blockState
= TBLOCK_INPROGRESS
;
3341 RestoreTransactionCharacteristics(&savetc
);
3344 else if (s
->blockState
== TBLOCK_PREPARE
)
3346 Assert(s
->parent
== NULL
);
3347 PrepareTransaction();
3348 s
->blockState
= TBLOCK_DEFAULT
;
3351 elog(ERROR
, "CommitTransactionCommand: unexpected state %s",
3352 BlockStateAsString(s
->blockState
));
3356 * The current already-failed subtransaction is ending due to a
3357 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3358 * examine the parent (which could be in any of several states).
3359 * As we need to examine the parent, return false to request the
3360 * caller to do the next iteration.
3362 case TBLOCK_SUBABORT_END
:
3363 CleanupSubTransaction();
3367 * As above, but it's not dead yet, so abort first.
3369 case TBLOCK_SUBABORT_PENDING
:
3370 AbortSubTransaction();
3371 CleanupSubTransaction();
3375 * The current subtransaction is the target of a ROLLBACK TO
3376 * command. Abort and pop it, then start a new subtransaction
3377 * with the same name.
3379 case TBLOCK_SUBRESTART
:
3384 /* save name and keep Cleanup from freeing it */
3387 savepointLevel
= s
->savepointLevel
;
3389 AbortSubTransaction();
3390 CleanupSubTransaction();
3392 DefineSavepoint(NULL
);
3393 s
= CurrentTransactionState
; /* changed by push */
3395 s
->savepointLevel
= savepointLevel
;
3397 /* This is the same as TBLOCK_SUBBEGIN case */
3398 Assert(s
->blockState
== TBLOCK_SUBBEGIN
);
3399 StartSubTransaction();
3400 s
->blockState
= TBLOCK_SUBINPROGRESS
;
3405 * Same as above, but the subtransaction had already failed, so we
3406 * don't need AbortSubTransaction.
3408 case TBLOCK_SUBABORT_RESTART
:
3413 /* save name and keep Cleanup from freeing it */
3416 savepointLevel
= s
->savepointLevel
;
3418 CleanupSubTransaction();
3420 DefineSavepoint(NULL
);
3421 s
= CurrentTransactionState
; /* changed by push */
3423 s
->savepointLevel
= savepointLevel
;
3425 /* This is the same as TBLOCK_SUBBEGIN case */
3426 Assert(s
->blockState
== TBLOCK_SUBBEGIN
);
3427 StartSubTransaction();
3428 s
->blockState
= TBLOCK_SUBINPROGRESS
;
3433 /* Done, no more iterations required */
3438 * AbortCurrentTransaction -- a wrapper function handling the
3439 * loop over subtransactions to avoid potentially dangerous recursion in
3440 * AbortCurrentTransactionInternal().
3443 AbortCurrentTransaction(void)
3446 * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3449 while (!AbortCurrentTransactionInternal())
3455 * AbortCurrentTransactionInternal - a function doing an iteration of work
3456 * regarding handling the current transaction abort. In the case of
3457 * subtransactions more than one iterations could be required. Returns
3458 * true when no more iterations required, false otherwise.
3461 AbortCurrentTransactionInternal(void)
3463 TransactionState s
= CurrentTransactionState
;
3465 switch (s
->blockState
)
3467 case TBLOCK_DEFAULT
:
3468 if (s
->state
== TRANS_DEFAULT
)
3470 /* we are idle, so nothing to do */
3475 * We can get here after an error during transaction start
3476 * (state will be TRANS_START). Need to clean up the
3477 * incompletely started transaction. First, adjust the
3478 * low-level state to suppress warning message from
3481 if (s
->state
== TRANS_START
)
3482 s
->state
= TRANS_INPROGRESS
;
3484 CleanupTransaction();
3489 * If we aren't in a transaction block, we just do the basic abort
3490 * & cleanup transaction. For this purpose, we treat an implicit
3491 * transaction block as if it were a simple statement.
3493 case TBLOCK_STARTED
:
3494 case TBLOCK_IMPLICIT_INPROGRESS
:
3496 CleanupTransaction();
3497 s
->blockState
= TBLOCK_DEFAULT
;
3501 * If we are in TBLOCK_BEGIN it means something screwed up right
3502 * after reading "BEGIN TRANSACTION". We assume that the user
3503 * will interpret the error as meaning the BEGIN failed to get him
3504 * into a transaction block, so we should abort and return to idle
3509 CleanupTransaction();
3510 s
->blockState
= TBLOCK_DEFAULT
;
3514 * We are somewhere in a transaction block and we've gotten a
3515 * failure, so we abort the transaction and set up the persistent
3516 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3518 case TBLOCK_INPROGRESS
:
3519 case TBLOCK_PARALLEL_INPROGRESS
:
3521 s
->blockState
= TBLOCK_ABORT
;
3522 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3526 * Here, we failed while trying to COMMIT. Clean up the
3527 * transaction and return to idle state (we do not want to stay in
3532 CleanupTransaction();
3533 s
->blockState
= TBLOCK_DEFAULT
;
3537 * Here, we are already in an aborted transaction state and are
3538 * waiting for a ROLLBACK, but for some reason we failed again! So
3539 * we just remain in the abort state.
3542 case TBLOCK_SUBABORT
:
3546 * We are in a failed transaction and we got the ROLLBACK command.
3547 * We have already aborted, we just need to cleanup and go to idle
3550 case TBLOCK_ABORT_END
:
3551 CleanupTransaction();
3552 s
->blockState
= TBLOCK_DEFAULT
;
3556 * We are in a live transaction and we got a ROLLBACK command.
3557 * Abort, cleanup, go to idle state.
3559 case TBLOCK_ABORT_PENDING
:
3561 CleanupTransaction();
3562 s
->blockState
= TBLOCK_DEFAULT
;
3566 * Here, we failed while trying to PREPARE. Clean up the
3567 * transaction and return to idle state (we do not want to stay in
3570 case TBLOCK_PREPARE
:
3572 CleanupTransaction();
3573 s
->blockState
= TBLOCK_DEFAULT
;
3577 * We got an error inside a subtransaction. Abort just the
3578 * subtransaction, and go to the persistent SUBABORT state until
3581 case TBLOCK_SUBINPROGRESS
:
3582 AbortSubTransaction();
3583 s
->blockState
= TBLOCK_SUBABORT
;
3587 * If we failed while trying to create a subtransaction, clean up
3588 * the broken subtransaction and abort the parent. The same
3589 * applies if we get a failure while ending a subtransaction. As
3590 * we need to abort the parent, return false to request the caller
3591 * to do the next iteration.
3593 case TBLOCK_SUBBEGIN
:
3594 case TBLOCK_SUBRELEASE
:
3595 case TBLOCK_SUBCOMMIT
:
3596 case TBLOCK_SUBABORT_PENDING
:
3597 case TBLOCK_SUBRESTART
:
3598 AbortSubTransaction();
3599 CleanupSubTransaction();
3603 * Same as above, except the Abort() was already done.
3605 case TBLOCK_SUBABORT_END
:
3606 case TBLOCK_SUBABORT_RESTART
:
3607 CleanupSubTransaction();
3611 /* Done, no more iterations required */
3616 * PreventInTransactionBlock
3618 * This routine is to be called by statements that must not run inside
3619 * a transaction block, typically because they have non-rollback-able
3620 * side effects or do internal commits.
3622 * If this routine completes successfully, then the calling statement is
3623 * guaranteed that if it completes without error, its results will be
3624 * committed immediately.
3626 * If we have already started a transaction block, issue an error; also issue
3627 * an error if we appear to be running inside a user-defined function (which
3628 * could issue more commands and possibly cause a failure after the statement
3629 * completes). Subtransactions are verboten too.
3631 * We must also set XACT_FLAGS_NEEDIMMEDIATECOMMIT in MyXactFlags, to ensure
3632 * that postgres.c follows through by committing after the statement is done.
3634 * isTopLevel: passed down from ProcessUtility to determine whether we are
3635 * inside a function. (We will always fail if this is false, but it's
3636 * convenient to centralize the check here instead of making callers do it.)
3637 * stmtType: statement type name, for error messages.
3640 PreventInTransactionBlock(bool isTopLevel
, const char *stmtType
)
3643 * xact block already started?
3645 if (IsTransactionBlock())
3647 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION
),
3648 /* translator: %s represents an SQL statement name */
3649 errmsg("%s cannot run inside a transaction block",
3655 if (IsSubTransaction())
3657 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION
),
3658 /* translator: %s represents an SQL statement name */
3659 errmsg("%s cannot run inside a subtransaction",
3663 * inside a function call?
3667 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION
),
3668 /* translator: %s represents an SQL statement name */
3669 errmsg("%s cannot be executed from a function", stmtType
)));
3671 /* If we got past IsTransactionBlock test, should be in default state */
3672 if (CurrentTransactionState
->blockState
!= TBLOCK_DEFAULT
&&
3673 CurrentTransactionState
->blockState
!= TBLOCK_STARTED
)
3674 elog(FATAL
, "cannot prevent transaction chain");
3676 /* All okay. Set the flag to make sure the right thing happens later. */
3677 MyXactFlags
|= XACT_FLAGS_NEEDIMMEDIATECOMMIT
;
3681 * WarnNoTransactionBlock
3682 * RequireTransactionBlock
3684 * These two functions allow for warnings or errors if a command is executed
3685 * outside of a transaction block. This is useful for commands that have no
3686 * effects that persist past transaction end (and so calling them outside a
3687 * transaction block is presumably an error). DECLARE CURSOR is an example.
3688 * While top-level transaction control commands (BEGIN/COMMIT/ABORT) and SET
3689 * that have no effect issue warnings, all other no-effect commands generate
3692 * If we appear to be running inside a user-defined function, we do not
3693 * issue anything, since the function could issue more commands that make
3694 * use of the current statement's results. Likewise subtransactions.
3695 * Thus these are inverses for PreventInTransactionBlock.
3697 * isTopLevel: passed down from ProcessUtility to determine whether we are
3698 * inside a function.
3699 * stmtType: statement type name, for warning or error messages.
3702 WarnNoTransactionBlock(bool isTopLevel
, const char *stmtType
)
3704 CheckTransactionBlock(isTopLevel
, false, stmtType
);
3708 RequireTransactionBlock(bool isTopLevel
, const char *stmtType
)
3710 CheckTransactionBlock(isTopLevel
, true, stmtType
);
3714 * This is the implementation of the above two.
3717 CheckTransactionBlock(bool isTopLevel
, bool throwError
, const char *stmtType
)
3720 * xact block already started?
3722 if (IsTransactionBlock())
3728 if (IsSubTransaction())
3732 * inside a function call?
3737 ereport(throwError
? ERROR
: WARNING
,
3738 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION
),
3739 /* translator: %s represents an SQL statement name */
3740 errmsg("%s can only be used in transaction blocks",
3745 * IsInTransactionBlock
3747 * This routine is for statements that need to behave differently inside
3748 * a transaction block than when running as single commands. ANALYZE is
3749 * currently the only example.
3751 * If this routine returns "false", then the calling statement is allowed
3752 * to perform internal transaction-commit-and-start cycles; there is not a
3753 * risk of messing up any transaction already in progress. (Note that this
3754 * is not the identical guarantee provided by PreventInTransactionBlock,
3755 * since we will not force a post-statement commit.)
3757 * isTopLevel: passed down from ProcessUtility to determine whether we are
3758 * inside a function.
3761 IsInTransactionBlock(bool isTopLevel
)
3764 * Return true on same conditions that would make
3765 * PreventInTransactionBlock error out
3767 if (IsTransactionBlock())
3770 if (IsSubTransaction())
3776 if (CurrentTransactionState
->blockState
!= TBLOCK_DEFAULT
&&
3777 CurrentTransactionState
->blockState
!= TBLOCK_STARTED
)
3785 * Register or deregister callback functions for start- and end-of-xact
3788 * These functions are intended for use by dynamically loaded modules.
3789 * For built-in modules we generally just hardwire the appropriate calls
3790 * (mainly because it's easier to control the order that way, where needed).
3792 * At transaction end, the callback occurs post-commit or post-abort, so the
3793 * callback functions can only do noncritical cleanup.
3796 RegisterXactCallback(XactCallback callback
, void *arg
)
3798 XactCallbackItem
*item
;
3800 item
= (XactCallbackItem
*)
3801 MemoryContextAlloc(TopMemoryContext
, sizeof(XactCallbackItem
));
3802 item
->callback
= callback
;
3804 item
->next
= Xact_callbacks
;
3805 Xact_callbacks
= item
;
3809 UnregisterXactCallback(XactCallback callback
, void *arg
)
3811 XactCallbackItem
*item
;
3812 XactCallbackItem
*prev
;
3815 for (item
= Xact_callbacks
; item
; prev
= item
, item
= item
->next
)
3817 if (item
->callback
== callback
&& item
->arg
== arg
)
3820 prev
->next
= item
->next
;
3822 Xact_callbacks
= item
->next
;
3830 CallXactCallbacks(XactEvent event
)
3832 XactCallbackItem
*item
;
3833 XactCallbackItem
*next
;
3835 for (item
= Xact_callbacks
; item
; item
= next
)
3837 /* allow callbacks to unregister themselves when called */
3839 item
->callback(event
, item
->arg
);
3845 * Register or deregister callback functions for start- and end-of-subxact
3848 * Pretty much same as above, but for subtransaction events.
3850 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3851 * so the callback functions can only do noncritical cleanup. At
3852 * subtransaction start, the callback is called when the subtransaction has
3853 * finished initializing.
3856 RegisterSubXactCallback(SubXactCallback callback
, void *arg
)
3858 SubXactCallbackItem
*item
;
3860 item
= (SubXactCallbackItem
*)
3861 MemoryContextAlloc(TopMemoryContext
, sizeof(SubXactCallbackItem
));
3862 item
->callback
= callback
;
3864 item
->next
= SubXact_callbacks
;
3865 SubXact_callbacks
= item
;
3869 UnregisterSubXactCallback(SubXactCallback callback
, void *arg
)
3871 SubXactCallbackItem
*item
;
3872 SubXactCallbackItem
*prev
;
3875 for (item
= SubXact_callbacks
; item
; prev
= item
, item
= item
->next
)
3877 if (item
->callback
== callback
&& item
->arg
== arg
)
3880 prev
->next
= item
->next
;
3882 SubXact_callbacks
= item
->next
;
3890 CallSubXactCallbacks(SubXactEvent event
,
3891 SubTransactionId mySubid
,
3892 SubTransactionId parentSubid
)
3894 SubXactCallbackItem
*item
;
3895 SubXactCallbackItem
*next
;
3897 for (item
= SubXact_callbacks
; item
; item
= next
)
3899 /* allow callbacks to unregister themselves when called */
3901 item
->callback(event
, mySubid
, parentSubid
, item
->arg
);
3906 /* ----------------------------------------------------------------
3907 * transaction block support
3908 * ----------------------------------------------------------------
3912 * BeginTransactionBlock
3913 * This executes a BEGIN command.
3916 BeginTransactionBlock(void)
3918 TransactionState s
= CurrentTransactionState
;
3920 switch (s
->blockState
)
3923 * We are not inside a transaction block, so allow one to begin.
3925 case TBLOCK_STARTED
:
3926 s
->blockState
= TBLOCK_BEGIN
;
3930 * BEGIN converts an implicit transaction block to a regular one.
3931 * (Note that we allow this even if we've already done some
3932 * commands, which is a bit odd but matches historical practice.)
3934 case TBLOCK_IMPLICIT_INPROGRESS
:
3935 s
->blockState
= TBLOCK_BEGIN
;
3939 * Already a transaction block in progress.
3941 case TBLOCK_INPROGRESS
:
3942 case TBLOCK_PARALLEL_INPROGRESS
:
3943 case TBLOCK_SUBINPROGRESS
:
3945 case TBLOCK_SUBABORT
:
3947 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION
),
3948 errmsg("there is already a transaction in progress")));
3951 /* These cases are invalid. */
3952 case TBLOCK_DEFAULT
:
3954 case TBLOCK_SUBBEGIN
:
3956 case TBLOCK_SUBRELEASE
:
3957 case TBLOCK_SUBCOMMIT
:
3958 case TBLOCK_ABORT_END
:
3959 case TBLOCK_SUBABORT_END
:
3960 case TBLOCK_ABORT_PENDING
:
3961 case TBLOCK_SUBABORT_PENDING
:
3962 case TBLOCK_SUBRESTART
:
3963 case TBLOCK_SUBABORT_RESTART
:
3964 case TBLOCK_PREPARE
:
3965 elog(FATAL
, "BeginTransactionBlock: unexpected state %s",
3966 BlockStateAsString(s
->blockState
));
3972 * PrepareTransactionBlock
3973 * This executes a PREPARE command.
3975 * Since PREPARE may actually do a ROLLBACK, the result indicates what
3976 * happened: true for PREPARE, false for ROLLBACK.
3978 * Note that we don't actually do anything here except change blockState.
3979 * The real work will be done in the upcoming PrepareTransaction().
3980 * We do it this way because it's not convenient to change memory context,
3981 * resource owner, etc while executing inside a Portal.
3984 PrepareTransactionBlock(const char *gid
)
3989 /* Set up to commit the current transaction */
3990 result
= EndTransactionBlock(false);
3992 /* If successful, change outer tblock state to PREPARE */
3995 s
= CurrentTransactionState
;
3997 while (s
->parent
!= NULL
)
4000 if (s
->blockState
== TBLOCK_END
)
4002 /* Save GID where PrepareTransaction can find it again */
4003 prepareGID
= MemoryContextStrdup(TopTransactionContext
, gid
);
4005 s
->blockState
= TBLOCK_PREPARE
;
4010 * ignore case where we are not in a transaction;
4011 * EndTransactionBlock already issued a warning.
4013 Assert(s
->blockState
== TBLOCK_STARTED
||
4014 s
->blockState
== TBLOCK_IMPLICIT_INPROGRESS
);
4015 /* Don't send back a PREPARE result tag... */
4024 * EndTransactionBlock
4025 * This executes a COMMIT command.
4027 * Since COMMIT may actually do a ROLLBACK, the result indicates what
4028 * happened: true for COMMIT, false for ROLLBACK.
4030 * Note that we don't actually do anything here except change blockState.
4031 * The real work will be done in the upcoming CommitTransactionCommand().
4032 * We do it this way because it's not convenient to change memory context,
4033 * resource owner, etc while executing inside a Portal.
4036 EndTransactionBlock(bool chain
)
4038 TransactionState s
= CurrentTransactionState
;
4039 bool result
= false;
4041 switch (s
->blockState
)
4044 * We are in a transaction block, so tell CommitTransactionCommand
4047 case TBLOCK_INPROGRESS
:
4048 s
->blockState
= TBLOCK_END
;
4053 * We are in an implicit transaction block. If AND CHAIN was
4054 * specified, error. Otherwise commit, but issue a warning
4055 * because there was no explicit BEGIN before this.
4057 case TBLOCK_IMPLICIT_INPROGRESS
:
4060 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION
),
4061 /* translator: %s represents an SQL statement name */
4062 errmsg("%s can only be used in transaction blocks",
4063 "COMMIT AND CHAIN")));
4066 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION
),
4067 errmsg("there is no transaction in progress")));
4068 s
->blockState
= TBLOCK_END
;
4073 * We are in a failed transaction block. Tell
4074 * CommitTransactionCommand it's time to exit the block.
4077 s
->blockState
= TBLOCK_ABORT_END
;
4081 * We are in a live subtransaction block. Set up to subcommit all
4082 * open subtransactions and then commit the main transaction.
4084 case TBLOCK_SUBINPROGRESS
:
4085 while (s
->parent
!= NULL
)
4087 if (s
->blockState
== TBLOCK_SUBINPROGRESS
)
4088 s
->blockState
= TBLOCK_SUBCOMMIT
;
4090 elog(FATAL
, "EndTransactionBlock: unexpected state %s",
4091 BlockStateAsString(s
->blockState
));
4094 if (s
->blockState
== TBLOCK_INPROGRESS
)
4095 s
->blockState
= TBLOCK_END
;
4097 elog(FATAL
, "EndTransactionBlock: unexpected state %s",
4098 BlockStateAsString(s
->blockState
));
4103 * Here we are inside an aborted subtransaction. Treat the COMMIT
4104 * as ROLLBACK: set up to abort everything and exit the main
4107 case TBLOCK_SUBABORT
:
4108 while (s
->parent
!= NULL
)
4110 if (s
->blockState
== TBLOCK_SUBINPROGRESS
)
4111 s
->blockState
= TBLOCK_SUBABORT_PENDING
;
4112 else if (s
->blockState
== TBLOCK_SUBABORT
)
4113 s
->blockState
= TBLOCK_SUBABORT_END
;
4115 elog(FATAL
, "EndTransactionBlock: unexpected state %s",
4116 BlockStateAsString(s
->blockState
));
4119 if (s
->blockState
== TBLOCK_INPROGRESS
)
4120 s
->blockState
= TBLOCK_ABORT_PENDING
;
4121 else if (s
->blockState
== TBLOCK_ABORT
)
4122 s
->blockState
= TBLOCK_ABORT_END
;
4124 elog(FATAL
, "EndTransactionBlock: unexpected state %s",
4125 BlockStateAsString(s
->blockState
));
4129 * The user issued COMMIT when not inside a transaction. For
4130 * COMMIT without CHAIN, issue a WARNING, staying in
4131 * TBLOCK_STARTED state. The upcoming call to
4132 * CommitTransactionCommand() will then close the transaction and
4133 * put us back into the default state. For COMMIT AND CHAIN,
4136 case TBLOCK_STARTED
:
4139 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION
),
4140 /* translator: %s represents an SQL statement name */
4141 errmsg("%s can only be used in transaction blocks",
4142 "COMMIT AND CHAIN")));
4145 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION
),
4146 errmsg("there is no transaction in progress")));
4151 * The user issued a COMMIT that somehow ran inside a parallel
4152 * worker. We can't cope with that.
4154 case TBLOCK_PARALLEL_INPROGRESS
:
4156 (errcode(ERRCODE_INVALID_TRANSACTION_STATE
),
4157 errmsg("cannot commit during a parallel operation")));
4160 /* These cases are invalid. */
4161 case TBLOCK_DEFAULT
:
4163 case TBLOCK_SUBBEGIN
:
4165 case TBLOCK_SUBRELEASE
:
4166 case TBLOCK_SUBCOMMIT
:
4167 case TBLOCK_ABORT_END
:
4168 case TBLOCK_SUBABORT_END
:
4169 case TBLOCK_ABORT_PENDING
:
4170 case TBLOCK_SUBABORT_PENDING
:
4171 case TBLOCK_SUBRESTART
:
4172 case TBLOCK_SUBABORT_RESTART
:
4173 case TBLOCK_PREPARE
:
4174 elog(FATAL
, "EndTransactionBlock: unexpected state %s",
4175 BlockStateAsString(s
->blockState
));
4179 Assert(s
->blockState
== TBLOCK_STARTED
||
4180 s
->blockState
== TBLOCK_END
||
4181 s
->blockState
== TBLOCK_ABORT_END
||
4182 s
->blockState
== TBLOCK_ABORT_PENDING
);
4190 * UserAbortTransactionBlock
4191 * This executes a ROLLBACK command.
4193 * As above, we don't actually do anything here except change blockState.
4196 UserAbortTransactionBlock(bool chain
)
4198 TransactionState s
= CurrentTransactionState
;
4200 switch (s
->blockState
)
4203 * We are inside a transaction block and we got a ROLLBACK command
4204 * from the user, so tell CommitTransactionCommand to abort and
4205 * exit the transaction block.
4207 case TBLOCK_INPROGRESS
:
4208 s
->blockState
= TBLOCK_ABORT_PENDING
;
4212 * We are inside a failed transaction block and we got a ROLLBACK
4213 * command from the user. Abort processing is already done, so
4214 * CommitTransactionCommand just has to cleanup and go back to
4218 s
->blockState
= TBLOCK_ABORT_END
;
4222 * We are inside a subtransaction. Mark everything up to top
4223 * level as exitable.
4225 case TBLOCK_SUBINPROGRESS
:
4226 case TBLOCK_SUBABORT
:
4227 while (s
->parent
!= NULL
)
4229 if (s
->blockState
== TBLOCK_SUBINPROGRESS
)
4230 s
->blockState
= TBLOCK_SUBABORT_PENDING
;
4231 else if (s
->blockState
== TBLOCK_SUBABORT
)
4232 s
->blockState
= TBLOCK_SUBABORT_END
;
4234 elog(FATAL
, "UserAbortTransactionBlock: unexpected state %s",
4235 BlockStateAsString(s
->blockState
));
4238 if (s
->blockState
== TBLOCK_INPROGRESS
)
4239 s
->blockState
= TBLOCK_ABORT_PENDING
;
4240 else if (s
->blockState
== TBLOCK_ABORT
)
4241 s
->blockState
= TBLOCK_ABORT_END
;
4243 elog(FATAL
, "UserAbortTransactionBlock: unexpected state %s",
4244 BlockStateAsString(s
->blockState
));
4248 * The user issued ABORT when not inside a transaction. For
4249 * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4250 * The upcoming call to CommitTransactionCommand() will then put
4251 * us back into the default state. For ROLLBACK AND CHAIN, error.
4253 * We do the same thing with ABORT inside an implicit transaction,
4254 * although in this case we might be rolling back actual database
4255 * state changes. (It's debatable whether we should issue a
4256 * WARNING in this case, but we have done so historically.)
4258 case TBLOCK_STARTED
:
4259 case TBLOCK_IMPLICIT_INPROGRESS
:
4262 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION
),
4263 /* translator: %s represents an SQL statement name */
4264 errmsg("%s can only be used in transaction blocks",
4265 "ROLLBACK AND CHAIN")));
4268 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION
),
4269 errmsg("there is no transaction in progress")));
4270 s
->blockState
= TBLOCK_ABORT_PENDING
;
4274 * The user issued an ABORT that somehow ran inside a parallel
4275 * worker. We can't cope with that.
4277 case TBLOCK_PARALLEL_INPROGRESS
:
4279 (errcode(ERRCODE_INVALID_TRANSACTION_STATE
),
4280 errmsg("cannot abort during a parallel operation")));
4283 /* These cases are invalid. */
4284 case TBLOCK_DEFAULT
:
4286 case TBLOCK_SUBBEGIN
:
4288 case TBLOCK_SUBRELEASE
:
4289 case TBLOCK_SUBCOMMIT
:
4290 case TBLOCK_ABORT_END
:
4291 case TBLOCK_SUBABORT_END
:
4292 case TBLOCK_ABORT_PENDING
:
4293 case TBLOCK_SUBABORT_PENDING
:
4294 case TBLOCK_SUBRESTART
:
4295 case TBLOCK_SUBABORT_RESTART
:
4296 case TBLOCK_PREPARE
:
4297 elog(FATAL
, "UserAbortTransactionBlock: unexpected state %s",
4298 BlockStateAsString(s
->blockState
));
4302 Assert(s
->blockState
== TBLOCK_ABORT_END
||
4303 s
->blockState
== TBLOCK_ABORT_PENDING
);
4309 * BeginImplicitTransactionBlock
4310 * Start an implicit transaction block if we're not already in one.
4312 * Unlike BeginTransactionBlock, this is called directly from the main loop
4313 * in postgres.c, not within a Portal. So we can just change blockState
4314 * without a lot of ceremony. We do not expect caller to do
4315 * CommitTransactionCommand/StartTransactionCommand.
4318 BeginImplicitTransactionBlock(void)
4320 TransactionState s
= CurrentTransactionState
;
4323 * If we are in STARTED state (that is, no transaction block is open),
4324 * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4327 * For caller convenience, we consider all other transaction states as
4328 * legal here; otherwise the caller would need its own state check, which
4329 * seems rather pointless.
4331 if (s
->blockState
== TBLOCK_STARTED
)
4332 s
->blockState
= TBLOCK_IMPLICIT_INPROGRESS
;
4336 * EndImplicitTransactionBlock
4337 * End an implicit transaction block, if we're in one.
4339 * Like EndTransactionBlock, we just make any needed blockState change here.
4340 * The real work will be done in the upcoming CommitTransactionCommand().
4343 EndImplicitTransactionBlock(void)
4345 TransactionState s
= CurrentTransactionState
;
4348 * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4349 * allowing CommitTransactionCommand to commit whatever happened during
4350 * the implicit transaction block as though it were a single statement.
4352 * For caller convenience, we consider all other transaction states as
4353 * legal here; otherwise the caller would need its own state check, which
4354 * seems rather pointless.
4356 if (s
->blockState
== TBLOCK_IMPLICIT_INPROGRESS
)
4357 s
->blockState
= TBLOCK_STARTED
;
4362 * This executes a SAVEPOINT command.
4365 DefineSavepoint(const char *name
)
4367 TransactionState s
= CurrentTransactionState
;
4370 * Workers synchronize transaction state at the beginning of each parallel
4371 * operation, so we can't account for new subtransactions after that
4372 * point. (Note that this check will certainly error out if s->blockState
4373 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4376 if (IsInParallelMode() || IsParallelWorker())
4378 (errcode(ERRCODE_INVALID_TRANSACTION_STATE
),
4379 errmsg("cannot define savepoints during a parallel operation")));
4381 switch (s
->blockState
)
4383 case TBLOCK_INPROGRESS
:
4384 case TBLOCK_SUBINPROGRESS
:
4385 /* Normal subtransaction start */
4387 s
= CurrentTransactionState
; /* changed by push */
4390 * Savepoint names, like the TransactionState block itself, live
4391 * in TopTransactionContext.
4394 s
->name
= MemoryContextStrdup(TopTransactionContext
, name
);
4398 * We disallow savepoint commands in implicit transaction blocks.
4399 * There would be no great difficulty in allowing them so far as
4400 * this module is concerned, but a savepoint seems inconsistent
4401 * with exec_simple_query's behavior of abandoning the whole query
4402 * string upon error. Also, the point of an implicit transaction
4403 * block (as opposed to a regular one) is to automatically close
4404 * after an error, so it's hard to see how a savepoint would fit
4407 * The error messages for this are phrased as if there were no
4408 * active transaction block at all, which is historical but
4409 * perhaps could be improved.
4411 case TBLOCK_IMPLICIT_INPROGRESS
:
4413 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION
),
4414 /* translator: %s represents an SQL statement name */
4415 errmsg("%s can only be used in transaction blocks",
4419 /* These cases are invalid. */
4420 case TBLOCK_DEFAULT
:
4421 case TBLOCK_STARTED
:
4423 case TBLOCK_PARALLEL_INPROGRESS
:
4424 case TBLOCK_SUBBEGIN
:
4426 case TBLOCK_SUBRELEASE
:
4427 case TBLOCK_SUBCOMMIT
:
4429 case TBLOCK_SUBABORT
:
4430 case TBLOCK_ABORT_END
:
4431 case TBLOCK_SUBABORT_END
:
4432 case TBLOCK_ABORT_PENDING
:
4433 case TBLOCK_SUBABORT_PENDING
:
4434 case TBLOCK_SUBRESTART
:
4435 case TBLOCK_SUBABORT_RESTART
:
4436 case TBLOCK_PREPARE
:
4437 elog(FATAL
, "DefineSavepoint: unexpected state %s",
4438 BlockStateAsString(s
->blockState
));
4445 * This executes a RELEASE command.
4447 * As above, we don't actually do anything here except change blockState.
4450 ReleaseSavepoint(const char *name
)
4452 TransactionState s
= CurrentTransactionState
;
4453 TransactionState target
,
4457 * Workers synchronize transaction state at the beginning of each parallel
4458 * operation, so we can't account for transaction state change after that
4459 * point. (Note that this check will certainly error out if s->blockState
4460 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4463 if (IsInParallelMode() || IsParallelWorker())
4465 (errcode(ERRCODE_INVALID_TRANSACTION_STATE
),
4466 errmsg("cannot release savepoints during a parallel operation")));
4468 switch (s
->blockState
)
4471 * We can't release a savepoint if there is no savepoint defined.
4473 case TBLOCK_INPROGRESS
:
4475 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION
),
4476 errmsg("savepoint \"%s\" does not exist", name
)));
4479 case TBLOCK_IMPLICIT_INPROGRESS
:
4480 /* See comment about implicit transactions in DefineSavepoint */
4482 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION
),
4483 /* translator: %s represents an SQL statement name */
4484 errmsg("%s can only be used in transaction blocks",
4485 "RELEASE SAVEPOINT")));
4489 * We are in a non-aborted subtransaction. This is the only valid
4492 case TBLOCK_SUBINPROGRESS
:
4495 /* These cases are invalid. */
4496 case TBLOCK_DEFAULT
:
4497 case TBLOCK_STARTED
:
4499 case TBLOCK_PARALLEL_INPROGRESS
:
4500 case TBLOCK_SUBBEGIN
:
4502 case TBLOCK_SUBRELEASE
:
4503 case TBLOCK_SUBCOMMIT
:
4505 case TBLOCK_SUBABORT
:
4506 case TBLOCK_ABORT_END
:
4507 case TBLOCK_SUBABORT_END
:
4508 case TBLOCK_ABORT_PENDING
:
4509 case TBLOCK_SUBABORT_PENDING
:
4510 case TBLOCK_SUBRESTART
:
4511 case TBLOCK_SUBABORT_RESTART
:
4512 case TBLOCK_PREPARE
:
4513 elog(FATAL
, "ReleaseSavepoint: unexpected state %s",
4514 BlockStateAsString(s
->blockState
));
4518 for (target
= s
; PointerIsValid(target
); target
= target
->parent
)
4520 if (PointerIsValid(target
->name
) && strcmp(target
->name
, name
) == 0)
4524 if (!PointerIsValid(target
))
4526 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION
),
4527 errmsg("savepoint \"%s\" does not exist", name
)));
4529 /* disallow crossing savepoint level boundaries */
4530 if (target
->savepointLevel
!= s
->savepointLevel
)
4532 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION
),
4533 errmsg("savepoint \"%s\" does not exist within current savepoint level", name
)));
4536 * Mark "commit pending" all subtransactions up to the target
4537 * subtransaction. The actual commits will happen when control gets to
4538 * CommitTransactionCommand.
4540 xact
= CurrentTransactionState
;
4543 Assert(xact
->blockState
== TBLOCK_SUBINPROGRESS
);
4544 xact
->blockState
= TBLOCK_SUBRELEASE
;
4547 xact
= xact
->parent
;
4548 Assert(PointerIsValid(xact
));
4553 * RollbackToSavepoint
4554 * This executes a ROLLBACK TO <savepoint> command.
4556 * As above, we don't actually do anything here except change blockState.
4559 RollbackToSavepoint(const char *name
)
4561 TransactionState s
= CurrentTransactionState
;
4562 TransactionState target
,
4566 * Workers synchronize transaction state at the beginning of each parallel
4567 * operation, so we can't account for transaction state change after that
4568 * point. (Note that this check will certainly error out if s->blockState
4569 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4572 if (IsInParallelMode() || IsParallelWorker())
4574 (errcode(ERRCODE_INVALID_TRANSACTION_STATE
),
4575 errmsg("cannot rollback to savepoints during a parallel operation")));
4577 switch (s
->blockState
)
4580 * We can't rollback to a savepoint if there is no savepoint
4583 case TBLOCK_INPROGRESS
:
4586 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION
),
4587 errmsg("savepoint \"%s\" does not exist", name
)));
4590 case TBLOCK_IMPLICIT_INPROGRESS
:
4591 /* See comment about implicit transactions in DefineSavepoint */
4593 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION
),
4594 /* translator: %s represents an SQL statement name */
4595 errmsg("%s can only be used in transaction blocks",
4596 "ROLLBACK TO SAVEPOINT")));
4600 * There is at least one savepoint, so proceed.
4602 case TBLOCK_SUBINPROGRESS
:
4603 case TBLOCK_SUBABORT
:
4606 /* These cases are invalid. */
4607 case TBLOCK_DEFAULT
:
4608 case TBLOCK_STARTED
:
4610 case TBLOCK_PARALLEL_INPROGRESS
:
4611 case TBLOCK_SUBBEGIN
:
4613 case TBLOCK_SUBRELEASE
:
4614 case TBLOCK_SUBCOMMIT
:
4615 case TBLOCK_ABORT_END
:
4616 case TBLOCK_SUBABORT_END
:
4617 case TBLOCK_ABORT_PENDING
:
4618 case TBLOCK_SUBABORT_PENDING
:
4619 case TBLOCK_SUBRESTART
:
4620 case TBLOCK_SUBABORT_RESTART
:
4621 case TBLOCK_PREPARE
:
4622 elog(FATAL
, "RollbackToSavepoint: unexpected state %s",
4623 BlockStateAsString(s
->blockState
));
4627 for (target
= s
; PointerIsValid(target
); target
= target
->parent
)
4629 if (PointerIsValid(target
->name
) && strcmp(target
->name
, name
) == 0)
4633 if (!PointerIsValid(target
))
4635 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION
),
4636 errmsg("savepoint \"%s\" does not exist", name
)));
4638 /* disallow crossing savepoint level boundaries */
4639 if (target
->savepointLevel
!= s
->savepointLevel
)
4641 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION
),
4642 errmsg("savepoint \"%s\" does not exist within current savepoint level", name
)));
4645 * Mark "abort pending" all subtransactions up to the target
4646 * subtransaction. The actual aborts will happen when control gets to
4647 * CommitTransactionCommand.
4649 xact
= CurrentTransactionState
;
4654 if (xact
->blockState
== TBLOCK_SUBINPROGRESS
)
4655 xact
->blockState
= TBLOCK_SUBABORT_PENDING
;
4656 else if (xact
->blockState
== TBLOCK_SUBABORT
)
4657 xact
->blockState
= TBLOCK_SUBABORT_END
;
4659 elog(FATAL
, "RollbackToSavepoint: unexpected state %s",
4660 BlockStateAsString(xact
->blockState
));
4661 xact
= xact
->parent
;
4662 Assert(PointerIsValid(xact
));
4665 /* And mark the target as "restart pending" */
4666 if (xact
->blockState
== TBLOCK_SUBINPROGRESS
)
4667 xact
->blockState
= TBLOCK_SUBRESTART
;
4668 else if (xact
->blockState
== TBLOCK_SUBABORT
)
4669 xact
->blockState
= TBLOCK_SUBABORT_RESTART
;
4671 elog(FATAL
, "RollbackToSavepoint: unexpected state %s",
4672 BlockStateAsString(xact
->blockState
));
4676 * BeginInternalSubTransaction
4677 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
4678 * TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_END,
4679 * and TBLOCK_PREPARE states, and therefore it can safely be used in
4680 * functions that might be called when not inside a BEGIN block or when
4681 * running deferred triggers at COMMIT/PREPARE time. Also, it
4682 * automatically does CommitTransactionCommand/StartTransactionCommand
4683 * instead of expecting the caller to do it.
4686 BeginInternalSubTransaction(const char *name
)
4688 TransactionState s
= CurrentTransactionState
;
4689 bool save_ExitOnAnyError
= ExitOnAnyError
;
4692 * Errors within this function are improbable, but if one does happen we
4693 * force a FATAL exit. Callers generally aren't prepared to handle losing
4694 * control, and moreover our transaction state is probably corrupted if we
4695 * fail partway through; so an ordinary ERROR longjmp isn't okay.
4697 ExitOnAnyError
= true;
4700 * We do not check for parallel mode here. It's permissible to start and
4701 * end "internal" subtransactions while in parallel mode, so long as no
4702 * new XIDs or command IDs are assigned. Enforcement of that occurs in
4703 * AssignTransactionId() and CommandCounterIncrement().
4706 switch (s
->blockState
)
4708 case TBLOCK_STARTED
:
4709 case TBLOCK_INPROGRESS
:
4710 case TBLOCK_IMPLICIT_INPROGRESS
:
4711 case TBLOCK_PARALLEL_INPROGRESS
:
4713 case TBLOCK_PREPARE
:
4714 case TBLOCK_SUBINPROGRESS
:
4715 /* Normal subtransaction start */
4717 s
= CurrentTransactionState
; /* changed by push */
4720 * Savepoint names, like the TransactionState block itself, live
4721 * in TopTransactionContext.
4724 s
->name
= MemoryContextStrdup(TopTransactionContext
, name
);
4727 /* These cases are invalid. */
4728 case TBLOCK_DEFAULT
:
4730 case TBLOCK_SUBBEGIN
:
4731 case TBLOCK_SUBRELEASE
:
4732 case TBLOCK_SUBCOMMIT
:
4734 case TBLOCK_SUBABORT
:
4735 case TBLOCK_ABORT_END
:
4736 case TBLOCK_SUBABORT_END
:
4737 case TBLOCK_ABORT_PENDING
:
4738 case TBLOCK_SUBABORT_PENDING
:
4739 case TBLOCK_SUBRESTART
:
4740 case TBLOCK_SUBABORT_RESTART
:
4741 elog(FATAL
, "BeginInternalSubTransaction: unexpected state %s",
4742 BlockStateAsString(s
->blockState
));
4746 CommitTransactionCommand();
4747 StartTransactionCommand();
4749 ExitOnAnyError
= save_ExitOnAnyError
;
4753 * ReleaseCurrentSubTransaction
4755 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
4756 * savepoint name (if any).
4757 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4760 ReleaseCurrentSubTransaction(void)
4762 TransactionState s
= CurrentTransactionState
;
4765 * We do not check for parallel mode here. It's permissible to start and
4766 * end "internal" subtransactions while in parallel mode, so long as no
4767 * new XIDs or command IDs are assigned.
4770 if (s
->blockState
!= TBLOCK_SUBINPROGRESS
)
4771 elog(ERROR
, "ReleaseCurrentSubTransaction: unexpected state %s",
4772 BlockStateAsString(s
->blockState
));
4773 Assert(s
->state
== TRANS_INPROGRESS
);
4774 MemoryContextSwitchTo(CurTransactionContext
);
4775 CommitSubTransaction();
4776 s
= CurrentTransactionState
; /* changed by pop */
4777 Assert(s
->state
== TRANS_INPROGRESS
);
4781 * RollbackAndReleaseCurrentSubTransaction
4783 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
4784 * of its savepoint name (if any).
4785 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4788 RollbackAndReleaseCurrentSubTransaction(void)
4790 TransactionState s
= CurrentTransactionState
;
4793 * We do not check for parallel mode here. It's permissible to start and
4794 * end "internal" subtransactions while in parallel mode, so long as no
4795 * new XIDs or command IDs are assigned.
4798 switch (s
->blockState
)
4800 /* Must be in a subtransaction */
4801 case TBLOCK_SUBINPROGRESS
:
4802 case TBLOCK_SUBABORT
:
4805 /* These cases are invalid. */
4806 case TBLOCK_DEFAULT
:
4807 case TBLOCK_STARTED
:
4809 case TBLOCK_IMPLICIT_INPROGRESS
:
4810 case TBLOCK_PARALLEL_INPROGRESS
:
4811 case TBLOCK_SUBBEGIN
:
4812 case TBLOCK_INPROGRESS
:
4814 case TBLOCK_SUBRELEASE
:
4815 case TBLOCK_SUBCOMMIT
:
4817 case TBLOCK_ABORT_END
:
4818 case TBLOCK_SUBABORT_END
:
4819 case TBLOCK_ABORT_PENDING
:
4820 case TBLOCK_SUBABORT_PENDING
:
4821 case TBLOCK_SUBRESTART
:
4822 case TBLOCK_SUBABORT_RESTART
:
4823 case TBLOCK_PREPARE
:
4824 elog(FATAL
, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4825 BlockStateAsString(s
->blockState
));
4830 * Abort the current subtransaction, if needed.
4832 if (s
->blockState
== TBLOCK_SUBINPROGRESS
)
4833 AbortSubTransaction();
4835 /* And clean it up, too */
4836 CleanupSubTransaction();
4838 s
= CurrentTransactionState
; /* changed by pop */
4839 Assert(s
->blockState
== TBLOCK_SUBINPROGRESS
||
4840 s
->blockState
== TBLOCK_INPROGRESS
||
4841 s
->blockState
== TBLOCK_IMPLICIT_INPROGRESS
||
4842 s
->blockState
== TBLOCK_PARALLEL_INPROGRESS
||
4843 s
->blockState
== TBLOCK_STARTED
);
4847 * AbortOutOfAnyTransaction
4849 * This routine is provided for error recovery purposes. It aborts any
4850 * active transaction or transaction block, leaving the system in a known
4854 AbortOutOfAnyTransaction(void)
4856 TransactionState s
= CurrentTransactionState
;
4858 /* Ensure we're not running in a doomed memory context */
4862 * Get out of any transaction or nested transaction
4866 switch (s
->blockState
)
4868 case TBLOCK_DEFAULT
:
4869 if (s
->state
== TRANS_DEFAULT
)
4871 /* Not in a transaction, do nothing */
4876 * We can get here after an error during transaction start
4877 * (state will be TRANS_START). Need to clean up the
4878 * incompletely started transaction. First, adjust the
4879 * low-level state to suppress warning message from
4882 if (s
->state
== TRANS_START
)
4883 s
->state
= TRANS_INPROGRESS
;
4885 CleanupTransaction();
4888 case TBLOCK_STARTED
:
4890 case TBLOCK_INPROGRESS
:
4891 case TBLOCK_IMPLICIT_INPROGRESS
:
4892 case TBLOCK_PARALLEL_INPROGRESS
:
4894 case TBLOCK_ABORT_PENDING
:
4895 case TBLOCK_PREPARE
:
4896 /* In a transaction, so clean up */
4898 CleanupTransaction();
4899 s
->blockState
= TBLOCK_DEFAULT
;
4902 case TBLOCK_ABORT_END
:
4905 * AbortTransaction is already done, still need Cleanup.
4906 * However, if we failed partway through running ROLLBACK,
4907 * there will be an active portal running that command, which
4908 * we need to shut down before doing CleanupTransaction.
4911 CleanupTransaction();
4912 s
->blockState
= TBLOCK_DEFAULT
;
4916 * In a subtransaction, so clean it up and abort parent too
4918 case TBLOCK_SUBBEGIN
:
4919 case TBLOCK_SUBINPROGRESS
:
4920 case TBLOCK_SUBRELEASE
:
4921 case TBLOCK_SUBCOMMIT
:
4922 case TBLOCK_SUBABORT_PENDING
:
4923 case TBLOCK_SUBRESTART
:
4924 AbortSubTransaction();
4925 CleanupSubTransaction();
4926 s
= CurrentTransactionState
; /* changed by pop */
4929 case TBLOCK_SUBABORT
:
4930 case TBLOCK_SUBABORT_END
:
4931 case TBLOCK_SUBABORT_RESTART
:
4932 /* As above, but AbortSubTransaction already done */
4933 if (s
->curTransactionOwner
)
4935 /* As in TBLOCK_ABORT, might have a live portal to zap */
4936 AtSubAbort_Portals(s
->subTransactionId
,
4937 s
->parent
->subTransactionId
,
4938 s
->curTransactionOwner
,
4939 s
->parent
->curTransactionOwner
);
4941 CleanupSubTransaction();
4942 s
= CurrentTransactionState
; /* changed by pop */
4945 } while (s
->blockState
!= TBLOCK_DEFAULT
);
4947 /* Should be out of all subxacts now */
4948 Assert(s
->parent
== NULL
);
4951 * Revert to TopMemoryContext, to ensure we exit in a well-defined state
4952 * whether there were any transactions to close or not. (Callers that
4953 * don't intend to exit soon should switch to some other context to avoid
4954 * long-term memory leaks.)
4956 MemoryContextSwitchTo(TopMemoryContext
);
4960 * IsTransactionBlock --- are we within a transaction block?
4963 IsTransactionBlock(void)
4965 TransactionState s
= CurrentTransactionState
;
4967 if (s
->blockState
== TBLOCK_DEFAULT
|| s
->blockState
== TBLOCK_STARTED
)
4974 * IsTransactionOrTransactionBlock --- are we within either a transaction
4975 * or a transaction block? (The backend is only really "idle" when this
4978 * This should match up with IsTransactionBlock and IsTransactionState.
4981 IsTransactionOrTransactionBlock(void)
4983 TransactionState s
= CurrentTransactionState
;
4985 if (s
->blockState
== TBLOCK_DEFAULT
)
4992 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
4995 TransactionBlockStatusCode(void)
4997 TransactionState s
= CurrentTransactionState
;
4999 switch (s
->blockState
)
5001 case TBLOCK_DEFAULT
:
5002 case TBLOCK_STARTED
:
5003 return 'I'; /* idle --- not in transaction */
5005 case TBLOCK_SUBBEGIN
:
5006 case TBLOCK_INPROGRESS
:
5007 case TBLOCK_IMPLICIT_INPROGRESS
:
5008 case TBLOCK_PARALLEL_INPROGRESS
:
5009 case TBLOCK_SUBINPROGRESS
:
5011 case TBLOCK_SUBRELEASE
:
5012 case TBLOCK_SUBCOMMIT
:
5013 case TBLOCK_PREPARE
:
5014 return 'T'; /* in transaction */
5016 case TBLOCK_SUBABORT
:
5017 case TBLOCK_ABORT_END
:
5018 case TBLOCK_SUBABORT_END
:
5019 case TBLOCK_ABORT_PENDING
:
5020 case TBLOCK_SUBABORT_PENDING
:
5021 case TBLOCK_SUBRESTART
:
5022 case TBLOCK_SUBABORT_RESTART
:
5023 return 'E'; /* in failed transaction */
5026 /* should never get here */
5027 elog(FATAL
, "invalid transaction block state: %s",
5028 BlockStateAsString(s
->blockState
));
5029 return 0; /* keep compiler quiet */
5036 IsSubTransaction(void)
5038 TransactionState s
= CurrentTransactionState
;
5040 if (s
->nestingLevel
>= 2)
5047 * StartSubTransaction
5049 * If you're wondering why this is separate from PushTransaction: it's because
5050 * we can't conveniently do this stuff right inside DefineSavepoint. The
5051 * SAVEPOINT utility command will be executed inside a Portal, and if we
5052 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
5053 * the Portal will undo those settings. So we make DefineSavepoint just
5054 * push a dummy transaction block, and when control returns to the main
5055 * idle loop, CommitTransactionCommand will be called, and we'll come here
5056 * to finish starting the subtransaction.
5059 StartSubTransaction(void)
5061 TransactionState s
= CurrentTransactionState
;
5063 if (s
->state
!= TRANS_DEFAULT
)
5064 elog(WARNING
, "StartSubTransaction while in %s state",
5065 TransStateAsString(s
->state
));
5067 s
->state
= TRANS_START
;
5070 * Initialize subsystems for new subtransaction
5072 * must initialize resource-management stuff first
5074 AtSubStart_Memory();
5075 AtSubStart_ResourceOwner();
5076 AfterTriggerBeginSubXact();
5078 s
->state
= TRANS_INPROGRESS
;
5081 * Call start-of-subxact callbacks
5083 CallSubXactCallbacks(SUBXACT_EVENT_START_SUB
, s
->subTransactionId
,
5084 s
->parent
->subTransactionId
);
5086 ShowTransactionState("StartSubTransaction");
5090 * CommitSubTransaction
5092 * The caller has to make sure to always reassign CurrentTransactionState
5093 * if it has a local pointer to it after calling this function.
5096 CommitSubTransaction(void)
5098 TransactionState s
= CurrentTransactionState
;
5100 ShowTransactionState("CommitSubTransaction");
5102 if (s
->state
!= TRANS_INPROGRESS
)
5103 elog(WARNING
, "CommitSubTransaction while in %s state",
5104 TransStateAsString(s
->state
));
5106 /* Pre-commit processing goes here */
5108 CallSubXactCallbacks(SUBXACT_EVENT_PRE_COMMIT_SUB
, s
->subTransactionId
,
5109 s
->parent
->subTransactionId
);
5112 * If this subxact has started any unfinished parallel operation, clean up
5113 * its workers and exit parallel mode. Warn about leaked resources.
5115 AtEOSubXact_Parallel(true, s
->subTransactionId
);
5116 if (s
->parallelModeLevel
!= 0)
5118 elog(WARNING
, "parallelModeLevel is %d not 0 at end of subtransaction",
5119 s
->parallelModeLevel
);
5120 s
->parallelModeLevel
= 0;
5123 /* Do the actual "commit", such as it is */
5124 s
->state
= TRANS_COMMIT
;
5126 /* Must CCI to ensure commands of subtransaction are seen as done */
5127 CommandCounterIncrement();
5130 * Prior to 8.4 we marked subcommit in clog at this point. We now only
5131 * perform that step, if required, as part of the atomic update of the
5132 * whole transaction tree at top level commit or abort.
5135 /* Post-commit cleanup */
5136 if (FullTransactionIdIsValid(s
->fullTransactionId
))
5137 AtSubCommit_childXids();
5138 AfterTriggerEndSubXact(true);
5139 AtSubCommit_Portals(s
->subTransactionId
,
5140 s
->parent
->subTransactionId
,
5141 s
->parent
->nestingLevel
,
5142 s
->parent
->curTransactionOwner
);
5143 AtEOSubXact_LargeObject(true, s
->subTransactionId
,
5144 s
->parent
->subTransactionId
);
5145 AtSubCommit_Notify();
5147 CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB
, s
->subTransactionId
,
5148 s
->parent
->subTransactionId
);
5150 ResourceOwnerRelease(s
->curTransactionOwner
,
5151 RESOURCE_RELEASE_BEFORE_LOCKS
,
5153 AtEOSubXact_RelationCache(true, s
->subTransactionId
,
5154 s
->parent
->subTransactionId
);
5155 AtEOSubXact_TypeCache();
5156 AtEOSubXact_Inval(true);
5160 * The only lock we actually release here is the subtransaction XID lock.
5162 CurrentResourceOwner
= s
->curTransactionOwner
;
5163 if (FullTransactionIdIsValid(s
->fullTransactionId
))
5164 XactLockTableDelete(XidFromFullTransactionId(s
->fullTransactionId
));
5167 * Other locks should get transferred to their parent resource owner.
5169 ResourceOwnerRelease(s
->curTransactionOwner
,
5170 RESOURCE_RELEASE_LOCKS
,
5172 ResourceOwnerRelease(s
->curTransactionOwner
,
5173 RESOURCE_RELEASE_AFTER_LOCKS
,
5176 AtEOXact_GUC(true, s
->gucNestLevel
);
5177 AtEOSubXact_SPI(true, s
->subTransactionId
);
5178 AtEOSubXact_on_commit_actions(true, s
->subTransactionId
,
5179 s
->parent
->subTransactionId
);
5180 AtEOSubXact_Namespace(true, s
->subTransactionId
,
5181 s
->parent
->subTransactionId
);
5182 AtEOSubXact_Files(true, s
->subTransactionId
,
5183 s
->parent
->subTransactionId
);
5184 AtEOSubXact_HashTables(true, s
->nestingLevel
);
5185 AtEOSubXact_PgStat(true, s
->nestingLevel
);
5186 AtSubCommit_Snapshot(s
->nestingLevel
);
5189 * We need to restore the upper transaction's read-only state, in case the
5190 * upper is read-write while the child is read-only; GUC will incorrectly
5191 * think it should leave the child state in place.
5193 XactReadOnly
= s
->prevXactReadOnly
;
5195 CurrentResourceOwner
= s
->parent
->curTransactionOwner
;
5196 CurTransactionResourceOwner
= s
->parent
->curTransactionOwner
;
5197 ResourceOwnerDelete(s
->curTransactionOwner
);
5198 s
->curTransactionOwner
= NULL
;
5200 AtSubCommit_Memory();
5202 s
->state
= TRANS_DEFAULT
;
5208 * AbortSubTransaction
5211 AbortSubTransaction(void)
5213 TransactionState s
= CurrentTransactionState
;
5215 /* Prevent cancel/die interrupt while cleaning up */
5218 /* Make sure we have a valid memory context and resource owner */
5219 AtSubAbort_Memory();
5220 AtSubAbort_ResourceOwner();
5223 * Release any LW locks we might be holding as quickly as possible.
5224 * (Regular locks, however, must be held till we finish aborting.)
5225 * Releasing LW locks is critical since we might try to grab them again
5226 * while cleaning up!
5228 * FIXME This may be incorrect --- Are there some locks we should keep?
5229 * Buffer locks, for example? I don't think so but I'm not sure.
5233 pgstat_report_wait_end();
5234 pgstat_progress_end_command();
5237 /* Reset WAL record construction state */
5238 XLogResetInsertion();
5240 /* Cancel condition variable sleep */
5241 ConditionVariableCancelSleep();
5244 * Also clean up any open wait for lock, since the lock manager will choke
5245 * if we try to wait for another lock before doing this.
5250 * If any timeout events are still active, make sure the timeout interrupt
5251 * is scheduled. This covers possible loss of a timeout interrupt due to
5252 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5253 * We delay this till after LockErrorCleanup so that we don't uselessly
5254 * reschedule lock or deadlock check timeouts.
5256 reschedule_timeouts();
5259 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5260 * handler. We do this fairly early in the sequence so that the timeout
5261 * infrastructure will be functional if needed while aborting.
5263 sigprocmask(SIG_SETMASK
, &UnBlockSig
, NULL
);
5266 * check the current transaction state
5268 ShowTransactionState("AbortSubTransaction");
5270 if (s
->state
!= TRANS_INPROGRESS
)
5271 elog(WARNING
, "AbortSubTransaction while in %s state",
5272 TransStateAsString(s
->state
));
5274 s
->state
= TRANS_ABORT
;
5277 * Reset user ID which might have been changed transiently. (See notes in
5278 * AbortTransaction.)
5280 SetUserIdAndSecContext(s
->prevUser
, s
->prevSecContext
);
5282 /* Forget about any active REINDEX. */
5283 ResetReindexState(s
->nestingLevel
);
5285 /* Reset logical streaming state. */
5286 ResetLogicalStreamingState();
5289 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5290 * exports are not supported in subtransactions.
5294 * If this subxact has started any unfinished parallel operation, clean up
5295 * its workers and exit parallel mode. Don't warn about leaked resources.
5297 AtEOSubXact_Parallel(false, s
->subTransactionId
);
5298 s
->parallelModeLevel
= 0;
5301 * We can skip all this stuff if the subxact failed before creating a
5304 if (s
->curTransactionOwner
)
5306 AfterTriggerEndSubXact(false);
5307 AtSubAbort_Portals(s
->subTransactionId
,
5308 s
->parent
->subTransactionId
,
5309 s
->curTransactionOwner
,
5310 s
->parent
->curTransactionOwner
);
5311 AtEOSubXact_LargeObject(false, s
->subTransactionId
,
5312 s
->parent
->subTransactionId
);
5313 AtSubAbort_Notify();
5315 /* Advertise the fact that we aborted in pg_xact. */
5316 (void) RecordTransactionAbort(true);
5318 /* Post-abort cleanup */
5319 if (FullTransactionIdIsValid(s
->fullTransactionId
))
5320 AtSubAbort_childXids();
5322 CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB
, s
->subTransactionId
,
5323 s
->parent
->subTransactionId
);
5325 ResourceOwnerRelease(s
->curTransactionOwner
,
5326 RESOURCE_RELEASE_BEFORE_LOCKS
,
5329 AtEOSubXact_RelationCache(false, s
->subTransactionId
,
5330 s
->parent
->subTransactionId
);
5331 AtEOSubXact_TypeCache();
5332 AtEOSubXact_Inval(false);
5333 ResourceOwnerRelease(s
->curTransactionOwner
,
5334 RESOURCE_RELEASE_LOCKS
,
5336 ResourceOwnerRelease(s
->curTransactionOwner
,
5337 RESOURCE_RELEASE_AFTER_LOCKS
,
5341 AtEOXact_GUC(false, s
->gucNestLevel
);
5342 AtEOSubXact_SPI(false, s
->subTransactionId
);
5343 AtEOSubXact_on_commit_actions(false, s
->subTransactionId
,
5344 s
->parent
->subTransactionId
);
5345 AtEOSubXact_Namespace(false, s
->subTransactionId
,
5346 s
->parent
->subTransactionId
);
5347 AtEOSubXact_Files(false, s
->subTransactionId
,
5348 s
->parent
->subTransactionId
);
5349 AtEOSubXact_HashTables(false, s
->nestingLevel
);
5350 AtEOSubXact_PgStat(false, s
->nestingLevel
);
5351 AtSubAbort_Snapshot(s
->nestingLevel
);
5355 * Restore the upper transaction's read-only state, too. This should be
5356 * redundant with GUC's cleanup but we may as well do it for consistency
5357 * with the commit case.
5359 XactReadOnly
= s
->prevXactReadOnly
;
5361 RESUME_INTERRUPTS();
5365 * CleanupSubTransaction
5367 * The caller has to make sure to always reassign CurrentTransactionState
5368 * if it has a local pointer to it after calling this function.
5371 CleanupSubTransaction(void)
5373 TransactionState s
= CurrentTransactionState
;
5375 ShowTransactionState("CleanupSubTransaction");
5377 if (s
->state
!= TRANS_ABORT
)
5378 elog(WARNING
, "CleanupSubTransaction while in %s state",
5379 TransStateAsString(s
->state
));
5381 AtSubCleanup_Portals(s
->subTransactionId
);
5383 CurrentResourceOwner
= s
->parent
->curTransactionOwner
;
5384 CurTransactionResourceOwner
= s
->parent
->curTransactionOwner
;
5385 if (s
->curTransactionOwner
)
5386 ResourceOwnerDelete(s
->curTransactionOwner
);
5387 s
->curTransactionOwner
= NULL
;
5389 AtSubCleanup_Memory();
5391 s
->state
= TRANS_DEFAULT
;
5398 * Create transaction state stack entry for a subtransaction
5400 * The caller has to make sure to always reassign CurrentTransactionState
5401 * if it has a local pointer to it after calling this function.
5404 PushTransaction(void)
5406 TransactionState p
= CurrentTransactionState
;
5410 * We keep subtransaction state nodes in TopTransactionContext.
5412 s
= (TransactionState
)
5413 MemoryContextAllocZero(TopTransactionContext
,
5414 sizeof(TransactionStateData
));
5417 * Assign a subtransaction ID, watching out for counter wraparound.
5419 currentSubTransactionId
+= 1;
5420 if (currentSubTransactionId
== InvalidSubTransactionId
)
5422 currentSubTransactionId
-= 1;
5425 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED
),
5426 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5430 * We can now stack a minimally valid subtransaction without fear of
5433 s
->fullTransactionId
= InvalidFullTransactionId
; /* until assigned */
5434 s
->subTransactionId
= currentSubTransactionId
;
5436 s
->nestingLevel
= p
->nestingLevel
+ 1;
5437 s
->gucNestLevel
= NewGUCNestLevel();
5438 s
->savepointLevel
= p
->savepointLevel
;
5439 s
->state
= TRANS_DEFAULT
;
5440 s
->blockState
= TBLOCK_SUBBEGIN
;
5441 GetUserIdAndSecContext(&s
->prevUser
, &s
->prevSecContext
);
5442 s
->prevXactReadOnly
= XactReadOnly
;
5443 s
->startedInRecovery
= p
->startedInRecovery
;
5444 s
->parallelModeLevel
= 0;
5445 s
->parallelChildXact
= (p
->parallelModeLevel
!= 0 || p
->parallelChildXact
);
5446 s
->topXidLogged
= false;
5448 CurrentTransactionState
= s
;
5451 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5452 * with the subtransaction from here on out; in particular they should not
5453 * assume that it necessarily has a transaction context, resource owner,
5460 * Pop back to parent transaction state
5462 * The caller has to make sure to always reassign CurrentTransactionState
5463 * if it has a local pointer to it after calling this function.
5466 PopTransaction(void)
5468 TransactionState s
= CurrentTransactionState
;
5470 if (s
->state
!= TRANS_DEFAULT
)
5471 elog(WARNING
, "PopTransaction while in %s state",
5472 TransStateAsString(s
->state
));
5474 if (s
->parent
== NULL
)
5475 elog(FATAL
, "PopTransaction with no parent");
5477 CurrentTransactionState
= s
->parent
;
5479 /* Let's just make sure CurTransactionContext is good */
5480 CurTransactionContext
= s
->parent
->curTransactionContext
;
5481 MemoryContextSwitchTo(CurTransactionContext
);
5483 /* Ditto for ResourceOwner links */
5484 CurTransactionResourceOwner
= s
->parent
->curTransactionOwner
;
5485 CurrentResourceOwner
= s
->parent
->curTransactionOwner
;
5487 /* Free the old child structure */
5494 * EstimateTransactionStateSpace
5495 * Estimate the amount of space that will be needed by
5496 * SerializeTransactionState. It would be OK to overestimate slightly,
5497 * but it's simple for us to work out the precise value, so we do.
5500 EstimateTransactionStateSpace(void)
5504 Size size
= SerializedTransactionStateHeaderSize
;
5506 for (s
= CurrentTransactionState
; s
!= NULL
; s
= s
->parent
)
5508 if (FullTransactionIdIsValid(s
->fullTransactionId
))
5509 nxids
= add_size(nxids
, 1);
5510 nxids
= add_size(nxids
, s
->nChildXids
);
5513 return add_size(size
, mul_size(sizeof(TransactionId
), nxids
));
5517 * SerializeTransactionState
5518 * Write out relevant details of our transaction state that will be
5519 * needed by a parallel worker.
5521 * We need to save and restore XactDeferrable, XactIsoLevel, and the XIDs
5522 * associated with this transaction. These are serialized into a
5523 * caller-supplied buffer big enough to hold the number of bytes reported by
5524 * EstimateTransactionStateSpace(). We emit the XIDs in sorted order for the
5525 * convenience of the receiving process.
5528 SerializeTransactionState(Size maxsize
, char *start_address
)
5533 TransactionId
*workspace
;
5534 SerializedTransactionState
*result
;
5536 result
= (SerializedTransactionState
*) start_address
;
5538 result
->xactIsoLevel
= XactIsoLevel
;
5539 result
->xactDeferrable
= XactDeferrable
;
5540 result
->topFullTransactionId
= XactTopFullTransactionId
;
5541 result
->currentFullTransactionId
=
5542 CurrentTransactionState
->fullTransactionId
;
5543 result
->currentCommandId
= currentCommandId
;
5546 * If we're running in a parallel worker and launching a parallel worker
5547 * of our own, we can just pass along the information that was passed to
5550 if (nParallelCurrentXids
> 0)
5552 result
->nParallelCurrentXids
= nParallelCurrentXids
;
5553 memcpy(&result
->parallelCurrentXids
[0], ParallelCurrentXids
,
5554 nParallelCurrentXids
* sizeof(TransactionId
));
5559 * OK, we need to generate a sorted list of XIDs that our workers should
5560 * view as current. First, figure out how many there are.
5562 for (s
= CurrentTransactionState
; s
!= NULL
; s
= s
->parent
)
5564 if (FullTransactionIdIsValid(s
->fullTransactionId
))
5565 nxids
= add_size(nxids
, 1);
5566 nxids
= add_size(nxids
, s
->nChildXids
);
5568 Assert(SerializedTransactionStateHeaderSize
+ nxids
* sizeof(TransactionId
)
5571 /* Copy them to our scratch space. */
5572 workspace
= palloc(nxids
* sizeof(TransactionId
));
5573 for (s
= CurrentTransactionState
; s
!= NULL
; s
= s
->parent
)
5575 if (FullTransactionIdIsValid(s
->fullTransactionId
))
5576 workspace
[i
++] = XidFromFullTransactionId(s
->fullTransactionId
);
5577 if (s
->nChildXids
> 0)
5578 memcpy(&workspace
[i
], s
->childXids
,
5579 s
->nChildXids
* sizeof(TransactionId
));
5585 qsort(workspace
, nxids
, sizeof(TransactionId
), xidComparator
);
5587 /* Copy data into output area. */
5588 result
->nParallelCurrentXids
= nxids
;
5589 memcpy(&result
->parallelCurrentXids
[0], workspace
,
5590 nxids
* sizeof(TransactionId
));
5594 * StartParallelWorkerTransaction
5595 * Start a parallel worker transaction, restoring the relevant
5596 * transaction state serialized by SerializeTransactionState.
5599 StartParallelWorkerTransaction(char *tstatespace
)
5601 SerializedTransactionState
*tstate
;
5603 Assert(CurrentTransactionState
->blockState
== TBLOCK_DEFAULT
);
5606 tstate
= (SerializedTransactionState
*) tstatespace
;
5607 XactIsoLevel
= tstate
->xactIsoLevel
;
5608 XactDeferrable
= tstate
->xactDeferrable
;
5609 XactTopFullTransactionId
= tstate
->topFullTransactionId
;
5610 CurrentTransactionState
->fullTransactionId
=
5611 tstate
->currentFullTransactionId
;
5612 currentCommandId
= tstate
->currentCommandId
;
5613 nParallelCurrentXids
= tstate
->nParallelCurrentXids
;
5614 ParallelCurrentXids
= &tstate
->parallelCurrentXids
[0];
5616 CurrentTransactionState
->blockState
= TBLOCK_PARALLEL_INPROGRESS
;
5620 * EndParallelWorkerTransaction
5621 * End a parallel worker transaction.
5624 EndParallelWorkerTransaction(void)
5626 Assert(CurrentTransactionState
->blockState
== TBLOCK_PARALLEL_INPROGRESS
);
5627 CommitTransaction();
5628 CurrentTransactionState
->blockState
= TBLOCK_DEFAULT
;
5632 * ShowTransactionState
5636 ShowTransactionState(const char *str
)
5638 /* skip work if message will definitely not be printed */
5639 if (message_level_is_interesting(DEBUG5
))
5640 ShowTransactionStateRec(str
, CurrentTransactionState
);
5644 * ShowTransactionStateRec
5645 * Recursive subroutine for ShowTransactionState
5648 ShowTransactionStateRec(const char *str
, TransactionState s
)
5655 * Since this function recurses, it could be driven to stack overflow.
5656 * This is just a debugging aid, so we can leave out some details
5657 * instead of erroring out with check_stack_depth().
5659 if (stack_is_too_deep())
5661 (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5662 str
, s
->nestingLevel
)));
5664 ShowTransactionStateRec(str
, s
->parent
);
5667 initStringInfo(&buf
);
5668 if (s
->nChildXids
> 0)
5672 appendStringInfo(&buf
, ", children: %u", s
->childXids
[0]);
5673 for (i
= 1; i
< s
->nChildXids
; i
++)
5674 appendStringInfo(&buf
, " %u", s
->childXids
[i
]);
5677 (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5678 str
, s
->nestingLevel
,
5679 PointerIsValid(s
->name
) ? s
->name
: "unnamed",
5680 BlockStateAsString(s
->blockState
),
5681 TransStateAsString(s
->state
),
5682 (unsigned int) XidFromFullTransactionId(s
->fullTransactionId
),
5683 (unsigned int) s
->subTransactionId
,
5684 (unsigned int) currentCommandId
,
5685 currentCommandIdUsed
? " (used)" : "",
5691 * BlockStateAsString
5695 BlockStateAsString(TBlockState blockState
)
5699 case TBLOCK_DEFAULT
:
5701 case TBLOCK_STARTED
:
5705 case TBLOCK_INPROGRESS
:
5706 return "INPROGRESS";
5707 case TBLOCK_IMPLICIT_INPROGRESS
:
5708 return "IMPLICIT_INPROGRESS";
5709 case TBLOCK_PARALLEL_INPROGRESS
:
5710 return "PARALLEL_INPROGRESS";
5715 case TBLOCK_ABORT_END
:
5717 case TBLOCK_ABORT_PENDING
:
5718 return "ABORT_PENDING";
5719 case TBLOCK_PREPARE
:
5721 case TBLOCK_SUBBEGIN
:
5723 case TBLOCK_SUBINPROGRESS
:
5724 return "SUBINPROGRESS";
5725 case TBLOCK_SUBRELEASE
:
5726 return "SUBRELEASE";
5727 case TBLOCK_SUBCOMMIT
:
5729 case TBLOCK_SUBABORT
:
5731 case TBLOCK_SUBABORT_END
:
5732 return "SUBABORT_END";
5733 case TBLOCK_SUBABORT_PENDING
:
5734 return "SUBABORT_PENDING";
5735 case TBLOCK_SUBRESTART
:
5736 return "SUBRESTART";
5737 case TBLOCK_SUBABORT_RESTART
:
5738 return "SUBABORT_RESTART";
5740 return "UNRECOGNIZED";
5744 * TransStateAsString
5748 TransStateAsString(TransState state
)
5756 case TRANS_INPROGRESS
:
5757 return "INPROGRESS";
5765 return "UNRECOGNIZED";
5769 * xactGetCommittedChildren
5771 * Gets the list of committed children of the current transaction. The return
5772 * value is the number of child transactions. *ptr is set to point to an
5773 * array of TransactionIds. The array is allocated in TopTransactionContext;
5774 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
5775 * If there are no subxacts, *ptr is set to NULL.
5778 xactGetCommittedChildren(TransactionId
**ptr
)
5780 TransactionState s
= CurrentTransactionState
;
5782 if (s
->nChildXids
== 0)
5785 *ptr
= s
->childXids
;
5787 return s
->nChildXids
;
5791 * XLOG support routines
5796 * Log the commit record for a plain or twophase transaction commit.
5798 * A 2pc commit will be emitted when twophase_xid is valid, a plain one
5802 XactLogCommitRecord(TimestampTz commit_time
,
5803 int nsubxacts
, TransactionId
*subxacts
,
5804 int nrels
, RelFileLocator
*rels
,
5805 int ndroppedstats
, xl_xact_stats_item
*droppedstats
,
5806 int nmsgs
, SharedInvalidationMessage
*msgs
,
5808 int xactflags
, TransactionId twophase_xid
,
5809 const char *twophase_gid
)
5811 xl_xact_commit xlrec
;
5812 xl_xact_xinfo xl_xinfo
;
5813 xl_xact_dbinfo xl_dbinfo
;
5814 xl_xact_subxacts xl_subxacts
;
5815 xl_xact_relfilelocators xl_relfilelocators
;
5816 xl_xact_stats_items xl_dropped_stats
;
5817 xl_xact_invals xl_invals
;
5818 xl_xact_twophase xl_twophase
;
5819 xl_xact_origin xl_origin
;
5822 Assert(CritSectionCount
> 0);
5826 /* decide between a plain and 2pc commit */
5827 if (!TransactionIdIsValid(twophase_xid
))
5828 info
= XLOG_XACT_COMMIT
;
5830 info
= XLOG_XACT_COMMIT_PREPARED
;
5832 /* First figure out and collect all the information needed */
5834 xlrec
.xact_time
= commit_time
;
5837 xl_xinfo
.xinfo
|= XACT_COMPLETION_UPDATE_RELCACHE_FILE
;
5838 if (forceSyncCommit
)
5839 xl_xinfo
.xinfo
|= XACT_COMPLETION_FORCE_SYNC_COMMIT
;
5840 if ((xactflags
& XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK
))
5841 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_AE_LOCKS
;
5844 * Check if the caller would like to ask standbys for immediate feedback
5845 * once this commit is applied.
5847 if (synchronous_commit
>= SYNCHRONOUS_COMMIT_REMOTE_APPLY
)
5848 xl_xinfo
.xinfo
|= XACT_COMPLETION_APPLY_FEEDBACK
;
5851 * Relcache invalidations requires information about the current database
5852 * and so does logical decoding.
5854 if (nmsgs
> 0 || XLogLogicalInfoActive())
5856 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_DBINFO
;
5857 xl_dbinfo
.dbId
= MyDatabaseId
;
5858 xl_dbinfo
.tsId
= MyDatabaseTableSpace
;
5863 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_SUBXACTS
;
5864 xl_subxacts
.nsubxacts
= nsubxacts
;
5869 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_RELFILELOCATORS
;
5870 xl_relfilelocators
.nrels
= nrels
;
5871 info
|= XLR_SPECIAL_REL_UPDATE
;
5874 if (ndroppedstats
> 0)
5876 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_DROPPED_STATS
;
5877 xl_dropped_stats
.nitems
= ndroppedstats
;
5882 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_INVALS
;
5883 xl_invals
.nmsgs
= nmsgs
;
5886 if (TransactionIdIsValid(twophase_xid
))
5888 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_TWOPHASE
;
5889 xl_twophase
.xid
= twophase_xid
;
5890 Assert(twophase_gid
!= NULL
);
5892 if (XLogLogicalInfoActive())
5893 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_GID
;
5896 /* dump transaction origin information */
5897 if (replorigin_session_origin
!= InvalidRepOriginId
)
5899 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_ORIGIN
;
5901 xl_origin
.origin_lsn
= replorigin_session_origin_lsn
;
5902 xl_origin
.origin_timestamp
= replorigin_session_origin_timestamp
;
5905 if (xl_xinfo
.xinfo
!= 0)
5906 info
|= XLOG_XACT_HAS_INFO
;
5908 /* Then include all the collected data into the commit record. */
5912 XLogRegisterData((char *) (&xlrec
), sizeof(xl_xact_commit
));
5914 if (xl_xinfo
.xinfo
!= 0)
5915 XLogRegisterData((char *) (&xl_xinfo
.xinfo
), sizeof(xl_xinfo
.xinfo
));
5917 if (xl_xinfo
.xinfo
& XACT_XINFO_HAS_DBINFO
)
5918 XLogRegisterData((char *) (&xl_dbinfo
), sizeof(xl_dbinfo
));
5920 if (xl_xinfo
.xinfo
& XACT_XINFO_HAS_SUBXACTS
)
5922 XLogRegisterData((char *) (&xl_subxacts
),
5923 MinSizeOfXactSubxacts
);
5924 XLogRegisterData((char *) subxacts
,
5925 nsubxacts
* sizeof(TransactionId
));
5928 if (xl_xinfo
.xinfo
& XACT_XINFO_HAS_RELFILELOCATORS
)
5930 XLogRegisterData((char *) (&xl_relfilelocators
),
5931 MinSizeOfXactRelfileLocators
);
5932 XLogRegisterData((char *) rels
,
5933 nrels
* sizeof(RelFileLocator
));
5936 if (xl_xinfo
.xinfo
& XACT_XINFO_HAS_DROPPED_STATS
)
5938 XLogRegisterData((char *) (&xl_dropped_stats
),
5939 MinSizeOfXactStatsItems
);
5940 XLogRegisterData((char *) droppedstats
,
5941 ndroppedstats
* sizeof(xl_xact_stats_item
));
5944 if (xl_xinfo
.xinfo
& XACT_XINFO_HAS_INVALS
)
5946 XLogRegisterData((char *) (&xl_invals
), MinSizeOfXactInvals
);
5947 XLogRegisterData((char *) msgs
,
5948 nmsgs
* sizeof(SharedInvalidationMessage
));
5951 if (xl_xinfo
.xinfo
& XACT_XINFO_HAS_TWOPHASE
)
5953 XLogRegisterData((char *) (&xl_twophase
), sizeof(xl_xact_twophase
));
5954 if (xl_xinfo
.xinfo
& XACT_XINFO_HAS_GID
)
5955 XLogRegisterData(twophase_gid
, strlen(twophase_gid
) + 1);
5958 if (xl_xinfo
.xinfo
& XACT_XINFO_HAS_ORIGIN
)
5959 XLogRegisterData((char *) (&xl_origin
), sizeof(xl_xact_origin
));
5961 /* we allow filtering by xacts */
5962 XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN
);
5964 return XLogInsert(RM_XACT_ID
, info
);
5968 * Log the commit record for a plain or twophase transaction abort.
5970 * A 2pc abort will be emitted when twophase_xid is valid, a plain one
5974 XactLogAbortRecord(TimestampTz abort_time
,
5975 int nsubxacts
, TransactionId
*subxacts
,
5976 int nrels
, RelFileLocator
*rels
,
5977 int ndroppedstats
, xl_xact_stats_item
*droppedstats
,
5978 int xactflags
, TransactionId twophase_xid
,
5979 const char *twophase_gid
)
5981 xl_xact_abort xlrec
;
5982 xl_xact_xinfo xl_xinfo
;
5983 xl_xact_subxacts xl_subxacts
;
5984 xl_xact_relfilelocators xl_relfilelocators
;
5985 xl_xact_stats_items xl_dropped_stats
;
5986 xl_xact_twophase xl_twophase
;
5987 xl_xact_dbinfo xl_dbinfo
;
5988 xl_xact_origin xl_origin
;
5992 Assert(CritSectionCount
> 0);
5996 /* decide between a plain and 2pc abort */
5997 if (!TransactionIdIsValid(twophase_xid
))
5998 info
= XLOG_XACT_ABORT
;
6000 info
= XLOG_XACT_ABORT_PREPARED
;
6003 /* First figure out and collect all the information needed */
6005 xlrec
.xact_time
= abort_time
;
6007 if ((xactflags
& XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK
))
6008 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_AE_LOCKS
;
6012 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_SUBXACTS
;
6013 xl_subxacts
.nsubxacts
= nsubxacts
;
6018 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_RELFILELOCATORS
;
6019 xl_relfilelocators
.nrels
= nrels
;
6020 info
|= XLR_SPECIAL_REL_UPDATE
;
6023 if (ndroppedstats
> 0)
6025 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_DROPPED_STATS
;
6026 xl_dropped_stats
.nitems
= ndroppedstats
;
6029 if (TransactionIdIsValid(twophase_xid
))
6031 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_TWOPHASE
;
6032 xl_twophase
.xid
= twophase_xid
;
6033 Assert(twophase_gid
!= NULL
);
6035 if (XLogLogicalInfoActive())
6036 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_GID
;
6039 if (TransactionIdIsValid(twophase_xid
) && XLogLogicalInfoActive())
6041 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_DBINFO
;
6042 xl_dbinfo
.dbId
= MyDatabaseId
;
6043 xl_dbinfo
.tsId
= MyDatabaseTableSpace
;
6047 * Dump transaction origin information. We need this during recovery to
6048 * update the replication origin progress.
6050 if (replorigin_session_origin
!= InvalidRepOriginId
)
6052 xl_xinfo
.xinfo
|= XACT_XINFO_HAS_ORIGIN
;
6054 xl_origin
.origin_lsn
= replorigin_session_origin_lsn
;
6055 xl_origin
.origin_timestamp
= replorigin_session_origin_timestamp
;
6058 if (xl_xinfo
.xinfo
!= 0)
6059 info
|= XLOG_XACT_HAS_INFO
;
6061 /* Then include all the collected data into the abort record. */
6065 XLogRegisterData((char *) (&xlrec
), MinSizeOfXactAbort
);
6067 if (xl_xinfo
.xinfo
!= 0)
6068 XLogRegisterData((char *) (&xl_xinfo
), sizeof(xl_xinfo
));
6070 if (xl_xinfo
.xinfo
& XACT_XINFO_HAS_DBINFO
)
6071 XLogRegisterData((char *) (&xl_dbinfo
), sizeof(xl_dbinfo
));
6073 if (xl_xinfo
.xinfo
& XACT_XINFO_HAS_SUBXACTS
)
6075 XLogRegisterData((char *) (&xl_subxacts
),
6076 MinSizeOfXactSubxacts
);
6077 XLogRegisterData((char *) subxacts
,
6078 nsubxacts
* sizeof(TransactionId
));
6081 if (xl_xinfo
.xinfo
& XACT_XINFO_HAS_RELFILELOCATORS
)
6083 XLogRegisterData((char *) (&xl_relfilelocators
),
6084 MinSizeOfXactRelfileLocators
);
6085 XLogRegisterData((char *) rels
,
6086 nrels
* sizeof(RelFileLocator
));
6089 if (xl_xinfo
.xinfo
& XACT_XINFO_HAS_DROPPED_STATS
)
6091 XLogRegisterData((char *) (&xl_dropped_stats
),
6092 MinSizeOfXactStatsItems
);
6093 XLogRegisterData((char *) droppedstats
,
6094 ndroppedstats
* sizeof(xl_xact_stats_item
));
6097 if (xl_xinfo
.xinfo
& XACT_XINFO_HAS_TWOPHASE
)
6099 XLogRegisterData((char *) (&xl_twophase
), sizeof(xl_xact_twophase
));
6100 if (xl_xinfo
.xinfo
& XACT_XINFO_HAS_GID
)
6101 XLogRegisterData(twophase_gid
, strlen(twophase_gid
) + 1);
6104 if (xl_xinfo
.xinfo
& XACT_XINFO_HAS_ORIGIN
)
6105 XLogRegisterData((char *) (&xl_origin
), sizeof(xl_xact_origin
));
6107 /* Include the replication origin */
6108 XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN
);
6110 return XLogInsert(RM_XACT_ID
, info
);
6114 * Before 9.0 this was a fairly short function, but now it performs many
6115 * actions for which the order of execution is critical.
6118 xact_redo_commit(xl_xact_parsed_commit
*parsed
,
6121 RepOriginId origin_id
)
6123 TransactionId max_xid
;
6124 TimestampTz commit_time
;
6126 Assert(TransactionIdIsValid(xid
));
6128 max_xid
= TransactionIdLatest(xid
, parsed
->nsubxacts
, parsed
->subxacts
);
6130 /* Make sure nextXid is beyond any XID mentioned in the record. */
6131 AdvanceNextFullTransactionIdPastXid(max_xid
);
6133 Assert(((parsed
->xinfo
& XACT_XINFO_HAS_ORIGIN
) == 0) ==
6134 (origin_id
== InvalidRepOriginId
));
6136 if (parsed
->xinfo
& XACT_XINFO_HAS_ORIGIN
)
6137 commit_time
= parsed
->origin_timestamp
;
6139 commit_time
= parsed
->xact_time
;
6141 /* Set the transaction commit timestamp and metadata */
6142 TransactionTreeSetCommitTsData(xid
, parsed
->nsubxacts
, parsed
->subxacts
,
6143 commit_time
, origin_id
);
6145 if (standbyState
== STANDBY_DISABLED
)
6148 * Mark the transaction committed in pg_xact.
6150 TransactionIdCommitTree(xid
, parsed
->nsubxacts
, parsed
->subxacts
);
6155 * If a transaction completion record arrives that has as-yet
6156 * unobserved subtransactions then this will not have been fully
6157 * handled by the call to RecordKnownAssignedTransactionIds() in the
6158 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6159 * cover that case. This is confusing and it is easy to think this
6160 * call is irrelevant, which has happened three times in development
6161 * already. Leave it in.
6163 RecordKnownAssignedTransactionIds(max_xid
);
6166 * Mark the transaction committed in pg_xact. We use async commit
6167 * protocol during recovery to provide information on database
6168 * consistency for when users try to set hint bits. It is important
6169 * that we do not set hint bits until the minRecoveryPoint is past
6170 * this commit record. This ensures that if we crash we don't see hint
6171 * bits set on changes made by transactions that haven't yet
6172 * recovered. It's unlikely but it's good to be safe.
6174 TransactionIdAsyncCommitTree(xid
, parsed
->nsubxacts
, parsed
->subxacts
, lsn
);
6177 * We must mark clog before we update the ProcArray.
6179 ExpireTreeKnownAssignedTransactionIds(xid
, parsed
->nsubxacts
, parsed
->subxacts
, max_xid
);
6182 * Send any cache invalidations attached to the commit. We must
6183 * maintain the same order of invalidation then release locks as
6184 * occurs in CommitTransaction().
6186 ProcessCommittedInvalidationMessages(parsed
->msgs
, parsed
->nmsgs
,
6187 XactCompletionRelcacheInitFileInval(parsed
->xinfo
),
6188 parsed
->dbId
, parsed
->tsId
);
6191 * Release locks, if any. We do this for both two phase and normal one
6192 * phase transactions. In effect we are ignoring the prepare phase and
6193 * just going straight to lock release.
6195 if (parsed
->xinfo
& XACT_XINFO_HAS_AE_LOCKS
)
6196 StandbyReleaseLockTree(xid
, parsed
->nsubxacts
, parsed
->subxacts
);
6199 if (parsed
->xinfo
& XACT_XINFO_HAS_ORIGIN
)
6201 /* recover apply progress */
6202 replorigin_advance(origin_id
, parsed
->origin_lsn
, lsn
,
6203 false /* backward */ , false /* WAL */ );
6206 /* Make sure files supposed to be dropped are dropped */
6207 if (parsed
->nrels
> 0)
6210 * First update minimum recovery point to cover this WAL record. Once
6211 * a relation is deleted, there's no going back. The buffer manager
6212 * enforces the WAL-first rule for normal updates to relation files,
6213 * so that the minimum recovery point is always updated before the
6214 * corresponding change in the data file is flushed to disk, but we
6215 * have to do the same here since we're bypassing the buffer manager.
6217 * Doing this before deleting the files means that if a deletion fails
6218 * for some reason, you cannot start up the system even after restart,
6219 * until you fix the underlying situation so that the deletion will
6220 * succeed. Alternatively, we could update the minimum recovery point
6221 * after deletion, but that would leave a small window where the
6222 * WAL-first rule would be violated.
6226 /* Make sure files supposed to be dropped are dropped */
6227 DropRelationFiles(parsed
->xlocators
, parsed
->nrels
, true);
6230 if (parsed
->nstats
> 0)
6232 /* see equivalent call for relations above */
6235 pgstat_execute_transactional_drops(parsed
->nstats
, parsed
->stats
, true);
6239 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
6240 * in normal operation. For example, in CREATE DATABASE, we copy all files
6241 * from the template database, and then commit the transaction. If we
6242 * crash after all the files have been copied but before the commit, you
6243 * have files in the data directory without an entry in pg_database. To
6244 * minimize the window for that, we use ForceSyncCommit() to rush the
6245 * commit record to disk as quick as possible. We have the same window
6246 * during recovery, and forcing an XLogFlush() (which updates
6247 * minRecoveryPoint during recovery) helps to reduce that problem window,
6248 * for any user that requested ForceSyncCommit().
6250 if (XactCompletionForceSyncCommit(parsed
->xinfo
))
6254 * If asked by the primary (because someone is waiting for a synchronous
6255 * commit = remote_apply), we will need to ask walreceiver to send a reply
6258 if (XactCompletionApplyFeedback(parsed
->xinfo
))
6259 XLogRequestWalReceiverReply();
6263 * Be careful with the order of execution, as with xact_redo_commit().
6264 * The two functions are similar but differ in key places.
6266 * Note also that an abort can be for a subtransaction and its children,
6267 * not just for a top level abort. That means we have to consider
6268 * topxid != xid, whereas in commit we would find topxid == xid always
6269 * because subtransaction commit is never WAL logged.
6272 xact_redo_abort(xl_xact_parsed_abort
*parsed
, TransactionId xid
,
6273 XLogRecPtr lsn
, RepOriginId origin_id
)
6275 TransactionId max_xid
;
6277 Assert(TransactionIdIsValid(xid
));
6279 /* Make sure nextXid is beyond any XID mentioned in the record. */
6280 max_xid
= TransactionIdLatest(xid
,
6283 AdvanceNextFullTransactionIdPastXid(max_xid
);
6285 if (standbyState
== STANDBY_DISABLED
)
6287 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6288 TransactionIdAbortTree(xid
, parsed
->nsubxacts
, parsed
->subxacts
);
6293 * If a transaction completion record arrives that has as-yet
6294 * unobserved subtransactions then this will not have been fully
6295 * handled by the call to RecordKnownAssignedTransactionIds() in the
6296 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6297 * cover that case. This is confusing and it is easy to think this
6298 * call is irrelevant, which has happened three times in development
6299 * already. Leave it in.
6301 RecordKnownAssignedTransactionIds(max_xid
);
6303 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6304 TransactionIdAbortTree(xid
, parsed
->nsubxacts
, parsed
->subxacts
);
6307 * We must update the ProcArray after we have marked clog.
6309 ExpireTreeKnownAssignedTransactionIds(xid
, parsed
->nsubxacts
, parsed
->subxacts
, max_xid
);
6312 * There are no invalidation messages to send or undo.
6316 * Release locks, if any. There are no invalidations to send.
6318 if (parsed
->xinfo
& XACT_XINFO_HAS_AE_LOCKS
)
6319 StandbyReleaseLockTree(xid
, parsed
->nsubxacts
, parsed
->subxacts
);
6322 if (parsed
->xinfo
& XACT_XINFO_HAS_ORIGIN
)
6324 /* recover apply progress */
6325 replorigin_advance(origin_id
, parsed
->origin_lsn
, lsn
,
6326 false /* backward */ , false /* WAL */ );
6329 /* Make sure files supposed to be dropped are dropped */
6330 if (parsed
->nrels
> 0)
6333 * See comments about update of minimum recovery point on truncation,
6334 * in xact_redo_commit().
6338 DropRelationFiles(parsed
->xlocators
, parsed
->nrels
, true);
6341 if (parsed
->nstats
> 0)
6343 /* see equivalent call for relations above */
6346 pgstat_execute_transactional_drops(parsed
->nstats
, parsed
->stats
, true);
6351 xact_redo(XLogReaderState
*record
)
6353 uint8 info
= XLogRecGetInfo(record
) & XLOG_XACT_OPMASK
;
6355 /* Backup blocks are not used in xact records */
6356 Assert(!XLogRecHasAnyBlockRefs(record
));
6358 if (info
== XLOG_XACT_COMMIT
)
6360 xl_xact_commit
*xlrec
= (xl_xact_commit
*) XLogRecGetData(record
);
6361 xl_xact_parsed_commit parsed
;
6363 ParseCommitRecord(XLogRecGetInfo(record
), xlrec
, &parsed
);
6364 xact_redo_commit(&parsed
, XLogRecGetXid(record
),
6365 record
->EndRecPtr
, XLogRecGetOrigin(record
));
6367 else if (info
== XLOG_XACT_COMMIT_PREPARED
)
6369 xl_xact_commit
*xlrec
= (xl_xact_commit
*) XLogRecGetData(record
);
6370 xl_xact_parsed_commit parsed
;
6372 ParseCommitRecord(XLogRecGetInfo(record
), xlrec
, &parsed
);
6373 xact_redo_commit(&parsed
, parsed
.twophase_xid
,
6374 record
->EndRecPtr
, XLogRecGetOrigin(record
));
6376 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6377 LWLockAcquire(TwoPhaseStateLock
, LW_EXCLUSIVE
);
6378 PrepareRedoRemove(parsed
.twophase_xid
, false);
6379 LWLockRelease(TwoPhaseStateLock
);
6381 else if (info
== XLOG_XACT_ABORT
)
6383 xl_xact_abort
*xlrec
= (xl_xact_abort
*) XLogRecGetData(record
);
6384 xl_xact_parsed_abort parsed
;
6386 ParseAbortRecord(XLogRecGetInfo(record
), xlrec
, &parsed
);
6387 xact_redo_abort(&parsed
, XLogRecGetXid(record
),
6388 record
->EndRecPtr
, XLogRecGetOrigin(record
));
6390 else if (info
== XLOG_XACT_ABORT_PREPARED
)
6392 xl_xact_abort
*xlrec
= (xl_xact_abort
*) XLogRecGetData(record
);
6393 xl_xact_parsed_abort parsed
;
6395 ParseAbortRecord(XLogRecGetInfo(record
), xlrec
, &parsed
);
6396 xact_redo_abort(&parsed
, parsed
.twophase_xid
,
6397 record
->EndRecPtr
, XLogRecGetOrigin(record
));
6399 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6400 LWLockAcquire(TwoPhaseStateLock
, LW_EXCLUSIVE
);
6401 PrepareRedoRemove(parsed
.twophase_xid
, false);
6402 LWLockRelease(TwoPhaseStateLock
);
6404 else if (info
== XLOG_XACT_PREPARE
)
6407 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6410 LWLockAcquire(TwoPhaseStateLock
, LW_EXCLUSIVE
);
6411 PrepareRedoAdd(XLogRecGetData(record
),
6414 XLogRecGetOrigin(record
));
6415 LWLockRelease(TwoPhaseStateLock
);
6417 else if (info
== XLOG_XACT_ASSIGNMENT
)
6419 xl_xact_assignment
*xlrec
= (xl_xact_assignment
*) XLogRecGetData(record
);
6421 if (standbyState
>= STANDBY_INITIALIZED
)
6422 ProcArrayApplyXidAssignment(xlrec
->xtop
,
6423 xlrec
->nsubxacts
, xlrec
->xsub
);
6425 else if (info
== XLOG_XACT_INVALIDATIONS
)
6428 * XXX we do ignore this for now, what matters are invalidations
6429 * written into the commit record.
6433 elog(PANIC
, "xact_redo: unknown op code %u", info
);