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);
2517 AtEOXact_RI(true);
2519 AtEOXact_Snapshot(true, false);
2524
2529
2531
2534 s->nestingLevel = 0;
2535 s->gucNestLevel = 0;
2536 s->childXids = NULL;
2537 s->nChildXids = 0;
2538 s->maxChildXids = 0;
2539
2542
2543 /*
2544 * done with commit processing, set current transaction state back to
2545 * default
2546 */
2547 s->state = TRANS_DEFAULT;
2548
2550}
2551
2552
2553/*
2554 * PrepareTransaction
2555 *
2556 * NB: if you change this routine, better look at CommitTransaction too!
2557 */
2558static void
2560{
2564 TimestampTz prepared_at;
2565
2567
2568 ShowTransactionState("PrepareTransaction");
2569
2570 /*
2571 * check the current transaction state
2572 */
2573 if (s->state != TRANS_INPROGRESS)
2574 elog(WARNING, "PrepareTransaction while in %s state",
2576 Assert(s->parent == NULL);
2577
2578 /*
2579 * Do pre-commit processing that involves calling user-defined code, such
2580 * as triggers. Since closing cursors could queue trigger actions,
2581 * triggers could open cursors, etc, we have to keep looping until there's
2582 * nothing left to do.
2583 */
2584 for (;;)
2585 {
2586 /*
2587 * Fire all currently pending deferred triggers.
2588 */
2590
2591 /*
2592 * Close open portals (converting holdable ones into static portals).
2593 * If there weren't any, we are done ... otherwise loop back to check
2594 * if they queued deferred triggers. Lather, rinse, repeat.
2595 */
2596 if (!PreCommit_Portals(true))
2597 break;
2598 }
2599
2601
2602 /*
2603 * The remaining actions cannot call any user-defined code, so it's safe
2604 * to start shutting down within-transaction services. But note that most
2605 * of this stuff could still throw an error, which would switch us into
2606 * the transaction-abort path.
2607 */
2608
2609 /* Shut down the deferred-trigger manager */
2610 AfterTriggerEndXact(true);
2611
2612 /*
2613 * Let ON COMMIT management do its thing (must happen after closing
2614 * cursors, to avoid dangling-reference problems)
2615 */
2617
2618 /*
2619 * Synchronize files that are created and not WAL-logged during this
2620 * transaction. This must happen before EndPrepare(), so that we don't see
2621 * committed-but-broken files after a crash and COMMIT PREPARED.
2622 */
2623 smgrDoPendingSyncs(true, false);
2624
2625 /* close large objects before lower-level cleanup */
2627
2628 /* NOTIFY requires no work at this point */
2629
2630 /*
2631 * Mark serializable transaction as complete for predicate locking
2632 * purposes. This should be done as late as we can put it and still allow
2633 * errors to be raised for failure patterns found at commit.
2634 */
2636
2637 /*
2638 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2639 * this transaction. Having the prepared xact hold locks on another
2640 * backend's temp table seems a bad idea --- for instance it would prevent
2641 * the backend from exiting. There are other problems too, such as how to
2642 * clean up the source backend's local buffers and ON COMMIT state if the
2643 * prepared xact includes a DROP of a temp table.
2644 *
2645 * Other objects types, like functions, operators or extensions, share the
2646 * same restriction as they should not be created, locked or dropped as
2647 * this can mess up with this session or even a follow-up session trying
2648 * to use the same temporary namespace.
2649 *
2650 * We must check this after executing any ON COMMIT actions, because they
2651 * might still access a temp relation.
2652 *
2653 * XXX In principle this could be relaxed to allow some useful special
2654 * cases, such as a temp table created and dropped all within the
2655 * transaction. That seems to require much more bookkeeping though.
2656 */
2658 ereport(ERROR,
2660 errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2661
2662 /*
2663 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2664 * supported if we added cleanup logic to twophase.c, but for now it
2665 * doesn't seem worth the trouble.
2666 */
2668 ereport(ERROR,
2670 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2671
2672 /* Prevent cancel/die interrupt while cleaning up */
2674
2675 /*
2676 * set the current transaction state information appropriately during
2677 * prepare processing
2678 */
2679 s->state = TRANS_PREPARE;
2680
2681 /* Disable transaction timeout */
2682 if (TransactionTimeout > 0)
2684
2685 prepared_at = GetCurrentTimestamp();
2686
2687 /*
2688 * Reserve the GID for this transaction. This could fail if the requested
2689 * GID is invalid or already in use.
2690 */
2691 gxact = MarkAsPreparing(fxid, prepareGID, prepared_at,
2693 prepareGID = NULL;
2694
2695 /*
2696 * Collect data for the 2PC state file. Note that in general, no actual
2697 * state change should happen in the called modules during this step,
2698 * since it's still possible to fail before commit, and in that case we
2699 * want transaction abort to be able to clean up. (In particular, the
2700 * AtPrepare routines may error out if they find cases they cannot
2701 * handle.) State cleanup should happen in the PostPrepare routines
2702 * below. However, some modules can go ahead and clear state here because
2703 * they wouldn't do anything with it during abort anyway.
2704 *
2705 * Note: because the 2PC state file records will be replayed in the same
2706 * order they are made, the order of these calls has to match the order in
2707 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2708 * PREPARED; in particular, pay attention to whether things should happen
2709 * before or after releasing the transaction's locks.
2710 */
2712
2719
2720 /*
2721 * Here is where we really truly prepare.
2722 *
2723 * We have to record transaction prepares even if we didn't make any
2724 * updates, because the transaction manager might get confused if we lose
2725 * a global transaction.
2726 */
2728
2729 /*
2730 * Now we clean up backend-internal state and release internal resources.
2731 */
2732
2733 /* Reset XactLastRecEnd until the next transaction writes something */
2734 XactLastRecEnd = 0;
2735
2736 /*
2737 * Transfer our locks to a dummy PGPROC. This has to be done before
2738 * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2739 * conclude "xact already committed or aborted" for our locks.
2740 */
2741 PostPrepare_Locks(fxid);
2742
2743 /*
2744 * Let others know about no transaction in progress by me. This has to be
2745 * done *after* the prepared transaction has been marked valid, else
2746 * someone may think it is unlocked and recyclable.
2747 */
2749
2750 /*
2751 * In normal commit-processing, this is all non-critical post-transaction
2752 * cleanup. When the transaction is prepared, however, it's important
2753 * that the locks and other per-backend resources are transferred to the
2754 * prepared transaction's PGPROC entry. Note that if an error is raised
2755 * here, it's too late to abort the transaction. XXX: This probably should
2756 * be in a critical section, to force a PANIC if any of this fails, but
2757 * that cure could be worse than the disease.
2758 */
2759
2761
2764 true, true);
2765
2766 AtEOXact_Aio(true);
2767
2768 /* Check we've released all buffer pins */
2769 AtEOXact_Buffers(true);
2770
2771 /* Clean up the relation cache */
2773
2774 /* Clean up the type cache */
2776
2777 /* notify doesn't need a postprepare call */
2778
2780
2782
2784
2786
2788
2791 true, true);
2794 true, true);
2795
2796 /*
2797 * Allow another backend to finish the transaction. After
2798 * PostPrepare_Twophase(), the transaction is completely detached from our
2799 * backend. The rest is just non-critical cleanup of backend-local state.
2800 */
2802
2803 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2804 AtEOXact_GUC(true, 1);
2805 AtEOXact_SPI(true);
2806 AtEOXact_Enum();
2808 AtEOXact_Namespace(true, false);
2809 AtEOXact_SMgr();
2810 AtEOXact_Files(true);
2812 AtEOXact_HashTables(true);
2813 AtEOXact_RI(true);
2814 /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2815 AtEOXact_Snapshot(true, true);
2816 /* we treat PREPARE as ROLLBACK so far as waking workers goes */
2821
2827
2829
2832 s->nestingLevel = 0;
2833 s->gucNestLevel = 0;
2834 s->childXids = NULL;
2835 s->nChildXids = 0;
2836 s->maxChildXids = 0;
2837
2840
2841 /*
2842 * done with 1st phase commit processing, set current transaction state
2843 * back to default
2844 */
2845 s->state = TRANS_DEFAULT;
2846
2848}
2849
2850
2851/*
2852 * AbortTransaction
2853 */
2854static void
2856{
2859 bool is_parallel_worker;
2860
2861 /* Prevent cancel/die interrupt while cleaning up */
2863
2864 /* Disable transaction timeout */
2865 if (TransactionTimeout > 0)
2867
2868 /* Make sure we have a valid memory context and resource owner */
2871
2872 /*
2873 * Release any LW locks we might be holding as quickly as possible.
2874 * (Regular locks, however, must be held till we finish aborting.)
2875 * Releasing LW locks is critical since we might try to grab them again
2876 * while cleaning up!
2877 */
2879
2880 /*
2881 * Cleanup waiting for LSN if any.
2882 */
2884
2885 /* Clear wait information and command progress indicator */
2888
2890
2891 /* Clean up buffer content locks, too */
2892 UnlockBuffers();
2893
2894 /* Reset WAL record construction state */
2896
2897 /* Cancel condition variable sleep */
2899
2900 /*
2901 * Also clean up any open wait for lock, since the lock manager will choke
2902 * if we try to wait for another lock before doing this.
2903 */
2905
2906 /*
2907 * If any timeout events are still active, make sure the timeout interrupt
2908 * is scheduled. This covers possible loss of a timeout interrupt due to
2909 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2910 * We delay this till after LockErrorCleanup so that we don't uselessly
2911 * reschedule lock or deadlock check timeouts.
2912 */
2914
2915 /*
2916 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2917 * handler. We do this fairly early in the sequence so that the timeout
2918 * infrastructure will be functional if needed while aborting.
2919 */
2921
2922 /*
2923 * check the current transaction state
2924 */
2926 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2927 elog(WARNING, "AbortTransaction while in %s state",
2929 Assert(s->parent == NULL);
2930
2931 /*
2932 * set the current transaction state information appropriately during the
2933 * abort processing
2934 */
2935 s->state = TRANS_ABORT;
2936
2937 /*
2938 * Reset user ID which might have been changed transiently. We need this
2939 * to clean up in case control escaped out of a SECURITY DEFINER function
2940 * or other local change of CurrentUserId; therefore, the prior value of
2941 * SecurityRestrictionContext also needs to be restored.
2942 *
2943 * (Note: it is not necessary to restore session authorization or role
2944 * settings here because those can only be changed via GUC, and GUC will
2945 * take care of rolling them back if need be.)
2946 */
2948
2949 /* Forget about any active REINDEX. */
2951
2952 /* Reset logical streaming state. */
2954
2955 /* Reset snapshot export state. */
2957
2958 /*
2959 * If this xact has started any unfinished parallel operation, clean up
2960 * its workers and exit parallel mode. Don't warn about leaked resources.
2961 */
2962 AtEOXact_Parallel(false);
2963 s->parallelModeLevel = 0;
2964 s->parallelChildXact = false; /* should be false already */
2965
2966 /*
2967 * do abort processing
2968 */
2969 AfterTriggerEndXact(false); /* 'false' means it's abort */
2972 AtEOXact_LargeObject(false);
2976
2977 /*
2978 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2979 * far as assigning an XID to advertise). But if we're inside a parallel
2980 * worker, skip this; the user backend must be the one to write the abort
2981 * record.
2982 */
2983 if (!is_parallel_worker)
2985 else
2986 {
2988
2989 /*
2990 * Since the parallel leader won't get our value of XactLastRecEnd in
2991 * this case, we nudge WAL-writer ourselves in this case. See related
2992 * comments in RecordTransactionAbort for why this matters.
2993 */
2995 }
2996
2998
2999 /*
3000 * Let others know about no transaction in progress by me. Note that this
3001 * must be done _before_ releasing locks we hold and _after_
3002 * RecordTransactionAbort.
3003 */
3005
3006 /*
3007 * Post-abort cleanup. See notes in CommitTransaction() concerning
3008 * ordering. We can skip all of it if the transaction failed before
3009 * creating a resource owner.
3010 */
3012 {
3015 else
3017
3020 false, true);
3021 AtEOXact_Aio(false);
3022 AtEOXact_Buffers(false);
3025 AtEOXact_Inval(false);
3029 false, true);
3032 false, true);
3033 smgrDoPendingDeletes(false);
3034
3035 AtEOXact_GUC(false, 1);
3036 AtEOXact_SPI(false);
3037 AtEOXact_Enum();
3040 AtEOXact_SMgr();
3041 AtEOXact_Files(false);
3043 AtEOXact_HashTables(false);
3044 AtEOXact_RI(false);
3050 }
3051
3052 /*
3053 * State remains TRANS_ABORT until CleanupTransaction().
3054 */
3056}
3057
3058/*
3059 * CleanupTransaction
3060 */
3061static void
3063{
3065
3066 /*
3067 * State should still be TRANS_ABORT from AbortTransaction().
3068 */
3069 if (s->state != TRANS_ABORT)
3070 elog(FATAL, "CleanupTransaction: unexpected state %s",
3072
3073 /*
3074 * do abort cleanup processing
3075 */
3076 AtCleanup_Portals(); /* now safe to release portal memory */
3077 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
3078
3079 CurrentResourceOwner = NULL; /* and resource owner */
3085
3086 AtCleanup_Memory(); /* and transaction memory */
3087
3090 s->nestingLevel = 0;
3091 s->gucNestLevel = 0;
3092 s->childXids = NULL;
3093 s->nChildXids = 0;
3094 s->maxChildXids = 0;
3095 s->parallelModeLevel = 0;
3096 s->parallelChildXact = false;
3097
3100
3101 /*
3102 * done with abort processing, set current transaction state back to
3103 * default
3104 */
3105 s->state = TRANS_DEFAULT;
3106}
3107
3108/*
3109 * StartTransactionCommand
3110 */
3111void
3113{
3115
3116 switch (s->blockState)
3117 {
3118 /*
3119 * if we aren't in a transaction block, we just do our usual start
3120 * transaction.
3121 */
3122 case TBLOCK_DEFAULT:
3125 break;
3126
3127 /*
3128 * We are somewhere in a transaction block or subtransaction and
3129 * about to start a new command. For now we do nothing, but
3130 * someday we may do command-local resource initialization. (Note
3131 * that any needed CommandCounterIncrement was done by the
3132 * previous CommitTransactionCommand.)
3133 */
3134 case TBLOCK_INPROGRESS:
3137 break;
3138
3139 /*
3140 * Here we are in a failed transaction block (one of the commands
3141 * caused an abort) so we do nothing but remain in the abort
3142 * state. Eventually we will get a ROLLBACK command which will
3143 * get us out of this state. (It is up to other code to ensure
3144 * that no commands other than ROLLBACK will be processed in these
3145 * states.)
3146 */
3147 case TBLOCK_ABORT:
3148 case TBLOCK_SUBABORT:
3149 break;
3150
3151 /* These cases are invalid. */
3152 case TBLOCK_STARTED:
3153 case TBLOCK_BEGIN:
3155 case TBLOCK_SUBBEGIN:
3156 case TBLOCK_END:
3157 case TBLOCK_SUBRELEASE:
3158 case TBLOCK_SUBCOMMIT:
3159 case TBLOCK_ABORT_END:
3163 case TBLOCK_SUBRESTART:
3165 case TBLOCK_PREPARE:
3166 elog(ERROR, "StartTransactionCommand: unexpected state %s",
3168 break;
3169 }
3170
3171 /*
3172 * We must switch to CurTransactionContext before returning. This is
3173 * already done if we called StartTransaction, otherwise not.
3174 */
3177}
3178
3179
3180/*
3181 * Simple system for saving and restoring transaction characteristics
3182 * (isolation level, read only, deferrable). We need this for transaction
3183 * chaining, so that we can set the characteristics of the new transaction to
3184 * be the same as the previous one. (We need something like this because the
3185 * GUC system resets the characteristics at transaction end, so for example
3186 * just skipping the reset in StartTransaction() won't work.)
3187 */
3188void
3195
3196void
3203
3204/*
3205 * CommitTransactionCommand -- a wrapper function handling the
3206 * loop over subtransactions to avoid a potentially dangerous recursion
3207 * in CommitTransactionCommandInternal().
3208 */
3209void
3211{
3212 /*
3213 * Repeatedly call CommitTransactionCommandInternal() until all the work
3214 * is done.
3215 */
3217 {
3218 }
3219}
3220
3221/*
3222 * CommitTransactionCommandInternal - a function doing an iteration of work
3223 * regarding handling the commit transaction command. In the case of
3224 * subtransactions more than one iterations could be required. Returns
3225 * true when no more iterations required, false otherwise.
3226 */
3227static bool
3229{
3232
3233 /* Must save in case we need to restore below */
3235
3236 switch (s->blockState)
3237 {
3238 /*
3239 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3240 * StartTransactionCommand didn't set the STARTED state
3241 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3242 * by EndParallelWorkerTransaction(), not this function.
3243 */
3244 case TBLOCK_DEFAULT:
3246 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3248 break;
3249
3250 /*
3251 * If we aren't in a transaction block, just do our usual
3252 * transaction commit, and return to the idle state.
3253 */
3254 case TBLOCK_STARTED:
3257 break;
3258
3259 /*
3260 * We are completing a "BEGIN TRANSACTION" command, so we change
3261 * to the "transaction block in progress" state and return. (We
3262 * assume the BEGIN did nothing to the database, so we need no
3263 * CommandCounterIncrement.)
3264 */
3265 case TBLOCK_BEGIN:
3267 break;
3268
3269 /*
3270 * This is the case when we have finished executing a command
3271 * someplace within a transaction block. We increment the command
3272 * counter and return.
3273 */
3274 case TBLOCK_INPROGRESS:
3278 break;
3279
3280 /*
3281 * We are completing a "COMMIT" command. Do it and return to the
3282 * idle state.
3283 */
3284 case TBLOCK_END:
3287 if (s->chain)
3288 {
3291 s->chain = false;
3293 }
3294 break;
3295
3296 /*
3297 * Here we are in the middle of a transaction block but one of the
3298 * commands caused an abort so we do nothing but remain in the
3299 * abort state. Eventually we will get a ROLLBACK command.
3300 */
3301 case TBLOCK_ABORT:
3302 case TBLOCK_SUBABORT:
3303 break;
3304
3305 /*
3306 * Here we were in an aborted transaction block and we just got
3307 * the ROLLBACK command from the user, so clean up the
3308 * already-aborted transaction and return to the idle state.
3309 */
3310 case TBLOCK_ABORT_END:
3313 if (s->chain)
3314 {
3317 s->chain = false;
3319 }
3320 break;
3321
3322 /*
3323 * Here we were in a perfectly good transaction block but the user
3324 * told us to ROLLBACK anyway. We have to abort the transaction
3325 * and then clean up.
3326 */
3331 if (s->chain)
3332 {
3335 s->chain = false;
3337 }
3338 break;
3339
3340 /*
3341 * We are completing a "PREPARE TRANSACTION" command. Do it and
3342 * return to the idle state.
3343 */
3344 case TBLOCK_PREPARE:
3347 break;
3348
3349 /*
3350 * The user issued a SAVEPOINT inside a transaction block. Start a
3351 * subtransaction. (DefineSavepoint already did PushTransaction,
3352 * so as to have someplace to put the SUBBEGIN state.)
3353 */
3354 case TBLOCK_SUBBEGIN:
3357 break;
3358
3359 /*
3360 * The user issued a RELEASE command, so we end the current
3361 * subtransaction and return to the parent transaction. The parent
3362 * might be ended too, so repeat till we find an INPROGRESS
3363 * transaction or subtransaction.
3364 */
3365 case TBLOCK_SUBRELEASE:
3366 do
3367 {
3369 s = CurrentTransactionState; /* changed by pop */
3370 } while (s->blockState == TBLOCK_SUBRELEASE);
3371
3374 break;
3375
3376 /*
3377 * The user issued a COMMIT, so we end the current subtransaction
3378 * hierarchy and perform final commit. We do this by rolling up
3379 * any subtransactions into their parent, which leads to O(N^2)
3380 * operations with respect to resource owners - this isn't that
3381 * bad until we approach a thousands of savepoints but is
3382 * necessary for correctness should after triggers create new
3383 * resource owners.
3384 */
3385 case TBLOCK_SUBCOMMIT:
3386 do
3387 {
3389 s = CurrentTransactionState; /* changed by pop */
3390 } while (s->blockState == TBLOCK_SUBCOMMIT);
3391 /* If we had a COMMIT command, finish off the main xact too */
3392 if (s->blockState == TBLOCK_END)
3393 {
3394 Assert(s->parent == NULL);
3397 if (s->chain)
3398 {
3401 s->chain = false;
3403 }
3404 }
3405 else if (s->blockState == TBLOCK_PREPARE)
3406 {
3407 Assert(s->parent == NULL);
3410 }
3411 else
3412 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3414 break;
3415
3416 /*
3417 * The current already-failed subtransaction is ending due to a
3418 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3419 * examine the parent (which could be in any of several states).
3420 * As we need to examine the parent, return false to request the
3421 * caller to do the next iteration.
3422 */
3425 return false;
3426
3427 /*
3428 * As above, but it's not dead yet, so abort first.
3429 */
3433 return false;
3434
3435 /*
3436 * The current subtransaction is the target of a ROLLBACK TO
3437 * command. Abort and pop it, then start a new subtransaction
3438 * with the same name.
3439 */
3440 case TBLOCK_SUBRESTART:
3441 {
3442 char *name;
3443 int savepointLevel;
3444
3445 /* save name and keep Cleanup from freeing it */
3446 name = s->name;
3447 s->name = NULL;
3448 savepointLevel = s->savepointLevel;
3449
3452
3454 s = CurrentTransactionState; /* changed by push */
3455 s->name = name;
3456 s->savepointLevel = savepointLevel;
3457
3458 /* This is the same as TBLOCK_SUBBEGIN case */
3462 }
3463 break;
3464
3465 /*
3466 * Same as above, but the subtransaction had already failed, so we
3467 * don't need AbortSubTransaction.
3468 */
3470 {
3471 char *name;
3472 int savepointLevel;
3473
3474 /* save name and keep Cleanup from freeing it */
3475 name = s->name;
3476 s->name = NULL;
3477 savepointLevel = s->savepointLevel;
3478
3480
3482 s = CurrentTransactionState; /* changed by push */
3483 s->name = name;
3484 s->savepointLevel = savepointLevel;
3485
3486 /* This is the same as TBLOCK_SUBBEGIN case */
3490 }
3491 break;
3492 }
3493
3494 /* Done, no more iterations required */
3495 return true;
3496}
3497
3498/*
3499 * AbortCurrentTransaction -- a wrapper function handling the
3500 * loop over subtransactions to avoid potentially dangerous recursion in
3501 * AbortCurrentTransactionInternal().
3502 */
3503void
3505{
3506 /*
3507 * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3508 * done.
3509 */
3511 {
3512 }
3513}
3514
3515/*
3516 * AbortCurrentTransactionInternal - a function doing an iteration of work
3517 * regarding handling the current transaction abort. In the case of
3518 * subtransactions more than one iterations could be required. Returns
3519 * true when no more iterations required, false otherwise.
3520 */
3521static bool
3523{
3525
3526 switch (s->blockState)
3527 {
3528 case TBLOCK_DEFAULT:
3529 if (s->state == TRANS_DEFAULT)
3530 {
3531 /* we are idle, so nothing to do */
3532 }
3533 else
3534 {
3535 /*
3536 * We can get here after an error during transaction start
3537 * (state will be TRANS_START). Need to clean up the
3538 * incompletely started transaction. First, adjust the
3539 * low-level state to suppress warning message from
3540 * AbortTransaction.
3541 */
3542 if (s->state == TRANS_START)
3546 }
3547 break;
3548
3549 /*
3550 * If we aren't in a transaction block, we just do the basic abort
3551 * & cleanup transaction. For this purpose, we treat an implicit
3552 * transaction block as if it were a simple statement.
3553 */
3554 case TBLOCK_STARTED:
3559 break;
3560
3561 /*
3562 * If we are in TBLOCK_BEGIN it means something screwed up right
3563 * after reading "BEGIN TRANSACTION". We assume that the user
3564 * will interpret the error as meaning the BEGIN failed to get him
3565 * into a transaction block, so we should abort and return to idle
3566 * state.
3567 */
3568 case TBLOCK_BEGIN:
3572 break;
3573
3574 /*
3575 * We are somewhere in a transaction block and we've gotten a
3576 * failure, so we abort the transaction and set up the persistent
3577 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3578 */
3579 case TBLOCK_INPROGRESS:
3583 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3584 break;
3585
3586 /*
3587 * Here, we failed while trying to COMMIT. Clean up the
3588 * transaction and return to idle state (we do not want to stay in
3589 * the transaction).
3590 */
3591 case TBLOCK_END:
3595 break;
3596
3597 /*
3598 * Here, we are already in an aborted transaction state and are
3599 * waiting for a ROLLBACK, but for some reason we failed again! So
3600 * we just remain in the abort state.
3601 */
3602 case TBLOCK_ABORT:
3603 case TBLOCK_SUBABORT:
3604 break;
3605
3606 /*
3607 * We are in a failed transaction and we got the ROLLBACK command.
3608 * We have already aborted, we just need to cleanup and go to idle
3609 * state.
3610 */
3611 case TBLOCK_ABORT_END:
3614 break;
3615
3616 /*
3617 * We are in a live transaction and we got a ROLLBACK command.
3618 * Abort, cleanup, go to idle state.
3619 */
3624 break;
3625
3626 /*
3627 * Here, we failed while trying to PREPARE. Clean up the
3628 * transaction and return to idle state (we do not want to stay in
3629 * the transaction).
3630 */
3631 case TBLOCK_PREPARE:
3635 break;
3636
3637 /*
3638 * We got an error inside a subtransaction. Abort just the
3639 * subtransaction, and go to the persistent SUBABORT state until
3640 * we get ROLLBACK.
3641 */
3645 break;
3646
3647 /*
3648 * If we failed while trying to create a subtransaction, clean up
3649 * the broken subtransaction and abort the parent. The same
3650 * applies if we get a failure while ending a subtransaction. As
3651 * we need to abort the parent, return false to request the caller
3652 * to do the next iteration.
3653 */
3654 case TBLOCK_SUBBEGIN:
3655 case TBLOCK_SUBRELEASE:
3656 case TBLOCK_SUBCOMMIT:
3658 case TBLOCK_SUBRESTART:
3661 return false;
3662
3663 /*
3664 * Same as above, except the Abort() was already done.
3665 */
3669 return false;
3670 }
3671
3672 /* Done, no more iterations required */
3673 return true;
3674}
3675
3676/*
3677 * PreventInTransactionBlock
3678 *
3679 * This routine is to be called by statements that must not run inside
3680 * a transaction block, typically because they have non-rollback-able
3681 * side effects or do internal commits.
3682 *
3683 * If this routine completes successfully, then the calling statement is
3684 * guaranteed that if it completes without error, its results will be
3685 * committed immediately.
3686 *
3687 * If we have already started a transaction block, issue an error; also issue
3688 * an error if we appear to be running inside a user-defined function (which
3689 * could issue more commands and possibly cause a failure after the statement
3690 * completes). Subtransactions are verboten too.
3691 *
3692 * We must also set XACT_FLAGS_NEEDIMMEDIATECOMMIT in MyXactFlags, to ensure
3693 * that postgres.c follows through by committing after the statement is done.
3694 *
3695 * isTopLevel: passed down from ProcessUtility to determine whether we are
3696 * inside a function. (We will always fail if this is false, but it's
3697 * convenient to centralize the check here instead of making callers do it.)
3698 * stmtType: statement type name, for error messages.
3699 */
3700void
3701PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
3702{
3703 /*
3704 * xact block already started?
3705 */
3706 if (IsTransactionBlock())
3707 ereport(ERROR,
3709 /* translator: %s represents an SQL statement name */
3710 errmsg("%s cannot run inside a transaction block",
3711 stmtType)));
3712
3713 /*
3714 * subtransaction?
3715 */
3716 if (IsSubTransaction())
3717 ereport(ERROR,
3719 /* translator: %s represents an SQL statement name */
3720 errmsg("%s cannot run inside a subtransaction",
3721 stmtType)));
3722
3723 /*
3724 * inside a function call?
3725 */
3726 if (!isTopLevel)
3727 ereport(ERROR,
3729 /* translator: %s represents an SQL statement name */
3730 errmsg("%s cannot be executed from a function or procedure",
3731 stmtType)));
3732
3733 /* If we got past IsTransactionBlock test, should be in default state */
3736 elog(FATAL, "cannot prevent transaction chain");
3737
3738 /* All okay. Set the flag to make sure the right thing happens later. */
3740}
3741
3742/*
3743 * WarnNoTransactionBlock
3744 * RequireTransactionBlock
3745 *
3746 * These two functions allow for warnings or errors if a command is executed
3747 * outside of a transaction block. This is useful for commands that have no
3748 * effects that persist past transaction end (and so calling them outside a
3749 * transaction block is presumably an error). DECLARE CURSOR is an example.
3750 * While top-level transaction control commands (BEGIN/COMMIT/ABORT) and SET
3751 * that have no effect issue warnings, all other no-effect commands generate
3752 * errors.
3753 *
3754 * If we appear to be running inside a user-defined function, we do not
3755 * issue anything, since the function could issue more commands that make
3756 * use of the current statement's results. Likewise subtransactions.
3757 * Thus these are inverses for PreventInTransactionBlock.
3758 *
3759 * isTopLevel: passed down from ProcessUtility to determine whether we are
3760 * inside a function.
3761 * stmtType: statement type name, for warning or error messages.
3762 */
3763void
3764WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
3765{
3766 CheckTransactionBlock(isTopLevel, false, stmtType);
3767}
3768
3769void
3770RequireTransactionBlock(bool isTopLevel, const char *stmtType)
3771{
3772 CheckTransactionBlock(isTopLevel, true, stmtType);
3773}
3774
3775/*
3776 * This is the implementation of the above two.
3777 */
3778static void
3779CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
3780{
3781 /*
3782 * xact block already started?
3783 */
3784 if (IsTransactionBlock())
3785 return;
3786
3787 /*
3788 * subtransaction?
3789 */
3790 if (IsSubTransaction())
3791 return;
3792
3793 /*
3794 * inside a function call?
3795 */
3796 if (!isTopLevel)
3797 return;
3798
3801 /* translator: %s represents an SQL statement name */
3802 errmsg("%s can only be used in transaction blocks",
3803 stmtType)));
3804}
3805
3806/*
3807 * IsInTransactionBlock
3808 *
3809 * This routine is for statements that need to behave differently inside
3810 * a transaction block than when running as single commands. ANALYZE is
3811 * currently the only example.
3812 *
3813 * If this routine returns "false", then the calling statement is allowed
3814 * to perform internal transaction-commit-and-start cycles; there is not a
3815 * risk of messing up any transaction already in progress. (Note that this
3816 * is not the identical guarantee provided by PreventInTransactionBlock,
3817 * since we will not force a post-statement commit.)
3818 *
3819 * isTopLevel: passed down from ProcessUtility to determine whether we are
3820 * inside a function.
3821 */
3822bool
3824{
3825 /*
3826 * Return true on same conditions that would make
3827 * PreventInTransactionBlock error out
3828 */
3829 if (IsTransactionBlock())
3830 return true;
3831
3832 if (IsSubTransaction())
3833 return true;
3834
3835 if (!isTopLevel)
3836 return true;
3837
3840 return true;
3841
3842 return false;
3843}
3844
3845
3846/*
3847 * Register or deregister callback functions for start- and end-of-xact
3848 * operations.
3849 *
3850 * These functions are intended for use by dynamically loaded modules.
3851 * For built-in modules we generally just hardwire the appropriate calls
3852 * (mainly because it's easier to control the order that way, where needed).
3853 *
3854 * At transaction end, the callback occurs post-commit or post-abort, so the
3855 * callback functions can only do noncritical cleanup.
3856 */
3857void
3859{
3860 XactCallbackItem *item;
3861
3862 item = (XactCallbackItem *)
3864 item->callback = callback;
3865 item->arg = arg;
3866 item->next = Xact_callbacks;
3867 Xact_callbacks = item;
3868}
3869
3870void
3872{
3873 XactCallbackItem *item;
3874 XactCallbackItem *prev;
3875
3876 prev = NULL;
3877 for (item = Xact_callbacks; item; prev = item, item = item->next)
3878 {
3879 if (item->callback == callback && item->arg == arg)
3880 {
3881 if (prev)
3882 prev->next = item->next;
3883 else
3884 Xact_callbacks = item->next;
3885 pfree(item);
3886 break;
3887 }
3888 }
3889}
3890
3891static void
3893{
3894 XactCallbackItem *item;
3896
3897 for (item = Xact_callbacks; item; item = next)
3898 {
3899 /* allow callbacks to unregister themselves when called */
3900 next = item->next;
3901 item->callback(event, item->arg);
3902 }
3903}
3904
3905
3906/*
3907 * Register or deregister callback functions for start- and end-of-subxact
3908 * operations.
3909 *
3910 * Pretty much same as above, but for subtransaction events.
3911 *
3912 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3913 * so the callback functions can only do noncritical cleanup. At
3914 * subtransaction start, the callback is called when the subtransaction has
3915 * finished initializing.
3916 */
3917void
3919{
3920 SubXactCallbackItem *item;
3921
3922 item = (SubXactCallbackItem *)
3924 item->callback = callback;
3925 item->arg = arg;
3926 item->next = SubXact_callbacks;
3927 SubXact_callbacks = item;
3928}
3929
3930void
3932{
3933 SubXactCallbackItem *item;
3934 SubXactCallbackItem *prev;
3935
3936 prev = NULL;
3937 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3938 {
3939 if (item->callback == callback && item->arg == arg)
3940 {
3941 if (prev)
3942 prev->next = item->next;
3943 else
3944 SubXact_callbacks = item->next;
3945 pfree(item);
3946 break;
3947 }
3948 }
3949}
3950
3951static void
3955{
3956 SubXactCallbackItem *item;
3958
3959 for (item = SubXact_callbacks; item; item = next)
3960 {
3961 /* allow callbacks to unregister themselves when called */
3962 next = item->next;
3963 item->callback(event, mySubid, parentSubid, item->arg);
3964 }
3965}
3966
3967
3968/* ----------------------------------------------------------------
3969 * transaction block support
3970 * ----------------------------------------------------------------
3971 */
3972
3973/*
3974 * BeginTransactionBlock
3975 * This executes a BEGIN command.
3976 */
3977void
3979{
3981
3982 switch (s->blockState)
3983 {
3984 /*
3985 * We are not inside a transaction block, so allow one to begin.
3986 */
3987 case TBLOCK_STARTED:
3989 break;
3990
3991 /*
3992 * BEGIN converts an implicit transaction block to a regular one.
3993 * (Note that we allow this even if we've already done some
3994 * commands, which is a bit odd but matches historical practice.)
3995 */
3998 break;
3999
4000 /*
4001 * Already a transaction block in progress.
4002 */
4003 case TBLOCK_INPROGRESS:
4006 case TBLOCK_ABORT:
4007 case TBLOCK_SUBABORT:
4010 errmsg("there is already a transaction in progress")));
4011 break;
4012
4013 /* These cases are invalid. */
4014 case TBLOCK_DEFAULT:
4015 case TBLOCK_BEGIN:
4016 case TBLOCK_SUBBEGIN:
4017 case TBLOCK_END:
4018 case TBLOCK_SUBRELEASE:
4019 case TBLOCK_SUBCOMMIT:
4020 case TBLOCK_ABORT_END:
4024 case TBLOCK_SUBRESTART:
4026 case TBLOCK_PREPARE:
4027 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
4029 break;
4030 }
4031}
4032
4033/*
4034 * PrepareTransactionBlock
4035 * This executes a PREPARE command.
4036 *
4037 * Since PREPARE may actually do a ROLLBACK, the result indicates what
4038 * happened: true for PREPARE, false for ROLLBACK.
4039 *
4040 * Note that we don't actually do anything here except change blockState.
4041 * The real work will be done in the upcoming PrepareTransaction().
4042 * We do it this way because it's not convenient to change memory context,
4043 * resource owner, etc while executing inside a Portal.
4044 */
4045bool
4047{
4049 bool result;
4050
4051 /* Set up to commit the current transaction */
4052 result = EndTransactionBlock(false);
4053
4054 /* If successful, change outer tblock state to PREPARE */
4055 if (result)
4056 {
4058
4059 while (s->parent != NULL)
4060 s = s->parent;
4061
4062 if (s->blockState == TBLOCK_END)
4063 {
4064 /* Save GID where PrepareTransaction can find it again */
4066
4068 }
4069 else
4070 {
4071 /*
4072 * ignore case where we are not in a transaction;
4073 * EndTransactionBlock already issued a warning.
4074 */
4077 /* Don't send back a PREPARE result tag... */
4078 result = false;
4079 }
4080 }
4081
4082 return result;
4083}
4084
4085/*
4086 * EndTransactionBlock
4087 * This executes a COMMIT command.
4088 *
4089 * Since COMMIT may actually do a ROLLBACK, the result indicates what
4090 * happened: true for COMMIT, false for ROLLBACK.
4091 *
4092 * Note that we don't actually do anything here except change blockState.
4093 * The real work will be done in the upcoming CommitTransactionCommand().
4094 * We do it this way because it's not convenient to change memory context,
4095 * resource owner, etc while executing inside a Portal.
4096 */
4097bool
4099{
4101 bool result = false;
4102
4103 switch (s->blockState)
4104 {
4105 /*
4106 * We are in a transaction block, so tell CommitTransactionCommand
4107 * to COMMIT.
4108 */
4109 case TBLOCK_INPROGRESS:
4111 result = true;
4112 break;
4113
4114 /*
4115 * We are in an implicit transaction block. If AND CHAIN was
4116 * specified, error. Otherwise commit, but issue a warning
4117 * because there was no explicit BEGIN before this.
4118 */
4120 if (chain)
4121 ereport(ERROR,
4123 /* translator: %s represents an SQL statement name */
4124 errmsg("%s can only be used in transaction blocks",
4125 "COMMIT AND CHAIN")));
4126 else
4129 errmsg("there is no transaction in progress")));
4131 result = true;
4132 break;
4133
4134 /*
4135 * We are in a failed transaction block. Tell
4136 * CommitTransactionCommand it's time to exit the block.
4137 */
4138 case TBLOCK_ABORT:
4140 break;
4141
4142 /*
4143 * We are in a live subtransaction block. Set up to subcommit all
4144 * open subtransactions and then commit the main transaction.
4145 */
4147 while (s->parent != NULL)
4148 {
4151 else
4152 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4154 s = s->parent;
4155 }
4156 if (s->blockState == TBLOCK_INPROGRESS)
4158 else
4159 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4161 result = true;
4162 break;
4163
4164 /*
4165 * Here we are inside an aborted subtransaction. Treat the COMMIT
4166 * as ROLLBACK: set up to abort everything and exit the main
4167 * transaction.
4168 */
4169 case TBLOCK_SUBABORT:
4170 while (s->parent != NULL)
4171 {
4174 else if (s->blockState == TBLOCK_SUBABORT)
4176 else
4177 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4179 s = s->parent;
4180 }
4181 if (s->blockState == TBLOCK_INPROGRESS)
4183 else if (s->blockState == TBLOCK_ABORT)
4185 else
4186 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4188 break;
4189
4190 /*
4191 * The user issued COMMIT when not inside a transaction. For
4192 * COMMIT without CHAIN, issue a WARNING, staying in
4193 * TBLOCK_STARTED state. The upcoming call to
4194 * CommitTransactionCommand() will then close the transaction and
4195 * put us back into the default state. For COMMIT AND CHAIN,
4196 * error.
4197 */
4198 case TBLOCK_STARTED:
4199 if (chain)
4200 ereport(ERROR,
4202 /* translator: %s represents an SQL statement name */
4203 errmsg("%s can only be used in transaction blocks",
4204 "COMMIT AND CHAIN")));
4205 else
4208 errmsg("there is no transaction in progress")));
4209 result = true;
4210 break;
4211
4212 /*
4213 * The user issued a COMMIT that somehow ran inside a parallel
4214 * worker. We can't cope with that.
4215 */
4217 ereport(FATAL,
4219 errmsg("cannot commit during a parallel operation")));
4220 break;
4221
4222 /* These cases are invalid. */
4223 case TBLOCK_DEFAULT:
4224 case TBLOCK_BEGIN:
4225 case TBLOCK_SUBBEGIN:
4226 case TBLOCK_END:
4227 case TBLOCK_SUBRELEASE:
4228 case TBLOCK_SUBCOMMIT:
4229 case TBLOCK_ABORT_END:
4233 case TBLOCK_SUBRESTART:
4235 case TBLOCK_PREPARE:
4236 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4238 break;
4239 }
4240
4242 s->blockState == TBLOCK_END ||
4245
4246 s->chain = chain;
4247
4248 return result;
4249}
4250
4251/*
4252 * UserAbortTransactionBlock
4253 * This executes a ROLLBACK command.
4254 *
4255 * As above, we don't actually do anything here except change blockState.
4256 */
4257void
4259{
4261
4262 switch (s->blockState)
4263 {
4264 /*
4265 * We are inside a transaction block and we got a ROLLBACK command
4266 * from the user, so tell CommitTransactionCommand to abort and
4267 * exit the transaction block.
4268 */
4269 case TBLOCK_INPROGRESS:
4271 break;
4272
4273 /*
4274 * We are inside a failed transaction block and we got a ROLLBACK
4275 * command from the user. Abort processing is already done, so
4276 * CommitTransactionCommand just has to cleanup and go back to
4277 * idle state.
4278 */
4279 case TBLOCK_ABORT:
4281 break;
4282
4283 /*
4284 * We are inside a subtransaction. Mark everything up to top
4285 * level as exitable.
4286 */
4288 case TBLOCK_SUBABORT:
4289 while (s->parent != NULL)
4290 {
4293 else if (s->blockState == TBLOCK_SUBABORT)
4295 else
4296 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4298 s = s->parent;
4299 }
4300 if (s->blockState == TBLOCK_INPROGRESS)
4302 else if (s->blockState == TBLOCK_ABORT)
4304 else
4305 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4307 break;
4308
4309 /*
4310 * The user issued ABORT when not inside a transaction. For
4311 * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4312 * The upcoming call to CommitTransactionCommand() will then put
4313 * us back into the default state. For ROLLBACK AND CHAIN, error.
4314 *
4315 * We do the same thing with ABORT inside an implicit transaction,
4316 * although in this case we might be rolling back actual database
4317 * state changes. (It's debatable whether we should issue a
4318 * WARNING in this case, but we have done so historically.)
4319 */
4320 case TBLOCK_STARTED:
4322 if (chain)
4323 ereport(ERROR,
4325 /* translator: %s represents an SQL statement name */
4326 errmsg("%s can only be used in transaction blocks",
4327 "ROLLBACK AND CHAIN")));
4328 else
4331 errmsg("there is no transaction in progress")));
4333 break;
4334
4335 /*
4336 * The user issued an ABORT that somehow ran inside a parallel
4337 * worker. We can't cope with that.
4338 */
4340 ereport(FATAL,
4342 errmsg("cannot abort during a parallel operation")));
4343 break;
4344
4345 /* These cases are invalid. */
4346 case TBLOCK_DEFAULT:
4347 case TBLOCK_BEGIN:
4348 case TBLOCK_SUBBEGIN:
4349 case TBLOCK_END:
4350 case TBLOCK_SUBRELEASE:
4351 case TBLOCK_SUBCOMMIT:
4352 case TBLOCK_ABORT_END:
4356 case TBLOCK_SUBRESTART:
4358 case TBLOCK_PREPARE:
4359 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4361 break;
4362 }
4363
4366
4367 s->chain = chain;
4368}
4369
4370/*
4371 * BeginImplicitTransactionBlock
4372 * Start an implicit transaction block if we're not already in one.
4373 *
4374 * Unlike BeginTransactionBlock, this is called directly from the main loop
4375 * in postgres.c, not within a Portal. So we can just change blockState
4376 * without a lot of ceremony. We do not expect caller to do
4377 * CommitTransactionCommand/StartTransactionCommand.
4378 */
4379void
4381{
4383
4384 /*
4385 * If we are in STARTED state (that is, no transaction block is open),
4386 * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4387 * block.
4388 *
4389 * For caller convenience, we consider all other transaction states as
4390 * legal here; otherwise the caller would need its own state check, which
4391 * seems rather pointless.
4392 */
4393 if (s->blockState == TBLOCK_STARTED)
4395}
4396
4397/*
4398 * EndImplicitTransactionBlock
4399 * End an implicit transaction block, if we're in one.
4400 *
4401 * Like EndTransactionBlock, we just make any needed blockState change here.
4402 * The real work will be done in the upcoming CommitTransactionCommand().
4403 */
4404void
4406{
4408
4409 /*
4410 * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4411 * allowing CommitTransactionCommand to commit whatever happened during
4412 * the implicit transaction block as though it were a single statement.
4413 *
4414 * For caller convenience, we consider all other transaction states as
4415 * legal here; otherwise the caller would need its own state check, which
4416 * seems rather pointless.
4417 */
4420}
4421
4422/*
4423 * DefineSavepoint
4424 * This executes a SAVEPOINT command.
4425 */
4426void
4428{
4430
4431 /*
4432 * Workers synchronize transaction state at the beginning of each parallel
4433 * operation, so we can't account for new subtransactions after that
4434 * point. (Note that this check will certainly error out if s->blockState
4435 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4436 * below.)
4437 */
4439 ereport(ERROR,
4441 errmsg("cannot define savepoints during a parallel operation")));
4442
4443 switch (s->blockState)
4444 {
4445 case TBLOCK_INPROGRESS:
4447 /* Normal subtransaction start */
4449 s = CurrentTransactionState; /* changed by push */
4450
4451 /*
4452 * Savepoint names, like the TransactionState block itself, live
4453 * in TopTransactionContext.
4454 */
4455 if (name)
4457 break;
4458
4459 /*
4460 * We disallow savepoint commands in implicit transaction blocks.
4461 * There would be no great difficulty in allowing them so far as
4462 * this module is concerned, but a savepoint seems inconsistent
4463 * with exec_simple_query's behavior of abandoning the whole query
4464 * string upon error. Also, the point of an implicit transaction
4465 * block (as opposed to a regular one) is to automatically close
4466 * after an error, so it's hard to see how a savepoint would fit
4467 * into that.
4468 *
4469 * The error messages for this are phrased as if there were no
4470 * active transaction block at all, which is historical but
4471 * perhaps could be improved.
4472 */
4474 ereport(ERROR,
4476 /* translator: %s represents an SQL statement name */
4477 errmsg("%s can only be used in transaction blocks",
4478 "SAVEPOINT")));
4479 break;
4480
4481 /* These cases are invalid. */
4482 case TBLOCK_DEFAULT:
4483 case TBLOCK_STARTED:
4484 case TBLOCK_BEGIN:
4486 case TBLOCK_SUBBEGIN:
4487 case TBLOCK_END:
4488 case TBLOCK_SUBRELEASE:
4489 case TBLOCK_SUBCOMMIT:
4490 case TBLOCK_ABORT:
4491 case TBLOCK_SUBABORT:
4492 case TBLOCK_ABORT_END:
4496 case TBLOCK_SUBRESTART:
4498 case TBLOCK_PREPARE:
4499 elog(FATAL, "DefineSavepoint: unexpected state %s",
4501 break;
4502 }
4503}
4504
4505/*
4506 * ReleaseSavepoint
4507 * This executes a RELEASE command.
4508 *
4509 * As above, we don't actually do anything here except change blockState.
4510 */
4511void
4513{
4515 TransactionState target,
4516 xact;
4517
4518 /*
4519 * Workers synchronize transaction state at the beginning of each parallel
4520 * operation, so we can't account for transaction state change after that
4521 * point. (Note that this check will certainly error out if s->blockState
4522 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4523 * below.)
4524 */
4526 ereport(ERROR,
4528 errmsg("cannot release savepoints during a parallel operation")));
4529
4530 switch (s->blockState)
4531 {
4532 /*
4533 * We can't release a savepoint if there is no savepoint defined.
4534 */
4535 case TBLOCK_INPROGRESS:
4536 ereport(ERROR,
4538 errmsg("savepoint \"%s\" does not exist", name)));
4539 break;
4540
4542 /* See comment about implicit transactions in DefineSavepoint */
4543 ereport(ERROR,
4545 /* translator: %s represents an SQL statement name */
4546 errmsg("%s can only be used in transaction blocks",
4547 "RELEASE SAVEPOINT")));
4548 break;
4549
4550 /*
4551 * We are in a non-aborted subtransaction. This is the only valid
4552 * case.
4553 */
4555 break;
4556
4557 /* These cases are invalid. */
4558 case TBLOCK_DEFAULT:
4559 case TBLOCK_STARTED:
4560 case TBLOCK_BEGIN:
4562 case TBLOCK_SUBBEGIN:
4563 case TBLOCK_END:
4564 case TBLOCK_SUBRELEASE:
4565 case TBLOCK_SUBCOMMIT:
4566 case TBLOCK_ABORT:
4567 case TBLOCK_SUBABORT:
4568 case TBLOCK_ABORT_END:
4572 case TBLOCK_SUBRESTART:
4574 case TBLOCK_PREPARE:
4575 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4577 break;
4578 }
4579
4580 for (target = s; target; target = target->parent)
4581 {
4582 if (target->name && strcmp(target->name, name) == 0)
4583 break;
4584 }
4585
4586 if (!target)
4587 ereport(ERROR,
4589 errmsg("savepoint \"%s\" does not exist", name)));
4590
4591 /* disallow crossing savepoint level boundaries */
4592 if (target->savepointLevel != s->savepointLevel)
4593 ereport(ERROR,
4595 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4596
4597 /*
4598 * Mark "commit pending" all subtransactions up to the target
4599 * subtransaction. The actual commits will happen when control gets to
4600 * CommitTransactionCommand.
4601 */
4603 for (;;)
4604 {
4605 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
4606 xact->blockState = TBLOCK_SUBRELEASE;
4607 if (xact == target)
4608 break;
4609 xact = xact->parent;
4610 Assert(xact);
4611 }
4612}
4613
4614/*
4615 * RollbackToSavepoint
4616 * This executes a ROLLBACK TO <savepoint> command.
4617 *
4618 * As above, we don't actually do anything here except change blockState.
4619 */
4620void
4622{
4624 TransactionState target,
4625 xact;
4626
4627 /*
4628 * Workers synchronize transaction state at the beginning of each parallel
4629 * operation, so we can't account for transaction state change after that
4630 * point. (Note that this check will certainly error out if s->blockState
4631 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4632 * below.)
4633 */
4635 ereport(ERROR,
4637 errmsg("cannot rollback to savepoints during a parallel operation")));
4638
4639 switch (s->blockState)
4640 {
4641 /*
4642 * We can't rollback to a savepoint if there is no savepoint
4643 * defined.
4644 */
4645 case TBLOCK_INPROGRESS:
4646 case TBLOCK_ABORT:
4647 ereport(ERROR,
4649 errmsg("savepoint \"%s\" does not exist", name)));
4650 break;
4651
4653 /* See comment about implicit transactions in DefineSavepoint */
4654 ereport(ERROR,
4656 /* translator: %s represents an SQL statement name */
4657 errmsg("%s can only be used in transaction blocks",
4658 "ROLLBACK TO SAVEPOINT")));
4659 break;
4660
4661 /*
4662 * There is at least one savepoint, so proceed.
4663 */
4665 case TBLOCK_SUBABORT:
4666 break;
4667
4668 /* These cases are invalid. */
4669 case TBLOCK_DEFAULT:
4670 case TBLOCK_STARTED:
4671 case TBLOCK_BEGIN:
4673 case TBLOCK_SUBBEGIN:
4674 case TBLOCK_END:
4675 case TBLOCK_SUBRELEASE:
4676 case TBLOCK_SUBCOMMIT:
4677 case TBLOCK_ABORT_END:
4681 case TBLOCK_SUBRESTART:
4683 case TBLOCK_PREPARE:
4684 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4686 break;
4687 }
4688
4689 for (target = s; target; target = target->parent)
4690 {
4691 if (target->name && strcmp(target->name, name) == 0)
4692 break;
4693 }
4694
4695 if (!target)
4696 ereport(ERROR,
4698 errmsg("savepoint \"%s\" does not exist", name)));
4699
4700 /* disallow crossing savepoint level boundaries */
4701 if (target->savepointLevel != s->savepointLevel)
4702 ereport(ERROR,
4704 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4705
4706 /*
4707 * Mark "abort pending" all subtransactions up to the target
4708 * subtransaction. The actual aborts will happen when control gets to
4709 * CommitTransactionCommand.
4710 */
4712 for (;;)
4713 {
4714 if (xact == target)
4715 break;
4716 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4718 else if (xact->blockState == TBLOCK_SUBABORT)
4719 xact->blockState = TBLOCK_SUBABORT_END;
4720 else
4721 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4722 BlockStateAsString(xact->blockState));
4723 xact = xact->parent;
4724 Assert(xact);
4725 }
4726
4727 /* And mark the target as "restart pending" */
4728 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4729 xact->blockState = TBLOCK_SUBRESTART;
4730 else if (xact->blockState == TBLOCK_SUBABORT)
4731 xact->blockState = TBLOCK_SUBABORT_RESTART;
4732 else
4733 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4734 BlockStateAsString(xact->blockState));
4735}
4736
4737/*
4738 * BeginInternalSubTransaction
4739 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
4740 * TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_END,
4741 * and TBLOCK_PREPARE states, and therefore it can safely be used in
4742 * functions that might be called when not inside a BEGIN block or when
4743 * running deferred triggers at COMMIT/PREPARE time. Also, it
4744 * automatically does CommitTransactionCommand/StartTransactionCommand
4745 * instead of expecting the caller to do it.
4746 */
4747void
4749{
4752
4753 /*
4754 * Errors within this function are improbable, but if one does happen we
4755 * force a FATAL exit. Callers generally aren't prepared to handle losing
4756 * control, and moreover our transaction state is probably corrupted if we
4757 * fail partway through; so an ordinary ERROR longjmp isn't okay.
4758 */
4759 ExitOnAnyError = true;
4760
4761 /*
4762 * We do not check for parallel mode here. It's permissible to start and
4763 * end "internal" subtransactions while in parallel mode, so long as no
4764 * new XIDs or command IDs are assigned. Enforcement of that occurs in
4765 * AssignTransactionId() and CommandCounterIncrement().
4766 */
4767
4768 switch (s->blockState)
4769 {
4770 case TBLOCK_STARTED:
4771 case TBLOCK_INPROGRESS:
4774 case TBLOCK_END:
4775 case TBLOCK_PREPARE:
4777 /* Normal subtransaction start */
4779 s = CurrentTransactionState; /* changed by push */
4780
4781 /*
4782 * Savepoint names, like the TransactionState block itself, live
4783 * in TopTransactionContext.
4784 */
4785 if (name)
4787 break;
4788
4789 /* These cases are invalid. */
4790 case TBLOCK_DEFAULT:
4791 case TBLOCK_BEGIN:
4792 case TBLOCK_SUBBEGIN:
4793 case TBLOCK_SUBRELEASE:
4794 case TBLOCK_SUBCOMMIT:
4795 case TBLOCK_ABORT:
4796 case TBLOCK_SUBABORT:
4797 case TBLOCK_ABORT_END:
4801 case TBLOCK_SUBRESTART:
4803 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4805 break;
4806 }
4807
4810
4812}
4813
4814/*
4815 * ReleaseCurrentSubTransaction
4816 *
4817 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
4818 * savepoint name (if any).
4819 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4820 */
4821void
4823{
4825
4826 /*
4827 * We do not check for parallel mode here. It's permissible to start and
4828 * end "internal" subtransactions while in parallel mode, so long as no
4829 * new XIDs or command IDs are assigned.
4830 */
4831
4833 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4838 s = CurrentTransactionState; /* changed by pop */
4840}
4841
4842/*
4843 * RollbackAndReleaseCurrentSubTransaction
4844 *
4845 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
4846 * of its savepoint name (if any).
4847 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4848 */
4849void
4851{
4853
4854 /*
4855 * We do not check for parallel mode here. It's permissible to start and
4856 * end "internal" subtransactions while in parallel mode, so long as no
4857 * new XIDs or command IDs are assigned.
4858 */
4859
4860 switch (s->blockState)
4861 {
4862 /* Must be in a subtransaction */
4864 case TBLOCK_SUBABORT:
4865 break;
4866
4867 /* These cases are invalid. */
4868 case TBLOCK_DEFAULT:
4869 case TBLOCK_STARTED:
4870 case TBLOCK_BEGIN:
4873 case TBLOCK_SUBBEGIN:
4874 case TBLOCK_INPROGRESS:
4875 case TBLOCK_END:
4876 case TBLOCK_SUBRELEASE:
4877 case TBLOCK_SUBCOMMIT:
4878 case TBLOCK_ABORT:
4879 case TBLOCK_ABORT_END:
4883 case TBLOCK_SUBRESTART:
4885 case TBLOCK_PREPARE:
4886 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4888 break;
4889 }
4890
4891 /*
4892 * Abort the current subtransaction, if needed.
4893 */
4896
4897 /* And clean it up, too */
4899
4900 s = CurrentTransactionState; /* changed by pop */
4906}
4907
4908/*
4909 * AbortOutOfAnyTransaction
4910 *
4911 * This routine is provided for error recovery purposes. It aborts any
4912 * active transaction or transaction block, leaving the system in a known
4913 * idle state.
4914 */
4915void
4917{
4919
4920 /* Ensure we're not running in a doomed memory context */
4922
4923 /*
4924 * Get out of any transaction or nested transaction
4925 */
4926 do
4927 {
4928 switch (s->blockState)
4929 {
4930 case TBLOCK_DEFAULT:
4931 if (s->state == TRANS_DEFAULT)
4932 {
4933 /* Not in a transaction, do nothing */
4934 }
4935 else
4936 {
4937 /*
4938 * We can get here after an error during transaction start
4939 * (state will be TRANS_START). Need to clean up the
4940 * incompletely started transaction. First, adjust the
4941 * low-level state to suppress warning message from
4942 * AbortTransaction.
4943 */
4944 if (s->state == TRANS_START)
4948 }
4949 break;
4950 case TBLOCK_STARTED:
4951 case TBLOCK_BEGIN:
4952 case TBLOCK_INPROGRESS:
4955 case TBLOCK_END:
4957 case TBLOCK_PREPARE:
4958 /* In a transaction, so clean up */
4962 break;
4963 case TBLOCK_ABORT:
4964 case TBLOCK_ABORT_END:
4965
4966 /*
4967 * AbortTransaction is already done, still need Cleanup.
4968 * However, if we failed partway through running ROLLBACK,
4969 * there will be an active portal running that command, which
4970 * we need to shut down before doing CleanupTransaction.
4971 */
4975 break;
4976
4977 /*
4978 * In a subtransaction, so clean it up and abort parent too
4979 */
4980 case TBLOCK_SUBBEGIN:
4982 case TBLOCK_SUBRELEASE:
4983 case TBLOCK_SUBCOMMIT:
4985 case TBLOCK_SUBRESTART:
4988 s = CurrentTransactionState; /* changed by pop */
4989 break;
4990
4991 case TBLOCK_SUBABORT:
4994 /* As above, but AbortSubTransaction already done */
4995 if (s->curTransactionOwner)
4996 {
4997 /* As in TBLOCK_ABORT, might have a live portal to zap */
5002 }
5004 s = CurrentTransactionState; /* changed by pop */
5005 break;
5006 }
5007 } while (s->blockState != TBLOCK_DEFAULT);
5008
5009 /* Should be out of all subxacts now */
5010 Assert(s->parent == NULL);
5011
5012 /*
5013 * Revert to TopMemoryContext, to ensure we exit in a well-defined state
5014 * whether there were any transactions to close or not. (Callers that
5015 * don't intend to exit soon should switch to some other context to avoid
5016 * long-term memory leaks.)
5017 */
5019}
5020
5021/*
5022 * IsTransactionBlock --- are we within a transaction block?
5023 */
5024bool
5026{
5028
5030 return false;
5031
5032 return true;
5033}
5034
5035/*
5036 * IsTransactionOrTransactionBlock --- are we within either a transaction
5037 * or a transaction block? (The backend is only really "idle" when this
5038 * returns false.)
5039 *
5040 * This should match up with IsTransactionBlock and IsTransactionState.
5041 */
5042bool
5044{
5046
5047 if (s->blockState == TBLOCK_DEFAULT)
5048 return false;
5049
5050 return true;
5051}
5052
5053/*
5054 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
5055 */
5056char
5058{
5060
5061 switch (s->blockState)
5062 {
5063 case TBLOCK_DEFAULT:
5064 case TBLOCK_STARTED:
5065 return 'I'; /* idle --- not in transaction */
5066 case TBLOCK_BEGIN:
5067 case TBLOCK_SUBBEGIN:
5068 case TBLOCK_INPROGRESS:
5072 case TBLOCK_END:
5073 case TBLOCK_SUBRELEASE:
5074 case TBLOCK_SUBCOMMIT:
5075 case TBLOCK_PREPARE:
5076 return 'T'; /* in transaction */
5077 case TBLOCK_ABORT:
5078 case TBLOCK_SUBABORT:
5079 case TBLOCK_ABORT_END:
5083 case TBLOCK_SUBRESTART:
5085 return 'E'; /* in failed transaction */
5086 }
5087
5088 /* should never get here */
5089 elog(FATAL, "invalid transaction block state: %s",
5091 return 0; /* keep compiler quiet */
5092}
5093
5094/*
5095 * IsSubTransaction
5096 */
5097bool
5099{
5101
5102 if (s->nestingLevel >= 2)
5103 return true;
5104
5105 return false;
5106}
5107
5108/*
5109 * StartSubTransaction
5110 *
5111 * If you're wondering why this is separate from PushTransaction: it's because
5112 * we can't conveniently do this stuff right inside DefineSavepoint. The
5113 * SAVEPOINT utility command will be executed inside a Portal, and if we
5114 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
5115 * the Portal will undo those settings. So we make DefineSavepoint just
5116 * push a dummy transaction block, and when control returns to the main
5117 * idle loop, CommitTransactionCommand will be called, and we'll come here
5118 * to finish starting the subtransaction.
5119 */
5120static void
5122{
5124
5125 if (s->state != TRANS_DEFAULT)
5126 elog(WARNING, "StartSubTransaction while in %s state",
5128
5129 s->state = TRANS_START;
5130
5131 /*
5132 * Initialize subsystems for new subtransaction
5133 *
5134 * must initialize resource-management stuff first
5135 */
5139
5141
5142 /*
5143 * Call start-of-subxact callbacks
5144 */
5147
5148 ShowTransactionState("StartSubTransaction");
5149}
5150
5151/*
5152 * CommitSubTransaction
5153 *
5154 * The caller has to make sure to always reassign CurrentTransactionState
5155 * if it has a local pointer to it after calling this function.
5156 */
5157static void
5159{
5161
5162 ShowTransactionState("CommitSubTransaction");
5163
5164 if (s->state != TRANS_INPROGRESS)
5165 elog(WARNING, "CommitSubTransaction while in %s state",
5167
5168 /* Pre-commit processing goes here */
5169
5172
5173 /*
5174 * If this subxact has started any unfinished parallel operation, clean up
5175 * its workers and exit parallel mode. Warn about leaked resources.
5176 */
5178 if (s->parallelModeLevel != 0)
5179 {
5180 elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5182 s->parallelModeLevel = 0;
5183 }
5184
5185 /* Do the actual "commit", such as it is */
5186 s->state = TRANS_COMMIT;
5187
5188 /* Must CCI to ensure commands of subtransaction are seen as done */
5190
5191 /*
5192 * Prior to 8.4 we marked subcommit in clog at this point. We now only
5193 * perform that step, if required, as part of the atomic update of the
5194 * whole transaction tree at top level commit or abort.
5195 */
5196
5197 /* Post-commit cleanup */
5203 s->parent->nestingLevel,
5208
5211
5214 true, false);
5218 AtEOSubXact_Inval(true);
5220
5221 /*
5222 * The only lock we actually release here is the subtransaction XID lock.
5223 */
5227
5228 /*
5229 * Other locks should get transferred to their parent resource owner.
5230 */
5233 true, false);
5236 true, false);
5237
5238 AtEOXact_GUC(true, s->gucNestLevel);
5249
5250 /*
5251 * We need to restore the upper transaction's read-only state, in case the
5252 * upper is read-write while the child is read-only; GUC will incorrectly
5253 * think it should leave the child state in place.
5254 */
5256
5261
5263
5264 s->state = TRANS_DEFAULT;
5265
5267}
5268
5269/*
5270 * AbortSubTransaction
5271 */
5272static void
5274{
5276
5277 /* Prevent cancel/die interrupt while cleaning up */
5279
5280 /* Make sure we have a valid memory context and resource owner */
5283
5284 /*
5285 * Release any LW locks we might be holding as quickly as possible.
5286 * (Regular locks, however, must be held till we finish aborting.)
5287 * Releasing LW locks is critical since we might try to grab them again
5288 * while cleaning up!
5289 *
5290 * FIXME This may be incorrect --- Are there some locks we should keep?
5291 * Buffer locks, for example? I don't think so but I'm not sure.
5292 */
5294
5295 /*
5296 * Cleanup waiting for LSN if any.
5297 */
5299
5302
5304
5305 UnlockBuffers();
5306
5307 /* Reset WAL record construction state */
5309
5310 /* Cancel condition variable sleep */
5312
5313 /*
5314 * Also clean up any open wait for lock, since the lock manager will choke
5315 * if we try to wait for another lock before doing this.
5316 */
5318
5319 /*
5320 * If any timeout events are still active, make sure the timeout interrupt
5321 * is scheduled. This covers possible loss of a timeout interrupt due to
5322 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5323 * We delay this till after LockErrorCleanup so that we don't uselessly
5324 * reschedule lock or deadlock check timeouts.
5325 */
5327
5328 /*
5329 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5330 * handler. We do this fairly early in the sequence so that the timeout
5331 * infrastructure will be functional if needed while aborting.
5332 */
5334
5335 /*
5336 * check the current transaction state
5337 */
5338 ShowTransactionState("AbortSubTransaction");
5339
5340 if (s->state != TRANS_INPROGRESS)
5341 elog(WARNING, "AbortSubTransaction while in %s state",
5343
5344 s->state = TRANS_ABORT;
5345
5346 /*
5347 * Reset user ID which might have been changed transiently. (See notes in
5348 * AbortTransaction.)
5349 */
5351
5352 /* Forget about any active REINDEX. */
5354
5355 /* Reset logical streaming state. */
5357
5358 /*
5359 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5360 * exports are not supported in subtransactions.
5361 */
5362
5363 /*
5364 * If this subxact has started any unfinished parallel operation, clean up
5365 * its workers and exit parallel mode. Don't warn about leaked resources.
5366 */
5368 s->parallelModeLevel = 0;
5369
5370 /*
5371 * We can skip all this stuff if the subxact failed before creating a
5372 * ResourceOwner...
5373 */
5374 if (s->curTransactionOwner)
5375 {
5384
5385 /* Advertise the fact that we aborted in pg_xact. */
5387
5388 /* Post-abort cleanup */
5391
5394
5397 false, false);
5398
5399 AtEOXact_Aio(false);
5403 AtEOSubXact_Inval(false);
5406 false, false);
5409 false, false);
5411
5412 AtEOXact_GUC(false, s->gucNestLevel);
5423 }
5424
5425 /*
5426 * Restore the upper transaction's read-only state, too. This should be
5427 * redundant with GUC's cleanup but we may as well do it for consistency
5428 * with the commit case.
5429 */
5431
5433}
5434
5435/*
5436 * CleanupSubTransaction
5437 *
5438 * The caller has to make sure to always reassign CurrentTransactionState
5439 * if it has a local pointer to it after calling this function.
5440 */
5441static void
5443{
5445
5446 ShowTransactionState("CleanupSubTransaction");
5447
5448 if (s->state != TRANS_ABORT)
5449 elog(WARNING, "CleanupSubTransaction while in %s state",
5451
5453
5456 if (s->curTransactionOwner)
5459
5461
5462 s->state = TRANS_DEFAULT;
5463
5465}
5466
5467/*
5468 * PushTransaction
5469 * Create transaction state stack entry for a subtransaction
5470 *
5471 * The caller has to make sure to always reassign CurrentTransactionState
5472 * if it has a local pointer to it after calling this function.
5473 */
5474static void
5476{
5479
5480 /*
5481 * We keep subtransaction state nodes in TopTransactionContext.
5482 */
5483 s = (TransactionState)
5485 sizeof(TransactionStateData));
5486
5487 /*
5488 * Assign a subtransaction ID, watching out for counter wraparound.
5489 */
5492 {
5494 pfree(s);
5495 ereport(ERROR,
5497 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5498 }
5499
5500 /*
5501 * We can now stack a minimally valid subtransaction without fear of
5502 * failure.
5503 */
5504 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5506 s->parent = p;
5507 s->nestingLevel = p->nestingLevel + 1;
5510 s->state = TRANS_DEFAULT;
5515 s->parallelModeLevel = 0;
5517 s->topXidLogged = false;
5518
5520
5521 /*
5522 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5523 * with the subtransaction from here on out; in particular they should not
5524 * assume that it necessarily has a transaction context, resource owner,
5525 * or XID.
5526 */
5527}
5528
5529/*
5530 * PopTransaction
5531 * Pop back to parent transaction state
5532 *
5533 * The caller has to make sure to always reassign CurrentTransactionState
5534 * if it has a local pointer to it after calling this function.
5535 */
5536static void
5538{
5540
5541 if (s->state != TRANS_DEFAULT)
5542 elog(WARNING, "PopTransaction while in %s state",
5544
5545 if (s->parent == NULL)
5546 elog(FATAL, "PopTransaction with no parent");
5547
5549
5550 /* Let's just make sure CurTransactionContext is good */
5553
5554 /* Ditto for ResourceOwner links */
5557
5558 /* Free the old child structure */
5559 if (s->name)
5560 pfree(s->name);
5561 pfree(s);
5562}
5563
5564/*
5565 * EstimateTransactionStateSpace
5566 * Estimate the amount of space that will be needed by
5567 * SerializeTransactionState. It would be OK to overestimate slightly,
5568 * but it's simple for us to work out the precise value, so we do.
5569 */
5570Size
5572{
5574 Size nxids = 0;
5576
5577 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5578 {
5580 nxids = add_size(nxids, 1);
5582 }
5583
5584 return add_size(size, mul_size(sizeof(TransactionId), nxids));
5585}
5586
5587/*
5588 * SerializeTransactionState
5589 * Write out relevant details of our transaction state that will be
5590 * needed by a parallel worker.
5591 *
5592 * We need to save and restore XactDeferrable, XactIsoLevel, and the XIDs
5593 * associated with this transaction. These are serialized into a
5594 * caller-supplied buffer big enough to hold the number of bytes reported by
5595 * EstimateTransactionStateSpace(). We emit the XIDs in sorted order for the
5596 * convenience of the receiving process.
5597 */
5598void
5600{
5602 Size nxids = 0;
5603 Size i = 0;
5604 TransactionId *workspace;
5606
5608
5610 result->xactDeferrable = XactDeferrable;
5611 result->topFullTransactionId = XactTopFullTransactionId;
5612 result->currentFullTransactionId =
5614 result->currentCommandId = currentCommandId;
5615
5616 /*
5617 * If we're running in a parallel worker and launching a parallel worker
5618 * of our own, we can just pass along the information that was passed to
5619 * us.
5620 */
5621 if (nParallelCurrentXids > 0)
5622 {
5623 result->nParallelCurrentXids = nParallelCurrentXids;
5624 memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
5626 return;
5627 }
5628
5629 /*
5630 * OK, we need to generate a sorted list of XIDs that our workers should
5631 * view as current. First, figure out how many there are.
5632 */
5633 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5634 {
5636 nxids = add_size(nxids, 1);
5638 }
5640 <= maxsize);
5641
5642 /* Copy them to our scratch space. */
5643 workspace = palloc(nxids * sizeof(TransactionId));
5644 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5645 {
5647 workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5648 if (s->nChildXids > 0)
5649 memcpy(&workspace[i], s->childXids,
5650 s->nChildXids * sizeof(TransactionId));
5651 i += s->nChildXids;
5652 }
5653 Assert(i == nxids);
5654
5655 /* Sort them. */
5656 qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5657
5658 /* Copy data into output area. */
5659 result->nParallelCurrentXids = nxids;
5660 memcpy(&result->parallelCurrentXids[0], workspace,
5661 nxids * sizeof(TransactionId));
5662}
5663
5664/*
5665 * StartParallelWorkerTransaction
5666 * Start a parallel worker transaction, restoring the relevant
5667 * transaction state serialized by SerializeTransactionState.
5668 */
5669void
5671{
5673
5676
5678 XactIsoLevel = tstate->xactIsoLevel;
5679 XactDeferrable = tstate->xactDeferrable;
5680 XactTopFullTransactionId = tstate->topFullTransactionId;
5682 tstate->currentFullTransactionId;
5683 currentCommandId = tstate->currentCommandId;
5684 nParallelCurrentXids = tstate->nParallelCurrentXids;
5685 ParallelCurrentXids = &tstate->parallelCurrentXids[0];
5686
5688}
5689
5690/*
5691 * EndParallelWorkerTransaction
5692 * End a parallel worker transaction.
5693 */
5694void
5701
5702/*
5703 * ShowTransactionState
5704 * Debug support
5705 */
5706static void
5708{
5709 /* skip work if message will definitely not be printed */
5712}
5713
5714/*
5715 * ShowTransactionStateRec
5716 * Recursive subroutine for ShowTransactionState
5717 */
5718static void
5720{
5722
5723 if (s->parent)
5724 {
5725 /*
5726 * Since this function recurses, it could be driven to stack overflow.
5727 * This is just a debugging aid, so we can leave out some details
5728 * instead of erroring out with check_stack_depth().
5729 */
5730 if (stack_is_too_deep())
5732 (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5733 str, s->nestingLevel)));
5734 else
5736 }
5737
5739 if (s->nChildXids > 0)
5740 {
5741 int i;
5742
5743 appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5744 for (i = 1; i < s->nChildXids; i++)
5745 appendStringInfo(&buf, " %u", s->childXids[i]);
5746 }
5748 (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5749 str, s->nestingLevel,
5750 s->name ? s->name : "unnamed",
5756 currentCommandIdUsed ? " (used)" : "",
5757 buf.data)));
5758 pfree(buf.data);
5759}
5760
5761/*
5762 * BlockStateAsString
5763 * Debug support
5764 */
5765static const char *
5767{
5768 switch (blockState)
5769 {
5770 case TBLOCK_DEFAULT:
5771 return "DEFAULT";
5772 case TBLOCK_STARTED:
5773 return "STARTED";
5774 case TBLOCK_BEGIN:
5775 return "BEGIN";
5776 case TBLOCK_INPROGRESS:
5777 return "INPROGRESS";
5779 return "IMPLICIT_INPROGRESS";
5781 return "PARALLEL_INPROGRESS";
5782 case TBLOCK_END:
5783 return "END";
5784 case TBLOCK_ABORT:
5785 return "ABORT";
5786 case TBLOCK_ABORT_END:
5787 return "ABORT_END";
5789 return "ABORT_PENDING";
5790 case TBLOCK_PREPARE:
5791 return "PREPARE";
5792 case TBLOCK_SUBBEGIN:
5793 return "SUBBEGIN";
5795 return "SUBINPROGRESS";
5796 case TBLOCK_SUBRELEASE:
5797 return "SUBRELEASE";
5798 case TBLOCK_SUBCOMMIT:
5799 return "SUBCOMMIT";
5800 case TBLOCK_SUBABORT:
5801 return "SUBABORT";
5803 return "SUBABORT_END";
5805 return "SUBABORT_PENDING";
5806 case TBLOCK_SUBRESTART:
5807 return "SUBRESTART";
5809 return "SUBABORT_RESTART";
5810 }
5811 return "UNRECOGNIZED";
5812}
5813
5814/*
5815 * TransStateAsString
5816 * Debug support
5817 */
5818static const char *
5820{
5821 switch (state)
5822 {
5823 case TRANS_DEFAULT:
5824 return "DEFAULT";
5825 case TRANS_START:
5826 return "START";
5827 case TRANS_INPROGRESS:
5828 return "INPROGRESS";
5829 case TRANS_COMMIT:
5830 return "COMMIT";
5831 case TRANS_ABORT:
5832 return "ABORT";
5833 case TRANS_PREPARE:
5834 return "PREPARE";
5835 }
5836 return "UNRECOGNIZED";
5837}
5838
5839/*
5840 * xactGetCommittedChildren
5841 *
5842 * Gets the list of committed children of the current transaction. The return
5843 * value is the number of child transactions. *ptr is set to point to an
5844 * array of TransactionIds. The array is allocated in TopTransactionContext;
5845 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
5846 * If there are no subxacts, *ptr is set to NULL.
5847 */
5848int
5850{
5852
5853 if (s->nChildXids == 0)
5854 *ptr = NULL;
5855 else
5856 *ptr = s->childXids;
5857
5858 return s->nChildXids;
5859}
5860
5861/*
5862 * XLOG support routines
5863 */
5864
5865
5866/*
5867 * Log the commit record for a plain or twophase transaction commit.
5868 *
5869 * A 2pc commit will be emitted when twophase_xid is valid, a plain one
5870 * otherwise.
5871 */
5874 int nsubxacts, TransactionId *subxacts,
5875 int nrels, RelFileLocator *rels,
5877 int nmsgs, SharedInvalidationMessage *msgs,
5878 bool relcacheInval,
5879 int xactflags, TransactionId twophase_xid,
5880 const char *twophase_gid)
5881{
5891 uint8 info;
5892
5894
5895 xl_xinfo.xinfo = 0;
5896
5897 /* decide between a plain and 2pc commit */
5898 if (!TransactionIdIsValid(twophase_xid))
5899 info = XLOG_XACT_COMMIT;
5900 else
5902
5903 /* First figure out and collect all the information needed */
5904
5905 xlrec.xact_time = commit_time;
5906
5907 if (relcacheInval)
5909 if (forceSyncCommit)
5913
5914 /*
5915 * Check if the caller would like to ask standbys for immediate feedback
5916 * once this commit is applied.
5917 */
5920
5921 /*
5922 * Relcache invalidations requires information about the current database
5923 * and so does logical decoding.
5924 */
5925 if (nmsgs > 0 || XLogLogicalInfoActive())
5926 {
5928 xl_dbinfo.dbId = MyDatabaseId;
5930 }
5931
5932 if (nsubxacts > 0)
5933 {
5935 xl_subxacts.nsubxacts = nsubxacts;
5936 }
5937
5938 if (nrels > 0)
5939 {
5941 xl_relfilelocators.nrels = nrels;
5942 info |= XLR_SPECIAL_REL_UPDATE;
5943 }
5944
5945 if (ndroppedstats > 0)
5946 {
5949 }
5950
5951 if (nmsgs > 0)
5952 {
5954 xl_invals.nmsgs = nmsgs;
5955 }
5956
5957 if (TransactionIdIsValid(twophase_xid))
5958 {
5960 xl_twophase.xid = twophase_xid;
5961 Assert(twophase_gid != NULL);
5962
5965 }
5966
5967 /* dump transaction origin information */
5969 {
5971
5974 }
5975
5976 if (xl_xinfo.xinfo != 0)
5977 info |= XLOG_XACT_HAS_INFO;
5978
5979 /* Then include all the collected data into the commit record. */
5980
5982
5984
5985 if (xl_xinfo.xinfo != 0)
5986 XLogRegisterData(&xl_xinfo.xinfo, sizeof(xl_xinfo.xinfo));
5987
5988 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5990
5992 {
5995 XLogRegisterData(subxacts,
5996 nsubxacts * sizeof(TransactionId));
5997 }
5998
6000 {
6003 XLogRegisterData(rels,
6004 nrels * sizeof(RelFileLocator));
6005 }
6006
6008 {
6013 }
6014
6015 if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
6016 {
6018 XLogRegisterData(msgs,
6019 nmsgs * sizeof(SharedInvalidationMessage));
6020 }
6021
6023 {
6025 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6026 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6027 }
6028
6029 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6031
6032 /* we allow filtering by xacts */
6034
6035 return XLogInsert(RM_XACT_ID, info);
6036}
6037
6038/*
6039 * Log the commit record for a plain or twophase transaction abort.
6040 *
6041 * A 2pc abort will be emitted when twophase_xid is valid, a plain one
6042 * otherwise.
6043 */
6046 int nsubxacts, TransactionId *subxacts,
6047 int nrels, RelFileLocator *rels,
6049 int xactflags, TransactionId twophase_xid,
6050 const char *twophase_gid)
6051{
6060
6061 uint8 info;
6062
6064
6065 xl_xinfo.xinfo = 0;
6066
6067 /* decide between a plain and 2pc abort */
6068 if (!TransactionIdIsValid(twophase_xid))
6069 info = XLOG_XACT_ABORT;
6070 else
6072
6073
6074 /* First figure out and collect all the information needed */
6075
6076 xlrec.xact_time = abort_time;
6077
6080
6081 if (nsubxacts > 0)
6082 {
6084 xl_subxacts.nsubxacts = nsubxacts;
6085 }
6086
6087 if (nrels > 0)
6088 {
6090 xl_relfilelocators.nrels = nrels;
6091 info |= XLR_SPECIAL_REL_UPDATE;
6092 }
6093
6094 if (ndroppedstats > 0)
6095 {
6098 }
6099
6100 if (TransactionIdIsValid(twophase_xid))
6101 {
6103 xl_twophase.xid = twophase_xid;
6104 Assert(twophase_gid != NULL);
6105
6108 }
6109
6110 if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6111 {
6113 xl_dbinfo.dbId = MyDatabaseId;
6115 }
6116
6117 /*
6118 * Dump transaction origin information. We need this during recovery to
6119 * update the replication origin progress.
6120 */
6122 {
6124
6127 }
6128
6129 if (xl_xinfo.xinfo != 0)
6130 info |= XLOG_XACT_HAS_INFO;
6131
6132 /* Then include all the collected data into the abort record. */
6133
6135
6137
6138 if (xl_xinfo.xinfo != 0)
6140
6141 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6143
6145 {
6148 XLogRegisterData(subxacts,
6149 nsubxacts * sizeof(TransactionId));
6150 }
6151
6153 {
6156 XLogRegisterData(rels,
6157 nrels * sizeof(RelFileLocator));
6158 }
6159
6161 {
6166 }
6167
6169 {
6171 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6172 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6173 }
6174
6175 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6177
6178 /* Include the replication origin */
6180
6181 return XLogInsert(RM_XACT_ID, info);
6182}
6183
6184/*
6185 * Before 9.0 this was a fairly short function, but now it performs many
6186 * actions for which the order of execution is critical.
6187 */
6188static void
6190 TransactionId xid,
6191 XLogRecPtr lsn,
6192 ReplOriginId origin_id)
6193{
6195 TimestampTz commit_time;
6196
6198
6199 max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
6200
6201 /* Make sure nextXid is beyond any XID mentioned in the record. */
6203
6204 Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) ==
6205 (origin_id == InvalidReplOriginId));
6206
6207 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6208 commit_time = parsed->origin_timestamp;
6209 else
6210 commit_time = parsed->xact_time;
6211
6212 /* Set the transaction commit timestamp and metadata */
6213 TransactionTreeSetCommitTsData(xid, parsed->nsubxacts, parsed->subxacts,
6214 commit_time, origin_id);
6215
6217 {
6218 /*
6219 * Mark the transaction committed in pg_xact.
6220 */
6221 TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
6222 }
6223 else
6224 {
6225 /*
6226 * If a transaction completion record arrives that has as-yet
6227 * unobserved subtransactions then this will not have been fully
6228 * handled by the call to RecordKnownAssignedTransactionIds() in the
6229 * main recovery loop in PerformWalRecovery(). So we need to do
6230 * bookkeeping again to cover that case. This is confusing and it is
6231 * easy to think this call is irrelevant, which has happened three
6232 * times in development already. Leave it in.
6233 */
6235
6236 /*
6237 * Mark the transaction committed in pg_xact. We use async commit
6238 * protocol during recovery to provide information on database
6239 * consistency for when users try to set hint bits. It is important
6240 * that we do not set hint bits until the minRecoveryPoint is past
6241 * this commit record. This ensures that if we crash we don't see hint
6242 * bits set on changes made by transactions that haven't yet
6243 * recovered. It's unlikely but it's good to be safe.
6244 */
6245 TransactionIdAsyncCommitTree(xid, parsed->nsubxacts, parsed->subxacts, lsn);
6246
6247 /*
6248 * We must mark clog before we update the ProcArray.
6249 */
6250 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6251
6252 /*
6253 * Send any cache invalidations attached to the commit. We must
6254 * maintain the same order of invalidation then release locks as
6255 * occurs in CommitTransaction().
6256 */
6259 parsed->dbId, parsed->tsId);
6260
6261 /*
6262 * Release locks, if any. We do this for both two phase and normal one
6263 * phase transactions. In effect we are ignoring the prepare phase and
6264 * just going straight to lock release.
6265 */
6266 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6267 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6268 }
6269
6270 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6271 {
6272 /* recover apply progress */
6273 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6274 false /* backward */ , false /* WAL */ );
6275 }
6276
6277 /* Make sure files supposed to be dropped are dropped */
6278 if (parsed->nrels > 0)
6279 {
6280 /*
6281 * First update minimum recovery point to cover this WAL record. Once
6282 * a relation is deleted, there's no going back. The buffer manager
6283 * enforces the WAL-first rule for normal updates to relation files,
6284 * so that the minimum recovery point is always updated before the
6285 * corresponding change in the data file is flushed to disk, but we
6286 * have to do the same here since we're bypassing the buffer manager.
6287 *
6288 * Doing this before deleting the files means that if a deletion fails
6289 * for some reason, you cannot start up the system even after restart,
6290 * until you fix the underlying situation so that the deletion will
6291 * succeed. Alternatively, we could update the minimum recovery point
6292 * after deletion, but that would leave a small window where the
6293 * WAL-first rule would be violated.
6294 */
6295 XLogFlush(lsn);
6296
6297 /* Make sure files supposed to be dropped are dropped */
6298 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6299 }
6300
6301 if (parsed->nstats > 0)
6302 {
6303 /* see equivalent call for relations above */
6304 XLogFlush(lsn);
6305
6306 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6307 }
6308
6309 /*
6310 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
6311 * in normal operation. For example, in CREATE DATABASE, we copy all files
6312 * from the template database, and then commit the transaction. If we
6313 * crash after all the files have been copied but before the commit, you
6314 * have files in the data directory without an entry in pg_database. To
6315 * minimize the window for that, we use ForceSyncCommit() to rush the
6316 * commit record to disk as quick as possible. We have the same window
6317 * during recovery, and forcing an XLogFlush() (which updates
6318 * minRecoveryPoint during recovery) helps to reduce that problem window,
6319 * for any user that requested ForceSyncCommit().
6320 */
6322 XLogFlush(lsn);
6323
6324 /*
6325 * If asked by the primary (because someone is waiting for a synchronous
6326 * commit = remote_apply), we will need to ask walreceiver to send a reply
6327 * immediately.
6328 */
6331}
6332
6333/*
6334 * Be careful with the order of execution, as with xact_redo_commit().
6335 * The two functions are similar but differ in key places.
6336 *
6337 * Note also that an abort can be for a subtransaction and its children,
6338 * not just for a top level abort. That means we have to consider
6339 * topxid != xid, whereas in commit we would find topxid == xid always
6340 * because subtransaction commit is never WAL logged.
6341 */
6342static void
6344 XLogRecPtr lsn, ReplOriginId origin_id)
6345{
6347
6349
6350 /* Make sure nextXid is beyond any XID mentioned in the record. */
6352 parsed->nsubxacts,
6353 parsed->subxacts);
6355
6357 {
6358 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6359 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6360 }
6361 else
6362 {
6363 /*
6364 * If a transaction completion record arrives that has as-yet
6365 * unobserved subtransactions then this will not have been fully
6366 * handled by the call to RecordKnownAssignedTransactionIds() in the
6367 * main recovery loop in PerformWalRecovery(). So we need to do
6368 * bookkeeping again to cover that case. This is confusing and it is
6369 * easy to think this call is irrelevant, which has happened three
6370 * times in development already. Leave it in.
6371 */
6373
6374 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6375 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6376
6377 /*
6378 * We must update the ProcArray after we have marked clog.
6379 */
6380 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6381
6382 /*
6383 * There are no invalidation messages to send or undo.
6384 */
6385
6386 /*
6387 * Release locks, if any. There are no invalidations to send.
6388 */
6389 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6390 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6391 }
6392
6393 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6394 {
6395 /* recover apply progress */
6396 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6397 false /* backward */ , false /* WAL */ );
6398 }
6399
6400 /* Make sure files supposed to be dropped are dropped */
6401 if (parsed->nrels > 0)
6402 {
6403 /*
6404 * See comments about update of minimum recovery point on truncation,
6405 * in xact_redo_commit().
6406 */
6407 XLogFlush(lsn);
6408
6409 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6410 }
6411
6412 if (parsed->nstats > 0)
6413 {
6414 /* see equivalent call for relations above */
6415 XLogFlush(lsn);
6416
6417 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6418 }
6419}
6420
6421void
6423{
6424 uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6425
6426 /* Backup blocks are not used in xact records */
6428
6429 if (info == XLOG_XACT_COMMIT)
6430 {
6433
6436 record->EndRecPtr, XLogRecGetOrigin(record));
6437 }
6438 else if (info == XLOG_XACT_COMMIT_PREPARED)
6439 {
6442
6444 xact_redo_commit(&parsed, parsed.twophase_xid,
6445 record->EndRecPtr, XLogRecGetOrigin(record));
6446
6447 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6449 PrepareRedoRemove(parsed.twophase_xid, false);
6451 }
6452 else if (info == XLOG_XACT_ABORT)
6453 {
6456
6459 record->EndRecPtr, XLogRecGetOrigin(record));
6460 }
6461 else if (info == XLOG_XACT_ABORT_PREPARED)
6462 {
6465
6467 xact_redo_abort(&parsed, parsed.twophase_xid,
6468 record->EndRecPtr, XLogRecGetOrigin(record));
6469
6470 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6472 PrepareRedoRemove(parsed.twophase_xid, false);
6474 }
6475 else if (info == XLOG_XACT_PREPARE)
6476 {
6477 /*
6478 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6479 * gxact entry.
6480 */
6483 XLogRecGetData(record),
6484 record->ReadRecPtr,
6485 record->EndRecPtr,
6486 XLogRecGetOrigin(record));
6488 }
6489 else if (info == XLOG_XACT_ASSIGNMENT)
6490 {
6492
6495 xlrec->nsubxacts, xlrec->xsub);
6496 }
6497 else if (info == XLOG_XACT_INVALIDATIONS)
6498 {
6499 /*
6500 * XXX we do ignore this for now, what matters are invalidations
6501 * written into the commit record.
6502 */
6503 }
6504 else
6505 elog(PANIC, "xact_redo: unknown op code %u", info);
6506}
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:2420
void PreCommit_Notify(void)
Definition async.c:1185
void AtSubAbort_Notify(void)
Definition async.c:2509
void AtPrepare_Notify(void)
Definition async.c:1160
void AtSubCommit_Notify(void)
Definition async.c:2439
#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:6348
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1649
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:4208
void UnlockBuffers(void)
Definition bufmgr.c:5861
#define InvalidCommandId
Definition c.h:812
#define TopSubTransactionId
Definition c.h:802
#define Min(x, y)
Definition c.h:1150
uint8_t uint8
Definition c.h:681
uint32 SubTransactionId
Definition c.h:799
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:308
#define InvalidSubTransactionId
Definition c.h:801
#define Assert(condition)
Definition c.h:1002
#define FLEXIBLE_ARRAY_MEMBER
Definition c.h:617
#define FirstCommandId
Definition c.h:811
uint32 LocalTransactionId
Definition c.h:797
uint32 CommandId
Definition c.h:809
uint32 TransactionId
Definition c.h:795
size_t Size
Definition c.h:748
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:1323
bool message_level_is_interesting(int elevel)
Definition elog.c:285
int errcode(int sqlerrcode)
Definition elog.c:875
#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:91
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:1936
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:1196
void AtEOSubXact_Inval(bool isCommit)
Definition inval.c:1307
void CommandEndInvalidationMessages(void)
Definition inval.c:1406
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:3580
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
Definition lock.c:4602
void AtPrepare_Locks(void)
Definition lock.c:3484
#define InvalidLocalTransactionId
Definition lock.h:68
void ResetLogicalStreamingState(void)
Definition logical.c:1941
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:1897
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1235
bool MemoryContextIsEmpty(MemoryContext context)
Definition mcxt.c:795
void MemoryContextReset(MemoryContext context)
Definition mcxt.c:406
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition mcxt.c:1269
Size add_size(Size s1, Size s2)
Definition mcxt.c:1733
MemoryContext TopTransactionContext
Definition mcxt.c:172
void * repalloc(void *pointer, Size size)
Definition mcxt.c:1635
void pfree(void *pointer)
Definition mcxt.c:1619
MemoryContext TopMemoryContext
Definition mcxt.c:167
Size mul_size(Size s1, Size s2)
Definition mcxt.c:1752
void * palloc(Size size)
Definition mcxt.c:1390
MemoryContext CurTransactionContext
Definition mcxt.c:173
MemoryContext CurrentMemoryContext
Definition mcxt.c:161
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:475
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:138
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:496
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:4632
void PostPrepare_PredicateLocks(FullTransactionId fxid)
Definition predicate.c:4788
void AtPrepare_PredicateLocks(void)
Definition predicate.c:4719
void RegisterPredicateLockingXid(TransactionId xid)
Definition predicate.c:1888
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:3998
void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
Definition procarray.c:663
void RecordKnownAssignedTransactionIds(TransactionId xid)
Definition procarray.c:4443
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:4512
void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition relcache.c:3380
void AtEOXact_RelationCache(bool isCommit)
Definition relcache.c:3228
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:428
ResourceOwner CurrentResourceOwner
Definition resowner.c:173
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition resowner.c:665
void ResourceOwnerDelete(ResourceOwner owner)
Definition resowner.c:878
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
void AtEOXact_RI(bool isCommit)
LocalTransactionId GetNextLocalTransactionId(void)
Definition sinvaladt.c:703
void AtEOXact_SMgr(void)
Definition smgr.c:1017
void SnapBuildResetExportedSnapshotState(void)
Definition snapbuild.c:630
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:1473
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
int delayChkptFlags
Definition proc.h:260
struct PGPROC::@134 vxid
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:5131
void AfterTriggerEndSubXact(bool isCommit)
Definition trigger.c:5519
void AfterTriggerFireDeferred(void)
Definition trigger.c:5354
void AfterTriggerEndXact(bool isCommit)
Definition trigger.c:5417
void AfterTriggerBeginSubXact(void)
Definition trigger.c:5471
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:3219
void AtEOSubXact_TypeCache(void)
Definition typcache.c:3225
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:3228
bool IsTransactionOrTransactionBlock(void)
Definition xact.c:5043
void SerializeTransactionState(Size maxsize, char *start_address)
Definition xact.c:5599
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:3189
static void CleanupSubTransaction(void)
Definition xact.c:5442
void BeginInternalSubTransaction(const char *name)
Definition xact.c:4748
static void AtStart_Memory(void)
Definition xact.c:1206
FullTransactionId GetCurrentFullTransactionId(void)
Definition xact.c:514
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition xact.c:3197
static XactCallbackItem * Xact_callbacks
Definition xact.c:317
void WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
Definition xact.c:3764
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:4258
bool IsInTransactionBlock(bool isTopLevel)
Definition xact.c:3823
bool PrepareTransactionBlock(const char *gid)
Definition xact.c:4046
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:6422
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:3952
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:3779
void UnregisterSubXactCallback(SubXactCallback callback, void *arg)
Definition xact.c:3931
bool XactDeferrable
Definition xact.c:87
static bool forceSyncCommit
Definition xact.c:295
void BeginImplicitTransactionBlock(void)
Definition xact.c:4380
static void CallXactCallbacks(XactEvent event)
Definition xact.c:3892
static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS]
Definition xact.c:260
void RequireTransactionBlock(bool isTopLevel, const char *stmtType)
Definition xact.c:3770
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:4427
bool DefaultXactDeferrable
Definition xact.c:86
static void CleanupTransaction(void)
Definition xact.c:3062
static int nUnreportedXids
Definition xact.c:259
static const char * TransStateAsString(TransState state)
Definition xact.c:5819
static TimestampTz xactStopTimestamp
Definition xact.c:284
bool TransactionStartedDuringRecovery(void)
Definition xact.c:1044
static void CommitSubTransaction(void)
Definition xact.c:5158
bool XactReadOnly
Definition xact.c:84
static void PushTransaction(void)
Definition xact.c:5475
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:3871
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:3701
static void AtCleanup_Memory(void)
Definition xact.c:2016
Size EstimateTransactionStateSpace(void)
Definition xact.c:5571
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:3522
static SubTransactionId currentSubTransactionId
Definition xact.c:268
static void AssignTransactionId(TransactionState s)
Definition xact.c:637
char TransactionBlockStatusCode(void)
Definition xact.c:5057
void RollbackAndReleaseCurrentSubTransaction(void)
Definition xact.c:4850
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:3112
static void PopTransaction(void)
Definition xact.c:5537
bool IsAbortedTransactionBlockState(void)
Definition xact.c:409
void ReleaseCurrentSubTransaction(void)
Definition xact.c:4822
void EndImplicitTransactionBlock(void)
Definition xact.c:4405
void StartParallelWorkerTransaction(char *tstatespace)
Definition xact.c:5670
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:4512
static TransactionStateData TopTransactionStateData
Definition xact.c:249
static FullTransactionId XactTopFullTransactionId
Definition xact.c:127
static void ShowTransactionState(const char *str)
Definition xact.c:5707
int XactIsoLevel
Definition xact.c:81
static void PrepareTransaction(void)
Definition xact.c:2559
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:5873
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:5273
bool IsSubTransaction(void)
Definition xact.c:5098
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:6343
bool IsTransactionBlock(void)
Definition xact.c:5025
bool IsInParallelMode(void)
Definition xact.c:1119
int xactGetCommittedChildren(TransactionId **ptr)
Definition xact.c:5849
TransactionId GetCurrentTransactionIdIfAny(void)
Definition xact.c:473
void BeginTransactionBlock(void)
Definition xact.c:3978
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:5766
void EndParallelWorkerTransaction(void)
Definition xact.c:5695
static void AtAbort_Memory(void)
Definition xact.c:1926
void RegisterXactCallback(XactCallback callback, void *arg)
Definition xact.c:3858
void CommitTransactionCommand(void)
Definition xact.c:3210
void RollbackToSavepoint(const char *name)
Definition xact.c:4621
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:3918
FullTransactionId GetTopFullTransactionIdIfAny(void)
Definition xact.c:501
TransactionId GetCurrentTransactionId(void)
Definition xact.c:456
static void AbortTransaction(void)
Definition xact.c:2855
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:4098
bool IsSubxactTopXidLogPending(void)
Definition xact.c:561
#define SerializedTransactionStateHeaderSize
Definition xact.c:241
void AbortOutOfAnyTransaction(void)
Definition xact.c:4916
int MyXactFlags
Definition xact.c:138
static void ShowTransactionStateRec(const char *str, TransactionState s)
Definition xact.c:5719
static TransactionState CurrentTransactionState
Definition xact.c:262
void AbortCurrentTransaction(void)
Definition xact.c:3504
static void StartSubTransaction(void)
Definition xact.c:5121
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:6045
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:6189
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:6836
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:366