PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
xact.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * xact.c
4 * top level transaction system support routines
5 *
6 * See src/backend/access/transam/README for more information.
7 *
8 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
10 *
11 *
12 * IDENTIFICATION
13 * src/backend/access/transam/xact.c
14 *
15 *-------------------------------------------------------------------------
16 */
17
18#include "postgres.h"
19
20#include <time.h>
21#include <unistd.h>
22
23#include "access/commit_ts.h"
24#include "access/multixact.h"
25#include "access/parallel.h"
26#include "access/subtrans.h"
27#include "access/transam.h"
28#include "access/twophase.h"
29#include "access/xact.h"
30#include "access/xlog.h"
31#include "access/xloginsert.h"
32#include "access/xlogrecovery.h"
33#include "access/xlogutils.h"
34#include "catalog/index.h"
35#include "catalog/namespace.h"
36#include "catalog/pg_enum.h"
37#include "catalog/storage.h"
38#include "commands/async.h"
39#include "commands/tablecmds.h"
40#include "commands/trigger.h"
41#include "common/pg_prng.h"
42#include "executor/spi.h"
43#include "libpq/be-fsstubs.h"
44#include "libpq/pqsignal.h"
45#include "miscadmin.h"
46#include "pg_trace.h"
47#include "pgstat.h"
48#include "replication/logical.h"
51#include "replication/origin.h"
53#include "replication/syncrep.h"
54#include "storage/aio_subsys.h"
56#include "storage/fd.h"
57#include "storage/lmgr.h"
58#include "storage/md.h"
59#include "storage/predicate.h"
60#include "storage/proc.h"
61#include "storage/procarray.h"
62#include "storage/sinvaladt.h"
63#include "storage/smgr.h"
64#include "utils/builtins.h"
65#include "utils/combocid.h"
66#include "utils/guc.h"
67#include "utils/inval.h"
68#include "utils/memutils.h"
69#include "utils/relmapper.h"
70#include "utils/snapmgr.h"
71#include "utils/timeout.h"
72#include "utils/timestamp.h"
73#include "utils/typcache.h"
74
75/*
76 * User-tweakable parameters
77 */
80
83
86
88
89/*
90 * CheckXidAlive is a xid value pointing to a possibly ongoing (sub)
91 * transaction. Currently, it is used in logical decoding. It's possible
92 * that such transactions can get aborted while the decoding is ongoing in
93 * which case we skip decoding that particular transaction. To ensure that we
94 * check whether the CheckXidAlive is aborted after fetching the tuple from
95 * system tables. We also ensure that during logical decoding we never
96 * directly access the tableam or heap APIs because we are checking for the
97 * concurrent aborts only in systable_* APIs.
98 */
100bool bsysscan = false;
101
102/*
103 * When running as a parallel worker, we place only a single
104 * TransactionStateData on the parallel worker's state stack, and the XID
105 * reflected there will be that of the *innermost* currently-active
106 * subtransaction in the backend that initiated parallelism. However,
107 * GetTopTransactionId() and TransactionIdIsCurrentTransactionId()
108 * need to return the same answers in the parallel worker as they would have
109 * in the user backend, so we need some additional bookkeeping.
110 *
111 * XactTopFullTransactionId stores the XID of our toplevel transaction, which
112 * will be the same as TopTransactionStateData.fullTransactionId in an
113 * ordinary backend; but in a parallel backend, which does not have the entire
114 * transaction state, it will instead be copied from the backend that started
115 * the parallel operation.
116 *
117 * nParallelCurrentXids will be 0 and ParallelCurrentXids NULL in an ordinary
118 * backend, but in a parallel backend, nParallelCurrentXids will contain the
119 * number of XIDs that need to be considered current, and ParallelCurrentXids
120 * will contain the XIDs themselves. This includes all XIDs that were current
121 * or sub-committed in the parent at the time the parallel operation began.
122 * The XIDs are stored sorted in numerical order (not logical order) to make
123 * lookups as fast as possible.
124 */
126static int nParallelCurrentXids = 0;
128
129/*
130 * Miscellaneous flag bits to record events which occur on the top level
131 * transaction. These flags are only persisted in MyXactFlags and are intended
132 * so we remember to do certain things later on in the transaction. This is
133 * globally accessible, so can be set from anywhere in the code that requires
134 * recording flags.
135 */
137
138/*
139 * transaction states - transaction state from server perspective
140 */
141typedef enum TransState
142{
143 TRANS_DEFAULT, /* idle */
144 TRANS_START, /* transaction starting */
145 TRANS_INPROGRESS, /* inside a valid transaction */
146 TRANS_COMMIT, /* commit in progress */
147 TRANS_ABORT, /* abort in progress */
148 TRANS_PREPARE, /* prepare in progress */
150
151/*
152 * transaction block states - transaction state of client queries
153 *
154 * Note: the subtransaction states are used only for non-topmost
155 * transactions; the others appear only in the topmost transaction.
156 */
157typedef enum TBlockState
158{
159 /* not-in-transaction-block states */
160 TBLOCK_DEFAULT, /* idle */
161 TBLOCK_STARTED, /* running single-query transaction */
162
163 /* transaction block states */
164 TBLOCK_BEGIN, /* starting transaction block */
165 TBLOCK_INPROGRESS, /* live transaction */
166 TBLOCK_IMPLICIT_INPROGRESS, /* live transaction after implicit BEGIN */
167 TBLOCK_PARALLEL_INPROGRESS, /* live transaction inside parallel worker */
168 TBLOCK_END, /* COMMIT received */
169 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
170 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
171 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
172 TBLOCK_PREPARE, /* live xact, PREPARE received */
173
174 /* subtransaction states */
175 TBLOCK_SUBBEGIN, /* starting a subtransaction */
176 TBLOCK_SUBINPROGRESS, /* live subtransaction */
177 TBLOCK_SUBRELEASE, /* RELEASE received */
178 TBLOCK_SUBCOMMIT, /* COMMIT received while TBLOCK_SUBINPROGRESS */
179 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
180 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
181 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
182 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
183 TBLOCK_SUBABORT_RESTART, /* failed subxact, ROLLBACK TO received */
185
186/*
187 * transaction state structure
188 *
189 * Note: parallelModeLevel counts the number of unmatched EnterParallelMode
190 * calls done at this transaction level. parallelChildXact is true if any
191 * upper transaction level has nonzero parallelModeLevel.
192 */
194{
195 FullTransactionId fullTransactionId; /* my FullTransactionId */
197 char *name; /* savepoint name, if any */
198 int savepointLevel; /* savepoint level */
199 TransState state; /* low-level state */
200 TBlockState blockState; /* high-level state */
201 int nestingLevel; /* transaction nesting depth */
202 int gucNestLevel; /* GUC context nesting depth */
203 MemoryContext curTransactionContext; /* my xact-lifetime context */
204 ResourceOwner curTransactionOwner; /* my query resources */
205 MemoryContext priorContext; /* CurrentMemoryContext before xact started */
206 TransactionId *childXids; /* subcommitted child XIDs, in XID order */
207 int nChildXids; /* # of subcommitted child XIDs */
208 int maxChildXids; /* allocated size of childXids[] */
209 Oid prevUser; /* previous CurrentUserId setting */
210 int prevSecContext; /* previous SecurityRestrictionContext */
211 bool prevXactReadOnly; /* entry-time xact r/o state */
212 bool startedInRecovery; /* did we start in recovery? */
213 bool didLogXid; /* has xid been included in WAL record? */
214 int parallelModeLevel; /* Enter/ExitParallelMode counter */
215 bool parallelChildXact; /* is any parent transaction parallel? */
216 bool chain; /* start a new block after this one */
217 bool topXidLogged; /* for a subxact: is top-level XID logged? */
218 struct TransactionStateData *parent; /* back link to parent */
220
222
223/*
224 * Serialized representation used to transmit transaction state to parallel
225 * workers through shared memory.
226 */
228{
237
238/* The size of SerializedTransactionState, not including the final array. */
239#define SerializedTransactionStateHeaderSize \
240 offsetof(SerializedTransactionState, parallelCurrentXids)
241
242/*
243 * CurrentTransactionState always points to the current transaction state
244 * block. It will point to TopTransactionStateData when not in a
245 * transaction at all, or when in a top-level transaction.
246 */
249 .blockState = TBLOCK_DEFAULT,
250 .topXidLogged = false,
251};
252
253/*
254 * unreportedXids holds XIDs of all subtransactions that have not yet been
255 * reported in an XLOG_XACT_ASSIGNMENT record.
256 */
259
261
262/*
263 * The subtransaction ID and command ID assignment counters are global
264 * to a whole transaction, so we do not keep them in the state stack.
265 */
269
270/*
271 * xactStartTimestamp is the value of transaction_timestamp().
272 * stmtStartTimestamp is the value of statement_timestamp().
273 * xactStopTimestamp is the time at which we log a commit / abort WAL record,
274 * or if that was skipped, the time of the first subsequent
275 * GetCurrentTransactionStopTimestamp() call.
276 *
277 * These do not change as we enter and exit subtransactions, so we don't
278 * keep them inside the TransactionState stack.
279 */
283
284/*
285 * GID to be used for preparing the current transaction. This is also
286 * global to a whole transaction, so we don't keep it in the state stack.
287 */
288static char *prepareGID;
289
290/*
291 * Some commands want to force synchronous commit.
292 */
293static bool forceSyncCommit = false;
294
295/* Flag for logging statements in a transaction. */
296bool xact_is_sampled = false;
297
298/*
299 * Private context for transaction-abort work --- we reserve space for this
300 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
301 * when we've run out of memory.
302 */
304
305/*
306 * List of add-on start- and end-of-xact callbacks
307 */
308typedef struct XactCallbackItem
309{
312 void *arg;
314
316
317/*
318 * List of add-on start- and end-of-subxact callbacks
319 */
321{
324 void *arg;
326
328
329
330/* local function prototypes */
332static void AbortTransaction(void);
333static void AtAbort_Memory(void);
334static void AtCleanup_Memory(void);
335static void AtAbort_ResourceOwner(void);
336static void AtCCI_LocalCache(void);
337static void AtCommit_Memory(void);
338static void AtStart_Cache(void);
339static void AtStart_Memory(void);
340static void AtStart_ResourceOwner(void);
341static void CallXactCallbacks(XactEvent event);
342static void CallSubXactCallbacks(SubXactEvent event,
343 SubTransactionId mySubid,
344 SubTransactionId parentSubid);
345static void CleanupTransaction(void);
346static void CheckTransactionBlock(bool isTopLevel, bool throwError,
347 const char *stmtType);
348static void CommitTransaction(void);
349static TransactionId RecordTransactionAbort(bool isSubXact);
350static void StartTransaction(void);
351
352static bool CommitTransactionCommandInternal(void);
353static bool AbortCurrentTransactionInternal(void);
354
355static void StartSubTransaction(void);
356static void CommitSubTransaction(void);
357static void AbortSubTransaction(void);
358static void CleanupSubTransaction(void);
359static void PushTransaction(void);
360static void PopTransaction(void);
361
362static void AtSubAbort_Memory(void);
363static void AtSubCleanup_Memory(void);
364static void AtSubAbort_ResourceOwner(void);
365static void AtSubCommit_Memory(void);
366static void AtSubStart_Memory(void);
367static void AtSubStart_ResourceOwner(void);
368
369static void ShowTransactionState(const char *str);
370static void ShowTransactionStateRec(const char *str, TransactionState s);
371static const char *BlockStateAsString(TBlockState blockState);
372static const char *TransStateAsString(TransState state);
373
374
375/* ----------------------------------------------------------------
376 * transaction state accessors
377 * ----------------------------------------------------------------
378 */
379
380/*
381 * IsTransactionState
382 *
383 * This returns true if we are inside a valid transaction; that is,
384 * it is safe to initiate database access, take heavyweight locks, etc.
385 */
386bool
388{
390
391 /*
392 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
393 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
394 * TRANS_PREPARE since it might be too soon or too late within those
395 * transition states to do anything interesting. Hence, the only "valid"
396 * state is TRANS_INPROGRESS.
397 */
398 return (s->state == TRANS_INPROGRESS);
399}
400
401/*
402 * IsAbortedTransactionBlockState
403 *
404 * This returns true if we are within an aborted transaction block.
405 */
406bool
408{
410
411 if (s->blockState == TBLOCK_ABORT ||
413 return true;
414
415 return false;
416}
417
418
419/*
420 * GetTopTransactionId
421 *
422 * This will return the XID of the main transaction, assigning one if
423 * it's not yet set. Be careful to call this only inside a valid xact.
424 */
427{
431}
432
433/*
434 * GetTopTransactionIdIfAny
435 *
436 * This will return the XID of the main transaction, if one is assigned.
437 * It will return InvalidTransactionId if we are not currently inside a
438 * transaction, or inside a transaction that hasn't yet been assigned an XID.
439 */
442{
444}
445
446/*
447 * GetCurrentTransactionId
448 *
449 * This will return the XID of the current transaction (main or sub
450 * transaction), assigning one if it's not yet set. Be careful to call this
451 * only inside a valid xact.
452 */
455{
457
461}
462
463/*
464 * GetCurrentTransactionIdIfAny
465 *
466 * This will return the XID of the current sub xact, if one is assigned.
467 * It will return InvalidTransactionId if we are not currently inside a
468 * transaction, or inside a transaction that hasn't been assigned an XID yet.
469 */
472{
474}
475
476/*
477 * GetTopFullTransactionId
478 *
479 * This will return the FullTransactionId of the main transaction, assigning
480 * one if it's not yet set. Be careful to call this only inside a valid xact.
481 */
484{
488}
489
490/*
491 * GetTopFullTransactionIdIfAny
492 *
493 * This will return the FullTransactionId of the main transaction, if one is
494 * assigned. It will return InvalidFullTransactionId if we are not currently
495 * inside a transaction, or inside a transaction that hasn't yet been assigned
496 * one.
497 */
500{
502}
503
504/*
505 * GetCurrentFullTransactionId
506 *
507 * This will return the FullTransactionId of the current transaction (main or
508 * sub transaction), assigning one if it's not yet set. Be careful to call
509 * this only inside a valid xact.
510 */
513{
515
518 return s->fullTransactionId;
519}
520
521/*
522 * GetCurrentFullTransactionIdIfAny
523 *
524 * This will return the FullTransactionId of the current sub xact, if one is
525 * assigned. It will return InvalidFullTransactionId if we are not currently
526 * inside a transaction, or inside a transaction that hasn't been assigned one
527 * yet.
528 */
531{
533}
534
535/*
536 * MarkCurrentTransactionIdLoggedIfAny
537 *
538 * Remember that the current xid - if it is assigned - now has been wal logged.
539 */
540void
542{
545}
546
547/*
548 * IsSubxactTopXidLogPending
549 *
550 * This is used to decide whether we need to WAL log the top-level XID for
551 * operation in a subtransaction. We require that for logical decoding, see
552 * LogicalDecodingProcessRecord.
553 *
554 * This returns true if wal_level >= logical and we are inside a valid
555 * subtransaction, for which the assignment was not yet written to any WAL
556 * record.
557 */
558bool
560{
561 /* check whether it is already logged */
563 return false;
564
565 /* wal_level has to be logical */
567 return false;
568
569 /* we need to be in a transaction state */
570 if (!IsTransactionState())
571 return false;
572
573 /* it has to be a subtransaction */
574 if (!IsSubTransaction())
575 return false;
576
577 /* the subtransaction has to have a XID assigned */
579 return false;
580
581 return true;
582}
583
584/*
585 * MarkSubxactTopXidLogged
586 *
587 * Remember that the top transaction id for the current subtransaction is WAL
588 * logged now.
589 */
590void
592{
594
596}
597
598/*
599 * GetStableLatestTransactionId
600 *
601 * Get the transaction's XID if it has one, else read the next-to-be-assigned
602 * XID. Once we have a value, return that same value for the remainder of the
603 * current transaction. This is meant to provide the reference point for the
604 * age(xid) function, but might be useful for other maintenance tasks as well.
605 */
608{
610 static TransactionId stablexid = InvalidTransactionId;
611
612 if (lxid != MyProc->vxid.lxid)
613 {
614 lxid = MyProc->vxid.lxid;
615 stablexid = GetTopTransactionIdIfAny();
616 if (!TransactionIdIsValid(stablexid))
617 stablexid = ReadNextTransactionId();
618 }
619
620 Assert(TransactionIdIsValid(stablexid));
621
622 return stablexid;
623}
624
625/*
626 * AssignTransactionId
627 *
628 * Assigns a new permanent FullTransactionId to the given TransactionState.
629 * We do not assign XIDs to transactions until/unless this is called.
630 * Also, any parent TransactionStates that don't yet have XIDs are assigned
631 * one; this maintains the invariant that a child transaction has an XID
632 * following its parent's.
633 */
634static void
636{
637 bool isSubXact = (s->parent != NULL);
638 ResourceOwner currentOwner;
639 bool log_unknown_top = false;
640
641 /* Assert that caller didn't screw up */
644
645 /*
646 * Workers synchronize transaction state at the beginning of each parallel
647 * operation, so we can't account for new XIDs at this point.
648 */
651 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
652 errmsg("cannot assign transaction IDs during a parallel operation")));
653
654 /*
655 * Ensure parent(s) have XIDs, so that a child always has an XID later
656 * than its parent. Mustn't recurse here, or we might get a stack
657 * overflow if we're at the bottom of a huge stack of subtransactions none
658 * of which have XIDs yet.
659 */
661 {
663 TransactionState *parents;
664 size_t parentOffset = 0;
665
666 parents = palloc(sizeof(TransactionState) * s->nestingLevel);
667 while (p != NULL && !FullTransactionIdIsValid(p->fullTransactionId))
668 {
669 parents[parentOffset++] = p;
670 p = p->parent;
671 }
672
673 /*
674 * This is technically a recursive call, but the recursion will never
675 * be more than one layer deep.
676 */
677 while (parentOffset != 0)
678 AssignTransactionId(parents[--parentOffset]);
679
680 pfree(parents);
681 }
682
683 /*
684 * When wal_level=logical, guarantee that a subtransaction's xid can only
685 * be seen in the WAL stream if its toplevel xid has been logged before.
686 * If necessary we log an xact_assignment record with fewer than
687 * PGPROC_MAX_CACHED_SUBXIDS. Note that it is fine if didLogXid isn't set
688 * for a transaction even though it appears in a WAL record, we just might
689 * superfluously log something. That can happen when an xid is included
690 * somewhere inside a wal record, but not in XLogRecord->xl_xid, like in
691 * xl_standby_locks.
692 */
693 if (isSubXact && XLogLogicalInfoActive() &&
695 log_unknown_top = true;
696
697 /*
698 * Generate a new FullTransactionId and record its xid in PGPROC and
699 * pg_subtrans.
700 *
701 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
702 * shared storage other than PGPROC; because if there's no room for it in
703 * PGPROC, the subtrans entry is needed to ensure that other backends see
704 * the Xid as "running". See GetNewTransactionId.
705 */
707 if (!isSubXact)
709
710 if (isSubXact)
713
714 /*
715 * If it's a top-level transaction, the predicate locking system needs to
716 * be told about it too.
717 */
718 if (!isSubXact)
720
721 /*
722 * Acquire lock on the transaction XID. (We assume this cannot block.) We
723 * have to ensure that the lock is assigned to the transaction's own
724 * ResourceOwner.
725 */
726 currentOwner = CurrentResourceOwner;
728
730
731 CurrentResourceOwner = currentOwner;
732
733 /*
734 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
735 * top-level transaction we issue a WAL record for the assignment. We
736 * include the top-level xid and all the subxids that have not yet been
737 * reported using XLOG_XACT_ASSIGNMENT records.
738 *
739 * This is required to limit the amount of shared memory required in a hot
740 * standby server to keep track of in-progress XIDs. See notes for
741 * RecordKnownAssignedTransactionIds().
742 *
743 * We don't keep track of the immediate parent of each subxid, only the
744 * top-level transaction that each subxact belongs to. This is correct in
745 * recovery only because aborted subtransactions are separately WAL
746 * logged.
747 *
748 * This is correct even for the case where several levels above us didn't
749 * have an xid assigned as we recursed up to them beforehand.
750 */
751 if (isSubXact && XLogStandbyInfoActive())
752 {
755
756 /*
757 * ensure this test matches similar one in
758 * RecoverPreparedTransactions()
759 */
761 log_unknown_top)
762 {
763 xl_xact_assignment xlrec;
764
765 /*
766 * xtop is always set by now because we recurse up transaction
767 * stack to the highest unassigned xid and then come back down
768 */
769 xlrec.xtop = GetTopTransactionId();
772
777
778 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT);
779
780 nUnreportedXids = 0;
781 /* mark top, not current xact as having been logged */
783 }
784 }
785}
786
787/*
788 * GetCurrentSubTransactionId
789 */
792{
794
795 return s->subTransactionId;
796}
797
798/*
799 * SubTransactionIsActive
800 *
801 * Test if the specified subxact ID is still active. Note caller is
802 * responsible for checking whether this ID is relevant to the current xact.
803 */
804bool
806{
808
809 for (s = CurrentTransactionState; s != NULL; s = s->parent)
810 {
811 if (s->state == TRANS_ABORT)
812 continue;
813 if (s->subTransactionId == subxid)
814 return true;
815 }
816 return false;
817}
818
819
820/*
821 * GetCurrentCommandId
822 *
823 * "used" must be true if the caller intends to use the command ID to mark
824 * inserted/updated/deleted tuples. false means the ID is being fetched
825 * for read-only purposes (ie, as a snapshot validity cutoff). See
826 * CommandCounterIncrement() for discussion.
827 */
830{
831 /* this is global to a transaction, not subtransaction-local */
832 if (used)
833 {
834 /*
835 * Forbid setting currentCommandIdUsed in a parallel worker, because
836 * we have no provision for communicating this back to the leader. We
837 * could relax this restriction when currentCommandIdUsed was already
838 * true at the start of the parallel operation.
839 */
840 if (IsParallelWorker())
842 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
843 errmsg("cannot modify data in a parallel worker")));
844
846 }
847 return currentCommandId;
848}
849
850/*
851 * SetParallelStartTimestamps
852 *
853 * In a parallel worker, we should inherit the parent transaction's
854 * timestamps rather than setting our own. The parallel worker
855 * infrastructure must call this to provide those values before
856 * calling StartTransaction() or SetCurrentStatementStartTimestamp().
857 */
858void
860{
862 xactStartTimestamp = xact_ts;
863 stmtStartTimestamp = stmt_ts;
864}
865
866/*
867 * GetCurrentTransactionStartTimestamp
868 */
871{
872 return xactStartTimestamp;
873}
874
875/*
876 * GetCurrentStatementStartTimestamp
877 */
880{
881 return stmtStartTimestamp;
882}
883
884/*
885 * GetCurrentTransactionStopTimestamp
886 *
887 * If the transaction stop time hasn't already been set, which can happen if
888 * we decided we don't need to log an XLOG record, set xactStopTimestamp.
889 */
892{
894
895 /* should only be called after commit / abort processing */
896 Assert(s->state == TRANS_DEFAULT ||
897 s->state == TRANS_COMMIT ||
898 s->state == TRANS_ABORT ||
899 s->state == TRANS_PREPARE);
900
901 if (xactStopTimestamp == 0)
903
904 return xactStopTimestamp;
905}
906
907/*
908 * SetCurrentStatementStartTimestamp
909 *
910 * In a parallel worker, this should already have been provided by a call
911 * to SetParallelStartTimestamps().
912 */
913void
915{
916 if (!IsParallelWorker())
918 else
920}
921
922/*
923 * GetCurrentTransactionNestLevel
924 *
925 * Note: this will return zero when not inside any transaction, one when
926 * inside a top-level transaction, etc.
927 */
928int
930{
932
933 return s->nestingLevel;
934}
935
936
937/*
938 * TransactionIdIsCurrentTransactionId
939 */
940bool
942{
944
945 /*
946 * We always say that BootstrapTransactionId is "not my transaction ID"
947 * even when it is (ie, during bootstrap). Along with the fact that
948 * transam.c always treats BootstrapTransactionId as already committed,
949 * this causes the heapam_visibility.c routines to see all tuples as
950 * committed, which is what we need during bootstrap. (Bootstrap mode
951 * only inserts tuples, it never updates or deletes them, so all tuples
952 * can be presumed good immediately.)
953 *
954 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
955 * not my transaction ID, so we can just return "false" immediately for
956 * any non-normal XID.
957 */
958 if (!TransactionIdIsNormal(xid))
959 return false;
960
962 return true;
963
964 /*
965 * In parallel workers, the XIDs we must consider as current are stored in
966 * ParallelCurrentXids rather than the transaction-state stack. Note that
967 * the XIDs in this array are sorted numerically rather than according to
968 * transactionIdPrecedes order.
969 */
970 if (nParallelCurrentXids > 0)
971 {
972 int low,
973 high;
974
975 low = 0;
976 high = nParallelCurrentXids - 1;
977 while (low <= high)
978 {
979 int middle;
980 TransactionId probe;
981
982 middle = low + (high - low) / 2;
983 probe = ParallelCurrentXids[middle];
984 if (probe == xid)
985 return true;
986 else if (probe < xid)
987 low = middle + 1;
988 else
989 high = middle - 1;
990 }
991 return false;
992 }
993
994 /*
995 * We will return true for the Xid of the current subtransaction, any of
996 * its subcommitted children, any of its parents, or any of their
997 * previously subcommitted children. However, a transaction being aborted
998 * is no longer "current", even though it may still have an entry on the
999 * state stack.
1000 */
1001 for (s = CurrentTransactionState; s != NULL; s = s->parent)
1002 {
1003 int low,
1004 high;
1005
1006 if (s->state == TRANS_ABORT)
1007 continue;
1009 continue; /* it can't have any child XIDs either */
1011 return true;
1012 /* As the childXids array is ordered, we can use binary search */
1013 low = 0;
1014 high = s->nChildXids - 1;
1015 while (low <= high)
1016 {
1017 int middle;
1018 TransactionId probe;
1019
1020 middle = low + (high - low) / 2;
1021 probe = s->childXids[middle];
1022 if (TransactionIdEquals(probe, xid))
1023 return true;
1024 else if (TransactionIdPrecedes(probe, xid))
1025 low = middle + 1;
1026 else
1027 high = middle - 1;
1028 }
1029 }
1030
1031 return false;
1032}
1033
1034/*
1035 * TransactionStartedDuringRecovery
1036 *
1037 * Returns true if the current transaction started while recovery was still
1038 * in progress. Recovery might have ended since so RecoveryInProgress() might
1039 * return false already.
1040 */
1041bool
1043{
1045}
1046
1047/*
1048 * EnterParallelMode
1049 */
1050void
1052{
1054
1055 Assert(s->parallelModeLevel >= 0);
1056
1057 ++s->parallelModeLevel;
1058}
1059
1060/*
1061 * ExitParallelMode
1062 */
1063void
1065{
1067
1068 Assert(s->parallelModeLevel > 0);
1071
1072 --s->parallelModeLevel;
1073}
1074
1075/*
1076 * IsInParallelMode
1077 *
1078 * Are we in a parallel operation, as either the leader or a worker? Check
1079 * this to prohibit operations that change backend-local state expected to
1080 * match across all workers. Mere caches usually don't require such a
1081 * restriction. State modified in a strict push/pop fashion, such as the
1082 * active snapshot stack, is often fine.
1083 *
1084 * We say we are in parallel mode if we are in a subxact of a transaction
1085 * that's initiated a parallel operation; for most purposes that context
1086 * has all the same restrictions.
1087 */
1088bool
1090{
1092
1093 return s->parallelModeLevel != 0 || s->parallelChildXact;
1094}
1095
1096/*
1097 * CommandCounterIncrement
1098 */
1099void
1101{
1102 /*
1103 * If the current value of the command counter hasn't been "used" to mark
1104 * tuples, we need not increment it, since there's no need to distinguish
1105 * a read-only command from others. This helps postpone command counter
1106 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
1107 */
1109 {
1110 /*
1111 * Workers synchronize transaction state at the beginning of each
1112 * parallel operation, so we can't account for new commands after that
1113 * point.
1114 */
1116 ereport(ERROR,
1117 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
1118 errmsg("cannot start commands during a parallel operation")));
1119
1120 currentCommandId += 1;
1122 {
1123 currentCommandId -= 1;
1124 ereport(ERROR,
1125 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1126 errmsg("cannot have more than 2^32-2 commands in a transaction")));
1127 }
1128 currentCommandIdUsed = false;
1129
1130 /* Propagate new command ID into static snapshots */
1132
1133 /*
1134 * Make any catalog changes done by the just-completed command visible
1135 * in the local syscache. We obviously don't need to do this after a
1136 * read-only command. (But see hacks in inval.c to make real sure we
1137 * don't think a command that queued inval messages was read-only.)
1138 */
1140 }
1141}
1142
1143/*
1144 * ForceSyncCommit
1145 *
1146 * Interface routine to allow commands to force a synchronous commit of the
1147 * current top-level transaction. Currently, two-phase commit does not
1148 * persist and restore this variable. So long as all callers use
1149 * PreventInTransactionBlock(), that omission has no consequences.
1150 */
1151void
1153{
1154 forceSyncCommit = true;
1155}
1156
1157
1158/* ----------------------------------------------------------------
1159 * StartTransaction stuff
1160 * ----------------------------------------------------------------
1161 */
1162
1163/*
1164 * AtStart_Cache
1165 */
1166static void
1168{
1170}
1171
1172/*
1173 * AtStart_Memory
1174 */
1175static void
1177{
1179
1180 /*
1181 * Remember the memory context that was active prior to transaction start.
1182 */
1184
1185 /*
1186 * If this is the first time through, create a private context for
1187 * AbortTransaction to work in. By reserving some space now, we can
1188 * insulate AbortTransaction from out-of-memory scenarios. Like
1189 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1190 * size, so that space will be reserved immediately.
1191 */
1192 if (TransactionAbortContext == NULL)
1195 "TransactionAbortContext",
1196 32 * 1024,
1197 32 * 1024,
1198 32 * 1024);
1199
1200 /*
1201 * Likewise, if this is the first time through, create a top-level context
1202 * for transaction-local data. This context will be reset at transaction
1203 * end, and then re-used in later transactions.
1204 */
1205 if (TopTransactionContext == NULL)
1208 "TopTransactionContext",
1210
1211 /*
1212 * In a top-level transaction, CurTransactionContext is the same as
1213 * TopTransactionContext.
1214 */
1217
1218 /* Make the CurTransactionContext active. */
1220}
1221
1222/*
1223 * AtStart_ResourceOwner
1224 */
1225static void
1227{
1229
1230 /*
1231 * We shouldn't have a transaction resource owner already.
1232 */
1234
1235 /*
1236 * Create a toplevel resource owner for the transaction.
1237 */
1238 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1239
1243}
1244
1245/* ----------------------------------------------------------------
1246 * StartSubTransaction stuff
1247 * ----------------------------------------------------------------
1248 */
1249
1250/*
1251 * AtSubStart_Memory
1252 */
1253static void
1255{
1257
1259
1260 /*
1261 * Remember the context that was active prior to subtransaction start.
1262 */
1264
1265 /*
1266 * Create a CurTransactionContext, which will be used to hold data that
1267 * survives subtransaction commit but disappears on subtransaction abort.
1268 * We make it a child of the immediate parent's CurTransactionContext.
1269 */
1271 "CurTransactionContext",
1274
1275 /* Make the CurTransactionContext active. */
1277}
1278
1279/*
1280 * AtSubStart_ResourceOwner
1281 */
1282static void
1284{
1286
1287 Assert(s->parent != NULL);
1288
1289 /*
1290 * Create a resource owner for the subtransaction. We make it a child of
1291 * the immediate parent's resource owner.
1292 */
1295 "SubTransaction");
1296
1299}
1300
1301/* ----------------------------------------------------------------
1302 * CommitTransaction stuff
1303 * ----------------------------------------------------------------
1304 */
1305
1306/*
1307 * RecordTransactionCommit
1308 *
1309 * Returns latest XID among xact and its children, or InvalidTransactionId
1310 * if the xact has no XID. (We compute that here just because it's easier.)
1311 *
1312 * If you change this function, see RecordTransactionCommitPrepared also.
1313 */
1314static TransactionId
1316{
1318 bool markXidCommitted = TransactionIdIsValid(xid);
1320 int nrels;
1321 RelFileLocator *rels;
1322 int nchildren;
1323 TransactionId *children;
1324 int ndroppedstats = 0;
1325 xl_xact_stats_item *droppedstats = NULL;
1326 int nmsgs = 0;
1327 SharedInvalidationMessage *invalMessages = NULL;
1328 bool RelcacheInitFileInval = false;
1329 bool wrote_xlog;
1330
1331 /*
1332 * Log pending invalidations for logical decoding of in-progress
1333 * transactions. Normally for DDLs, we log this at each command end,
1334 * however, for certain cases where we directly update the system table
1335 * without a transaction block, the invalidations are not logged till this
1336 * time.
1337 */
1340
1341 /* Get data needed for commit record */
1342 nrels = smgrGetPendingDeletes(true, &rels);
1343 nchildren = xactGetCommittedChildren(&children);
1344 ndroppedstats = pgstat_get_transactional_drops(true, &droppedstats);
1346 nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
1347 &RelcacheInitFileInval);
1348 wrote_xlog = (XactLastRecEnd != 0);
1349
1350 /*
1351 * If we haven't been assigned an XID yet, we neither can, nor do we want
1352 * to write a COMMIT record.
1353 */
1354 if (!markXidCommitted)
1355 {
1356 /*
1357 * We expect that every RelationDropStorage is followed by a catalog
1358 * update, and hence XID assignment, so we shouldn't get here with any
1359 * pending deletes. Same is true for dropping stats.
1360 *
1361 * Use a real test not just an Assert to check this, since it's a bit
1362 * fragile.
1363 */
1364 if (nrels != 0 || ndroppedstats != 0)
1365 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
1366
1367 /* Can't have child XIDs either; AssignTransactionId enforces this */
1368 Assert(nchildren == 0);
1369
1370 /*
1371 * Transactions without an assigned xid can contain invalidation
1372 * messages. While inplace updates do this, this is not known to be
1373 * necessary; see comment at inplace CacheInvalidateHeapTuple().
1374 * Extensions might still rely on this capability, and standbys may
1375 * need to process those invals. We can't emit a commit record
1376 * without an xid, and we don't want to force assigning an xid,
1377 * because that'd be problematic for e.g. vacuum. Hence we emit a
1378 * bespoke record for the invalidations. We don't want to use that in
1379 * case a commit record is emitted, so they happen synchronously with
1380 * commits (besides not wanting to emit more WAL records).
1381 *
1382 * XXX Every known use of this capability is a defect. Since an XID
1383 * isn't controlling visibility of the change that prompted invals,
1384 * other sessions need the inval even if this transactions aborts.
1385 *
1386 * ON COMMIT DELETE ROWS does a nontransactional index_build(), which
1387 * queues a relcache inval, including in transactions without an xid
1388 * that had read the (empty) table. Standbys don't need any ON COMMIT
1389 * DELETE ROWS invals, but we've not done the work to withhold them.
1390 */
1391 if (nmsgs != 0)
1392 {
1393 LogStandbyInvalidations(nmsgs, invalMessages,
1394 RelcacheInitFileInval);
1395 wrote_xlog = true; /* not strictly necessary */
1396 }
1397
1398 /*
1399 * If we didn't create XLOG entries, we're done here; otherwise we
1400 * should trigger flushing those entries the same as a commit record
1401 * would. This will primarily happen for HOT pruning and the like; we
1402 * want these to be flushed to disk in due time.
1403 */
1404 if (!wrote_xlog)
1405 goto cleanup;
1406 }
1407 else
1408 {
1409 bool replorigin;
1410
1411 /*
1412 * Are we using the replication origins feature? Or, in other words,
1413 * are we replaying remote actions?
1414 */
1417
1418 /*
1419 * Mark ourselves as within our "commit critical section". This
1420 * forces any concurrent checkpoint to wait until we've updated
1421 * pg_xact. Without this, it is possible for the checkpoint to set
1422 * REDO after the XLOG record but fail to flush the pg_xact update to
1423 * disk, leading to loss of the transaction commit if the system
1424 * crashes a little later.
1425 *
1426 * Note: we could, but don't bother to, set this flag in
1427 * RecordTransactionAbort. That's because loss of a transaction abort
1428 * is noncritical; the presumption would be that it aborted, anyway.
1429 *
1430 * It's safe to change the delayChkptFlags flag of our own backend
1431 * without holding the ProcArrayLock, since we're the only one
1432 * modifying it. This makes checkpoint's determination of which xacts
1433 * are delaying the checkpoint a bit fuzzy, but it doesn't matter.
1434 */
1438
1439 /*
1440 * Insert the commit XLOG record.
1441 */
1443 nchildren, children, nrels, rels,
1444 ndroppedstats, droppedstats,
1445 nmsgs, invalMessages,
1446 RelcacheInitFileInval,
1448 InvalidTransactionId, NULL /* plain commit */ );
1449
1450 if (replorigin)
1451 /* Move LSNs forward for this replication origin */
1454
1455 /*
1456 * Record commit timestamp. The value comes from plain commit
1457 * timestamp if there's no replication origin; otherwise, the
1458 * timestamp was already set in replorigin_session_origin_timestamp by
1459 * replication.
1460 *
1461 * We don't need to WAL-log anything here, as the commit record
1462 * written above already contains the data.
1463 */
1464
1465 if (!replorigin || replorigin_session_origin_timestamp == 0)
1467
1468 TransactionTreeSetCommitTsData(xid, nchildren, children,
1471 }
1472
1473 /*
1474 * Check if we want to commit asynchronously. We can allow the XLOG flush
1475 * to happen asynchronously if synchronous_commit=off, or if the current
1476 * transaction has not performed any WAL-logged operation or didn't assign
1477 * an xid. The transaction can end up not writing any WAL, even if it has
1478 * an xid, if it only wrote to temporary and/or unlogged tables. It can
1479 * end up having written WAL without an xid if it did HOT pruning. In
1480 * case of a crash, the loss of such a transaction will be irrelevant;
1481 * temp tables will be lost anyway, unlogged tables will be truncated and
1482 * HOT pruning will be done again later. (Given the foregoing, you might
1483 * think that it would be unnecessary to emit the XLOG record at all in
1484 * this case, but we don't currently try to do that. It would certainly
1485 * cause problems at least in Hot Standby mode, where the
1486 * KnownAssignedXids machinery requires tracking every XID assignment. It
1487 * might be OK to skip it only when wal_level < replica, but for now we
1488 * don't.)
1489 *
1490 * However, if we're doing cleanup of any non-temp rels or committing any
1491 * command that wanted to force sync commit, then we must flush XLOG
1492 * immediately. (We must not allow asynchronous commit if there are any
1493 * non-temp tables to be deleted, because we might delete the files before
1494 * the COMMIT record is flushed to disk. We do allow asynchronous commit
1495 * if all to-be-deleted tables are temporary though, since they are lost
1496 * anyway if we crash.)
1497 */
1498 if ((wrote_xlog && markXidCommitted &&
1500 forceSyncCommit || nrels > 0)
1501 {
1503
1504 /*
1505 * Now we may update the CLOG, if we wrote a COMMIT record above
1506 */
1507 if (markXidCommitted)
1508 TransactionIdCommitTree(xid, nchildren, children);
1509 }
1510 else
1511 {
1512 /*
1513 * Asynchronous commit case:
1514 *
1515 * This enables possible committed transaction loss in the case of a
1516 * postmaster crash because WAL buffers are left unwritten. Ideally we
1517 * could issue the WAL write without the fsync, but some
1518 * wal_sync_methods do not allow separate write/fsync.
1519 *
1520 * Report the latest async commit LSN, so that the WAL writer knows to
1521 * flush this commit.
1522 */
1524
1525 /*
1526 * We must not immediately update the CLOG, since we didn't flush the
1527 * XLOG. Instead, we store the LSN up to which the XLOG must be
1528 * flushed before the CLOG may be updated.
1529 */
1530 if (markXidCommitted)
1531 TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1532 }
1533
1534 /*
1535 * If we entered a commit critical section, leave it now, and let
1536 * checkpoints proceed.
1537 */
1538 if (markXidCommitted)
1539 {
1540 MyProc->delayChkptFlags &= ~DELAY_CHKPT_START;
1542 }
1543
1544 /* Compute latestXid while we have the child XIDs handy */
1545 latestXid = TransactionIdLatest(xid, nchildren, children);
1546
1547 /*
1548 * Wait for synchronous replication, if required. Similar to the decision
1549 * above about using committing asynchronously we only want to wait if
1550 * this backend assigned an xid and wrote WAL. No need to wait if an xid
1551 * was assigned due to temporary/unlogged tables or due to HOT pruning.
1552 *
1553 * Note that at this stage we have marked clog, but still show as running
1554 * in the procarray and continue to hold locks.
1555 */
1556 if (wrote_xlog && markXidCommitted)
1558
1559 /* remember end of last commit record */
1561
1562 /* Reset XactLastRecEnd until the next transaction writes something */
1563 XactLastRecEnd = 0;
1564cleanup:
1565 /* Clean up local data */
1566 if (rels)
1567 pfree(rels);
1568 if (ndroppedstats)
1569 pfree(droppedstats);
1570
1571 return latestXid;
1572}
1573
1574
1575/*
1576 * AtCCI_LocalCache
1577 */
1578static void
1580{
1581 /*
1582 * Make any pending relation map changes visible. We must do this before
1583 * processing local sinval messages, so that the map changes will get
1584 * reflected into the relcache when relcache invals are processed.
1585 */
1587
1588 /*
1589 * Make catalog changes visible to me for the next command.
1590 */
1592}
1593
1594/*
1595 * AtCommit_Memory
1596 */
1597static void
1599{
1601
1602 /*
1603 * Return to the memory context that was current before we started the
1604 * transaction. (In principle, this could not be any of the contexts we
1605 * are about to delete. If it somehow is, assertions in mcxt.c will
1606 * complain.)
1607 */
1609
1610 /*
1611 * Release all transaction-local memory. TopTransactionContext survives
1612 * but becomes empty; any sub-contexts go away.
1613 */
1616
1617 /*
1618 * Clear these pointers as a pro-forma matter. (Notionally, while
1619 * TopTransactionContext still exists, it's currently not associated with
1620 * this TransactionState struct.)
1621 */
1622 CurTransactionContext = NULL;
1623 s->curTransactionContext = NULL;
1624}
1625
1626/* ----------------------------------------------------------------
1627 * CommitSubTransaction stuff
1628 * ----------------------------------------------------------------
1629 */
1630
1631/*
1632 * AtSubCommit_Memory
1633 */
1634static void
1636{
1638
1639 Assert(s->parent != NULL);
1640
1641 /* Return to parent transaction level's memory context. */
1644
1645 /*
1646 * Ordinarily we cannot throw away the child's CurTransactionContext,
1647 * since the data it contains will be needed at upper commit. However, if
1648 * there isn't actually anything in it, we can throw it away. This avoids
1649 * a small memory leak in the common case of "trivial" subxacts.
1650 */
1652 {
1654 s->curTransactionContext = NULL;
1655 }
1656}
1657
1658/*
1659 * AtSubCommit_childXids
1660 *
1661 * Pass my own XID and my child XIDs up to my parent as committed children.
1662 */
1663static void
1665{
1667 int new_nChildXids;
1668
1669 Assert(s->parent != NULL);
1670
1671 /*
1672 * The parent childXids array will need to hold my XID and all my
1673 * childXids, in addition to the XIDs already there.
1674 */
1675 new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1676
1677 /* Allocate or enlarge the parent array if necessary */
1678 if (s->parent->maxChildXids < new_nChildXids)
1679 {
1680 int new_maxChildXids;
1681 TransactionId *new_childXids;
1682
1683 /*
1684 * Make it 2x what's needed right now, to avoid having to enlarge it
1685 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1686 * is what ensures that we don't need to worry about integer overflow
1687 * here or in the calculation of new_nChildXids.)
1688 */
1689 new_maxChildXids = Min(new_nChildXids * 2,
1690 (int) (MaxAllocSize / sizeof(TransactionId)));
1691
1692 if (new_maxChildXids < new_nChildXids)
1693 ereport(ERROR,
1694 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1695 errmsg("maximum number of committed subtransactions (%d) exceeded",
1696 (int) (MaxAllocSize / sizeof(TransactionId)))));
1697
1698 /*
1699 * We keep the child-XID arrays in TopTransactionContext; this avoids
1700 * setting up child-transaction contexts for what might be just a few
1701 * bytes of grandchild XIDs.
1702 */
1703 if (s->parent->childXids == NULL)
1704 new_childXids =
1706 new_maxChildXids * sizeof(TransactionId));
1707 else
1708 new_childXids = repalloc(s->parent->childXids,
1709 new_maxChildXids * sizeof(TransactionId));
1710
1711 s->parent->childXids = new_childXids;
1712 s->parent->maxChildXids = new_maxChildXids;
1713 }
1714
1715 /*
1716 * Copy all my XIDs to parent's array.
1717 *
1718 * Note: We rely on the fact that the XID of a child always follows that
1719 * of its parent. By copying the XID of this subtransaction before the
1720 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1721 * all XIDs already in the array belong to subtransactions started and
1722 * subcommitted before us, so their XIDs must precede ours.
1723 */
1725
1726 if (s->nChildXids > 0)
1727 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1728 s->childXids,
1729 s->nChildXids * sizeof(TransactionId));
1730
1731 s->parent->nChildXids = new_nChildXids;
1732
1733 /* Release child's array to avoid leakage */
1734 if (s->childXids != NULL)
1735 pfree(s->childXids);
1736 /* We must reset these to avoid double-free if fail later in commit */
1737 s->childXids = NULL;
1738 s->nChildXids = 0;
1739 s->maxChildXids = 0;
1740}
1741
1742/* ----------------------------------------------------------------
1743 * AbortTransaction stuff
1744 * ----------------------------------------------------------------
1745 */
1746
1747/*
1748 * RecordTransactionAbort
1749 *
1750 * Returns latest XID among xact and its children, or InvalidTransactionId
1751 * if the xact has no XID. (We compute that here just because it's easier.)
1752 */
1753static TransactionId
1755{
1757 TransactionId latestXid;
1758 int nrels;
1759 RelFileLocator *rels;
1760 int ndroppedstats = 0;
1761 xl_xact_stats_item *droppedstats = NULL;
1762 int nchildren;
1763 TransactionId *children;
1764 TimestampTz xact_time;
1765 bool replorigin;
1766
1767 /*
1768 * If we haven't been assigned an XID, nobody will care whether we aborted
1769 * or not. Hence, we're done in that case. It does not matter if we have
1770 * rels to delete (note that this routine is not responsible for actually
1771 * deleting 'em). We cannot have any child XIDs, either.
1772 */
1773 if (!TransactionIdIsValid(xid))
1774 {
1775 /* Reset XactLastRecEnd until the next transaction writes something */
1776 if (!isSubXact)
1777 XactLastRecEnd = 0;
1778 return InvalidTransactionId;
1779 }
1780
1781 /*
1782 * We have a valid XID, so we should write an ABORT record for it.
1783 *
1784 * We do not flush XLOG to disk here, since the default assumption after a
1785 * crash would be that we aborted, anyway. For the same reason, we don't
1786 * need to worry about interlocking against checkpoint start.
1787 */
1788
1789 /*
1790 * Check that we haven't aborted halfway through RecordTransactionCommit.
1791 */
1792 if (TransactionIdDidCommit(xid))
1793 elog(PANIC, "cannot abort transaction %u, it was already committed",
1794 xid);
1795
1796 /*
1797 * Are we using the replication origins feature? Or, in other words, are
1798 * we replaying remote actions?
1799 */
1802
1803 /* Fetch the data we need for the abort record */
1804 nrels = smgrGetPendingDeletes(false, &rels);
1805 nchildren = xactGetCommittedChildren(&children);
1806 ndroppedstats = pgstat_get_transactional_drops(false, &droppedstats);
1807
1808 /* XXX do we really need a critical section here? */
1810
1811 /* Write the ABORT record */
1812 if (isSubXact)
1813 xact_time = GetCurrentTimestamp();
1814 else
1815 {
1817 }
1818
1819 XactLogAbortRecord(xact_time,
1820 nchildren, children,
1821 nrels, rels,
1822 ndroppedstats, droppedstats,
1824 NULL);
1825
1826 if (replorigin)
1827 /* Move LSNs forward for this replication origin */
1830
1831 /*
1832 * Report the latest async abort LSN, so that the WAL writer knows to
1833 * flush this abort. There's nothing to be gained by delaying this, since
1834 * WALWriter may as well do this when it can. This is important with
1835 * streaming replication because if we don't flush WAL regularly we will
1836 * find that large aborts leave us with a long backlog for when commits
1837 * occur after the abort, increasing our window of data loss should
1838 * problems occur at that point.
1839 */
1840 if (!isSubXact)
1842
1843 /*
1844 * Mark the transaction aborted in clog. This is not absolutely necessary
1845 * but we may as well do it while we are here; also, in the subxact case
1846 * it is helpful because XactLockTableWait makes use of it to avoid
1847 * waiting for already-aborted subtransactions. It is OK to do it without
1848 * having flushed the ABORT record to disk, because in event of a crash
1849 * we'd be assumed to have aborted anyway.
1850 */
1851 TransactionIdAbortTree(xid, nchildren, children);
1852
1854
1855 /* Compute latestXid while we have the child XIDs handy */
1856 latestXid = TransactionIdLatest(xid, nchildren, children);
1857
1858 /*
1859 * If we're aborting a subtransaction, we can immediately remove failed
1860 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1861 * subxacts, because we already have the child XID array at hand. For
1862 * main xacts, the equivalent happens just after this function returns.
1863 */
1864 if (isSubXact)
1865 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1866
1867 /* Reset XactLastRecEnd until the next transaction writes something */
1868 if (!isSubXact)
1869 XactLastRecEnd = 0;
1870
1871 /* And clean up local data */
1872 if (rels)
1873 pfree(rels);
1874 if (ndroppedstats)
1875 pfree(droppedstats);
1876
1877 return latestXid;
1878}
1879
1880/*
1881 * AtAbort_Memory
1882 */
1883static void
1885{
1886 /*
1887 * Switch into TransactionAbortContext, which should have some free space
1888 * even if nothing else does. We'll work in this context until we've
1889 * finished cleaning up.
1890 *
1891 * It is barely possible to get here when we've not been able to create
1892 * TransactionAbortContext yet; if so use TopMemoryContext.
1893 */
1894 if (TransactionAbortContext != NULL)
1896 else
1898}
1899
1900/*
1901 * AtSubAbort_Memory
1902 */
1903static void
1905{
1907
1909}
1910
1911
1912/*
1913 * AtAbort_ResourceOwner
1914 */
1915static void
1917{
1918 /*
1919 * Make sure we have a valid ResourceOwner, if possible (else it will be
1920 * NULL, which is OK)
1921 */
1923}
1924
1925/*
1926 * AtSubAbort_ResourceOwner
1927 */
1928static void
1930{
1932
1933 /* Make sure we have a valid ResourceOwner */
1935}
1936
1937
1938/*
1939 * AtSubAbort_childXids
1940 */
1941static void
1943{
1945
1946 /*
1947 * We keep the child-XID arrays in TopTransactionContext (see
1948 * AtSubCommit_childXids). This means we'd better free the array
1949 * explicitly at abort to avoid leakage.
1950 */
1951 if (s->childXids != NULL)
1952 pfree(s->childXids);
1953 s->childXids = NULL;
1954 s->nChildXids = 0;
1955 s->maxChildXids = 0;
1956
1957 /*
1958 * We could prune the unreportedXids array here. But we don't bother. That
1959 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1960 * would likely introduce more CPU time into the more common paths, so we
1961 * choose not to do that.
1962 */
1963}
1964
1965/* ----------------------------------------------------------------
1966 * CleanupTransaction stuff
1967 * ----------------------------------------------------------------
1968 */
1969
1970/*
1971 * AtCleanup_Memory
1972 */
1973static void
1975{
1977
1978 /* Should be at top level */
1979 Assert(s->parent == NULL);
1980
1981 /*
1982 * Return to the memory context that was current before we started the
1983 * transaction. (In principle, this could not be any of the contexts we
1984 * are about to delete. If it somehow is, assertions in mcxt.c will
1985 * complain.)
1986 */
1988
1989 /*
1990 * Clear the special abort context for next time.
1991 */
1992 if (TransactionAbortContext != NULL)
1994
1995 /*
1996 * Release all transaction-local memory, the same as in AtCommit_Memory,
1997 * except we must cope with the possibility that we didn't get as far as
1998 * creating TopTransactionContext.
1999 */
2000 if (TopTransactionContext != NULL)
2002
2003 /*
2004 * Clear these pointers as a pro-forma matter. (Notionally, while
2005 * TopTransactionContext still exists, it's currently not associated with
2006 * this TransactionState struct.)
2007 */
2008 CurTransactionContext = NULL;
2009 s->curTransactionContext = NULL;
2010}
2011
2012
2013/* ----------------------------------------------------------------
2014 * CleanupSubTransaction stuff
2015 * ----------------------------------------------------------------
2016 */
2017
2018/*
2019 * AtSubCleanup_Memory
2020 */
2021static void
2023{
2025
2026 Assert(s->parent != NULL);
2027
2028 /*
2029 * Return to the memory context that was current before we started the
2030 * subtransaction. (In principle, this could not be any of the contexts
2031 * we are about to delete. If it somehow is, assertions in mcxt.c will
2032 * complain.)
2033 */
2035
2036 /* Update CurTransactionContext (might not be same as priorContext) */
2038
2039 /*
2040 * Clear the special abort context for next time.
2041 */
2042 if (TransactionAbortContext != NULL)
2044
2045 /*
2046 * Delete the subxact local memory contexts. Its CurTransactionContext can
2047 * go too (note this also kills CurTransactionContexts from any children
2048 * of the subxact).
2049 */
2050 if (s->curTransactionContext)
2052 s->curTransactionContext = NULL;
2053}
2054
2055/* ----------------------------------------------------------------
2056 * interface routines
2057 * ----------------------------------------------------------------
2058 */
2059
2060/*
2061 * StartTransaction
2062 */
2063static void
2065{
2068
2069 /*
2070 * Let's just make sure the state stack is empty
2071 */
2074
2076
2077 /* check the current transaction state */
2078 Assert(s->state == TRANS_DEFAULT);
2079
2080 /*
2081 * Set the current transaction state information appropriately during
2082 * start processing. Note that once the transaction status is switched
2083 * this process cannot fail until the user ID and the security context
2084 * flags are fetched below.
2085 */
2086 s->state = TRANS_START;
2087 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
2088
2089 /* Determine if statements are logged in this transaction */
2091 (log_xact_sample_rate == 1 ||
2093
2094 /*
2095 * initialize current transaction state fields
2096 *
2097 * note: prevXactReadOnly is not used at the outermost level
2098 */
2099 s->nestingLevel = 1;
2100 s->gucNestLevel = 1;
2101 s->childXids = NULL;
2102 s->nChildXids = 0;
2103 s->maxChildXids = 0;
2104
2105 /*
2106 * Once the current user ID and the security context flags are fetched,
2107 * both will be properly reset even if transaction startup fails.
2108 */
2110
2111 /* SecurityRestrictionContext should never be set outside a transaction */
2112 Assert(s->prevSecContext == 0);
2113
2114 /*
2115 * Make sure we've reset xact state variables
2116 *
2117 * If recovery is still in progress, mark this transaction as read-only.
2118 * We have lower level defences in XLogInsert and elsewhere to stop us
2119 * from modifying data during recovery, but this gives the normal
2120 * indication to the user that the transaction is read-only.
2121 */
2122 if (RecoveryInProgress())
2123 {
2124 s->startedInRecovery = true;
2125 XactReadOnly = true;
2126 }
2127 else
2128 {
2129 s->startedInRecovery = false;
2131 }
2134 forceSyncCommit = false;
2135 MyXactFlags = 0;
2136
2137 /*
2138 * reinitialize within-transaction counters
2139 */
2143 currentCommandIdUsed = false;
2144
2145 /*
2146 * initialize reported xid accounting
2147 */
2148 nUnreportedXids = 0;
2149 s->didLogXid = false;
2150
2151 /*
2152 * must initialize resource-management stuff first
2153 */
2156
2157 /*
2158 * Assign a new LocalTransactionId, and combine it with the proc number to
2159 * form a virtual transaction id.
2160 */
2161 vxid.procNumber = MyProcNumber;
2163
2164 /*
2165 * Lock the virtual transaction id before we announce it in the proc array
2166 */
2168
2169 /*
2170 * Advertise it in the proc array. We assume assignment of
2171 * localTransactionId is atomic, and the proc number should be set
2172 * already.
2173 */
2176
2177 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
2178
2179 /*
2180 * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2181 * be the same as the first command's statement_timestamp(), so don't do a
2182 * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2183 * for transactions started inside procedures (i.e., nonatomic SPI
2184 * contexts), we do need to advance the timestamp. Also, in a parallel
2185 * worker, the timestamp should already have been provided by a call to
2186 * SetParallelStartTimestamps().
2187 */
2188 if (!IsParallelWorker())
2189 {
2192 else
2194 }
2195 else
2198 /* Mark xactStopTimestamp as unset. */
2200
2201 /*
2202 * initialize other subsystems for new transaction
2203 */
2204 AtStart_GUC();
2205 AtStart_Cache();
2207
2208 /*
2209 * done with start processing, set current transaction state to "in
2210 * progress"
2211 */
2213
2214 /* Schedule transaction timeout */
2215 if (TransactionTimeout > 0)
2217
2218 ShowTransactionState("StartTransaction");
2219}
2220
2221
2222/*
2223 * CommitTransaction
2224 *
2225 * NB: if you change this routine, better look at PrepareTransaction too!
2226 */
2227static void
2229{
2231 TransactionId latestXid;
2232 bool is_parallel_worker;
2233
2234 is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2235
2236 /* Enforce parallel mode restrictions during parallel worker commit. */
2237 if (is_parallel_worker)
2239
2240 ShowTransactionState("CommitTransaction");
2241
2242 /*
2243 * check the current transaction state
2244 */
2245 if (s->state != TRANS_INPROGRESS)
2246 elog(WARNING, "CommitTransaction while in %s state",
2248 Assert(s->parent == NULL);
2249
2250 /*
2251 * Do pre-commit processing that involves calling user-defined code, such
2252 * as triggers. SECURITY_RESTRICTED_OPERATION contexts must not queue an
2253 * action that would run here, because that would bypass the sandbox.
2254 * Since closing cursors could queue trigger actions, triggers could open
2255 * cursors, etc, we have to keep looping until there's nothing left to do.
2256 */
2257 for (;;)
2258 {
2259 /*
2260 * Fire all currently pending deferred triggers.
2261 */
2263
2264 /*
2265 * Close open portals (converting holdable ones into static portals).
2266 * If there weren't any, we are done ... otherwise loop back to check
2267 * if they queued deferred triggers. Lather, rinse, repeat.
2268 */
2269 if (!PreCommit_Portals(false))
2270 break;
2271 }
2272
2273 /*
2274 * The remaining actions cannot call any user-defined code, so it's safe
2275 * to start shutting down within-transaction services. But note that most
2276 * of this stuff could still throw an error, which would switch us into
2277 * the transaction-abort path.
2278 */
2279
2282
2283 /*
2284 * If this xact has started any unfinished parallel operation, clean up
2285 * its workers, warning about leaked resources. (But we don't actually
2286 * reset parallelModeLevel till entering TRANS_COMMIT, a bit below. This
2287 * keeps parallel mode restrictions active as long as possible in a
2288 * parallel worker.)
2289 */
2290 AtEOXact_Parallel(true);
2291 if (is_parallel_worker)
2292 {
2293 if (s->parallelModeLevel != 1)
2294 elog(WARNING, "parallelModeLevel is %d not 1 at end of parallel worker transaction",
2296 }
2297 else
2298 {
2299 if (s->parallelModeLevel != 0)
2300 elog(WARNING, "parallelModeLevel is %d not 0 at end of transaction",
2302 }
2303
2304 /* Shut down the deferred-trigger manager */
2305 AfterTriggerEndXact(true);
2306
2307 /*
2308 * Let ON COMMIT management do its thing (must happen after closing
2309 * cursors, to avoid dangling-reference problems)
2310 */
2312
2313 /*
2314 * Synchronize files that are created and not WAL-logged during this
2315 * transaction. This must happen before AtEOXact_RelationMap(), so that we
2316 * don't see committed-but-broken files after a crash.
2317 */
2318 smgrDoPendingSyncs(true, is_parallel_worker);
2319
2320 /* close large objects before lower-level cleanup */
2322
2323 /*
2324 * Insert notifications sent by NOTIFY commands into the queue. This
2325 * should be late in the pre-commit sequence to minimize time spent
2326 * holding the notify-insertion lock. However, this could result in
2327 * creating a snapshot, so we must do it before serializable cleanup.
2328 */
2330
2331 /*
2332 * Mark serializable transaction as complete for predicate locking
2333 * purposes. This should be done as late as we can put it and still allow
2334 * errors to be raised for failure patterns found at commit. This is not
2335 * appropriate in a parallel worker however, because we aren't committing
2336 * the leader's transaction and its serializable state will live on.
2337 */
2338 if (!is_parallel_worker)
2340
2341 /* Prevent cancel/die interrupt while cleaning up */
2343
2344 /* Commit updates to the relation map --- do this as late as possible */
2345 AtEOXact_RelationMap(true, is_parallel_worker);
2346
2347 /*
2348 * set the current transaction state information appropriately during
2349 * commit processing
2350 */
2351 s->state = TRANS_COMMIT;
2352 s->parallelModeLevel = 0;
2353 s->parallelChildXact = false; /* should be false already */
2354
2355 /* Disable transaction timeout */
2356 if (TransactionTimeout > 0)
2358
2359 if (!is_parallel_worker)
2360 {
2361 /*
2362 * We need to mark our XIDs as committed in pg_xact. This is where we
2363 * durably commit.
2364 */
2365 latestXid = RecordTransactionCommit();
2366 }
2367 else
2368 {
2369 /*
2370 * We must not mark our XID committed; the parallel leader is
2371 * responsible for that.
2372 */
2373 latestXid = InvalidTransactionId;
2374
2375 /*
2376 * Make sure the leader will know about any WAL we wrote before it
2377 * commits.
2378 */
2380 }
2381
2382 TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->vxid.lxid);
2383
2384 /*
2385 * Let others know about no transaction in progress by me. Note that this
2386 * must be done _before_ releasing locks we hold and _after_
2387 * RecordTransactionCommit.
2388 */
2389 ProcArrayEndTransaction(MyProc, latestXid);
2390
2391 /*
2392 * This is all post-commit cleanup. Note that if an error is raised here,
2393 * it's too late to abort the transaction. This should be just
2394 * noncritical resource releasing.
2395 *
2396 * The ordering of operations is not entirely random. The idea is:
2397 * release resources visible to other backends (eg, files, buffer pins);
2398 * then release locks; then release backend-local resources. We want to
2399 * release locks at the point where any backend waiting for us will see
2400 * our transaction as being fully cleaned up.
2401 *
2402 * Resources that can be associated with individual queries are handled by
2403 * the ResourceOwner mechanism. The other calls here are for backend-wide
2404 * state.
2405 */
2406
2409
2410 CurrentResourceOwner = NULL;
2413 true, true);
2414
2415 AtEOXact_Aio(true);
2416
2417 /* Check we've released all buffer pins */
2418 AtEOXact_Buffers(true);
2419
2420 /* Clean up the relation cache */
2422
2423 /* Clean up the type cache */
2425
2426 /*
2427 * Make catalog changes visible to all backends. This has to happen after
2428 * relcache references are dropped (see comments for
2429 * AtEOXact_RelationCache), but before locks are released (if anyone is
2430 * waiting for lock on a relation we've modified, we want them to know
2431 * about the catalog change before they start using the relation).
2432 */
2433 AtEOXact_Inval(true);
2434
2436
2439 true, true);
2442 true, true);
2443
2444 /*
2445 * Likewise, dropping of files deleted during the transaction is best done
2446 * after releasing relcache and buffer pins. (This is not strictly
2447 * necessary during commit, since such pins should have been released
2448 * already, but this ordering is definitely critical during abort.) Since
2449 * this may take many seconds, also delay until after releasing locks.
2450 * Other backends will observe the attendant catalog changes and not
2451 * attempt to access affected files.
2452 */
2454
2455 /*
2456 * Send out notification signals to other backends (and do other
2457 * post-commit NOTIFY cleanup). This must not happen until after our
2458 * transaction is fully done from the viewpoint of other backends.
2459 */
2461
2462 /*
2463 * Everything after this should be purely internal-to-this-backend
2464 * cleanup.
2465 */
2466 AtEOXact_GUC(true, 1);
2467 AtEOXact_SPI(true);
2468 AtEOXact_Enum();
2470 AtEOXact_Namespace(true, is_parallel_worker);
2471 AtEOXact_SMgr();
2472 AtEOXact_Files(true);
2474 AtEOXact_HashTables(true);
2475 AtEOXact_PgStat(true, is_parallel_worker);
2476 AtEOXact_Snapshot(true, false);
2480
2482 s->curTransactionOwner = NULL;
2485
2487
2490 s->nestingLevel = 0;
2491 s->gucNestLevel = 0;
2492 s->childXids = NULL;
2493 s->nChildXids = 0;
2494 s->maxChildXids = 0;
2495
2498
2499 /*
2500 * done with commit processing, set current transaction state back to
2501 * default
2502 */
2503 s->state = TRANS_DEFAULT;
2504
2506}
2507
2508
2509/*
2510 * PrepareTransaction
2511 *
2512 * NB: if you change this routine, better look at CommitTransaction too!
2513 */
2514static void
2516{
2519 GlobalTransaction gxact;
2520 TimestampTz prepared_at;
2521
2523
2524 ShowTransactionState("PrepareTransaction");
2525
2526 /*
2527 * check the current transaction state
2528 */
2529 if (s->state != TRANS_INPROGRESS)
2530 elog(WARNING, "PrepareTransaction while in %s state",
2532 Assert(s->parent == NULL);
2533
2534 /*
2535 * Do pre-commit processing that involves calling user-defined code, such
2536 * as triggers. Since closing cursors could queue trigger actions,
2537 * triggers could open cursors, etc, we have to keep looping until there's
2538 * nothing left to do.
2539 */
2540 for (;;)
2541 {
2542 /*
2543 * Fire all currently pending deferred triggers.
2544 */
2546
2547 /*
2548 * Close open portals (converting holdable ones into static portals).
2549 * If there weren't any, we are done ... otherwise loop back to check
2550 * if they queued deferred triggers. Lather, rinse, repeat.
2551 */
2552 if (!PreCommit_Portals(true))
2553 break;
2554 }
2555
2557
2558 /*
2559 * The remaining actions cannot call any user-defined code, so it's safe
2560 * to start shutting down within-transaction services. But note that most
2561 * of this stuff could still throw an error, which would switch us into
2562 * the transaction-abort path.
2563 */
2564
2565 /* Shut down the deferred-trigger manager */
2566 AfterTriggerEndXact(true);
2567
2568 /*
2569 * Let ON COMMIT management do its thing (must happen after closing
2570 * cursors, to avoid dangling-reference problems)
2571 */
2573
2574 /*
2575 * Synchronize files that are created and not WAL-logged during this
2576 * transaction. This must happen before EndPrepare(), so that we don't see
2577 * committed-but-broken files after a crash and COMMIT PREPARED.
2578 */
2579 smgrDoPendingSyncs(true, false);
2580
2581 /* close large objects before lower-level cleanup */
2583
2584 /* NOTIFY requires no work at this point */
2585
2586 /*
2587 * Mark serializable transaction as complete for predicate locking
2588 * purposes. This should be done as late as we can put it and still allow
2589 * errors to be raised for failure patterns found at commit.
2590 */
2592
2593 /*
2594 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2595 * this transaction. Having the prepared xact hold locks on another
2596 * backend's temp table seems a bad idea --- for instance it would prevent
2597 * the backend from exiting. There are other problems too, such as how to
2598 * clean up the source backend's local buffers and ON COMMIT state if the
2599 * prepared xact includes a DROP of a temp table.
2600 *
2601 * Other objects types, like functions, operators or extensions, share the
2602 * same restriction as they should not be created, locked or dropped as
2603 * this can mess up with this session or even a follow-up session trying
2604 * to use the same temporary namespace.
2605 *
2606 * We must check this after executing any ON COMMIT actions, because they
2607 * might still access a temp relation.
2608 *
2609 * XXX In principle this could be relaxed to allow some useful special
2610 * cases, such as a temp table created and dropped all within the
2611 * transaction. That seems to require much more bookkeeping though.
2612 */
2614 ereport(ERROR,
2615 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2616 errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2617
2618 /*
2619 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2620 * supported if we added cleanup logic to twophase.c, but for now it
2621 * doesn't seem worth the trouble.
2622 */
2624 ereport(ERROR,
2625 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2626 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2627
2628 /* Prevent cancel/die interrupt while cleaning up */
2630
2631 /*
2632 * set the current transaction state information appropriately during
2633 * prepare processing
2634 */
2635 s->state = TRANS_PREPARE;
2636
2637 /* Disable transaction timeout */
2638 if (TransactionTimeout > 0)
2640
2641 prepared_at = GetCurrentTimestamp();
2642
2643 /*
2644 * Reserve the GID for this transaction. This could fail if the requested
2645 * GID is invalid or already in use.
2646 */
2647 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
2649 prepareGID = NULL;
2650
2651 /*
2652 * Collect data for the 2PC state file. Note that in general, no actual
2653 * state change should happen in the called modules during this step,
2654 * since it's still possible to fail before commit, and in that case we
2655 * want transaction abort to be able to clean up. (In particular, the
2656 * AtPrepare routines may error out if they find cases they cannot
2657 * handle.) State cleanup should happen in the PostPrepare routines
2658 * below. However, some modules can go ahead and clear state here because
2659 * they wouldn't do anything with it during abort anyway.
2660 *
2661 * Note: because the 2PC state file records will be replayed in the same
2662 * order they are made, the order of these calls has to match the order in
2663 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2664 * PREPARED; in particular, pay attention to whether things should happen
2665 * before or after releasing the transaction's locks.
2666 */
2667 StartPrepare(gxact);
2668
2675
2676 /*
2677 * Here is where we really truly prepare.
2678 *
2679 * We have to record transaction prepares even if we didn't make any
2680 * updates, because the transaction manager might get confused if we lose
2681 * a global transaction.
2682 */
2683 EndPrepare(gxact);
2684
2685 /*
2686 * Now we clean up backend-internal state and release internal resources.
2687 */
2688
2689 /* Reset XactLastRecEnd until the next transaction writes something */
2690 XactLastRecEnd = 0;
2691
2692 /*
2693 * Transfer our locks to a dummy PGPROC. This has to be done before
2694 * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2695 * conclude "xact already committed or aborted" for our locks.
2696 */
2697 PostPrepare_Locks(xid);
2698
2699 /*
2700 * Let others know about no transaction in progress by me. This has to be
2701 * done *after* the prepared transaction has been marked valid, else
2702 * someone may think it is unlocked and recyclable.
2703 */
2705
2706 /*
2707 * In normal commit-processing, this is all non-critical post-transaction
2708 * cleanup. When the transaction is prepared, however, it's important
2709 * that the locks and other per-backend resources are transferred to the
2710 * prepared transaction's PGPROC entry. Note that if an error is raised
2711 * here, it's too late to abort the transaction. XXX: This probably should
2712 * be in a critical section, to force a PANIC if any of this fails, but
2713 * that cure could be worse than the disease.
2714 */
2715
2717
2720 true, true);
2721
2722 AtEOXact_Aio(true);
2723
2724 /* Check we've released all buffer pins */
2725 AtEOXact_Buffers(true);
2726
2727 /* Clean up the relation cache */
2729
2730 /* Clean up the type cache */
2732
2733 /* notify doesn't need a postprepare call */
2734
2736
2738
2740
2742
2744
2747 true, true);
2750 true, true);
2751
2752 /*
2753 * Allow another backend to finish the transaction. After
2754 * PostPrepare_Twophase(), the transaction is completely detached from our
2755 * backend. The rest is just non-critical cleanup of backend-local state.
2756 */
2758
2759 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2760 AtEOXact_GUC(true, 1);
2761 AtEOXact_SPI(true);
2762 AtEOXact_Enum();
2764 AtEOXact_Namespace(true, false);
2765 AtEOXact_SMgr();
2766 AtEOXact_Files(true);
2768 AtEOXact_HashTables(true);
2769 /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2770 AtEOXact_Snapshot(true, true);
2771 /* we treat PREPARE as ROLLBACK so far as waking workers goes */
2775
2776 CurrentResourceOwner = NULL;
2778 s->curTransactionOwner = NULL;
2781
2783
2786 s->nestingLevel = 0;
2787 s->gucNestLevel = 0;
2788 s->childXids = NULL;
2789 s->nChildXids = 0;
2790 s->maxChildXids = 0;
2791
2794
2795 /*
2796 * done with 1st phase commit processing, set current transaction state
2797 * back to default
2798 */
2799 s->state = TRANS_DEFAULT;
2800
2802}
2803
2804
2805/*
2806 * AbortTransaction
2807 */
2808static void
2810{
2812 TransactionId latestXid;
2813 bool is_parallel_worker;
2814
2815 /* Prevent cancel/die interrupt while cleaning up */
2817
2818 /* Disable transaction timeout */
2819 if (TransactionTimeout > 0)
2821
2822 /* Make sure we have a valid memory context and resource owner */
2825
2826 /*
2827 * Release any LW locks we might be holding as quickly as possible.
2828 * (Regular locks, however, must be held till we finish aborting.)
2829 * Releasing LW locks is critical since we might try to grab them again
2830 * while cleaning up!
2831 */
2833
2834 /* Clear wait information and command progress indicator */
2837
2839
2840 /* Clean up buffer content locks, too */
2841 UnlockBuffers();
2842
2843 /* Reset WAL record construction state */
2845
2846 /* Cancel condition variable sleep */
2848
2849 /*
2850 * Also clean up any open wait for lock, since the lock manager will choke
2851 * if we try to wait for another lock before doing this.
2852 */
2854
2855 /*
2856 * If any timeout events are still active, make sure the timeout interrupt
2857 * is scheduled. This covers possible loss of a timeout interrupt due to
2858 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2859 * We delay this till after LockErrorCleanup so that we don't uselessly
2860 * reschedule lock or deadlock check timeouts.
2861 */
2863
2864 /*
2865 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2866 * handler. We do this fairly early in the sequence so that the timeout
2867 * infrastructure will be functional if needed while aborting.
2868 */
2869 sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
2870
2871 /*
2872 * check the current transaction state
2873 */
2874 is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2875 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2876 elog(WARNING, "AbortTransaction while in %s state",
2878 Assert(s->parent == NULL);
2879
2880 /*
2881 * set the current transaction state information appropriately during the
2882 * abort processing
2883 */
2884 s->state = TRANS_ABORT;
2885
2886 /*
2887 * Reset user ID which might have been changed transiently. We need this
2888 * to clean up in case control escaped out of a SECURITY DEFINER function
2889 * or other local change of CurrentUserId; therefore, the prior value of
2890 * SecurityRestrictionContext also needs to be restored.
2891 *
2892 * (Note: it is not necessary to restore session authorization or role
2893 * settings here because those can only be changed via GUC, and GUC will
2894 * take care of rolling them back if need be.)
2895 */
2897
2898 /* Forget about any active REINDEX. */
2900
2901 /* Reset logical streaming state. */
2903
2904 /* Reset snapshot export state. */
2906
2907 /*
2908 * If this xact has started any unfinished parallel operation, clean up
2909 * its workers and exit parallel mode. Don't warn about leaked resources.
2910 */
2911 AtEOXact_Parallel(false);
2912 s->parallelModeLevel = 0;
2913 s->parallelChildXact = false; /* should be false already */
2914
2915 /*
2916 * do abort processing
2917 */
2918 AfterTriggerEndXact(false); /* 'false' means it's abort */
2920 smgrDoPendingSyncs(false, is_parallel_worker);
2921 AtEOXact_LargeObject(false);
2923 AtEOXact_RelationMap(false, is_parallel_worker);
2925
2926 /*
2927 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2928 * far as assigning an XID to advertise). But if we're inside a parallel
2929 * worker, skip this; the user backend must be the one to write the abort
2930 * record.
2931 */
2932 if (!is_parallel_worker)
2933 latestXid = RecordTransactionAbort(false);
2934 else
2935 {
2936 latestXid = InvalidTransactionId;
2937
2938 /*
2939 * Since the parallel leader won't get our value of XactLastRecEnd in
2940 * this case, we nudge WAL-writer ourselves in this case. See related
2941 * comments in RecordTransactionAbort for why this matters.
2942 */
2944 }
2945
2946 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->vxid.lxid);
2947
2948 /*
2949 * Let others know about no transaction in progress by me. Note that this
2950 * must be done _before_ releasing locks we hold and _after_
2951 * RecordTransactionAbort.
2952 */
2953 ProcArrayEndTransaction(MyProc, latestXid);
2954
2955 /*
2956 * Post-abort cleanup. See notes in CommitTransaction() concerning
2957 * ordering. We can skip all of it if the transaction failed before
2958 * creating a resource owner.
2959 */
2960 if (TopTransactionResourceOwner != NULL)
2961 {
2962 if (is_parallel_worker)
2964 else
2966
2969 false, true);
2970 AtEOXact_Aio(false);
2971 AtEOXact_Buffers(false);
2974 AtEOXact_Inval(false);
2978 false, true);
2981 false, true);
2982 smgrDoPendingDeletes(false);
2983
2984 AtEOXact_GUC(false, 1);
2985 AtEOXact_SPI(false);
2986 AtEOXact_Enum();
2988 AtEOXact_Namespace(false, is_parallel_worker);
2989 AtEOXact_SMgr();
2990 AtEOXact_Files(false);
2992 AtEOXact_HashTables(false);
2993 AtEOXact_PgStat(false, is_parallel_worker);
2997 }
2998
2999 /*
3000 * State remains TRANS_ABORT until CleanupTransaction().
3001 */
3003}
3004
3005/*
3006 * CleanupTransaction
3007 */
3008static void
3010{
3012
3013 /*
3014 * State should still be TRANS_ABORT from AbortTransaction().
3015 */
3016 if (s->state != TRANS_ABORT)
3017 elog(FATAL, "CleanupTransaction: unexpected state %s",
3019
3020 /*
3021 * do abort cleanup processing
3022 */
3023 AtCleanup_Portals(); /* now safe to release portal memory */
3024 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
3025
3026 CurrentResourceOwner = NULL; /* and resource owner */
3029 s->curTransactionOwner = NULL;
3032
3033 AtCleanup_Memory(); /* and transaction memory */
3034
3037 s->nestingLevel = 0;
3038 s->gucNestLevel = 0;
3039 s->childXids = NULL;
3040 s->nChildXids = 0;
3041 s->maxChildXids = 0;
3042 s->parallelModeLevel = 0;
3043 s->parallelChildXact = false;
3044
3047
3048 /*
3049 * done with abort processing, set current transaction state back to
3050 * default
3051 */
3052 s->state = TRANS_DEFAULT;
3053}
3054
3055/*
3056 * StartTransactionCommand
3057 */
3058void
3060{
3062
3063 switch (s->blockState)
3064 {
3065 /*
3066 * if we aren't in a transaction block, we just do our usual start
3067 * transaction.
3068 */
3069 case TBLOCK_DEFAULT:
3072 break;
3073
3074 /*
3075 * We are somewhere in a transaction block or subtransaction and
3076 * about to start a new command. For now we do nothing, but
3077 * someday we may do command-local resource initialization. (Note
3078 * that any needed CommandCounterIncrement was done by the
3079 * previous CommitTransactionCommand.)
3080 */
3081 case TBLOCK_INPROGRESS:
3084 break;
3085
3086 /*
3087 * Here we are in a failed transaction block (one of the commands
3088 * caused an abort) so we do nothing but remain in the abort
3089 * state. Eventually we will get a ROLLBACK command which will
3090 * get us out of this state. (It is up to other code to ensure
3091 * that no commands other than ROLLBACK will be processed in these
3092 * states.)
3093 */
3094 case TBLOCK_ABORT:
3095 case TBLOCK_SUBABORT:
3096 break;
3097
3098 /* These cases are invalid. */
3099 case TBLOCK_STARTED:
3100 case TBLOCK_BEGIN:
3102 case TBLOCK_SUBBEGIN:
3103 case TBLOCK_END:
3104 case TBLOCK_SUBRELEASE:
3105 case TBLOCK_SUBCOMMIT:
3106 case TBLOCK_ABORT_END:
3110 case TBLOCK_SUBRESTART:
3112 case TBLOCK_PREPARE:
3113 elog(ERROR, "StartTransactionCommand: unexpected state %s",
3115 break;
3116 }
3117
3118 /*
3119 * We must switch to CurTransactionContext before returning. This is
3120 * already done if we called StartTransaction, otherwise not.
3121 */
3124}
3125
3126
3127/*
3128 * Simple system for saving and restoring transaction characteristics
3129 * (isolation level, read only, deferrable). We need this for transaction
3130 * chaining, so that we can set the characteristics of the new transaction to
3131 * be the same as the previous one. (We need something like this because the
3132 * GUC system resets the characteristics at transaction end, so for example
3133 * just skipping the reset in StartTransaction() won't work.)
3134 */
3135void
3137{
3141}
3142
3143void
3145{
3149}
3150
3151/*
3152 * CommitTransactionCommand -- a wrapper function handling the
3153 * loop over subtransactions to avoid a potentially dangerous recursion
3154 * in CommitTransactionCommandInternal().
3155 */
3156void
3158{
3159 /*
3160 * Repeatedly call CommitTransactionCommandInternal() until all the work
3161 * is done.
3162 */
3164 {
3165 }
3166}
3167
3168/*
3169 * CommitTransactionCommandInternal - a function doing an iteration of work
3170 * regarding handling the commit transaction command. In the case of
3171 * subtransactions more than one iterations could be required. Returns
3172 * true when no more iterations required, false otherwise.
3173 */
3174static bool
3176{
3179
3180 /* Must save in case we need to restore below */
3182
3183 switch (s->blockState)
3184 {
3185 /*
3186 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3187 * StartTransactionCommand didn't set the STARTED state
3188 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3189 * by EndParallelWorkerTransaction(), not this function.
3190 */
3191 case TBLOCK_DEFAULT:
3193 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3195 break;
3196
3197 /*
3198 * If we aren't in a transaction block, just do our usual
3199 * transaction commit, and return to the idle state.
3200 */
3201 case TBLOCK_STARTED:
3204 break;
3205
3206 /*
3207 * We are completing a "BEGIN TRANSACTION" command, so we change
3208 * to the "transaction block in progress" state and return. (We
3209 * assume the BEGIN did nothing to the database, so we need no
3210 * CommandCounterIncrement.)
3211 */
3212 case TBLOCK_BEGIN:
3214 break;
3215
3216 /*
3217 * This is the case when we have finished executing a command
3218 * someplace within a transaction block. We increment the command
3219 * counter and return.
3220 */
3221 case TBLOCK_INPROGRESS:
3225 break;
3226
3227 /*
3228 * We are completing a "COMMIT" command. Do it and return to the
3229 * idle state.
3230 */
3231 case TBLOCK_END:
3234 if (s->chain)
3235 {
3238 s->chain = false;
3240 }
3241 break;
3242
3243 /*
3244 * Here we are in the middle of a transaction block but one of the
3245 * commands caused an abort so we do nothing but remain in the
3246 * abort state. Eventually we will get a ROLLBACK command.
3247 */
3248 case TBLOCK_ABORT:
3249 case TBLOCK_SUBABORT:
3250 break;
3251
3252 /*
3253 * Here we were in an aborted transaction block and we just got
3254 * the ROLLBACK command from the user, so clean up the
3255 * already-aborted transaction and return to the idle state.
3256 */
3257 case TBLOCK_ABORT_END:
3260 if (s->chain)
3261 {
3264 s->chain = false;
3266 }
3267 break;
3268
3269 /*
3270 * Here we were in a perfectly good transaction block but the user
3271 * told us to ROLLBACK anyway. We have to abort the transaction
3272 * and then clean up.
3273 */
3278 if (s->chain)
3279 {
3282 s->chain = false;
3284 }
3285 break;
3286
3287 /*
3288 * We are completing a "PREPARE TRANSACTION" command. Do it and
3289 * return to the idle state.
3290 */
3291 case TBLOCK_PREPARE:
3294 break;
3295
3296 /*
3297 * The user issued a SAVEPOINT inside a transaction block. Start a
3298 * subtransaction. (DefineSavepoint already did PushTransaction,
3299 * so as to have someplace to put the SUBBEGIN state.)
3300 */
3301 case TBLOCK_SUBBEGIN:
3304 break;
3305
3306 /*
3307 * The user issued a RELEASE command, so we end the current
3308 * subtransaction and return to the parent transaction. The parent
3309 * might be ended too, so repeat till we find an INPROGRESS
3310 * transaction or subtransaction.
3311 */
3312 case TBLOCK_SUBRELEASE:
3313 do
3314 {
3316 s = CurrentTransactionState; /* changed by pop */
3317 } while (s->blockState == TBLOCK_SUBRELEASE);
3318
3321 break;
3322
3323 /*
3324 * The user issued a COMMIT, so we end the current subtransaction
3325 * hierarchy and perform final commit. We do this by rolling up
3326 * any subtransactions into their parent, which leads to O(N^2)
3327 * operations with respect to resource owners - this isn't that
3328 * bad until we approach a thousands of savepoints but is
3329 * necessary for correctness should after triggers create new
3330 * resource owners.
3331 */
3332 case TBLOCK_SUBCOMMIT:
3333 do
3334 {
3336 s = CurrentTransactionState; /* changed by pop */
3337 } while (s->blockState == TBLOCK_SUBCOMMIT);
3338 /* If we had a COMMIT command, finish off the main xact too */
3339 if (s->blockState == TBLOCK_END)
3340 {
3341 Assert(s->parent == NULL);
3344 if (s->chain)
3345 {
3348 s->chain = false;
3350 }
3351 }
3352 else if (s->blockState == TBLOCK_PREPARE)
3353 {
3354 Assert(s->parent == NULL);
3357 }
3358 else
3359 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3361 break;
3362
3363 /*
3364 * The current already-failed subtransaction is ending due to a
3365 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3366 * examine the parent (which could be in any of several states).
3367 * As we need to examine the parent, return false to request the
3368 * caller to do the next iteration.
3369 */
3372 return false;
3373
3374 /*
3375 * As above, but it's not dead yet, so abort first.
3376 */
3380 return false;
3381
3382 /*
3383 * The current subtransaction is the target of a ROLLBACK TO
3384 * command. Abort and pop it, then start a new subtransaction
3385 * with the same name.
3386 */
3387 case TBLOCK_SUBRESTART:
3388 {
3389 char *name;
3390 int savepointLevel;
3391
3392 /* save name and keep Cleanup from freeing it */
3393 name = s->name;
3394 s->name = NULL;
3395 savepointLevel = s->savepointLevel;
3396
3399
3400 DefineSavepoint(NULL);
3401 s = CurrentTransactionState; /* changed by push */
3402 s->name = name;
3403 s->savepointLevel = savepointLevel;
3404
3405 /* This is the same as TBLOCK_SUBBEGIN case */
3409 }
3410 break;
3411
3412 /*
3413 * Same as above, but the subtransaction had already failed, so we
3414 * don't need AbortSubTransaction.
3415 */
3417 {
3418 char *name;
3419 int savepointLevel;
3420
3421 /* save name and keep Cleanup from freeing it */
3422 name = s->name;
3423 s->name = NULL;
3424 savepointLevel = s->savepointLevel;
3425
3427
3428 DefineSavepoint(NULL);
3429 s = CurrentTransactionState; /* changed by push */
3430 s->name = name;
3431 s->savepointLevel = savepointLevel;
3432
3433 /* This is the same as TBLOCK_SUBBEGIN case */
3437 }
3438 break;
3439 }
3440
3441 /* Done, no more iterations required */
3442 return true;
3443}
3444
3445/*
3446 * AbortCurrentTransaction -- a wrapper function handling the
3447 * loop over subtransactions to avoid potentially dangerous recursion in
3448 * AbortCurrentTransactionInternal().
3449 */
3450void
3452{
3453 /*
3454 * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3455 * done.
3456 */
3458 {
3459 }
3460}
3461
3462/*
3463 * AbortCurrentTransactionInternal - a function doing an iteration of work
3464 * regarding handling the current transaction abort. In the case of
3465 * subtransactions more than one iterations could be required. Returns
3466 * true when no more iterations required, false otherwise.
3467 */
3468static bool
3470{
3472
3473 switch (s->blockState)
3474 {
3475 case TBLOCK_DEFAULT:
3476 if (s->state == TRANS_DEFAULT)
3477 {
3478 /* we are idle, so nothing to do */
3479 }
3480 else
3481 {
3482 /*
3483 * We can get here after an error during transaction start
3484 * (state will be TRANS_START). Need to clean up the
3485 * incompletely started transaction. First, adjust the
3486 * low-level state to suppress warning message from
3487 * AbortTransaction.
3488 */
3489 if (s->state == TRANS_START)
3493 }
3494 break;
3495
3496 /*
3497 * If we aren't in a transaction block, we just do the basic abort
3498 * & cleanup transaction. For this purpose, we treat an implicit
3499 * transaction block as if it were a simple statement.
3500 */
3501 case TBLOCK_STARTED:
3506 break;
3507
3508 /*
3509 * If we are in TBLOCK_BEGIN it means something screwed up right
3510 * after reading "BEGIN TRANSACTION". We assume that the user
3511 * will interpret the error as meaning the BEGIN failed to get him
3512 * into a transaction block, so we should abort and return to idle
3513 * state.
3514 */
3515 case TBLOCK_BEGIN:
3519 break;
3520
3521 /*
3522 * We are somewhere in a transaction block and we've gotten a
3523 * failure, so we abort the transaction and set up the persistent
3524 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3525 */
3526 case TBLOCK_INPROGRESS:
3530 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3531 break;
3532
3533 /*
3534 * Here, we failed while trying to COMMIT. Clean up the
3535 * transaction and return to idle state (we do not want to stay in
3536 * the transaction).
3537 */
3538 case TBLOCK_END:
3542 break;
3543
3544 /*
3545 * Here, we are already in an aborted transaction state and are
3546 * waiting for a ROLLBACK, but for some reason we failed again! So
3547 * we just remain in the abort state.
3548 */
3549 case TBLOCK_ABORT:
3550 case TBLOCK_SUBABORT:
3551 break;
3552
3553 /*
3554 * We are in a failed transaction and we got the ROLLBACK command.
3555 * We have already aborted, we just need to cleanup and go to idle
3556 * state.
3557 */
3558 case TBLOCK_ABORT_END:
3561 break;
3562
3563 /*
3564 * We are in a live transaction and we got a ROLLBACK command.
3565 * Abort, cleanup, go to idle state.
3566 */
3571 break;
3572
3573 /*
3574 * Here, we failed while trying to PREPARE. Clean up the
3575 * transaction and return to idle state (we do not want to stay in
3576 * the transaction).
3577 */
3578 case TBLOCK_PREPARE:
3582 break;
3583
3584 /*
3585 * We got an error inside a subtransaction. Abort just the
3586 * subtransaction, and go to the persistent SUBABORT state until
3587 * we get ROLLBACK.
3588 */
3592 break;
3593
3594 /*
3595 * If we failed while trying to create a subtransaction, clean up
3596 * the broken subtransaction and abort the parent. The same
3597 * applies if we get a failure while ending a subtransaction. As
3598 * we need to abort the parent, return false to request the caller
3599 * to do the next iteration.
3600 */
3601 case TBLOCK_SUBBEGIN:
3602 case TBLOCK_SUBRELEASE:
3603 case TBLOCK_SUBCOMMIT:
3605 case TBLOCK_SUBRESTART:
3608 return false;
3609
3610 /*
3611 * Same as above, except the Abort() was already done.
3612 */
3616 return false;
3617 }
3618
3619 /* Done, no more iterations required */
3620 return true;
3621}
3622
3623/*
3624 * PreventInTransactionBlock
3625 *
3626 * This routine is to be called by statements that must not run inside
3627 * a transaction block, typically because they have non-rollback-able
3628 * side effects or do internal commits.
3629 *
3630 * If this routine completes successfully, then the calling statement is
3631 * guaranteed that if it completes without error, its results will be
3632 * committed immediately.
3633 *
3634 * If we have already started a transaction block, issue an error; also issue
3635 * an error if we appear to be running inside a user-defined function (which
3636 * could issue more commands and possibly cause a failure after the statement
3637 * completes). Subtransactions are verboten too.
3638 *
3639 * We must also set XACT_FLAGS_NEEDIMMEDIATECOMMIT in MyXactFlags, to ensure
3640 * that postgres.c follows through by committing after the statement is done.
3641 *
3642 * isTopLevel: passed down from ProcessUtility to determine whether we are
3643 * inside a function. (We will always fail if this is false, but it's
3644 * convenient to centralize the check here instead of making callers do it.)
3645 * stmtType: statement type name, for error messages.
3646 */
3647void
3648PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
3649{
3650 /*
3651 * xact block already started?
3652 */
3653 if (IsTransactionBlock())
3654 ereport(ERROR,
3655 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3656 /* translator: %s represents an SQL statement name */
3657 errmsg("%s cannot run inside a transaction block",
3658 stmtType)));
3659
3660 /*
3661 * subtransaction?
3662 */
3663 if (IsSubTransaction())
3664 ereport(ERROR,
3665 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3666 /* translator: %s represents an SQL statement name */
3667 errmsg("%s cannot run inside a subtransaction",
3668 stmtType)));
3669
3670 /*
3671 * inside a function call?
3672 */
3673 if (!isTopLevel)
3674 ereport(ERROR,
3675 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3676 /* translator: %s represents an SQL statement name */
3677 errmsg("%s cannot be executed from a function", stmtType)));
3678
3679 /* If we got past IsTransactionBlock test, should be in default state */
3682 elog(FATAL, "cannot prevent transaction chain");
3683
3684 /* All okay. Set the flag to make sure the right thing happens later. */
3686}
3687
3688/*
3689 * WarnNoTransactionBlock
3690 * RequireTransactionBlock
3691 *
3692 * These two functions allow for warnings or errors if a command is executed
3693 * outside of a transaction block. This is useful for commands that have no
3694 * effects that persist past transaction end (and so calling them outside a
3695 * transaction block is presumably an error). DECLARE CURSOR is an example.
3696 * While top-level transaction control commands (BEGIN/COMMIT/ABORT) and SET
3697 * that have no effect issue warnings, all other no-effect commands generate
3698 * errors.
3699 *
3700 * If we appear to be running inside a user-defined function, we do not
3701 * issue anything, since the function could issue more commands that make
3702 * use of the current statement's results. Likewise subtransactions.
3703 * Thus these are inverses for PreventInTransactionBlock.
3704 *
3705 * isTopLevel: passed down from ProcessUtility to determine whether we are
3706 * inside a function.
3707 * stmtType: statement type name, for warning or error messages.
3708 */
3709void
3710WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
3711{
3712 CheckTransactionBlock(isTopLevel, false, stmtType);
3713}
3714
3715void
3716RequireTransactionBlock(bool isTopLevel, const char *stmtType)
3717{
3718 CheckTransactionBlock(isTopLevel, true, stmtType);
3719}
3720
3721/*
3722 * This is the implementation of the above two.
3723 */
3724static void
3725CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
3726{
3727 /*
3728 * xact block already started?
3729 */
3730 if (IsTransactionBlock())
3731 return;
3732
3733 /*
3734 * subtransaction?
3735 */
3736 if (IsSubTransaction())
3737 return;
3738
3739 /*
3740 * inside a function call?
3741 */
3742 if (!isTopLevel)
3743 return;
3744
3745 ereport(throwError ? ERROR : WARNING,
3746 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3747 /* translator: %s represents an SQL statement name */
3748 errmsg("%s can only be used in transaction blocks",
3749 stmtType)));
3750}
3751
3752/*
3753 * IsInTransactionBlock
3754 *
3755 * This routine is for statements that need to behave differently inside
3756 * a transaction block than when running as single commands. ANALYZE is
3757 * currently the only example.
3758 *
3759 * If this routine returns "false", then the calling statement is allowed
3760 * to perform internal transaction-commit-and-start cycles; there is not a
3761 * risk of messing up any transaction already in progress. (Note that this
3762 * is not the identical guarantee provided by PreventInTransactionBlock,
3763 * since we will not force a post-statement commit.)
3764 *
3765 * isTopLevel: passed down from ProcessUtility to determine whether we are
3766 * inside a function.
3767 */
3768bool
3769IsInTransactionBlock(bool isTopLevel)
3770{
3771 /*
3772 * Return true on same conditions that would make
3773 * PreventInTransactionBlock error out
3774 */
3775 if (IsTransactionBlock())
3776 return true;
3777
3778 if (IsSubTransaction())
3779 return true;
3780
3781 if (!isTopLevel)
3782 return true;
3783
3786 return true;
3787
3788 return false;
3789}
3790
3791
3792/*
3793 * Register or deregister callback functions for start- and end-of-xact
3794 * operations.
3795 *
3796 * These functions are intended for use by dynamically loaded modules.
3797 * For built-in modules we generally just hardwire the appropriate calls
3798 * (mainly because it's easier to control the order that way, where needed).
3799 *
3800 * At transaction end, the callback occurs post-commit or post-abort, so the
3801 * callback functions can only do noncritical cleanup.
3802 */
3803void
3805{
3806 XactCallbackItem *item;
3807
3808 item = (XactCallbackItem *)
3810 item->callback = callback;
3811 item->arg = arg;
3812 item->next = Xact_callbacks;
3813 Xact_callbacks = item;
3814}
3815
3816void
3818{
3819 XactCallbackItem *item;
3820 XactCallbackItem *prev;
3821
3822 prev = NULL;
3823 for (item = Xact_callbacks; item; prev = item, item = item->next)
3824 {
3825 if (item->callback == callback && item->arg == arg)
3826 {
3827 if (prev)
3828 prev->next = item->next;
3829 else
3830 Xact_callbacks = item->next;
3831 pfree(item);
3832 break;
3833 }
3834 }
3835}
3836
3837static void
3839{
3840 XactCallbackItem *item;
3842
3843 for (item = Xact_callbacks; item; item = next)
3844 {
3845 /* allow callbacks to unregister themselves when called */
3846 next = item->next;
3847 item->callback(event, item->arg);
3848 }
3849}
3850
3851
3852/*
3853 * Register or deregister callback functions for start- and end-of-subxact
3854 * operations.
3855 *
3856 * Pretty much same as above, but for subtransaction events.
3857 *
3858 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3859 * so the callback functions can only do noncritical cleanup. At
3860 * subtransaction start, the callback is called when the subtransaction has
3861 * finished initializing.
3862 */
3863void
3865{
3866 SubXactCallbackItem *item;
3867
3868 item = (SubXactCallbackItem *)
3870 item->callback = callback;
3871 item->arg = arg;
3872 item->next = SubXact_callbacks;
3873 SubXact_callbacks = item;
3874}
3875
3876void
3878{
3879 SubXactCallbackItem *item;
3880 SubXactCallbackItem *prev;
3881
3882 prev = NULL;
3883 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3884 {
3885 if (item->callback == callback && item->arg == arg)
3886 {
3887 if (prev)
3888 prev->next = item->next;
3889 else
3890 SubXact_callbacks = item->next;
3891 pfree(item);
3892 break;
3893 }
3894 }
3895}
3896
3897static void
3899 SubTransactionId mySubid,
3900 SubTransactionId parentSubid)
3901{
3902 SubXactCallbackItem *item;
3904
3905 for (item = SubXact_callbacks; item; item = next)
3906 {
3907 /* allow callbacks to unregister themselves when called */
3908 next = item->next;
3909 item->callback(event, mySubid, parentSubid, item->arg);
3910 }
3911}
3912
3913
3914/* ----------------------------------------------------------------
3915 * transaction block support
3916 * ----------------------------------------------------------------
3917 */
3918
3919/*
3920 * BeginTransactionBlock
3921 * This executes a BEGIN command.
3922 */
3923void
3925{
3927
3928 switch (s->blockState)
3929 {
3930 /*
3931 * We are not inside a transaction block, so allow one to begin.
3932 */
3933 case TBLOCK_STARTED:
3935 break;
3936
3937 /*
3938 * BEGIN converts an implicit transaction block to a regular one.
3939 * (Note that we allow this even if we've already done some
3940 * commands, which is a bit odd but matches historical practice.)
3941 */
3944 break;
3945
3946 /*
3947 * Already a transaction block in progress.
3948 */
3949 case TBLOCK_INPROGRESS:
3952 case TBLOCK_ABORT:
3953 case TBLOCK_SUBABORT:
3955 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3956 errmsg("there is already a transaction in progress")));
3957 break;
3958
3959 /* These cases are invalid. */
3960 case TBLOCK_DEFAULT:
3961 case TBLOCK_BEGIN:
3962 case TBLOCK_SUBBEGIN:
3963 case TBLOCK_END:
3964 case TBLOCK_SUBRELEASE:
3965 case TBLOCK_SUBCOMMIT:
3966 case TBLOCK_ABORT_END:
3970 case TBLOCK_SUBRESTART:
3972 case TBLOCK_PREPARE:
3973 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3975 break;
3976 }
3977}
3978
3979/*
3980 * PrepareTransactionBlock
3981 * This executes a PREPARE command.
3982 *
3983 * Since PREPARE may actually do a ROLLBACK, the result indicates what
3984 * happened: true for PREPARE, false for ROLLBACK.
3985 *
3986 * Note that we don't actually do anything here except change blockState.
3987 * The real work will be done in the upcoming PrepareTransaction().
3988 * We do it this way because it's not convenient to change memory context,
3989 * resource owner, etc while executing inside a Portal.
3990 */
3991bool
3993{
3995 bool result;
3996
3997 /* Set up to commit the current transaction */
3998 result = EndTransactionBlock(false);
3999
4000 /* If successful, change outer tblock state to PREPARE */
4001 if (result)
4002 {
4004
4005 while (s->parent != NULL)
4006 s = s->parent;
4007
4008 if (s->blockState == TBLOCK_END)
4009 {
4010 /* Save GID where PrepareTransaction can find it again */
4012
4014 }
4015 else
4016 {
4017 /*
4018 * ignore case where we are not in a transaction;
4019 * EndTransactionBlock already issued a warning.
4020 */
4023 /* Don't send back a PREPARE result tag... */
4024 result = false;
4025 }
4026 }
4027
4028 return result;
4029}
4030
4031/*
4032 * EndTransactionBlock
4033 * This executes a COMMIT command.
4034 *
4035 * Since COMMIT may actually do a ROLLBACK, the result indicates what
4036 * happened: true for COMMIT, false for ROLLBACK.
4037 *
4038 * Note that we don't actually do anything here except change blockState.
4039 * The real work will be done in the upcoming CommitTransactionCommand().
4040 * We do it this way because it's not convenient to change memory context,
4041 * resource owner, etc while executing inside a Portal.
4042 */
4043bool
4045{
4047 bool result = false;
4048
4049 switch (s->blockState)
4050 {
4051 /*
4052 * We are in a transaction block, so tell CommitTransactionCommand
4053 * to COMMIT.
4054 */
4055 case TBLOCK_INPROGRESS:
4057 result = true;
4058 break;
4059
4060 /*
4061 * We are in an implicit transaction block. If AND CHAIN was
4062 * specified, error. Otherwise commit, but issue a warning
4063 * because there was no explicit BEGIN before this.
4064 */
4066 if (chain)
4067 ereport(ERROR,
4068 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4069 /* translator: %s represents an SQL statement name */
4070 errmsg("%s can only be used in transaction blocks",
4071 "COMMIT AND CHAIN")));
4072 else
4074 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4075 errmsg("there is no transaction in progress")));
4077 result = true;
4078 break;
4079
4080 /*
4081 * We are in a failed transaction block. Tell
4082 * CommitTransactionCommand it's time to exit the block.
4083 */
4084 case TBLOCK_ABORT:
4086 break;
4087
4088 /*
4089 * We are in a live subtransaction block. Set up to subcommit all
4090 * open subtransactions and then commit the main transaction.
4091 */
4093 while (s->parent != NULL)
4094 {
4097 else
4098 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4100 s = s->parent;
4101 }
4102 if (s->blockState == TBLOCK_INPROGRESS)
4104 else
4105 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4107 result = true;
4108 break;
4109
4110 /*
4111 * Here we are inside an aborted subtransaction. Treat the COMMIT
4112 * as ROLLBACK: set up to abort everything and exit the main
4113 * transaction.
4114 */
4115 case TBLOCK_SUBABORT:
4116 while (s->parent != NULL)
4117 {
4120 else if (s->blockState == TBLOCK_SUBABORT)
4122 else
4123 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4125 s = s->parent;
4126 }
4127 if (s->blockState == TBLOCK_INPROGRESS)
4129 else if (s->blockState == TBLOCK_ABORT)
4131 else
4132 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4134 break;
4135
4136 /*
4137 * The user issued COMMIT when not inside a transaction. For
4138 * COMMIT without CHAIN, issue a WARNING, staying in
4139 * TBLOCK_STARTED state. The upcoming call to
4140 * CommitTransactionCommand() will then close the transaction and
4141 * put us back into the default state. For COMMIT AND CHAIN,
4142 * error.
4143 */
4144 case TBLOCK_STARTED:
4145 if (chain)
4146 ereport(ERROR,
4147 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4148 /* translator: %s represents an SQL statement name */
4149 errmsg("%s can only be used in transaction blocks",
4150 "COMMIT AND CHAIN")));
4151 else
4153 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4154 errmsg("there is no transaction in progress")));
4155 result = true;
4156 break;
4157
4158 /*
4159 * The user issued a COMMIT that somehow ran inside a parallel
4160 * worker. We can't cope with that.
4161 */
4163 ereport(FATAL,
4164 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4165 errmsg("cannot commit during a parallel operation")));
4166 break;
4167
4168 /* These cases are invalid. */
4169 case TBLOCK_DEFAULT:
4170 case TBLOCK_BEGIN:
4171 case TBLOCK_SUBBEGIN:
4172 case TBLOCK_END:
4173 case TBLOCK_SUBRELEASE:
4174 case TBLOCK_SUBCOMMIT:
4175 case TBLOCK_ABORT_END:
4179 case TBLOCK_SUBRESTART:
4181 case TBLOCK_PREPARE:
4182 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4184 break;
4185 }
4186
4188 s->blockState == TBLOCK_END ||
4191
4192 s->chain = chain;
4193
4194 return result;
4195}
4196
4197/*
4198 * UserAbortTransactionBlock
4199 * This executes a ROLLBACK command.
4200 *
4201 * As above, we don't actually do anything here except change blockState.
4202 */
4203void
4205{
4207
4208 switch (s->blockState)
4209 {
4210 /*
4211 * We are inside a transaction block and we got a ROLLBACK command
4212 * from the user, so tell CommitTransactionCommand to abort and
4213 * exit the transaction block.
4214 */
4215 case TBLOCK_INPROGRESS:
4217 break;
4218
4219 /*
4220 * We are inside a failed transaction block and we got a ROLLBACK
4221 * command from the user. Abort processing is already done, so
4222 * CommitTransactionCommand just has to cleanup and go back to
4223 * idle state.
4224 */
4225 case TBLOCK_ABORT:
4227 break;
4228
4229 /*
4230 * We are inside a subtransaction. Mark everything up to top
4231 * level as exitable.
4232 */
4234 case TBLOCK_SUBABORT:
4235 while (s->parent != NULL)
4236 {
4239 else if (s->blockState == TBLOCK_SUBABORT)
4241 else
4242 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4244 s = s->parent;
4245 }
4246 if (s->blockState == TBLOCK_INPROGRESS)
4248 else if (s->blockState == TBLOCK_ABORT)
4250 else
4251 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4253 break;
4254
4255 /*
4256 * The user issued ABORT when not inside a transaction. For
4257 * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4258 * The upcoming call to CommitTransactionCommand() will then put
4259 * us back into the default state. For ROLLBACK AND CHAIN, error.
4260 *
4261 * We do the same thing with ABORT inside an implicit transaction,
4262 * although in this case we might be rolling back actual database
4263 * state changes. (It's debatable whether we should issue a
4264 * WARNING in this case, but we have done so historically.)
4265 */
4266 case TBLOCK_STARTED:
4268 if (chain)
4269 ereport(ERROR,
4270 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4271 /* translator: %s represents an SQL statement name */
4272 errmsg("%s can only be used in transaction blocks",
4273 "ROLLBACK AND CHAIN")));
4274 else
4276 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4277 errmsg("there is no transaction in progress")));
4279 break;
4280
4281 /*
4282 * The user issued an ABORT that somehow ran inside a parallel
4283 * worker. We can't cope with that.
4284 */
4286 ereport(FATAL,
4287 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4288 errmsg("cannot abort during a parallel operation")));
4289 break;
4290
4291 /* These cases are invalid. */
4292 case TBLOCK_DEFAULT:
4293 case TBLOCK_BEGIN:
4294 case TBLOCK_SUBBEGIN:
4295 case TBLOCK_END:
4296 case TBLOCK_SUBRELEASE:
4297 case TBLOCK_SUBCOMMIT:
4298 case TBLOCK_ABORT_END:
4302 case TBLOCK_SUBRESTART:
4304 case TBLOCK_PREPARE:
4305 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4307 break;
4308 }
4309
4312
4313 s->chain = chain;
4314}
4315
4316/*
4317 * BeginImplicitTransactionBlock
4318 * Start an implicit transaction block if we're not already in one.
4319 *
4320 * Unlike BeginTransactionBlock, this is called directly from the main loop
4321 * in postgres.c, not within a Portal. So we can just change blockState
4322 * without a lot of ceremony. We do not expect caller to do
4323 * CommitTransactionCommand/StartTransactionCommand.
4324 */
4325void
4327{
4329
4330 /*
4331 * If we are in STARTED state (that is, no transaction block is open),
4332 * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4333 * block.
4334 *
4335 * For caller convenience, we consider all other transaction states as
4336 * legal here; otherwise the caller would need its own state check, which
4337 * seems rather pointless.
4338 */
4339 if (s->blockState == TBLOCK_STARTED)
4341}
4342
4343/*
4344 * EndImplicitTransactionBlock
4345 * End an implicit transaction block, if we're in one.
4346 *
4347 * Like EndTransactionBlock, we just make any needed blockState change here.
4348 * The real work will be done in the upcoming CommitTransactionCommand().
4349 */
4350void
4352{
4354
4355 /*
4356 * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4357 * allowing CommitTransactionCommand to commit whatever happened during
4358 * the implicit transaction block as though it were a single statement.
4359 *
4360 * For caller convenience, we consider all other transaction states as
4361 * legal here; otherwise the caller would need its own state check, which
4362 * seems rather pointless.
4363 */
4366}
4367
4368/*
4369 * DefineSavepoint
4370 * This executes a SAVEPOINT command.
4371 */
4372void
4374{
4376
4377 /*
4378 * Workers synchronize transaction state at the beginning of each parallel
4379 * operation, so we can't account for new subtransactions after that
4380 * point. (Note that this check will certainly error out if s->blockState
4381 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4382 * below.)
4383 */
4385 ereport(ERROR,
4386 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4387 errmsg("cannot define savepoints during a parallel operation")));
4388
4389 switch (s->blockState)
4390 {
4391 case TBLOCK_INPROGRESS:
4393 /* Normal subtransaction start */
4395 s = CurrentTransactionState; /* changed by push */
4396
4397 /*
4398 * Savepoint names, like the TransactionState block itself, live
4399 * in TopTransactionContext.
4400 */
4401 if (name)
4403 break;
4404
4405 /*
4406 * We disallow savepoint commands in implicit transaction blocks.
4407 * There would be no great difficulty in allowing them so far as
4408 * this module is concerned, but a savepoint seems inconsistent
4409 * with exec_simple_query's behavior of abandoning the whole query
4410 * string upon error. Also, the point of an implicit transaction
4411 * block (as opposed to a regular one) is to automatically close
4412 * after an error, so it's hard to see how a savepoint would fit
4413 * into that.
4414 *
4415 * The error messages for this are phrased as if there were no
4416 * active transaction block at all, which is historical but
4417 * perhaps could be improved.
4418 */
4420 ereport(ERROR,
4421 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4422 /* translator: %s represents an SQL statement name */
4423 errmsg("%s can only be used in transaction blocks",
4424 "SAVEPOINT")));
4425 break;
4426
4427 /* These cases are invalid. */
4428 case TBLOCK_DEFAULT:
4429 case TBLOCK_STARTED:
4430 case TBLOCK_BEGIN:
4432 case TBLOCK_SUBBEGIN:
4433 case TBLOCK_END:
4434 case TBLOCK_SUBRELEASE:
4435 case TBLOCK_SUBCOMMIT:
4436 case TBLOCK_ABORT:
4437 case TBLOCK_SUBABORT:
4438 case TBLOCK_ABORT_END:
4442 case TBLOCK_SUBRESTART:
4444 case TBLOCK_PREPARE:
4445 elog(FATAL, "DefineSavepoint: unexpected state %s",
4447 break;
4448 }
4449}
4450
4451/*
4452 * ReleaseSavepoint
4453 * This executes a RELEASE command.
4454 *
4455 * As above, we don't actually do anything here except change blockState.
4456 */
4457void
4459{
4461 TransactionState target,
4462 xact;
4463
4464 /*
4465 * Workers synchronize transaction state at the beginning of each parallel
4466 * operation, so we can't account for transaction state change after that
4467 * point. (Note that this check will certainly error out if s->blockState
4468 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4469 * below.)
4470 */
4472 ereport(ERROR,
4473 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4474 errmsg("cannot release savepoints during a parallel operation")));
4475
4476 switch (s->blockState)
4477 {
4478 /*
4479 * We can't release a savepoint if there is no savepoint defined.
4480 */
4481 case TBLOCK_INPROGRESS:
4482 ereport(ERROR,
4483 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4484 errmsg("savepoint \"%s\" does not exist", name)));
4485 break;
4486
4488 /* See comment about implicit transactions in DefineSavepoint */
4489 ereport(ERROR,
4490 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4491 /* translator: %s represents an SQL statement name */
4492 errmsg("%s can only be used in transaction blocks",
4493 "RELEASE SAVEPOINT")));
4494 break;
4495
4496 /*
4497 * We are in a non-aborted subtransaction. This is the only valid
4498 * case.
4499 */
4501 break;
4502
4503 /* These cases are invalid. */
4504 case TBLOCK_DEFAULT:
4505 case TBLOCK_STARTED:
4506 case TBLOCK_BEGIN:
4508 case TBLOCK_SUBBEGIN:
4509 case TBLOCK_END:
4510 case TBLOCK_SUBRELEASE:
4511 case TBLOCK_SUBCOMMIT:
4512 case TBLOCK_ABORT:
4513 case TBLOCK_SUBABORT:
4514 case TBLOCK_ABORT_END:
4518 case TBLOCK_SUBRESTART:
4520 case TBLOCK_PREPARE:
4521 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4523 break;
4524 }
4525
4526 for (target = s; PointerIsValid(target); target = target->parent)
4527 {
4528 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4529 break;
4530 }
4531
4532 if (!PointerIsValid(target))
4533 ereport(ERROR,
4534 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4535 errmsg("savepoint \"%s\" does not exist", name)));
4536
4537 /* disallow crossing savepoint level boundaries */
4538 if (target->savepointLevel != s->savepointLevel)
4539 ereport(ERROR,
4540 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4541 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4542
4543 /*
4544 * Mark "commit pending" all subtransactions up to the target
4545 * subtransaction. The actual commits will happen when control gets to
4546 * CommitTransactionCommand.
4547 */
4549 for (;;)
4550 {
4553 if (xact == target)
4554 break;
4555 xact = xact->parent;
4556 Assert(PointerIsValid(xact));
4557 }
4558}
4559
4560/*
4561 * RollbackToSavepoint
4562 * This executes a ROLLBACK TO <savepoint> command.
4563 *
4564 * As above, we don't actually do anything here except change blockState.
4565 */
4566void
4568{
4570 TransactionState target,
4571 xact;
4572
4573 /*
4574 * Workers synchronize transaction state at the beginning of each parallel
4575 * operation, so we can't account for transaction state change after that
4576 * point. (Note that this check will certainly error out if s->blockState
4577 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4578 * below.)
4579 */
4581 ereport(ERROR,
4582 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4583 errmsg("cannot rollback to savepoints during a parallel operation")));
4584
4585 switch (s->blockState)
4586 {
4587 /*
4588 * We can't rollback to a savepoint if there is no savepoint
4589 * defined.
4590 */
4591 case TBLOCK_INPROGRESS:
4592 case TBLOCK_ABORT:
4593 ereport(ERROR,
4594 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4595 errmsg("savepoint \"%s\" does not exist", name)));
4596 break;
4597
4599 /* See comment about implicit transactions in DefineSavepoint */
4600 ereport(ERROR,
4601 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4602 /* translator: %s represents an SQL statement name */
4603 errmsg("%s can only be used in transaction blocks",
4604 "ROLLBACK TO SAVEPOINT")));
4605 break;
4606
4607 /*
4608 * There is at least one savepoint, so proceed.
4609 */
4611 case TBLOCK_SUBABORT:
4612 break;
4613
4614 /* These cases are invalid. */
4615 case TBLOCK_DEFAULT:
4616 case TBLOCK_STARTED:
4617 case TBLOCK_BEGIN:
4619 case TBLOCK_SUBBEGIN:
4620 case TBLOCK_END:
4621 case TBLOCK_SUBRELEASE:
4622 case TBLOCK_SUBCOMMIT:
4623 case TBLOCK_ABORT_END:
4627 case TBLOCK_SUBRESTART:
4629 case TBLOCK_PREPARE:
4630 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4632 break;
4633 }
4634
4635 for (target = s; PointerIsValid(target); target = target->parent)
4636 {
4637 if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4638 break;
4639 }
4640
4641 if (!PointerIsValid(target))
4642 ereport(ERROR,
4643 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4644 errmsg("savepoint \"%s\" does not exist", name)));
4645
4646 /* disallow crossing savepoint level boundaries */
4647 if (target->savepointLevel != s->savepointLevel)
4648 ereport(ERROR,
4649 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4650 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4651
4652 /*
4653 * Mark "abort pending" all subtransactions up to the target
4654 * subtransaction. The actual aborts will happen when control gets to
4655 * CommitTransactionCommand.
4656 */
4658 for (;;)
4659 {
4660 if (xact == target)
4661 break;
4662 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4664 else if (xact->blockState == TBLOCK_SUBABORT)
4666 else
4667 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4669 xact = xact->parent;
4670 Assert(PointerIsValid(xact));
4671 }
4672
4673 /* And mark the target as "restart pending" */
4674 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4676 else if (xact->blockState == TBLOCK_SUBABORT)
4678 else
4679 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4681}
4682
4683/*
4684 * BeginInternalSubTransaction
4685 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
4686 * TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_END,
4687 * and TBLOCK_PREPARE states, and therefore it can safely be used in
4688 * functions that might be called when not inside a BEGIN block or when
4689 * running deferred triggers at COMMIT/PREPARE time. Also, it
4690 * automatically does CommitTransactionCommand/StartTransactionCommand
4691 * instead of expecting the caller to do it.
4692 */
4693void
4695{
4697 bool save_ExitOnAnyError = ExitOnAnyError;
4698
4699 /*
4700 * Errors within this function are improbable, but if one does happen we
4701 * force a FATAL exit. Callers generally aren't prepared to handle losing
4702 * control, and moreover our transaction state is probably corrupted if we
4703 * fail partway through; so an ordinary ERROR longjmp isn't okay.
4704 */
4705 ExitOnAnyError = true;
4706
4707 /*
4708 * We do not check for parallel mode here. It's permissible to start and
4709 * end "internal" subtransactions while in parallel mode, so long as no
4710 * new XIDs or command IDs are assigned. Enforcement of that occurs in
4711 * AssignTransactionId() and CommandCounterIncrement().
4712 */
4713
4714 switch (s->blockState)
4715 {
4716 case TBLOCK_STARTED:
4717 case TBLOCK_INPROGRESS:
4720 case TBLOCK_END:
4721 case TBLOCK_PREPARE:
4723 /* Normal subtransaction start */
4725 s = CurrentTransactionState; /* changed by push */
4726
4727 /*
4728 * Savepoint names, like the TransactionState block itself, live
4729 * in TopTransactionContext.
4730 */
4731 if (name)
4733 break;
4734
4735 /* These cases are invalid. */
4736 case TBLOCK_DEFAULT:
4737 case TBLOCK_BEGIN:
4738 case TBLOCK_SUBBEGIN:
4739 case TBLOCK_SUBRELEASE:
4740 case TBLOCK_SUBCOMMIT:
4741 case TBLOCK_ABORT:
4742 case TBLOCK_SUBABORT:
4743 case TBLOCK_ABORT_END:
4747 case TBLOCK_SUBRESTART:
4749 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4751 break;
4752 }
4753
4756
4757 ExitOnAnyError = save_ExitOnAnyError;
4758}
4759
4760/*
4761 * ReleaseCurrentSubTransaction
4762 *
4763 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
4764 * savepoint name (if any).
4765 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4766 */
4767void
4769{
4771
4772 /*
4773 * We do not check for parallel mode here. It's permissible to start and
4774 * end "internal" subtransactions while in parallel mode, so long as no
4775 * new XIDs or command IDs are assigned.
4776 */
4777
4779 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4784 s = CurrentTransactionState; /* changed by pop */
4786}
4787
4788/*
4789 * RollbackAndReleaseCurrentSubTransaction
4790 *
4791 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
4792 * of its savepoint name (if any).
4793 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4794 */
4795void
4797{
4799
4800 /*
4801 * We do not check for parallel mode here. It's permissible to start and
4802 * end "internal" subtransactions while in parallel mode, so long as no
4803 * new XIDs or command IDs are assigned.
4804 */
4805
4806 switch (s->blockState)
4807 {
4808 /* Must be in a subtransaction */
4810 case TBLOCK_SUBABORT:
4811 break;
4812
4813 /* These cases are invalid. */
4814 case TBLOCK_DEFAULT:
4815 case TBLOCK_STARTED:
4816 case TBLOCK_BEGIN:
4819 case TBLOCK_SUBBEGIN:
4820 case TBLOCK_INPROGRESS:
4821 case TBLOCK_END:
4822 case TBLOCK_SUBRELEASE:
4823 case TBLOCK_SUBCOMMIT:
4824 case TBLOCK_ABORT:
4825 case TBLOCK_ABORT_END:
4829 case TBLOCK_SUBRESTART:
4831 case TBLOCK_PREPARE:
4832 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4834 break;
4835 }
4836
4837 /*
4838 * Abort the current subtransaction, if needed.
4839 */
4842
4843 /* And clean it up, too */
4845
4846 s = CurrentTransactionState; /* changed by pop */
4852}
4853
4854/*
4855 * AbortOutOfAnyTransaction
4856 *
4857 * This routine is provided for error recovery purposes. It aborts any
4858 * active transaction or transaction block, leaving the system in a known
4859 * idle state.
4860 */
4861void
4863{
4865
4866 /* Ensure we're not running in a doomed memory context */
4868
4869 /*
4870 * Get out of any transaction or nested transaction
4871 */
4872 do
4873 {
4874 switch (s->blockState)
4875 {
4876 case TBLOCK_DEFAULT:
4877 if (s->state == TRANS_DEFAULT)
4878 {
4879 /* Not in a transaction, do nothing */
4880 }
4881 else
4882 {
4883 /*
4884 * We can get here after an error during transaction start
4885 * (state will be TRANS_START). Need to clean up the
4886 * incompletely started transaction. First, adjust the
4887 * low-level state to suppress warning message from
4888 * AbortTransaction.
4889 */
4890 if (s->state == TRANS_START)
4894 }
4895 break;
4896 case TBLOCK_STARTED:
4897 case TBLOCK_BEGIN:
4898 case TBLOCK_INPROGRESS:
4901 case TBLOCK_END:
4903 case TBLOCK_PREPARE:
4904 /* In a transaction, so clean up */
4908 break;
4909 case TBLOCK_ABORT:
4910 case TBLOCK_ABORT_END:
4911
4912 /*
4913 * AbortTransaction is already done, still need Cleanup.
4914 * However, if we failed partway through running ROLLBACK,
4915 * there will be an active portal running that command, which
4916 * we need to shut down before doing CleanupTransaction.
4917 */
4921 break;
4922
4923 /*
4924 * In a subtransaction, so clean it up and abort parent too
4925 */
4926 case TBLOCK_SUBBEGIN:
4928 case TBLOCK_SUBRELEASE:
4929 case TBLOCK_SUBCOMMIT:
4931 case TBLOCK_SUBRESTART:
4934 s = CurrentTransactionState; /* changed by pop */
4935 break;
4936
4937 case TBLOCK_SUBABORT:
4940 /* As above, but AbortSubTransaction already done */
4941 if (s->curTransactionOwner)
4942 {
4943 /* As in TBLOCK_ABORT, might have a live portal to zap */
4948 }
4950 s = CurrentTransactionState; /* changed by pop */
4951 break;
4952 }
4953 } while (s->blockState != TBLOCK_DEFAULT);
4954
4955 /* Should be out of all subxacts now */
4956 Assert(s->parent == NULL);
4957
4958 /*
4959 * Revert to TopMemoryContext, to ensure we exit in a well-defined state
4960 * whether there were any transactions to close or not. (Callers that
4961 * don't intend to exit soon should switch to some other context to avoid
4962 * long-term memory leaks.)
4963 */
4965}
4966
4967/*
4968 * IsTransactionBlock --- are we within a transaction block?
4969 */
4970bool
4972{
4974
4976 return false;
4977
4978 return true;
4979}
4980
4981/*
4982 * IsTransactionOrTransactionBlock --- are we within either a transaction
4983 * or a transaction block? (The backend is only really "idle" when this
4984 * returns false.)
4985 *
4986 * This should match up with IsTransactionBlock and IsTransactionState.
4987 */
4988bool
4990{
4992
4993 if (s->blockState == TBLOCK_DEFAULT)
4994 return false;
4995
4996 return true;
4997}
4998
4999/*
5000 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
5001 */
5002char
5004{
5006
5007 switch (s->blockState)
5008 {
5009 case TBLOCK_DEFAULT:
5010 case TBLOCK_STARTED:
5011 return 'I'; /* idle --- not in transaction */
5012 case TBLOCK_BEGIN:
5013 case TBLOCK_SUBBEGIN:
5014 case TBLOCK_INPROGRESS:
5018 case TBLOCK_END:
5019 case TBLOCK_SUBRELEASE:
5020 case TBLOCK_SUBCOMMIT:
5021 case TBLOCK_PREPARE:
5022 return 'T'; /* in transaction */
5023 case TBLOCK_ABORT:
5024 case TBLOCK_SUBABORT:
5025 case TBLOCK_ABORT_END:
5029 case TBLOCK_SUBRESTART:
5031 return 'E'; /* in failed transaction */
5032 }
5033
5034 /* should never get here */
5035 elog(FATAL, "invalid transaction block state: %s",
5037 return 0; /* keep compiler quiet */
5038}
5039
5040/*
5041 * IsSubTransaction
5042 */
5043bool
5045{
5047
5048 if (s->nestingLevel >= 2)
5049 return true;
5050
5051 return false;
5052}
5053
5054/*
5055 * StartSubTransaction
5056 *
5057 * If you're wondering why this is separate from PushTransaction: it's because
5058 * we can't conveniently do this stuff right inside DefineSavepoint. The
5059 * SAVEPOINT utility command will be executed inside a Portal, and if we
5060 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
5061 * the Portal will undo those settings. So we make DefineSavepoint just
5062 * push a dummy transaction block, and when control returns to the main
5063 * idle loop, CommitTransactionCommand will be called, and we'll come here
5064 * to finish starting the subtransaction.
5065 */
5066static void
5068{
5070
5071 if (s->state != TRANS_DEFAULT)
5072 elog(WARNING, "StartSubTransaction while in %s state",
5074
5075 s->state = TRANS_START;
5076
5077 /*
5078 * Initialize subsystems for new subtransaction
5079 *
5080 * must initialize resource-management stuff first
5081 */
5085
5087
5088 /*
5089 * Call start-of-subxact callbacks
5090 */
5093
5094 ShowTransactionState("StartSubTransaction");
5095}
5096
5097/*
5098 * CommitSubTransaction
5099 *
5100 * The caller has to make sure to always reassign CurrentTransactionState
5101 * if it has a local pointer to it after calling this function.
5102 */
5103static void
5105{
5107
5108 ShowTransactionState("CommitSubTransaction");
5109
5110 if (s->state != TRANS_INPROGRESS)
5111 elog(WARNING, "CommitSubTransaction while in %s state",
5113
5114 /* Pre-commit processing goes here */
5115
5118
5119 /*
5120 * If this subxact has started any unfinished parallel operation, clean up
5121 * its workers and exit parallel mode. Warn about leaked resources.
5122 */
5124 if (s->parallelModeLevel != 0)
5125 {
5126 elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5128 s->parallelModeLevel = 0;
5129 }
5130
5131 /* Do the actual "commit", such as it is */
5132 s->state = TRANS_COMMIT;
5133
5134 /* Must CCI to ensure commands of subtransaction are seen as done */
5136
5137 /*
5138 * Prior to 8.4 we marked subcommit in clog at this point. We now only
5139 * perform that step, if required, as part of the atomic update of the
5140 * whole transaction tree at top level commit or abort.
5141 */
5142
5143 /* Post-commit cleanup */
5149 s->parent->nestingLevel,
5154
5157
5160 true, false);
5164 AtEOSubXact_Inval(true);
5166
5167 /*
5168 * The only lock we actually release here is the subtransaction XID lock.
5169 */
5173
5174 /*
5175 * Other locks should get transferred to their parent resource owner.
5176 */
5179 true, false);
5182 true, false);
5183
5184 AtEOXact_GUC(true, s->gucNestLevel);
5195
5196 /*
5197 * We need to restore the upper transaction's read-only state, in case the
5198 * upper is read-write while the child is read-only; GUC will incorrectly
5199 * think it should leave the child state in place.
5200 */
5202
5206 s->curTransactionOwner = NULL;
5207
5209
5210 s->state = TRANS_DEFAULT;
5211
5213}
5214
5215/*
5216 * AbortSubTransaction
5217 */
5218static void
5220{
5222
5223 /* Prevent cancel/die interrupt while cleaning up */
5225
5226 /* Make sure we have a valid memory context and resource owner */
5229
5230 /*
5231 * Release any LW locks we might be holding as quickly as possible.
5232 * (Regular locks, however, must be held till we finish aborting.)
5233 * Releasing LW locks is critical since we might try to grab them again
5234 * while cleaning up!
5235 *
5236 * FIXME This may be incorrect --- Are there some locks we should keep?
5237 * Buffer locks, for example? I don't think so but I'm not sure.
5238 */
5240
5243
5245
5246 UnlockBuffers();
5247
5248 /* Reset WAL record construction state */
5250
5251 /* Cancel condition variable sleep */
5253
5254 /*
5255 * Also clean up any open wait for lock, since the lock manager will choke
5256 * if we try to wait for another lock before doing this.
5257 */
5259
5260 /*
5261 * If any timeout events are still active, make sure the timeout interrupt
5262 * is scheduled. This covers possible loss of a timeout interrupt due to
5263 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5264 * We delay this till after LockErrorCleanup so that we don't uselessly
5265 * reschedule lock or deadlock check timeouts.
5266 */
5268
5269 /*
5270 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5271 * handler. We do this fairly early in the sequence so that the timeout
5272 * infrastructure will be functional if needed while aborting.
5273 */
5274 sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
5275
5276 /*
5277 * check the current transaction state
5278 */
5279 ShowTransactionState("AbortSubTransaction");
5280
5281 if (s->state != TRANS_INPROGRESS)
5282 elog(WARNING, "AbortSubTransaction while in %s state",
5284
5285 s->state = TRANS_ABORT;
5286
5287 /*
5288 * Reset user ID which might have been changed transiently. (See notes in
5289 * AbortTransaction.)
5290 */
5292
5293 /* Forget about any active REINDEX. */
5295
5296 /* Reset logical streaming state. */
5298
5299 /*
5300 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5301 * exports are not supported in subtransactions.
5302 */
5303
5304 /*
5305 * If this subxact has started any unfinished parallel operation, clean up
5306 * its workers and exit parallel mode. Don't warn about leaked resources.
5307 */
5309 s->parallelModeLevel = 0;
5310
5311 /*
5312 * We can skip all this stuff if the subxact failed before creating a
5313 * ResourceOwner...
5314 */
5315 if (s->curTransactionOwner)
5316 {
5325
5326 /* Advertise the fact that we aborted in pg_xact. */
5327 (void) RecordTransactionAbort(true);
5328
5329 /* Post-abort cleanup */
5332
5335
5338 false, false);
5339
5340 AtEOXact_Aio(false);
5344 AtEOSubXact_Inval(false);
5347 false, false);
5350 false, false);
5352
5353 AtEOXact_GUC(false, s->gucNestLevel);
5364 }
5365
5366 /*
5367 * Restore the upper transaction's read-only state, too. This should be
5368 * redundant with GUC's cleanup but we may as well do it for consistency
5369 * with the commit case.
5370 */
5372
5374}
5375
5376/*
5377 * CleanupSubTransaction
5378 *
5379 * The caller has to make sure to always reassign CurrentTransactionState
5380 * if it has a local pointer to it after calling this function.
5381 */
5382static void
5384{
5386
5387 ShowTransactionState("CleanupSubTransaction");
5388
5389 if (s->state != TRANS_ABORT)
5390 elog(WARNING, "CleanupSubTransaction while in %s state",
5392
5394
5397 if (s->curTransactionOwner)
5399 s->curTransactionOwner = NULL;
5400
5402
5403 s->state = TRANS_DEFAULT;
5404
5406}
5407
5408/*
5409 * PushTransaction
5410 * Create transaction state stack entry for a subtransaction
5411 *
5412 * The caller has to make sure to always reassign CurrentTransactionState
5413 * if it has a local pointer to it after calling this function.
5414 */
5415static void
5417{
5420
5421 /*
5422 * We keep subtransaction state nodes in TopTransactionContext.
5423 */
5424 s = (TransactionState)
5426 sizeof(TransactionStateData));
5427
5428 /*
5429 * Assign a subtransaction ID, watching out for counter wraparound.
5430 */
5433 {
5435 pfree(s);
5436 ereport(ERROR,
5437 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5438 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5439 }
5440
5441 /*
5442 * We can now stack a minimally valid subtransaction without fear of
5443 * failure.
5444 */
5445 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5447 s->parent = p;
5448 s->nestingLevel = p->nestingLevel + 1;
5451 s->state = TRANS_DEFAULT;
5456 s->parallelModeLevel = 0;
5458 s->topXidLogged = false;
5459
5461
5462 /*
5463 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5464 * with the subtransaction from here on out; in particular they should not
5465 * assume that it necessarily has a transaction context, resource owner,
5466 * or XID.
5467 */
5468}
5469
5470/*
5471 * PopTransaction
5472 * Pop back to parent transaction state
5473 *
5474 * The caller has to make sure to always reassign CurrentTransactionState
5475 * if it has a local pointer to it after calling this function.
5476 */
5477static void
5479{
5481
5482 if (s->state != TRANS_DEFAULT)
5483 elog(WARNING, "PopTransaction while in %s state",
5485
5486 if (s->parent == NULL)
5487 elog(FATAL, "PopTransaction with no parent");
5488
5490
5491 /* Let's just make sure CurTransactionContext is good */
5494
5495 /* Ditto for ResourceOwner links */
5498
5499 /* Free the old child structure */
5500 if (s->name)
5501 pfree(s->name);
5502 pfree(s);
5503}
5504
5505/*
5506 * EstimateTransactionStateSpace
5507 * Estimate the amount of space that will be needed by
5508 * SerializeTransactionState. It would be OK to overestimate slightly,
5509 * but it's simple for us to work out the precise value, so we do.
5510 */
5511Size
5513{
5515 Size nxids = 0;
5517
5518 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5519 {
5521 nxids = add_size(nxids, 1);
5522 nxids = add_size(nxids, s->nChildXids);
5523 }
5524
5525 return add_size(size, mul_size(sizeof(TransactionId), nxids));
5526}
5527
5528/*
5529 * SerializeTransactionState
5530 * Write out relevant details of our transaction state that will be
5531 * needed by a parallel worker.
5532 *
5533 * We need to save and restore XactDeferrable, XactIsoLevel, and the XIDs
5534 * associated with this transaction. These are serialized into a
5535 * caller-supplied buffer big enough to hold the number of bytes reported by
5536 * EstimateTransactionStateSpace(). We emit the XIDs in sorted order for the
5537 * convenience of the receiving process.
5538 */
5539void
5540SerializeTransactionState(Size maxsize, char *start_address)
5541{
5543 Size nxids = 0;
5544 Size i = 0;
5545 TransactionId *workspace;
5547
5548 result = (SerializedTransactionState *) start_address;
5549
5550 result->xactIsoLevel = XactIsoLevel;
5553 result->currentFullTransactionId =
5556
5557 /*
5558 * If we're running in a parallel worker and launching a parallel worker
5559 * of our own, we can just pass along the information that was passed to
5560 * us.
5561 */
5562 if (nParallelCurrentXids > 0)
5563 {
5565 memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
5567 return;
5568 }
5569
5570 /*
5571 * OK, we need to generate a sorted list of XIDs that our workers should
5572 * view as current. First, figure out how many there are.
5573 */
5574 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5575 {
5577 nxids = add_size(nxids, 1);
5578 nxids = add_size(nxids, s->nChildXids);
5579 }
5581 <= maxsize);
5582
5583 /* Copy them to our scratch space. */
5584 workspace = palloc(nxids * sizeof(TransactionId));
5585 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5586 {
5588 workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5589 if (s->nChildXids > 0)
5590 memcpy(&workspace[i], s->childXids,
5591 s->nChildXids * sizeof(TransactionId));
5592 i += s->nChildXids;
5593 }
5594 Assert(i == nxids);
5595
5596 /* Sort them. */
5597 qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5598
5599 /* Copy data into output area. */
5600 result->nParallelCurrentXids = nxids;
5601 memcpy(&result->parallelCurrentXids[0], workspace,
5602 nxids * sizeof(TransactionId));
5603}
5604
5605/*
5606 * StartParallelWorkerTransaction
5607 * Start a parallel worker transaction, restoring the relevant
5608 * transaction state serialized by SerializeTransactionState.
5609 */
5610void
5612{
5614
5617
5618 tstate = (SerializedTransactionState *) tstatespace;
5619 XactIsoLevel = tstate->xactIsoLevel;
5627
5629}
5630
5631/*
5632 * EndParallelWorkerTransaction
5633 * End a parallel worker transaction.
5634 */
5635void
5637{
5641}
5642
5643/*
5644 * ShowTransactionState
5645 * Debug support
5646 */
5647static void
5649{
5650 /* skip work if message will definitely not be printed */
5653}
5654
5655/*
5656 * ShowTransactionStateRec
5657 * Recursive subroutine for ShowTransactionState
5658 */
5659static void
5661{
5663
5664 if (s->parent)
5665 {
5666 /*
5667 * Since this function recurses, it could be driven to stack overflow.
5668 * This is just a debugging aid, so we can leave out some details
5669 * instead of erroring out with check_stack_depth().
5670 */
5671 if (stack_is_too_deep())
5673 (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5674 str, s->nestingLevel)));
5675 else
5677 }
5678
5680 if (s->nChildXids > 0)
5681 {
5682 int i;
5683
5684 appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5685 for (i = 1; i < s->nChildXids; i++)
5686 appendStringInfo(&buf, " %u", s->childXids[i]);
5687 }
5689 (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5690 str, s->nestingLevel,
5691 PointerIsValid(s->name) ? s->name : "unnamed",
5695 (unsigned int) s->subTransactionId,
5696 (unsigned int) currentCommandId,
5697 currentCommandIdUsed ? " (used)" : "",
5698 buf.data)));
5699 pfree(buf.data);
5700}
5701
5702/*
5703 * BlockStateAsString
5704 * Debug support
5705 */
5706static const char *
5708{
5709 switch (blockState)
5710 {
5711 case TBLOCK_DEFAULT:
5712 return "DEFAULT";
5713 case TBLOCK_STARTED:
5714 return "STARTED";
5715 case TBLOCK_BEGIN:
5716 return "BEGIN";
5717 case TBLOCK_INPROGRESS:
5718 return "INPROGRESS";
5720 return "IMPLICIT_INPROGRESS";
5722 return "PARALLEL_INPROGRESS";
5723 case TBLOCK_END:
5724 return "END";
5725 case TBLOCK_ABORT:
5726 return "ABORT";
5727 case TBLOCK_ABORT_END:
5728 return "ABORT_END";
5730 return "ABORT_PENDING";
5731 case TBLOCK_PREPARE:
5732 return "PREPARE";
5733 case TBLOCK_SUBBEGIN:
5734 return "SUBBEGIN";
5736 return "SUBINPROGRESS";
5737 case TBLOCK_SUBRELEASE:
5738 return "SUBRELEASE";
5739 case TBLOCK_SUBCOMMIT:
5740 return "SUBCOMMIT";
5741 case TBLOCK_SUBABORT:
5742 return "SUBABORT";
5744 return "SUBABORT_END";
5746 return "SUBABORT_PENDING";
5747 case TBLOCK_SUBRESTART:
5748 return "SUBRESTART";
5750 return "SUBABORT_RESTART";
5751 }
5752 return "UNRECOGNIZED";
5753}
5754
5755/*
5756 * TransStateAsString
5757 * Debug support
5758 */
5759static const char *
5761{
5762 switch (state)
5763 {
5764 case TRANS_DEFAULT:
5765 return "DEFAULT";
5766 case TRANS_START:
5767 return "START";
5768 case TRANS_INPROGRESS:
5769 return "INPROGRESS";
5770 case TRANS_COMMIT:
5771 return "COMMIT";
5772 case TRANS_ABORT:
5773 return "ABORT";
5774 case TRANS_PREPARE:
5775 return "PREPARE";
5776 }
5777 return "UNRECOGNIZED";
5778}
5779
5780/*
5781 * xactGetCommittedChildren
5782 *
5783 * Gets the list of committed children of the current transaction. The return
5784 * value is the number of child transactions. *ptr is set to point to an
5785 * array of TransactionIds. The array is allocated in TopTransactionContext;
5786 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
5787 * If there are no subxacts, *ptr is set to NULL.
5788 */
5789int
5791{
5793
5794 if (s->nChildXids == 0)
5795 *ptr = NULL;
5796 else
5797 *ptr = s->childXids;
5798
5799 return s->nChildXids;
5800}
5801
5802/*
5803 * XLOG support routines
5804 */
5805
5806
5807/*
5808 * Log the commit record for a plain or twophase transaction commit.
5809 *
5810 * A 2pc commit will be emitted when twophase_xid is valid, a plain one
5811 * otherwise.
5812 */
5815 int nsubxacts, TransactionId *subxacts,
5816 int nrels, RelFileLocator *rels,
5817 int ndroppedstats, xl_xact_stats_item *droppedstats,
5818 int nmsgs, SharedInvalidationMessage *msgs,
5819 bool relcacheInval,
5820 int xactflags, TransactionId twophase_xid,
5821 const char *twophase_gid)
5822{
5823 xl_xact_commit xlrec;
5824 xl_xact_xinfo xl_xinfo;
5825 xl_xact_dbinfo xl_dbinfo;
5826 xl_xact_subxacts xl_subxacts;
5827 xl_xact_relfilelocators xl_relfilelocators;
5828 xl_xact_stats_items xl_dropped_stats;
5829 xl_xact_invals xl_invals;
5830 xl_xact_twophase xl_twophase;
5831 xl_xact_origin xl_origin;
5832 uint8 info;
5833
5835
5836 xl_xinfo.xinfo = 0;
5837
5838 /* decide between a plain and 2pc commit */
5839 if (!TransactionIdIsValid(twophase_xid))
5840 info = XLOG_XACT_COMMIT;
5841 else
5843
5844 /* First figure out and collect all the information needed */
5845
5846 xlrec.xact_time = commit_time;
5847
5848 if (relcacheInval)
5850 if (forceSyncCommit)
5853 xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5854
5855 /*
5856 * Check if the caller would like to ask standbys for immediate feedback
5857 * once this commit is applied.
5858 */
5861
5862 /*
5863 * Relcache invalidations requires information about the current database
5864 * and so does logical decoding.
5865 */
5866 if (nmsgs > 0 || XLogLogicalInfoActive())
5867 {
5868 xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5869 xl_dbinfo.dbId = MyDatabaseId;
5870 xl_dbinfo.tsId = MyDatabaseTableSpace;
5871 }
5872
5873 if (nsubxacts > 0)
5874 {
5875 xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5876 xl_subxacts.nsubxacts = nsubxacts;
5877 }
5878
5879 if (nrels > 0)
5880 {
5882 xl_relfilelocators.nrels = nrels;
5883 info |= XLR_SPECIAL_REL_UPDATE;
5884 }
5885
5886 if (ndroppedstats > 0)
5887 {
5889 xl_dropped_stats.nitems = ndroppedstats;
5890 }
5891
5892 if (nmsgs > 0)
5893 {
5894 xl_xinfo.xinfo |= XACT_XINFO_HAS_INVALS;
5895 xl_invals.nmsgs = nmsgs;
5896 }
5897
5898 if (TransactionIdIsValid(twophase_xid))
5899 {
5900 xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5901 xl_twophase.xid = twophase_xid;
5902 Assert(twophase_gid != NULL);
5903
5905 xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
5906 }
5907
5908 /* dump transaction origin information */
5910 {
5911 xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
5912
5915 }
5916
5917 if (xl_xinfo.xinfo != 0)
5918 info |= XLOG_XACT_HAS_INFO;
5919
5920 /* Then include all the collected data into the commit record. */
5921
5923
5924 XLogRegisterData(&xlrec, sizeof(xl_xact_commit));
5925
5926 if (xl_xinfo.xinfo != 0)
5927 XLogRegisterData(&xl_xinfo.xinfo, sizeof(xl_xinfo.xinfo));
5928
5929 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5930 XLogRegisterData(&xl_dbinfo, sizeof(xl_dbinfo));
5931
5932 if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5933 {
5934 XLogRegisterData(&xl_subxacts,
5936 XLogRegisterData(subxacts,
5937 nsubxacts * sizeof(TransactionId));
5938 }
5939
5941 {
5942 XLogRegisterData(&xl_relfilelocators,
5944 XLogRegisterData(rels,
5945 nrels * sizeof(RelFileLocator));
5946 }
5947
5948 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
5949 {
5950 XLogRegisterData(&xl_dropped_stats,
5952 XLogRegisterData(droppedstats,
5953 ndroppedstats * sizeof(xl_xact_stats_item));
5954 }
5955
5956 if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
5957 {
5959 XLogRegisterData(msgs,
5960 nmsgs * sizeof(SharedInvalidationMessage));
5961 }
5962
5963 if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5964 {
5965 XLogRegisterData(&xl_twophase, sizeof(xl_xact_twophase));
5966 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
5967 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
5968 }
5969
5970 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5971 XLogRegisterData(&xl_origin, sizeof(xl_xact_origin));
5972
5973 /* we allow filtering by xacts */
5975
5976 return XLogInsert(RM_XACT_ID, info);
5977}
5978
5979/*
5980 * Log the commit record for a plain or twophase transaction abort.
5981 *
5982 * A 2pc abort will be emitted when twophase_xid is valid, a plain one
5983 * otherwise.
5984 */
5987 int nsubxacts, TransactionId *subxacts,
5988 int nrels, RelFileLocator *rels,
5989 int ndroppedstats, xl_xact_stats_item *droppedstats,
5990 int xactflags, TransactionId twophase_xid,
5991 const char *twophase_gid)
5992{
5993 xl_xact_abort xlrec;
5994 xl_xact_xinfo xl_xinfo;
5995 xl_xact_subxacts xl_subxacts;
5996 xl_xact_relfilelocators xl_relfilelocators;
5997 xl_xact_stats_items xl_dropped_stats;
5998 xl_xact_twophase xl_twophase;
5999 xl_xact_dbinfo xl_dbinfo;
6000 xl_xact_origin xl_origin;
6001
6002 uint8 info;
6003
6005
6006 xl_xinfo.xinfo = 0;
6007
6008 /* decide between a plain and 2pc abort */
6009 if (!TransactionIdIsValid(twophase_xid))
6010 info = XLOG_XACT_ABORT;
6011 else
6013
6014
6015 /* First figure out and collect all the information needed */
6016
6017 xlrec.xact_time = abort_time;
6018
6020 xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
6021
6022 if (nsubxacts > 0)
6023 {
6024 xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
6025 xl_subxacts.nsubxacts = nsubxacts;
6026 }
6027
6028 if (nrels > 0)
6029 {
6031 xl_relfilelocators.nrels = nrels;
6032 info |= XLR_SPECIAL_REL_UPDATE;
6033 }
6034
6035 if (ndroppedstats > 0)
6036 {
6038 xl_dropped_stats.nitems = ndroppedstats;
6039 }
6040
6041 if (TransactionIdIsValid(twophase_xid))
6042 {
6043 xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
6044 xl_twophase.xid = twophase_xid;
6045 Assert(twophase_gid != NULL);
6046
6048 xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
6049 }
6050
6051 if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6052 {
6053 xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
6054 xl_dbinfo.dbId = MyDatabaseId;
6055 xl_dbinfo.tsId = MyDatabaseTableSpace;
6056 }
6057
6058 /*
6059 * Dump transaction origin information. We need this during recovery to
6060 * update the replication origin progress.
6061 */
6063 {
6064 xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
6065
6068 }
6069
6070 if (xl_xinfo.xinfo != 0)
6071 info |= XLOG_XACT_HAS_INFO;
6072
6073 /* Then include all the collected data into the abort record. */
6074
6076
6078
6079 if (xl_xinfo.xinfo != 0)
6080 XLogRegisterData(&xl_xinfo, sizeof(xl_xinfo));
6081
6082 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6083 XLogRegisterData(&xl_dbinfo, sizeof(xl_dbinfo));
6084
6085 if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
6086 {
6087 XLogRegisterData(&xl_subxacts,
6089 XLogRegisterData(subxacts,
6090 nsubxacts * sizeof(TransactionId));
6091 }
6092
6094 {
6095 XLogRegisterData(&xl_relfilelocators,
6097 XLogRegisterData(rels,
6098 nrels * sizeof(RelFileLocator));
6099 }
6100
6101 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
6102 {
6103 XLogRegisterData(&xl_dropped_stats,
6105 XLogRegisterData(droppedstats,
6106 ndroppedstats * sizeof(xl_xact_stats_item));
6107 }
6108
6109 if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
6110 {
6111 XLogRegisterData(&xl_twophase, sizeof(xl_xact_twophase));
6112 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6113 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6114 }
6115
6116 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6117 XLogRegisterData(&xl_origin, sizeof(xl_xact_origin));
6118
6119 /* Include the replication origin */
6121
6122 return XLogInsert(RM_XACT_ID, info);
6123}
6124
6125/*
6126 * Before 9.0 this was a fairly short function, but now it performs many
6127 * actions for which the order of execution is critical.
6128 */
6129static void
6131 TransactionId xid,
6132 XLogRecPtr lsn,
6133 RepOriginId origin_id)
6134{
6135 TransactionId max_xid;
6136 TimestampTz commit_time;
6137
6139
6140 max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
6141
6142 /* Make sure nextXid is beyond any XID mentioned in the record. */
6144
6145 Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) ==
6146 (origin_id == InvalidRepOriginId));
6147
6148 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6149 commit_time = parsed->origin_timestamp;
6150 else
6151 commit_time = parsed->xact_time;
6152
6153 /* Set the transaction commit timestamp and metadata */
6155 commit_time, origin_id);
6156
6158 {
6159 /*
6160 * Mark the transaction committed in pg_xact.
6161 */
6162 TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
6163 }
6164 else
6165 {
6166 /*
6167 * If a transaction completion record arrives that has as-yet
6168 * unobserved subtransactions then this will not have been fully
6169 * handled by the call to RecordKnownAssignedTransactionIds() in the
6170 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6171 * cover that case. This is confusing and it is easy to think this
6172 * call is irrelevant, which has happened three times in development
6173 * already. Leave it in.
6174 */
6176
6177 /*
6178 * Mark the transaction committed in pg_xact. We use async commit
6179 * protocol during recovery to provide information on database
6180 * consistency for when users try to set hint bits. It is important
6181 * that we do not set hint bits until the minRecoveryPoint is past
6182 * this commit record. This ensures that if we crash we don't see hint
6183 * bits set on changes made by transactions that haven't yet
6184 * recovered. It's unlikely but it's good to be safe.
6185 */
6186 TransactionIdAsyncCommitTree(xid, parsed->nsubxacts, parsed->subxacts, lsn);
6187
6188 /*
6189 * We must mark clog before we update the ProcArray.
6190 */
6191 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6192
6193 /*
6194 * Send any cache invalidations attached to the commit. We must
6195 * maintain the same order of invalidation then release locks as
6196 * occurs in CommitTransaction().
6197 */
6200 parsed->dbId, parsed->tsId);
6201
6202 /*
6203 * Release locks, if any. We do this for both two phase and normal one
6204 * phase transactions. In effect we are ignoring the prepare phase and
6205 * just going straight to lock release.
6206 */
6207 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6208 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6209 }
6210
6211 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6212 {
6213 /* recover apply progress */
6214 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6215 false /* backward */ , false /* WAL */ );
6216 }
6217
6218 /* Make sure files supposed to be dropped are dropped */
6219 if (parsed->nrels > 0)
6220 {
6221 /*
6222 * First update minimum recovery point to cover this WAL record. Once
6223 * a relation is deleted, there's no going back. The buffer manager
6224 * enforces the WAL-first rule for normal updates to relation files,
6225 * so that the minimum recovery point is always updated before the
6226 * corresponding change in the data file is flushed to disk, but we
6227 * have to do the same here since we're bypassing the buffer manager.
6228 *
6229 * Doing this before deleting the files means that if a deletion fails
6230 * for some reason, you cannot start up the system even after restart,
6231 * until you fix the underlying situation so that the deletion will
6232 * succeed. Alternatively, we could update the minimum recovery point
6233 * after deletion, but that would leave a small window where the
6234 * WAL-first rule would be violated.
6235 */
6236 XLogFlush(lsn);
6237
6238 /* Make sure files supposed to be dropped are dropped */
6239 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6240 }
6241
6242 if (parsed->nstats > 0)
6243 {
6244 /* see equivalent call for relations above */
6245 XLogFlush(lsn);
6246
6247 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6248 }
6249
6250 /*
6251 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
6252 * in normal operation. For example, in CREATE DATABASE, we copy all files
6253 * from the template database, and then commit the transaction. If we
6254 * crash after all the files have been copied but before the commit, you
6255 * have files in the data directory without an entry in pg_database. To
6256 * minimize the window for that, we use ForceSyncCommit() to rush the
6257 * commit record to disk as quick as possible. We have the same window
6258 * during recovery, and forcing an XLogFlush() (which updates
6259 * minRecoveryPoint during recovery) helps to reduce that problem window,
6260 * for any user that requested ForceSyncCommit().
6261 */
6263 XLogFlush(lsn);
6264
6265 /*
6266 * If asked by the primary (because someone is waiting for a synchronous
6267 * commit = remote_apply), we will need to ask walreceiver to send a reply
6268 * immediately.
6269 */
6272}
6273
6274/*
6275 * Be careful with the order of execution, as with xact_redo_commit().
6276 * The two functions are similar but differ in key places.
6277 *
6278 * Note also that an abort can be for a subtransaction and its children,
6279 * not just for a top level abort. That means we have to consider
6280 * topxid != xid, whereas in commit we would find topxid == xid always
6281 * because subtransaction commit is never WAL logged.
6282 */
6283static void
6285 XLogRecPtr lsn, RepOriginId origin_id)
6286{
6287 TransactionId max_xid;
6288
6290
6291 /* Make sure nextXid is beyond any XID mentioned in the record. */
6292 max_xid = TransactionIdLatest(xid,
6293 parsed->nsubxacts,
6294 parsed->subxacts);
6296
6298 {
6299 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6300 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6301 }
6302 else
6303 {
6304 /*
6305 * If a transaction completion record arrives that has as-yet
6306 * unobserved subtransactions then this will not have been fully
6307 * handled by the call to RecordKnownAssignedTransactionIds() in the
6308 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6309 * cover that case. This is confusing and it is easy to think this
6310 * call is irrelevant, which has happened three times in development
6311 * already. Leave it in.
6312 */
6314
6315 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6316 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6317
6318 /*
6319 * We must update the ProcArray after we have marked clog.
6320 */
6321 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6322
6323 /*
6324 * There are no invalidation messages to send or undo.
6325 */
6326
6327 /*
6328 * Release locks, if any. There are no invalidations to send.
6329 */
6330 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6331 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6332 }
6333
6334 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6335 {
6336 /* recover apply progress */
6337 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6338 false /* backward */ , false /* WAL */ );
6339 }
6340
6341 /* Make sure files supposed to be dropped are dropped */
6342 if (parsed->nrels > 0)
6343 {
6344 /*
6345 * See comments about update of minimum recovery point on truncation,
6346 * in xact_redo_commit().
6347 */
6348 XLogFlush(lsn);
6349
6350 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6351 }
6352
6353 if (parsed->nstats > 0)
6354 {
6355 /* see equivalent call for relations above */
6356 XLogFlush(lsn);
6357
6358 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6359 }
6360}
6361
6362void
6364{
6365 uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6366
6367 /* Backup blocks are not used in xact records */
6369
6370 if (info == XLOG_XACT_COMMIT)
6371 {
6372 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6373 xl_xact_parsed_commit parsed;
6374
6375 ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6376 xact_redo_commit(&parsed, XLogRecGetXid(record),
6377 record->EndRecPtr, XLogRecGetOrigin(record));
6378 }
6379 else if (info == XLOG_XACT_COMMIT_PREPARED)
6380 {
6381 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6382 xl_xact_parsed_commit parsed;
6383
6384 ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6385 xact_redo_commit(&parsed, parsed.twophase_xid,
6386 record->EndRecPtr, XLogRecGetOrigin(record));
6387
6388 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6389 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6390 PrepareRedoRemove(parsed.twophase_xid, false);
6391 LWLockRelease(TwoPhaseStateLock);
6392 }
6393 else if (info == XLOG_XACT_ABORT)
6394 {
6395 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6396 xl_xact_parsed_abort parsed;
6397
6398 ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6399 xact_redo_abort(&parsed, XLogRecGetXid(record),
6400 record->EndRecPtr, XLogRecGetOrigin(record));
6401 }
6402 else if (info == XLOG_XACT_ABORT_PREPARED)
6403 {
6404 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6405 xl_xact_parsed_abort parsed;
6406
6407 ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6408 xact_redo_abort(&parsed, parsed.twophase_xid,
6409 record->EndRecPtr, XLogRecGetOrigin(record));
6410
6411 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6412 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6413 PrepareRedoRemove(parsed.twophase_xid, false);
6414 LWLockRelease(TwoPhaseStateLock);
6415 }
6416 else if (info == XLOG_XACT_PREPARE)
6417 {
6418 /*
6419 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6420 * gxact entry.
6421 */
6422 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6424 record->ReadRecPtr,
6425 record->EndRecPtr,
6426 XLogRecGetOrigin(record));
6427 LWLockRelease(TwoPhaseStateLock);
6428 }
6429 else if (info == XLOG_XACT_ASSIGNMENT)
6430 {
6432
6435 xlrec->nsubxacts, xlrec->xsub);
6436 }
6437 else if (info == XLOG_XACT_INVALIDATIONS)
6438 {
6439 /*
6440 * XXX we do ignore this for now, what matters are invalidations
6441 * written into the commit record.
6442 */
6443 }
6444 else
6445 elog(PANIC, "xact_redo: unknown op code %u", info);
6446}
void pgaio_error_cleanup(void)
Definition: aio.c:1062
void AtEOXact_Aio(bool is_commit)
Definition: aio.c:1090
void AtCommit_Notify(void)
Definition: async.c:968
void AtAbort_Notify(void)
Definition: async.c:1671
void PreCommit_Notify(void)
Definition: async.c:861
void AtSubAbort_Notify(void)
Definition: async.c:1761
void AtPrepare_Notify(void)
Definition: async.c:836
void AtSubCommit_Notify(void)
Definition: async.c:1691
void ParallelWorkerReportLastRecEnd(XLogRecPtr last_xlog_end)
Definition: parallel.c:1586
bool ParallelContextActive(void)
Definition: parallel.c:1024
void AtEOSubXact_Parallel(bool isCommit, SubTransactionId mySubId)
Definition: parallel.c:1254
void AtEOXact_Parallel(bool isCommit)
Definition: parallel.c:1275
sigset_t UnBlockSig
Definition: pqsignal.c:22
void AtEOXact_LogicalRepWorkers(bool isCommit)
Definition: worker.c:5125
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1645
void pgstat_progress_end_command(void)
void pgstat_report_xact_timestamp(TimestampTz tstamp)
void AtEOXact_LargeObject(bool isCommit)
Definition: be-fsstubs.c:607
void AtEOSubXact_LargeObject(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: be-fsstubs.c:653
static int32 next
Definition: blutils.c:224
static void cleanup(void)
Definition: bootstrap.c:713
void AtEOXact_Buffers(bool isCommit)
Definition: bufmgr.c:3989
void UnlockBuffers(void)
Definition: bufmgr.c:5509
#define InvalidCommandId
Definition: c.h:640
#define TopSubTransactionId
Definition: c.h:630
#define Min(x, y)
Definition: c.h:975
uint8_t uint8
Definition: c.h:500
uint32 SubTransactionId
Definition: c.h:627
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:224
#define InvalidSubTransactionId
Definition: c.h:629
#define PointerIsValid(pointer)
Definition: c.h:734
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:434
#define FirstCommandId
Definition: c.h:639
uint32 LocalTransactionId
Definition: c.h:625
uint32 CommandId
Definition: c.h:637
uint32 TransactionId
Definition: c.h:623
size_t Size
Definition: c.h:576
void AtEOXact_ComboCid(void)
Definition: combocid.c:182
void TransactionTreeSetCommitTsData(TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz timestamp, RepOriginId nodeid)
Definition: commit_ts.c:141
bool ConditionVariableCancelSleep(void)
int64 TimestampTz
Definition: timestamp.h:39
void AtEOXact_HashTables(bool isCommit)
Definition: dynahash.c:1912
void AtEOSubXact_HashTables(bool isCommit, int nestDepth)
Definition: dynahash.c:1938
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1158
bool message_level_is_interesting(int elevel)
Definition: elog.c:273
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define FATAL
Definition: elog.h:41
#define WARNING
Definition: elog.h:36
#define PANIC
Definition: elog.h:42
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
#define ereport(elevel,...)
Definition: elog.h:149
#define DEBUG5
Definition: elog.h:26
void AtEOXact_Files(bool isCommit)
Definition: fd.c:3229
void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: fd.c:3196
#define MaxAllocSize
Definition: fe_memutils.h:22
ProcNumber MyProcNumber
Definition: globals.c:91
Oid MyDatabaseTableSpace
Definition: globals.c:97
volatile uint32 CritSectionCount
Definition: globals.c:46
bool ExitOnAnyError
Definition: globals.c:124
Oid MyDatabaseId
Definition: globals.c:95
int NewGUCNestLevel(void)
Definition: guc.c:2235
void AtStart_GUC(void)
Definition: guc.c:2215
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:2262
double log_xact_sample_rate
Definition: guc_tables.c:547
Assert(PointerIsAligned(start, uint64))
const char * str
#define IsParallelWorker()
Definition: parallel.h:60
void ResetReindexState(int nestLevel)
Definition: index.c:4213
void PostPrepare_Inval(void)
Definition: inval.c:986
void LogLogicalInvalidations(void)
Definition: inval.c:1925
void AcceptInvalidationMessages(void)
Definition: inval.c:929
int xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs, bool *RelcacheInitFileInval)
Definition: inval.c:1005
void AtEOXact_Inval(bool isCommit)
Definition: inval.c:1192
void AtEOSubXact_Inval(bool isCommit)
Definition: inval.c:1303
void CommandEndInvalidationMessages(void)
Definition: inval.c:1402
void ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs, int nmsgs, bool RelcacheInitFileInval, Oid dbid, Oid tsid)
Definition: inval.c:1128
int i
Definition: isn.c:77
void AtEOXact_ApplyLauncher(bool isCommit)
Definition: launcher.c:1083
void XactLockTableDelete(TransactionId xid)
Definition: lmgr.c:639
void XactLockTableInsert(TransactionId xid)
Definition: lmgr.c:622
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
Definition: lock.c:4587
void AtPrepare_Locks(void)
Definition: lock.c:3443
void PostPrepare_Locks(TransactionId xid)
Definition: lock.c:3539
#define InvalidLocalTransactionId
Definition: lock.h:66
void ResetLogicalStreamingState(void)
Definition: logical.c:1905
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1182
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1902
void LWLockReleaseAll(void)
Definition: lwlock.c:1953
@ LW_EXCLUSIVE
Definition: lwlock.h:114
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:2309
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1256
bool MemoryContextIsEmpty(MemoryContext context)
Definition: mcxt.c:774
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:414
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1290
MemoryContext TopTransactionContext
Definition: mcxt.c:170
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:2167
void pfree(void *pointer)
Definition: mcxt.c:2147
MemoryContext TopMemoryContext
Definition: mcxt.c:165
void * palloc(Size size)
Definition: mcxt.c:1940
MemoryContext CurTransactionContext
Definition: mcxt.c:171
MemoryContext CurrentMemoryContext
Definition: mcxt.c:159
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:485
void DropRelationFiles(RelFileLocator *delrels, int ndelrels, bool isRedo)
Definition: md.c:1587
#define AllocSetContextCreate
Definition: memutils.h:149
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:180
#define RESUME_INTERRUPTS()
Definition: miscadmin.h:136
#define START_CRIT_SECTION()
Definition: miscadmin.h:150
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:134
#define END_CRIT_SECTION()
Definition: miscadmin.h:152
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition: miscinit.c:663
Oid GetUserId(void)
Definition: miscinit.c:520
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition: miscinit.c:670
void AtPrepare_MultiXact(void)
Definition: multixact.c:1836
void PostPrepare_MultiXact(TransactionId xid)
Definition: multixact.c:1850
void AtEOXact_MultiXact(void)
Definition: multixact.c:1808
void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: namespace.c:4558
void AtEOXact_Namespace(bool isCommit, bool parallel)
Definition: namespace.c:4512
TimestampTz replorigin_session_origin_timestamp
Definition: origin.c:165
void replorigin_session_advance(XLogRecPtr remote_commit, XLogRecPtr local_commit)
Definition: origin.c:1219
RepOriginId replorigin_session_origin
Definition: origin.c:163
void replorigin_advance(RepOriginId node, XLogRecPtr remote_commit, XLogRecPtr local_commit, bool go_backward, bool wal_log)
Definition: origin.c:888
XLogRecPtr replorigin_session_origin_lsn
Definition: origin.c:164
#define DoNotReplicateId
Definition: origin.h:34
#define InvalidRepOriginId
Definition: origin.h:33
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
void * arg
void AtEOXact_Enum(void)
Definition: pg_enum.c:726
double pg_prng_double(pg_prng_state *state)
Definition: pg_prng.c:268
pg_prng_state pg_global_prng_state
Definition: pg_prng.c:34
static char * buf
Definition: pg_test_fsync.c:72
void AtPrepare_PgStat(void)
Definition: pgstat_xact.c:191
void pgstat_execute_transactional_drops(int ndrops, struct xl_xact_stats_item *items, bool is_redo)
Definition: pgstat_xact.c:314
void AtEOXact_PgStat(bool isCommit, bool parallel)
Definition: pgstat_xact.c:40
void PostPrepare_PgStat(void)
Definition: pgstat_xact.c:211
int pgstat_get_transactional_drops(bool isCommit, xl_xact_stats_item **items)
Definition: pgstat_xact.c:272
void AtEOSubXact_PgStat(bool isCommit, int nestDepth)
Definition: pgstat_xact.c:113
#define qsort(a, b, c, d)
Definition: port.h:479
void AtAbort_Portals(void)
Definition: portalmem.c:783
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition: portalmem.c:981
bool PreCommit_Portals(bool isPrepare)
Definition: portalmem.c:679
void AtSubCommit_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, int parentLevel, ResourceOwner parentXactOwner)
Definition: portalmem.c:945
void AtCleanup_Portals(void)
Definition: portalmem.c:860
void AtSubCleanup_Portals(SubTransactionId mySubid)
Definition: portalmem.c:1094
unsigned int Oid
Definition: postgres_ext.h:30
void PreCommit_CheckForSerializationFailure(void)
Definition: predicate.c:4703
void AtPrepare_PredicateLocks(void)
Definition: predicate.c:4790
void RegisterPredicateLockingXid(TransactionId xid)
Definition: predicate.c:1959
void PostPrepare_PredicateLocks(TransactionId xid)
Definition: predicate.c:4859
#define PGPROC_MAX_CACHED_SUBXIDS
Definition: proc.h:39
#define DELAY_CHKPT_START
Definition: proc.h:120
void XidCacheRemoveRunningXids(TransactionId xid, int nxids, const TransactionId *xids, TransactionId latestXid)
Definition: procarray.c:3991
void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
Definition: procarray.c:667
void RecordKnownAssignedTransactionIds(TransactionId xid)
Definition: procarray.c:4403
void ProcArrayClearTransaction(PGPROC *proc)
Definition: procarray.c:907
void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)
Definition: procarray.c:1318
void ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids, TransactionId *subxids, TransactionId max_xid)
Definition: procarray.c:4472
void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: relcache.c:3364
void AtEOXact_RelationCache(bool isCommit)
Definition: relcache.c:3212
void AtPrepare_RelationMap(void)
Definition: relmapper.c:588
void AtEOXact_RelationMap(bool isCommit, bool isParallelWorker)
Definition: relmapper.c:541
void AtCCI_RelationMap(void)
Definition: relmapper.c:504
ResourceOwner TopTransactionResourceOwner
Definition: resowner.c:175
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition: resowner.c:421
ResourceOwner CurrentResourceOwner
Definition: resowner.c:173
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition: resowner.c:658
void ResourceOwnerDelete(ResourceOwner owner)
Definition: resowner.c:871
ResourceOwner CurTransactionResourceOwner
Definition: resowner.c:174
@ RESOURCE_RELEASE_LOCKS
Definition: resowner.h:55
@ RESOURCE_RELEASE_BEFORE_LOCKS
Definition: resowner.h:54
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition: resowner.h:56
Size add_size(Size s1, Size s2)
Definition: shmem.c:493
Size mul_size(Size s1, Size s2)
Definition: shmem.c:510
LocalTransactionId GetNextLocalTransactionId(void)
Definition: sinvaladt.c:700
void AtEOXact_SMgr(void)
Definition: smgr.c:1008
void SnapBuildResetExportedSnapshotState(void)
Definition: snapbuild.c:627
void AtSubAbort_Snapshot(int level)
Definition: snapmgr.c:969
void AtEOXact_Snapshot(bool isCommit, bool resetXmin)
Definition: snapmgr.c:1003
void AtSubCommit_Snapshot(int level)
Definition: snapmgr.c:948
bool XactHasExportedSnapshots(void)
Definition: snapmgr.c:1561
void SnapshotSetCommandId(CommandId curcid)
Definition: snapmgr.c:477
void AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid)
Definition: spi.c:483
bool SPI_inside_nonatomic_context(void)
Definition: spi.c:582
void AtEOXact_SPI(bool isCommit)
Definition: spi.c:429
PGPROC * MyProc
Definition: proc.c:67
int TransactionTimeout
Definition: proc.c:62
void LockErrorCleanup(void)
Definition: proc.c:814
bool stack_is_too_deep(void)
Definition: stack_depth.c:109
void StandbyReleaseLockTree(TransactionId xid, int nsubxids, TransactionId *subxids)
Definition: standby.c:1092
void LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInitFileInval)
Definition: standby.c:1470
void AtSubCommit_smgr(void)
Definition: storage.c:955
void AtSubAbort_smgr(void)
Definition: storage.c:975
int smgrGetPendingDeletes(bool forCommit, RelFileLocator **ptr)
Definition: storage.c:893
void PostPrepare_smgr(void)
Definition: storage.c:934
void smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
Definition: storage.c:741
void smgrDoPendingDeletes(bool isCommit)
Definition: storage.c:673
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
struct PGPROC::@127 vxid
LocalTransactionId lxid
Definition: proc.h:201
ProcNumber procNumber
Definition: proc.h:196
int delayChkptFlags
Definition: proc.h:241
FullTransactionId currentFullTransactionId
Definition: xact.c:232
FullTransactionId topFullTransactionId
Definition: xact.c:231
CommandId currentCommandId
Definition: xact.c:233
TransactionId parallelCurrentXids[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.c:235
struct SubXactCallbackItem * next
Definition: xact.c:322
SubXactCallback callback
Definition: xact.c:323
TransState state
Definition: xact.c:199
int parallelModeLevel
Definition: xact.c:214
SubTransactionId subTransactionId
Definition: xact.c:196
FullTransactionId fullTransactionId
Definition: xact.c:195
struct TransactionStateData * parent
Definition: xact.c:218
MemoryContext priorContext
Definition: xact.c:205
bool parallelChildXact
Definition: xact.c:215
MemoryContext curTransactionContext
Definition: xact.c:203
TBlockState blockState
Definition: xact.c:200
bool prevXactReadOnly
Definition: xact.c:211
TransactionId * childXids
Definition: xact.c:206
bool startedInRecovery
Definition: xact.c:212
ResourceOwner curTransactionOwner
Definition: xact.c:204
LocalTransactionId localTransactionId
Definition: lock.h:63
ProcNumber procNumber
Definition: lock.h:62
XLogRecPtr EndRecPtr
Definition: xlogreader.h:207
XLogRecPtr ReadRecPtr
Definition: xlogreader.h:206
struct XactCallbackItem * next
Definition: xact.c:310
void * arg
Definition: xact.c:312
XactCallback callback
Definition: xact.c:311
Definition: regguts.h:323
TimestampTz xact_time
Definition: xact.h:338
TransactionId xtop
Definition: xact.h:220
TransactionId xsub[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:222
TimestampTz xact_time
Definition: xact.h:322
Oid tsId
Definition: xact.h:258
Oid dbId
Definition: xact.h:257
int nmsgs
Definition: xact.h:304
TimestampTz origin_timestamp
Definition: xact.h:317
XLogRecPtr origin_lsn
Definition: xact.h:316
xl_xact_stats_item * stats
Definition: xact.h:425
RelFileLocator * xlocators
Definition: xact.h:422
TransactionId twophase_xid
Definition: xact.h:427
TransactionId * subxacts
Definition: xact.h:419
XLogRecPtr origin_lsn
Definition: xact.h:430
xl_xact_stats_item * stats
Definition: xact.h:392
TimestampTz xact_time
Definition: xact.h:379
TransactionId twophase_xid
Definition: xact.h:397
RelFileLocator * xlocators
Definition: xact.h:389
TimestampTz origin_timestamp
Definition: xact.h:405
TransactionId * subxacts
Definition: xact.h:386
XLogRecPtr origin_lsn
Definition: xact.h:404
SharedInvalidationMessage * msgs
Definition: xact.h:395
int nsubxacts
Definition: xact.h:263
TransactionId xid
Definition: xact.h:311
uint32 xinfo
Definition: xact.h:252
void SubTransSetParent(TransactionId xid, TransactionId parent)
Definition: subtrans.c:85
void SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
Definition: syncrep.c:148
void AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: tablecmds.c:19351
void PreCommit_on_commit_actions(void)
Definition: tablecmds.c:19212
void AtEOXact_on_commit_actions(bool isCommit)
Definition: tablecmds.c:19319
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:46
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition: timeout.c:560
void reschedule_timeouts(void)
Definition: timeout.c:540
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition: timeout.c:685
@ TRANSACTION_TIMEOUT
Definition: timeout.h:34
void TransactionIdAsyncCommitTree(TransactionId xid, int nxids, TransactionId *xids, XLogRecPtr lsn)
Definition: transam.c:252
TransactionId TransactionIdLatest(TransactionId mainxid, int nxids, const TransactionId *xids)
Definition: transam.c:345
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:126
void TransactionIdCommitTree(TransactionId xid, int nxids, TransactionId *xids)
Definition: transam.c:240
void TransactionIdAbortTree(TransactionId xid, int nxids, TransactionId *xids)
Definition: transam.c:270
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:280
static TransactionId ReadNextTransactionId(void)
Definition: transam.h:315
#define InvalidTransactionId
Definition: transam.h:31
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
#define XidFromFullTransactionId(x)
Definition: transam.h:48
#define TransactionIdIsValid(xid)
Definition: transam.h:41
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
#define InvalidFullTransactionId
Definition: transam.h:56
#define FullTransactionIdIsValid(x)
Definition: transam.h:55
void AfterTriggerBeginXact(void)
Definition: trigger.c:5021
void AfterTriggerEndSubXact(bool isCommit)
Definition: trigger.c:5399
void AfterTriggerFireDeferred(void)
Definition: trigger.c:5247
void AfterTriggerEndXact(bool isCommit)
Definition: trigger.c:5303
void AfterTriggerBeginSubXact(void)
Definition: trigger.c:5351
void AtAbort_Twophase(void)
Definition: twophase.c:304
void PrepareRedoRemove(TransactionId xid, bool giveWarning)
Definition: twophase.c:2571
void EndPrepare(GlobalTransaction gxact)
Definition: twophase.c:1142
void StartPrepare(GlobalTransaction gxact)
Definition: twophase.c:1049
void PrepareRedoAdd(char *buf, XLogRecPtr start_lsn, XLogRecPtr end_lsn, RepOriginId origin_id)
Definition: twophase.c:2469
void PostPrepare_Twophase(void)
Definition: twophase.c:344
GlobalTransaction MarkAsPreparing(TransactionId xid, const char *gid, TimestampTz prepared_at, Oid owner, Oid databaseid)
Definition: twophase.c:359
void AtEOXact_TypeCache(void)
Definition: typcache.c:3180
void AtEOSubXact_TypeCache(void)
Definition: typcache.c:3186
void AdvanceNextFullTransactionIdPastXid(TransactionId xid)
Definition: varsup.c:304
FullTransactionId GetNewTransactionId(bool isSubXact)
Definition: varsup.c:77
static void pgstat_report_wait_end(void)
Definition: wait_event.h:101
const char * name
static bool CommitTransactionCommandInternal(void)
Definition: xact.c:3175
bool IsTransactionOrTransactionBlock(void)
Definition: xact.c:4989
struct SerializedTransactionState SerializedTransactionState
void SerializeTransactionState(Size maxsize, char *start_address)
Definition: xact.c:5540
void ExitParallelMode(void)
Definition: xact.c:1064
static TimestampTz xactStartTimestamp
Definition: xact.c:280
static bool currentCommandIdUsed
Definition: xact.c:268
static void AtSubCommit_Memory(void)
Definition: xact.c:1635
void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
Definition: xact.c:3136
static void CleanupSubTransaction(void)
Definition: xact.c:5383
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4694
static void AtStart_Memory(void)
Definition: xact.c:1176
FullTransactionId GetCurrentFullTransactionId(void)
Definition: xact.c:512
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition: xact.c:3144
static XactCallbackItem * Xact_callbacks
Definition: xact.c:315
void WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
Definition: xact.c:3710
static TimestampTz stmtStartTimestamp
Definition: xact.c:281
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:791
int synchronous_commit
Definition: xact.c:87
void UserAbortTransactionBlock(bool chain)
Definition: xact.c:4204
bool IsInTransactionBlock(bool isTopLevel)
Definition: xact.c:3769
bool PrepareTransactionBlock(const char *gid)
Definition: xact.c:3992
static void AtSubCleanup_Memory(void)
Definition: xact.c:2022
static void StartTransaction(void)
Definition: xact.c:2064
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:929
void xact_redo(XLogReaderState *record)
Definition: xact.c:6363
TransactionId GetTopTransactionId(void)
Definition: xact.c:426
static void AtSubCommit_childXids(void)
Definition: xact.c:1664
static void CallSubXactCallbacks(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: xact.c:3898
void EnterParallelMode(void)
Definition: xact.c:1051
static void AtAbort_ResourceOwner(void)
Definition: xact.c:1916
TransactionId GetStableLatestTransactionId(void)
Definition: xact.c:607
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3725
void UnregisterSubXactCallback(SubXactCallback callback, void *arg)
Definition: xact.c:3877
bool XactDeferrable
Definition: xact.c:85
static bool forceSyncCommit
Definition: xact.c:293
void BeginImplicitTransactionBlock(void)
Definition: xact.c:4326
static void CallXactCallbacks(XactEvent event)
Definition: xact.c:3838
static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS]
Definition: xact.c:258
static void xact_redo_commit(xl_xact_parsed_commit *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:6130
void RequireTransactionBlock(bool isTopLevel, const char *stmtType)
Definition: xact.c:3716
static void AtSubAbort_Memory(void)
Definition: xact.c:1904
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:327
void DefineSavepoint(const char *name)
Definition: xact.c:4373
bool DefaultXactDeferrable
Definition: xact.c:84
static void CleanupTransaction(void)
Definition: xact.c:3009
static int nUnreportedXids
Definition: xact.c:257
static const char * TransStateAsString(TransState state)
Definition: xact.c:5760
static TimestampTz xactStopTimestamp
Definition: xact.c:282
bool TransactionStartedDuringRecovery(void)
Definition: xact.c:1042
static void CommitSubTransaction(void)
Definition: xact.c:5104
bool XactReadOnly
Definition: xact.c:82
static void PushTransaction(void)
Definition: xact.c:5416
bool bsysscan
Definition: xact.c:100
TransactionId CheckXidAlive
Definition: xact.c:99
static TransactionId RecordTransactionCommit(void)
Definition: xact.c:1315
static char * prepareGID
Definition: xact.c:288
void UnregisterXactCallback(XactCallback callback, void *arg)
Definition: xact.c:3817
bool IsTransactionState(void)
Definition: xact.c:387
struct SubXactCallbackItem SubXactCallbackItem
static MemoryContext TransactionAbortContext
Definition: xact.c:303
void CommandCounterIncrement(void)
Definition: xact.c:1100
TransState
Definition: xact.c:142
@ TRANS_INPROGRESS
Definition: xact.c:145
@ TRANS_START
Definition: xact.c:144
@ TRANS_COMMIT
Definition: xact.c:146
@ TRANS_ABORT
Definition: xact.c:147
@ TRANS_DEFAULT
Definition: xact.c:143
@ TRANS_PREPARE
Definition: xact.c:148
void PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
Definition: xact.c:3648
static void AtCleanup_Memory(void)
Definition: xact.c:1974
Size EstimateTransactionStateSpace(void)
Definition: xact.c:5512
TransactionStateData * TransactionState
Definition: xact.c:221
static void AtSubAbort_childXids(void)
Definition: xact.c:1942
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:441
static bool AbortCurrentTransactionInternal(void)
Definition: xact.c:3469
struct XactCallbackItem XactCallbackItem
static SubTransactionId currentSubTransactionId
Definition: xact.c:266
static void AssignTransactionId(TransactionState s)
Definition: xact.c:635
static void xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:6284
char TransactionBlockStatusCode(void)
Definition: xact.c:5003
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4796
static int nParallelCurrentXids
Definition: xact.c:126
FullTransactionId GetCurrentFullTransactionIdIfAny(void)
Definition: xact.c:530
static void CommitTransaction(void)
Definition: xact.c:2228
void StartTransactionCommand(void)
Definition: xact.c:3059
static void PopTransaction(void)
Definition: xact.c:5478
bool IsAbortedTransactionBlockState(void)
Definition: xact.c:407
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4768
void EndImplicitTransactionBlock(void)
Definition: xact.c:4351
void StartParallelWorkerTransaction(char *tstatespace)
Definition: xact.c:5611
void SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts)
Definition: xact.c:859
static void AtSubAbort_ResourceOwner(void)
Definition: xact.c:1929
void ReleaseSavepoint(const char *name)
Definition: xact.c:4458
static TransactionStateData TopTransactionStateData
Definition: xact.c:247
static FullTransactionId XactTopFullTransactionId
Definition: xact.c:125
static void ShowTransactionState(const char *str)
Definition: xact.c:5648
int XactIsoLevel
Definition: xact.c:79
static void PrepareTransaction(void)
Definition: xact.c:2515
FullTransactionId GetTopFullTransactionId(void)
Definition: xact.c:483
static CommandId currentCommandId
Definition: xact.c:267
XLogRecPtr XactLogCommitRecord(TimestampTz commit_time, int nsubxacts, TransactionId *subxacts, int nrels, RelFileLocator *rels, int ndroppedstats, xl_xact_stats_item *droppedstats, int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInval, int xactflags, TransactionId twophase_xid, const char *twophase_gid)
Definition: xact.c:5814
void ForceSyncCommit(void)
Definition: xact.c:1152
static TransactionId RecordTransactionAbort(bool isSubXact)
Definition: xact.c:1754
static void AtCommit_Memory(void)
Definition: xact.c:1598
static void AbortSubTransaction(void)
Definition: xact.c:5219
bool IsSubTransaction(void)
Definition: xact.c:5044
void MarkSubxactTopXidLogged(void)
Definition: xact.c:591
void SetCurrentStatementStartTimestamp(void)
Definition: xact.c:914
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:941
bool IsTransactionBlock(void)
Definition: xact.c:4971
bool IsInParallelMode(void)
Definition: xact.c:1089
int xactGetCommittedChildren(TransactionId **ptr)
Definition: xact.c:5790
struct TransactionStateData TransactionStateData
TransactionId GetCurrentTransactionIdIfAny(void)
Definition: xact.c:471
void BeginTransactionBlock(void)
Definition: xact.c:3924
static void AtStart_ResourceOwner(void)
Definition: xact.c:1226
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition: xact.c:879
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition: xact.c:870
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5707
void EndParallelWorkerTransaction(void)
Definition: xact.c:5636
static void AtAbort_Memory(void)
Definition: xact.c:1884
void RegisterXactCallback(XactCallback callback, void *arg)
Definition: xact.c:3804
void CommitTransactionCommand(void)
Definition: xact.c:3157
void RollbackToSavepoint(const char *name)
Definition: xact.c:4567
bool SubTransactionIsActive(SubTransactionId subxid)
Definition: xact.c:805
TBlockState
Definition: xact.c:158
@ TBLOCK_DEFAULT
Definition: xact.c:160
@ TBLOCK_SUBABORT_END
Definition: xact.c:180
@ TBLOCK_STARTED
Definition: xact.c:161
@ TBLOCK_SUBCOMMIT
Definition: xact.c:178
@ TBLOCK_IMPLICIT_INPROGRESS
Definition: xact.c:166
@ TBLOCK_ABORT_END
Definition: xact.c:170
@ TBLOCK_PREPARE
Definition: xact.c:172
@ TBLOCK_ABORT_PENDING
Definition: xact.c:171
@ TBLOCK_ABORT
Definition: xact.c:169
@ TBLOCK_SUBRELEASE
Definition: xact.c:177
@ TBLOCK_SUBBEGIN
Definition: xact.c:175
@ TBLOCK_SUBABORT
Definition: xact.c:179
@ TBLOCK_SUBRESTART
Definition: xact.c:182
@ TBLOCK_INPROGRESS
Definition: xact.c:165
@ TBLOCK_END
Definition: xact.c:168
@ TBLOCK_PARALLEL_INPROGRESS
Definition: xact.c:167
@ TBLOCK_SUBABORT_RESTART
Definition: xact.c:183
@ TBLOCK_SUBABORT_PENDING
Definition: xact.c:181
@ TBLOCK_BEGIN
Definition: xact.c:164
@ TBLOCK_SUBINPROGRESS
Definition: xact.c:176
void RegisterSubXactCallback(SubXactCallback callback, void *arg)
Definition: xact.c:3864
FullTransactionId GetTopFullTransactionIdIfAny(void)
Definition: xact.c:499
TransactionId GetCurrentTransactionId(void)
Definition: xact.c:454
static void AbortTransaction(void)
Definition: xact.c:2809
static void AtStart_Cache(void)
Definition: xact.c:1167
static void AtSubStart_ResourceOwner(void)
Definition: xact.c:1283
int DefaultXactIsoLevel
Definition: xact.c:78
static void AtSubStart_Memory(void)
Definition: xact.c:1254
bool xact_is_sampled
Definition: xact.c:296
bool EndTransactionBlock(bool chain)
Definition: xact.c:4044
bool IsSubxactTopXidLogPending(void)
Definition: xact.c:559
#define SerializedTransactionStateHeaderSize
Definition: xact.c:239
void AbortOutOfAnyTransaction(void)
Definition: xact.c:4862
int MyXactFlags
Definition: xact.c:136
static void ShowTransactionStateRec(const char *str, TransactionState s)
Definition: xact.c:5660
static TransactionState CurrentTransactionState
Definition: xact.c:260
void AbortCurrentTransaction(void)
Definition: xact.c:3451
static void StartSubTransaction(void)
Definition: xact.c:5067
static TransactionId * ParallelCurrentXids
Definition: xact.c:127
bool DefaultXactReadOnly
Definition: xact.c:81
TimestampTz GetCurrentTransactionStopTimestamp(void)
Definition: xact.c:891
static void AtCCI_LocalCache(void)
Definition: xact.c:1579
XLogRecPtr XactLogAbortRecord(TimestampTz abort_time, int nsubxacts, TransactionId *subxacts, int nrels, RelFileLocator *rels, int ndroppedstats, xl_xact_stats_item *droppedstats, int xactflags, TransactionId twophase_xid, const char *twophase_gid)
Definition: xact.c:5986
void MarkCurrentTransactionIdLoggedIfAny(void)
Definition: xact.c:541
CommandId GetCurrentCommandId(bool used)
Definition: xact.c:829
#define XactCompletionForceSyncCommit(xinfo)
Definition: xact.h:215
#define MinSizeOfXactInvals
Definition: xact.h:307
void(* SubXactCallback)(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg)
Definition: xact.h:148
#define MinSizeOfXactSubxacts
Definition: xact.h:266
#define XLOG_XACT_COMMIT_PREPARED
Definition: xact.h:172
#define XLOG_XACT_INVALIDATIONS
Definition: xact.h:175
#define XACT_COMPLETION_UPDATE_RELCACHE_FILE
Definition: xact.h:207
SubXactEvent
Definition: xact.h:141
@ SUBXACT_EVENT_PRE_COMMIT_SUB
Definition: xact.h:145
@ SUBXACT_EVENT_START_SUB
Definition: xact.h:142
@ SUBXACT_EVENT_ABORT_SUB
Definition: xact.h:144
@ SUBXACT_EVENT_COMMIT_SUB
Definition: xact.h:143
void(* XactCallback)(XactEvent event, void *arg)
Definition: xact.h:138
#define XACT_XINFO_HAS_GID
Definition: xact.h:195
#define XACT_COMPLETION_FORCE_SYNC_COMMIT
Definition: xact.h:208
#define XACT_XINFO_HAS_ORIGIN
Definition: xact.h:193
@ SYNCHRONOUS_COMMIT_REMOTE_APPLY
Definition: xact.h:75
@ SYNCHRONOUS_COMMIT_OFF
Definition: xact.h:70
#define XLOG_XACT_PREPARE
Definition: xact.h:170
XactEvent
Definition: xact.h:127
@ XACT_EVENT_PRE_PREPARE
Definition: xact.h:135
@ XACT_EVENT_COMMIT
Definition: xact.h:128
@ XACT_EVENT_PARALLEL_PRE_COMMIT
Definition: xact.h:134
@ XACT_EVENT_PARALLEL_COMMIT
Definition: xact.h:129
@ XACT_EVENT_ABORT
Definition: xact.h:130
@ XACT_EVENT_PRE_COMMIT
Definition: xact.h:133
@ XACT_EVENT_PARALLEL_ABORT
Definition: xact.h:131
@ XACT_EVENT_PREPARE
Definition: xact.h:132
#define SYNCHRONOUS_COMMIT_ON
Definition: xact.h:80
#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK
Definition: xact.h:108
#define XACT_XINFO_HAS_TWOPHASE
Definition: xact.h:192
#define XLOG_XACT_COMMIT
Definition: xact.h:169
#define XLOG_XACT_OPMASK
Definition: xact.h:179
#define MinSizeOfXactRelfileLocators
Definition: xact.h:273
#define XLOG_XACT_ABORT
Definition: xact.h:171
#define MinSizeOfXactStatsItems
Definition: xact.h:300
#define XACT_XINFO_HAS_RELFILELOCATORS
Definition: xact.h:190
#define MinSizeOfXactAbort
Definition: xact.h:350
#define XACT_COMPLETION_APPLY_FEEDBACK
Definition: xact.h:206
#define MinSizeOfXactAssignment
Definition: xact.h:225
#define XACT_XINFO_HAS_DBINFO
Definition: xact.h:188
#define XACT_FLAGS_NEEDIMMEDIATECOMMIT
Definition: xact.h:114
#define XactCompletionApplyFeedback(xinfo)
Definition: xact.h:211
#define XLOG_XACT_ASSIGNMENT
Definition: xact.h:174
#define XACT_XINFO_HAS_INVALS
Definition: xact.h:191
#define XLOG_XACT_ABORT_PREPARED
Definition: xact.h:173
#define XACT_XINFO_HAS_AE_LOCKS
Definition: xact.h:194
#define XLOG_XACT_HAS_INFO
Definition: xact.h:182
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE
Definition: xact.h:102
#define XactCompletionRelcacheInitFileInval(xinfo)
Definition: xact.h:213
#define XACT_READ_COMMITTED
Definition: xact.h:37
#define XACT_XINFO_HAS_SUBXACTS
Definition: xact.h:189
#define XACT_XINFO_HAS_DROPPED_STATS
Definition: xact.h:196
void ParseCommitRecord(uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *parsed)
Definition: xactdesc.c:35
void ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed)
Definition: xactdesc.c:141
int xidComparator(const void *arg1, const void *arg2)
Definition: xid.c:152
bool RecoveryInProgress(void)
Definition: xlog.c:6522
XLogRecPtr XactLastRecEnd
Definition: xlog.c:254
XLogRecPtr XactLastCommitEnd
Definition: xlog.c:255
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2923
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition: xlog.c:2752
#define XLogLogicalInfoActive()
Definition: xlog.h:126
#define XLOG_INCLUDE_ORIGIN
Definition: xlog.h:154
#define XLogStandbyInfoActive()
Definition: xlog.h:123
uint16 RepOriginId
Definition: xlogdefs.h:65
uint64 XLogRecPtr
Definition: xlogdefs.h:21
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:474
void XLogRegisterData(const void *data, uint32 len)
Definition: xloginsert.c:364
void XLogSetRecordFlags(uint8 flags)
Definition: xloginsert.c:456
void XLogResetInsertion(void)
Definition: xloginsert.c:222
void XLogBeginInsert(void)
Definition: xloginsert.c:149
#define XLogRecGetOrigin(decoder)
Definition: xlogreader.h:413
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:410
#define XLogRecGetData(decoder)
Definition: xlogreader.h:415
#define XLogRecGetXid(decoder)
Definition: xlogreader.h:412
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:417
#define XLR_SPECIAL_REL_UPDATE
Definition: xlogrecord.h:82
void XLogRequestWalReceiverReply(void)
HotStandbyState standbyState
Definition: xlogutils.c:53
@ STANDBY_DISABLED
Definition: xlogutils.h:52
@ STANDBY_INITIALIZED
Definition: xlogutils.h:53