PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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-2026, 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 "access/xlogwait.h"
35#include "catalog/index.h"
36#include "catalog/namespace.h"
37#include "catalog/pg_enum.h"
38#include "catalog/storage.h"
39#include "commands/async.h"
40#include "commands/tablecmds.h"
41#include "commands/trigger.h"
42#include "common/pg_prng.h"
43#include "executor/spi.h"
44#include "libpq/be-fsstubs.h"
45#include "libpq/pqsignal.h"
46#include "miscadmin.h"
47#include "pg_trace.h"
48#include "pgstat.h"
49#include "replication/logical.h"
52#include "replication/origin.h"
54#include "replication/syncrep.h"
55#include "storage/aio_subsys.h"
57#include "storage/fd.h"
58#include "storage/lmgr.h"
59#include "storage/md.h"
60#include "storage/predicate.h"
61#include "storage/proc.h"
62#include "storage/procarray.h"
63#include "storage/sinvaladt.h"
64#include "storage/smgr.h"
65#include "utils/builtins.h"
66#include "utils/combocid.h"
67#include "utils/guc.h"
68#include "utils/inval.h"
69#include "utils/memutils.h"
70#include "utils/relmapper.h"
71#include "utils/snapmgr.h"
72#include "utils/timeout.h"
73#include "utils/timestamp.h"
74#include "utils/typcache.h"
75#include "utils/wait_event.h"
76
77/*
78 * User-tweakable parameters
79 */
82
85
88
90
91/*
92 * CheckXidAlive is a xid value pointing to a possibly ongoing (sub)
93 * transaction. Currently, it is used in logical decoding. It's possible
94 * that such transactions can get aborted while the decoding is ongoing in
95 * which case we skip decoding that particular transaction. To ensure that we
96 * check whether the CheckXidAlive is aborted after fetching the tuple from
97 * system tables. We also ensure that during logical decoding we never
98 * directly access the tableam or heap APIs because we are checking for the
99 * concurrent aborts only in systable_* APIs.
100 */
102bool bsysscan = false;
103
104/*
105 * When running as a parallel worker, we place only a single
106 * TransactionStateData on the parallel worker's state stack, and the XID
107 * reflected there will be that of the *innermost* currently-active
108 * subtransaction in the backend that initiated parallelism. However,
109 * GetTopTransactionId() and TransactionIdIsCurrentTransactionId()
110 * need to return the same answers in the parallel worker as they would have
111 * in the user backend, so we need some additional bookkeeping.
112 *
113 * XactTopFullTransactionId stores the XID of our toplevel transaction, which
114 * will be the same as TopTransactionStateData.fullTransactionId in an
115 * ordinary backend; but in a parallel backend, which does not have the entire
116 * transaction state, it will instead be copied from the backend that started
117 * the parallel operation.
118 *
119 * nParallelCurrentXids will be 0 and ParallelCurrentXids NULL in an ordinary
120 * backend, but in a parallel backend, nParallelCurrentXids will contain the
121 * number of XIDs that need to be considered current, and ParallelCurrentXids
122 * will contain the XIDs themselves. This includes all XIDs that were current
123 * or sub-committed in the parent at the time the parallel operation began.
124 * The XIDs are stored sorted in numerical order (not logical order) to make
125 * lookups as fast as possible.
126 */
128static int nParallelCurrentXids = 0;
130
131/*
132 * Miscellaneous flag bits to record events which occur on the top level
133 * transaction. These flags are only persisted in MyXactFlags and are intended
134 * so we remember to do certain things later on in the transaction. This is
135 * globally accessible, so can be set from anywhere in the code that requires
136 * recording flags.
137 */
139
140/*
141 * transaction states - transaction state from server perspective
142 */
143typedef enum TransState
144{
145 TRANS_DEFAULT, /* idle */
146 TRANS_START, /* transaction starting */
147 TRANS_INPROGRESS, /* inside a valid transaction */
148 TRANS_COMMIT, /* commit in progress */
149 TRANS_ABORT, /* abort in progress */
150 TRANS_PREPARE, /* prepare in progress */
152
153/*
154 * transaction block states - transaction state of client queries
155 *
156 * Note: the subtransaction states are used only for non-topmost
157 * transactions; the others appear only in the topmost transaction.
158 */
159typedef enum TBlockState
160{
161 /* not-in-transaction-block states */
162 TBLOCK_DEFAULT, /* idle */
163 TBLOCK_STARTED, /* running single-query transaction */
164
165 /* transaction block states */
166 TBLOCK_BEGIN, /* starting transaction block */
167 TBLOCK_INPROGRESS, /* live transaction */
168 TBLOCK_IMPLICIT_INPROGRESS, /* live transaction after implicit BEGIN */
169 TBLOCK_PARALLEL_INPROGRESS, /* live transaction inside parallel worker */
170 TBLOCK_END, /* COMMIT received */
171 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
172 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
173 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
174 TBLOCK_PREPARE, /* live xact, PREPARE received */
175
176 /* subtransaction states */
177 TBLOCK_SUBBEGIN, /* starting a subtransaction */
178 TBLOCK_SUBINPROGRESS, /* live subtransaction */
179 TBLOCK_SUBRELEASE, /* RELEASE received */
180 TBLOCK_SUBCOMMIT, /* COMMIT received while TBLOCK_SUBINPROGRESS */
181 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
182 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
183 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
184 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
185 TBLOCK_SUBABORT_RESTART, /* failed subxact, ROLLBACK TO received */
187
188/*
189 * transaction state structure
190 *
191 * Note: parallelModeLevel counts the number of unmatched EnterParallelMode
192 * calls done at this transaction level. parallelChildXact is true if any
193 * upper transaction level has nonzero parallelModeLevel.
194 */
196{
197 FullTransactionId fullTransactionId; /* my FullTransactionId */
199 char *name; /* savepoint name, if any */
200 int savepointLevel; /* savepoint level */
201 TransState state; /* low-level state */
202 TBlockState blockState; /* high-level state */
203 int nestingLevel; /* transaction nesting depth */
204 int gucNestLevel; /* GUC context nesting depth */
205 MemoryContext curTransactionContext; /* my xact-lifetime context */
206 ResourceOwner curTransactionOwner; /* my query resources */
207 MemoryContext priorContext; /* CurrentMemoryContext before xact started */
208 TransactionId *childXids; /* subcommitted child XIDs, in XID order */
209 int nChildXids; /* # of subcommitted child XIDs */
210 int maxChildXids; /* allocated size of childXids[] */
211 Oid prevUser; /* previous CurrentUserId setting */
212 int prevSecContext; /* previous SecurityRestrictionContext */
213 bool prevXactReadOnly; /* entry-time xact r/o state */
214 bool startedInRecovery; /* did we start in recovery? */
215 bool didLogXid; /* has xid been included in WAL record? */
216 int parallelModeLevel; /* Enter/ExitParallelMode counter */
217 bool parallelChildXact; /* is any parent transaction parallel? */
218 bool chain; /* start a new block after this one */
219 bool topXidLogged; /* for a subxact: is top-level XID logged? */
220 struct TransactionStateData *parent; /* back link to parent */
222
224
225/*
226 * Serialized representation used to transmit transaction state to parallel
227 * workers through shared memory.
228 */
239
240/* The size of SerializedTransactionState, not including the final array. */
241#define SerializedTransactionStateHeaderSize \
242 offsetof(SerializedTransactionState, parallelCurrentXids)
243
244/*
245 * CurrentTransactionState always points to the current transaction state
246 * block. It will point to TopTransactionStateData when not in a
247 * transaction at all, or when in a top-level transaction.
248 */
251 .blockState = TBLOCK_DEFAULT,
252 .topXidLogged = false,
253};
254
255/*
256 * unreportedXids holds XIDs of all subtransactions that have not yet been
257 * reported in an XLOG_XACT_ASSIGNMENT record.
258 */
261
263
264/*
265 * The subtransaction ID and command ID assignment counters are global
266 * to a whole transaction, so we do not keep them in the state stack.
267 */
271
272/*
273 * xactStartTimestamp is the value of transaction_timestamp().
274 * stmtStartTimestamp is the value of statement_timestamp().
275 * xactStopTimestamp is the time at which we log a commit / abort WAL record,
276 * or if that was skipped, the time of the first subsequent
277 * GetCurrentTransactionStopTimestamp() call.
278 *
279 * These do not change as we enter and exit subtransactions, so we don't
280 * keep them inside the TransactionState stack.
281 */
285
286/*
287 * GID to be used for preparing the current transaction. This is also
288 * global to a whole transaction, so we don't keep it in the state stack.
289 */
290static char *prepareGID;
291
292/*
293 * Some commands want to force synchronous commit.
294 */
295static bool forceSyncCommit = false;
296
297/* Flag for logging statements in a transaction. */
298bool xact_is_sampled = false;
299
300/*
301 * Private context for transaction-abort work --- we reserve space for this
302 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
303 * when we've run out of memory.
304 */
306
307/*
308 * List of add-on start- and end-of-xact callbacks
309 */
316
318
319/*
320 * List of add-on start- and end-of-subxact callbacks
321 */
328
330
331
332/* local function prototypes */
334static void AbortTransaction(void);
335static void AtAbort_Memory(void);
336static void AtCleanup_Memory(void);
337static void AtAbort_ResourceOwner(void);
338static void AtCCI_LocalCache(void);
339static void AtCommit_Memory(void);
340static void AtStart_Cache(void);
341static void AtStart_Memory(void);
342static void AtStart_ResourceOwner(void);
343static void CallXactCallbacks(XactEvent event);
344static void CallSubXactCallbacks(SubXactEvent event,
347static void CleanupTransaction(void);
348static void CheckTransactionBlock(bool isTopLevel, bool throwError,
349 const char *stmtType);
350static void CommitTransaction(void);
352static void StartTransaction(void);
353
354static bool CommitTransactionCommandInternal(void);
355static bool AbortCurrentTransactionInternal(void);
356
357static void StartSubTransaction(void);
358static void CommitSubTransaction(void);
359static void AbortSubTransaction(void);
360static void CleanupSubTransaction(void);
361static void PushTransaction(void);
362static void PopTransaction(void);
363
364static void AtSubAbort_Memory(void);
365static void AtSubCleanup_Memory(void);
366static void AtSubAbort_ResourceOwner(void);
367static void AtSubCommit_Memory(void);
368static void AtSubStart_Memory(void);
369static void AtSubStart_ResourceOwner(void);
370
371static void ShowTransactionState(const char *str);
372static void ShowTransactionStateRec(const char *str, TransactionState s);
373static const char *BlockStateAsString(TBlockState blockState);
374static const char *TransStateAsString(TransState state);
375
376
377/* ----------------------------------------------------------------
378 * transaction state accessors
379 * ----------------------------------------------------------------
380 */
381
382/*
383 * IsTransactionState
384 *
385 * This returns true if we are inside a valid transaction; that is,
386 * it is safe to initiate database access, take heavyweight locks, etc.
387 */
388bool
390{
392
393 /*
394 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
395 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
396 * TRANS_PREPARE since it might be too soon or too late within those
397 * transition states to do anything interesting. Hence, the only "valid"
398 * state is TRANS_INPROGRESS.
399 */
400 return (s->state == TRANS_INPROGRESS);
401}
402
403/*
404 * IsAbortedTransactionBlockState
405 *
406 * This returns true if we are within an aborted transaction block.
407 */
408bool
410{
412
413 if (s->blockState == TBLOCK_ABORT ||
415 return true;
416
417 return false;
418}
419
420
421/*
422 * GetTopTransactionId
423 *
424 * This will return the XID of the main transaction, assigning one if
425 * it's not yet set. Be careful to call this only inside a valid xact.
426 */
434
435/*
436 * GetTopTransactionIdIfAny
437 *
438 * This will return the XID of the main transaction, if one is assigned.
439 * It will return InvalidTransactionId if we are not currently inside a
440 * transaction, or inside a transaction that hasn't yet been assigned an XID.
441 */
447
448/*
449 * GetCurrentTransactionId
450 *
451 * This will return the XID of the current transaction (main or sub
452 * transaction), assigning one if it's not yet set. Be careful to call this
453 * only inside a valid xact.
454 */
464
465/*
466 * GetCurrentTransactionIdIfAny
467 *
468 * This will return the XID of the current sub xact, if one is assigned.
469 * It will return InvalidTransactionId if we are not currently inside a
470 * transaction, or inside a transaction that hasn't been assigned an XID yet.
471 */
477
478/*
479 * GetTopFullTransactionId
480 *
481 * This will return the FullTransactionId of the main transaction, assigning
482 * one if it's not yet set. Be careful to call this only inside a valid xact.
483 */
491
492/*
493 * GetTopFullTransactionIdIfAny
494 *
495 * This will return the FullTransactionId of the main transaction, if one is
496 * assigned. It will return InvalidFullTransactionId if we are not currently
497 * inside a transaction, or inside a transaction that hasn't yet been assigned
498 * one.
499 */
505
506/*
507 * GetCurrentFullTransactionId
508 *
509 * This will return the FullTransactionId of the current transaction (main or
510 * sub transaction), assigning one if it's not yet set. Be careful to call
511 * this only inside a valid xact.
512 */
522
523/*
524 * GetCurrentFullTransactionIdIfAny
525 *
526 * This will return the FullTransactionId of the current sub xact, if one is
527 * assigned. It will return InvalidFullTransactionId if we are not currently
528 * inside a transaction, or inside a transaction that hasn't been assigned one
529 * yet.
530 */
536
537/*
538 * MarkCurrentTransactionIdLoggedIfAny
539 *
540 * Remember that the current xid - if it is assigned - now has been wal logged.
541 */
542void
548
549/*
550 * IsSubxactTopXidLogPending
551 *
552 * This is used to decide whether we need to WAL log the top-level XID for
553 * operation in a subtransaction. We require that for logical decoding, see
554 * LogicalDecodingProcessRecord.
555 *
556 * This returns true if effective_wal_level is logical and we are inside
557 * a valid subtransaction, for which the assignment was not yet written to
558 * any WAL record.
559 */
560bool
562{
563 /* check whether it is already logged */
565 return false;
566
567 /* effective_wal_level has to be logical */
569 return false;
570
571 /* we need to be in a transaction state */
572 if (!IsTransactionState())
573 return false;
574
575 /* it has to be a subtransaction */
576 if (!IsSubTransaction())
577 return false;
578
579 /* the subtransaction has to have a XID assigned */
581 return false;
582
583 return true;
584}
585
586/*
587 * MarkSubxactTopXidLogged
588 *
589 * Remember that the top transaction id for the current subtransaction is WAL
590 * logged now.
591 */
592void
599
600/*
601 * GetStableLatestTransactionId
602 *
603 * Get the transaction's XID if it has one, else read the next-to-be-assigned
604 * XID. Once we have a value, return that same value for the remainder of the
605 * current transaction. This is meant to provide the reference point for the
606 * age(xid) function, but might be useful for other maintenance tasks as well.
607 */
626
627/*
628 * AssignTransactionId
629 *
630 * Assigns a new permanent FullTransactionId to the given TransactionState.
631 * We do not assign XIDs to transactions until/unless this is called.
632 * Also, any parent TransactionStates that don't yet have XIDs are assigned
633 * one; this maintains the invariant that a child transaction has an XID
634 * following its parent's.
635 */
636static void
638{
639 bool isSubXact = (s->parent != NULL);
641 bool log_unknown_top = false;
642
643 /* Assert that caller didn't screw up */
646
647 /*
648 * Workers synchronize transaction state at the beginning of each parallel
649 * operation, so we can't account for new XIDs at this point.
650 */
654 errmsg("cannot assign transaction IDs during a parallel operation")));
655
656 /*
657 * Ensure parent(s) have XIDs, so that a child always has an XID later
658 * than its parent. Mustn't recurse here, or we might get a stack
659 * overflow if we're at the bottom of a huge stack of subtransactions none
660 * of which have XIDs yet.
661 */
663 {
665 TransactionState *parents;
666 size_t parentOffset = 0;
667
670 {
671 parents[parentOffset++] = p;
672 p = p->parent;
673 }
674
675 /*
676 * This is technically a recursive call, but the recursion will never
677 * be more than one layer deep.
678 */
679 while (parentOffset != 0)
680 AssignTransactionId(parents[--parentOffset]);
681
682 pfree(parents);
683 }
684
685 /*
686 * When effective_wal_level is logical, guarantee that a subtransaction's
687 * xid can only be seen in the WAL stream if its toplevel xid has been
688 * logged before. If necessary we log an xact_assignment record with fewer
689 * than PGPROC_MAX_CACHED_SUBXIDS. Note that it is fine if didLogXid isn't
690 * set for a transaction even though it appears in a WAL record, we just
691 * might superfluously log something. That can happen when an xid is
692 * included somewhere inside a wal record, but not in XLogRecord->xl_xid,
693 * like in xl_standby_locks.
694 */
697 log_unknown_top = true;
698
699 /*
700 * Generate a new FullTransactionId and record its xid in PGPROC and
701 * pg_subtrans.
702 *
703 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
704 * shared storage other than PGPROC; because if there's no room for it in
705 * PGPROC, the subtrans entry is needed to ensure that other backends see
706 * the Xid as "running". See GetNewTransactionId.
707 */
709 if (!isSubXact)
711
712 if (isSubXact)
715
716 /*
717 * If it's a top-level transaction, the predicate locking system needs to
718 * be told about it too.
719 */
720 if (!isSubXact)
722
723 /*
724 * Acquire lock on the transaction XID. (We assume this cannot block.) We
725 * have to ensure that the lock is assigned to the transaction's own
726 * ResourceOwner.
727 */
730
732
734
735 /*
736 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
737 * top-level transaction we issue a WAL record for the assignment. We
738 * include the top-level xid and all the subxids that have not yet been
739 * reported using XLOG_XACT_ASSIGNMENT records.
740 *
741 * This is required to limit the amount of shared memory required in a hot
742 * standby server to keep track of in-progress XIDs. See notes for
743 * RecordKnownAssignedTransactionIds().
744 *
745 * We don't keep track of the immediate parent of each subxid, only the
746 * top-level transaction that each subxact belongs to. This is correct in
747 * recovery only because aborted subtransactions are separately WAL
748 * logged.
749 *
750 * This is correct even for the case where several levels above us didn't
751 * have an xid assigned as we recursed up to them beforehand.
752 */
754 {
757
758 /*
759 * ensure this test matches similar one in
760 * RecoverPreparedTransactions()
761 */
764 {
766
767 /*
768 * xtop is always set by now because we recurse up transaction
769 * stack to the highest unassigned xid and then come back down
770 */
773 xlrec.nsubxacts = nUnreportedXids;
774
779
781
782 nUnreportedXids = 0;
783 /* mark top, not current xact as having been logged */
785 }
786 }
787}
788
789/*
790 * GetCurrentSubTransactionId
791 */
799
800/*
801 * SubTransactionIsActive
802 *
803 * Test if the specified subxact ID is still active. Note caller is
804 * responsible for checking whether this ID is relevant to the current xact.
805 */
806bool
808{
810
811 for (s = CurrentTransactionState; s != NULL; s = s->parent)
812 {
813 if (s->state == TRANS_ABORT)
814 continue;
815 if (s->subTransactionId == subxid)
816 return true;
817 }
818 return false;
819}
820
821
822/*
823 * GetCurrentCommandId
824 *
825 * "used" must be true if the caller intends to use the command ID to mark
826 * inserted/updated/deleted tuples. false means the ID is being fetched
827 * for read-only purposes (ie, as a snapshot validity cutoff). See
828 * CommandCounterIncrement() for discussion.
829 */
832{
833 /* this is global to a transaction, not subtransaction-local */
834 if (used)
835 {
836 /*
837 * Forbid setting currentCommandIdUsed in a parallel worker, because
838 * we have no provision for communicating this back to the leader. We
839 * could relax this restriction when currentCommandIdUsed was already
840 * true at the start of the parallel operation.
841 */
842 if (IsParallelWorker())
845 errmsg("cannot modify data in a parallel worker")));
846
848 }
849 return currentCommandId;
850}
851
852/*
853 * SetParallelStartTimestamps
854 *
855 * In a parallel worker, we should inherit the parent transaction's
856 * timestamps rather than setting our own. The parallel worker
857 * infrastructure must call this to provide those values before
858 * calling StartTransaction() or SetCurrentStatementStartTimestamp().
859 */
860void
867
868/*
869 * GetCurrentTransactionStartTimestamp
870 */
876
877/*
878 * GetCurrentStatementStartTimestamp
879 */
885
886/*
887 * GetCurrentTransactionStopTimestamp
888 *
889 * If the transaction stop time hasn't already been set, which can happen if
890 * we decided we don't need to log an XLOG record, set xactStopTimestamp.
891 */
894{
896
897 /* should only be called after commit / abort processing */
898 Assert(s->state == TRANS_DEFAULT ||
899 s->state == TRANS_COMMIT ||
900 s->state == TRANS_ABORT ||
901 s->state == TRANS_PREPARE);
902
903 if (xactStopTimestamp == 0)
905
906 return xactStopTimestamp;
907}
908
909/*
910 * SetCurrentStatementStartTimestamp
911 *
912 * In a parallel worker, this should already have been provided by a call
913 * to SetParallelStartTimestamps().
914 */
915void
923
924/*
925 * GetCurrentTransactionNestLevel
926 *
927 * Note: this will return zero when not inside any transaction, one when
928 * inside a top-level transaction, etc.
929 */
930int
937
938
939/*
940 * TransactionIdIsCurrentTransactionId
941 */
942bool
944{
946
947 /*
948 * We always say that BootstrapTransactionId is "not my transaction ID"
949 * even when it is (ie, during bootstrap). Along with the fact that
950 * transam.c always treats BootstrapTransactionId as already committed,
951 * this causes the heapam_visibility.c routines to see all tuples as
952 * committed, which is what we need during bootstrap. (Bootstrap mode
953 * only inserts tuples, it never updates or deletes them, so all tuples
954 * can be presumed good immediately.)
955 *
956 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
957 * not my transaction ID, so we can just return "false" immediately for
958 * any non-normal XID.
959 */
960 if (!TransactionIdIsNormal(xid))
961 return false;
962
964 return true;
965
966 /*
967 * In parallel workers, the XIDs we must consider as current are stored in
968 * ParallelCurrentXids rather than the transaction-state stack. Note that
969 * the XIDs in this array are sorted numerically rather than according to
970 * transactionIdPrecedes order.
971 */
972 if (nParallelCurrentXids > 0)
973 {
974 int low,
975 high;
976
977 low = 0;
978 high = nParallelCurrentXids - 1;
979 while (low <= high)
980 {
981 int middle;
983
984 middle = low + (high - low) / 2;
986 if (probe == xid)
987 return true;
988 else if (probe < xid)
989 low = middle + 1;
990 else
991 high = middle - 1;
992 }
993 return false;
994 }
995
996 /*
997 * We will return true for the Xid of the current subtransaction, any of
998 * its subcommitted children, any of its parents, or any of their
999 * previously subcommitted children. However, a transaction being aborted
1000 * is no longer "current", even though it may still have an entry on the
1001 * state stack.
1002 */
1003 for (s = CurrentTransactionState; s != NULL; s = s->parent)
1004 {
1005 int low,
1006 high;
1007
1008 if (s->state == TRANS_ABORT)
1009 continue;
1011 continue; /* it can't have any child XIDs either */
1013 return true;
1014 /* As the childXids array is ordered, we can use binary search */
1015 low = 0;
1016 high = s->nChildXids - 1;
1017 while (low <= high)
1018 {
1019 int middle;
1021
1022 middle = low + (high - low) / 2;
1023 probe = s->childXids[middle];
1024 if (TransactionIdEquals(probe, xid))
1025 return true;
1026 else if (TransactionIdPrecedes(probe, xid))
1027 low = middle + 1;
1028 else
1029 high = middle - 1;
1030 }
1031 }
1032
1033 return false;
1034}
1035
1036/*
1037 * TransactionStartedDuringRecovery
1038 *
1039 * Returns true if the current transaction started while recovery was still
1040 * in progress. Recovery might have ended since so RecoveryInProgress() might
1041 * return false already.
1042 */
1043bool
1048
1049/*
1050 * GetTopReadOnlyTransactionNestLevel
1051 *
1052 * Note: this will return zero when not inside any transaction or when neither
1053 * a top-level transaction nor subtransactions are read-only, one when the
1054 * top-level transaction is read-only, two when one level of subtransaction is
1055 * read-only, etc.
1056 *
1057 * Note: subtransactions of the topmost read-only transaction are also
1058 * read-only, because they inherit read-only mode from the transaction, and
1059 * thus can't change to read-write mode (see check_transaction_read_only).
1060 */
1061int
1063{
1065
1066 if (!XactReadOnly)
1067 return 0;
1068 while (s->nestingLevel > 1)
1069 {
1070 if (!s->prevXactReadOnly)
1071 return s->nestingLevel;
1072 s = s->parent;
1073 }
1074 return s->nestingLevel;
1075}
1076
1077/*
1078 * EnterParallelMode
1079 */
1080void
1082{
1084
1085 Assert(s->parallelModeLevel >= 0);
1086
1087 ++s->parallelModeLevel;
1088}
1089
1090/*
1091 * ExitParallelMode
1092 */
1093void
1104
1105/*
1106 * IsInParallelMode
1107 *
1108 * Are we in a parallel operation, as either the leader or a worker? Check
1109 * this to prohibit operations that change backend-local state expected to
1110 * match across all workers. Mere caches usually don't require such a
1111 * restriction. State modified in a strict push/pop fashion, such as the
1112 * active snapshot stack, is often fine.
1113 *
1114 * We say we are in parallel mode if we are in a subxact of a transaction
1115 * that's initiated a parallel operation; for most purposes that context
1116 * has all the same restrictions.
1117 */
1118bool
1120{
1122
1123 return s->parallelModeLevel != 0 || s->parallelChildXact;
1124}
1125
1126/*
1127 * CommandCounterIncrement
1128 */
1129void
1131{
1132 /*
1133 * If the current value of the command counter hasn't been "used" to mark
1134 * tuples, we need not increment it, since there's no need to distinguish
1135 * a read-only command from others. This helps postpone command counter
1136 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
1137 */
1139 {
1140 /*
1141 * Workers synchronize transaction state at the beginning of each
1142 * parallel operation, so we can't account for new commands after that
1143 * point.
1144 */
1146 ereport(ERROR,
1148 errmsg("cannot start commands during a parallel operation")));
1149
1150 currentCommandId += 1;
1152 {
1153 currentCommandId -= 1;
1154 ereport(ERROR,
1156 errmsg("cannot have more than 2^32-2 commands in a transaction")));
1157 }
1158 currentCommandIdUsed = false;
1159
1160 /* Propagate new command ID into static snapshots */
1162
1163 /*
1164 * Make any catalog changes done by the just-completed command visible
1165 * in the local syscache. We obviously don't need to do this after a
1166 * read-only command. (But see hacks in inval.c to make real sure we
1167 * don't think a command that queued inval messages was read-only.)
1168 */
1170 }
1171}
1172
1173/*
1174 * ForceSyncCommit
1175 *
1176 * Interface routine to allow commands to force a synchronous commit of the
1177 * current top-level transaction. Currently, two-phase commit does not
1178 * persist and restore this variable. So long as all callers use
1179 * PreventInTransactionBlock(), that omission has no consequences.
1180 */
1181void
1183{
1184 forceSyncCommit = true;
1185}
1186
1187
1188/* ----------------------------------------------------------------
1189 * StartTransaction stuff
1190 * ----------------------------------------------------------------
1191 */
1192
1193/*
1194 * AtStart_Cache
1195 */
1196static void
1201
1202/*
1203 * AtStart_Memory
1204 */
1205static void
1207{
1209
1210 /*
1211 * Remember the memory context that was active prior to transaction start.
1212 */
1214
1215 /*
1216 * If this is the first time through, create a private context for
1217 * AbortTransaction to work in. By reserving some space now, we can
1218 * insulate AbortTransaction from out-of-memory scenarios. Like
1219 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1220 * size, so that space will be reserved immediately.
1221 */
1225 "TransactionAbortContext",
1226 32 * 1024,
1227 32 * 1024,
1228 32 * 1024);
1229
1230 /*
1231 * Likewise, if this is the first time through, create a top-level context
1232 * for transaction-local data. This context will be reset at transaction
1233 * end, and then re-used in later transactions.
1234 */
1238 "TopTransactionContext",
1240
1241 /*
1242 * In a top-level transaction, CurTransactionContext is the same as
1243 * TopTransactionContext.
1244 */
1247
1248 /* Make the CurTransactionContext active. */
1250}
1251
1252/*
1253 * AtStart_ResourceOwner
1254 */
1255static void
1257{
1259
1260 /*
1261 * We shouldn't have a transaction resource owner already.
1262 */
1264
1265 /*
1266 * Create a toplevel resource owner for the transaction.
1267 */
1268 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1269
1273}
1274
1275/* ----------------------------------------------------------------
1276 * StartSubTransaction stuff
1277 * ----------------------------------------------------------------
1278 */
1279
1280/*
1281 * AtSubStart_Memory
1282 */
1283static void
1285{
1287
1289
1290 /*
1291 * Remember the context that was active prior to subtransaction start.
1292 */
1294
1295 /*
1296 * Create a CurTransactionContext, which will be used to hold data that
1297 * survives subtransaction commit but disappears on subtransaction abort.
1298 * We make it a child of the immediate parent's CurTransactionContext.
1299 */
1301 "CurTransactionContext",
1304
1305 /* Make the CurTransactionContext active. */
1307}
1308
1309/*
1310 * AtSubStart_ResourceOwner
1311 */
1312static void
1314{
1316
1317 Assert(s->parent != NULL);
1318
1319 /*
1320 * Create a resource owner for the subtransaction. We make it a child of
1321 * the immediate parent's resource owner.
1322 */
1325 "SubTransaction");
1326
1329}
1330
1331/* ----------------------------------------------------------------
1332 * CommitTransaction stuff
1333 * ----------------------------------------------------------------
1334 */
1335
1336/*
1337 * RecordTransactionCommit
1338 *
1339 * Returns latest XID among xact and its children, or InvalidTransactionId
1340 * if the xact has no XID. (We compute that here just because it's easier.)
1341 *
1342 * If you change this function, see RecordTransactionCommitPrepared also.
1343 */
1344static TransactionId
1346{
1350 int nrels;
1351 RelFileLocator *rels;
1352 int nchildren;
1353 TransactionId *children;
1354 int ndroppedstats = 0;
1356 int nmsgs = 0;
1358 bool RelcacheInitFileInval = false;
1359 bool wrote_xlog;
1360
1361 /*
1362 * Log pending invalidations for logical decoding of in-progress
1363 * transactions. Normally for DDLs, we log this at each command end,
1364 * however, for certain cases where we directly update the system table
1365 * without a transaction block, the invalidations are not logged till this
1366 * time.
1367 */
1370
1371 /* Get data needed for commit record */
1372 nrels = smgrGetPendingDeletes(true, &rels);
1377 &RelcacheInitFileInval);
1378 wrote_xlog = (XactLastRecEnd != 0);
1379
1380 /*
1381 * If we haven't been assigned an XID yet, we neither can, nor do we want
1382 * to write a COMMIT record.
1383 */
1384 if (!markXidCommitted)
1385 {
1386 /*
1387 * We expect that every RelationDropStorage is followed by a catalog
1388 * update, and hence XID assignment, so we shouldn't get here with any
1389 * pending deletes. Same is true for dropping stats.
1390 *
1391 * Use a real test not just an Assert to check this, since it's a bit
1392 * fragile.
1393 */
1394 if (nrels != 0 || ndroppedstats != 0)
1395 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
1396
1397 /* Can't have child XIDs either; AssignTransactionId enforces this */
1398 Assert(nchildren == 0);
1399
1400 /*
1401 * Transactions without an assigned xid can contain invalidation
1402 * messages. While inplace updates do this, this is not known to be
1403 * necessary; see comment at inplace CacheInvalidateHeapTuple().
1404 * Extensions might still rely on this capability, and standbys may
1405 * need to process those invals. We can't emit a commit record
1406 * without an xid, and we don't want to force assigning an xid,
1407 * because that'd be problematic for e.g. vacuum. Hence we emit a
1408 * bespoke record for the invalidations. We don't want to use that in
1409 * case a commit record is emitted, so they happen synchronously with
1410 * commits (besides not wanting to emit more WAL records).
1411 *
1412 * XXX Every known use of this capability is a defect. Since an XID
1413 * isn't controlling visibility of the change that prompted invals,
1414 * other sessions need the inval even if this transactions aborts.
1415 *
1416 * ON COMMIT DELETE ROWS does a nontransactional index_build(), which
1417 * queues a relcache inval, including in transactions without an xid
1418 * that had read the (empty) table. Standbys don't need any ON COMMIT
1419 * DELETE ROWS invals, but we've not done the work to withhold them.
1420 */
1421 if (nmsgs != 0)
1422 {
1424 RelcacheInitFileInval);
1425 wrote_xlog = true; /* not strictly necessary */
1426 }
1427
1428 /*
1429 * If we didn't create XLOG entries, we're done here; otherwise we
1430 * should trigger flushing those entries the same as a commit record
1431 * would. This will primarily happen for HOT pruning and the like; we
1432 * want these to be flushed to disk in due time.
1433 */
1434 if (!wrote_xlog)
1435 goto cleanup;
1436 }
1437 else
1438 {
1439 bool replorigin;
1440
1441 /*
1442 * Are we using the replication origins feature? Or, in other words,
1443 * are we replaying remote actions?
1444 */
1447
1448 /*
1449 * Mark ourselves as within our "commit critical section". This
1450 * forces any concurrent checkpoint to wait until we've updated
1451 * pg_xact. Without this, it is possible for the checkpoint to set
1452 * REDO after the XLOG record but fail to flush the pg_xact update to
1453 * disk, leading to loss of the transaction commit if the system
1454 * crashes a little later.
1455 *
1456 * Note: we could, but don't bother to, set this flag in
1457 * RecordTransactionAbort. That's because loss of a transaction abort
1458 * is noncritical; the presumption would be that it aborted, anyway.
1459 *
1460 * It's safe to change the delayChkptFlags flag of our own backend
1461 * without holding the ProcArrayLock, since we're the only one
1462 * modifying it. This makes checkpoint's determination of which xacts
1463 * are delaying the checkpoint a bit fuzzy, but it doesn't matter.
1464 *
1465 * Note, it is important to get the commit timestamp after marking the
1466 * transaction in the commit critical section. See
1467 * RecordTransactionCommitPrepared.
1468 */
1472
1474
1475 /*
1476 * Ensures the DELAY_CHKPT_IN_COMMIT flag write is globally visible
1477 * before commit time is written.
1478 */
1480
1481 /*
1482 * Insert the commit XLOG record.
1483 */
1485 nchildren, children, nrels, rels,
1487 nmsgs, invalMessages,
1488 RelcacheInitFileInval,
1490 InvalidTransactionId, NULL /* plain commit */ );
1491
1492 if (replorigin)
1493 /* Move LSNs forward for this replication origin */
1496
1497 /*
1498 * Record commit timestamp. The value comes from plain commit
1499 * timestamp if there's no replication origin; otherwise, the
1500 * timestamp was already set in replorigin_xact_state.origin_timestamp
1501 * by replication.
1502 *
1503 * We don't need to WAL-log anything here, as the commit record
1504 * written above already contains the data.
1505 */
1506
1509
1513 }
1514
1515 /*
1516 * Check if we want to commit asynchronously. We can allow the XLOG flush
1517 * to happen asynchronously if synchronous_commit=off, or if the current
1518 * transaction has not performed any WAL-logged operation or didn't assign
1519 * an xid. The transaction can end up not writing any WAL, even if it has
1520 * an xid, if it only wrote to temporary and/or unlogged tables. It can
1521 * end up having written WAL without an xid if it did HOT pruning. In
1522 * case of a crash, the loss of such a transaction will be irrelevant;
1523 * temp tables will be lost anyway, unlogged tables will be truncated and
1524 * HOT pruning will be done again later. (Given the foregoing, you might
1525 * think that it would be unnecessary to emit the XLOG record at all in
1526 * this case, but we don't currently try to do that. It would certainly
1527 * cause problems at least in Hot Standby mode, where the
1528 * KnownAssignedXids machinery requires tracking every XID assignment. It
1529 * might be OK to skip it only when wal_level < replica, but for now we
1530 * don't.)
1531 *
1532 * However, if we're doing cleanup of any non-temp rels or committing any
1533 * command that wanted to force sync commit, then we must flush XLOG
1534 * immediately. (We must not allow asynchronous commit if there are any
1535 * non-temp tables to be deleted, because we might delete the files before
1536 * the COMMIT record is flushed to disk. We do allow asynchronous commit
1537 * if all to-be-deleted tables are temporary though, since they are lost
1538 * anyway if we crash.)
1539 */
1540 if ((wrote_xlog && markXidCommitted &&
1542 forceSyncCommit || nrels > 0)
1543 {
1545
1546 /*
1547 * Now we may update the CLOG, if we wrote a COMMIT record above
1548 */
1549 if (markXidCommitted)
1550 TransactionIdCommitTree(xid, nchildren, children);
1551 }
1552 else
1553 {
1554 /*
1555 * Asynchronous commit case:
1556 *
1557 * This enables possible committed transaction loss in the case of a
1558 * postmaster crash because WAL buffers are left unwritten. Ideally we
1559 * could issue the WAL write without the fsync, but some
1560 * wal_sync_methods do not allow separate write/fsync.
1561 *
1562 * Report the latest async commit LSN, so that the WAL writer knows to
1563 * flush this commit.
1564 */
1566
1567 /*
1568 * We must not immediately update the CLOG, since we didn't flush the
1569 * XLOG. Instead, we store the LSN up to which the XLOG must be
1570 * flushed before the CLOG may be updated.
1571 */
1572 if (markXidCommitted)
1574 }
1575
1576 /*
1577 * If we entered a commit critical section, leave it now, and let
1578 * checkpoints proceed.
1579 */
1580 if (markXidCommitted)
1581 {
1584 }
1585
1586 /* Compute latestXid while we have the child XIDs handy */
1587 latestXid = TransactionIdLatest(xid, nchildren, children);
1588
1589 /*
1590 * Wait for synchronous replication, if required. Similar to the decision
1591 * above about using committing asynchronously we only want to wait if
1592 * this backend assigned an xid and wrote WAL. No need to wait if an xid
1593 * was assigned due to temporary/unlogged tables or due to HOT pruning.
1594 *
1595 * Note that at this stage we have marked clog, but still show as running
1596 * in the procarray and continue to hold locks.
1597 */
1600
1601 /* remember end of last commit record */
1603
1604 /* Reset XactLastRecEnd until the next transaction writes something */
1605 XactLastRecEnd = 0;
1606cleanup:
1607 /* Clean up local data */
1608 if (rels)
1609 pfree(rels);
1610 if (ndroppedstats)
1612
1613 return latestXid;
1614}
1615
1616
1617/*
1618 * AtCCI_LocalCache
1619 */
1620static void
1622{
1623 /*
1624 * Make any pending relation map changes visible. We must do this before
1625 * processing local sinval messages, so that the map changes will get
1626 * reflected into the relcache when relcache invals are processed.
1627 */
1629
1630 /*
1631 * Make catalog changes visible to me for the next command.
1632 */
1634}
1635
1636/*
1637 * AtCommit_Memory
1638 */
1639static void
1641{
1643
1644 /*
1645 * Return to the memory context that was current before we started the
1646 * transaction. (In principle, this could not be any of the contexts we
1647 * are about to delete. If it somehow is, assertions in mcxt.c will
1648 * complain.)
1649 */
1651
1652 /*
1653 * Release all transaction-local memory. TopTransactionContext survives
1654 * but becomes empty; any sub-contexts go away.
1655 */
1658
1659 /*
1660 * Clear these pointers as a pro-forma matter. (Notionally, while
1661 * TopTransactionContext still exists, it's currently not associated with
1662 * this TransactionState struct.)
1663 */
1666}
1667
1668/* ----------------------------------------------------------------
1669 * CommitSubTransaction stuff
1670 * ----------------------------------------------------------------
1671 */
1672
1673/*
1674 * AtSubCommit_Memory
1675 */
1676static void
1678{
1680
1681 Assert(s->parent != NULL);
1682
1683 /* Return to parent transaction level's memory context. */
1686
1687 /*
1688 * Ordinarily we cannot throw away the child's CurTransactionContext,
1689 * since the data it contains will be needed at upper commit. However, if
1690 * there isn't actually anything in it, we can throw it away. This avoids
1691 * a small memory leak in the common case of "trivial" subxacts.
1692 */
1694 {
1697 }
1698}
1699
1700/*
1701 * AtSubCommit_childXids
1702 *
1703 * Pass my own XID and my child XIDs up to my parent as committed children.
1704 */
1705static void
1707{
1709 int new_nChildXids;
1710
1711 Assert(s->parent != NULL);
1712
1713 /*
1714 * The parent childXids array will need to hold my XID and all my
1715 * childXids, in addition to the XIDs already there.
1716 */
1718
1719 /* Allocate or enlarge the parent array if necessary */
1721 {
1722 int new_maxChildXids;
1724
1725 /*
1726 * Make it 2x what's needed right now, to avoid having to enlarge it
1727 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1728 * is what ensures that we don't need to worry about integer overflow
1729 * here or in the calculation of new_nChildXids.)
1730 */
1732 (int) (MaxAllocSize / sizeof(TransactionId)));
1733
1735 ereport(ERROR,
1737 errmsg("maximum number of committed subtransactions (%d) exceeded",
1738 (int) (MaxAllocSize / sizeof(TransactionId)))));
1739
1740 /*
1741 * We keep the child-XID arrays in TopTransactionContext; this avoids
1742 * setting up child-transaction contexts for what might be just a few
1743 * bytes of grandchild XIDs.
1744 */
1745 if (s->parent->childXids == NULL)
1749 else
1752
1755 }
1756
1757 /*
1758 * Copy all my XIDs to parent's array.
1759 *
1760 * Note: We rely on the fact that the XID of a child always follows that
1761 * of its parent. By copying the XID of this subtransaction before the
1762 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1763 * all XIDs already in the array belong to subtransactions started and
1764 * subcommitted before us, so their XIDs must precede ours.
1765 */
1767
1768 if (s->nChildXids > 0)
1769 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1770 s->childXids,
1771 s->nChildXids * sizeof(TransactionId));
1772
1774
1775 /* Release child's array to avoid leakage */
1776 if (s->childXids != NULL)
1777 pfree(s->childXids);
1778 /* We must reset these to avoid double-free if fail later in commit */
1779 s->childXids = NULL;
1780 s->nChildXids = 0;
1781 s->maxChildXids = 0;
1782}
1783
1784/* ----------------------------------------------------------------
1785 * AbortTransaction stuff
1786 * ----------------------------------------------------------------
1787 */
1788
1789/*
1790 * RecordTransactionAbort
1791 *
1792 * Returns latest XID among xact and its children, or InvalidTransactionId
1793 * if the xact has no XID. (We compute that here just because it's easier.)
1794 */
1795static TransactionId
1797{
1800 int nrels;
1801 RelFileLocator *rels;
1802 int ndroppedstats = 0;
1804 int nchildren;
1805 TransactionId *children;
1806 TimestampTz xact_time;
1807 bool replorigin;
1808
1809 /*
1810 * If we haven't been assigned an XID, nobody will care whether we aborted
1811 * or not. Hence, we're done in that case. It does not matter if we have
1812 * rels to delete (note that this routine is not responsible for actually
1813 * deleting 'em). We cannot have any child XIDs, either.
1814 */
1815 if (!TransactionIdIsValid(xid))
1816 {
1817 /* Reset XactLastRecEnd until the next transaction writes something */
1818 if (!isSubXact)
1819 XactLastRecEnd = 0;
1820 return InvalidTransactionId;
1821 }
1822
1823 /*
1824 * We have a valid XID, so we should write an ABORT record for it.
1825 *
1826 * We do not flush XLOG to disk here, since the default assumption after a
1827 * crash would be that we aborted, anyway. For the same reason, we don't
1828 * need to worry about interlocking against checkpoint start.
1829 */
1830
1831 /*
1832 * Check that we haven't aborted halfway through RecordTransactionCommit.
1833 */
1834 if (TransactionIdDidCommit(xid))
1835 elog(PANIC, "cannot abort transaction %u, it was already committed",
1836 xid);
1837
1838 /*
1839 * Are we using the replication origins feature? Or, in other words, are
1840 * we replaying remote actions?
1841 */
1844
1845 /* Fetch the data we need for the abort record */
1846 nrels = smgrGetPendingDeletes(false, &rels);
1849
1850 /* XXX do we really need a critical section here? */
1852
1853 /* Write the ABORT record */
1854 if (isSubXact)
1855 xact_time = GetCurrentTimestamp();
1856 else
1857 {
1859 }
1860
1861 XactLogAbortRecord(xact_time,
1862 nchildren, children,
1863 nrels, rels,
1866 NULL);
1867
1868 if (replorigin)
1869 /* Move LSNs forward for this replication origin */
1872
1873 /*
1874 * Report the latest async abort LSN, so that the WAL writer knows to
1875 * flush this abort. There's nothing to be gained by delaying this, since
1876 * WALWriter may as well do this when it can. This is important with
1877 * streaming replication because if we don't flush WAL regularly we will
1878 * find that large aborts leave us with a long backlog for when commits
1879 * occur after the abort, increasing our window of data loss should
1880 * problems occur at that point.
1881 */
1882 if (!isSubXact)
1884
1885 /*
1886 * Mark the transaction aborted in clog. This is not absolutely necessary
1887 * but we may as well do it while we are here; also, in the subxact case
1888 * it is helpful because XactLockTableWait makes use of it to avoid
1889 * waiting for already-aborted subtransactions. It is OK to do it without
1890 * having flushed the ABORT record to disk, because in event of a crash
1891 * we'd be assumed to have aborted anyway.
1892 */
1893 TransactionIdAbortTree(xid, nchildren, children);
1894
1896
1897 /* Compute latestXid while we have the child XIDs handy */
1898 latestXid = TransactionIdLatest(xid, nchildren, children);
1899
1900 /*
1901 * If we're aborting a subtransaction, we can immediately remove failed
1902 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1903 * subxacts, because we already have the child XID array at hand. For
1904 * main xacts, the equivalent happens just after this function returns.
1905 */
1906 if (isSubXact)
1908
1909 /* Reset XactLastRecEnd until the next transaction writes something */
1910 if (!isSubXact)
1911 XactLastRecEnd = 0;
1912
1913 /* And clean up local data */
1914 if (rels)
1915 pfree(rels);
1916 if (ndroppedstats)
1918
1919 return latestXid;
1920}
1921
1922/*
1923 * AtAbort_Memory
1924 */
1925static void
1927{
1928 /*
1929 * Switch into TransactionAbortContext, which should have some free space
1930 * even if nothing else does. We'll work in this context until we've
1931 * finished cleaning up.
1932 *
1933 * It is barely possible to get here when we've not been able to create
1934 * TransactionAbortContext yet; if so use TopMemoryContext.
1935 */
1938 else
1940}
1941
1942/*
1943 * AtSubAbort_Memory
1944 */
1945static void
1952
1953
1954/*
1955 * AtAbort_ResourceOwner
1956 */
1957static void
1959{
1960 /*
1961 * Make sure we have a valid ResourceOwner, if possible (else it will be
1962 * NULL, which is OK)
1963 */
1965}
1966
1967/*
1968 * AtSubAbort_ResourceOwner
1969 */
1970static void
1972{
1974
1975 /* Make sure we have a valid ResourceOwner */
1977}
1978
1979
1980/*
1981 * AtSubAbort_childXids
1982 */
1983static void
1985{
1987
1988 /*
1989 * We keep the child-XID arrays in TopTransactionContext (see
1990 * AtSubCommit_childXids). This means we'd better free the array
1991 * explicitly at abort to avoid leakage.
1992 */
1993 if (s->childXids != NULL)
1994 pfree(s->childXids);
1995 s->childXids = NULL;
1996 s->nChildXids = 0;
1997 s->maxChildXids = 0;
1998
1999 /*
2000 * We could prune the unreportedXids array here. But we don't bother. That
2001 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
2002 * would likely introduce more CPU time into the more common paths, so we
2003 * choose not to do that.
2004 */
2005}
2006
2007/* ----------------------------------------------------------------
2008 * CleanupTransaction stuff
2009 * ----------------------------------------------------------------
2010 */
2011
2012/*
2013 * AtCleanup_Memory
2014 */
2015static void
2017{
2019
2020 /* Should be at top level */
2021 Assert(s->parent == NULL);
2022
2023 /*
2024 * Return to the memory context that was current before we started the
2025 * transaction. (In principle, this could not be any of the contexts we
2026 * are about to delete. If it somehow is, assertions in mcxt.c will
2027 * complain.)
2028 */
2030
2031 /*
2032 * Clear the special abort context for next time.
2033 */
2036
2037 /*
2038 * Release all transaction-local memory, the same as in AtCommit_Memory,
2039 * except we must cope with the possibility that we didn't get as far as
2040 * creating TopTransactionContext.
2041 */
2044
2045 /*
2046 * Clear these pointers as a pro-forma matter. (Notionally, while
2047 * TopTransactionContext still exists, it's currently not associated with
2048 * this TransactionState struct.)
2049 */
2052}
2053
2054
2055/* ----------------------------------------------------------------
2056 * CleanupSubTransaction stuff
2057 * ----------------------------------------------------------------
2058 */
2059
2060/*
2061 * AtSubCleanup_Memory
2062 */
2063static void
2065{
2067
2068 Assert(s->parent != NULL);
2069
2070 /*
2071 * Return to the memory context that was current before we started the
2072 * subtransaction. (In principle, this could not be any of the contexts
2073 * we are about to delete. If it somehow is, assertions in mcxt.c will
2074 * complain.)
2075 */
2077
2078 /* Update CurTransactionContext (might not be same as priorContext) */
2080
2081 /*
2082 * Clear the special abort context for next time.
2083 */
2086
2087 /*
2088 * Delete the subxact local memory contexts. Its CurTransactionContext can
2089 * go too (note this also kills CurTransactionContexts from any children
2090 * of the subxact).
2091 */
2092 if (s->curTransactionContext)
2095}
2096
2097/* ----------------------------------------------------------------
2098 * interface routines
2099 * ----------------------------------------------------------------
2100 */
2101
2102/*
2103 * StartTransaction
2104 */
2105static void
2107{
2110
2111 /*
2112 * Let's just make sure the state stack is empty
2113 */
2116
2118
2119 /* check the current transaction state */
2120 Assert(s->state == TRANS_DEFAULT);
2121
2122 /*
2123 * Set the current transaction state information appropriately during
2124 * start processing. Note that once the transaction status is switched
2125 * this process cannot fail until the user ID and the security context
2126 * flags are fetched below.
2127 */
2128 s->state = TRANS_START;
2129 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
2130
2131 /* Determine if statements are logged in this transaction */
2133 (log_xact_sample_rate == 1 ||
2135
2136 /*
2137 * initialize current transaction state fields
2138 *
2139 * note: prevXactReadOnly is not used at the outermost level
2140 */
2141 s->nestingLevel = 1;
2142 s->gucNestLevel = 1;
2143 s->childXids = NULL;
2144 s->nChildXids = 0;
2145 s->maxChildXids = 0;
2146
2147 /*
2148 * Once the current user ID and the security context flags are fetched,
2149 * both will be properly reset even if transaction startup fails.
2150 */
2152
2153 /* SecurityRestrictionContext should never be set outside a transaction */
2154 Assert(s->prevSecContext == 0);
2155
2156 /*
2157 * Make sure we've reset xact state variables
2158 *
2159 * If recovery is still in progress, mark this transaction as read-only.
2160 * We have lower level defences in XLogInsert and elsewhere to stop us
2161 * from modifying data during recovery, but this gives the normal
2162 * indication to the user that the transaction is read-only.
2163 */
2164 if (RecoveryInProgress())
2165 {
2166 s->startedInRecovery = true;
2167 XactReadOnly = true;
2168 }
2169 else
2170 {
2171 s->startedInRecovery = false;
2173 }
2176 forceSyncCommit = false;
2177 MyXactFlags = 0;
2178
2179 /*
2180 * reinitialize within-transaction counters
2181 */
2185 currentCommandIdUsed = false;
2186
2187 /*
2188 * initialize reported xid accounting
2189 */
2190 nUnreportedXids = 0;
2191 s->didLogXid = false;
2192
2193 /*
2194 * must initialize resource-management stuff first
2195 */
2198
2199 /*
2200 * Assign a new LocalTransactionId, and combine it with the proc number to
2201 * form a virtual transaction id.
2202 */
2203 vxid.procNumber = MyProcNumber;
2205
2206 /*
2207 * Lock the virtual transaction id before we announce it in the proc array
2208 */
2210
2211 /*
2212 * Advertise it in the proc array. We assume assignment of
2213 * localTransactionId is atomic, and the proc number should be set
2214 * already.
2215 */
2218
2220
2221 /*
2222 * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2223 * be the same as the first command's statement_timestamp(), so don't do a
2224 * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2225 * for transactions started inside procedures (i.e., nonatomic SPI
2226 * contexts), we do need to advance the timestamp. Also, in a parallel
2227 * worker, the timestamp should already have been provided by a call to
2228 * SetParallelStartTimestamps().
2229 */
2230 if (!IsParallelWorker())
2231 {
2234 else
2236 }
2237 else
2240 /* Mark xactStopTimestamp as unset. */
2242
2243 /*
2244 * initialize other subsystems for new transaction
2245 */
2246 AtStart_GUC();
2247 AtStart_Cache();
2249
2250 /*
2251 * done with start processing, set current transaction state to "in
2252 * progress"
2253 */
2255
2256 /* Schedule transaction timeout */
2257 if (TransactionTimeout > 0)
2259
2260 ShowTransactionState("StartTransaction");
2261}
2262
2263
2264/*
2265 * CommitTransaction
2266 *
2267 * NB: if you change this routine, better look at PrepareTransaction too!
2268 */
2269static void
2271{
2274 bool is_parallel_worker;
2275
2277
2278 /* Enforce parallel mode restrictions during parallel worker commit. */
2281
2282 ShowTransactionState("CommitTransaction");
2283
2284 /*
2285 * check the current transaction state
2286 */
2287 if (s->state != TRANS_INPROGRESS)
2288 elog(WARNING, "CommitTransaction while in %s state",
2290 Assert(s->parent == NULL);
2291
2292 /*
2293 * Do pre-commit processing that involves calling user-defined code, such
2294 * as triggers. SECURITY_RESTRICTED_OPERATION contexts must not queue an
2295 * action that would run here, because that would bypass the sandbox.
2296 * Since closing cursors could queue trigger actions, triggers could open
2297 * cursors, etc, we have to keep looping until there's nothing left to do.
2298 */
2299 for (;;)
2300 {
2301 /*
2302 * Fire all currently pending deferred triggers.
2303 */
2305
2306 /*
2307 * Close open portals (converting holdable ones into static portals).
2308 * If there weren't any, we are done ... otherwise loop back to check
2309 * if they queued deferred triggers. Lather, rinse, repeat.
2310 */
2311 if (!PreCommit_Portals(false))
2312 break;
2313 }
2314
2315 /*
2316 * The remaining actions cannot call any user-defined code, so it's safe
2317 * to start shutting down within-transaction services. But note that most
2318 * of this stuff could still throw an error, which would switch us into
2319 * the transaction-abort path.
2320 */
2321
2324
2325 /*
2326 * If this xact has started any unfinished parallel operation, clean up
2327 * its workers, warning about leaked resources. (But we don't actually
2328 * reset parallelModeLevel till entering TRANS_COMMIT, a bit below. This
2329 * keeps parallel mode restrictions active as long as possible in a
2330 * parallel worker.)
2331 */
2332 AtEOXact_Parallel(true);
2334 {
2335 if (s->parallelModeLevel != 1)
2336 elog(WARNING, "parallelModeLevel is %d not 1 at end of parallel worker transaction",
2338 }
2339 else
2340 {
2341 if (s->parallelModeLevel != 0)
2342 elog(WARNING, "parallelModeLevel is %d not 0 at end of transaction",
2344 }
2345
2346 /* Shut down the deferred-trigger manager */
2347 AfterTriggerEndXact(true);
2348
2349 /*
2350 * Let ON COMMIT management do its thing (must happen after closing
2351 * cursors, to avoid dangling-reference problems)
2352 */
2354
2355 /*
2356 * Synchronize files that are created and not WAL-logged during this
2357 * transaction. This must happen before AtEOXact_RelationMap(), so that we
2358 * don't see committed-but-broken files after a crash.
2359 */
2361
2362 /* close large objects before lower-level cleanup */
2364
2365 /*
2366 * Insert notifications sent by NOTIFY commands into the queue. This
2367 * should be late in the pre-commit sequence to minimize time spent
2368 * holding the notify-insertion lock. However, this could result in
2369 * creating a snapshot, so we must do it before serializable cleanup.
2370 */
2372
2373 /*
2374 * Mark serializable transaction as complete for predicate locking
2375 * purposes. This should be done as late as we can put it and still allow
2376 * errors to be raised for failure patterns found at commit. This is not
2377 * appropriate in a parallel worker however, because we aren't committing
2378 * the leader's transaction and its serializable state will live on.
2379 */
2380 if (!is_parallel_worker)
2382
2383 /* Prevent cancel/die interrupt while cleaning up */
2385
2386 /* Commit updates to the relation map --- do this as late as possible */
2388
2389 /*
2390 * set the current transaction state information appropriately during
2391 * commit processing
2392 */
2393 s->state = TRANS_COMMIT;
2394 s->parallelModeLevel = 0;
2395 s->parallelChildXact = false; /* should be false already */
2396
2397 /* Disable transaction timeout */
2398 if (TransactionTimeout > 0)
2400
2401 if (!is_parallel_worker)
2402 {
2403 /*
2404 * We need to mark our XIDs as committed in pg_xact. This is where we
2405 * durably commit.
2406 */
2408 }
2409 else
2410 {
2411 /*
2412 * We must not mark our XID committed; the parallel leader is
2413 * responsible for that.
2414 */
2416
2417 /*
2418 * Make sure the leader will know about any WAL we wrote before it
2419 * commits.
2420 */
2422 }
2423
2425
2426 /*
2427 * Let others know about no transaction in progress by me. Note that this
2428 * must be done _before_ releasing locks we hold and _after_
2429 * RecordTransactionCommit.
2430 */
2432
2433 /*
2434 * This is all post-commit cleanup. Note that if an error is raised here,
2435 * it's too late to abort the transaction. This should be just
2436 * noncritical resource releasing.
2437 *
2438 * The ordering of operations is not entirely random. The idea is:
2439 * release resources visible to other backends (eg, files, buffer pins);
2440 * then release locks; then release backend-local resources. We want to
2441 * release locks at the point where any backend waiting for us will see
2442 * our transaction as being fully cleaned up.
2443 *
2444 * Resources that can be associated with individual queries are handled by
2445 * the ResourceOwner mechanism. The other calls here are for backend-wide
2446 * state.
2447 */
2448
2451
2455 true, true);
2456
2457 AtEOXact_Aio(true);
2458
2459 /* Check we've released all buffer pins */
2460 AtEOXact_Buffers(true);
2461
2462 /* Clean up the relation cache */
2464
2465 /* Clean up the type cache */
2467
2468 /*
2469 * Make catalog changes visible to all backends. This has to happen after
2470 * relcache references are dropped (see comments for
2471 * AtEOXact_RelationCache), but before locks are released (if anyone is
2472 * waiting for lock on a relation we've modified, we want them to know
2473 * about the catalog change before they start using the relation).
2474 */
2475 AtEOXact_Inval(true);
2476
2478
2481 true, true);
2484 true, true);
2485
2486 /*
2487 * Likewise, dropping of files deleted during the transaction is best done
2488 * after releasing relcache and buffer pins. (This is not strictly
2489 * necessary during commit, since such pins should have been released
2490 * already, but this ordering is definitely critical during abort.) Since
2491 * this may take many seconds, also delay until after releasing locks.
2492 * Other backends will observe the attendant catalog changes and not
2493 * attempt to access affected files.
2494 */
2496
2497 /*
2498 * Send out notification signals to other backends (and do other
2499 * post-commit NOTIFY cleanup). This must not happen until after our
2500 * transaction is fully done from the viewpoint of other backends.
2501 */
2503
2504 /*
2505 * Everything after this should be purely internal-to-this-backend
2506 * cleanup.
2507 */
2508 AtEOXact_GUC(true, 1);
2509 AtEOXact_SPI(true);
2510 AtEOXact_Enum();
2513 AtEOXact_SMgr();
2514 AtEOXact_Files(true);
2516 AtEOXact_HashTables(true);
2518 AtEOXact_Snapshot(true, false);
2523
2528
2530
2533 s->nestingLevel = 0;
2534 s->gucNestLevel = 0;
2535 s->childXids = NULL;
2536 s->nChildXids = 0;
2537 s->maxChildXids = 0;
2538
2541
2542 /*
2543 * done with commit processing, set current transaction state back to
2544 * default
2545 */
2546 s->state = TRANS_DEFAULT;
2547
2549}
2550
2551
2552/*
2553 * PrepareTransaction
2554 *
2555 * NB: if you change this routine, better look at CommitTransaction too!
2556 */
2557static void
2559{
2563 TimestampTz prepared_at;
2564
2566
2567 ShowTransactionState("PrepareTransaction");
2568
2569 /*
2570 * check the current transaction state
2571 */
2572 if (s->state != TRANS_INPROGRESS)
2573 elog(WARNING, "PrepareTransaction while in %s state",
2575 Assert(s->parent == NULL);
2576
2577 /*
2578 * Do pre-commit processing that involves calling user-defined code, such
2579 * as triggers. Since closing cursors could queue trigger actions,
2580 * triggers could open cursors, etc, we have to keep looping until there's
2581 * nothing left to do.
2582 */
2583 for (;;)
2584 {
2585 /*
2586 * Fire all currently pending deferred triggers.
2587 */
2589
2590 /*
2591 * Close open portals (converting holdable ones into static portals).
2592 * If there weren't any, we are done ... otherwise loop back to check
2593 * if they queued deferred triggers. Lather, rinse, repeat.
2594 */
2595 if (!PreCommit_Portals(true))
2596 break;
2597 }
2598
2600
2601 /*
2602 * The remaining actions cannot call any user-defined code, so it's safe
2603 * to start shutting down within-transaction services. But note that most
2604 * of this stuff could still throw an error, which would switch us into
2605 * the transaction-abort path.
2606 */
2607
2608 /* Shut down the deferred-trigger manager */
2609 AfterTriggerEndXact(true);
2610
2611 /*
2612 * Let ON COMMIT management do its thing (must happen after closing
2613 * cursors, to avoid dangling-reference problems)
2614 */
2616
2617 /*
2618 * Synchronize files that are created and not WAL-logged during this
2619 * transaction. This must happen before EndPrepare(), so that we don't see
2620 * committed-but-broken files after a crash and COMMIT PREPARED.
2621 */
2622 smgrDoPendingSyncs(true, false);
2623
2624 /* close large objects before lower-level cleanup */
2626
2627 /* NOTIFY requires no work at this point */
2628
2629 /*
2630 * Mark serializable transaction as complete for predicate locking
2631 * purposes. This should be done as late as we can put it and still allow
2632 * errors to be raised for failure patterns found at commit.
2633 */
2635
2636 /*
2637 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2638 * this transaction. Having the prepared xact hold locks on another
2639 * backend's temp table seems a bad idea --- for instance it would prevent
2640 * the backend from exiting. There are other problems too, such as how to
2641 * clean up the source backend's local buffers and ON COMMIT state if the
2642 * prepared xact includes a DROP of a temp table.
2643 *
2644 * Other objects types, like functions, operators or extensions, share the
2645 * same restriction as they should not be created, locked or dropped as
2646 * this can mess up with this session or even a follow-up session trying
2647 * to use the same temporary namespace.
2648 *
2649 * We must check this after executing any ON COMMIT actions, because they
2650 * might still access a temp relation.
2651 *
2652 * XXX In principle this could be relaxed to allow some useful special
2653 * cases, such as a temp table created and dropped all within the
2654 * transaction. That seems to require much more bookkeeping though.
2655 */
2657 ereport(ERROR,
2659 errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2660
2661 /*
2662 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2663 * supported if we added cleanup logic to twophase.c, but for now it
2664 * doesn't seem worth the trouble.
2665 */
2667 ereport(ERROR,
2669 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2670
2671 /* Prevent cancel/die interrupt while cleaning up */
2673
2674 /*
2675 * set the current transaction state information appropriately during
2676 * prepare processing
2677 */
2678 s->state = TRANS_PREPARE;
2679
2680 /* Disable transaction timeout */
2681 if (TransactionTimeout > 0)
2683
2684 prepared_at = GetCurrentTimestamp();
2685
2686 /*
2687 * Reserve the GID for this transaction. This could fail if the requested
2688 * GID is invalid or already in use.
2689 */
2690 gxact = MarkAsPreparing(fxid, prepareGID, prepared_at,
2692 prepareGID = NULL;
2693
2694 /*
2695 * Collect data for the 2PC state file. Note that in general, no actual
2696 * state change should happen in the called modules during this step,
2697 * since it's still possible to fail before commit, and in that case we
2698 * want transaction abort to be able to clean up. (In particular, the
2699 * AtPrepare routines may error out if they find cases they cannot
2700 * handle.) State cleanup should happen in the PostPrepare routines
2701 * below. However, some modules can go ahead and clear state here because
2702 * they wouldn't do anything with it during abort anyway.
2703 *
2704 * Note: because the 2PC state file records will be replayed in the same
2705 * order they are made, the order of these calls has to match the order in
2706 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2707 * PREPARED; in particular, pay attention to whether things should happen
2708 * before or after releasing the transaction's locks.
2709 */
2711
2718
2719 /*
2720 * Here is where we really truly prepare.
2721 *
2722 * We have to record transaction prepares even if we didn't make any
2723 * updates, because the transaction manager might get confused if we lose
2724 * a global transaction.
2725 */
2727
2728 /*
2729 * Now we clean up backend-internal state and release internal resources.
2730 */
2731
2732 /* Reset XactLastRecEnd until the next transaction writes something */
2733 XactLastRecEnd = 0;
2734
2735 /*
2736 * Transfer our locks to a dummy PGPROC. This has to be done before
2737 * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2738 * conclude "xact already committed or aborted" for our locks.
2739 */
2740 PostPrepare_Locks(fxid);
2741
2742 /*
2743 * Let others know about no transaction in progress by me. This has to be
2744 * done *after* the prepared transaction has been marked valid, else
2745 * someone may think it is unlocked and recyclable.
2746 */
2748
2749 /*
2750 * In normal commit-processing, this is all non-critical post-transaction
2751 * cleanup. When the transaction is prepared, however, it's important
2752 * that the locks and other per-backend resources are transferred to the
2753 * prepared transaction's PGPROC entry. Note that if an error is raised
2754 * here, it's too late to abort the transaction. XXX: This probably should
2755 * be in a critical section, to force a PANIC if any of this fails, but
2756 * that cure could be worse than the disease.
2757 */
2758
2760
2763 true, true);
2764
2765 AtEOXact_Aio(true);
2766
2767 /* Check we've released all buffer pins */
2768 AtEOXact_Buffers(true);
2769
2770 /* Clean up the relation cache */
2772
2773 /* Clean up the type cache */
2775
2776 /* notify doesn't need a postprepare call */
2777
2779
2781
2783
2785
2787
2790 true, true);
2793 true, true);
2794
2795 /*
2796 * Allow another backend to finish the transaction. After
2797 * PostPrepare_Twophase(), the transaction is completely detached from our
2798 * backend. The rest is just non-critical cleanup of backend-local state.
2799 */
2801
2802 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2803 AtEOXact_GUC(true, 1);
2804 AtEOXact_SPI(true);
2805 AtEOXact_Enum();
2807 AtEOXact_Namespace(true, false);
2808 AtEOXact_SMgr();
2809 AtEOXact_Files(true);
2811 AtEOXact_HashTables(true);
2812 /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2813 AtEOXact_Snapshot(true, true);
2814 /* we treat PREPARE as ROLLBACK so far as waking workers goes */
2819
2825
2827
2830 s->nestingLevel = 0;
2831 s->gucNestLevel = 0;
2832 s->childXids = NULL;
2833 s->nChildXids = 0;
2834 s->maxChildXids = 0;
2835
2838
2839 /*
2840 * done with 1st phase commit processing, set current transaction state
2841 * back to default
2842 */
2843 s->state = TRANS_DEFAULT;
2844
2846}
2847
2848
2849/*
2850 * AbortTransaction
2851 */
2852static void
2854{
2857 bool is_parallel_worker;
2858
2859 /* Prevent cancel/die interrupt while cleaning up */
2861
2862 /* Disable transaction timeout */
2863 if (TransactionTimeout > 0)
2865
2866 /* Make sure we have a valid memory context and resource owner */
2869
2870 /*
2871 * Release any LW locks we might be holding as quickly as possible.
2872 * (Regular locks, however, must be held till we finish aborting.)
2873 * Releasing LW locks is critical since we might try to grab them again
2874 * while cleaning up!
2875 */
2877
2878 /*
2879 * Cleanup waiting for LSN if any.
2880 */
2882
2883 /* Clear wait information and command progress indicator */
2886
2888
2889 /* Clean up buffer content locks, too */
2890 UnlockBuffers();
2891
2892 /* Reset WAL record construction state */
2894
2895 /* Cancel condition variable sleep */
2897
2898 /*
2899 * Also clean up any open wait for lock, since the lock manager will choke
2900 * if we try to wait for another lock before doing this.
2901 */
2903
2904 /*
2905 * If any timeout events are still active, make sure the timeout interrupt
2906 * is scheduled. This covers possible loss of a timeout interrupt due to
2907 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2908 * We delay this till after LockErrorCleanup so that we don't uselessly
2909 * reschedule lock or deadlock check timeouts.
2910 */
2912
2913 /*
2914 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2915 * handler. We do this fairly early in the sequence so that the timeout
2916 * infrastructure will be functional if needed while aborting.
2917 */
2919
2920 /*
2921 * check the current transaction state
2922 */
2924 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2925 elog(WARNING, "AbortTransaction while in %s state",
2927 Assert(s->parent == NULL);
2928
2929 /*
2930 * set the current transaction state information appropriately during the
2931 * abort processing
2932 */
2933 s->state = TRANS_ABORT;
2934
2935 /*
2936 * Reset user ID which might have been changed transiently. We need this
2937 * to clean up in case control escaped out of a SECURITY DEFINER function
2938 * or other local change of CurrentUserId; therefore, the prior value of
2939 * SecurityRestrictionContext also needs to be restored.
2940 *
2941 * (Note: it is not necessary to restore session authorization or role
2942 * settings here because those can only be changed via GUC, and GUC will
2943 * take care of rolling them back if need be.)
2944 */
2946
2947 /* Forget about any active REINDEX. */
2949
2950 /* Reset logical streaming state. */
2952
2953 /* Reset snapshot export state. */
2955
2956 /*
2957 * If this xact has started any unfinished parallel operation, clean up
2958 * its workers and exit parallel mode. Don't warn about leaked resources.
2959 */
2960 AtEOXact_Parallel(false);
2961 s->parallelModeLevel = 0;
2962 s->parallelChildXact = false; /* should be false already */
2963
2964 /*
2965 * do abort processing
2966 */
2967 AfterTriggerEndXact(false); /* 'false' means it's abort */
2970 AtEOXact_LargeObject(false);
2974
2975 /*
2976 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2977 * far as assigning an XID to advertise). But if we're inside a parallel
2978 * worker, skip this; the user backend must be the one to write the abort
2979 * record.
2980 */
2981 if (!is_parallel_worker)
2983 else
2984 {
2986
2987 /*
2988 * Since the parallel leader won't get our value of XactLastRecEnd in
2989 * this case, we nudge WAL-writer ourselves in this case. See related
2990 * comments in RecordTransactionAbort for why this matters.
2991 */
2993 }
2994
2996
2997 /*
2998 * Let others know about no transaction in progress by me. Note that this
2999 * must be done _before_ releasing locks we hold and _after_
3000 * RecordTransactionAbort.
3001 */
3003
3004 /*
3005 * Post-abort cleanup. See notes in CommitTransaction() concerning
3006 * ordering. We can skip all of it if the transaction failed before
3007 * creating a resource owner.
3008 */
3010 {
3013 else
3015
3018 false, true);
3019 AtEOXact_Aio(false);
3020 AtEOXact_Buffers(false);
3023 AtEOXact_Inval(false);
3027 false, true);
3030 false, true);
3031 smgrDoPendingDeletes(false);
3032
3033 AtEOXact_GUC(false, 1);
3034 AtEOXact_SPI(false);
3035 AtEOXact_Enum();
3038 AtEOXact_SMgr();
3039 AtEOXact_Files(false);
3041 AtEOXact_HashTables(false);
3047 }
3048
3049 /*
3050 * State remains TRANS_ABORT until CleanupTransaction().
3051 */
3053}
3054
3055/*
3056 * CleanupTransaction
3057 */
3058static void
3060{
3062
3063 /*
3064 * State should still be TRANS_ABORT from AbortTransaction().
3065 */
3066 if (s->state != TRANS_ABORT)
3067 elog(FATAL, "CleanupTransaction: unexpected state %s",
3069
3070 /*
3071 * do abort cleanup processing
3072 */
3073 AtCleanup_Portals(); /* now safe to release portal memory */
3074 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
3075
3076 CurrentResourceOwner = NULL; /* and resource owner */
3082
3083 AtCleanup_Memory(); /* and transaction memory */
3084
3087 s->nestingLevel = 0;
3088 s->gucNestLevel = 0;
3089 s->childXids = NULL;
3090 s->nChildXids = 0;
3091 s->maxChildXids = 0;
3092 s->parallelModeLevel = 0;
3093 s->parallelChildXact = false;
3094
3097
3098 /*
3099 * done with abort processing, set current transaction state back to
3100 * default
3101 */
3102 s->state = TRANS_DEFAULT;
3103}
3104
3105/*
3106 * StartTransactionCommand
3107 */
3108void
3110{
3112
3113 switch (s->blockState)
3114 {
3115 /*
3116 * if we aren't in a transaction block, we just do our usual start
3117 * transaction.
3118 */
3119 case TBLOCK_DEFAULT:
3122 break;
3123
3124 /*
3125 * We are somewhere in a transaction block or subtransaction and
3126 * about to start a new command. For now we do nothing, but
3127 * someday we may do command-local resource initialization. (Note
3128 * that any needed CommandCounterIncrement was done by the
3129 * previous CommitTransactionCommand.)
3130 */
3131 case TBLOCK_INPROGRESS:
3134 break;
3135
3136 /*
3137 * Here we are in a failed transaction block (one of the commands
3138 * caused an abort) so we do nothing but remain in the abort
3139 * state. Eventually we will get a ROLLBACK command which will
3140 * get us out of this state. (It is up to other code to ensure
3141 * that no commands other than ROLLBACK will be processed in these
3142 * states.)
3143 */
3144 case TBLOCK_ABORT:
3145 case TBLOCK_SUBABORT:
3146 break;
3147
3148 /* These cases are invalid. */
3149 case TBLOCK_STARTED:
3150 case TBLOCK_BEGIN:
3152 case TBLOCK_SUBBEGIN:
3153 case TBLOCK_END:
3154 case TBLOCK_SUBRELEASE:
3155 case TBLOCK_SUBCOMMIT:
3156 case TBLOCK_ABORT_END:
3160 case TBLOCK_SUBRESTART:
3162 case TBLOCK_PREPARE:
3163 elog(ERROR, "StartTransactionCommand: unexpected state %s",
3165 break;
3166 }
3167
3168 /*
3169 * We must switch to CurTransactionContext before returning. This is
3170 * already done if we called StartTransaction, otherwise not.
3171 */
3174}
3175
3176
3177/*
3178 * Simple system for saving and restoring transaction characteristics
3179 * (isolation level, read only, deferrable). We need this for transaction
3180 * chaining, so that we can set the characteristics of the new transaction to
3181 * be the same as the previous one. (We need something like this because the
3182 * GUC system resets the characteristics at transaction end, so for example
3183 * just skipping the reset in StartTransaction() won't work.)
3184 */
3185void
3192
3193void
3200
3201/*
3202 * CommitTransactionCommand -- a wrapper function handling the
3203 * loop over subtransactions to avoid a potentially dangerous recursion
3204 * in CommitTransactionCommandInternal().
3205 */
3206void
3208{
3209 /*
3210 * Repeatedly call CommitTransactionCommandInternal() until all the work
3211 * is done.
3212 */
3214 {
3215 }
3216}
3217
3218/*
3219 * CommitTransactionCommandInternal - a function doing an iteration of work
3220 * regarding handling the commit transaction command. In the case of
3221 * subtransactions more than one iterations could be required. Returns
3222 * true when no more iterations required, false otherwise.
3223 */
3224static bool
3226{
3229
3230 /* Must save in case we need to restore below */
3232
3233 switch (s->blockState)
3234 {
3235 /*
3236 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3237 * StartTransactionCommand didn't set the STARTED state
3238 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3239 * by EndParallelWorkerTransaction(), not this function.
3240 */
3241 case TBLOCK_DEFAULT:
3243 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3245 break;
3246
3247 /*
3248 * If we aren't in a transaction block, just do our usual
3249 * transaction commit, and return to the idle state.
3250 */
3251 case TBLOCK_STARTED:
3254 break;
3255
3256 /*
3257 * We are completing a "BEGIN TRANSACTION" command, so we change
3258 * to the "transaction block in progress" state and return. (We
3259 * assume the BEGIN did nothing to the database, so we need no
3260 * CommandCounterIncrement.)
3261 */
3262 case TBLOCK_BEGIN:
3264 break;
3265
3266 /*
3267 * This is the case when we have finished executing a command
3268 * someplace within a transaction block. We increment the command
3269 * counter and return.
3270 */
3271 case TBLOCK_INPROGRESS:
3275 break;
3276
3277 /*
3278 * We are completing a "COMMIT" command. Do it and return to the
3279 * idle state.
3280 */
3281 case TBLOCK_END:
3284 if (s->chain)
3285 {
3288 s->chain = false;
3290 }
3291 break;
3292
3293 /*
3294 * Here we are in the middle of a transaction block but one of the
3295 * commands caused an abort so we do nothing but remain in the
3296 * abort state. Eventually we will get a ROLLBACK command.
3297 */
3298 case TBLOCK_ABORT:
3299 case TBLOCK_SUBABORT:
3300 break;
3301
3302 /*
3303 * Here we were in an aborted transaction block and we just got
3304 * the ROLLBACK command from the user, so clean up the
3305 * already-aborted transaction and return to the idle state.
3306 */
3307 case TBLOCK_ABORT_END:
3310 if (s->chain)
3311 {
3314 s->chain = false;
3316 }
3317 break;
3318
3319 /*
3320 * Here we were in a perfectly good transaction block but the user
3321 * told us to ROLLBACK anyway. We have to abort the transaction
3322 * and then clean up.
3323 */
3328 if (s->chain)
3329 {
3332 s->chain = false;
3334 }
3335 break;
3336
3337 /*
3338 * We are completing a "PREPARE TRANSACTION" command. Do it and
3339 * return to the idle state.
3340 */
3341 case TBLOCK_PREPARE:
3344 break;
3345
3346 /*
3347 * The user issued a SAVEPOINT inside a transaction block. Start a
3348 * subtransaction. (DefineSavepoint already did PushTransaction,
3349 * so as to have someplace to put the SUBBEGIN state.)
3350 */
3351 case TBLOCK_SUBBEGIN:
3354 break;
3355
3356 /*
3357 * The user issued a RELEASE command, so we end the current
3358 * subtransaction and return to the parent transaction. The parent
3359 * might be ended too, so repeat till we find an INPROGRESS
3360 * transaction or subtransaction.
3361 */
3362 case TBLOCK_SUBRELEASE:
3363 do
3364 {
3366 s = CurrentTransactionState; /* changed by pop */
3367 } while (s->blockState == TBLOCK_SUBRELEASE);
3368
3371 break;
3372
3373 /*
3374 * The user issued a COMMIT, so we end the current subtransaction
3375 * hierarchy and perform final commit. We do this by rolling up
3376 * any subtransactions into their parent, which leads to O(N^2)
3377 * operations with respect to resource owners - this isn't that
3378 * bad until we approach a thousands of savepoints but is
3379 * necessary for correctness should after triggers create new
3380 * resource owners.
3381 */
3382 case TBLOCK_SUBCOMMIT:
3383 do
3384 {
3386 s = CurrentTransactionState; /* changed by pop */
3387 } while (s->blockState == TBLOCK_SUBCOMMIT);
3388 /* If we had a COMMIT command, finish off the main xact too */
3389 if (s->blockState == TBLOCK_END)
3390 {
3391 Assert(s->parent == NULL);
3394 if (s->chain)
3395 {
3398 s->chain = false;
3400 }
3401 }
3402 else if (s->blockState == TBLOCK_PREPARE)
3403 {
3404 Assert(s->parent == NULL);
3407 }
3408 else
3409 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3411 break;
3412
3413 /*
3414 * The current already-failed subtransaction is ending due to a
3415 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3416 * examine the parent (which could be in any of several states).
3417 * As we need to examine the parent, return false to request the
3418 * caller to do the next iteration.
3419 */
3422 return false;
3423
3424 /*
3425 * As above, but it's not dead yet, so abort first.
3426 */
3430 return false;
3431
3432 /*
3433 * The current subtransaction is the target of a ROLLBACK TO
3434 * command. Abort and pop it, then start a new subtransaction
3435 * with the same name.
3436 */
3437 case TBLOCK_SUBRESTART:
3438 {
3439 char *name;
3440 int savepointLevel;
3441
3442 /* save name and keep Cleanup from freeing it */
3443 name = s->name;
3444 s->name = NULL;
3445 savepointLevel = s->savepointLevel;
3446
3449
3451 s = CurrentTransactionState; /* changed by push */
3452 s->name = name;
3453 s->savepointLevel = savepointLevel;
3454
3455 /* This is the same as TBLOCK_SUBBEGIN case */
3459 }
3460 break;
3461
3462 /*
3463 * Same as above, but the subtransaction had already failed, so we
3464 * don't need AbortSubTransaction.
3465 */
3467 {
3468 char *name;
3469 int savepointLevel;
3470
3471 /* save name and keep Cleanup from freeing it */
3472 name = s->name;
3473 s->name = NULL;
3474 savepointLevel = s->savepointLevel;
3475
3477
3479 s = CurrentTransactionState; /* changed by push */
3480 s->name = name;
3481 s->savepointLevel = savepointLevel;
3482
3483 /* This is the same as TBLOCK_SUBBEGIN case */
3487 }
3488 break;
3489 }
3490
3491 /* Done, no more iterations required */
3492 return true;
3493}
3494
3495/*
3496 * AbortCurrentTransaction -- a wrapper function handling the
3497 * loop over subtransactions to avoid potentially dangerous recursion in
3498 * AbortCurrentTransactionInternal().
3499 */
3500void
3502{
3503 /*
3504 * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3505 * done.
3506 */
3508 {
3509 }
3510}
3511
3512/*
3513 * AbortCurrentTransactionInternal - a function doing an iteration of work
3514 * regarding handling the current transaction abort. In the case of
3515 * subtransactions more than one iterations could be required. Returns
3516 * true when no more iterations required, false otherwise.
3517 */
3518static bool
3520{
3522
3523 switch (s->blockState)
3524 {
3525 case TBLOCK_DEFAULT:
3526 if (s->state == TRANS_DEFAULT)
3527 {
3528 /* we are idle, so nothing to do */
3529 }
3530 else
3531 {
3532 /*
3533 * We can get here after an error during transaction start
3534 * (state will be TRANS_START). Need to clean up the
3535 * incompletely started transaction. First, adjust the
3536 * low-level state to suppress warning message from
3537 * AbortTransaction.
3538 */
3539 if (s->state == TRANS_START)
3543 }
3544 break;
3545
3546 /*
3547 * If we aren't in a transaction block, we just do the basic abort
3548 * & cleanup transaction. For this purpose, we treat an implicit
3549 * transaction block as if it were a simple statement.
3550 */
3551 case TBLOCK_STARTED:
3556 break;
3557
3558 /*
3559 * If we are in TBLOCK_BEGIN it means something screwed up right
3560 * after reading "BEGIN TRANSACTION". We assume that the user
3561 * will interpret the error as meaning the BEGIN failed to get him
3562 * into a transaction block, so we should abort and return to idle
3563 * state.
3564 */
3565 case TBLOCK_BEGIN:
3569 break;
3570
3571 /*
3572 * We are somewhere in a transaction block and we've gotten a
3573 * failure, so we abort the transaction and set up the persistent
3574 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3575 */
3576 case TBLOCK_INPROGRESS:
3580 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3581 break;
3582
3583 /*
3584 * Here, we failed while trying to COMMIT. Clean up the
3585 * transaction and return to idle state (we do not want to stay in
3586 * the transaction).
3587 */
3588 case TBLOCK_END:
3592 break;
3593
3594 /*
3595 * Here, we are already in an aborted transaction state and are
3596 * waiting for a ROLLBACK, but for some reason we failed again! So
3597 * we just remain in the abort state.
3598 */
3599 case TBLOCK_ABORT:
3600 case TBLOCK_SUBABORT:
3601 break;
3602
3603 /*
3604 * We are in a failed transaction and we got the ROLLBACK command.
3605 * We have already aborted, we just need to cleanup and go to idle
3606 * state.
3607 */
3608 case TBLOCK_ABORT_END:
3611 break;
3612
3613 /*
3614 * We are in a live transaction and we got a ROLLBACK command.
3615 * Abort, cleanup, go to idle state.
3616 */
3621 break;
3622
3623 /*
3624 * Here, we failed while trying to PREPARE. Clean up the
3625 * transaction and return to idle state (we do not want to stay in
3626 * the transaction).
3627 */
3628 case TBLOCK_PREPARE:
3632 break;
3633
3634 /*
3635 * We got an error inside a subtransaction. Abort just the
3636 * subtransaction, and go to the persistent SUBABORT state until
3637 * we get ROLLBACK.
3638 */
3642 break;
3643
3644 /*
3645 * If we failed while trying to create a subtransaction, clean up
3646 * the broken subtransaction and abort the parent. The same
3647 * applies if we get a failure while ending a subtransaction. As
3648 * we need to abort the parent, return false to request the caller
3649 * to do the next iteration.
3650 */
3651 case TBLOCK_SUBBEGIN:
3652 case TBLOCK_SUBRELEASE:
3653 case TBLOCK_SUBCOMMIT:
3655 case TBLOCK_SUBRESTART:
3658 return false;
3659
3660 /*
3661 * Same as above, except the Abort() was already done.
3662 */
3666 return false;
3667 }
3668
3669 /* Done, no more iterations required */
3670 return true;
3671}
3672
3673/*
3674 * PreventInTransactionBlock
3675 *
3676 * This routine is to be called by statements that must not run inside
3677 * a transaction block, typically because they have non-rollback-able
3678 * side effects or do internal commits.
3679 *
3680 * If this routine completes successfully, then the calling statement is
3681 * guaranteed that if it completes without error, its results will be
3682 * committed immediately.
3683 *
3684 * If we have already started a transaction block, issue an error; also issue
3685 * an error if we appear to be running inside a user-defined function (which
3686 * could issue more commands and possibly cause a failure after the statement
3687 * completes). Subtransactions are verboten too.
3688 *
3689 * We must also set XACT_FLAGS_NEEDIMMEDIATECOMMIT in MyXactFlags, to ensure
3690 * that postgres.c follows through by committing after the statement is done.
3691 *
3692 * isTopLevel: passed down from ProcessUtility to determine whether we are
3693 * inside a function. (We will always fail if this is false, but it's
3694 * convenient to centralize the check here instead of making callers do it.)
3695 * stmtType: statement type name, for error messages.
3696 */
3697void
3698PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
3699{
3700 /*
3701 * xact block already started?
3702 */
3703 if (IsTransactionBlock())
3704 ereport(ERROR,
3706 /* translator: %s represents an SQL statement name */
3707 errmsg("%s cannot run inside a transaction block",
3708 stmtType)));
3709
3710 /*
3711 * subtransaction?
3712 */
3713 if (IsSubTransaction())
3714 ereport(ERROR,
3716 /* translator: %s represents an SQL statement name */
3717 errmsg("%s cannot run inside a subtransaction",
3718 stmtType)));
3719
3720 /*
3721 * inside a function call?
3722 */
3723 if (!isTopLevel)
3724 ereport(ERROR,
3726 /* translator: %s represents an SQL statement name */
3727 errmsg("%s cannot be executed from a function or procedure",
3728 stmtType)));
3729
3730 /* If we got past IsTransactionBlock test, should be in default state */
3733 elog(FATAL, "cannot prevent transaction chain");
3734
3735 /* All okay. Set the flag to make sure the right thing happens later. */
3737}
3738
3739/*
3740 * WarnNoTransactionBlock
3741 * RequireTransactionBlock
3742 *
3743 * These two functions allow for warnings or errors if a command is executed
3744 * outside of a transaction block. This is useful for commands that have no
3745 * effects that persist past transaction end (and so calling them outside a
3746 * transaction block is presumably an error). DECLARE CURSOR is an example.
3747 * While top-level transaction control commands (BEGIN/COMMIT/ABORT) and SET
3748 * that have no effect issue warnings, all other no-effect commands generate
3749 * errors.
3750 *
3751 * If we appear to be running inside a user-defined function, we do not
3752 * issue anything, since the function could issue more commands that make
3753 * use of the current statement's results. Likewise subtransactions.
3754 * Thus these are inverses for PreventInTransactionBlock.
3755 *
3756 * isTopLevel: passed down from ProcessUtility to determine whether we are
3757 * inside a function.
3758 * stmtType: statement type name, for warning or error messages.
3759 */
3760void
3761WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
3762{
3763 CheckTransactionBlock(isTopLevel, false, stmtType);
3764}
3765
3766void
3767RequireTransactionBlock(bool isTopLevel, const char *stmtType)
3768{
3769 CheckTransactionBlock(isTopLevel, true, stmtType);
3770}
3771
3772/*
3773 * This is the implementation of the above two.
3774 */
3775static void
3776CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
3777{
3778 /*
3779 * xact block already started?
3780 */
3781 if (IsTransactionBlock())
3782 return;
3783
3784 /*
3785 * subtransaction?
3786 */
3787 if (IsSubTransaction())
3788 return;
3789
3790 /*
3791 * inside a function call?
3792 */
3793 if (!isTopLevel)
3794 return;
3795
3798 /* translator: %s represents an SQL statement name */
3799 errmsg("%s can only be used in transaction blocks",
3800 stmtType)));
3801}
3802
3803/*
3804 * IsInTransactionBlock
3805 *
3806 * This routine is for statements that need to behave differently inside
3807 * a transaction block than when running as single commands. ANALYZE is
3808 * currently the only example.
3809 *
3810 * If this routine returns "false", then the calling statement is allowed
3811 * to perform internal transaction-commit-and-start cycles; there is not a
3812 * risk of messing up any transaction already in progress. (Note that this
3813 * is not the identical guarantee provided by PreventInTransactionBlock,
3814 * since we will not force a post-statement commit.)
3815 *
3816 * isTopLevel: passed down from ProcessUtility to determine whether we are
3817 * inside a function.
3818 */
3819bool
3821{
3822 /*
3823 * Return true on same conditions that would make
3824 * PreventInTransactionBlock error out
3825 */
3826 if (IsTransactionBlock())
3827 return true;
3828
3829 if (IsSubTransaction())
3830 return true;
3831
3832 if (!isTopLevel)
3833 return true;
3834
3837 return true;
3838
3839 return false;
3840}
3841
3842
3843/*
3844 * Register or deregister callback functions for start- and end-of-xact
3845 * operations.
3846 *
3847 * These functions are intended for use by dynamically loaded modules.
3848 * For built-in modules we generally just hardwire the appropriate calls
3849 * (mainly because it's easier to control the order that way, where needed).
3850 *
3851 * At transaction end, the callback occurs post-commit or post-abort, so the
3852 * callback functions can only do noncritical cleanup.
3853 */
3854void
3856{
3857 XactCallbackItem *item;
3858
3859 item = (XactCallbackItem *)
3861 item->callback = callback;
3862 item->arg = arg;
3863 item->next = Xact_callbacks;
3864 Xact_callbacks = item;
3865}
3866
3867void
3869{
3870 XactCallbackItem *item;
3871 XactCallbackItem *prev;
3872
3873 prev = NULL;
3874 for (item = Xact_callbacks; item; prev = item, item = item->next)
3875 {
3876 if (item->callback == callback && item->arg == arg)
3877 {
3878 if (prev)
3879 prev->next = item->next;
3880 else
3881 Xact_callbacks = item->next;
3882 pfree(item);
3883 break;
3884 }
3885 }
3886}
3887
3888static void
3890{
3891 XactCallbackItem *item;
3893
3894 for (item = Xact_callbacks; item; item = next)
3895 {
3896 /* allow callbacks to unregister themselves when called */
3897 next = item->next;
3898 item->callback(event, item->arg);
3899 }
3900}
3901
3902
3903/*
3904 * Register or deregister callback functions for start- and end-of-subxact
3905 * operations.
3906 *
3907 * Pretty much same as above, but for subtransaction events.
3908 *
3909 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3910 * so the callback functions can only do noncritical cleanup. At
3911 * subtransaction start, the callback is called when the subtransaction has
3912 * finished initializing.
3913 */
3914void
3916{
3917 SubXactCallbackItem *item;
3918
3919 item = (SubXactCallbackItem *)
3921 item->callback = callback;
3922 item->arg = arg;
3923 item->next = SubXact_callbacks;
3924 SubXact_callbacks = item;
3925}
3926
3927void
3929{
3930 SubXactCallbackItem *item;
3931 SubXactCallbackItem *prev;
3932
3933 prev = NULL;
3934 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3935 {
3936 if (item->callback == callback && item->arg == arg)
3937 {
3938 if (prev)
3939 prev->next = item->next;
3940 else
3941 SubXact_callbacks = item->next;
3942 pfree(item);
3943 break;
3944 }
3945 }
3946}
3947
3948static void
3952{
3953 SubXactCallbackItem *item;
3955
3956 for (item = SubXact_callbacks; item; item = next)
3957 {
3958 /* allow callbacks to unregister themselves when called */
3959 next = item->next;
3960 item->callback(event, mySubid, parentSubid, item->arg);
3961 }
3962}
3963
3964
3965/* ----------------------------------------------------------------
3966 * transaction block support
3967 * ----------------------------------------------------------------
3968 */
3969
3970/*
3971 * BeginTransactionBlock
3972 * This executes a BEGIN command.
3973 */
3974void
3976{
3978
3979 switch (s->blockState)
3980 {
3981 /*
3982 * We are not inside a transaction block, so allow one to begin.
3983 */
3984 case TBLOCK_STARTED:
3986 break;
3987
3988 /*
3989 * BEGIN converts an implicit transaction block to a regular one.
3990 * (Note that we allow this even if we've already done some
3991 * commands, which is a bit odd but matches historical practice.)
3992 */
3995 break;
3996
3997 /*
3998 * Already a transaction block in progress.
3999 */
4000 case TBLOCK_INPROGRESS:
4003 case TBLOCK_ABORT:
4004 case TBLOCK_SUBABORT:
4007 errmsg("there is already a transaction in progress")));
4008 break;
4009
4010 /* These cases are invalid. */
4011 case TBLOCK_DEFAULT:
4012 case TBLOCK_BEGIN:
4013 case TBLOCK_SUBBEGIN:
4014 case TBLOCK_END:
4015 case TBLOCK_SUBRELEASE:
4016 case TBLOCK_SUBCOMMIT:
4017 case TBLOCK_ABORT_END:
4021 case TBLOCK_SUBRESTART:
4023 case TBLOCK_PREPARE:
4024 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
4026 break;
4027 }
4028}
4029
4030/*
4031 * PrepareTransactionBlock
4032 * This executes a PREPARE command.
4033 *
4034 * Since PREPARE may actually do a ROLLBACK, the result indicates what
4035 * happened: true for PREPARE, false for ROLLBACK.
4036 *
4037 * Note that we don't actually do anything here except change blockState.
4038 * The real work will be done in the upcoming PrepareTransaction().
4039 * We do it this way because it's not convenient to change memory context,
4040 * resource owner, etc while executing inside a Portal.
4041 */
4042bool
4044{
4046 bool result;
4047
4048 /* Set up to commit the current transaction */
4049 result = EndTransactionBlock(false);
4050
4051 /* If successful, change outer tblock state to PREPARE */
4052 if (result)
4053 {
4055
4056 while (s->parent != NULL)
4057 s = s->parent;
4058
4059 if (s->blockState == TBLOCK_END)
4060 {
4061 /* Save GID where PrepareTransaction can find it again */
4063
4065 }
4066 else
4067 {
4068 /*
4069 * ignore case where we are not in a transaction;
4070 * EndTransactionBlock already issued a warning.
4071 */
4074 /* Don't send back a PREPARE result tag... */
4075 result = false;
4076 }
4077 }
4078
4079 return result;
4080}
4081
4082/*
4083 * EndTransactionBlock
4084 * This executes a COMMIT command.
4085 *
4086 * Since COMMIT may actually do a ROLLBACK, the result indicates what
4087 * happened: true for COMMIT, false for ROLLBACK.
4088 *
4089 * Note that we don't actually do anything here except change blockState.
4090 * The real work will be done in the upcoming CommitTransactionCommand().
4091 * We do it this way because it's not convenient to change memory context,
4092 * resource owner, etc while executing inside a Portal.
4093 */
4094bool
4096{
4098 bool result = false;
4099
4100 switch (s->blockState)
4101 {
4102 /*
4103 * We are in a transaction block, so tell CommitTransactionCommand
4104 * to COMMIT.
4105 */
4106 case TBLOCK_INPROGRESS:
4108 result = true;
4109 break;
4110
4111 /*
4112 * We are in an implicit transaction block. If AND CHAIN was
4113 * specified, error. Otherwise commit, but issue a warning
4114 * because there was no explicit BEGIN before this.
4115 */
4117 if (chain)
4118 ereport(ERROR,
4120 /* translator: %s represents an SQL statement name */
4121 errmsg("%s can only be used in transaction blocks",
4122 "COMMIT AND CHAIN")));
4123 else
4126 errmsg("there is no transaction in progress")));
4128 result = true;
4129 break;
4130
4131 /*
4132 * We are in a failed transaction block. Tell
4133 * CommitTransactionCommand it's time to exit the block.
4134 */
4135 case TBLOCK_ABORT:
4137 break;
4138
4139 /*
4140 * We are in a live subtransaction block. Set up to subcommit all
4141 * open subtransactions and then commit the main transaction.
4142 */
4144 while (s->parent != NULL)
4145 {
4148 else
4149 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4151 s = s->parent;
4152 }
4153 if (s->blockState == TBLOCK_INPROGRESS)
4155 else
4156 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4158 result = true;
4159 break;
4160
4161 /*
4162 * Here we are inside an aborted subtransaction. Treat the COMMIT
4163 * as ROLLBACK: set up to abort everything and exit the main
4164 * transaction.
4165 */
4166 case TBLOCK_SUBABORT:
4167 while (s->parent != NULL)
4168 {
4171 else if (s->blockState == TBLOCK_SUBABORT)
4173 else
4174 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4176 s = s->parent;
4177 }
4178 if (s->blockState == TBLOCK_INPROGRESS)
4180 else if (s->blockState == TBLOCK_ABORT)
4182 else
4183 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4185 break;
4186
4187 /*
4188 * The user issued COMMIT when not inside a transaction. For
4189 * COMMIT without CHAIN, issue a WARNING, staying in
4190 * TBLOCK_STARTED state. The upcoming call to
4191 * CommitTransactionCommand() will then close the transaction and
4192 * put us back into the default state. For COMMIT AND CHAIN,
4193 * error.
4194 */
4195 case TBLOCK_STARTED:
4196 if (chain)
4197 ereport(ERROR,
4199 /* translator: %s represents an SQL statement name */
4200 errmsg("%s can only be used in transaction blocks",
4201 "COMMIT AND CHAIN")));
4202 else
4205 errmsg("there is no transaction in progress")));
4206 result = true;
4207 break;
4208
4209 /*
4210 * The user issued a COMMIT that somehow ran inside a parallel
4211 * worker. We can't cope with that.
4212 */
4214 ereport(FATAL,
4216 errmsg("cannot commit during a parallel operation")));
4217 break;
4218
4219 /* These cases are invalid. */
4220 case TBLOCK_DEFAULT:
4221 case TBLOCK_BEGIN:
4222 case TBLOCK_SUBBEGIN:
4223 case TBLOCK_END:
4224 case TBLOCK_SUBRELEASE:
4225 case TBLOCK_SUBCOMMIT:
4226 case TBLOCK_ABORT_END:
4230 case TBLOCK_SUBRESTART:
4232 case TBLOCK_PREPARE:
4233 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4235 break;
4236 }
4237
4239 s->blockState == TBLOCK_END ||
4242
4243 s->chain = chain;
4244
4245 return result;
4246}
4247
4248/*
4249 * UserAbortTransactionBlock
4250 * This executes a ROLLBACK command.
4251 *
4252 * As above, we don't actually do anything here except change blockState.
4253 */
4254void
4256{
4258
4259 switch (s->blockState)
4260 {
4261 /*
4262 * We are inside a transaction block and we got a ROLLBACK command
4263 * from the user, so tell CommitTransactionCommand to abort and
4264 * exit the transaction block.
4265 */
4266 case TBLOCK_INPROGRESS:
4268 break;
4269
4270 /*
4271 * We are inside a failed transaction block and we got a ROLLBACK
4272 * command from the user. Abort processing is already done, so
4273 * CommitTransactionCommand just has to cleanup and go back to
4274 * idle state.
4275 */
4276 case TBLOCK_ABORT:
4278 break;
4279
4280 /*
4281 * We are inside a subtransaction. Mark everything up to top
4282 * level as exitable.
4283 */
4285 case TBLOCK_SUBABORT:
4286 while (s->parent != NULL)
4287 {
4290 else if (s->blockState == TBLOCK_SUBABORT)
4292 else
4293 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4295 s = s->parent;
4296 }
4297 if (s->blockState == TBLOCK_INPROGRESS)
4299 else if (s->blockState == TBLOCK_ABORT)
4301 else
4302 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4304 break;
4305
4306 /*
4307 * The user issued ABORT when not inside a transaction. For
4308 * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4309 * The upcoming call to CommitTransactionCommand() will then put
4310 * us back into the default state. For ROLLBACK AND CHAIN, error.
4311 *
4312 * We do the same thing with ABORT inside an implicit transaction,
4313 * although in this case we might be rolling back actual database
4314 * state changes. (It's debatable whether we should issue a
4315 * WARNING in this case, but we have done so historically.)
4316 */
4317 case TBLOCK_STARTED:
4319 if (chain)
4320 ereport(ERROR,
4322 /* translator: %s represents an SQL statement name */
4323 errmsg("%s can only be used in transaction blocks",
4324 "ROLLBACK AND CHAIN")));
4325 else
4328 errmsg("there is no transaction in progress")));
4330 break;
4331
4332 /*
4333 * The user issued an ABORT that somehow ran inside a parallel
4334 * worker. We can't cope with that.
4335 */
4337 ereport(FATAL,
4339 errmsg("cannot abort during a parallel operation")));
4340 break;
4341
4342 /* These cases are invalid. */
4343 case TBLOCK_DEFAULT:
4344 case TBLOCK_BEGIN:
4345 case TBLOCK_SUBBEGIN:
4346 case TBLOCK_END:
4347 case TBLOCK_SUBRELEASE:
4348 case TBLOCK_SUBCOMMIT:
4349 case TBLOCK_ABORT_END:
4353 case TBLOCK_SUBRESTART:
4355 case TBLOCK_PREPARE:
4356 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4358 break;
4359 }
4360
4363
4364 s->chain = chain;
4365}
4366
4367/*
4368 * BeginImplicitTransactionBlock
4369 * Start an implicit transaction block if we're not already in one.
4370 *
4371 * Unlike BeginTransactionBlock, this is called directly from the main loop
4372 * in postgres.c, not within a Portal. So we can just change blockState
4373 * without a lot of ceremony. We do not expect caller to do
4374 * CommitTransactionCommand/StartTransactionCommand.
4375 */
4376void
4378{
4380
4381 /*
4382 * If we are in STARTED state (that is, no transaction block is open),
4383 * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4384 * block.
4385 *
4386 * For caller convenience, we consider all other transaction states as
4387 * legal here; otherwise the caller would need its own state check, which
4388 * seems rather pointless.
4389 */
4390 if (s->blockState == TBLOCK_STARTED)
4392}
4393
4394/*
4395 * EndImplicitTransactionBlock
4396 * End an implicit transaction block, if we're in one.
4397 *
4398 * Like EndTransactionBlock, we just make any needed blockState change here.
4399 * The real work will be done in the upcoming CommitTransactionCommand().
4400 */
4401void
4403{
4405
4406 /*
4407 * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4408 * allowing CommitTransactionCommand to commit whatever happened during
4409 * the implicit transaction block as though it were a single statement.
4410 *
4411 * For caller convenience, we consider all other transaction states as
4412 * legal here; otherwise the caller would need its own state check, which
4413 * seems rather pointless.
4414 */
4417}
4418
4419/*
4420 * DefineSavepoint
4421 * This executes a SAVEPOINT command.
4422 */
4423void
4425{
4427
4428 /*
4429 * Workers synchronize transaction state at the beginning of each parallel
4430 * operation, so we can't account for new subtransactions after that
4431 * point. (Note that this check will certainly error out if s->blockState
4432 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4433 * below.)
4434 */
4436 ereport(ERROR,
4438 errmsg("cannot define savepoints during a parallel operation")));
4439
4440 switch (s->blockState)
4441 {
4442 case TBLOCK_INPROGRESS:
4444 /* Normal subtransaction start */
4446 s = CurrentTransactionState; /* changed by push */
4447
4448 /*
4449 * Savepoint names, like the TransactionState block itself, live
4450 * in TopTransactionContext.
4451 */
4452 if (name)
4454 break;
4455
4456 /*
4457 * We disallow savepoint commands in implicit transaction blocks.
4458 * There would be no great difficulty in allowing them so far as
4459 * this module is concerned, but a savepoint seems inconsistent
4460 * with exec_simple_query's behavior of abandoning the whole query
4461 * string upon error. Also, the point of an implicit transaction
4462 * block (as opposed to a regular one) is to automatically close
4463 * after an error, so it's hard to see how a savepoint would fit
4464 * into that.
4465 *
4466 * The error messages for this are phrased as if there were no
4467 * active transaction block at all, which is historical but
4468 * perhaps could be improved.
4469 */
4471 ereport(ERROR,
4473 /* translator: %s represents an SQL statement name */
4474 errmsg("%s can only be used in transaction blocks",
4475 "SAVEPOINT")));
4476 break;
4477
4478 /* These cases are invalid. */
4479 case TBLOCK_DEFAULT:
4480 case TBLOCK_STARTED:
4481 case TBLOCK_BEGIN:
4483 case TBLOCK_SUBBEGIN:
4484 case TBLOCK_END:
4485 case TBLOCK_SUBRELEASE:
4486 case TBLOCK_SUBCOMMIT:
4487 case TBLOCK_ABORT:
4488 case TBLOCK_SUBABORT:
4489 case TBLOCK_ABORT_END:
4493 case TBLOCK_SUBRESTART:
4495 case TBLOCK_PREPARE:
4496 elog(FATAL, "DefineSavepoint: unexpected state %s",
4498 break;
4499 }
4500}
4501
4502/*
4503 * ReleaseSavepoint
4504 * This executes a RELEASE command.
4505 *
4506 * As above, we don't actually do anything here except change blockState.
4507 */
4508void
4510{
4512 TransactionState target,
4513 xact;
4514
4515 /*
4516 * Workers synchronize transaction state at the beginning of each parallel
4517 * operation, so we can't account for transaction state change after that
4518 * point. (Note that this check will certainly error out if s->blockState
4519 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4520 * below.)
4521 */
4523 ereport(ERROR,
4525 errmsg("cannot release savepoints during a parallel operation")));
4526
4527 switch (s->blockState)
4528 {
4529 /*
4530 * We can't release a savepoint if there is no savepoint defined.
4531 */
4532 case TBLOCK_INPROGRESS:
4533 ereport(ERROR,
4535 errmsg("savepoint \"%s\" does not exist", name)));
4536 break;
4537
4539 /* See comment about implicit transactions in DefineSavepoint */
4540 ereport(ERROR,
4542 /* translator: %s represents an SQL statement name */
4543 errmsg("%s can only be used in transaction blocks",
4544 "RELEASE SAVEPOINT")));
4545 break;
4546
4547 /*
4548 * We are in a non-aborted subtransaction. This is the only valid
4549 * case.
4550 */
4552 break;
4553
4554 /* These cases are invalid. */
4555 case TBLOCK_DEFAULT:
4556 case TBLOCK_STARTED:
4557 case TBLOCK_BEGIN:
4559 case TBLOCK_SUBBEGIN:
4560 case TBLOCK_END:
4561 case TBLOCK_SUBRELEASE:
4562 case TBLOCK_SUBCOMMIT:
4563 case TBLOCK_ABORT:
4564 case TBLOCK_SUBABORT:
4565 case TBLOCK_ABORT_END:
4569 case TBLOCK_SUBRESTART:
4571 case TBLOCK_PREPARE:
4572 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4574 break;
4575 }
4576
4577 for (target = s; target; target = target->parent)
4578 {
4579 if (target->name && strcmp(target->name, name) == 0)
4580 break;
4581 }
4582
4583 if (!target)
4584 ereport(ERROR,
4586 errmsg("savepoint \"%s\" does not exist", name)));
4587
4588 /* disallow crossing savepoint level boundaries */
4589 if (target->savepointLevel != s->savepointLevel)
4590 ereport(ERROR,
4592 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4593
4594 /*
4595 * Mark "commit pending" all subtransactions up to the target
4596 * subtransaction. The actual commits will happen when control gets to
4597 * CommitTransactionCommand.
4598 */
4600 for (;;)
4601 {
4602 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
4603 xact->blockState = TBLOCK_SUBRELEASE;
4604 if (xact == target)
4605 break;
4606 xact = xact->parent;
4607 Assert(xact);
4608 }
4609}
4610
4611/*
4612 * RollbackToSavepoint
4613 * This executes a ROLLBACK TO <savepoint> command.
4614 *
4615 * As above, we don't actually do anything here except change blockState.
4616 */
4617void
4619{
4621 TransactionState target,
4622 xact;
4623
4624 /*
4625 * Workers synchronize transaction state at the beginning of each parallel
4626 * operation, so we can't account for transaction state change after that
4627 * point. (Note that this check will certainly error out if s->blockState
4628 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4629 * below.)
4630 */
4632 ereport(ERROR,
4634 errmsg("cannot rollback to savepoints during a parallel operation")));
4635
4636 switch (s->blockState)
4637 {
4638 /*
4639 * We can't rollback to a savepoint if there is no savepoint
4640 * defined.
4641 */
4642 case TBLOCK_INPROGRESS:
4643 case TBLOCK_ABORT:
4644 ereport(ERROR,
4646 errmsg("savepoint \"%s\" does not exist", name)));
4647 break;
4648
4650 /* See comment about implicit transactions in DefineSavepoint */
4651 ereport(ERROR,
4653 /* translator: %s represents an SQL statement name */
4654 errmsg("%s can only be used in transaction blocks",
4655 "ROLLBACK TO SAVEPOINT")));
4656 break;
4657
4658 /*
4659 * There is at least one savepoint, so proceed.
4660 */
4662 case TBLOCK_SUBABORT:
4663 break;
4664
4665 /* These cases are invalid. */
4666 case TBLOCK_DEFAULT:
4667 case TBLOCK_STARTED:
4668 case TBLOCK_BEGIN:
4670 case TBLOCK_SUBBEGIN:
4671 case TBLOCK_END:
4672 case TBLOCK_SUBRELEASE:
4673 case TBLOCK_SUBCOMMIT:
4674 case TBLOCK_ABORT_END:
4678 case TBLOCK_SUBRESTART:
4680 case TBLOCK_PREPARE:
4681 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4683 break;
4684 }
4685
4686 for (target = s; target; target = target->parent)
4687 {
4688 if (target->name && strcmp(target->name, name) == 0)
4689 break;
4690 }
4691
4692 if (!target)
4693 ereport(ERROR,
4695 errmsg("savepoint \"%s\" does not exist", name)));
4696
4697 /* disallow crossing savepoint level boundaries */
4698 if (target->savepointLevel != s->savepointLevel)
4699 ereport(ERROR,
4701 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4702
4703 /*
4704 * Mark "abort pending" all subtransactions up to the target
4705 * subtransaction. The actual aborts will happen when control gets to
4706 * CommitTransactionCommand.
4707 */
4709 for (;;)
4710 {
4711 if (xact == target)
4712 break;
4713 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4715 else if (xact->blockState == TBLOCK_SUBABORT)
4716 xact->blockState = TBLOCK_SUBABORT_END;
4717 else
4718 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4719 BlockStateAsString(xact->blockState));
4720 xact = xact->parent;
4721 Assert(xact);
4722 }
4723
4724 /* And mark the target as "restart pending" */
4725 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4726 xact->blockState = TBLOCK_SUBRESTART;
4727 else if (xact->blockState == TBLOCK_SUBABORT)
4728 xact->blockState = TBLOCK_SUBABORT_RESTART;
4729 else
4730 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4731 BlockStateAsString(xact->blockState));
4732}
4733
4734/*
4735 * BeginInternalSubTransaction
4736 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
4737 * TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_END,
4738 * and TBLOCK_PREPARE states, and therefore it can safely be used in
4739 * functions that might be called when not inside a BEGIN block or when
4740 * running deferred triggers at COMMIT/PREPARE time. Also, it
4741 * automatically does CommitTransactionCommand/StartTransactionCommand
4742 * instead of expecting the caller to do it.
4743 */
4744void
4746{
4749
4750 /*
4751 * Errors within this function are improbable, but if one does happen we
4752 * force a FATAL exit. Callers generally aren't prepared to handle losing
4753 * control, and moreover our transaction state is probably corrupted if we
4754 * fail partway through; so an ordinary ERROR longjmp isn't okay.
4755 */
4756 ExitOnAnyError = true;
4757
4758 /*
4759 * We do not check for parallel mode here. It's permissible to start and
4760 * end "internal" subtransactions while in parallel mode, so long as no
4761 * new XIDs or command IDs are assigned. Enforcement of that occurs in
4762 * AssignTransactionId() and CommandCounterIncrement().
4763 */
4764
4765 switch (s->blockState)
4766 {
4767 case TBLOCK_STARTED:
4768 case TBLOCK_INPROGRESS:
4771 case TBLOCK_END:
4772 case TBLOCK_PREPARE:
4774 /* Normal subtransaction start */
4776 s = CurrentTransactionState; /* changed by push */
4777
4778 /*
4779 * Savepoint names, like the TransactionState block itself, live
4780 * in TopTransactionContext.
4781 */
4782 if (name)
4784 break;
4785
4786 /* These cases are invalid. */
4787 case TBLOCK_DEFAULT:
4788 case TBLOCK_BEGIN:
4789 case TBLOCK_SUBBEGIN:
4790 case TBLOCK_SUBRELEASE:
4791 case TBLOCK_SUBCOMMIT:
4792 case TBLOCK_ABORT:
4793 case TBLOCK_SUBABORT:
4794 case TBLOCK_ABORT_END:
4798 case TBLOCK_SUBRESTART:
4800 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4802 break;
4803 }
4804
4807
4809}
4810
4811/*
4812 * ReleaseCurrentSubTransaction
4813 *
4814 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
4815 * savepoint name (if any).
4816 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4817 */
4818void
4820{
4822
4823 /*
4824 * We do not check for parallel mode here. It's permissible to start and
4825 * end "internal" subtransactions while in parallel mode, so long as no
4826 * new XIDs or command IDs are assigned.
4827 */
4828
4830 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4835 s = CurrentTransactionState; /* changed by pop */
4837}
4838
4839/*
4840 * RollbackAndReleaseCurrentSubTransaction
4841 *
4842 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
4843 * of its savepoint name (if any).
4844 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4845 */
4846void
4848{
4850
4851 /*
4852 * We do not check for parallel mode here. It's permissible to start and
4853 * end "internal" subtransactions while in parallel mode, so long as no
4854 * new XIDs or command IDs are assigned.
4855 */
4856
4857 switch (s->blockState)
4858 {
4859 /* Must be in a subtransaction */
4861 case TBLOCK_SUBABORT:
4862 break;
4863
4864 /* These cases are invalid. */
4865 case TBLOCK_DEFAULT:
4866 case TBLOCK_STARTED:
4867 case TBLOCK_BEGIN:
4870 case TBLOCK_SUBBEGIN:
4871 case TBLOCK_INPROGRESS:
4872 case TBLOCK_END:
4873 case TBLOCK_SUBRELEASE:
4874 case TBLOCK_SUBCOMMIT:
4875 case TBLOCK_ABORT:
4876 case TBLOCK_ABORT_END:
4880 case TBLOCK_SUBRESTART:
4882 case TBLOCK_PREPARE:
4883 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4885 break;
4886 }
4887
4888 /*
4889 * Abort the current subtransaction, if needed.
4890 */
4893
4894 /* And clean it up, too */
4896
4897 s = CurrentTransactionState; /* changed by pop */
4903}
4904
4905/*
4906 * AbortOutOfAnyTransaction
4907 *
4908 * This routine is provided for error recovery purposes. It aborts any
4909 * active transaction or transaction block, leaving the system in a known
4910 * idle state.
4911 */
4912void
4914{
4916
4917 /* Ensure we're not running in a doomed memory context */
4919
4920 /*
4921 * Get out of any transaction or nested transaction
4922 */
4923 do
4924 {
4925 switch (s->blockState)
4926 {
4927 case TBLOCK_DEFAULT:
4928 if (s->state == TRANS_DEFAULT)
4929 {
4930 /* Not in a transaction, do nothing */
4931 }
4932 else
4933 {
4934 /*
4935 * We can get here after an error during transaction start
4936 * (state will be TRANS_START). Need to clean up the
4937 * incompletely started transaction. First, adjust the
4938 * low-level state to suppress warning message from
4939 * AbortTransaction.
4940 */
4941 if (s->state == TRANS_START)
4945 }
4946 break;
4947 case TBLOCK_STARTED:
4948 case TBLOCK_BEGIN:
4949 case TBLOCK_INPROGRESS:
4952 case TBLOCK_END:
4954 case TBLOCK_PREPARE:
4955 /* In a transaction, so clean up */
4959 break;
4960 case TBLOCK_ABORT:
4961 case TBLOCK_ABORT_END:
4962
4963 /*
4964 * AbortTransaction is already done, still need Cleanup.
4965 * However, if we failed partway through running ROLLBACK,
4966 * there will be an active portal running that command, which
4967 * we need to shut down before doing CleanupTransaction.
4968 */
4972 break;
4973
4974 /*
4975 * In a subtransaction, so clean it up and abort parent too
4976 */
4977 case TBLOCK_SUBBEGIN:
4979 case TBLOCK_SUBRELEASE:
4980 case TBLOCK_SUBCOMMIT:
4982 case TBLOCK_SUBRESTART:
4985 s = CurrentTransactionState; /* changed by pop */
4986 break;
4987
4988 case TBLOCK_SUBABORT:
4991 /* As above, but AbortSubTransaction already done */
4992 if (s->curTransactionOwner)
4993 {
4994 /* As in TBLOCK_ABORT, might have a live portal to zap */
4999 }
5001 s = CurrentTransactionState; /* changed by pop */
5002 break;
5003 }
5004 } while (s->blockState != TBLOCK_DEFAULT);
5005
5006 /* Should be out of all subxacts now */
5007 Assert(s->parent == NULL);
5008
5009 /*
5010 * Revert to TopMemoryContext, to ensure we exit in a well-defined state
5011 * whether there were any transactions to close or not. (Callers that
5012 * don't intend to exit soon should switch to some other context to avoid
5013 * long-term memory leaks.)
5014 */
5016}
5017
5018/*
5019 * IsTransactionBlock --- are we within a transaction block?
5020 */
5021bool
5023{
5025
5027 return false;
5028
5029 return true;
5030}
5031
5032/*
5033 * IsTransactionOrTransactionBlock --- are we within either a transaction
5034 * or a transaction block? (The backend is only really "idle" when this
5035 * returns false.)
5036 *
5037 * This should match up with IsTransactionBlock and IsTransactionState.
5038 */
5039bool
5041{
5043
5044 if (s->blockState == TBLOCK_DEFAULT)
5045 return false;
5046
5047 return true;
5048}
5049
5050/*
5051 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
5052 */
5053char
5055{
5057
5058 switch (s->blockState)
5059 {
5060 case TBLOCK_DEFAULT:
5061 case TBLOCK_STARTED:
5062 return 'I'; /* idle --- not in transaction */
5063 case TBLOCK_BEGIN:
5064 case TBLOCK_SUBBEGIN:
5065 case TBLOCK_INPROGRESS:
5069 case TBLOCK_END:
5070 case TBLOCK_SUBRELEASE:
5071 case TBLOCK_SUBCOMMIT:
5072 case TBLOCK_PREPARE:
5073 return 'T'; /* in transaction */
5074 case TBLOCK_ABORT:
5075 case TBLOCK_SUBABORT:
5076 case TBLOCK_ABORT_END:
5080 case TBLOCK_SUBRESTART:
5082 return 'E'; /* in failed transaction */
5083 }
5084
5085 /* should never get here */
5086 elog(FATAL, "invalid transaction block state: %s",
5088 return 0; /* keep compiler quiet */
5089}
5090
5091/*
5092 * IsSubTransaction
5093 */
5094bool
5096{
5098
5099 if (s->nestingLevel >= 2)
5100 return true;
5101
5102 return false;
5103}
5104
5105/*
5106 * StartSubTransaction
5107 *
5108 * If you're wondering why this is separate from PushTransaction: it's because
5109 * we can't conveniently do this stuff right inside DefineSavepoint. The
5110 * SAVEPOINT utility command will be executed inside a Portal, and if we
5111 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
5112 * the Portal will undo those settings. So we make DefineSavepoint just
5113 * push a dummy transaction block, and when control returns to the main
5114 * idle loop, CommitTransactionCommand will be called, and we'll come here
5115 * to finish starting the subtransaction.
5116 */
5117static void
5119{
5121
5122 if (s->state != TRANS_DEFAULT)
5123 elog(WARNING, "StartSubTransaction while in %s state",
5125
5126 s->state = TRANS_START;
5127
5128 /*
5129 * Initialize subsystems for new subtransaction
5130 *
5131 * must initialize resource-management stuff first
5132 */
5136
5138
5139 /*
5140 * Call start-of-subxact callbacks
5141 */
5144
5145 ShowTransactionState("StartSubTransaction");
5146}
5147
5148/*
5149 * CommitSubTransaction
5150 *
5151 * The caller has to make sure to always reassign CurrentTransactionState
5152 * if it has a local pointer to it after calling this function.
5153 */
5154static void
5156{
5158
5159 ShowTransactionState("CommitSubTransaction");
5160
5161 if (s->state != TRANS_INPROGRESS)
5162 elog(WARNING, "CommitSubTransaction while in %s state",
5164
5165 /* Pre-commit processing goes here */
5166
5169
5170 /*
5171 * If this subxact has started any unfinished parallel operation, clean up
5172 * its workers and exit parallel mode. Warn about leaked resources.
5173 */
5175 if (s->parallelModeLevel != 0)
5176 {
5177 elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5179 s->parallelModeLevel = 0;
5180 }
5181
5182 /* Do the actual "commit", such as it is */
5183 s->state = TRANS_COMMIT;
5184
5185 /* Must CCI to ensure commands of subtransaction are seen as done */
5187
5188 /*
5189 * Prior to 8.4 we marked subcommit in clog at this point. We now only
5190 * perform that step, if required, as part of the atomic update of the
5191 * whole transaction tree at top level commit or abort.
5192 */
5193
5194 /* Post-commit cleanup */
5200 s->parent->nestingLevel,
5205
5208
5211 true, false);
5215 AtEOSubXact_Inval(true);
5217
5218 /*
5219 * The only lock we actually release here is the subtransaction XID lock.
5220 */
5224
5225 /*
5226 * Other locks should get transferred to their parent resource owner.
5227 */
5230 true, false);
5233 true, false);
5234
5235 AtEOXact_GUC(true, s->gucNestLevel);
5246
5247 /*
5248 * We need to restore the upper transaction's read-only state, in case the
5249 * upper is read-write while the child is read-only; GUC will incorrectly
5250 * think it should leave the child state in place.
5251 */
5253
5258
5260
5261 s->state = TRANS_DEFAULT;
5262
5264}
5265
5266/*
5267 * AbortSubTransaction
5268 */
5269static void
5271{
5273
5274 /* Prevent cancel/die interrupt while cleaning up */
5276
5277 /* Make sure we have a valid memory context and resource owner */
5280
5281 /*
5282 * Release any LW locks we might be holding as quickly as possible.
5283 * (Regular locks, however, must be held till we finish aborting.)
5284 * Releasing LW locks is critical since we might try to grab them again
5285 * while cleaning up!
5286 *
5287 * FIXME This may be incorrect --- Are there some locks we should keep?
5288 * Buffer locks, for example? I don't think so but I'm not sure.
5289 */
5291
5294
5296
5297 UnlockBuffers();
5298
5299 /* Reset WAL record construction state */
5301
5302 /* Cancel condition variable sleep */
5304
5305 /*
5306 * Also clean up any open wait for lock, since the lock manager will choke
5307 * if we try to wait for another lock before doing this.
5308 */
5310
5311 /*
5312 * If any timeout events are still active, make sure the timeout interrupt
5313 * is scheduled. This covers possible loss of a timeout interrupt due to
5314 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5315 * We delay this till after LockErrorCleanup so that we don't uselessly
5316 * reschedule lock or deadlock check timeouts.
5317 */
5319
5320 /*
5321 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5322 * handler. We do this fairly early in the sequence so that the timeout
5323 * infrastructure will be functional if needed while aborting.
5324 */
5326
5327 /*
5328 * check the current transaction state
5329 */
5330 ShowTransactionState("AbortSubTransaction");
5331
5332 if (s->state != TRANS_INPROGRESS)
5333 elog(WARNING, "AbortSubTransaction while in %s state",
5335
5336 s->state = TRANS_ABORT;
5337
5338 /*
5339 * Reset user ID which might have been changed transiently. (See notes in
5340 * AbortTransaction.)
5341 */
5343
5344 /* Forget about any active REINDEX. */
5346
5347 /* Reset logical streaming state. */
5349
5350 /*
5351 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5352 * exports are not supported in subtransactions.
5353 */
5354
5355 /*
5356 * If this subxact has started any unfinished parallel operation, clean up
5357 * its workers and exit parallel mode. Don't warn about leaked resources.
5358 */
5360 s->parallelModeLevel = 0;
5361
5362 /*
5363 * We can skip all this stuff if the subxact failed before creating a
5364 * ResourceOwner...
5365 */
5366 if (s->curTransactionOwner)
5367 {
5376
5377 /* Advertise the fact that we aborted in pg_xact. */
5379
5380 /* Post-abort cleanup */
5383
5386
5389 false, false);
5390
5391 AtEOXact_Aio(false);
5395 AtEOSubXact_Inval(false);
5398 false, false);
5401 false, false);
5403
5404 AtEOXact_GUC(false, s->gucNestLevel);
5415 }
5416
5417 /*
5418 * Restore the upper transaction's read-only state, too. This should be
5419 * redundant with GUC's cleanup but we may as well do it for consistency
5420 * with the commit case.
5421 */
5423
5425}
5426
5427/*
5428 * CleanupSubTransaction
5429 *
5430 * The caller has to make sure to always reassign CurrentTransactionState
5431 * if it has a local pointer to it after calling this function.
5432 */
5433static void
5435{
5437
5438 ShowTransactionState("CleanupSubTransaction");
5439
5440 if (s->state != TRANS_ABORT)
5441 elog(WARNING, "CleanupSubTransaction while in %s state",
5443
5445
5448 if (s->curTransactionOwner)
5451
5453
5454 s->state = TRANS_DEFAULT;
5455
5457}
5458
5459/*
5460 * PushTransaction
5461 * Create transaction state stack entry for a subtransaction
5462 *
5463 * The caller has to make sure to always reassign CurrentTransactionState
5464 * if it has a local pointer to it after calling this function.
5465 */
5466static void
5468{
5471
5472 /*
5473 * We keep subtransaction state nodes in TopTransactionContext.
5474 */
5475 s = (TransactionState)
5477 sizeof(TransactionStateData));
5478
5479 /*
5480 * Assign a subtransaction ID, watching out for counter wraparound.
5481 */
5484 {
5486 pfree(s);
5487 ereport(ERROR,
5489 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5490 }
5491
5492 /*
5493 * We can now stack a minimally valid subtransaction without fear of
5494 * failure.
5495 */
5496 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5498 s->parent = p;
5499 s->nestingLevel = p->nestingLevel + 1;
5502 s->state = TRANS_DEFAULT;
5507 s->parallelModeLevel = 0;
5509 s->topXidLogged = false;
5510
5512
5513 /*
5514 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5515 * with the subtransaction from here on out; in particular they should not
5516 * assume that it necessarily has a transaction context, resource owner,
5517 * or XID.
5518 */
5519}
5520
5521/*
5522 * PopTransaction
5523 * Pop back to parent transaction state
5524 *
5525 * The caller has to make sure to always reassign CurrentTransactionState
5526 * if it has a local pointer to it after calling this function.
5527 */
5528static void
5530{
5532
5533 if (s->state != TRANS_DEFAULT)
5534 elog(WARNING, "PopTransaction while in %s state",
5536
5537 if (s->parent == NULL)
5538 elog(FATAL, "PopTransaction with no parent");
5539
5541
5542 /* Let's just make sure CurTransactionContext is good */
5545
5546 /* Ditto for ResourceOwner links */
5549
5550 /* Free the old child structure */
5551 if (s->name)
5552 pfree(s->name);
5553 pfree(s);
5554}
5555
5556/*
5557 * EstimateTransactionStateSpace
5558 * Estimate the amount of space that will be needed by
5559 * SerializeTransactionState. It would be OK to overestimate slightly,
5560 * but it's simple for us to work out the precise value, so we do.
5561 */
5562Size
5564{
5566 Size nxids = 0;
5568
5569 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5570 {
5572 nxids = add_size(nxids, 1);
5574 }
5575
5576 return add_size(size, mul_size(sizeof(TransactionId), nxids));
5577}
5578
5579/*
5580 * SerializeTransactionState
5581 * Write out relevant details of our transaction state that will be
5582 * needed by a parallel worker.
5583 *
5584 * We need to save and restore XactDeferrable, XactIsoLevel, and the XIDs
5585 * associated with this transaction. These are serialized into a
5586 * caller-supplied buffer big enough to hold the number of bytes reported by
5587 * EstimateTransactionStateSpace(). We emit the XIDs in sorted order for the
5588 * convenience of the receiving process.
5589 */
5590void
5592{
5594 Size nxids = 0;
5595 Size i = 0;
5596 TransactionId *workspace;
5598
5600
5602 result->xactDeferrable = XactDeferrable;
5603 result->topFullTransactionId = XactTopFullTransactionId;
5604 result->currentFullTransactionId =
5606 result->currentCommandId = currentCommandId;
5607
5608 /*
5609 * If we're running in a parallel worker and launching a parallel worker
5610 * of our own, we can just pass along the information that was passed to
5611 * us.
5612 */
5613 if (nParallelCurrentXids > 0)
5614 {
5615 result->nParallelCurrentXids = nParallelCurrentXids;
5616 memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
5618 return;
5619 }
5620
5621 /*
5622 * OK, we need to generate a sorted list of XIDs that our workers should
5623 * view as current. First, figure out how many there are.
5624 */
5625 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5626 {
5628 nxids = add_size(nxids, 1);
5630 }
5632 <= maxsize);
5633
5634 /* Copy them to our scratch space. */
5635 workspace = palloc(nxids * sizeof(TransactionId));
5636 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5637 {
5639 workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5640 if (s->nChildXids > 0)
5641 memcpy(&workspace[i], s->childXids,
5642 s->nChildXids * sizeof(TransactionId));
5643 i += s->nChildXids;
5644 }
5645 Assert(i == nxids);
5646
5647 /* Sort them. */
5648 qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5649
5650 /* Copy data into output area. */
5651 result->nParallelCurrentXids = nxids;
5652 memcpy(&result->parallelCurrentXids[0], workspace,
5653 nxids * sizeof(TransactionId));
5654}
5655
5656/*
5657 * StartParallelWorkerTransaction
5658 * Start a parallel worker transaction, restoring the relevant
5659 * transaction state serialized by SerializeTransactionState.
5660 */
5661void
5663{
5665
5668
5670 XactIsoLevel = tstate->xactIsoLevel;
5671 XactDeferrable = tstate->xactDeferrable;
5672 XactTopFullTransactionId = tstate->topFullTransactionId;
5674 tstate->currentFullTransactionId;
5675 currentCommandId = tstate->currentCommandId;
5676 nParallelCurrentXids = tstate->nParallelCurrentXids;
5677 ParallelCurrentXids = &tstate->parallelCurrentXids[0];
5678
5680}
5681
5682/*
5683 * EndParallelWorkerTransaction
5684 * End a parallel worker transaction.
5685 */
5686void
5693
5694/*
5695 * ShowTransactionState
5696 * Debug support
5697 */
5698static void
5700{
5701 /* skip work if message will definitely not be printed */
5704}
5705
5706/*
5707 * ShowTransactionStateRec
5708 * Recursive subroutine for ShowTransactionState
5709 */
5710static void
5712{
5714
5715 if (s->parent)
5716 {
5717 /*
5718 * Since this function recurses, it could be driven to stack overflow.
5719 * This is just a debugging aid, so we can leave out some details
5720 * instead of erroring out with check_stack_depth().
5721 */
5722 if (stack_is_too_deep())
5724 (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5725 str, s->nestingLevel)));
5726 else
5728 }
5729
5731 if (s->nChildXids > 0)
5732 {
5733 int i;
5734
5735 appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5736 for (i = 1; i < s->nChildXids; i++)
5737 appendStringInfo(&buf, " %u", s->childXids[i]);
5738 }
5740 (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5741 str, s->nestingLevel,
5742 s->name ? s->name : "unnamed",
5748 currentCommandIdUsed ? " (used)" : "",
5749 buf.data)));
5750 pfree(buf.data);
5751}
5752
5753/*
5754 * BlockStateAsString
5755 * Debug support
5756 */
5757static const char *
5759{
5760 switch (blockState)
5761 {
5762 case TBLOCK_DEFAULT:
5763 return "DEFAULT";
5764 case TBLOCK_STARTED:
5765 return "STARTED";
5766 case TBLOCK_BEGIN:
5767 return "BEGIN";
5768 case TBLOCK_INPROGRESS:
5769 return "INPROGRESS";
5771 return "IMPLICIT_INPROGRESS";
5773 return "PARALLEL_INPROGRESS";
5774 case TBLOCK_END:
5775 return "END";
5776 case TBLOCK_ABORT:
5777 return "ABORT";
5778 case TBLOCK_ABORT_END:
5779 return "ABORT_END";
5781 return "ABORT_PENDING";
5782 case TBLOCK_PREPARE:
5783 return "PREPARE";
5784 case TBLOCK_SUBBEGIN:
5785 return "SUBBEGIN";
5787 return "SUBINPROGRESS";
5788 case TBLOCK_SUBRELEASE:
5789 return "SUBRELEASE";
5790 case TBLOCK_SUBCOMMIT:
5791 return "SUBCOMMIT";
5792 case TBLOCK_SUBABORT:
5793 return "SUBABORT";
5795 return "SUBABORT_END";
5797 return "SUBABORT_PENDING";
5798 case TBLOCK_SUBRESTART:
5799 return "SUBRESTART";
5801 return "SUBABORT_RESTART";
5802 }
5803 return "UNRECOGNIZED";
5804}
5805
5806/*
5807 * TransStateAsString
5808 * Debug support
5809 */
5810static const char *
5812{
5813 switch (state)
5814 {
5815 case TRANS_DEFAULT:
5816 return "DEFAULT";
5817 case TRANS_START:
5818 return "START";
5819 case TRANS_INPROGRESS:
5820 return "INPROGRESS";
5821 case TRANS_COMMIT:
5822 return "COMMIT";
5823 case TRANS_ABORT:
5824 return "ABORT";
5825 case TRANS_PREPARE:
5826 return "PREPARE";
5827 }
5828 return "UNRECOGNIZED";
5829}
5830
5831/*
5832 * xactGetCommittedChildren
5833 *
5834 * Gets the list of committed children of the current transaction. The return
5835 * value is the number of child transactions. *ptr is set to point to an
5836 * array of TransactionIds. The array is allocated in TopTransactionContext;
5837 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
5838 * If there are no subxacts, *ptr is set to NULL.
5839 */
5840int
5842{
5844
5845 if (s->nChildXids == 0)
5846 *ptr = NULL;
5847 else
5848 *ptr = s->childXids;
5849
5850 return s->nChildXids;
5851}
5852
5853/*
5854 * XLOG support routines
5855 */
5856
5857
5858/*
5859 * Log the commit record for a plain or twophase transaction commit.
5860 *
5861 * A 2pc commit will be emitted when twophase_xid is valid, a plain one
5862 * otherwise.
5863 */
5866 int nsubxacts, TransactionId *subxacts,
5867 int nrels, RelFileLocator *rels,
5869 int nmsgs, SharedInvalidationMessage *msgs,
5870 bool relcacheInval,
5871 int xactflags, TransactionId twophase_xid,
5872 const char *twophase_gid)
5873{
5883 uint8 info;
5884
5886
5887 xl_xinfo.xinfo = 0;
5888
5889 /* decide between a plain and 2pc commit */
5890 if (!TransactionIdIsValid(twophase_xid))
5891 info = XLOG_XACT_COMMIT;
5892 else
5894
5895 /* First figure out and collect all the information needed */
5896
5897 xlrec.xact_time = commit_time;
5898
5899 if (relcacheInval)
5901 if (forceSyncCommit)
5905
5906 /*
5907 * Check if the caller would like to ask standbys for immediate feedback
5908 * once this commit is applied.
5909 */
5912
5913 /*
5914 * Relcache invalidations requires information about the current database
5915 * and so does logical decoding.
5916 */
5917 if (nmsgs > 0 || XLogLogicalInfoActive())
5918 {
5920 xl_dbinfo.dbId = MyDatabaseId;
5922 }
5923
5924 if (nsubxacts > 0)
5925 {
5927 xl_subxacts.nsubxacts = nsubxacts;
5928 }
5929
5930 if (nrels > 0)
5931 {
5933 xl_relfilelocators.nrels = nrels;
5934 info |= XLR_SPECIAL_REL_UPDATE;
5935 }
5936
5937 if (ndroppedstats > 0)
5938 {
5941 }
5942
5943 if (nmsgs > 0)
5944 {
5946 xl_invals.nmsgs = nmsgs;
5947 }
5948
5949 if (TransactionIdIsValid(twophase_xid))
5950 {
5952 xl_twophase.xid = twophase_xid;
5953 Assert(twophase_gid != NULL);
5954
5957 }
5958
5959 /* dump transaction origin information */
5961 {
5963
5966 }
5967
5968 if (xl_xinfo.xinfo != 0)
5969 info |= XLOG_XACT_HAS_INFO;
5970
5971 /* Then include all the collected data into the commit record. */
5972
5974
5976
5977 if (xl_xinfo.xinfo != 0)
5978 XLogRegisterData(&xl_xinfo.xinfo, sizeof(xl_xinfo.xinfo));
5979
5980 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5982
5984 {
5987 XLogRegisterData(subxacts,
5988 nsubxacts * sizeof(TransactionId));
5989 }
5990
5992 {
5995 XLogRegisterData(rels,
5996 nrels * sizeof(RelFileLocator));
5997 }
5998
6000 {
6005 }
6006
6007 if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
6008 {
6010 XLogRegisterData(msgs,
6011 nmsgs * sizeof(SharedInvalidationMessage));
6012 }
6013
6015 {
6017 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6018 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6019 }
6020
6021 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6023
6024 /* we allow filtering by xacts */
6026
6027 return XLogInsert(RM_XACT_ID, info);
6028}
6029
6030/*
6031 * Log the commit record for a plain or twophase transaction abort.
6032 *
6033 * A 2pc abort will be emitted when twophase_xid is valid, a plain one
6034 * otherwise.
6035 */
6038 int nsubxacts, TransactionId *subxacts,
6039 int nrels, RelFileLocator *rels,
6041 int xactflags, TransactionId twophase_xid,
6042 const char *twophase_gid)
6043{
6052
6053 uint8 info;
6054
6056
6057 xl_xinfo.xinfo = 0;
6058
6059 /* decide between a plain and 2pc abort */
6060 if (!TransactionIdIsValid(twophase_xid))
6061 info = XLOG_XACT_ABORT;
6062 else
6064
6065
6066 /* First figure out and collect all the information needed */
6067
6068 xlrec.xact_time = abort_time;
6069
6072
6073 if (nsubxacts > 0)
6074 {
6076 xl_subxacts.nsubxacts = nsubxacts;
6077 }
6078
6079 if (nrels > 0)
6080 {
6082 xl_relfilelocators.nrels = nrels;
6083 info |= XLR_SPECIAL_REL_UPDATE;
6084 }
6085
6086 if (ndroppedstats > 0)
6087 {
6090 }
6091
6092 if (TransactionIdIsValid(twophase_xid))
6093 {
6095 xl_twophase.xid = twophase_xid;
6096 Assert(twophase_gid != NULL);
6097
6100 }
6101
6102 if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6103 {
6105 xl_dbinfo.dbId = MyDatabaseId;
6107 }
6108
6109 /*
6110 * Dump transaction origin information. We need this during recovery to
6111 * update the replication origin progress.
6112 */
6114 {
6116
6119 }
6120
6121 if (xl_xinfo.xinfo != 0)
6122 info |= XLOG_XACT_HAS_INFO;
6123
6124 /* Then include all the collected data into the abort record. */
6125
6127
6129
6130 if (xl_xinfo.xinfo != 0)
6132
6133 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6135
6137 {
6140 XLogRegisterData(subxacts,
6141 nsubxacts * sizeof(TransactionId));
6142 }
6143
6145 {
6148 XLogRegisterData(rels,
6149 nrels * sizeof(RelFileLocator));
6150 }
6151
6153 {
6158 }
6159
6161 {
6163 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6164 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6165 }
6166
6167 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6169
6170 /* Include the replication origin */
6172
6173 return XLogInsert(RM_XACT_ID, info);
6174}
6175
6176/*
6177 * Before 9.0 this was a fairly short function, but now it performs many
6178 * actions for which the order of execution is critical.
6179 */
6180static void
6182 TransactionId xid,
6183 XLogRecPtr lsn,
6184 ReplOriginId origin_id)
6185{
6187 TimestampTz commit_time;
6188
6190
6191 max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
6192
6193 /* Make sure nextXid is beyond any XID mentioned in the record. */
6195
6196 Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) ==
6197 (origin_id == InvalidReplOriginId));
6198
6199 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6200 commit_time = parsed->origin_timestamp;
6201 else
6202 commit_time = parsed->xact_time;
6203
6204 /* Set the transaction commit timestamp and metadata */
6205 TransactionTreeSetCommitTsData(xid, parsed->nsubxacts, parsed->subxacts,
6206 commit_time, origin_id);
6207
6209 {
6210 /*
6211 * Mark the transaction committed in pg_xact.
6212 */
6213 TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
6214 }
6215 else
6216 {
6217 /*
6218 * If a transaction completion record arrives that has as-yet
6219 * unobserved subtransactions then this will not have been fully
6220 * handled by the call to RecordKnownAssignedTransactionIds() in the
6221 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6222 * cover that case. This is confusing and it is easy to think this
6223 * call is irrelevant, which has happened three times in development
6224 * already. Leave it in.
6225 */
6227
6228 /*
6229 * Mark the transaction committed in pg_xact. We use async commit
6230 * protocol during recovery to provide information on database
6231 * consistency for when users try to set hint bits. It is important
6232 * that we do not set hint bits until the minRecoveryPoint is past
6233 * this commit record. This ensures that if we crash we don't see hint
6234 * bits set on changes made by transactions that haven't yet
6235 * recovered. It's unlikely but it's good to be safe.
6236 */
6237 TransactionIdAsyncCommitTree(xid, parsed->nsubxacts, parsed->subxacts, lsn);
6238
6239 /*
6240 * We must mark clog before we update the ProcArray.
6241 */
6242 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6243
6244 /*
6245 * Send any cache invalidations attached to the commit. We must
6246 * maintain the same order of invalidation then release locks as
6247 * occurs in CommitTransaction().
6248 */
6251 parsed->dbId, parsed->tsId);
6252
6253 /*
6254 * Release locks, if any. We do this for both two phase and normal one
6255 * phase transactions. In effect we are ignoring the prepare phase and
6256 * just going straight to lock release.
6257 */
6258 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6259 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6260 }
6261
6262 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6263 {
6264 /* recover apply progress */
6265 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6266 false /* backward */ , false /* WAL */ );
6267 }
6268
6269 /* Make sure files supposed to be dropped are dropped */
6270 if (parsed->nrels > 0)
6271 {
6272 /*
6273 * First update minimum recovery point to cover this WAL record. Once
6274 * a relation is deleted, there's no going back. The buffer manager
6275 * enforces the WAL-first rule for normal updates to relation files,
6276 * so that the minimum recovery point is always updated before the
6277 * corresponding change in the data file is flushed to disk, but we
6278 * have to do the same here since we're bypassing the buffer manager.
6279 *
6280 * Doing this before deleting the files means that if a deletion fails
6281 * for some reason, you cannot start up the system even after restart,
6282 * until you fix the underlying situation so that the deletion will
6283 * succeed. Alternatively, we could update the minimum recovery point
6284 * after deletion, but that would leave a small window where the
6285 * WAL-first rule would be violated.
6286 */
6287 XLogFlush(lsn);
6288
6289 /* Make sure files supposed to be dropped are dropped */
6290 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6291 }
6292
6293 if (parsed->nstats > 0)
6294 {
6295 /* see equivalent call for relations above */
6296 XLogFlush(lsn);
6297
6298 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6299 }
6300
6301 /*
6302 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
6303 * in normal operation. For example, in CREATE DATABASE, we copy all files
6304 * from the template database, and then commit the transaction. If we
6305 * crash after all the files have been copied but before the commit, you
6306 * have files in the data directory without an entry in pg_database. To
6307 * minimize the window for that, we use ForceSyncCommit() to rush the
6308 * commit record to disk as quick as possible. We have the same window
6309 * during recovery, and forcing an XLogFlush() (which updates
6310 * minRecoveryPoint during recovery) helps to reduce that problem window,
6311 * for any user that requested ForceSyncCommit().
6312 */
6314 XLogFlush(lsn);
6315
6316 /*
6317 * If asked by the primary (because someone is waiting for a synchronous
6318 * commit = remote_apply), we will need to ask walreceiver to send a reply
6319 * immediately.
6320 */
6323}
6324
6325/*
6326 * Be careful with the order of execution, as with xact_redo_commit().
6327 * The two functions are similar but differ in key places.
6328 *
6329 * Note also that an abort can be for a subtransaction and its children,
6330 * not just for a top level abort. That means we have to consider
6331 * topxid != xid, whereas in commit we would find topxid == xid always
6332 * because subtransaction commit is never WAL logged.
6333 */
6334static void
6336 XLogRecPtr lsn, ReplOriginId origin_id)
6337{
6339
6341
6342 /* Make sure nextXid is beyond any XID mentioned in the record. */
6344 parsed->nsubxacts,
6345 parsed->subxacts);
6347
6349 {
6350 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6351 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6352 }
6353 else
6354 {
6355 /*
6356 * If a transaction completion record arrives that has as-yet
6357 * unobserved subtransactions then this will not have been fully
6358 * handled by the call to RecordKnownAssignedTransactionIds() in the
6359 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6360 * cover that case. This is confusing and it is easy to think this
6361 * call is irrelevant, which has happened three times in development
6362 * already. Leave it in.
6363 */
6365
6366 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6367 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6368
6369 /*
6370 * We must update the ProcArray after we have marked clog.
6371 */
6372 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6373
6374 /*
6375 * There are no invalidation messages to send or undo.
6376 */
6377
6378 /*
6379 * Release locks, if any. There are no invalidations to send.
6380 */
6381 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6382 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6383 }
6384
6385 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6386 {
6387 /* recover apply progress */
6388 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6389 false /* backward */ , false /* WAL */ );
6390 }
6391
6392 /* Make sure files supposed to be dropped are dropped */
6393 if (parsed->nrels > 0)
6394 {
6395 /*
6396 * See comments about update of minimum recovery point on truncation,
6397 * in xact_redo_commit().
6398 */
6399 XLogFlush(lsn);
6400
6401 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6402 }
6403
6404 if (parsed->nstats > 0)
6405 {
6406 /* see equivalent call for relations above */
6407 XLogFlush(lsn);
6408
6409 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6410 }
6411}
6412
6413void
6415{
6416 uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6417
6418 /* Backup blocks are not used in xact records */
6420
6421 if (info == XLOG_XACT_COMMIT)
6422 {
6425
6428 record->EndRecPtr, XLogRecGetOrigin(record));
6429 }
6430 else if (info == XLOG_XACT_COMMIT_PREPARED)
6431 {
6434
6436 xact_redo_commit(&parsed, parsed.twophase_xid,
6437 record->EndRecPtr, XLogRecGetOrigin(record));
6438
6439 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6441 PrepareRedoRemove(parsed.twophase_xid, false);
6443 }
6444 else if (info == XLOG_XACT_ABORT)
6445 {
6448
6451 record->EndRecPtr, XLogRecGetOrigin(record));
6452 }
6453 else if (info == XLOG_XACT_ABORT_PREPARED)
6454 {
6457
6459 xact_redo_abort(&parsed, parsed.twophase_xid,
6460 record->EndRecPtr, XLogRecGetOrigin(record));
6461
6462 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6464 PrepareRedoRemove(parsed.twophase_xid, false);
6466 }
6467 else if (info == XLOG_XACT_PREPARE)
6468 {
6469 /*
6470 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6471 * gxact entry.
6472 */
6475 XLogRecGetData(record),
6476 record->ReadRecPtr,
6477 record->EndRecPtr,
6478 XLogRecGetOrigin(record));
6480 }
6481 else if (info == XLOG_XACT_ASSIGNMENT)
6482 {
6484
6487 xlrec->nsubxacts, xlrec->xsub);
6488 }
6489 else if (info == XLOG_XACT_INVALIDATIONS)
6490 {
6491 /*
6492 * XXX we do ignore this for now, what matters are invalidations
6493 * written into the commit record.
6494 */
6495 }
6496 else
6497 elog(PANIC, "xact_redo: unknown op code %u", info);
6498}
void pgaio_error_cleanup(void)
Definition aio.c:1175
void AtEOXact_Aio(bool is_commit)
Definition aio.c:1203
void AtCommit_Notify(void)
Definition async.c:1378
void AtAbort_Notify(void)
Definition async.c:2418
void PreCommit_Notify(void)
Definition async.c:1185
void AtSubAbort_Notify(void)
Definition async.c:2507
void AtPrepare_Notify(void)
Definition async.c:1160
void AtSubCommit_Notify(void)
Definition async.c:2437
#define pg_write_barrier()
Definition atomics.h:155
void ParallelWorkerReportLastRecEnd(XLogRecPtr last_xlog_end)
Definition parallel.c:1594
bool ParallelContextActive(void)
Definition parallel.c:1033
void AtEOSubXact_Parallel(bool isCommit, SubTransactionId mySubId)
Definition parallel.c:1263
void AtEOXact_Parallel(bool isCommit)
Definition parallel.c:1284
sigset_t UnBlockSig
Definition pqsignal.c:22
void AtEOXact_LogicalRepWorkers(bool isCommit)
Definition worker.c:6332
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1639
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:225
static void cleanup(void)
Definition bootstrap.c:886
void AtEOXact_Buffers(bool isCommit)
Definition bufmgr.c:4199
void UnlockBuffers(void)
Definition bufmgr.c:5852
#define InvalidCommandId
Definition c.h:753
#define TopSubTransactionId
Definition c.h:743
#define Min(x, y)
Definition c.h:1091
uint8_t uint8
Definition c.h:622
uint32 SubTransactionId
Definition c.h:740
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:249
#define InvalidSubTransactionId
Definition c.h:742
#define Assert(condition)
Definition c.h:943
#define FLEXIBLE_ARRAY_MEMBER
Definition c.h:558
#define FirstCommandId
Definition c.h:752
uint32 LocalTransactionId
Definition c.h:738
uint32 CommandId
Definition c.h:750
uint32 TransactionId
Definition c.h:736
size_t Size
Definition c.h:689
uint32 result
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
void AtEOXact_ComboCid(void)
Definition combocid.c:182
void TransactionTreeSetCommitTsData(TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz timestamp, ReplOriginId nodeid)
Definition commit_ts.c:150
bool ConditionVariableCancelSleep(void)
int64 TimestampTz
Definition timestamp.h:39
void AtEOXact_HashTables(bool isCommit)
Definition dynahash.c:1864
void AtEOSubXact_HashTables(bool isCommit, int nestDepth)
Definition dynahash.c:1890
Datum arg
Definition elog.c:1322
bool message_level_is_interesting(int elevel)
Definition elog.c:284
int errcode(int sqlerrcode)
Definition elog.c:874
#define FATAL
Definition elog.h:42
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define WARNING
Definition elog.h:37
#define PANIC
Definition elog.h:44
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
#define DEBUG5
Definition elog.h:27
void AtEOXact_Files(bool isCommit)
Definition fd.c:3214
void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition fd.c:3181
#define MaxAllocSize
Definition fe_memutils.h:22
#define palloc_array(type, count)
Definition fe_memutils.h:76
ProcNumber MyProcNumber
Definition globals.c:92
Oid MyDatabaseTableSpace
Definition globals.c:98
volatile uint32 CritSectionCount
Definition globals.c:45
bool ExitOnAnyError
Definition globals.c:125
Oid MyDatabaseId
Definition globals.c:96
int NewGUCNestLevel(void)
Definition guc.c:2142
void AtStart_GUC(void)
Definition guc.c:2122
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition guc.c:2169
double log_xact_sample_rate
Definition guc_tables.c:575
const char * str
#define IsParallelWorker()
Definition parallel.h:62
void ResetReindexState(int nestLevel)
Definition index.c:4234
void PostPrepare_Inval(void)
Definition inval.c:993
void LogLogicalInvalidations(void)
Definition inval.c:1939
void AcceptInvalidationMessages(void)
Definition inval.c:930
int xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs, bool *RelcacheInitFileInval)
Definition inval.c:1012
void AtEOXact_Inval(bool isCommit)
Definition inval.c:1199
void AtEOSubXact_Inval(bool isCommit)
Definition inval.c:1310
void CommandEndInvalidationMessages(void)
Definition inval.c:1409
void ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs, int nmsgs, bool RelcacheInitFileInval, Oid dbid, Oid tsid)
Definition inval.c:1135
int i
Definition isn.c:77
void AtEOXact_ApplyLauncher(bool isCommit)
Definition launcher.c:1166
void XactLockTableDelete(TransactionId xid)
Definition lmgr.c:639
void XactLockTableInsert(TransactionId xid)
Definition lmgr.c:622
void PostPrepare_Locks(FullTransactionId fxid)
Definition lock.c:3581
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
Definition lock.c:4603
void AtPrepare_Locks(void)
Definition lock.c:3485
#define InvalidLocalTransactionId
Definition lock.h:68
void ResetLogicalStreamingState(void)
Definition logical.c:1938
void AtEOXact_LogicalCtl(void)
Definition logicalctl.c:233
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1150
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1767
void LWLockReleaseAll(void)
Definition lwlock.c:1866
@ LW_EXCLUSIVE
Definition lwlock.h:104
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition mcxt.c:1768
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1232
bool MemoryContextIsEmpty(MemoryContext context)
Definition mcxt.c:792
void MemoryContextReset(MemoryContext context)
Definition mcxt.c:403
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition mcxt.c:1266
MemoryContext TopTransactionContext
Definition mcxt.c:171
void * repalloc(void *pointer, Size size)
Definition mcxt.c:1632
void pfree(void *pointer)
Definition mcxt.c:1616
MemoryContext TopMemoryContext
Definition mcxt.c:166
void * palloc(Size size)
Definition mcxt.c:1387
MemoryContext CurTransactionContext
Definition mcxt.c:172
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472
void DropRelationFiles(RelFileLocator *delrels, int ndelrels, bool isRedo)
Definition md.c:1612
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
#define RESUME_INTERRUPTS()
Definition miscadmin.h:138
#define START_CRIT_SECTION()
Definition miscadmin.h:152
#define HOLD_INTERRUPTS()
Definition miscadmin.h:136
#define END_CRIT_SECTION()
Definition miscadmin.h:154
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition miscinit.c:613
Oid GetUserId(void)
Definition miscinit.c:470
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition miscinit.c:620
void PostPrepare_MultiXact(FullTransactionId fxid)
Definition multixact.c:1670
void AtPrepare_MultiXact(void)
Definition multixact.c:1656
void AtEOXact_MultiXact(void)
Definition multixact.c:1628
void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition namespace.c:4630
void AtEOXact_Namespace(bool isCommit, bool parallel)
Definition namespace.c:4584
static char * errmsg
ReplOriginXactState replorigin_xact_state
Definition origin.c:168
void replorigin_advance(ReplOriginId node, XLogRecPtr remote_commit, XLogRecPtr local_commit, bool go_backward, bool wal_log)
Definition origin.c:928
void replorigin_session_advance(XLogRecPtr remote_commit, XLogRecPtr local_commit)
Definition origin.c:1335
#define DoNotReplicateId
Definition origin.h:34
#define InvalidReplOriginId
Definition origin.h:33
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
void AtEOXact_Enum(void)
Definition pg_enum.c:739
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[DEFAULT_XLOG_SEG_SIZE]
void AtPrepare_PgStat(void)
void pgstat_execute_transactional_drops(int ndrops, struct xl_xact_stats_item *items, bool is_redo)
void AtEOXact_PgStat(bool isCommit, bool parallel)
Definition pgstat_xact.c:40
void PostPrepare_PgStat(void)
int pgstat_get_transactional_drops(bool isCommit, xl_xact_stats_item **items)
void AtEOSubXact_PgStat(bool isCommit, int nestDepth)
#define qsort(a, b, c, d)
Definition port.h:495
void AtAbort_Portals(void)
Definition portalmem.c:782
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition portalmem.c:981
bool PreCommit_Portals(bool isPrepare)
Definition portalmem.c:678
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
void PreCommit_CheckForSerializationFailure(void)
Definition predicate.c:4633
void PostPrepare_PredicateLocks(FullTransactionId fxid)
Definition predicate.c:4789
void AtPrepare_PredicateLocks(void)
Definition predicate.c:4720
void RegisterPredicateLockingXid(TransactionId xid)
Definition predicate.c:1889
static int fb(int x)
#define DELAY_CHKPT_IN_COMMIT
Definition proc.h:141
#define PGPROC_MAX_CACHED_SUBXIDS
Definition proc.h:43
void XidCacheRemoveRunningXids(TransactionId xid, int nxids, const TransactionId *xids, TransactionId latestXid)
Definition procarray.c:4011
void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
Definition procarray.c:663
void RecordKnownAssignedTransactionIds(TransactionId xid)
Definition procarray.c:4456
void ProcArrayClearTransaction(PGPROC *proc)
Definition procarray.c:899
void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)
Definition procarray.c:1309
void ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids, TransactionId *subxids, TransactionId max_xid)
Definition procarray.c:4525
void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition relcache.c:3368
void AtEOXact_RelationCache(bool isCommit)
Definition relcache.c:3216
void AtPrepare_RelationMap(void)
Definition relmapper.c:589
void AtEOXact_RelationMap(bool isCommit, bool isParallelWorker)
Definition relmapper.c:542
void AtCCI_RelationMap(void)
Definition relmapper.c:505
ResourceOwner TopTransactionResourceOwner
Definition resowner.c:175
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition resowner.c:418
ResourceOwner CurrentResourceOwner
Definition resowner.c:173
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition resowner.c:655
void ResourceOwnerDelete(ResourceOwner owner)
Definition resowner.c:868
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:1048
Size mul_size(Size s1, Size s2)
Definition shmem.c:1063
LocalTransactionId GetNextLocalTransactionId(void)
Definition sinvaladt.c:703
void AtEOXact_SMgr(void)
Definition smgr.c:1017
void SnapBuildResetExportedSnapshotState(void)
Definition snapbuild.c:644
void AtSubAbort_Snapshot(int level)
Definition snapmgr.c:982
void AtEOXact_Snapshot(bool isCommit, bool resetXmin)
Definition snapmgr.c:1016
void AtSubCommit_Snapshot(int level)
Definition snapmgr.c:961
bool XactHasExportedSnapshots(void)
Definition snapmgr.c:1574
void SnapshotSetCommandId(CommandId curcid)
Definition snapmgr.c:490
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:71
int TransactionTimeout
Definition proc.c:66
void LockErrorCleanup(void)
Definition proc.c:818
bool stack_is_too_deep(void)
void StandbyReleaseLockTree(TransactionId xid, int nsubxids, TransactionId *subxids)
Definition standby.c:1094
void LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInitFileInval)
Definition standby.c:1493
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
LocalTransactionId lxid
Definition proc.h:231
ProcNumber procNumber
Definition proc.h:226
struct PGPROC::@136 vxid
int delayChkptFlags
Definition proc.h:260
ReplOriginId origin
Definition origin.h:45
XLogRecPtr origin_lsn
Definition origin.h:46
TimestampTz origin_timestamp
Definition origin.h:47
FullTransactionId currentFullTransactionId
Definition xact.c:234
FullTransactionId topFullTransactionId
Definition xact.c:233
CommandId currentCommandId
Definition xact.c:235
TransactionId parallelCurrentXids[FLEXIBLE_ARRAY_MEMBER]
Definition xact.c:237
struct SubXactCallbackItem * next
Definition xact.c:324
SubXactCallback callback
Definition xact.c:325
TransState state
Definition xact.c:201
SubTransactionId subTransactionId
Definition xact.c:198
FullTransactionId fullTransactionId
Definition xact.c:197
struct TransactionStateData * parent
Definition xact.c:220
MemoryContext priorContext
Definition xact.c:207
bool parallelChildXact
Definition xact.c:217
MemoryContext curTransactionContext
Definition xact.c:205
TBlockState blockState
Definition xact.c:202
bool prevXactReadOnly
Definition xact.c:213
TransactionId * childXids
Definition xact.c:208
bool startedInRecovery
Definition xact.c:214
ResourceOwner curTransactionOwner
Definition xact.c:206
LocalTransactionId localTransactionId
Definition lock.h:65
ProcNumber procNumber
Definition lock.h:64
XLogRecPtr EndRecPtr
Definition xlogreader.h:206
XLogRecPtr ReadRecPtr
Definition xlogreader.h:205
struct XactCallbackItem * next
Definition xact.c:312
void * arg
Definition xact.c:314
XactCallback callback
Definition xact.c:313
TransactionId xtop
Definition xact.h:221
void SubTransSetParent(TransactionId xid, TransactionId parent)
Definition subtrans.c:92
void SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
Definition syncrep.c:149
void AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
void PreCommit_on_commit_actions(void)
void AtEOXact_on_commit_actions(bool isCommit)
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
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:281
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
static TransactionId ReadNextTransactionId(void)
Definition transam.h:375
#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
static bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition transam.h:263
void AfterTriggerBeginXact(void)
Definition trigger.c:5106
void AfterTriggerEndSubXact(bool isCommit)
Definition trigger.c:5489
void AfterTriggerFireDeferred(void)
Definition trigger.c:5324
void AfterTriggerEndXact(bool isCommit)
Definition trigger.c:5387
void AfterTriggerBeginSubXact(void)
Definition trigger.c:5441
GlobalTransaction MarkAsPreparing(FullTransactionId fxid, const char *gid, TimestampTz prepared_at, Oid owner, Oid databaseid)
Definition twophase.c:365
void PrepareRedoAdd(FullTransactionId fxid, char *buf, XLogRecPtr start_lsn, XLogRecPtr end_lsn, ReplOriginId origin_id)
Definition twophase.c:2513
void AtAbort_Twophase(void)
Definition twophase.c:310
void PrepareRedoRemove(TransactionId xid, bool giveWarning)
Definition twophase.c:2670
void EndPrepare(GlobalTransaction gxact)
Definition twophase.c:1151
void StartPrepare(GlobalTransaction gxact)
Definition twophase.c:1058
void PostPrepare_Twophase(void)
Definition twophase.c:350
void AtEOXact_TypeCache(void)
Definition typcache.c:3217
void AtEOSubXact_TypeCache(void)
Definition typcache.c:3223
void AdvanceNextFullTransactionIdPastXid(TransactionId xid)
Definition varsup.c:299
FullTransactionId GetNewTransactionId(bool isSubXact)
Definition varsup.c:68
static void pgstat_report_wait_end(void)
Definition wait_event.h:83
const char * name
static bool CommitTransactionCommandInternal(void)
Definition xact.c:3225
bool IsTransactionOrTransactionBlock(void)
Definition xact.c:5040
void SerializeTransactionState(Size maxsize, char *start_address)
Definition xact.c:5591
void ExitParallelMode(void)
Definition xact.c:1094
static TimestampTz xactStartTimestamp
Definition xact.c:282
static bool currentCommandIdUsed
Definition xact.c:270
static void AtSubCommit_Memory(void)
Definition xact.c:1677
void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
Definition xact.c:3186
static void CleanupSubTransaction(void)
Definition xact.c:5434
void BeginInternalSubTransaction(const char *name)
Definition xact.c:4745
static void AtStart_Memory(void)
Definition xact.c:1206
FullTransactionId GetCurrentFullTransactionId(void)
Definition xact.c:514
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition xact.c:3194
static XactCallbackItem * Xact_callbacks
Definition xact.c:317
void WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
Definition xact.c:3761
static TimestampTz stmtStartTimestamp
Definition xact.c:283
SubTransactionId GetCurrentSubTransactionId(void)
Definition xact.c:793
int synchronous_commit
Definition xact.c:89
void UserAbortTransactionBlock(bool chain)
Definition xact.c:4255
bool IsInTransactionBlock(bool isTopLevel)
Definition xact.c:3820
bool PrepareTransactionBlock(const char *gid)
Definition xact.c:4043
static void AtSubCleanup_Memory(void)
Definition xact.c:2064
static void StartTransaction(void)
Definition xact.c:2106
int GetCurrentTransactionNestLevel(void)
Definition xact.c:931
void xact_redo(XLogReaderState *record)
Definition xact.c:6414
TransactionId GetTopTransactionId(void)
Definition xact.c:428
static void AtSubCommit_childXids(void)
Definition xact.c:1706
static void CallSubXactCallbacks(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition xact.c:3949
void EnterParallelMode(void)
Definition xact.c:1081
static void AtAbort_ResourceOwner(void)
Definition xact.c:1958
TransactionId GetStableLatestTransactionId(void)
Definition xact.c:609
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition xact.c:3776
void UnregisterSubXactCallback(SubXactCallback callback, void *arg)
Definition xact.c:3928
bool XactDeferrable
Definition xact.c:87
static bool forceSyncCommit
Definition xact.c:295
void BeginImplicitTransactionBlock(void)
Definition xact.c:4377
static void CallXactCallbacks(XactEvent event)
Definition xact.c:3889
static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS]
Definition xact.c:260
void RequireTransactionBlock(bool isTopLevel, const char *stmtType)
Definition xact.c:3767
static void AtSubAbort_Memory(void)
Definition xact.c:1946
static SubXactCallbackItem * SubXact_callbacks
Definition xact.c:329
void DefineSavepoint(const char *name)
Definition xact.c:4424
bool DefaultXactDeferrable
Definition xact.c:86
static void CleanupTransaction(void)
Definition xact.c:3059
static int nUnreportedXids
Definition xact.c:259
static const char * TransStateAsString(TransState state)
Definition xact.c:5811
static TimestampTz xactStopTimestamp
Definition xact.c:284
bool TransactionStartedDuringRecovery(void)
Definition xact.c:1044
static void CommitSubTransaction(void)
Definition xact.c:5155
bool XactReadOnly
Definition xact.c:84
static void PushTransaction(void)
Definition xact.c:5467
bool bsysscan
Definition xact.c:102
TransactionId CheckXidAlive
Definition xact.c:101
static TransactionId RecordTransactionCommit(void)
Definition xact.c:1345
static char * prepareGID
Definition xact.c:290
void UnregisterXactCallback(XactCallback callback, void *arg)
Definition xact.c:3868
bool IsTransactionState(void)
Definition xact.c:389
static MemoryContext TransactionAbortContext
Definition xact.c:305
void CommandCounterIncrement(void)
Definition xact.c:1130
TransState
Definition xact.c:144
@ TRANS_INPROGRESS
Definition xact.c:147
@ TRANS_START
Definition xact.c:146
@ TRANS_COMMIT
Definition xact.c:148
@ TRANS_ABORT
Definition xact.c:149
@ TRANS_DEFAULT
Definition xact.c:145
@ TRANS_PREPARE
Definition xact.c:150
void PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
Definition xact.c:3698
static void AtCleanup_Memory(void)
Definition xact.c:2016
Size EstimateTransactionStateSpace(void)
Definition xact.c:5563
TransactionStateData * TransactionState
Definition xact.c:223
static void AtSubAbort_childXids(void)
Definition xact.c:1984
TransactionId GetTopTransactionIdIfAny(void)
Definition xact.c:443
static bool AbortCurrentTransactionInternal(void)
Definition xact.c:3519
static SubTransactionId currentSubTransactionId
Definition xact.c:268
static void AssignTransactionId(TransactionState s)
Definition xact.c:637
char TransactionBlockStatusCode(void)
Definition xact.c:5054
void RollbackAndReleaseCurrentSubTransaction(void)
Definition xact.c:4847
static int nParallelCurrentXids
Definition xact.c:128
FullTransactionId GetCurrentFullTransactionIdIfAny(void)
Definition xact.c:532
static void CommitTransaction(void)
Definition xact.c:2270
void StartTransactionCommand(void)
Definition xact.c:3109
static void PopTransaction(void)
Definition xact.c:5529
bool IsAbortedTransactionBlockState(void)
Definition xact.c:409
void ReleaseCurrentSubTransaction(void)
Definition xact.c:4819
void EndImplicitTransactionBlock(void)
Definition xact.c:4402
void StartParallelWorkerTransaction(char *tstatespace)
Definition xact.c:5662
void SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts)
Definition xact.c:861
static void AtSubAbort_ResourceOwner(void)
Definition xact.c:1971
void ReleaseSavepoint(const char *name)
Definition xact.c:4509
static TransactionStateData TopTransactionStateData
Definition xact.c:249
static FullTransactionId XactTopFullTransactionId
Definition xact.c:127
static void ShowTransactionState(const char *str)
Definition xact.c:5699
int XactIsoLevel
Definition xact.c:81
static void PrepareTransaction(void)
Definition xact.c:2558
FullTransactionId GetTopFullTransactionId(void)
Definition xact.c:485
static CommandId currentCommandId
Definition xact.c:269
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:5865
void ForceSyncCommit(void)
Definition xact.c:1182
int GetTopReadOnlyTransactionNestLevel(void)
Definition xact.c:1062
static TransactionId RecordTransactionAbort(bool isSubXact)
Definition xact.c:1796
static void AtCommit_Memory(void)
Definition xact.c:1640
static void AbortSubTransaction(void)
Definition xact.c:5270
bool IsSubTransaction(void)
Definition xact.c:5095
void MarkSubxactTopXidLogged(void)
Definition xact.c:593
void SetCurrentStatementStartTimestamp(void)
Definition xact.c:916
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition xact.c:943
static void xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid, XLogRecPtr lsn, ReplOriginId origin_id)
Definition xact.c:6335
bool IsTransactionBlock(void)
Definition xact.c:5022
bool IsInParallelMode(void)
Definition xact.c:1119
int xactGetCommittedChildren(TransactionId **ptr)
Definition xact.c:5841
TransactionId GetCurrentTransactionIdIfAny(void)
Definition xact.c:473
void BeginTransactionBlock(void)
Definition xact.c:3975
static void AtStart_ResourceOwner(void)
Definition xact.c:1256
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition xact.c:881
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition xact.c:872
static const char * BlockStateAsString(TBlockState blockState)
Definition xact.c:5758
void EndParallelWorkerTransaction(void)
Definition xact.c:5687
static void AtAbort_Memory(void)
Definition xact.c:1926
void RegisterXactCallback(XactCallback callback, void *arg)
Definition xact.c:3855
void CommitTransactionCommand(void)
Definition xact.c:3207
void RollbackToSavepoint(const char *name)
Definition xact.c:4618
bool SubTransactionIsActive(SubTransactionId subxid)
Definition xact.c:807
TBlockState
Definition xact.c:160
@ TBLOCK_DEFAULT
Definition xact.c:162
@ TBLOCK_SUBABORT_END
Definition xact.c:182
@ TBLOCK_STARTED
Definition xact.c:163
@ TBLOCK_SUBCOMMIT
Definition xact.c:180
@ TBLOCK_IMPLICIT_INPROGRESS
Definition xact.c:168
@ TBLOCK_ABORT_END
Definition xact.c:172
@ TBLOCK_PREPARE
Definition xact.c:174
@ TBLOCK_ABORT_PENDING
Definition xact.c:173
@ TBLOCK_ABORT
Definition xact.c:171
@ TBLOCK_SUBRELEASE
Definition xact.c:179
@ TBLOCK_SUBBEGIN
Definition xact.c:177
@ TBLOCK_SUBABORT
Definition xact.c:181
@ TBLOCK_SUBRESTART
Definition xact.c:184
@ TBLOCK_INPROGRESS
Definition xact.c:167
@ TBLOCK_END
Definition xact.c:170
@ TBLOCK_PARALLEL_INPROGRESS
Definition xact.c:169
@ TBLOCK_SUBABORT_RESTART
Definition xact.c:185
@ TBLOCK_SUBABORT_PENDING
Definition xact.c:183
@ TBLOCK_BEGIN
Definition xact.c:166
@ TBLOCK_SUBINPROGRESS
Definition xact.c:178
void RegisterSubXactCallback(SubXactCallback callback, void *arg)
Definition xact.c:3915
FullTransactionId GetTopFullTransactionIdIfAny(void)
Definition xact.c:501
TransactionId GetCurrentTransactionId(void)
Definition xact.c:456
static void AbortTransaction(void)
Definition xact.c:2853
static void AtStart_Cache(void)
Definition xact.c:1197
static void AtSubStart_ResourceOwner(void)
Definition xact.c:1313
int DefaultXactIsoLevel
Definition xact.c:80
static void AtSubStart_Memory(void)
Definition xact.c:1284
bool xact_is_sampled
Definition xact.c:298
bool EndTransactionBlock(bool chain)
Definition xact.c:4095
bool IsSubxactTopXidLogPending(void)
Definition xact.c:561
#define SerializedTransactionStateHeaderSize
Definition xact.c:241
void AbortOutOfAnyTransaction(void)
Definition xact.c:4913
int MyXactFlags
Definition xact.c:138
static void ShowTransactionStateRec(const char *str, TransactionState s)
Definition xact.c:5711
static TransactionState CurrentTransactionState
Definition xact.c:262
void AbortCurrentTransaction(void)
Definition xact.c:3501
static void StartSubTransaction(void)
Definition xact.c:5118
static TransactionId * ParallelCurrentXids
Definition xact.c:129
bool DefaultXactReadOnly
Definition xact.c:83
TimestampTz GetCurrentTransactionStopTimestamp(void)
Definition xact.c:893
static void AtCCI_LocalCache(void)
Definition xact.c:1621
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:6037
void MarkCurrentTransactionIdLoggedIfAny(void)
Definition xact.c:543
static void xact_redo_commit(xl_xact_parsed_commit *parsed, TransactionId xid, XLogRecPtr lsn, ReplOriginId origin_id)
Definition xact.c:6181
CommandId GetCurrentCommandId(bool used)
Definition xact.c:831
#define XactCompletionForceSyncCommit(xinfo)
Definition xact.h:216
#define MinSizeOfXactInvals
Definition xact.h:308
void(* SubXactCallback)(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg)
Definition xact.h:149
#define MinSizeOfXactSubxacts
Definition xact.h:267
#define XLOG_XACT_COMMIT_PREPARED
Definition xact.h:173
#define XLOG_XACT_INVALIDATIONS
Definition xact.h:176
#define XACT_COMPLETION_UPDATE_RELCACHE_FILE
Definition xact.h:208
SubXactEvent
Definition xact.h:142
@ SUBXACT_EVENT_PRE_COMMIT_SUB
Definition xact.h:146
@ SUBXACT_EVENT_START_SUB
Definition xact.h:143
@ SUBXACT_EVENT_ABORT_SUB
Definition xact.h:145
@ SUBXACT_EVENT_COMMIT_SUB
Definition xact.h:144
void(* XactCallback)(XactEvent event, void *arg)
Definition xact.h:139
#define XACT_XINFO_HAS_GID
Definition xact.h:196
#define XACT_COMPLETION_FORCE_SYNC_COMMIT
Definition xact.h:209
#define XACT_XINFO_HAS_ORIGIN
Definition xact.h:194
@ SYNCHRONOUS_COMMIT_REMOTE_APPLY
Definition xact.h:76
@ SYNCHRONOUS_COMMIT_OFF
Definition xact.h:71
#define XLOG_XACT_PREPARE
Definition xact.h:171
XactEvent
Definition xact.h:128
@ XACT_EVENT_PRE_PREPARE
Definition xact.h:136
@ XACT_EVENT_COMMIT
Definition xact.h:129
@ XACT_EVENT_PARALLEL_PRE_COMMIT
Definition xact.h:135
@ XACT_EVENT_PARALLEL_COMMIT
Definition xact.h:130
@ XACT_EVENT_ABORT
Definition xact.h:131
@ XACT_EVENT_PRE_COMMIT
Definition xact.h:134
@ XACT_EVENT_PARALLEL_ABORT
Definition xact.h:132
@ XACT_EVENT_PREPARE
Definition xact.h:133
#define SYNCHRONOUS_COMMIT_ON
Definition xact.h:81
#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK
Definition xact.h:109
#define XACT_XINFO_HAS_TWOPHASE
Definition xact.h:193
#define XLOG_XACT_COMMIT
Definition xact.h:170
#define XLOG_XACT_OPMASK
Definition xact.h:180
#define MinSizeOfXactRelfileLocators
Definition xact.h:274
#define XLOG_XACT_ABORT
Definition xact.h:172
#define MinSizeOfXactStatsItems
Definition xact.h:301
#define XACT_XINFO_HAS_RELFILELOCATORS
Definition xact.h:191
#define MinSizeOfXactAbort
Definition xact.h:351
#define XACT_COMPLETION_APPLY_FEEDBACK
Definition xact.h:207
#define MinSizeOfXactAssignment
Definition xact.h:226
#define XACT_XINFO_HAS_DBINFO
Definition xact.h:189
#define XACT_FLAGS_NEEDIMMEDIATECOMMIT
Definition xact.h:115
#define XactCompletionApplyFeedback(xinfo)
Definition xact.h:212
#define XLOG_XACT_ASSIGNMENT
Definition xact.h:175
#define XACT_XINFO_HAS_INVALS
Definition xact.h:192
#define XLOG_XACT_ABORT_PREPARED
Definition xact.h:174
#define XACT_XINFO_HAS_AE_LOCKS
Definition xact.h:195
#define XLOG_XACT_HAS_INFO
Definition xact.h:183
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE
Definition xact.h:103
#define XactCompletionRelcacheInitFileInval(xinfo)
Definition xact.h:214
#define XACT_READ_COMMITTED
Definition xact.h:37
#define XACT_XINFO_HAS_SUBXACTS
Definition xact.h:190
#define XACT_XINFO_HAS_DROPPED_STATS
Definition xact.h:197
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:6830
XLogRecPtr XactLastRecEnd
Definition xlog.c:261
XLogRecPtr XactLastCommitEnd
Definition xlog.c:262
void XLogFlush(XLogRecPtr record)
Definition xlog.c:2801
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition xlog.c:2630
#define XLogLogicalInfoActive()
Definition xlog.h:137
#define XLOG_INCLUDE_ORIGIN
Definition xlog.h:166
#define XLogStandbyInfoActive()
Definition xlog.h:126
uint16 ReplOriginId
Definition xlogdefs.h:69
uint64 XLogRecPtr
Definition xlogdefs.h:21
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition xloginsert.c:482
void XLogRegisterData(const void *data, uint32 len)
Definition xloginsert.c:372
void XLogSetRecordFlags(uint8 flags)
Definition xloginsert.c:464
void XLogResetInsertion(void)
Definition xloginsert.c:226
void XLogBeginInsert(void)
Definition xloginsert.c:153
#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
void WaitLSNCleanup(void)
Definition xlogwait.c:341