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 * EnterParallelMode
1051 */
1052void
1054{
1056
1057 Assert(s->parallelModeLevel >= 0);
1058
1059 ++s->parallelModeLevel;
1060}
1061
1062/*
1063 * ExitParallelMode
1064 */
1065void
1076
1077/*
1078 * IsInParallelMode
1079 *
1080 * Are we in a parallel operation, as either the leader or a worker? Check
1081 * this to prohibit operations that change backend-local state expected to
1082 * match across all workers. Mere caches usually don't require such a
1083 * restriction. State modified in a strict push/pop fashion, such as the
1084 * active snapshot stack, is often fine.
1085 *
1086 * We say we are in parallel mode if we are in a subxact of a transaction
1087 * that's initiated a parallel operation; for most purposes that context
1088 * has all the same restrictions.
1089 */
1090bool
1092{
1094
1095 return s->parallelModeLevel != 0 || s->parallelChildXact;
1096}
1097
1098/*
1099 * CommandCounterIncrement
1100 */
1101void
1103{
1104 /*
1105 * If the current value of the command counter hasn't been "used" to mark
1106 * tuples, we need not increment it, since there's no need to distinguish
1107 * a read-only command from others. This helps postpone command counter
1108 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
1109 */
1111 {
1112 /*
1113 * Workers synchronize transaction state at the beginning of each
1114 * parallel operation, so we can't account for new commands after that
1115 * point.
1116 */
1118 ereport(ERROR,
1120 errmsg("cannot start commands during a parallel operation")));
1121
1122 currentCommandId += 1;
1124 {
1125 currentCommandId -= 1;
1126 ereport(ERROR,
1128 errmsg("cannot have more than 2^32-2 commands in a transaction")));
1129 }
1130 currentCommandIdUsed = false;
1131
1132 /* Propagate new command ID into static snapshots */
1134
1135 /*
1136 * Make any catalog changes done by the just-completed command visible
1137 * in the local syscache. We obviously don't need to do this after a
1138 * read-only command. (But see hacks in inval.c to make real sure we
1139 * don't think a command that queued inval messages was read-only.)
1140 */
1142 }
1143}
1144
1145/*
1146 * ForceSyncCommit
1147 *
1148 * Interface routine to allow commands to force a synchronous commit of the
1149 * current top-level transaction. Currently, two-phase commit does not
1150 * persist and restore this variable. So long as all callers use
1151 * PreventInTransactionBlock(), that omission has no consequences.
1152 */
1153void
1155{
1156 forceSyncCommit = true;
1157}
1158
1159
1160/* ----------------------------------------------------------------
1161 * StartTransaction stuff
1162 * ----------------------------------------------------------------
1163 */
1164
1165/*
1166 * AtStart_Cache
1167 */
1168static void
1173
1174/*
1175 * AtStart_Memory
1176 */
1177static void
1179{
1181
1182 /*
1183 * Remember the memory context that was active prior to transaction start.
1184 */
1186
1187 /*
1188 * If this is the first time through, create a private context for
1189 * AbortTransaction to work in. By reserving some space now, we can
1190 * insulate AbortTransaction from out-of-memory scenarios. Like
1191 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1192 * size, so that space will be reserved immediately.
1193 */
1197 "TransactionAbortContext",
1198 32 * 1024,
1199 32 * 1024,
1200 32 * 1024);
1201
1202 /*
1203 * Likewise, if this is the first time through, create a top-level context
1204 * for transaction-local data. This context will be reset at transaction
1205 * end, and then re-used in later transactions.
1206 */
1210 "TopTransactionContext",
1212
1213 /*
1214 * In a top-level transaction, CurTransactionContext is the same as
1215 * TopTransactionContext.
1216 */
1219
1220 /* Make the CurTransactionContext active. */
1222}
1223
1224/*
1225 * AtStart_ResourceOwner
1226 */
1227static void
1229{
1231
1232 /*
1233 * We shouldn't have a transaction resource owner already.
1234 */
1236
1237 /*
1238 * Create a toplevel resource owner for the transaction.
1239 */
1240 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1241
1245}
1246
1247/* ----------------------------------------------------------------
1248 * StartSubTransaction stuff
1249 * ----------------------------------------------------------------
1250 */
1251
1252/*
1253 * AtSubStart_Memory
1254 */
1255static void
1257{
1259
1261
1262 /*
1263 * Remember the context that was active prior to subtransaction start.
1264 */
1266
1267 /*
1268 * Create a CurTransactionContext, which will be used to hold data that
1269 * survives subtransaction commit but disappears on subtransaction abort.
1270 * We make it a child of the immediate parent's CurTransactionContext.
1271 */
1273 "CurTransactionContext",
1276
1277 /* Make the CurTransactionContext active. */
1279}
1280
1281/*
1282 * AtSubStart_ResourceOwner
1283 */
1284static void
1286{
1288
1289 Assert(s->parent != NULL);
1290
1291 /*
1292 * Create a resource owner for the subtransaction. We make it a child of
1293 * the immediate parent's resource owner.
1294 */
1297 "SubTransaction");
1298
1301}
1302
1303/* ----------------------------------------------------------------
1304 * CommitTransaction stuff
1305 * ----------------------------------------------------------------
1306 */
1307
1308/*
1309 * RecordTransactionCommit
1310 *
1311 * Returns latest XID among xact and its children, or InvalidTransactionId
1312 * if the xact has no XID. (We compute that here just because it's easier.)
1313 *
1314 * If you change this function, see RecordTransactionCommitPrepared also.
1315 */
1316static TransactionId
1318{
1322 int nrels;
1323 RelFileLocator *rels;
1324 int nchildren;
1325 TransactionId *children;
1326 int ndroppedstats = 0;
1328 int nmsgs = 0;
1330 bool RelcacheInitFileInval = false;
1331 bool wrote_xlog;
1332
1333 /*
1334 * Log pending invalidations for logical decoding of in-progress
1335 * transactions. Normally for DDLs, we log this at each command end,
1336 * however, for certain cases where we directly update the system table
1337 * without a transaction block, the invalidations are not logged till this
1338 * time.
1339 */
1342
1343 /* Get data needed for commit record */
1344 nrels = smgrGetPendingDeletes(true, &rels);
1349 &RelcacheInitFileInval);
1350 wrote_xlog = (XactLastRecEnd != 0);
1351
1352 /*
1353 * If we haven't been assigned an XID yet, we neither can, nor do we want
1354 * to write a COMMIT record.
1355 */
1356 if (!markXidCommitted)
1357 {
1358 /*
1359 * We expect that every RelationDropStorage is followed by a catalog
1360 * update, and hence XID assignment, so we shouldn't get here with any
1361 * pending deletes. Same is true for dropping stats.
1362 *
1363 * Use a real test not just an Assert to check this, since it's a bit
1364 * fragile.
1365 */
1366 if (nrels != 0 || ndroppedstats != 0)
1367 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
1368
1369 /* Can't have child XIDs either; AssignTransactionId enforces this */
1370 Assert(nchildren == 0);
1371
1372 /*
1373 * Transactions without an assigned xid can contain invalidation
1374 * messages. While inplace updates do this, this is not known to be
1375 * necessary; see comment at inplace CacheInvalidateHeapTuple().
1376 * Extensions might still rely on this capability, and standbys may
1377 * need to process those invals. We can't emit a commit record
1378 * without an xid, and we don't want to force assigning an xid,
1379 * because that'd be problematic for e.g. vacuum. Hence we emit a
1380 * bespoke record for the invalidations. We don't want to use that in
1381 * case a commit record is emitted, so they happen synchronously with
1382 * commits (besides not wanting to emit more WAL records).
1383 *
1384 * XXX Every known use of this capability is a defect. Since an XID
1385 * isn't controlling visibility of the change that prompted invals,
1386 * other sessions need the inval even if this transactions aborts.
1387 *
1388 * ON COMMIT DELETE ROWS does a nontransactional index_build(), which
1389 * queues a relcache inval, including in transactions without an xid
1390 * that had read the (empty) table. Standbys don't need any ON COMMIT
1391 * DELETE ROWS invals, but we've not done the work to withhold them.
1392 */
1393 if (nmsgs != 0)
1394 {
1396 RelcacheInitFileInval);
1397 wrote_xlog = true; /* not strictly necessary */
1398 }
1399
1400 /*
1401 * If we didn't create XLOG entries, we're done here; otherwise we
1402 * should trigger flushing those entries the same as a commit record
1403 * would. This will primarily happen for HOT pruning and the like; we
1404 * want these to be flushed to disk in due time.
1405 */
1406 if (!wrote_xlog)
1407 goto cleanup;
1408 }
1409 else
1410 {
1411 bool replorigin;
1412
1413 /*
1414 * Are we using the replication origins feature? Or, in other words,
1415 * are we replaying remote actions?
1416 */
1419
1420 /*
1421 * Mark ourselves as within our "commit critical section". This
1422 * forces any concurrent checkpoint to wait until we've updated
1423 * pg_xact. Without this, it is possible for the checkpoint to set
1424 * REDO after the XLOG record but fail to flush the pg_xact update to
1425 * disk, leading to loss of the transaction commit if the system
1426 * crashes a little later.
1427 *
1428 * Note: we could, but don't bother to, set this flag in
1429 * RecordTransactionAbort. That's because loss of a transaction abort
1430 * is noncritical; the presumption would be that it aborted, anyway.
1431 *
1432 * It's safe to change the delayChkptFlags flag of our own backend
1433 * without holding the ProcArrayLock, since we're the only one
1434 * modifying it. This makes checkpoint's determination of which xacts
1435 * are delaying the checkpoint a bit fuzzy, but it doesn't matter.
1436 *
1437 * Note, it is important to get the commit timestamp after marking the
1438 * transaction in the commit critical section. See
1439 * RecordTransactionCommitPrepared.
1440 */
1444
1446
1447 /*
1448 * Ensures the DELAY_CHKPT_IN_COMMIT flag write is globally visible
1449 * before commit time is written.
1450 */
1452
1453 /*
1454 * Insert the commit XLOG record.
1455 */
1457 nchildren, children, nrels, rels,
1459 nmsgs, invalMessages,
1460 RelcacheInitFileInval,
1462 InvalidTransactionId, NULL /* plain commit */ );
1463
1464 if (replorigin)
1465 /* Move LSNs forward for this replication origin */
1468
1469 /*
1470 * Record commit timestamp. The value comes from plain commit
1471 * timestamp if there's no replication origin; otherwise, the
1472 * timestamp was already set in replorigin_xact_state.origin_timestamp
1473 * by replication.
1474 *
1475 * We don't need to WAL-log anything here, as the commit record
1476 * written above already contains the data.
1477 */
1478
1481
1485 }
1486
1487 /*
1488 * Check if we want to commit asynchronously. We can allow the XLOG flush
1489 * to happen asynchronously if synchronous_commit=off, or if the current
1490 * transaction has not performed any WAL-logged operation or didn't assign
1491 * an xid. The transaction can end up not writing any WAL, even if it has
1492 * an xid, if it only wrote to temporary and/or unlogged tables. It can
1493 * end up having written WAL without an xid if it did HOT pruning. In
1494 * case of a crash, the loss of such a transaction will be irrelevant;
1495 * temp tables will be lost anyway, unlogged tables will be truncated and
1496 * HOT pruning will be done again later. (Given the foregoing, you might
1497 * think that it would be unnecessary to emit the XLOG record at all in
1498 * this case, but we don't currently try to do that. It would certainly
1499 * cause problems at least in Hot Standby mode, where the
1500 * KnownAssignedXids machinery requires tracking every XID assignment. It
1501 * might be OK to skip it only when wal_level < replica, but for now we
1502 * don't.)
1503 *
1504 * However, if we're doing cleanup of any non-temp rels or committing any
1505 * command that wanted to force sync commit, then we must flush XLOG
1506 * immediately. (We must not allow asynchronous commit if there are any
1507 * non-temp tables to be deleted, because we might delete the files before
1508 * the COMMIT record is flushed to disk. We do allow asynchronous commit
1509 * if all to-be-deleted tables are temporary though, since they are lost
1510 * anyway if we crash.)
1511 */
1512 if ((wrote_xlog && markXidCommitted &&
1514 forceSyncCommit || nrels > 0)
1515 {
1517
1518 /*
1519 * Now we may update the CLOG, if we wrote a COMMIT record above
1520 */
1521 if (markXidCommitted)
1522 TransactionIdCommitTree(xid, nchildren, children);
1523 }
1524 else
1525 {
1526 /*
1527 * Asynchronous commit case:
1528 *
1529 * This enables possible committed transaction loss in the case of a
1530 * postmaster crash because WAL buffers are left unwritten. Ideally we
1531 * could issue the WAL write without the fsync, but some
1532 * wal_sync_methods do not allow separate write/fsync.
1533 *
1534 * Report the latest async commit LSN, so that the WAL writer knows to
1535 * flush this commit.
1536 */
1538
1539 /*
1540 * We must not immediately update the CLOG, since we didn't flush the
1541 * XLOG. Instead, we store the LSN up to which the XLOG must be
1542 * flushed before the CLOG may be updated.
1543 */
1544 if (markXidCommitted)
1546 }
1547
1548 /*
1549 * If we entered a commit critical section, leave it now, and let
1550 * checkpoints proceed.
1551 */
1552 if (markXidCommitted)
1553 {
1556 }
1557
1558 /* Compute latestXid while we have the child XIDs handy */
1559 latestXid = TransactionIdLatest(xid, nchildren, children);
1560
1561 /*
1562 * Wait for synchronous replication, if required. Similar to the decision
1563 * above about using committing asynchronously we only want to wait if
1564 * this backend assigned an xid and wrote WAL. No need to wait if an xid
1565 * was assigned due to temporary/unlogged tables or due to HOT pruning.
1566 *
1567 * Note that at this stage we have marked clog, but still show as running
1568 * in the procarray and continue to hold locks.
1569 */
1572
1573 /* remember end of last commit record */
1575
1576 /* Reset XactLastRecEnd until the next transaction writes something */
1577 XactLastRecEnd = 0;
1578cleanup:
1579 /* Clean up local data */
1580 if (rels)
1581 pfree(rels);
1582 if (ndroppedstats)
1584
1585 return latestXid;
1586}
1587
1588
1589/*
1590 * AtCCI_LocalCache
1591 */
1592static void
1594{
1595 /*
1596 * Make any pending relation map changes visible. We must do this before
1597 * processing local sinval messages, so that the map changes will get
1598 * reflected into the relcache when relcache invals are processed.
1599 */
1601
1602 /*
1603 * Make catalog changes visible to me for the next command.
1604 */
1606}
1607
1608/*
1609 * AtCommit_Memory
1610 */
1611static void
1613{
1615
1616 /*
1617 * Return to the memory context that was current before we started the
1618 * transaction. (In principle, this could not be any of the contexts we
1619 * are about to delete. If it somehow is, assertions in mcxt.c will
1620 * complain.)
1621 */
1623
1624 /*
1625 * Release all transaction-local memory. TopTransactionContext survives
1626 * but becomes empty; any sub-contexts go away.
1627 */
1630
1631 /*
1632 * Clear these pointers as a pro-forma matter. (Notionally, while
1633 * TopTransactionContext still exists, it's currently not associated with
1634 * this TransactionState struct.)
1635 */
1638}
1639
1640/* ----------------------------------------------------------------
1641 * CommitSubTransaction stuff
1642 * ----------------------------------------------------------------
1643 */
1644
1645/*
1646 * AtSubCommit_Memory
1647 */
1648static void
1650{
1652
1653 Assert(s->parent != NULL);
1654
1655 /* Return to parent transaction level's memory context. */
1658
1659 /*
1660 * Ordinarily we cannot throw away the child's CurTransactionContext,
1661 * since the data it contains will be needed at upper commit. However, if
1662 * there isn't actually anything in it, we can throw it away. This avoids
1663 * a small memory leak in the common case of "trivial" subxacts.
1664 */
1666 {
1669 }
1670}
1671
1672/*
1673 * AtSubCommit_childXids
1674 *
1675 * Pass my own XID and my child XIDs up to my parent as committed children.
1676 */
1677static void
1679{
1681 int new_nChildXids;
1682
1683 Assert(s->parent != NULL);
1684
1685 /*
1686 * The parent childXids array will need to hold my XID and all my
1687 * childXids, in addition to the XIDs already there.
1688 */
1690
1691 /* Allocate or enlarge the parent array if necessary */
1693 {
1694 int new_maxChildXids;
1696
1697 /*
1698 * Make it 2x what's needed right now, to avoid having to enlarge it
1699 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1700 * is what ensures that we don't need to worry about integer overflow
1701 * here or in the calculation of new_nChildXids.)
1702 */
1704 (int) (MaxAllocSize / sizeof(TransactionId)));
1705
1707 ereport(ERROR,
1709 errmsg("maximum number of committed subtransactions (%d) exceeded",
1710 (int) (MaxAllocSize / sizeof(TransactionId)))));
1711
1712 /*
1713 * We keep the child-XID arrays in TopTransactionContext; this avoids
1714 * setting up child-transaction contexts for what might be just a few
1715 * bytes of grandchild XIDs.
1716 */
1717 if (s->parent->childXids == NULL)
1721 else
1724
1727 }
1728
1729 /*
1730 * Copy all my XIDs to parent's array.
1731 *
1732 * Note: We rely on the fact that the XID of a child always follows that
1733 * of its parent. By copying the XID of this subtransaction before the
1734 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1735 * all XIDs already in the array belong to subtransactions started and
1736 * subcommitted before us, so their XIDs must precede ours.
1737 */
1739
1740 if (s->nChildXids > 0)
1741 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1742 s->childXids,
1743 s->nChildXids * sizeof(TransactionId));
1744
1746
1747 /* Release child's array to avoid leakage */
1748 if (s->childXids != NULL)
1749 pfree(s->childXids);
1750 /* We must reset these to avoid double-free if fail later in commit */
1751 s->childXids = NULL;
1752 s->nChildXids = 0;
1753 s->maxChildXids = 0;
1754}
1755
1756/* ----------------------------------------------------------------
1757 * AbortTransaction stuff
1758 * ----------------------------------------------------------------
1759 */
1760
1761/*
1762 * RecordTransactionAbort
1763 *
1764 * Returns latest XID among xact and its children, or InvalidTransactionId
1765 * if the xact has no XID. (We compute that here just because it's easier.)
1766 */
1767static TransactionId
1769{
1772 int nrels;
1773 RelFileLocator *rels;
1774 int ndroppedstats = 0;
1776 int nchildren;
1777 TransactionId *children;
1778 TimestampTz xact_time;
1779 bool replorigin;
1780
1781 /*
1782 * If we haven't been assigned an XID, nobody will care whether we aborted
1783 * or not. Hence, we're done in that case. It does not matter if we have
1784 * rels to delete (note that this routine is not responsible for actually
1785 * deleting 'em). We cannot have any child XIDs, either.
1786 */
1787 if (!TransactionIdIsValid(xid))
1788 {
1789 /* Reset XactLastRecEnd until the next transaction writes something */
1790 if (!isSubXact)
1791 XactLastRecEnd = 0;
1792 return InvalidTransactionId;
1793 }
1794
1795 /*
1796 * We have a valid XID, so we should write an ABORT record for it.
1797 *
1798 * We do not flush XLOG to disk here, since the default assumption after a
1799 * crash would be that we aborted, anyway. For the same reason, we don't
1800 * need to worry about interlocking against checkpoint start.
1801 */
1802
1803 /*
1804 * Check that we haven't aborted halfway through RecordTransactionCommit.
1805 */
1806 if (TransactionIdDidCommit(xid))
1807 elog(PANIC, "cannot abort transaction %u, it was already committed",
1808 xid);
1809
1810 /*
1811 * Are we using the replication origins feature? Or, in other words, are
1812 * we replaying remote actions?
1813 */
1816
1817 /* Fetch the data we need for the abort record */
1818 nrels = smgrGetPendingDeletes(false, &rels);
1821
1822 /* XXX do we really need a critical section here? */
1824
1825 /* Write the ABORT record */
1826 if (isSubXact)
1827 xact_time = GetCurrentTimestamp();
1828 else
1829 {
1831 }
1832
1833 XactLogAbortRecord(xact_time,
1834 nchildren, children,
1835 nrels, rels,
1838 NULL);
1839
1840 if (replorigin)
1841 /* Move LSNs forward for this replication origin */
1844
1845 /*
1846 * Report the latest async abort LSN, so that the WAL writer knows to
1847 * flush this abort. There's nothing to be gained by delaying this, since
1848 * WALWriter may as well do this when it can. This is important with
1849 * streaming replication because if we don't flush WAL regularly we will
1850 * find that large aborts leave us with a long backlog for when commits
1851 * occur after the abort, increasing our window of data loss should
1852 * problems occur at that point.
1853 */
1854 if (!isSubXact)
1856
1857 /*
1858 * Mark the transaction aborted in clog. This is not absolutely necessary
1859 * but we may as well do it while we are here; also, in the subxact case
1860 * it is helpful because XactLockTableWait makes use of it to avoid
1861 * waiting for already-aborted subtransactions. It is OK to do it without
1862 * having flushed the ABORT record to disk, because in event of a crash
1863 * we'd be assumed to have aborted anyway.
1864 */
1865 TransactionIdAbortTree(xid, nchildren, children);
1866
1868
1869 /* Compute latestXid while we have the child XIDs handy */
1870 latestXid = TransactionIdLatest(xid, nchildren, children);
1871
1872 /*
1873 * If we're aborting a subtransaction, we can immediately remove failed
1874 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1875 * subxacts, because we already have the child XID array at hand. For
1876 * main xacts, the equivalent happens just after this function returns.
1877 */
1878 if (isSubXact)
1880
1881 /* Reset XactLastRecEnd until the next transaction writes something */
1882 if (!isSubXact)
1883 XactLastRecEnd = 0;
1884
1885 /* And clean up local data */
1886 if (rels)
1887 pfree(rels);
1888 if (ndroppedstats)
1890
1891 return latestXid;
1892}
1893
1894/*
1895 * AtAbort_Memory
1896 */
1897static void
1899{
1900 /*
1901 * Switch into TransactionAbortContext, which should have some free space
1902 * even if nothing else does. We'll work in this context until we've
1903 * finished cleaning up.
1904 *
1905 * It is barely possible to get here when we've not been able to create
1906 * TransactionAbortContext yet; if so use TopMemoryContext.
1907 */
1910 else
1912}
1913
1914/*
1915 * AtSubAbort_Memory
1916 */
1917static void
1924
1925
1926/*
1927 * AtAbort_ResourceOwner
1928 */
1929static void
1931{
1932 /*
1933 * Make sure we have a valid ResourceOwner, if possible (else it will be
1934 * NULL, which is OK)
1935 */
1937}
1938
1939/*
1940 * AtSubAbort_ResourceOwner
1941 */
1942static void
1944{
1946
1947 /* Make sure we have a valid ResourceOwner */
1949}
1950
1951
1952/*
1953 * AtSubAbort_childXids
1954 */
1955static void
1957{
1959
1960 /*
1961 * We keep the child-XID arrays in TopTransactionContext (see
1962 * AtSubCommit_childXids). This means we'd better free the array
1963 * explicitly at abort to avoid leakage.
1964 */
1965 if (s->childXids != NULL)
1966 pfree(s->childXids);
1967 s->childXids = NULL;
1968 s->nChildXids = 0;
1969 s->maxChildXids = 0;
1970
1971 /*
1972 * We could prune the unreportedXids array here. But we don't bother. That
1973 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1974 * would likely introduce more CPU time into the more common paths, so we
1975 * choose not to do that.
1976 */
1977}
1978
1979/* ----------------------------------------------------------------
1980 * CleanupTransaction stuff
1981 * ----------------------------------------------------------------
1982 */
1983
1984/*
1985 * AtCleanup_Memory
1986 */
1987static void
1989{
1991
1992 /* Should be at top level */
1993 Assert(s->parent == NULL);
1994
1995 /*
1996 * Return to the memory context that was current before we started the
1997 * transaction. (In principle, this could not be any of the contexts we
1998 * are about to delete. If it somehow is, assertions in mcxt.c will
1999 * complain.)
2000 */
2002
2003 /*
2004 * Clear the special abort context for next time.
2005 */
2008
2009 /*
2010 * Release all transaction-local memory, the same as in AtCommit_Memory,
2011 * except we must cope with the possibility that we didn't get as far as
2012 * creating TopTransactionContext.
2013 */
2016
2017 /*
2018 * Clear these pointers as a pro-forma matter. (Notionally, while
2019 * TopTransactionContext still exists, it's currently not associated with
2020 * this TransactionState struct.)
2021 */
2024}
2025
2026
2027/* ----------------------------------------------------------------
2028 * CleanupSubTransaction stuff
2029 * ----------------------------------------------------------------
2030 */
2031
2032/*
2033 * AtSubCleanup_Memory
2034 */
2035static void
2037{
2039
2040 Assert(s->parent != NULL);
2041
2042 /*
2043 * Return to the memory context that was current before we started the
2044 * subtransaction. (In principle, this could not be any of the contexts
2045 * we are about to delete. If it somehow is, assertions in mcxt.c will
2046 * complain.)
2047 */
2049
2050 /* Update CurTransactionContext (might not be same as priorContext) */
2052
2053 /*
2054 * Clear the special abort context for next time.
2055 */
2058
2059 /*
2060 * Delete the subxact local memory contexts. Its CurTransactionContext can
2061 * go too (note this also kills CurTransactionContexts from any children
2062 * of the subxact).
2063 */
2064 if (s->curTransactionContext)
2067}
2068
2069/* ----------------------------------------------------------------
2070 * interface routines
2071 * ----------------------------------------------------------------
2072 */
2073
2074/*
2075 * StartTransaction
2076 */
2077static void
2079{
2082
2083 /*
2084 * Let's just make sure the state stack is empty
2085 */
2088
2090
2091 /* check the current transaction state */
2092 Assert(s->state == TRANS_DEFAULT);
2093
2094 /*
2095 * Set the current transaction state information appropriately during
2096 * start processing. Note that once the transaction status is switched
2097 * this process cannot fail until the user ID and the security context
2098 * flags are fetched below.
2099 */
2100 s->state = TRANS_START;
2101 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
2102
2103 /* Determine if statements are logged in this transaction */
2105 (log_xact_sample_rate == 1 ||
2107
2108 /*
2109 * initialize current transaction state fields
2110 *
2111 * note: prevXactReadOnly is not used at the outermost level
2112 */
2113 s->nestingLevel = 1;
2114 s->gucNestLevel = 1;
2115 s->childXids = NULL;
2116 s->nChildXids = 0;
2117 s->maxChildXids = 0;
2118
2119 /*
2120 * Once the current user ID and the security context flags are fetched,
2121 * both will be properly reset even if transaction startup fails.
2122 */
2124
2125 /* SecurityRestrictionContext should never be set outside a transaction */
2126 Assert(s->prevSecContext == 0);
2127
2128 /*
2129 * Make sure we've reset xact state variables
2130 *
2131 * If recovery is still in progress, mark this transaction as read-only.
2132 * We have lower level defences in XLogInsert and elsewhere to stop us
2133 * from modifying data during recovery, but this gives the normal
2134 * indication to the user that the transaction is read-only.
2135 */
2136 if (RecoveryInProgress())
2137 {
2138 s->startedInRecovery = true;
2139 XactReadOnly = true;
2140 }
2141 else
2142 {
2143 s->startedInRecovery = false;
2145 }
2148 forceSyncCommit = false;
2149 MyXactFlags = 0;
2150
2151 /*
2152 * reinitialize within-transaction counters
2153 */
2157 currentCommandIdUsed = false;
2158
2159 /*
2160 * initialize reported xid accounting
2161 */
2162 nUnreportedXids = 0;
2163 s->didLogXid = false;
2164
2165 /*
2166 * must initialize resource-management stuff first
2167 */
2170
2171 /*
2172 * Assign a new LocalTransactionId, and combine it with the proc number to
2173 * form a virtual transaction id.
2174 */
2175 vxid.procNumber = MyProcNumber;
2177
2178 /*
2179 * Lock the virtual transaction id before we announce it in the proc array
2180 */
2182
2183 /*
2184 * Advertise it in the proc array. We assume assignment of
2185 * localTransactionId is atomic, and the proc number should be set
2186 * already.
2187 */
2190
2192
2193 /*
2194 * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2195 * be the same as the first command's statement_timestamp(), so don't do a
2196 * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2197 * for transactions started inside procedures (i.e., nonatomic SPI
2198 * contexts), we do need to advance the timestamp. Also, in a parallel
2199 * worker, the timestamp should already have been provided by a call to
2200 * SetParallelStartTimestamps().
2201 */
2202 if (!IsParallelWorker())
2203 {
2206 else
2208 }
2209 else
2212 /* Mark xactStopTimestamp as unset. */
2214
2215 /*
2216 * initialize other subsystems for new transaction
2217 */
2218 AtStart_GUC();
2219 AtStart_Cache();
2221
2222 /*
2223 * done with start processing, set current transaction state to "in
2224 * progress"
2225 */
2227
2228 /* Schedule transaction timeout */
2229 if (TransactionTimeout > 0)
2231
2232 ShowTransactionState("StartTransaction");
2233}
2234
2235
2236/*
2237 * CommitTransaction
2238 *
2239 * NB: if you change this routine, better look at PrepareTransaction too!
2240 */
2241static void
2243{
2246 bool is_parallel_worker;
2247
2249
2250 /* Enforce parallel mode restrictions during parallel worker commit. */
2253
2254 ShowTransactionState("CommitTransaction");
2255
2256 /*
2257 * check the current transaction state
2258 */
2259 if (s->state != TRANS_INPROGRESS)
2260 elog(WARNING, "CommitTransaction while in %s state",
2262 Assert(s->parent == NULL);
2263
2264 /*
2265 * Do pre-commit processing that involves calling user-defined code, such
2266 * as triggers. SECURITY_RESTRICTED_OPERATION contexts must not queue an
2267 * action that would run here, because that would bypass the sandbox.
2268 * Since closing cursors could queue trigger actions, triggers could open
2269 * cursors, etc, we have to keep looping until there's nothing left to do.
2270 */
2271 for (;;)
2272 {
2273 /*
2274 * Fire all currently pending deferred triggers.
2275 */
2277
2278 /*
2279 * Close open portals (converting holdable ones into static portals).
2280 * If there weren't any, we are done ... otherwise loop back to check
2281 * if they queued deferred triggers. Lather, rinse, repeat.
2282 */
2283 if (!PreCommit_Portals(false))
2284 break;
2285 }
2286
2287 /*
2288 * The remaining actions cannot call any user-defined code, so it's safe
2289 * to start shutting down within-transaction services. But note that most
2290 * of this stuff could still throw an error, which would switch us into
2291 * the transaction-abort path.
2292 */
2293
2296
2297 /*
2298 * If this xact has started any unfinished parallel operation, clean up
2299 * its workers, warning about leaked resources. (But we don't actually
2300 * reset parallelModeLevel till entering TRANS_COMMIT, a bit below. This
2301 * keeps parallel mode restrictions active as long as possible in a
2302 * parallel worker.)
2303 */
2304 AtEOXact_Parallel(true);
2306 {
2307 if (s->parallelModeLevel != 1)
2308 elog(WARNING, "parallelModeLevel is %d not 1 at end of parallel worker transaction",
2310 }
2311 else
2312 {
2313 if (s->parallelModeLevel != 0)
2314 elog(WARNING, "parallelModeLevel is %d not 0 at end of transaction",
2316 }
2317
2318 /* Shut down the deferred-trigger manager */
2319 AfterTriggerEndXact(true);
2320
2321 /*
2322 * Let ON COMMIT management do its thing (must happen after closing
2323 * cursors, to avoid dangling-reference problems)
2324 */
2326
2327 /*
2328 * Synchronize files that are created and not WAL-logged during this
2329 * transaction. This must happen before AtEOXact_RelationMap(), so that we
2330 * don't see committed-but-broken files after a crash.
2331 */
2333
2334 /* close large objects before lower-level cleanup */
2336
2337 /*
2338 * Insert notifications sent by NOTIFY commands into the queue. This
2339 * should be late in the pre-commit sequence to minimize time spent
2340 * holding the notify-insertion lock. However, this could result in
2341 * creating a snapshot, so we must do it before serializable cleanup.
2342 */
2344
2345 /*
2346 * Mark serializable transaction as complete for predicate locking
2347 * purposes. This should be done as late as we can put it and still allow
2348 * errors to be raised for failure patterns found at commit. This is not
2349 * appropriate in a parallel worker however, because we aren't committing
2350 * the leader's transaction and its serializable state will live on.
2351 */
2352 if (!is_parallel_worker)
2354
2355 /* Prevent cancel/die interrupt while cleaning up */
2357
2358 /* Commit updates to the relation map --- do this as late as possible */
2360
2361 /*
2362 * set the current transaction state information appropriately during
2363 * commit processing
2364 */
2365 s->state = TRANS_COMMIT;
2366 s->parallelModeLevel = 0;
2367 s->parallelChildXact = false; /* should be false already */
2368
2369 /* Disable transaction timeout */
2370 if (TransactionTimeout > 0)
2372
2373 if (!is_parallel_worker)
2374 {
2375 /*
2376 * We need to mark our XIDs as committed in pg_xact. This is where we
2377 * durably commit.
2378 */
2380 }
2381 else
2382 {
2383 /*
2384 * We must not mark our XID committed; the parallel leader is
2385 * responsible for that.
2386 */
2388
2389 /*
2390 * Make sure the leader will know about any WAL we wrote before it
2391 * commits.
2392 */
2394 }
2395
2397
2398 /*
2399 * Let others know about no transaction in progress by me. Note that this
2400 * must be done _before_ releasing locks we hold and _after_
2401 * RecordTransactionCommit.
2402 */
2404
2405 /*
2406 * This is all post-commit cleanup. Note that if an error is raised here,
2407 * it's too late to abort the transaction. This should be just
2408 * noncritical resource releasing.
2409 *
2410 * The ordering of operations is not entirely random. The idea is:
2411 * release resources visible to other backends (eg, files, buffer pins);
2412 * then release locks; then release backend-local resources. We want to
2413 * release locks at the point where any backend waiting for us will see
2414 * our transaction as being fully cleaned up.
2415 *
2416 * Resources that can be associated with individual queries are handled by
2417 * the ResourceOwner mechanism. The other calls here are for backend-wide
2418 * state.
2419 */
2420
2423
2427 true, true);
2428
2429 AtEOXact_Aio(true);
2430
2431 /* Check we've released all buffer pins */
2432 AtEOXact_Buffers(true);
2433
2434 /* Clean up the relation cache */
2436
2437 /* Clean up the type cache */
2439
2440 /*
2441 * Make catalog changes visible to all backends. This has to happen after
2442 * relcache references are dropped (see comments for
2443 * AtEOXact_RelationCache), but before locks are released (if anyone is
2444 * waiting for lock on a relation we've modified, we want them to know
2445 * about the catalog change before they start using the relation).
2446 */
2447 AtEOXact_Inval(true);
2448
2450
2453 true, true);
2456 true, true);
2457
2458 /*
2459 * Likewise, dropping of files deleted during the transaction is best done
2460 * after releasing relcache and buffer pins. (This is not strictly
2461 * necessary during commit, since such pins should have been released
2462 * already, but this ordering is definitely critical during abort.) Since
2463 * this may take many seconds, also delay until after releasing locks.
2464 * Other backends will observe the attendant catalog changes and not
2465 * attempt to access affected files.
2466 */
2468
2469 /*
2470 * Send out notification signals to other backends (and do other
2471 * post-commit NOTIFY cleanup). This must not happen until after our
2472 * transaction is fully done from the viewpoint of other backends.
2473 */
2475
2476 /*
2477 * Everything after this should be purely internal-to-this-backend
2478 * cleanup.
2479 */
2480 AtEOXact_GUC(true, 1);
2481 AtEOXact_SPI(true);
2482 AtEOXact_Enum();
2485 AtEOXact_SMgr();
2486 AtEOXact_Files(true);
2488 AtEOXact_HashTables(true);
2490 AtEOXact_Snapshot(true, false);
2495
2500
2502
2505 s->nestingLevel = 0;
2506 s->gucNestLevel = 0;
2507 s->childXids = NULL;
2508 s->nChildXids = 0;
2509 s->maxChildXids = 0;
2510
2513
2514 /*
2515 * done with commit processing, set current transaction state back to
2516 * default
2517 */
2518 s->state = TRANS_DEFAULT;
2519
2521}
2522
2523
2524/*
2525 * PrepareTransaction
2526 *
2527 * NB: if you change this routine, better look at CommitTransaction too!
2528 */
2529static void
2531{
2535 TimestampTz prepared_at;
2536
2538
2539 ShowTransactionState("PrepareTransaction");
2540
2541 /*
2542 * check the current transaction state
2543 */
2544 if (s->state != TRANS_INPROGRESS)
2545 elog(WARNING, "PrepareTransaction while in %s state",
2547 Assert(s->parent == NULL);
2548
2549 /*
2550 * Do pre-commit processing that involves calling user-defined code, such
2551 * as triggers. Since closing cursors could queue trigger actions,
2552 * triggers could open cursors, etc, we have to keep looping until there's
2553 * nothing left to do.
2554 */
2555 for (;;)
2556 {
2557 /*
2558 * Fire all currently pending deferred triggers.
2559 */
2561
2562 /*
2563 * Close open portals (converting holdable ones into static portals).
2564 * If there weren't any, we are done ... otherwise loop back to check
2565 * if they queued deferred triggers. Lather, rinse, repeat.
2566 */
2567 if (!PreCommit_Portals(true))
2568 break;
2569 }
2570
2572
2573 /*
2574 * The remaining actions cannot call any user-defined code, so it's safe
2575 * to start shutting down within-transaction services. But note that most
2576 * of this stuff could still throw an error, which would switch us into
2577 * the transaction-abort path.
2578 */
2579
2580 /* Shut down the deferred-trigger manager */
2581 AfterTriggerEndXact(true);
2582
2583 /*
2584 * Let ON COMMIT management do its thing (must happen after closing
2585 * cursors, to avoid dangling-reference problems)
2586 */
2588
2589 /*
2590 * Synchronize files that are created and not WAL-logged during this
2591 * transaction. This must happen before EndPrepare(), so that we don't see
2592 * committed-but-broken files after a crash and COMMIT PREPARED.
2593 */
2594 smgrDoPendingSyncs(true, false);
2595
2596 /* close large objects before lower-level cleanup */
2598
2599 /* NOTIFY requires no work at this point */
2600
2601 /*
2602 * Mark serializable transaction as complete for predicate locking
2603 * purposes. This should be done as late as we can put it and still allow
2604 * errors to be raised for failure patterns found at commit.
2605 */
2607
2608 /*
2609 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2610 * this transaction. Having the prepared xact hold locks on another
2611 * backend's temp table seems a bad idea --- for instance it would prevent
2612 * the backend from exiting. There are other problems too, such as how to
2613 * clean up the source backend's local buffers and ON COMMIT state if the
2614 * prepared xact includes a DROP of a temp table.
2615 *
2616 * Other objects types, like functions, operators or extensions, share the
2617 * same restriction as they should not be created, locked or dropped as
2618 * this can mess up with this session or even a follow-up session trying
2619 * to use the same temporary namespace.
2620 *
2621 * We must check this after executing any ON COMMIT actions, because they
2622 * might still access a temp relation.
2623 *
2624 * XXX In principle this could be relaxed to allow some useful special
2625 * cases, such as a temp table created and dropped all within the
2626 * transaction. That seems to require much more bookkeeping though.
2627 */
2629 ereport(ERROR,
2631 errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2632
2633 /*
2634 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2635 * supported if we added cleanup logic to twophase.c, but for now it
2636 * doesn't seem worth the trouble.
2637 */
2639 ereport(ERROR,
2641 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2642
2643 /* Prevent cancel/die interrupt while cleaning up */
2645
2646 /*
2647 * set the current transaction state information appropriately during
2648 * prepare processing
2649 */
2650 s->state = TRANS_PREPARE;
2651
2652 /* Disable transaction timeout */
2653 if (TransactionTimeout > 0)
2655
2656 prepared_at = GetCurrentTimestamp();
2657
2658 /*
2659 * Reserve the GID for this transaction. This could fail if the requested
2660 * GID is invalid or already in use.
2661 */
2662 gxact = MarkAsPreparing(fxid, prepareGID, prepared_at,
2664 prepareGID = NULL;
2665
2666 /*
2667 * Collect data for the 2PC state file. Note that in general, no actual
2668 * state change should happen in the called modules during this step,
2669 * since it's still possible to fail before commit, and in that case we
2670 * want transaction abort to be able to clean up. (In particular, the
2671 * AtPrepare routines may error out if they find cases they cannot
2672 * handle.) State cleanup should happen in the PostPrepare routines
2673 * below. However, some modules can go ahead and clear state here because
2674 * they wouldn't do anything with it during abort anyway.
2675 *
2676 * Note: because the 2PC state file records will be replayed in the same
2677 * order they are made, the order of these calls has to match the order in
2678 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2679 * PREPARED; in particular, pay attention to whether things should happen
2680 * before or after releasing the transaction's locks.
2681 */
2683
2690
2691 /*
2692 * Here is where we really truly prepare.
2693 *
2694 * We have to record transaction prepares even if we didn't make any
2695 * updates, because the transaction manager might get confused if we lose
2696 * a global transaction.
2697 */
2699
2700 /*
2701 * Now we clean up backend-internal state and release internal resources.
2702 */
2703
2704 /* Reset XactLastRecEnd until the next transaction writes something */
2705 XactLastRecEnd = 0;
2706
2707 /*
2708 * Transfer our locks to a dummy PGPROC. This has to be done before
2709 * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2710 * conclude "xact already committed or aborted" for our locks.
2711 */
2712 PostPrepare_Locks(fxid);
2713
2714 /*
2715 * Let others know about no transaction in progress by me. This has to be
2716 * done *after* the prepared transaction has been marked valid, else
2717 * someone may think it is unlocked and recyclable.
2718 */
2720
2721 /*
2722 * In normal commit-processing, this is all non-critical post-transaction
2723 * cleanup. When the transaction is prepared, however, it's important
2724 * that the locks and other per-backend resources are transferred to the
2725 * prepared transaction's PGPROC entry. Note that if an error is raised
2726 * here, it's too late to abort the transaction. XXX: This probably should
2727 * be in a critical section, to force a PANIC if any of this fails, but
2728 * that cure could be worse than the disease.
2729 */
2730
2732
2735 true, true);
2736
2737 AtEOXact_Aio(true);
2738
2739 /* Check we've released all buffer pins */
2740 AtEOXact_Buffers(true);
2741
2742 /* Clean up the relation cache */
2744
2745 /* Clean up the type cache */
2747
2748 /* notify doesn't need a postprepare call */
2749
2751
2753
2755
2757
2759
2762 true, true);
2765 true, true);
2766
2767 /*
2768 * Allow another backend to finish the transaction. After
2769 * PostPrepare_Twophase(), the transaction is completely detached from our
2770 * backend. The rest is just non-critical cleanup of backend-local state.
2771 */
2773
2774 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2775 AtEOXact_GUC(true, 1);
2776 AtEOXact_SPI(true);
2777 AtEOXact_Enum();
2779 AtEOXact_Namespace(true, false);
2780 AtEOXact_SMgr();
2781 AtEOXact_Files(true);
2783 AtEOXact_HashTables(true);
2784 /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2785 AtEOXact_Snapshot(true, true);
2786 /* we treat PREPARE as ROLLBACK so far as waking workers goes */
2791
2797
2799
2802 s->nestingLevel = 0;
2803 s->gucNestLevel = 0;
2804 s->childXids = NULL;
2805 s->nChildXids = 0;
2806 s->maxChildXids = 0;
2807
2810
2811 /*
2812 * done with 1st phase commit processing, set current transaction state
2813 * back to default
2814 */
2815 s->state = TRANS_DEFAULT;
2816
2818}
2819
2820
2821/*
2822 * AbortTransaction
2823 */
2824static void
2826{
2829 bool is_parallel_worker;
2830
2831 /* Prevent cancel/die interrupt while cleaning up */
2833
2834 /* Disable transaction timeout */
2835 if (TransactionTimeout > 0)
2837
2838 /* Make sure we have a valid memory context and resource owner */
2841
2842 /*
2843 * Release any LW locks we might be holding as quickly as possible.
2844 * (Regular locks, however, must be held till we finish aborting.)
2845 * Releasing LW locks is critical since we might try to grab them again
2846 * while cleaning up!
2847 */
2849
2850 /*
2851 * Cleanup waiting for LSN if any.
2852 */
2854
2855 /* Clear wait information and command progress indicator */
2858
2860
2861 /* Clean up buffer content locks, too */
2862 UnlockBuffers();
2863
2864 /* Reset WAL record construction state */
2866
2867 /* Cancel condition variable sleep */
2869
2870 /*
2871 * Also clean up any open wait for lock, since the lock manager will choke
2872 * if we try to wait for another lock before doing this.
2873 */
2875
2876 /*
2877 * If any timeout events are still active, make sure the timeout interrupt
2878 * is scheduled. This covers possible loss of a timeout interrupt due to
2879 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2880 * We delay this till after LockErrorCleanup so that we don't uselessly
2881 * reschedule lock or deadlock check timeouts.
2882 */
2884
2885 /*
2886 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2887 * handler. We do this fairly early in the sequence so that the timeout
2888 * infrastructure will be functional if needed while aborting.
2889 */
2891
2892 /*
2893 * check the current transaction state
2894 */
2896 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2897 elog(WARNING, "AbortTransaction while in %s state",
2899 Assert(s->parent == NULL);
2900
2901 /*
2902 * set the current transaction state information appropriately during the
2903 * abort processing
2904 */
2905 s->state = TRANS_ABORT;
2906
2907 /*
2908 * Reset user ID which might have been changed transiently. We need this
2909 * to clean up in case control escaped out of a SECURITY DEFINER function
2910 * or other local change of CurrentUserId; therefore, the prior value of
2911 * SecurityRestrictionContext also needs to be restored.
2912 *
2913 * (Note: it is not necessary to restore session authorization or role
2914 * settings here because those can only be changed via GUC, and GUC will
2915 * take care of rolling them back if need be.)
2916 */
2918
2919 /* Forget about any active REINDEX. */
2921
2922 /* Reset logical streaming state. */
2924
2925 /* Reset snapshot export state. */
2927
2928 /*
2929 * If this xact has started any unfinished parallel operation, clean up
2930 * its workers and exit parallel mode. Don't warn about leaked resources.
2931 */
2932 AtEOXact_Parallel(false);
2933 s->parallelModeLevel = 0;
2934 s->parallelChildXact = false; /* should be false already */
2935
2936 /*
2937 * do abort processing
2938 */
2939 AfterTriggerEndXact(false); /* 'false' means it's abort */
2942 AtEOXact_LargeObject(false);
2946
2947 /*
2948 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2949 * far as assigning an XID to advertise). But if we're inside a parallel
2950 * worker, skip this; the user backend must be the one to write the abort
2951 * record.
2952 */
2953 if (!is_parallel_worker)
2955 else
2956 {
2958
2959 /*
2960 * Since the parallel leader won't get our value of XactLastRecEnd in
2961 * this case, we nudge WAL-writer ourselves in this case. See related
2962 * comments in RecordTransactionAbort for why this matters.
2963 */
2965 }
2966
2968
2969 /*
2970 * Let others know about no transaction in progress by me. Note that this
2971 * must be done _before_ releasing locks we hold and _after_
2972 * RecordTransactionAbort.
2973 */
2975
2976 /*
2977 * Post-abort cleanup. See notes in CommitTransaction() concerning
2978 * ordering. We can skip all of it if the transaction failed before
2979 * creating a resource owner.
2980 */
2982 {
2985 else
2987
2990 false, true);
2991 AtEOXact_Aio(false);
2992 AtEOXact_Buffers(false);
2995 AtEOXact_Inval(false);
2999 false, true);
3002 false, true);
3003 smgrDoPendingDeletes(false);
3004
3005 AtEOXact_GUC(false, 1);
3006 AtEOXact_SPI(false);
3007 AtEOXact_Enum();
3010 AtEOXact_SMgr();
3011 AtEOXact_Files(false);
3013 AtEOXact_HashTables(false);
3019 }
3020
3021 /*
3022 * State remains TRANS_ABORT until CleanupTransaction().
3023 */
3025}
3026
3027/*
3028 * CleanupTransaction
3029 */
3030static void
3032{
3034
3035 /*
3036 * State should still be TRANS_ABORT from AbortTransaction().
3037 */
3038 if (s->state != TRANS_ABORT)
3039 elog(FATAL, "CleanupTransaction: unexpected state %s",
3041
3042 /*
3043 * do abort cleanup processing
3044 */
3045 AtCleanup_Portals(); /* now safe to release portal memory */
3046 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
3047
3048 CurrentResourceOwner = NULL; /* and resource owner */
3054
3055 AtCleanup_Memory(); /* and transaction memory */
3056
3059 s->nestingLevel = 0;
3060 s->gucNestLevel = 0;
3061 s->childXids = NULL;
3062 s->nChildXids = 0;
3063 s->maxChildXids = 0;
3064 s->parallelModeLevel = 0;
3065 s->parallelChildXact = false;
3066
3069
3070 /*
3071 * done with abort processing, set current transaction state back to
3072 * default
3073 */
3074 s->state = TRANS_DEFAULT;
3075}
3076
3077/*
3078 * StartTransactionCommand
3079 */
3080void
3082{
3084
3085 switch (s->blockState)
3086 {
3087 /*
3088 * if we aren't in a transaction block, we just do our usual start
3089 * transaction.
3090 */
3091 case TBLOCK_DEFAULT:
3094 break;
3095
3096 /*
3097 * We are somewhere in a transaction block or subtransaction and
3098 * about to start a new command. For now we do nothing, but
3099 * someday we may do command-local resource initialization. (Note
3100 * that any needed CommandCounterIncrement was done by the
3101 * previous CommitTransactionCommand.)
3102 */
3103 case TBLOCK_INPROGRESS:
3106 break;
3107
3108 /*
3109 * Here we are in a failed transaction block (one of the commands
3110 * caused an abort) so we do nothing but remain in the abort
3111 * state. Eventually we will get a ROLLBACK command which will
3112 * get us out of this state. (It is up to other code to ensure
3113 * that no commands other than ROLLBACK will be processed in these
3114 * states.)
3115 */
3116 case TBLOCK_ABORT:
3117 case TBLOCK_SUBABORT:
3118 break;
3119
3120 /* These cases are invalid. */
3121 case TBLOCK_STARTED:
3122 case TBLOCK_BEGIN:
3124 case TBLOCK_SUBBEGIN:
3125 case TBLOCK_END:
3126 case TBLOCK_SUBRELEASE:
3127 case TBLOCK_SUBCOMMIT:
3128 case TBLOCK_ABORT_END:
3132 case TBLOCK_SUBRESTART:
3134 case TBLOCK_PREPARE:
3135 elog(ERROR, "StartTransactionCommand: unexpected state %s",
3137 break;
3138 }
3139
3140 /*
3141 * We must switch to CurTransactionContext before returning. This is
3142 * already done if we called StartTransaction, otherwise not.
3143 */
3146}
3147
3148
3149/*
3150 * Simple system for saving and restoring transaction characteristics
3151 * (isolation level, read only, deferrable). We need this for transaction
3152 * chaining, so that we can set the characteristics of the new transaction to
3153 * be the same as the previous one. (We need something like this because the
3154 * GUC system resets the characteristics at transaction end, so for example
3155 * just skipping the reset in StartTransaction() won't work.)
3156 */
3157void
3164
3165void
3172
3173/*
3174 * CommitTransactionCommand -- a wrapper function handling the
3175 * loop over subtransactions to avoid a potentially dangerous recursion
3176 * in CommitTransactionCommandInternal().
3177 */
3178void
3180{
3181 /*
3182 * Repeatedly call CommitTransactionCommandInternal() until all the work
3183 * is done.
3184 */
3186 {
3187 }
3188}
3189
3190/*
3191 * CommitTransactionCommandInternal - a function doing an iteration of work
3192 * regarding handling the commit transaction command. In the case of
3193 * subtransactions more than one iterations could be required. Returns
3194 * true when no more iterations required, false otherwise.
3195 */
3196static bool
3198{
3201
3202 /* Must save in case we need to restore below */
3204
3205 switch (s->blockState)
3206 {
3207 /*
3208 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3209 * StartTransactionCommand didn't set the STARTED state
3210 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3211 * by EndParallelWorkerTransaction(), not this function.
3212 */
3213 case TBLOCK_DEFAULT:
3215 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3217 break;
3218
3219 /*
3220 * If we aren't in a transaction block, just do our usual
3221 * transaction commit, and return to the idle state.
3222 */
3223 case TBLOCK_STARTED:
3226 break;
3227
3228 /*
3229 * We are completing a "BEGIN TRANSACTION" command, so we change
3230 * to the "transaction block in progress" state and return. (We
3231 * assume the BEGIN did nothing to the database, so we need no
3232 * CommandCounterIncrement.)
3233 */
3234 case TBLOCK_BEGIN:
3236 break;
3237
3238 /*
3239 * This is the case when we have finished executing a command
3240 * someplace within a transaction block. We increment the command
3241 * counter and return.
3242 */
3243 case TBLOCK_INPROGRESS:
3247 break;
3248
3249 /*
3250 * We are completing a "COMMIT" command. Do it and return to the
3251 * idle state.
3252 */
3253 case TBLOCK_END:
3256 if (s->chain)
3257 {
3260 s->chain = false;
3262 }
3263 break;
3264
3265 /*
3266 * Here we are in the middle of a transaction block but one of the
3267 * commands caused an abort so we do nothing but remain in the
3268 * abort state. Eventually we will get a ROLLBACK command.
3269 */
3270 case TBLOCK_ABORT:
3271 case TBLOCK_SUBABORT:
3272 break;
3273
3274 /*
3275 * Here we were in an aborted transaction block and we just got
3276 * the ROLLBACK command from the user, so clean up the
3277 * already-aborted transaction and return to the idle state.
3278 */
3279 case TBLOCK_ABORT_END:
3282 if (s->chain)
3283 {
3286 s->chain = false;
3288 }
3289 break;
3290
3291 /*
3292 * Here we were in a perfectly good transaction block but the user
3293 * told us to ROLLBACK anyway. We have to abort the transaction
3294 * and then clean up.
3295 */
3300 if (s->chain)
3301 {
3304 s->chain = false;
3306 }
3307 break;
3308
3309 /*
3310 * We are completing a "PREPARE TRANSACTION" command. Do it and
3311 * return to the idle state.
3312 */
3313 case TBLOCK_PREPARE:
3316 break;
3317
3318 /*
3319 * The user issued a SAVEPOINT inside a transaction block. Start a
3320 * subtransaction. (DefineSavepoint already did PushTransaction,
3321 * so as to have someplace to put the SUBBEGIN state.)
3322 */
3323 case TBLOCK_SUBBEGIN:
3326 break;
3327
3328 /*
3329 * The user issued a RELEASE command, so we end the current
3330 * subtransaction and return to the parent transaction. The parent
3331 * might be ended too, so repeat till we find an INPROGRESS
3332 * transaction or subtransaction.
3333 */
3334 case TBLOCK_SUBRELEASE:
3335 do
3336 {
3338 s = CurrentTransactionState; /* changed by pop */
3339 } while (s->blockState == TBLOCK_SUBRELEASE);
3340
3343 break;
3344
3345 /*
3346 * The user issued a COMMIT, so we end the current subtransaction
3347 * hierarchy and perform final commit. We do this by rolling up
3348 * any subtransactions into their parent, which leads to O(N^2)
3349 * operations with respect to resource owners - this isn't that
3350 * bad until we approach a thousands of savepoints but is
3351 * necessary for correctness should after triggers create new
3352 * resource owners.
3353 */
3354 case TBLOCK_SUBCOMMIT:
3355 do
3356 {
3358 s = CurrentTransactionState; /* changed by pop */
3359 } while (s->blockState == TBLOCK_SUBCOMMIT);
3360 /* If we had a COMMIT command, finish off the main xact too */
3361 if (s->blockState == TBLOCK_END)
3362 {
3363 Assert(s->parent == NULL);
3366 if (s->chain)
3367 {
3370 s->chain = false;
3372 }
3373 }
3374 else if (s->blockState == TBLOCK_PREPARE)
3375 {
3376 Assert(s->parent == NULL);
3379 }
3380 else
3381 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3383 break;
3384
3385 /*
3386 * The current already-failed subtransaction is ending due to a
3387 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3388 * examine the parent (which could be in any of several states).
3389 * As we need to examine the parent, return false to request the
3390 * caller to do the next iteration.
3391 */
3394 return false;
3395
3396 /*
3397 * As above, but it's not dead yet, so abort first.
3398 */
3402 return false;
3403
3404 /*
3405 * The current subtransaction is the target of a ROLLBACK TO
3406 * command. Abort and pop it, then start a new subtransaction
3407 * with the same name.
3408 */
3409 case TBLOCK_SUBRESTART:
3410 {
3411 char *name;
3412 int savepointLevel;
3413
3414 /* save name and keep Cleanup from freeing it */
3415 name = s->name;
3416 s->name = NULL;
3417 savepointLevel = s->savepointLevel;
3418
3421
3423 s = CurrentTransactionState; /* changed by push */
3424 s->name = name;
3425 s->savepointLevel = savepointLevel;
3426
3427 /* This is the same as TBLOCK_SUBBEGIN case */
3431 }
3432 break;
3433
3434 /*
3435 * Same as above, but the subtransaction had already failed, so we
3436 * don't need AbortSubTransaction.
3437 */
3439 {
3440 char *name;
3441 int savepointLevel;
3442
3443 /* save name and keep Cleanup from freeing it */
3444 name = s->name;
3445 s->name = NULL;
3446 savepointLevel = s->savepointLevel;
3447
3449
3451 s = CurrentTransactionState; /* changed by push */
3452 s->name = name;
3453 s->savepointLevel = savepointLevel;
3454
3455 /* This is the same as TBLOCK_SUBBEGIN case */
3459 }
3460 break;
3461 }
3462
3463 /* Done, no more iterations required */
3464 return true;
3465}
3466
3467/*
3468 * AbortCurrentTransaction -- a wrapper function handling the
3469 * loop over subtransactions to avoid potentially dangerous recursion in
3470 * AbortCurrentTransactionInternal().
3471 */
3472void
3474{
3475 /*
3476 * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3477 * done.
3478 */
3480 {
3481 }
3482}
3483
3484/*
3485 * AbortCurrentTransactionInternal - a function doing an iteration of work
3486 * regarding handling the current transaction abort. In the case of
3487 * subtransactions more than one iterations could be required. Returns
3488 * true when no more iterations required, false otherwise.
3489 */
3490static bool
3492{
3494
3495 switch (s->blockState)
3496 {
3497 case TBLOCK_DEFAULT:
3498 if (s->state == TRANS_DEFAULT)
3499 {
3500 /* we are idle, so nothing to do */
3501 }
3502 else
3503 {
3504 /*
3505 * We can get here after an error during transaction start
3506 * (state will be TRANS_START). Need to clean up the
3507 * incompletely started transaction. First, adjust the
3508 * low-level state to suppress warning message from
3509 * AbortTransaction.
3510 */
3511 if (s->state == TRANS_START)
3515 }
3516 break;
3517
3518 /*
3519 * If we aren't in a transaction block, we just do the basic abort
3520 * & cleanup transaction. For this purpose, we treat an implicit
3521 * transaction block as if it were a simple statement.
3522 */
3523 case TBLOCK_STARTED:
3528 break;
3529
3530 /*
3531 * If we are in TBLOCK_BEGIN it means something screwed up right
3532 * after reading "BEGIN TRANSACTION". We assume that the user
3533 * will interpret the error as meaning the BEGIN failed to get him
3534 * into a transaction block, so we should abort and return to idle
3535 * state.
3536 */
3537 case TBLOCK_BEGIN:
3541 break;
3542
3543 /*
3544 * We are somewhere in a transaction block and we've gotten a
3545 * failure, so we abort the transaction and set up the persistent
3546 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3547 */
3548 case TBLOCK_INPROGRESS:
3552 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3553 break;
3554
3555 /*
3556 * Here, we failed while trying to COMMIT. Clean up the
3557 * transaction and return to idle state (we do not want to stay in
3558 * the transaction).
3559 */
3560 case TBLOCK_END:
3564 break;
3565
3566 /*
3567 * Here, we are already in an aborted transaction state and are
3568 * waiting for a ROLLBACK, but for some reason we failed again! So
3569 * we just remain in the abort state.
3570 */
3571 case TBLOCK_ABORT:
3572 case TBLOCK_SUBABORT:
3573 break;
3574
3575 /*
3576 * We are in a failed transaction and we got the ROLLBACK command.
3577 * We have already aborted, we just need to cleanup and go to idle
3578 * state.
3579 */
3580 case TBLOCK_ABORT_END:
3583 break;
3584
3585 /*
3586 * We are in a live transaction and we got a ROLLBACK command.
3587 * Abort, cleanup, go to idle state.
3588 */
3593 break;
3594
3595 /*
3596 * Here, we failed while trying to PREPARE. Clean up the
3597 * transaction and return to idle state (we do not want to stay in
3598 * the transaction).
3599 */
3600 case TBLOCK_PREPARE:
3604 break;
3605
3606 /*
3607 * We got an error inside a subtransaction. Abort just the
3608 * subtransaction, and go to the persistent SUBABORT state until
3609 * we get ROLLBACK.
3610 */
3614 break;
3615
3616 /*
3617 * If we failed while trying to create a subtransaction, clean up
3618 * the broken subtransaction and abort the parent. The same
3619 * applies if we get a failure while ending a subtransaction. As
3620 * we need to abort the parent, return false to request the caller
3621 * to do the next iteration.
3622 */
3623 case TBLOCK_SUBBEGIN:
3624 case TBLOCK_SUBRELEASE:
3625 case TBLOCK_SUBCOMMIT:
3627 case TBLOCK_SUBRESTART:
3630 return false;
3631
3632 /*
3633 * Same as above, except the Abort() was already done.
3634 */
3638 return false;
3639 }
3640
3641 /* Done, no more iterations required */
3642 return true;
3643}
3644
3645/*
3646 * PreventInTransactionBlock
3647 *
3648 * This routine is to be called by statements that must not run inside
3649 * a transaction block, typically because they have non-rollback-able
3650 * side effects or do internal commits.
3651 *
3652 * If this routine completes successfully, then the calling statement is
3653 * guaranteed that if it completes without error, its results will be
3654 * committed immediately.
3655 *
3656 * If we have already started a transaction block, issue an error; also issue
3657 * an error if we appear to be running inside a user-defined function (which
3658 * could issue more commands and possibly cause a failure after the statement
3659 * completes). Subtransactions are verboten too.
3660 *
3661 * We must also set XACT_FLAGS_NEEDIMMEDIATECOMMIT in MyXactFlags, to ensure
3662 * that postgres.c follows through by committing after the statement is done.
3663 *
3664 * isTopLevel: passed down from ProcessUtility to determine whether we are
3665 * inside a function. (We will always fail if this is false, but it's
3666 * convenient to centralize the check here instead of making callers do it.)
3667 * stmtType: statement type name, for error messages.
3668 */
3669void
3670PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
3671{
3672 /*
3673 * xact block already started?
3674 */
3675 if (IsTransactionBlock())
3676 ereport(ERROR,
3678 /* translator: %s represents an SQL statement name */
3679 errmsg("%s cannot run inside a transaction block",
3680 stmtType)));
3681
3682 /*
3683 * subtransaction?
3684 */
3685 if (IsSubTransaction())
3686 ereport(ERROR,
3688 /* translator: %s represents an SQL statement name */
3689 errmsg("%s cannot run inside a subtransaction",
3690 stmtType)));
3691
3692 /*
3693 * inside a function call?
3694 */
3695 if (!isTopLevel)
3696 ereport(ERROR,
3698 /* translator: %s represents an SQL statement name */
3699 errmsg("%s cannot be executed from a function or procedure",
3700 stmtType)));
3701
3702 /* If we got past IsTransactionBlock test, should be in default state */
3705 elog(FATAL, "cannot prevent transaction chain");
3706
3707 /* All okay. Set the flag to make sure the right thing happens later. */
3709}
3710
3711/*
3712 * WarnNoTransactionBlock
3713 * RequireTransactionBlock
3714 *
3715 * These two functions allow for warnings or errors if a command is executed
3716 * outside of a transaction block. This is useful for commands that have no
3717 * effects that persist past transaction end (and so calling them outside a
3718 * transaction block is presumably an error). DECLARE CURSOR is an example.
3719 * While top-level transaction control commands (BEGIN/COMMIT/ABORT) and SET
3720 * that have no effect issue warnings, all other no-effect commands generate
3721 * errors.
3722 *
3723 * If we appear to be running inside a user-defined function, we do not
3724 * issue anything, since the function could issue more commands that make
3725 * use of the current statement's results. Likewise subtransactions.
3726 * Thus these are inverses for PreventInTransactionBlock.
3727 *
3728 * isTopLevel: passed down from ProcessUtility to determine whether we are
3729 * inside a function.
3730 * stmtType: statement type name, for warning or error messages.
3731 */
3732void
3733WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
3734{
3735 CheckTransactionBlock(isTopLevel, false, stmtType);
3736}
3737
3738void
3739RequireTransactionBlock(bool isTopLevel, const char *stmtType)
3740{
3741 CheckTransactionBlock(isTopLevel, true, stmtType);
3742}
3743
3744/*
3745 * This is the implementation of the above two.
3746 */
3747static void
3748CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
3749{
3750 /*
3751 * xact block already started?
3752 */
3753 if (IsTransactionBlock())
3754 return;
3755
3756 /*
3757 * subtransaction?
3758 */
3759 if (IsSubTransaction())
3760 return;
3761
3762 /*
3763 * inside a function call?
3764 */
3765 if (!isTopLevel)
3766 return;
3767
3770 /* translator: %s represents an SQL statement name */
3771 errmsg("%s can only be used in transaction blocks",
3772 stmtType)));
3773}
3774
3775/*
3776 * IsInTransactionBlock
3777 *
3778 * This routine is for statements that need to behave differently inside
3779 * a transaction block than when running as single commands. ANALYZE is
3780 * currently the only example.
3781 *
3782 * If this routine returns "false", then the calling statement is allowed
3783 * to perform internal transaction-commit-and-start cycles; there is not a
3784 * risk of messing up any transaction already in progress. (Note that this
3785 * is not the identical guarantee provided by PreventInTransactionBlock,
3786 * since we will not force a post-statement commit.)
3787 *
3788 * isTopLevel: passed down from ProcessUtility to determine whether we are
3789 * inside a function.
3790 */
3791bool
3793{
3794 /*
3795 * Return true on same conditions that would make
3796 * PreventInTransactionBlock error out
3797 */
3798 if (IsTransactionBlock())
3799 return true;
3800
3801 if (IsSubTransaction())
3802 return true;
3803
3804 if (!isTopLevel)
3805 return true;
3806
3809 return true;
3810
3811 return false;
3812}
3813
3814
3815/*
3816 * Register or deregister callback functions for start- and end-of-xact
3817 * operations.
3818 *
3819 * These functions are intended for use by dynamically loaded modules.
3820 * For built-in modules we generally just hardwire the appropriate calls
3821 * (mainly because it's easier to control the order that way, where needed).
3822 *
3823 * At transaction end, the callback occurs post-commit or post-abort, so the
3824 * callback functions can only do noncritical cleanup.
3825 */
3826void
3828{
3829 XactCallbackItem *item;
3830
3831 item = (XactCallbackItem *)
3833 item->callback = callback;
3834 item->arg = arg;
3835 item->next = Xact_callbacks;
3836 Xact_callbacks = item;
3837}
3838
3839void
3841{
3842 XactCallbackItem *item;
3843 XactCallbackItem *prev;
3844
3845 prev = NULL;
3846 for (item = Xact_callbacks; item; prev = item, item = item->next)
3847 {
3848 if (item->callback == callback && item->arg == arg)
3849 {
3850 if (prev)
3851 prev->next = item->next;
3852 else
3853 Xact_callbacks = item->next;
3854 pfree(item);
3855 break;
3856 }
3857 }
3858}
3859
3860static void
3862{
3863 XactCallbackItem *item;
3865
3866 for (item = Xact_callbacks; item; item = next)
3867 {
3868 /* allow callbacks to unregister themselves when called */
3869 next = item->next;
3870 item->callback(event, item->arg);
3871 }
3872}
3873
3874
3875/*
3876 * Register or deregister callback functions for start- and end-of-subxact
3877 * operations.
3878 *
3879 * Pretty much same as above, but for subtransaction events.
3880 *
3881 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3882 * so the callback functions can only do noncritical cleanup. At
3883 * subtransaction start, the callback is called when the subtransaction has
3884 * finished initializing.
3885 */
3886void
3888{
3889 SubXactCallbackItem *item;
3890
3891 item = (SubXactCallbackItem *)
3893 item->callback = callback;
3894 item->arg = arg;
3895 item->next = SubXact_callbacks;
3896 SubXact_callbacks = item;
3897}
3898
3899void
3901{
3902 SubXactCallbackItem *item;
3903 SubXactCallbackItem *prev;
3904
3905 prev = NULL;
3906 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3907 {
3908 if (item->callback == callback && item->arg == arg)
3909 {
3910 if (prev)
3911 prev->next = item->next;
3912 else
3913 SubXact_callbacks = item->next;
3914 pfree(item);
3915 break;
3916 }
3917 }
3918}
3919
3920static void
3924{
3925 SubXactCallbackItem *item;
3927
3928 for (item = SubXact_callbacks; item; item = next)
3929 {
3930 /* allow callbacks to unregister themselves when called */
3931 next = item->next;
3932 item->callback(event, mySubid, parentSubid, item->arg);
3933 }
3934}
3935
3936
3937/* ----------------------------------------------------------------
3938 * transaction block support
3939 * ----------------------------------------------------------------
3940 */
3941
3942/*
3943 * BeginTransactionBlock
3944 * This executes a BEGIN command.
3945 */
3946void
3948{
3950
3951 switch (s->blockState)
3952 {
3953 /*
3954 * We are not inside a transaction block, so allow one to begin.
3955 */
3956 case TBLOCK_STARTED:
3958 break;
3959
3960 /*
3961 * BEGIN converts an implicit transaction block to a regular one.
3962 * (Note that we allow this even if we've already done some
3963 * commands, which is a bit odd but matches historical practice.)
3964 */
3967 break;
3968
3969 /*
3970 * Already a transaction block in progress.
3971 */
3972 case TBLOCK_INPROGRESS:
3975 case TBLOCK_ABORT:
3976 case TBLOCK_SUBABORT:
3979 errmsg("there is already a transaction in progress")));
3980 break;
3981
3982 /* These cases are invalid. */
3983 case TBLOCK_DEFAULT:
3984 case TBLOCK_BEGIN:
3985 case TBLOCK_SUBBEGIN:
3986 case TBLOCK_END:
3987 case TBLOCK_SUBRELEASE:
3988 case TBLOCK_SUBCOMMIT:
3989 case TBLOCK_ABORT_END:
3993 case TBLOCK_SUBRESTART:
3995 case TBLOCK_PREPARE:
3996 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3998 break;
3999 }
4000}
4001
4002/*
4003 * PrepareTransactionBlock
4004 * This executes a PREPARE command.
4005 *
4006 * Since PREPARE may actually do a ROLLBACK, the result indicates what
4007 * happened: true for PREPARE, false for ROLLBACK.
4008 *
4009 * Note that we don't actually do anything here except change blockState.
4010 * The real work will be done in the upcoming PrepareTransaction().
4011 * We do it this way because it's not convenient to change memory context,
4012 * resource owner, etc while executing inside a Portal.
4013 */
4014bool
4016{
4018 bool result;
4019
4020 /* Set up to commit the current transaction */
4021 result = EndTransactionBlock(false);
4022
4023 /* If successful, change outer tblock state to PREPARE */
4024 if (result)
4025 {
4027
4028 while (s->parent != NULL)
4029 s = s->parent;
4030
4031 if (s->blockState == TBLOCK_END)
4032 {
4033 /* Save GID where PrepareTransaction can find it again */
4035
4037 }
4038 else
4039 {
4040 /*
4041 * ignore case where we are not in a transaction;
4042 * EndTransactionBlock already issued a warning.
4043 */
4046 /* Don't send back a PREPARE result tag... */
4047 result = false;
4048 }
4049 }
4050
4051 return result;
4052}
4053
4054/*
4055 * EndTransactionBlock
4056 * This executes a COMMIT command.
4057 *
4058 * Since COMMIT may actually do a ROLLBACK, the result indicates what
4059 * happened: true for COMMIT, false for ROLLBACK.
4060 *
4061 * Note that we don't actually do anything here except change blockState.
4062 * The real work will be done in the upcoming CommitTransactionCommand().
4063 * We do it this way because it's not convenient to change memory context,
4064 * resource owner, etc while executing inside a Portal.
4065 */
4066bool
4068{
4070 bool result = false;
4071
4072 switch (s->blockState)
4073 {
4074 /*
4075 * We are in a transaction block, so tell CommitTransactionCommand
4076 * to COMMIT.
4077 */
4078 case TBLOCK_INPROGRESS:
4080 result = true;
4081 break;
4082
4083 /*
4084 * We are in an implicit transaction block. If AND CHAIN was
4085 * specified, error. Otherwise commit, but issue a warning
4086 * because there was no explicit BEGIN before this.
4087 */
4089 if (chain)
4090 ereport(ERROR,
4092 /* translator: %s represents an SQL statement name */
4093 errmsg("%s can only be used in transaction blocks",
4094 "COMMIT AND CHAIN")));
4095 else
4098 errmsg("there is no transaction in progress")));
4100 result = true;
4101 break;
4102
4103 /*
4104 * We are in a failed transaction block. Tell
4105 * CommitTransactionCommand it's time to exit the block.
4106 */
4107 case TBLOCK_ABORT:
4109 break;
4110
4111 /*
4112 * We are in a live subtransaction block. Set up to subcommit all
4113 * open subtransactions and then commit the main transaction.
4114 */
4116 while (s->parent != NULL)
4117 {
4120 else
4121 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4123 s = s->parent;
4124 }
4125 if (s->blockState == TBLOCK_INPROGRESS)
4127 else
4128 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4130 result = true;
4131 break;
4132
4133 /*
4134 * Here we are inside an aborted subtransaction. Treat the COMMIT
4135 * as ROLLBACK: set up to abort everything and exit the main
4136 * transaction.
4137 */
4138 case TBLOCK_SUBABORT:
4139 while (s->parent != NULL)
4140 {
4143 else if (s->blockState == TBLOCK_SUBABORT)
4145 else
4146 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4148 s = s->parent;
4149 }
4150 if (s->blockState == TBLOCK_INPROGRESS)
4152 else if (s->blockState == TBLOCK_ABORT)
4154 else
4155 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4157 break;
4158
4159 /*
4160 * The user issued COMMIT when not inside a transaction. For
4161 * COMMIT without CHAIN, issue a WARNING, staying in
4162 * TBLOCK_STARTED state. The upcoming call to
4163 * CommitTransactionCommand() will then close the transaction and
4164 * put us back into the default state. For COMMIT AND CHAIN,
4165 * error.
4166 */
4167 case TBLOCK_STARTED:
4168 if (chain)
4169 ereport(ERROR,
4171 /* translator: %s represents an SQL statement name */
4172 errmsg("%s can only be used in transaction blocks",
4173 "COMMIT AND CHAIN")));
4174 else
4177 errmsg("there is no transaction in progress")));
4178 result = true;
4179 break;
4180
4181 /*
4182 * The user issued a COMMIT that somehow ran inside a parallel
4183 * worker. We can't cope with that.
4184 */
4186 ereport(FATAL,
4188 errmsg("cannot commit during a parallel operation")));
4189 break;
4190
4191 /* These cases are invalid. */
4192 case TBLOCK_DEFAULT:
4193 case TBLOCK_BEGIN:
4194 case TBLOCK_SUBBEGIN:
4195 case TBLOCK_END:
4196 case TBLOCK_SUBRELEASE:
4197 case TBLOCK_SUBCOMMIT:
4198 case TBLOCK_ABORT_END:
4202 case TBLOCK_SUBRESTART:
4204 case TBLOCK_PREPARE:
4205 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4207 break;
4208 }
4209
4211 s->blockState == TBLOCK_END ||
4214
4215 s->chain = chain;
4216
4217 return result;
4218}
4219
4220/*
4221 * UserAbortTransactionBlock
4222 * This executes a ROLLBACK command.
4223 *
4224 * As above, we don't actually do anything here except change blockState.
4225 */
4226void
4228{
4230
4231 switch (s->blockState)
4232 {
4233 /*
4234 * We are inside a transaction block and we got a ROLLBACK command
4235 * from the user, so tell CommitTransactionCommand to abort and
4236 * exit the transaction block.
4237 */
4238 case TBLOCK_INPROGRESS:
4240 break;
4241
4242 /*
4243 * We are inside a failed transaction block and we got a ROLLBACK
4244 * command from the user. Abort processing is already done, so
4245 * CommitTransactionCommand just has to cleanup and go back to
4246 * idle state.
4247 */
4248 case TBLOCK_ABORT:
4250 break;
4251
4252 /*
4253 * We are inside a subtransaction. Mark everything up to top
4254 * level as exitable.
4255 */
4257 case TBLOCK_SUBABORT:
4258 while (s->parent != NULL)
4259 {
4262 else if (s->blockState == TBLOCK_SUBABORT)
4264 else
4265 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4267 s = s->parent;
4268 }
4269 if (s->blockState == TBLOCK_INPROGRESS)
4271 else if (s->blockState == TBLOCK_ABORT)
4273 else
4274 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4276 break;
4277
4278 /*
4279 * The user issued ABORT when not inside a transaction. For
4280 * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4281 * The upcoming call to CommitTransactionCommand() will then put
4282 * us back into the default state. For ROLLBACK AND CHAIN, error.
4283 *
4284 * We do the same thing with ABORT inside an implicit transaction,
4285 * although in this case we might be rolling back actual database
4286 * state changes. (It's debatable whether we should issue a
4287 * WARNING in this case, but we have done so historically.)
4288 */
4289 case TBLOCK_STARTED:
4291 if (chain)
4292 ereport(ERROR,
4294 /* translator: %s represents an SQL statement name */
4295 errmsg("%s can only be used in transaction blocks",
4296 "ROLLBACK AND CHAIN")));
4297 else
4300 errmsg("there is no transaction in progress")));
4302 break;
4303
4304 /*
4305 * The user issued an ABORT that somehow ran inside a parallel
4306 * worker. We can't cope with that.
4307 */
4309 ereport(FATAL,
4311 errmsg("cannot abort during a parallel operation")));
4312 break;
4313
4314 /* These cases are invalid. */
4315 case TBLOCK_DEFAULT:
4316 case TBLOCK_BEGIN:
4317 case TBLOCK_SUBBEGIN:
4318 case TBLOCK_END:
4319 case TBLOCK_SUBRELEASE:
4320 case TBLOCK_SUBCOMMIT:
4321 case TBLOCK_ABORT_END:
4325 case TBLOCK_SUBRESTART:
4327 case TBLOCK_PREPARE:
4328 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4330 break;
4331 }
4332
4335
4336 s->chain = chain;
4337}
4338
4339/*
4340 * BeginImplicitTransactionBlock
4341 * Start an implicit transaction block if we're not already in one.
4342 *
4343 * Unlike BeginTransactionBlock, this is called directly from the main loop
4344 * in postgres.c, not within a Portal. So we can just change blockState
4345 * without a lot of ceremony. We do not expect caller to do
4346 * CommitTransactionCommand/StartTransactionCommand.
4347 */
4348void
4350{
4352
4353 /*
4354 * If we are in STARTED state (that is, no transaction block is open),
4355 * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4356 * block.
4357 *
4358 * For caller convenience, we consider all other transaction states as
4359 * legal here; otherwise the caller would need its own state check, which
4360 * seems rather pointless.
4361 */
4362 if (s->blockState == TBLOCK_STARTED)
4364}
4365
4366/*
4367 * EndImplicitTransactionBlock
4368 * End an implicit transaction block, if we're in one.
4369 *
4370 * Like EndTransactionBlock, we just make any needed blockState change here.
4371 * The real work will be done in the upcoming CommitTransactionCommand().
4372 */
4373void
4375{
4377
4378 /*
4379 * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4380 * allowing CommitTransactionCommand to commit whatever happened during
4381 * the implicit transaction block as though it were a single statement.
4382 *
4383 * For caller convenience, we consider all other transaction states as
4384 * legal here; otherwise the caller would need its own state check, which
4385 * seems rather pointless.
4386 */
4389}
4390
4391/*
4392 * DefineSavepoint
4393 * This executes a SAVEPOINT command.
4394 */
4395void
4397{
4399
4400 /*
4401 * Workers synchronize transaction state at the beginning of each parallel
4402 * operation, so we can't account for new subtransactions after that
4403 * point. (Note that this check will certainly error out if s->blockState
4404 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4405 * below.)
4406 */
4408 ereport(ERROR,
4410 errmsg("cannot define savepoints during a parallel operation")));
4411
4412 switch (s->blockState)
4413 {
4414 case TBLOCK_INPROGRESS:
4416 /* Normal subtransaction start */
4418 s = CurrentTransactionState; /* changed by push */
4419
4420 /*
4421 * Savepoint names, like the TransactionState block itself, live
4422 * in TopTransactionContext.
4423 */
4424 if (name)
4426 break;
4427
4428 /*
4429 * We disallow savepoint commands in implicit transaction blocks.
4430 * There would be no great difficulty in allowing them so far as
4431 * this module is concerned, but a savepoint seems inconsistent
4432 * with exec_simple_query's behavior of abandoning the whole query
4433 * string upon error. Also, the point of an implicit transaction
4434 * block (as opposed to a regular one) is to automatically close
4435 * after an error, so it's hard to see how a savepoint would fit
4436 * into that.
4437 *
4438 * The error messages for this are phrased as if there were no
4439 * active transaction block at all, which is historical but
4440 * perhaps could be improved.
4441 */
4443 ereport(ERROR,
4445 /* translator: %s represents an SQL statement name */
4446 errmsg("%s can only be used in transaction blocks",
4447 "SAVEPOINT")));
4448 break;
4449
4450 /* These cases are invalid. */
4451 case TBLOCK_DEFAULT:
4452 case TBLOCK_STARTED:
4453 case TBLOCK_BEGIN:
4455 case TBLOCK_SUBBEGIN:
4456 case TBLOCK_END:
4457 case TBLOCK_SUBRELEASE:
4458 case TBLOCK_SUBCOMMIT:
4459 case TBLOCK_ABORT:
4460 case TBLOCK_SUBABORT:
4461 case TBLOCK_ABORT_END:
4465 case TBLOCK_SUBRESTART:
4467 case TBLOCK_PREPARE:
4468 elog(FATAL, "DefineSavepoint: unexpected state %s",
4470 break;
4471 }
4472}
4473
4474/*
4475 * ReleaseSavepoint
4476 * This executes a RELEASE command.
4477 *
4478 * As above, we don't actually do anything here except change blockState.
4479 */
4480void
4482{
4484 TransactionState target,
4485 xact;
4486
4487 /*
4488 * Workers synchronize transaction state at the beginning of each parallel
4489 * operation, so we can't account for transaction state change after that
4490 * point. (Note that this check will certainly error out if s->blockState
4491 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4492 * below.)
4493 */
4495 ereport(ERROR,
4497 errmsg("cannot release savepoints during a parallel operation")));
4498
4499 switch (s->blockState)
4500 {
4501 /*
4502 * We can't release a savepoint if there is no savepoint defined.
4503 */
4504 case TBLOCK_INPROGRESS:
4505 ereport(ERROR,
4507 errmsg("savepoint \"%s\" does not exist", name)));
4508 break;
4509
4511 /* See comment about implicit transactions in DefineSavepoint */
4512 ereport(ERROR,
4514 /* translator: %s represents an SQL statement name */
4515 errmsg("%s can only be used in transaction blocks",
4516 "RELEASE SAVEPOINT")));
4517 break;
4518
4519 /*
4520 * We are in a non-aborted subtransaction. This is the only valid
4521 * case.
4522 */
4524 break;
4525
4526 /* These cases are invalid. */
4527 case TBLOCK_DEFAULT:
4528 case TBLOCK_STARTED:
4529 case TBLOCK_BEGIN:
4531 case TBLOCK_SUBBEGIN:
4532 case TBLOCK_END:
4533 case TBLOCK_SUBRELEASE:
4534 case TBLOCK_SUBCOMMIT:
4535 case TBLOCK_ABORT:
4536 case TBLOCK_SUBABORT:
4537 case TBLOCK_ABORT_END:
4541 case TBLOCK_SUBRESTART:
4543 case TBLOCK_PREPARE:
4544 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4546 break;
4547 }
4548
4549 for (target = s; target; target = target->parent)
4550 {
4551 if (target->name && strcmp(target->name, name) == 0)
4552 break;
4553 }
4554
4555 if (!target)
4556 ereport(ERROR,
4558 errmsg("savepoint \"%s\" does not exist", name)));
4559
4560 /* disallow crossing savepoint level boundaries */
4561 if (target->savepointLevel != s->savepointLevel)
4562 ereport(ERROR,
4564 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4565
4566 /*
4567 * Mark "commit pending" all subtransactions up to the target
4568 * subtransaction. The actual commits will happen when control gets to
4569 * CommitTransactionCommand.
4570 */
4572 for (;;)
4573 {
4574 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
4575 xact->blockState = TBLOCK_SUBRELEASE;
4576 if (xact == target)
4577 break;
4578 xact = xact->parent;
4579 Assert(xact);
4580 }
4581}
4582
4583/*
4584 * RollbackToSavepoint
4585 * This executes a ROLLBACK TO <savepoint> command.
4586 *
4587 * As above, we don't actually do anything here except change blockState.
4588 */
4589void
4591{
4593 TransactionState target,
4594 xact;
4595
4596 /*
4597 * Workers synchronize transaction state at the beginning of each parallel
4598 * operation, so we can't account for transaction state change after that
4599 * point. (Note that this check will certainly error out if s->blockState
4600 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4601 * below.)
4602 */
4604 ereport(ERROR,
4606 errmsg("cannot rollback to savepoints during a parallel operation")));
4607
4608 switch (s->blockState)
4609 {
4610 /*
4611 * We can't rollback to a savepoint if there is no savepoint
4612 * defined.
4613 */
4614 case TBLOCK_INPROGRESS:
4615 case TBLOCK_ABORT:
4616 ereport(ERROR,
4618 errmsg("savepoint \"%s\" does not exist", name)));
4619 break;
4620
4622 /* See comment about implicit transactions in DefineSavepoint */
4623 ereport(ERROR,
4625 /* translator: %s represents an SQL statement name */
4626 errmsg("%s can only be used in transaction blocks",
4627 "ROLLBACK TO SAVEPOINT")));
4628 break;
4629
4630 /*
4631 * There is at least one savepoint, so proceed.
4632 */
4634 case TBLOCK_SUBABORT:
4635 break;
4636
4637 /* These cases are invalid. */
4638 case TBLOCK_DEFAULT:
4639 case TBLOCK_STARTED:
4640 case TBLOCK_BEGIN:
4642 case TBLOCK_SUBBEGIN:
4643 case TBLOCK_END:
4644 case TBLOCK_SUBRELEASE:
4645 case TBLOCK_SUBCOMMIT:
4646 case TBLOCK_ABORT_END:
4650 case TBLOCK_SUBRESTART:
4652 case TBLOCK_PREPARE:
4653 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4655 break;
4656 }
4657
4658 for (target = s; target; target = target->parent)
4659 {
4660 if (target->name && strcmp(target->name, name) == 0)
4661 break;
4662 }
4663
4664 if (!target)
4665 ereport(ERROR,
4667 errmsg("savepoint \"%s\" does not exist", name)));
4668
4669 /* disallow crossing savepoint level boundaries */
4670 if (target->savepointLevel != s->savepointLevel)
4671 ereport(ERROR,
4673 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4674
4675 /*
4676 * Mark "abort pending" all subtransactions up to the target
4677 * subtransaction. The actual aborts will happen when control gets to
4678 * CommitTransactionCommand.
4679 */
4681 for (;;)
4682 {
4683 if (xact == target)
4684 break;
4685 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4687 else if (xact->blockState == TBLOCK_SUBABORT)
4688 xact->blockState = TBLOCK_SUBABORT_END;
4689 else
4690 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4691 BlockStateAsString(xact->blockState));
4692 xact = xact->parent;
4693 Assert(xact);
4694 }
4695
4696 /* And mark the target as "restart pending" */
4697 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4698 xact->blockState = TBLOCK_SUBRESTART;
4699 else if (xact->blockState == TBLOCK_SUBABORT)
4700 xact->blockState = TBLOCK_SUBABORT_RESTART;
4701 else
4702 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4703 BlockStateAsString(xact->blockState));
4704}
4705
4706/*
4707 * BeginInternalSubTransaction
4708 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
4709 * TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_END,
4710 * and TBLOCK_PREPARE states, and therefore it can safely be used in
4711 * functions that might be called when not inside a BEGIN block or when
4712 * running deferred triggers at COMMIT/PREPARE time. Also, it
4713 * automatically does CommitTransactionCommand/StartTransactionCommand
4714 * instead of expecting the caller to do it.
4715 */
4716void
4718{
4721
4722 /*
4723 * Errors within this function are improbable, but if one does happen we
4724 * force a FATAL exit. Callers generally aren't prepared to handle losing
4725 * control, and moreover our transaction state is probably corrupted if we
4726 * fail partway through; so an ordinary ERROR longjmp isn't okay.
4727 */
4728 ExitOnAnyError = true;
4729
4730 /*
4731 * We do not check for parallel mode here. It's permissible to start and
4732 * end "internal" subtransactions while in parallel mode, so long as no
4733 * new XIDs or command IDs are assigned. Enforcement of that occurs in
4734 * AssignTransactionId() and CommandCounterIncrement().
4735 */
4736
4737 switch (s->blockState)
4738 {
4739 case TBLOCK_STARTED:
4740 case TBLOCK_INPROGRESS:
4743 case TBLOCK_END:
4744 case TBLOCK_PREPARE:
4746 /* Normal subtransaction start */
4748 s = CurrentTransactionState; /* changed by push */
4749
4750 /*
4751 * Savepoint names, like the TransactionState block itself, live
4752 * in TopTransactionContext.
4753 */
4754 if (name)
4756 break;
4757
4758 /* These cases are invalid. */
4759 case TBLOCK_DEFAULT:
4760 case TBLOCK_BEGIN:
4761 case TBLOCK_SUBBEGIN:
4762 case TBLOCK_SUBRELEASE:
4763 case TBLOCK_SUBCOMMIT:
4764 case TBLOCK_ABORT:
4765 case TBLOCK_SUBABORT:
4766 case TBLOCK_ABORT_END:
4770 case TBLOCK_SUBRESTART:
4772 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4774 break;
4775 }
4776
4779
4781}
4782
4783/*
4784 * ReleaseCurrentSubTransaction
4785 *
4786 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
4787 * savepoint name (if any).
4788 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4789 */
4790void
4792{
4794
4795 /*
4796 * We do not check for parallel mode here. It's permissible to start and
4797 * end "internal" subtransactions while in parallel mode, so long as no
4798 * new XIDs or command IDs are assigned.
4799 */
4800
4802 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4807 s = CurrentTransactionState; /* changed by pop */
4809}
4810
4811/*
4812 * RollbackAndReleaseCurrentSubTransaction
4813 *
4814 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
4815 * of its savepoint name (if any).
4816 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4817 */
4818void
4820{
4822
4823 /*
4824 * We do not check for parallel mode here. It's permissible to start and
4825 * end "internal" subtransactions while in parallel mode, so long as no
4826 * new XIDs or command IDs are assigned.
4827 */
4828
4829 switch (s->blockState)
4830 {
4831 /* Must be in a subtransaction */
4833 case TBLOCK_SUBABORT:
4834 break;
4835
4836 /* These cases are invalid. */
4837 case TBLOCK_DEFAULT:
4838 case TBLOCK_STARTED:
4839 case TBLOCK_BEGIN:
4842 case TBLOCK_SUBBEGIN:
4843 case TBLOCK_INPROGRESS:
4844 case TBLOCK_END:
4845 case TBLOCK_SUBRELEASE:
4846 case TBLOCK_SUBCOMMIT:
4847 case TBLOCK_ABORT:
4848 case TBLOCK_ABORT_END:
4852 case TBLOCK_SUBRESTART:
4854 case TBLOCK_PREPARE:
4855 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4857 break;
4858 }
4859
4860 /*
4861 * Abort the current subtransaction, if needed.
4862 */
4865
4866 /* And clean it up, too */
4868
4869 s = CurrentTransactionState; /* changed by pop */
4875}
4876
4877/*
4878 * AbortOutOfAnyTransaction
4879 *
4880 * This routine is provided for error recovery purposes. It aborts any
4881 * active transaction or transaction block, leaving the system in a known
4882 * idle state.
4883 */
4884void
4886{
4888
4889 /* Ensure we're not running in a doomed memory context */
4891
4892 /*
4893 * Get out of any transaction or nested transaction
4894 */
4895 do
4896 {
4897 switch (s->blockState)
4898 {
4899 case TBLOCK_DEFAULT:
4900 if (s->state == TRANS_DEFAULT)
4901 {
4902 /* Not in a transaction, do nothing */
4903 }
4904 else
4905 {
4906 /*
4907 * We can get here after an error during transaction start
4908 * (state will be TRANS_START). Need to clean up the
4909 * incompletely started transaction. First, adjust the
4910 * low-level state to suppress warning message from
4911 * AbortTransaction.
4912 */
4913 if (s->state == TRANS_START)
4917 }
4918 break;
4919 case TBLOCK_STARTED:
4920 case TBLOCK_BEGIN:
4921 case TBLOCK_INPROGRESS:
4924 case TBLOCK_END:
4926 case TBLOCK_PREPARE:
4927 /* In a transaction, so clean up */
4931 break;
4932 case TBLOCK_ABORT:
4933 case TBLOCK_ABORT_END:
4934
4935 /*
4936 * AbortTransaction is already done, still need Cleanup.
4937 * However, if we failed partway through running ROLLBACK,
4938 * there will be an active portal running that command, which
4939 * we need to shut down before doing CleanupTransaction.
4940 */
4944 break;
4945
4946 /*
4947 * In a subtransaction, so clean it up and abort parent too
4948 */
4949 case TBLOCK_SUBBEGIN:
4951 case TBLOCK_SUBRELEASE:
4952 case TBLOCK_SUBCOMMIT:
4954 case TBLOCK_SUBRESTART:
4957 s = CurrentTransactionState; /* changed by pop */
4958 break;
4959
4960 case TBLOCK_SUBABORT:
4963 /* As above, but AbortSubTransaction already done */
4964 if (s->curTransactionOwner)
4965 {
4966 /* As in TBLOCK_ABORT, might have a live portal to zap */
4971 }
4973 s = CurrentTransactionState; /* changed by pop */
4974 break;
4975 }
4976 } while (s->blockState != TBLOCK_DEFAULT);
4977
4978 /* Should be out of all subxacts now */
4979 Assert(s->parent == NULL);
4980
4981 /*
4982 * Revert to TopMemoryContext, to ensure we exit in a well-defined state
4983 * whether there were any transactions to close or not. (Callers that
4984 * don't intend to exit soon should switch to some other context to avoid
4985 * long-term memory leaks.)
4986 */
4988}
4989
4990/*
4991 * IsTransactionBlock --- are we within a transaction block?
4992 */
4993bool
4995{
4997
4999 return false;
5000
5001 return true;
5002}
5003
5004/*
5005 * IsTransactionOrTransactionBlock --- are we within either a transaction
5006 * or a transaction block? (The backend is only really "idle" when this
5007 * returns false.)
5008 *
5009 * This should match up with IsTransactionBlock and IsTransactionState.
5010 */
5011bool
5013{
5015
5016 if (s->blockState == TBLOCK_DEFAULT)
5017 return false;
5018
5019 return true;
5020}
5021
5022/*
5023 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
5024 */
5025char
5027{
5029
5030 switch (s->blockState)
5031 {
5032 case TBLOCK_DEFAULT:
5033 case TBLOCK_STARTED:
5034 return 'I'; /* idle --- not in transaction */
5035 case TBLOCK_BEGIN:
5036 case TBLOCK_SUBBEGIN:
5037 case TBLOCK_INPROGRESS:
5041 case TBLOCK_END:
5042 case TBLOCK_SUBRELEASE:
5043 case TBLOCK_SUBCOMMIT:
5044 case TBLOCK_PREPARE:
5045 return 'T'; /* in transaction */
5046 case TBLOCK_ABORT:
5047 case TBLOCK_SUBABORT:
5048 case TBLOCK_ABORT_END:
5052 case TBLOCK_SUBRESTART:
5054 return 'E'; /* in failed transaction */
5055 }
5056
5057 /* should never get here */
5058 elog(FATAL, "invalid transaction block state: %s",
5060 return 0; /* keep compiler quiet */
5061}
5062
5063/*
5064 * IsSubTransaction
5065 */
5066bool
5068{
5070
5071 if (s->nestingLevel >= 2)
5072 return true;
5073
5074 return false;
5075}
5076
5077/*
5078 * StartSubTransaction
5079 *
5080 * If you're wondering why this is separate from PushTransaction: it's because
5081 * we can't conveniently do this stuff right inside DefineSavepoint. The
5082 * SAVEPOINT utility command will be executed inside a Portal, and if we
5083 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
5084 * the Portal will undo those settings. So we make DefineSavepoint just
5085 * push a dummy transaction block, and when control returns to the main
5086 * idle loop, CommitTransactionCommand will be called, and we'll come here
5087 * to finish starting the subtransaction.
5088 */
5089static void
5091{
5093
5094 if (s->state != TRANS_DEFAULT)
5095 elog(WARNING, "StartSubTransaction while in %s state",
5097
5098 s->state = TRANS_START;
5099
5100 /*
5101 * Initialize subsystems for new subtransaction
5102 *
5103 * must initialize resource-management stuff first
5104 */
5108
5110
5111 /*
5112 * Call start-of-subxact callbacks
5113 */
5116
5117 ShowTransactionState("StartSubTransaction");
5118}
5119
5120/*
5121 * CommitSubTransaction
5122 *
5123 * The caller has to make sure to always reassign CurrentTransactionState
5124 * if it has a local pointer to it after calling this function.
5125 */
5126static void
5128{
5130
5131 ShowTransactionState("CommitSubTransaction");
5132
5133 if (s->state != TRANS_INPROGRESS)
5134 elog(WARNING, "CommitSubTransaction while in %s state",
5136
5137 /* Pre-commit processing goes here */
5138
5141
5142 /*
5143 * If this subxact has started any unfinished parallel operation, clean up
5144 * its workers and exit parallel mode. Warn about leaked resources.
5145 */
5147 if (s->parallelModeLevel != 0)
5148 {
5149 elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5151 s->parallelModeLevel = 0;
5152 }
5153
5154 /* Do the actual "commit", such as it is */
5155 s->state = TRANS_COMMIT;
5156
5157 /* Must CCI to ensure commands of subtransaction are seen as done */
5159
5160 /*
5161 * Prior to 8.4 we marked subcommit in clog at this point. We now only
5162 * perform that step, if required, as part of the atomic update of the
5163 * whole transaction tree at top level commit or abort.
5164 */
5165
5166 /* Post-commit cleanup */
5172 s->parent->nestingLevel,
5177
5180
5183 true, false);
5187 AtEOSubXact_Inval(true);
5189
5190 /*
5191 * The only lock we actually release here is the subtransaction XID lock.
5192 */
5196
5197 /*
5198 * Other locks should get transferred to their parent resource owner.
5199 */
5202 true, false);
5205 true, false);
5206
5207 AtEOXact_GUC(true, s->gucNestLevel);
5218
5219 /*
5220 * We need to restore the upper transaction's read-only state, in case the
5221 * upper is read-write while the child is read-only; GUC will incorrectly
5222 * think it should leave the child state in place.
5223 */
5225
5230
5232
5233 s->state = TRANS_DEFAULT;
5234
5236}
5237
5238/*
5239 * AbortSubTransaction
5240 */
5241static void
5243{
5245
5246 /* Prevent cancel/die interrupt while cleaning up */
5248
5249 /* Make sure we have a valid memory context and resource owner */
5252
5253 /*
5254 * Release any LW locks we might be holding as quickly as possible.
5255 * (Regular locks, however, must be held till we finish aborting.)
5256 * Releasing LW locks is critical since we might try to grab them again
5257 * while cleaning up!
5258 *
5259 * FIXME This may be incorrect --- Are there some locks we should keep?
5260 * Buffer locks, for example? I don't think so but I'm not sure.
5261 */
5263
5266
5268
5269 UnlockBuffers();
5270
5271 /* Reset WAL record construction state */
5273
5274 /* Cancel condition variable sleep */
5276
5277 /*
5278 * Also clean up any open wait for lock, since the lock manager will choke
5279 * if we try to wait for another lock before doing this.
5280 */
5282
5283 /*
5284 * If any timeout events are still active, make sure the timeout interrupt
5285 * is scheduled. This covers possible loss of a timeout interrupt due to
5286 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5287 * We delay this till after LockErrorCleanup so that we don't uselessly
5288 * reschedule lock or deadlock check timeouts.
5289 */
5291
5292 /*
5293 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5294 * handler. We do this fairly early in the sequence so that the timeout
5295 * infrastructure will be functional if needed while aborting.
5296 */
5298
5299 /*
5300 * check the current transaction state
5301 */
5302 ShowTransactionState("AbortSubTransaction");
5303
5304 if (s->state != TRANS_INPROGRESS)
5305 elog(WARNING, "AbortSubTransaction while in %s state",
5307
5308 s->state = TRANS_ABORT;
5309
5310 /*
5311 * Reset user ID which might have been changed transiently. (See notes in
5312 * AbortTransaction.)
5313 */
5315
5316 /* Forget about any active REINDEX. */
5318
5319 /* Reset logical streaming state. */
5321
5322 /*
5323 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5324 * exports are not supported in subtransactions.
5325 */
5326
5327 /*
5328 * If this subxact has started any unfinished parallel operation, clean up
5329 * its workers and exit parallel mode. Don't warn about leaked resources.
5330 */
5332 s->parallelModeLevel = 0;
5333
5334 /*
5335 * We can skip all this stuff if the subxact failed before creating a
5336 * ResourceOwner...
5337 */
5338 if (s->curTransactionOwner)
5339 {
5348
5349 /* Advertise the fact that we aborted in pg_xact. */
5351
5352 /* Post-abort cleanup */
5355
5358
5361 false, false);
5362
5363 AtEOXact_Aio(false);
5367 AtEOSubXact_Inval(false);
5370 false, false);
5373 false, false);
5375
5376 AtEOXact_GUC(false, s->gucNestLevel);
5387 }
5388
5389 /*
5390 * Restore the upper transaction's read-only state, too. This should be
5391 * redundant with GUC's cleanup but we may as well do it for consistency
5392 * with the commit case.
5393 */
5395
5397}
5398
5399/*
5400 * CleanupSubTransaction
5401 *
5402 * The caller has to make sure to always reassign CurrentTransactionState
5403 * if it has a local pointer to it after calling this function.
5404 */
5405static void
5407{
5409
5410 ShowTransactionState("CleanupSubTransaction");
5411
5412 if (s->state != TRANS_ABORT)
5413 elog(WARNING, "CleanupSubTransaction while in %s state",
5415
5417
5420 if (s->curTransactionOwner)
5423
5425
5426 s->state = TRANS_DEFAULT;
5427
5429}
5430
5431/*
5432 * PushTransaction
5433 * Create transaction state stack entry for a subtransaction
5434 *
5435 * The caller has to make sure to always reassign CurrentTransactionState
5436 * if it has a local pointer to it after calling this function.
5437 */
5438static void
5440{
5443
5444 /*
5445 * We keep subtransaction state nodes in TopTransactionContext.
5446 */
5447 s = (TransactionState)
5449 sizeof(TransactionStateData));
5450
5451 /*
5452 * Assign a subtransaction ID, watching out for counter wraparound.
5453 */
5456 {
5458 pfree(s);
5459 ereport(ERROR,
5461 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5462 }
5463
5464 /*
5465 * We can now stack a minimally valid subtransaction without fear of
5466 * failure.
5467 */
5468 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5470 s->parent = p;
5471 s->nestingLevel = p->nestingLevel + 1;
5474 s->state = TRANS_DEFAULT;
5479 s->parallelModeLevel = 0;
5481 s->topXidLogged = false;
5482
5484
5485 /*
5486 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5487 * with the subtransaction from here on out; in particular they should not
5488 * assume that it necessarily has a transaction context, resource owner,
5489 * or XID.
5490 */
5491}
5492
5493/*
5494 * PopTransaction
5495 * Pop back to parent transaction state
5496 *
5497 * The caller has to make sure to always reassign CurrentTransactionState
5498 * if it has a local pointer to it after calling this function.
5499 */
5500static void
5502{
5504
5505 if (s->state != TRANS_DEFAULT)
5506 elog(WARNING, "PopTransaction while in %s state",
5508
5509 if (s->parent == NULL)
5510 elog(FATAL, "PopTransaction with no parent");
5511
5513
5514 /* Let's just make sure CurTransactionContext is good */
5517
5518 /* Ditto for ResourceOwner links */
5521
5522 /* Free the old child structure */
5523 if (s->name)
5524 pfree(s->name);
5525 pfree(s);
5526}
5527
5528/*
5529 * EstimateTransactionStateSpace
5530 * Estimate the amount of space that will be needed by
5531 * SerializeTransactionState. It would be OK to overestimate slightly,
5532 * but it's simple for us to work out the precise value, so we do.
5533 */
5534Size
5536{
5538 Size nxids = 0;
5540
5541 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5542 {
5544 nxids = add_size(nxids, 1);
5546 }
5547
5548 return add_size(size, mul_size(sizeof(TransactionId), nxids));
5549}
5550
5551/*
5552 * SerializeTransactionState
5553 * Write out relevant details of our transaction state that will be
5554 * needed by a parallel worker.
5555 *
5556 * We need to save and restore XactDeferrable, XactIsoLevel, and the XIDs
5557 * associated with this transaction. These are serialized into a
5558 * caller-supplied buffer big enough to hold the number of bytes reported by
5559 * EstimateTransactionStateSpace(). We emit the XIDs in sorted order for the
5560 * convenience of the receiving process.
5561 */
5562void
5564{
5566 Size nxids = 0;
5567 Size i = 0;
5568 TransactionId *workspace;
5570
5572
5573 result->xactIsoLevel = XactIsoLevel;
5576 result->currentFullTransactionId =
5579
5580 /*
5581 * If we're running in a parallel worker and launching a parallel worker
5582 * of our own, we can just pass along the information that was passed to
5583 * us.
5584 */
5585 if (nParallelCurrentXids > 0)
5586 {
5590 return;
5591 }
5592
5593 /*
5594 * OK, we need to generate a sorted list of XIDs that our workers should
5595 * view as current. First, figure out how many there are.
5596 */
5597 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5598 {
5600 nxids = add_size(nxids, 1);
5602 }
5604 <= maxsize);
5605
5606 /* Copy them to our scratch space. */
5607 workspace = palloc(nxids * sizeof(TransactionId));
5608 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5609 {
5611 workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5612 if (s->nChildXids > 0)
5613 memcpy(&workspace[i], s->childXids,
5614 s->nChildXids * sizeof(TransactionId));
5615 i += s->nChildXids;
5616 }
5617 Assert(i == nxids);
5618
5619 /* Sort them. */
5620 qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5621
5622 /* Copy data into output area. */
5623 result->nParallelCurrentXids = nxids;
5624 memcpy(&result->parallelCurrentXids[0], workspace,
5625 nxids * sizeof(TransactionId));
5626}
5627
5628/*
5629 * StartParallelWorkerTransaction
5630 * Start a parallel worker transaction, restoring the relevant
5631 * transaction state serialized by SerializeTransactionState.
5632 */
5633void
5635{
5637
5640
5642 XactIsoLevel = tstate->xactIsoLevel;
5643 XactDeferrable = tstate->xactDeferrable;
5644 XactTopFullTransactionId = tstate->topFullTransactionId;
5646 tstate->currentFullTransactionId;
5647 currentCommandId = tstate->currentCommandId;
5648 nParallelCurrentXids = tstate->nParallelCurrentXids;
5649 ParallelCurrentXids = &tstate->parallelCurrentXids[0];
5650
5652}
5653
5654/*
5655 * EndParallelWorkerTransaction
5656 * End a parallel worker transaction.
5657 */
5658void
5665
5666/*
5667 * ShowTransactionState
5668 * Debug support
5669 */
5670static void
5672{
5673 /* skip work if message will definitely not be printed */
5676}
5677
5678/*
5679 * ShowTransactionStateRec
5680 * Recursive subroutine for ShowTransactionState
5681 */
5682static void
5684{
5686
5687 if (s->parent)
5688 {
5689 /*
5690 * Since this function recurses, it could be driven to stack overflow.
5691 * This is just a debugging aid, so we can leave out some details
5692 * instead of erroring out with check_stack_depth().
5693 */
5694 if (stack_is_too_deep())
5696 (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5697 str, s->nestingLevel)));
5698 else
5700 }
5701
5703 if (s->nChildXids > 0)
5704 {
5705 int i;
5706
5707 appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5708 for (i = 1; i < s->nChildXids; i++)
5709 appendStringInfo(&buf, " %u", s->childXids[i]);
5710 }
5712 (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5713 str, s->nestingLevel,
5714 s->name ? s->name : "unnamed",
5720 currentCommandIdUsed ? " (used)" : "",
5721 buf.data)));
5722 pfree(buf.data);
5723}
5724
5725/*
5726 * BlockStateAsString
5727 * Debug support
5728 */
5729static const char *
5731{
5732 switch (blockState)
5733 {
5734 case TBLOCK_DEFAULT:
5735 return "DEFAULT";
5736 case TBLOCK_STARTED:
5737 return "STARTED";
5738 case TBLOCK_BEGIN:
5739 return "BEGIN";
5740 case TBLOCK_INPROGRESS:
5741 return "INPROGRESS";
5743 return "IMPLICIT_INPROGRESS";
5745 return "PARALLEL_INPROGRESS";
5746 case TBLOCK_END:
5747 return "END";
5748 case TBLOCK_ABORT:
5749 return "ABORT";
5750 case TBLOCK_ABORT_END:
5751 return "ABORT_END";
5753 return "ABORT_PENDING";
5754 case TBLOCK_PREPARE:
5755 return "PREPARE";
5756 case TBLOCK_SUBBEGIN:
5757 return "SUBBEGIN";
5759 return "SUBINPROGRESS";
5760 case TBLOCK_SUBRELEASE:
5761 return "SUBRELEASE";
5762 case TBLOCK_SUBCOMMIT:
5763 return "SUBCOMMIT";
5764 case TBLOCK_SUBABORT:
5765 return "SUBABORT";
5767 return "SUBABORT_END";
5769 return "SUBABORT_PENDING";
5770 case TBLOCK_SUBRESTART:
5771 return "SUBRESTART";
5773 return "SUBABORT_RESTART";
5774 }
5775 return "UNRECOGNIZED";
5776}
5777
5778/*
5779 * TransStateAsString
5780 * Debug support
5781 */
5782static const char *
5784{
5785 switch (state)
5786 {
5787 case TRANS_DEFAULT:
5788 return "DEFAULT";
5789 case TRANS_START:
5790 return "START";
5791 case TRANS_INPROGRESS:
5792 return "INPROGRESS";
5793 case TRANS_COMMIT:
5794 return "COMMIT";
5795 case TRANS_ABORT:
5796 return "ABORT";
5797 case TRANS_PREPARE:
5798 return "PREPARE";
5799 }
5800 return "UNRECOGNIZED";
5801}
5802
5803/*
5804 * xactGetCommittedChildren
5805 *
5806 * Gets the list of committed children of the current transaction. The return
5807 * value is the number of child transactions. *ptr is set to point to an
5808 * array of TransactionIds. The array is allocated in TopTransactionContext;
5809 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
5810 * If there are no subxacts, *ptr is set to NULL.
5811 */
5812int
5814{
5816
5817 if (s->nChildXids == 0)
5818 *ptr = NULL;
5819 else
5820 *ptr = s->childXids;
5821
5822 return s->nChildXids;
5823}
5824
5825/*
5826 * XLOG support routines
5827 */
5828
5829
5830/*
5831 * Log the commit record for a plain or twophase transaction commit.
5832 *
5833 * A 2pc commit will be emitted when twophase_xid is valid, a plain one
5834 * otherwise.
5835 */
5838 int nsubxacts, TransactionId *subxacts,
5839 int nrels, RelFileLocator *rels,
5841 int nmsgs, SharedInvalidationMessage *msgs,
5842 bool relcacheInval,
5843 int xactflags, TransactionId twophase_xid,
5844 const char *twophase_gid)
5845{
5855 uint8 info;
5856
5858
5859 xl_xinfo.xinfo = 0;
5860
5861 /* decide between a plain and 2pc commit */
5862 if (!TransactionIdIsValid(twophase_xid))
5863 info = XLOG_XACT_COMMIT;
5864 else
5866
5867 /* First figure out and collect all the information needed */
5868
5869 xlrec.xact_time = commit_time;
5870
5871 if (relcacheInval)
5873 if (forceSyncCommit)
5877
5878 /*
5879 * Check if the caller would like to ask standbys for immediate feedback
5880 * once this commit is applied.
5881 */
5884
5885 /*
5886 * Relcache invalidations requires information about the current database
5887 * and so does logical decoding.
5888 */
5889 if (nmsgs > 0 || XLogLogicalInfoActive())
5890 {
5892 xl_dbinfo.dbId = MyDatabaseId;
5894 }
5895
5896 if (nsubxacts > 0)
5897 {
5899 xl_subxacts.nsubxacts = nsubxacts;
5900 }
5901
5902 if (nrels > 0)
5903 {
5905 xl_relfilelocators.nrels = nrels;
5906 info |= XLR_SPECIAL_REL_UPDATE;
5907 }
5908
5909 if (ndroppedstats > 0)
5910 {
5913 }
5914
5915 if (nmsgs > 0)
5916 {
5918 xl_invals.nmsgs = nmsgs;
5919 }
5920
5921 if (TransactionIdIsValid(twophase_xid))
5922 {
5924 xl_twophase.xid = twophase_xid;
5925 Assert(twophase_gid != NULL);
5926
5929 }
5930
5931 /* dump transaction origin information */
5933 {
5935
5938 }
5939
5940 if (xl_xinfo.xinfo != 0)
5941 info |= XLOG_XACT_HAS_INFO;
5942
5943 /* Then include all the collected data into the commit record. */
5944
5946
5948
5949 if (xl_xinfo.xinfo != 0)
5950 XLogRegisterData(&xl_xinfo.xinfo, sizeof(xl_xinfo.xinfo));
5951
5952 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5954
5956 {
5959 XLogRegisterData(subxacts,
5960 nsubxacts * sizeof(TransactionId));
5961 }
5962
5964 {
5967 XLogRegisterData(rels,
5968 nrels * sizeof(RelFileLocator));
5969 }
5970
5972 {
5977 }
5978
5979 if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
5980 {
5982 XLogRegisterData(msgs,
5983 nmsgs * sizeof(SharedInvalidationMessage));
5984 }
5985
5987 {
5989 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
5990 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
5991 }
5992
5993 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5995
5996 /* we allow filtering by xacts */
5998
5999 return XLogInsert(RM_XACT_ID, info);
6000}
6001
6002/*
6003 * Log the commit record for a plain or twophase transaction abort.
6004 *
6005 * A 2pc abort will be emitted when twophase_xid is valid, a plain one
6006 * otherwise.
6007 */
6010 int nsubxacts, TransactionId *subxacts,
6011 int nrels, RelFileLocator *rels,
6013 int xactflags, TransactionId twophase_xid,
6014 const char *twophase_gid)
6015{
6024
6025 uint8 info;
6026
6028
6029 xl_xinfo.xinfo = 0;
6030
6031 /* decide between a plain and 2pc abort */
6032 if (!TransactionIdIsValid(twophase_xid))
6033 info = XLOG_XACT_ABORT;
6034 else
6036
6037
6038 /* First figure out and collect all the information needed */
6039
6040 xlrec.xact_time = abort_time;
6041
6044
6045 if (nsubxacts > 0)
6046 {
6048 xl_subxacts.nsubxacts = nsubxacts;
6049 }
6050
6051 if (nrels > 0)
6052 {
6054 xl_relfilelocators.nrels = nrels;
6055 info |= XLR_SPECIAL_REL_UPDATE;
6056 }
6057
6058 if (ndroppedstats > 0)
6059 {
6062 }
6063
6064 if (TransactionIdIsValid(twophase_xid))
6065 {
6067 xl_twophase.xid = twophase_xid;
6068 Assert(twophase_gid != NULL);
6069
6072 }
6073
6074 if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6075 {
6077 xl_dbinfo.dbId = MyDatabaseId;
6079 }
6080
6081 /*
6082 * Dump transaction origin information. We need this during recovery to
6083 * update the replication origin progress.
6084 */
6086 {
6088
6091 }
6092
6093 if (xl_xinfo.xinfo != 0)
6094 info |= XLOG_XACT_HAS_INFO;
6095
6096 /* Then include all the collected data into the abort record. */
6097
6099
6101
6102 if (xl_xinfo.xinfo != 0)
6104
6105 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6107
6109 {
6112 XLogRegisterData(subxacts,
6113 nsubxacts * sizeof(TransactionId));
6114 }
6115
6117 {
6120 XLogRegisterData(rels,
6121 nrels * sizeof(RelFileLocator));
6122 }
6123
6125 {
6130 }
6131
6133 {
6135 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6136 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6137 }
6138
6139 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6141
6142 /* Include the replication origin */
6144
6145 return XLogInsert(RM_XACT_ID, info);
6146}
6147
6148/*
6149 * Before 9.0 this was a fairly short function, but now it performs many
6150 * actions for which the order of execution is critical.
6151 */
6152static void
6154 TransactionId xid,
6155 XLogRecPtr lsn,
6156 ReplOriginId origin_id)
6157{
6159 TimestampTz commit_time;
6160
6162
6163 max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
6164
6165 /* Make sure nextXid is beyond any XID mentioned in the record. */
6167
6168 Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) ==
6169 (origin_id == InvalidReplOriginId));
6170
6171 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6172 commit_time = parsed->origin_timestamp;
6173 else
6174 commit_time = parsed->xact_time;
6175
6176 /* Set the transaction commit timestamp and metadata */
6177 TransactionTreeSetCommitTsData(xid, parsed->nsubxacts, parsed->subxacts,
6178 commit_time, origin_id);
6179
6181 {
6182 /*
6183 * Mark the transaction committed in pg_xact.
6184 */
6185 TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
6186 }
6187 else
6188 {
6189 /*
6190 * If a transaction completion record arrives that has as-yet
6191 * unobserved subtransactions then this will not have been fully
6192 * handled by the call to RecordKnownAssignedTransactionIds() in the
6193 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6194 * cover that case. This is confusing and it is easy to think this
6195 * call is irrelevant, which has happened three times in development
6196 * already. Leave it in.
6197 */
6199
6200 /*
6201 * Mark the transaction committed in pg_xact. We use async commit
6202 * protocol during recovery to provide information on database
6203 * consistency for when users try to set hint bits. It is important
6204 * that we do not set hint bits until the minRecoveryPoint is past
6205 * this commit record. This ensures that if we crash we don't see hint
6206 * bits set on changes made by transactions that haven't yet
6207 * recovered. It's unlikely but it's good to be safe.
6208 */
6209 TransactionIdAsyncCommitTree(xid, parsed->nsubxacts, parsed->subxacts, lsn);
6210
6211 /*
6212 * We must mark clog before we update the ProcArray.
6213 */
6214 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6215
6216 /*
6217 * Send any cache invalidations attached to the commit. We must
6218 * maintain the same order of invalidation then release locks as
6219 * occurs in CommitTransaction().
6220 */
6223 parsed->dbId, parsed->tsId);
6224
6225 /*
6226 * Release locks, if any. We do this for both two phase and normal one
6227 * phase transactions. In effect we are ignoring the prepare phase and
6228 * just going straight to lock release.
6229 */
6230 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6231 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6232 }
6233
6234 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6235 {
6236 /* recover apply progress */
6237 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6238 false /* backward */ , false /* WAL */ );
6239 }
6240
6241 /* Make sure files supposed to be dropped are dropped */
6242 if (parsed->nrels > 0)
6243 {
6244 /*
6245 * First update minimum recovery point to cover this WAL record. Once
6246 * a relation is deleted, there's no going back. The buffer manager
6247 * enforces the WAL-first rule for normal updates to relation files,
6248 * so that the minimum recovery point is always updated before the
6249 * corresponding change in the data file is flushed to disk, but we
6250 * have to do the same here since we're bypassing the buffer manager.
6251 *
6252 * Doing this before deleting the files means that if a deletion fails
6253 * for some reason, you cannot start up the system even after restart,
6254 * until you fix the underlying situation so that the deletion will
6255 * succeed. Alternatively, we could update the minimum recovery point
6256 * after deletion, but that would leave a small window where the
6257 * WAL-first rule would be violated.
6258 */
6259 XLogFlush(lsn);
6260
6261 /* Make sure files supposed to be dropped are dropped */
6262 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6263 }
6264
6265 if (parsed->nstats > 0)
6266 {
6267 /* see equivalent call for relations above */
6268 XLogFlush(lsn);
6269
6270 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6271 }
6272
6273 /*
6274 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
6275 * in normal operation. For example, in CREATE DATABASE, we copy all files
6276 * from the template database, and then commit the transaction. If we
6277 * crash after all the files have been copied but before the commit, you
6278 * have files in the data directory without an entry in pg_database. To
6279 * minimize the window for that, we use ForceSyncCommit() to rush the
6280 * commit record to disk as quick as possible. We have the same window
6281 * during recovery, and forcing an XLogFlush() (which updates
6282 * minRecoveryPoint during recovery) helps to reduce that problem window,
6283 * for any user that requested ForceSyncCommit().
6284 */
6286 XLogFlush(lsn);
6287
6288 /*
6289 * If asked by the primary (because someone is waiting for a synchronous
6290 * commit = remote_apply), we will need to ask walreceiver to send a reply
6291 * immediately.
6292 */
6295}
6296
6297/*
6298 * Be careful with the order of execution, as with xact_redo_commit().
6299 * The two functions are similar but differ in key places.
6300 *
6301 * Note also that an abort can be for a subtransaction and its children,
6302 * not just for a top level abort. That means we have to consider
6303 * topxid != xid, whereas in commit we would find topxid == xid always
6304 * because subtransaction commit is never WAL logged.
6305 */
6306static void
6308 XLogRecPtr lsn, ReplOriginId origin_id)
6309{
6311
6313
6314 /* Make sure nextXid is beyond any XID mentioned in the record. */
6316 parsed->nsubxacts,
6317 parsed->subxacts);
6319
6321 {
6322 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6323 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6324 }
6325 else
6326 {
6327 /*
6328 * If a transaction completion record arrives that has as-yet
6329 * unobserved subtransactions then this will not have been fully
6330 * handled by the call to RecordKnownAssignedTransactionIds() in the
6331 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6332 * cover that case. This is confusing and it is easy to think this
6333 * call is irrelevant, which has happened three times in development
6334 * already. Leave it in.
6335 */
6337
6338 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6339 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6340
6341 /*
6342 * We must update the ProcArray after we have marked clog.
6343 */
6344 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6345
6346 /*
6347 * There are no invalidation messages to send or undo.
6348 */
6349
6350 /*
6351 * Release locks, if any. There are no invalidations to send.
6352 */
6353 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6354 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6355 }
6356
6357 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6358 {
6359 /* recover apply progress */
6360 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6361 false /* backward */ , false /* WAL */ );
6362 }
6363
6364 /* Make sure files supposed to be dropped are dropped */
6365 if (parsed->nrels > 0)
6366 {
6367 /*
6368 * See comments about update of minimum recovery point on truncation,
6369 * in xact_redo_commit().
6370 */
6371 XLogFlush(lsn);
6372
6373 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6374 }
6375
6376 if (parsed->nstats > 0)
6377 {
6378 /* see equivalent call for relations above */
6379 XLogFlush(lsn);
6380
6381 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6382 }
6383}
6384
6385void
6387{
6388 uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6389
6390 /* Backup blocks are not used in xact records */
6392
6393 if (info == XLOG_XACT_COMMIT)
6394 {
6397
6400 record->EndRecPtr, XLogRecGetOrigin(record));
6401 }
6402 else if (info == XLOG_XACT_COMMIT_PREPARED)
6403 {
6406
6408 xact_redo_commit(&parsed, parsed.twophase_xid,
6409 record->EndRecPtr, XLogRecGetOrigin(record));
6410
6411 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6413 PrepareRedoRemove(parsed.twophase_xid, false);
6415 }
6416 else if (info == XLOG_XACT_ABORT)
6417 {
6420
6423 record->EndRecPtr, XLogRecGetOrigin(record));
6424 }
6425 else if (info == XLOG_XACT_ABORT_PREPARED)
6426 {
6429
6431 xact_redo_abort(&parsed, parsed.twophase_xid,
6432 record->EndRecPtr, XLogRecGetOrigin(record));
6433
6434 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6436 PrepareRedoRemove(parsed.twophase_xid, false);
6438 }
6439 else if (info == XLOG_XACT_PREPARE)
6440 {
6441 /*
6442 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6443 * gxact entry.
6444 */
6447 XLogRecGetData(record),
6448 record->ReadRecPtr,
6449 record->EndRecPtr,
6450 XLogRecGetOrigin(record));
6452 }
6453 else if (info == XLOG_XACT_ASSIGNMENT)
6454 {
6456
6459 xlrec->nsubxacts, xlrec->xsub);
6460 }
6461 else if (info == XLOG_XACT_INVALIDATIONS)
6462 {
6463 /*
6464 * XXX we do ignore this for now, what matters are invalidations
6465 * written into the commit record.
6466 */
6467 }
6468 else
6469 elog(PANIC, "xact_redo: unknown op code %u", info);
6470}
void pgaio_error_cleanup(void)
Definition aio.c:1165
void AtEOXact_Aio(bool is_commit)
Definition aio.c:1193
void AtCommit_Notify(void)
Definition async.c:1381
void AtAbort_Notify(void)
Definition async.c:2421
void PreCommit_Notify(void)
Definition async.c:1188
void AtSubAbort_Notify(void)
Definition async.c:2510
void AtPrepare_Notify(void)
Definition async.c:1163
void AtSubCommit_Notify(void)
Definition async.c:2440
#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:6331
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1636
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:879
void AtEOXact_Buffers(bool isCommit)
Definition bufmgr.c:4110
void UnlockBuffers(void)
Definition bufmgr.c:5719
#define InvalidCommandId
Definition c.h:755
#define TopSubTransactionId
Definition c.h:745
#define Min(x, y)
Definition c.h:1093
uint8_t uint8
Definition c.h:616
uint32 SubTransactionId
Definition c.h:742
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:243
#define InvalidSubTransactionId
Definition c.h:744
#define Assert(condition)
Definition c.h:945
#define FLEXIBLE_ARRAY_MEMBER
Definition c.h:552
#define FirstCommandId
Definition c.h:754
uint32 LocalTransactionId
Definition c.h:740
uint32 CommandId
Definition c.h:752
uint32 TransactionId
Definition c.h:738
size_t Size
Definition c.h:691
void AtEOXact_ComboCid(void)
Definition combocid.c:182
void TransactionTreeSetCommitTsData(TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz timestamp, ReplOriginId nodeid)
Definition commit_ts.c:140
bool ConditionVariableCancelSleep(void)
int64 TimestampTz
Definition timestamp.h:39
void AtEOXact_HashTables(bool isCommit)
Definition dynahash.c:1931
void AtEOSubXact_HashTables(bool isCommit, int nestDepth)
Definition dynahash.c:1957
Datum arg
Definition elog.c:1322
bool message_level_is_interesting(int elevel)
Definition elog.c:284
int errcode(int sqlerrcode)
Definition elog.c:874
#define FATAL
Definition elog.h:41
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define WARNING
Definition elog.h:36
#define PANIC
Definition elog.h:42
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
#define DEBUG5
Definition elog.h:26
void AtEOXact_Files(bool isCommit)
Definition fd.c:3214
void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition fd.c:3181
#define MaxAllocSize
Definition fe_memutils.h:22
#define palloc_array(type, count)
Definition fe_memutils.h:76
ProcNumber MyProcNumber
Definition globals.c:90
Oid MyDatabaseTableSpace
Definition globals.c:96
volatile uint32 CritSectionCount
Definition globals.c:45
bool ExitOnAnyError
Definition globals.c:123
Oid MyDatabaseId
Definition globals.c:94
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:557
const char * str
#define IsParallelWorker()
Definition parallel.h:62
void ResetReindexState(int nestLevel)
Definition index.c:4214
void PostPrepare_Inval(void)
Definition inval.c:993
void LogLogicalInvalidations(void)
Definition inval.c:1939
void AcceptInvalidationMessages(void)
Definition inval.c:930
int xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs, bool *RelcacheInitFileInval)
Definition inval.c:1012
void AtEOXact_Inval(bool isCommit)
Definition inval.c:1199
void AtEOSubXact_Inval(bool isCommit)
Definition inval.c:1310
void CommandEndInvalidationMessages(void)
Definition inval.c:1409
void ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs, int nmsgs, bool RelcacheInitFileInval, Oid dbid, Oid tsid)
Definition inval.c:1135
int i
Definition isn.c:77
void AtEOXact_ApplyLauncher(bool isCommit)
Definition launcher.c:1166
void XactLockTableDelete(TransactionId xid)
Definition lmgr.c:639
void XactLockTableInsert(TransactionId xid)
Definition lmgr.c:622
void PostPrepare_Locks(FullTransactionId fxid)
Definition lock.c:3572
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
Definition lock.c:4619
void AtPrepare_Locks(void)
Definition lock.c:3476
#define InvalidLocalTransactionId
Definition lock.h:68
void ResetLogicalStreamingState(void)
Definition logical.c:1933
void AtEOXact_LogicalCtl(void)
Definition logicalctl.c:236
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1177
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1794
void LWLockReleaseAll(void)
Definition lwlock.c:1893
@ LW_EXCLUSIVE
Definition lwlock.h:112
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition mcxt.c:1768
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1232
bool MemoryContextIsEmpty(MemoryContext context)
Definition mcxt.c:792
void MemoryContextReset(MemoryContext context)
Definition mcxt.c:403
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition mcxt.c:1266
MemoryContext TopTransactionContext
Definition mcxt.c:171
void * repalloc(void *pointer, Size size)
Definition mcxt.c:1632
void pfree(void *pointer)
Definition mcxt.c:1616
MemoryContext TopMemoryContext
Definition mcxt.c:166
void * palloc(Size size)
Definition mcxt.c:1387
MemoryContext CurTransactionContext
Definition mcxt.c:172
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472
void DropRelationFiles(RelFileLocator *delrels, int ndelrels, bool isRedo)
Definition md.c:1612
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
#define RESUME_INTERRUPTS()
Definition miscadmin.h:136
#define START_CRIT_SECTION()
Definition miscadmin.h:150
#define HOLD_INTERRUPTS()
Definition miscadmin.h:134
#define END_CRIT_SECTION()
Definition miscadmin.h:152
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition miscinit.c: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:1659
void AtPrepare_MultiXact(void)
Definition multixact.c:1645
void AtEOXact_MultiXact(void)
Definition multixact.c:1617
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:167
void replorigin_advance(ReplOriginId node, XLogRecPtr remote_commit, XLogRecPtr local_commit, bool go_backward, bool wal_log)
Definition origin.c:919
void replorigin_session_advance(XLogRecPtr remote_commit, XLogRecPtr local_commit)
Definition origin.c:1311
#define DoNotReplicateId
Definition origin.h:34
#define InvalidReplOriginId
Definition origin.h:33
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
void AtEOXact_Enum(void)
Definition pg_enum.c:739
double pg_prng_double(pg_prng_state *state)
Definition pg_prng.c:268
pg_prng_state pg_global_prng_state
Definition pg_prng.c:34
static char buf[DEFAULT_XLOG_SEG_SIZE]
void AtPrepare_PgStat(void)
void pgstat_execute_transactional_drops(int ndrops, struct xl_xact_stats_item *items, bool is_redo)
void AtEOXact_PgStat(bool isCommit, bool parallel)
Definition pgstat_xact.c:40
void PostPrepare_PgStat(void)
int pgstat_get_transactional_drops(bool isCommit, xl_xact_stats_item **items)
void AtEOSubXact_PgStat(bool isCommit, int nestDepth)
#define qsort(a, b, c, d)
Definition port.h:495
void AtAbort_Portals(void)
Definition portalmem.c:782
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition portalmem.c:981
bool PreCommit_Portals(bool isPrepare)
Definition portalmem.c:678
void AtSubCommit_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, int parentLevel, ResourceOwner parentXactOwner)
Definition portalmem.c:945
void AtCleanup_Portals(void)
Definition portalmem.c:860
void AtSubCleanup_Portals(SubTransactionId mySubid)
Definition portalmem.c:1094
unsigned int Oid
void PreCommit_CheckForSerializationFailure(void)
Definition predicate.c:4712
void PostPrepare_PredicateLocks(FullTransactionId fxid)
Definition predicate.c:4868
void AtPrepare_PredicateLocks(void)
Definition predicate.c:4799
void RegisterPredicateLockingXid(TransactionId xid)
Definition predicate.c:1968
static int fb(int x)
#define DELAY_CHKPT_IN_COMMIT
Definition proc.h:138
#define PGPROC_MAX_CACHED_SUBXIDS
Definition proc.h:40
void XidCacheRemoveRunningXids(TransactionId xid, int nxids, const TransactionId *xids, TransactionId latestXid)
Definition procarray.c:3998
void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
Definition procarray.c:671
void RecordKnownAssignedTransactionIds(TransactionId xid)
Definition procarray.c:4410
void ProcArrayClearTransaction(PGPROC *proc)
Definition procarray.c:907
void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)
Definition procarray.c:1317
void ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids, TransactionId *subxids, TransactionId max_xid)
Definition procarray.c:4479
void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition relcache.c:3367
void AtEOXact_RelationCache(bool isCommit)
Definition relcache.c:3215
void AtPrepare_RelationMap(void)
Definition relmapper.c:589
void AtEOXact_RelationMap(bool isCommit, bool isParallelWorker)
Definition relmapper.c:542
void AtCCI_RelationMap(void)
Definition relmapper.c:505
ResourceOwner TopTransactionResourceOwner
Definition resowner.c:175
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition resowner.c:418
ResourceOwner CurrentResourceOwner
Definition resowner.c:173
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition resowner.c:655
void ResourceOwnerDelete(ResourceOwner owner)
Definition resowner.c:868
ResourceOwner CurTransactionResourceOwner
Definition resowner.c:174
@ RESOURCE_RELEASE_LOCKS
Definition resowner.h:55
@ RESOURCE_RELEASE_BEFORE_LOCKS
Definition resowner.h:54
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition resowner.h:56
Size add_size(Size s1, Size s2)
Definition shmem.c:485
Size mul_size(Size s1, Size s2)
Definition shmem.c:500
LocalTransactionId GetNextLocalTransactionId(void)
Definition sinvaladt.c:701
void AtEOXact_SMgr(void)
Definition smgr.c:1017
void SnapBuildResetExportedSnapshotState(void)
Definition snapbuild.c:629
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:68
int TransactionTimeout
Definition proc.c:63
void LockErrorCleanup(void)
Definition proc.c:806
bool stack_is_too_deep(void)
void StandbyReleaseLockTree(TransactionId xid, int nsubxids, TransactionId *subxids)
Definition standby.c:1093
void LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInitFileInval)
Definition standby.c:1472
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:228
struct PGPROC::@133 vxid
ProcNumber procNumber
Definition proc.h:223
int delayChkptFlags
Definition proc.h:257
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:85
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:377
#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:5085
void AfterTriggerEndSubXact(bool isCommit)
Definition trigger.c:5440
void AfterTriggerFireDeferred(void)
Definition trigger.c:5288
void AfterTriggerEndXact(bool isCommit)
Definition trigger.c:5344
void AfterTriggerBeginSubXact(void)
Definition trigger.c:5392
GlobalTransaction MarkAsPreparing(FullTransactionId fxid, const char *gid, TimestampTz prepared_at, Oid owner, Oid databaseid)
Definition twophase.c:362
void PrepareRedoAdd(FullTransactionId fxid, char *buf, XLogRecPtr start_lsn, XLogRecPtr end_lsn, ReplOriginId origin_id)
Definition twophase.c:2510
void AtAbort_Twophase(void)
Definition twophase.c:307
void PrepareRedoRemove(TransactionId xid, bool giveWarning)
Definition twophase.c:2667
void EndPrepare(GlobalTransaction gxact)
Definition twophase.c:1148
void StartPrepare(GlobalTransaction gxact)
Definition twophase.c:1055
void PostPrepare_Twophase(void)
Definition twophase.c:347
void AtEOXact_TypeCache(void)
Definition typcache.c:3217
void AtEOSubXact_TypeCache(void)
Definition typcache.c:3223
void AdvanceNextFullTransactionIdPastXid(TransactionId xid)
Definition varsup.c:308
FullTransactionId GetNewTransactionId(bool isSubXact)
Definition varsup.c:77
static void pgstat_report_wait_end(void)
Definition wait_event.h:85
const char * name
static bool CommitTransactionCommandInternal(void)
Definition xact.c:3197
bool IsTransactionOrTransactionBlock(void)
Definition xact.c:5012
void SerializeTransactionState(Size maxsize, char *start_address)
Definition xact.c:5563
void ExitParallelMode(void)
Definition xact.c:1066
static TimestampTz xactStartTimestamp
Definition xact.c:282
static bool currentCommandIdUsed
Definition xact.c:270
static void AtSubCommit_Memory(void)
Definition xact.c:1649
void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
Definition xact.c:3158
static void CleanupSubTransaction(void)
Definition xact.c:5406
void BeginInternalSubTransaction(const char *name)
Definition xact.c:4717
static void AtStart_Memory(void)
Definition xact.c:1178
FullTransactionId GetCurrentFullTransactionId(void)
Definition xact.c:514
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition xact.c:3166
static XactCallbackItem * Xact_callbacks
Definition xact.c:317
void WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
Definition xact.c:3733
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:4227
bool IsInTransactionBlock(bool isTopLevel)
Definition xact.c:3792
bool PrepareTransactionBlock(const char *gid)
Definition xact.c:4015
static void AtSubCleanup_Memory(void)
Definition xact.c:2036
static void StartTransaction(void)
Definition xact.c:2078
int GetCurrentTransactionNestLevel(void)
Definition xact.c:931
void xact_redo(XLogReaderState *record)
Definition xact.c:6386
TransactionId GetTopTransactionId(void)
Definition xact.c:428
static void AtSubCommit_childXids(void)
Definition xact.c:1678
static void CallSubXactCallbacks(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition xact.c:3921
void EnterParallelMode(void)
Definition xact.c:1053
static void AtAbort_ResourceOwner(void)
Definition xact.c:1930
TransactionId GetStableLatestTransactionId(void)
Definition xact.c:609
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition xact.c:3748
void UnregisterSubXactCallback(SubXactCallback callback, void *arg)
Definition xact.c:3900
bool XactDeferrable
Definition xact.c:87
static bool forceSyncCommit
Definition xact.c:295
void BeginImplicitTransactionBlock(void)
Definition xact.c:4349
static void CallXactCallbacks(XactEvent event)
Definition xact.c:3861
static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS]
Definition xact.c:260
void RequireTransactionBlock(bool isTopLevel, const char *stmtType)
Definition xact.c:3739
static void AtSubAbort_Memory(void)
Definition xact.c:1918
static SubXactCallbackItem * SubXact_callbacks
Definition xact.c:329
void DefineSavepoint(const char *name)
Definition xact.c:4396
bool DefaultXactDeferrable
Definition xact.c:86
static void CleanupTransaction(void)
Definition xact.c:3031
static int nUnreportedXids
Definition xact.c:259
static const char * TransStateAsString(TransState state)
Definition xact.c:5783
static TimestampTz xactStopTimestamp
Definition xact.c:284
bool TransactionStartedDuringRecovery(void)
Definition xact.c:1044
static void CommitSubTransaction(void)
Definition xact.c:5127
bool XactReadOnly
Definition xact.c:84
static void PushTransaction(void)
Definition xact.c:5439
bool bsysscan
Definition xact.c:102
TransactionId CheckXidAlive
Definition xact.c:101
static TransactionId RecordTransactionCommit(void)
Definition xact.c:1317
static char * prepareGID
Definition xact.c:290
void UnregisterXactCallback(XactCallback callback, void *arg)
Definition xact.c:3840
bool IsTransactionState(void)
Definition xact.c:389
static MemoryContext TransactionAbortContext
Definition xact.c:305
void CommandCounterIncrement(void)
Definition xact.c:1102
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:3670
static void AtCleanup_Memory(void)
Definition xact.c:1988
Size EstimateTransactionStateSpace(void)
Definition xact.c:5535
TransactionStateData * TransactionState
Definition xact.c:223
static void AtSubAbort_childXids(void)
Definition xact.c:1956
TransactionId GetTopTransactionIdIfAny(void)
Definition xact.c:443
static bool AbortCurrentTransactionInternal(void)
Definition xact.c:3491
static SubTransactionId currentSubTransactionId
Definition xact.c:268
static void AssignTransactionId(TransactionState s)
Definition xact.c:637
char TransactionBlockStatusCode(void)
Definition xact.c:5026
void RollbackAndReleaseCurrentSubTransaction(void)
Definition xact.c:4819
static int nParallelCurrentXids
Definition xact.c:128
FullTransactionId GetCurrentFullTransactionIdIfAny(void)
Definition xact.c:532
static void CommitTransaction(void)
Definition xact.c:2242
void StartTransactionCommand(void)
Definition xact.c:3081
static void PopTransaction(void)
Definition xact.c:5501
bool IsAbortedTransactionBlockState(void)
Definition xact.c:409
void ReleaseCurrentSubTransaction(void)
Definition xact.c:4791
void EndImplicitTransactionBlock(void)
Definition xact.c:4374
void StartParallelWorkerTransaction(char *tstatespace)
Definition xact.c:5634
void SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts)
Definition xact.c:861
static void AtSubAbort_ResourceOwner(void)
Definition xact.c:1943
void ReleaseSavepoint(const char *name)
Definition xact.c:4481
static TransactionStateData TopTransactionStateData
Definition xact.c:249
static FullTransactionId XactTopFullTransactionId
Definition xact.c:127
static void ShowTransactionState(const char *str)
Definition xact.c:5671
int XactIsoLevel
Definition xact.c:81
static void PrepareTransaction(void)
Definition xact.c:2530
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:5837
void ForceSyncCommit(void)
Definition xact.c:1154
static TransactionId RecordTransactionAbort(bool isSubXact)
Definition xact.c:1768
static void AtCommit_Memory(void)
Definition xact.c:1612
static void AbortSubTransaction(void)
Definition xact.c:5242
bool IsSubTransaction(void)
Definition xact.c:5067
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:6307
bool IsTransactionBlock(void)
Definition xact.c:4994
bool IsInParallelMode(void)
Definition xact.c:1091
int xactGetCommittedChildren(TransactionId **ptr)
Definition xact.c:5813
TransactionId GetCurrentTransactionIdIfAny(void)
Definition xact.c:473
void BeginTransactionBlock(void)
Definition xact.c:3947
static void AtStart_ResourceOwner(void)
Definition xact.c:1228
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition xact.c:881
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition xact.c:872
static const char * BlockStateAsString(TBlockState blockState)
Definition xact.c:5730
void EndParallelWorkerTransaction(void)
Definition xact.c:5659
static void AtAbort_Memory(void)
Definition xact.c:1898
void RegisterXactCallback(XactCallback callback, void *arg)
Definition xact.c:3827
void CommitTransactionCommand(void)
Definition xact.c:3179
void RollbackToSavepoint(const char *name)
Definition xact.c:4590
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:3887
FullTransactionId GetTopFullTransactionIdIfAny(void)
Definition xact.c:501
TransactionId GetCurrentTransactionId(void)
Definition xact.c:456
static void AbortTransaction(void)
Definition xact.c:2825
static void AtStart_Cache(void)
Definition xact.c:1169
static void AtSubStart_ResourceOwner(void)
Definition xact.c:1285
int DefaultXactIsoLevel
Definition xact.c:80
static void AtSubStart_Memory(void)
Definition xact.c:1256
bool xact_is_sampled
Definition xact.c:298
bool EndTransactionBlock(bool chain)
Definition xact.c:4067
bool IsSubxactTopXidLogPending(void)
Definition xact.c:561
#define SerializedTransactionStateHeaderSize
Definition xact.c:241
void AbortOutOfAnyTransaction(void)
Definition xact.c:4885
int MyXactFlags
Definition xact.c:138
static void ShowTransactionStateRec(const char *str, TransactionState s)
Definition xact.c:5683
static TransactionState CurrentTransactionState
Definition xact.c:262
void AbortCurrentTransaction(void)
Definition xact.c:3473
static void StartSubTransaction(void)
Definition xact.c:5090
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:1593
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:6009
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:6153
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:6444
XLogRecPtr XactLastRecEnd
Definition xlog.c:258
XLogRecPtr XactLastCommitEnd
Definition xlog.c:259
void XLogFlush(XLogRecPtr record)
Definition xlog.c:2767
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition xlog.c:2596
#define XLogLogicalInfoActive()
Definition xlog.h:136
#define XLOG_INCLUDE_ORIGIN
Definition xlog.h:165
#define XLogStandbyInfoActive()
Definition xlog.h:125
uint16 ReplOriginId
Definition xlogdefs.h:69
uint64 XLogRecPtr
Definition xlogdefs.h:21
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition xloginsert.c:479
void XLogRegisterData(const void *data, uint32 len)
Definition xloginsert.c:369
void XLogSetRecordFlags(uint8 flags)
Definition xloginsert.c:461
void XLogResetInsertion(void)
Definition xloginsert.c:226
void XLogBeginInsert(void)
Definition xloginsert.c:153
#define XLogRecGetOrigin(decoder)
Definition xlogreader.h:412
#define XLogRecGetInfo(decoder)
Definition xlogreader.h:409
#define XLogRecGetData(decoder)
Definition xlogreader.h:414
#define XLogRecGetXid(decoder)
Definition xlogreader.h:411
#define XLogRecHasAnyBlockRefs(decoder)
Definition xlogreader.h:416
#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:339