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
76/*
77 * User-tweakable parameters
78 */
81
84
87
89
90/*
91 * CheckXidAlive is a xid value pointing to a possibly ongoing (sub)
92 * transaction. Currently, it is used in logical decoding. It's possible
93 * that such transactions can get aborted while the decoding is ongoing in
94 * which case we skip decoding that particular transaction. To ensure that we
95 * check whether the CheckXidAlive is aborted after fetching the tuple from
96 * system tables. We also ensure that during logical decoding we never
97 * directly access the tableam or heap APIs because we are checking for the
98 * concurrent aborts only in systable_* APIs.
99 */
101bool bsysscan = false;
102
103/*
104 * When running as a parallel worker, we place only a single
105 * TransactionStateData on the parallel worker's state stack, and the XID
106 * reflected there will be that of the *innermost* currently-active
107 * subtransaction in the backend that initiated parallelism. However,
108 * GetTopTransactionId() and TransactionIdIsCurrentTransactionId()
109 * need to return the same answers in the parallel worker as they would have
110 * in the user backend, so we need some additional bookkeeping.
111 *
112 * XactTopFullTransactionId stores the XID of our toplevel transaction, which
113 * will be the same as TopTransactionStateData.fullTransactionId in an
114 * ordinary backend; but in a parallel backend, which does not have the entire
115 * transaction state, it will instead be copied from the backend that started
116 * the parallel operation.
117 *
118 * nParallelCurrentXids will be 0 and ParallelCurrentXids NULL in an ordinary
119 * backend, but in a parallel backend, nParallelCurrentXids will contain the
120 * number of XIDs that need to be considered current, and ParallelCurrentXids
121 * will contain the XIDs themselves. This includes all XIDs that were current
122 * or sub-committed in the parent at the time the parallel operation began.
123 * The XIDs are stored sorted in numerical order (not logical order) to make
124 * lookups as fast as possible.
125 */
127static int nParallelCurrentXids = 0;
129
130/*
131 * Miscellaneous flag bits to record events which occur on the top level
132 * transaction. These flags are only persisted in MyXactFlags and are intended
133 * so we remember to do certain things later on in the transaction. This is
134 * globally accessible, so can be set from anywhere in the code that requires
135 * recording flags.
136 */
138
139/*
140 * transaction states - transaction state from server perspective
141 */
142typedef enum TransState
143{
144 TRANS_DEFAULT, /* idle */
145 TRANS_START, /* transaction starting */
146 TRANS_INPROGRESS, /* inside a valid transaction */
147 TRANS_COMMIT, /* commit in progress */
148 TRANS_ABORT, /* abort in progress */
149 TRANS_PREPARE, /* prepare in progress */
151
152/*
153 * transaction block states - transaction state of client queries
154 *
155 * Note: the subtransaction states are used only for non-topmost
156 * transactions; the others appear only in the topmost transaction.
157 */
158typedef enum TBlockState
159{
160 /* not-in-transaction-block states */
161 TBLOCK_DEFAULT, /* idle */
162 TBLOCK_STARTED, /* running single-query transaction */
163
164 /* transaction block states */
165 TBLOCK_BEGIN, /* starting transaction block */
166 TBLOCK_INPROGRESS, /* live transaction */
167 TBLOCK_IMPLICIT_INPROGRESS, /* live transaction after implicit BEGIN */
168 TBLOCK_PARALLEL_INPROGRESS, /* live transaction inside parallel worker */
169 TBLOCK_END, /* COMMIT received */
170 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
171 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
172 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
173 TBLOCK_PREPARE, /* live xact, PREPARE received */
174
175 /* subtransaction states */
176 TBLOCK_SUBBEGIN, /* starting a subtransaction */
177 TBLOCK_SUBINPROGRESS, /* live subtransaction */
178 TBLOCK_SUBRELEASE, /* RELEASE received */
179 TBLOCK_SUBCOMMIT, /* COMMIT received while TBLOCK_SUBINPROGRESS */
180 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
181 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
182 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
183 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
184 TBLOCK_SUBABORT_RESTART, /* failed subxact, ROLLBACK TO received */
186
187/*
188 * transaction state structure
189 *
190 * Note: parallelModeLevel counts the number of unmatched EnterParallelMode
191 * calls done at this transaction level. parallelChildXact is true if any
192 * upper transaction level has nonzero parallelModeLevel.
193 */
195{
196 FullTransactionId fullTransactionId; /* my FullTransactionId */
198 char *name; /* savepoint name, if any */
199 int savepointLevel; /* savepoint level */
200 TransState state; /* low-level state */
201 TBlockState blockState; /* high-level state */
202 int nestingLevel; /* transaction nesting depth */
203 int gucNestLevel; /* GUC context nesting depth */
204 MemoryContext curTransactionContext; /* my xact-lifetime context */
205 ResourceOwner curTransactionOwner; /* my query resources */
206 MemoryContext priorContext; /* CurrentMemoryContext before xact started */
207 TransactionId *childXids; /* subcommitted child XIDs, in XID order */
208 int nChildXids; /* # of subcommitted child XIDs */
209 int maxChildXids; /* allocated size of childXids[] */
210 Oid prevUser; /* previous CurrentUserId setting */
211 int prevSecContext; /* previous SecurityRestrictionContext */
212 bool prevXactReadOnly; /* entry-time xact r/o state */
213 bool startedInRecovery; /* did we start in recovery? */
214 bool didLogXid; /* has xid been included in WAL record? */
215 int parallelModeLevel; /* Enter/ExitParallelMode counter */
216 bool parallelChildXact; /* is any parent transaction parallel? */
217 bool chain; /* start a new block after this one */
218 bool topXidLogged; /* for a subxact: is top-level XID logged? */
219 struct TransactionStateData *parent; /* back link to parent */
221
223
224/*
225 * Serialized representation used to transmit transaction state to parallel
226 * workers through shared memory.
227 */
238
239/* The size of SerializedTransactionState, not including the final array. */
240#define SerializedTransactionStateHeaderSize \
241 offsetof(SerializedTransactionState, parallelCurrentXids)
242
243/*
244 * CurrentTransactionState always points to the current transaction state
245 * block. It will point to TopTransactionStateData when not in a
246 * transaction at all, or when in a top-level transaction.
247 */
250 .blockState = TBLOCK_DEFAULT,
251 .topXidLogged = false,
252};
253
254/*
255 * unreportedXids holds XIDs of all subtransactions that have not yet been
256 * reported in an XLOG_XACT_ASSIGNMENT record.
257 */
260
262
263/*
264 * The subtransaction ID and command ID assignment counters are global
265 * to a whole transaction, so we do not keep them in the state stack.
266 */
270
271/*
272 * xactStartTimestamp is the value of transaction_timestamp().
273 * stmtStartTimestamp is the value of statement_timestamp().
274 * xactStopTimestamp is the time at which we log a commit / abort WAL record,
275 * or if that was skipped, the time of the first subsequent
276 * GetCurrentTransactionStopTimestamp() call.
277 *
278 * These do not change as we enter and exit subtransactions, so we don't
279 * keep them inside the TransactionState stack.
280 */
284
285/*
286 * GID to be used for preparing the current transaction. This is also
287 * global to a whole transaction, so we don't keep it in the state stack.
288 */
289static char *prepareGID;
290
291/*
292 * Some commands want to force synchronous commit.
293 */
294static bool forceSyncCommit = false;
295
296/* Flag for logging statements in a transaction. */
297bool xact_is_sampled = false;
298
299/*
300 * Private context for transaction-abort work --- we reserve space for this
301 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
302 * when we've run out of memory.
303 */
305
306/*
307 * List of add-on start- and end-of-xact callbacks
308 */
315
317
318/*
319 * List of add-on start- and end-of-subxact callbacks
320 */
327
329
330
331/* local function prototypes */
333static void AbortTransaction(void);
334static void AtAbort_Memory(void);
335static void AtCleanup_Memory(void);
336static void AtAbort_ResourceOwner(void);
337static void AtCCI_LocalCache(void);
338static void AtCommit_Memory(void);
339static void AtStart_Cache(void);
340static void AtStart_Memory(void);
341static void AtStart_ResourceOwner(void);
342static void CallXactCallbacks(XactEvent event);
343static void CallSubXactCallbacks(SubXactEvent event,
346static void CleanupTransaction(void);
347static void CheckTransactionBlock(bool isTopLevel, bool throwError,
348 const char *stmtType);
349static void CommitTransaction(void);
351static void StartTransaction(void);
352
353static bool CommitTransactionCommandInternal(void);
354static bool AbortCurrentTransactionInternal(void);
355
356static void StartSubTransaction(void);
357static void CommitSubTransaction(void);
358static void AbortSubTransaction(void);
359static void CleanupSubTransaction(void);
360static void PushTransaction(void);
361static void PopTransaction(void);
362
363static void AtSubAbort_Memory(void);
364static void AtSubCleanup_Memory(void);
365static void AtSubAbort_ResourceOwner(void);
366static void AtSubCommit_Memory(void);
367static void AtSubStart_Memory(void);
368static void AtSubStart_ResourceOwner(void);
369
370static void ShowTransactionState(const char *str);
371static void ShowTransactionStateRec(const char *str, TransactionState s);
372static const char *BlockStateAsString(TBlockState blockState);
373static const char *TransStateAsString(TransState state);
374
375
376/* ----------------------------------------------------------------
377 * transaction state accessors
378 * ----------------------------------------------------------------
379 */
380
381/*
382 * IsTransactionState
383 *
384 * This returns true if we are inside a valid transaction; that is,
385 * it is safe to initiate database access, take heavyweight locks, etc.
386 */
387bool
389{
391
392 /*
393 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
394 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
395 * TRANS_PREPARE since it might be too soon or too late within those
396 * transition states to do anything interesting. Hence, the only "valid"
397 * state is TRANS_INPROGRESS.
398 */
399 return (s->state == TRANS_INPROGRESS);
400}
401
402/*
403 * IsAbortedTransactionBlockState
404 *
405 * This returns true if we are within an aborted transaction block.
406 */
407bool
409{
411
412 if (s->blockState == TBLOCK_ABORT ||
414 return true;
415
416 return false;
417}
418
419
420/*
421 * GetTopTransactionId
422 *
423 * This will return the XID of the main transaction, assigning one if
424 * it's not yet set. Be careful to call this only inside a valid xact.
425 */
433
434/*
435 * GetTopTransactionIdIfAny
436 *
437 * This will return the XID of the main transaction, if one is assigned.
438 * It will return InvalidTransactionId if we are not currently inside a
439 * transaction, or inside a transaction that hasn't yet been assigned an XID.
440 */
446
447/*
448 * GetCurrentTransactionId
449 *
450 * This will return the XID of the current transaction (main or sub
451 * transaction), assigning one if it's not yet set. Be careful to call this
452 * only inside a valid xact.
453 */
463
464/*
465 * GetCurrentTransactionIdIfAny
466 *
467 * This will return the XID of the current sub xact, if one is assigned.
468 * It will return InvalidTransactionId if we are not currently inside a
469 * transaction, or inside a transaction that hasn't been assigned an XID yet.
470 */
476
477/*
478 * GetTopFullTransactionId
479 *
480 * This will return the FullTransactionId of the main transaction, assigning
481 * one if it's not yet set. Be careful to call this only inside a valid xact.
482 */
490
491/*
492 * GetTopFullTransactionIdIfAny
493 *
494 * This will return the FullTransactionId of the main transaction, if one is
495 * assigned. It will return InvalidFullTransactionId if we are not currently
496 * inside a transaction, or inside a transaction that hasn't yet been assigned
497 * one.
498 */
504
505/*
506 * GetCurrentFullTransactionId
507 *
508 * This will return the FullTransactionId of the current transaction (main or
509 * sub transaction), assigning one if it's not yet set. Be careful to call
510 * this only inside a valid xact.
511 */
521
522/*
523 * GetCurrentFullTransactionIdIfAny
524 *
525 * This will return the FullTransactionId of the current sub xact, if one is
526 * assigned. It will return InvalidFullTransactionId if we are not currently
527 * inside a transaction, or inside a transaction that hasn't been assigned one
528 * yet.
529 */
535
536/*
537 * MarkCurrentTransactionIdLoggedIfAny
538 *
539 * Remember that the current xid - if it is assigned - now has been wal logged.
540 */
541void
547
548/*
549 * IsSubxactTopXidLogPending
550 *
551 * This is used to decide whether we need to WAL log the top-level XID for
552 * operation in a subtransaction. We require that for logical decoding, see
553 * LogicalDecodingProcessRecord.
554 *
555 * This returns true if effective_wal_level is logical and we are inside
556 * a valid subtransaction, for which the assignment was not yet written to
557 * any WAL record.
558 */
559bool
561{
562 /* check whether it is already logged */
564 return false;
565
566 /* effective_wal_level has to be logical */
568 return false;
569
570 /* we need to be in a transaction state */
571 if (!IsTransactionState())
572 return false;
573
574 /* it has to be a subtransaction */
575 if (!IsSubTransaction())
576 return false;
577
578 /* the subtransaction has to have a XID assigned */
580 return false;
581
582 return true;
583}
584
585/*
586 * MarkSubxactTopXidLogged
587 *
588 * Remember that the top transaction id for the current subtransaction is WAL
589 * logged now.
590 */
591void
598
599/*
600 * GetStableLatestTransactionId
601 *
602 * Get the transaction's XID if it has one, else read the next-to-be-assigned
603 * XID. Once we have a value, return that same value for the remainder of the
604 * current transaction. This is meant to provide the reference point for the
605 * age(xid) function, but might be useful for other maintenance tasks as well.
606 */
625
626/*
627 * AssignTransactionId
628 *
629 * Assigns a new permanent FullTransactionId to the given TransactionState.
630 * We do not assign XIDs to transactions until/unless this is called.
631 * Also, any parent TransactionStates that don't yet have XIDs are assigned
632 * one; this maintains the invariant that a child transaction has an XID
633 * following its parent's.
634 */
635static void
637{
638 bool isSubXact = (s->parent != NULL);
640 bool log_unknown_top = false;
641
642 /* Assert that caller didn't screw up */
645
646 /*
647 * Workers synchronize transaction state at the beginning of each parallel
648 * operation, so we can't account for new XIDs at this point.
649 */
653 errmsg("cannot assign transaction IDs during a parallel operation")));
654
655 /*
656 * Ensure parent(s) have XIDs, so that a child always has an XID later
657 * than its parent. Mustn't recurse here, or we might get a stack
658 * overflow if we're at the bottom of a huge stack of subtransactions none
659 * of which have XIDs yet.
660 */
662 {
664 TransactionState *parents;
665 size_t parentOffset = 0;
666
669 {
670 parents[parentOffset++] = p;
671 p = p->parent;
672 }
673
674 /*
675 * This is technically a recursive call, but the recursion will never
676 * be more than one layer deep.
677 */
678 while (parentOffset != 0)
679 AssignTransactionId(parents[--parentOffset]);
680
681 pfree(parents);
682 }
683
684 /*
685 * When effective_wal_level is logical, guarantee that a subtransaction's
686 * xid can only be seen in the WAL stream if its toplevel xid has been
687 * logged before. If necessary we log an xact_assignment record with fewer
688 * than PGPROC_MAX_CACHED_SUBXIDS. Note that it is fine if didLogXid isn't
689 * set for a transaction even though it appears in a WAL record, we just
690 * might superfluously log something. That can happen when an xid is
691 * included somewhere inside a wal record, but not in XLogRecord->xl_xid,
692 * like in xl_standby_locks.
693 */
696 log_unknown_top = true;
697
698 /*
699 * Generate a new FullTransactionId and record its xid in PGPROC and
700 * pg_subtrans.
701 *
702 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
703 * shared storage other than PGPROC; because if there's no room for it in
704 * PGPROC, the subtrans entry is needed to ensure that other backends see
705 * the Xid as "running". See GetNewTransactionId.
706 */
708 if (!isSubXact)
710
711 if (isSubXact)
714
715 /*
716 * If it's a top-level transaction, the predicate locking system needs to
717 * be told about it too.
718 */
719 if (!isSubXact)
721
722 /*
723 * Acquire lock on the transaction XID. (We assume this cannot block.) We
724 * have to ensure that the lock is assigned to the transaction's own
725 * ResourceOwner.
726 */
729
731
733
734 /*
735 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
736 * top-level transaction we issue a WAL record for the assignment. We
737 * include the top-level xid and all the subxids that have not yet been
738 * reported using XLOG_XACT_ASSIGNMENT records.
739 *
740 * This is required to limit the amount of shared memory required in a hot
741 * standby server to keep track of in-progress XIDs. See notes for
742 * RecordKnownAssignedTransactionIds().
743 *
744 * We don't keep track of the immediate parent of each subxid, only the
745 * top-level transaction that each subxact belongs to. This is correct in
746 * recovery only because aborted subtransactions are separately WAL
747 * logged.
748 *
749 * This is correct even for the case where several levels above us didn't
750 * have an xid assigned as we recursed up to them beforehand.
751 */
753 {
756
757 /*
758 * ensure this test matches similar one in
759 * RecoverPreparedTransactions()
760 */
763 {
765
766 /*
767 * xtop is always set by now because we recurse up transaction
768 * stack to the highest unassigned xid and then come back down
769 */
772 xlrec.nsubxacts = nUnreportedXids;
773
778
780
781 nUnreportedXids = 0;
782 /* mark top, not current xact as having been logged */
784 }
785 }
786}
787
788/*
789 * GetCurrentSubTransactionId
790 */
798
799/*
800 * SubTransactionIsActive
801 *
802 * Test if the specified subxact ID is still active. Note caller is
803 * responsible for checking whether this ID is relevant to the current xact.
804 */
805bool
807{
809
810 for (s = CurrentTransactionState; s != NULL; s = s->parent)
811 {
812 if (s->state == TRANS_ABORT)
813 continue;
814 if (s->subTransactionId == subxid)
815 return true;
816 }
817 return false;
818}
819
820
821/*
822 * GetCurrentCommandId
823 *
824 * "used" must be true if the caller intends to use the command ID to mark
825 * inserted/updated/deleted tuples. false means the ID is being fetched
826 * for read-only purposes (ie, as a snapshot validity cutoff). See
827 * CommandCounterIncrement() for discussion.
828 */
831{
832 /* this is global to a transaction, not subtransaction-local */
833 if (used)
834 {
835 /*
836 * Forbid setting currentCommandIdUsed in a parallel worker, because
837 * we have no provision for communicating this back to the leader. We
838 * could relax this restriction when currentCommandIdUsed was already
839 * true at the start of the parallel operation.
840 */
841 if (IsParallelWorker())
844 errmsg("cannot modify data in a parallel worker")));
845
847 }
848 return currentCommandId;
849}
850
851/*
852 * SetParallelStartTimestamps
853 *
854 * In a parallel worker, we should inherit the parent transaction's
855 * timestamps rather than setting our own. The parallel worker
856 * infrastructure must call this to provide those values before
857 * calling StartTransaction() or SetCurrentStatementStartTimestamp().
858 */
859void
866
867/*
868 * GetCurrentTransactionStartTimestamp
869 */
875
876/*
877 * GetCurrentStatementStartTimestamp
878 */
884
885/*
886 * GetCurrentTransactionStopTimestamp
887 *
888 * If the transaction stop time hasn't already been set, which can happen if
889 * we decided we don't need to log an XLOG record, set xactStopTimestamp.
890 */
893{
895
896 /* should only be called after commit / abort processing */
897 Assert(s->state == TRANS_DEFAULT ||
898 s->state == TRANS_COMMIT ||
899 s->state == TRANS_ABORT ||
900 s->state == TRANS_PREPARE);
901
902 if (xactStopTimestamp == 0)
904
905 return xactStopTimestamp;
906}
907
908/*
909 * SetCurrentStatementStartTimestamp
910 *
911 * In a parallel worker, this should already have been provided by a call
912 * to SetParallelStartTimestamps().
913 */
914void
922
923/*
924 * GetCurrentTransactionNestLevel
925 *
926 * Note: this will return zero when not inside any transaction, one when
927 * inside a top-level transaction, etc.
928 */
929int
936
937
938/*
939 * TransactionIdIsCurrentTransactionId
940 */
941bool
943{
945
946 /*
947 * We always say that BootstrapTransactionId is "not my transaction ID"
948 * even when it is (ie, during bootstrap). Along with the fact that
949 * transam.c always treats BootstrapTransactionId as already committed,
950 * this causes the heapam_visibility.c routines to see all tuples as
951 * committed, which is what we need during bootstrap. (Bootstrap mode
952 * only inserts tuples, it never updates or deletes them, so all tuples
953 * can be presumed good immediately.)
954 *
955 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
956 * not my transaction ID, so we can just return "false" immediately for
957 * any non-normal XID.
958 */
959 if (!TransactionIdIsNormal(xid))
960 return false;
961
963 return true;
964
965 /*
966 * In parallel workers, the XIDs we must consider as current are stored in
967 * ParallelCurrentXids rather than the transaction-state stack. Note that
968 * the XIDs in this array are sorted numerically rather than according to
969 * transactionIdPrecedes order.
970 */
971 if (nParallelCurrentXids > 0)
972 {
973 int low,
974 high;
975
976 low = 0;
977 high = nParallelCurrentXids - 1;
978 while (low <= high)
979 {
980 int middle;
982
983 middle = low + (high - low) / 2;
985 if (probe == xid)
986 return true;
987 else if (probe < xid)
988 low = middle + 1;
989 else
990 high = middle - 1;
991 }
992 return false;
993 }
994
995 /*
996 * We will return true for the Xid of the current subtransaction, any of
997 * its subcommitted children, any of its parents, or any of their
998 * previously subcommitted children. However, a transaction being aborted
999 * is no longer "current", even though it may still have an entry on the
1000 * state stack.
1001 */
1002 for (s = CurrentTransactionState; s != NULL; s = s->parent)
1003 {
1004 int low,
1005 high;
1006
1007 if (s->state == TRANS_ABORT)
1008 continue;
1010 continue; /* it can't have any child XIDs either */
1012 return true;
1013 /* As the childXids array is ordered, we can use binary search */
1014 low = 0;
1015 high = s->nChildXids - 1;
1016 while (low <= high)
1017 {
1018 int middle;
1020
1021 middle = low + (high - low) / 2;
1022 probe = s->childXids[middle];
1023 if (TransactionIdEquals(probe, xid))
1024 return true;
1025 else if (TransactionIdPrecedes(probe, xid))
1026 low = middle + 1;
1027 else
1028 high = middle - 1;
1029 }
1030 }
1031
1032 return false;
1033}
1034
1035/*
1036 * TransactionStartedDuringRecovery
1037 *
1038 * Returns true if the current transaction started while recovery was still
1039 * in progress. Recovery might have ended since so RecoveryInProgress() might
1040 * return false already.
1041 */
1042bool
1047
1048/*
1049 * EnterParallelMode
1050 */
1051void
1053{
1055
1056 Assert(s->parallelModeLevel >= 0);
1057
1058 ++s->parallelModeLevel;
1059}
1060
1061/*
1062 * ExitParallelMode
1063 */
1064void
1075
1076/*
1077 * IsInParallelMode
1078 *
1079 * Are we in a parallel operation, as either the leader or a worker? Check
1080 * this to prohibit operations that change backend-local state expected to
1081 * match across all workers. Mere caches usually don't require such a
1082 * restriction. State modified in a strict push/pop fashion, such as the
1083 * active snapshot stack, is often fine.
1084 *
1085 * We say we are in parallel mode if we are in a subxact of a transaction
1086 * that's initiated a parallel operation; for most purposes that context
1087 * has all the same restrictions.
1088 */
1089bool
1091{
1093
1094 return s->parallelModeLevel != 0 || s->parallelChildXact;
1095}
1096
1097/*
1098 * CommandCounterIncrement
1099 */
1100void
1102{
1103 /*
1104 * If the current value of the command counter hasn't been "used" to mark
1105 * tuples, we need not increment it, since there's no need to distinguish
1106 * a read-only command from others. This helps postpone command counter
1107 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
1108 */
1110 {
1111 /*
1112 * Workers synchronize transaction state at the beginning of each
1113 * parallel operation, so we can't account for new commands after that
1114 * point.
1115 */
1117 ereport(ERROR,
1119 errmsg("cannot start commands during a parallel operation")));
1120
1121 currentCommandId += 1;
1123 {
1124 currentCommandId -= 1;
1125 ereport(ERROR,
1127 errmsg("cannot have more than 2^32-2 commands in a transaction")));
1128 }
1129 currentCommandIdUsed = false;
1130
1131 /* Propagate new command ID into static snapshots */
1133
1134 /*
1135 * Make any catalog changes done by the just-completed command visible
1136 * in the local syscache. We obviously don't need to do this after a
1137 * read-only command. (But see hacks in inval.c to make real sure we
1138 * don't think a command that queued inval messages was read-only.)
1139 */
1141 }
1142}
1143
1144/*
1145 * ForceSyncCommit
1146 *
1147 * Interface routine to allow commands to force a synchronous commit of the
1148 * current top-level transaction. Currently, two-phase commit does not
1149 * persist and restore this variable. So long as all callers use
1150 * PreventInTransactionBlock(), that omission has no consequences.
1151 */
1152void
1154{
1155 forceSyncCommit = true;
1156}
1157
1158
1159/* ----------------------------------------------------------------
1160 * StartTransaction stuff
1161 * ----------------------------------------------------------------
1162 */
1163
1164/*
1165 * AtStart_Cache
1166 */
1167static void
1172
1173/*
1174 * AtStart_Memory
1175 */
1176static void
1178{
1180
1181 /*
1182 * Remember the memory context that was active prior to transaction start.
1183 */
1185
1186 /*
1187 * If this is the first time through, create a private context for
1188 * AbortTransaction to work in. By reserving some space now, we can
1189 * insulate AbortTransaction from out-of-memory scenarios. Like
1190 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1191 * size, so that space will be reserved immediately.
1192 */
1196 "TransactionAbortContext",
1197 32 * 1024,
1198 32 * 1024,
1199 32 * 1024);
1200
1201 /*
1202 * Likewise, if this is the first time through, create a top-level context
1203 * for transaction-local data. This context will be reset at transaction
1204 * end, and then re-used in later transactions.
1205 */
1209 "TopTransactionContext",
1211
1212 /*
1213 * In a top-level transaction, CurTransactionContext is the same as
1214 * TopTransactionContext.
1215 */
1218
1219 /* Make the CurTransactionContext active. */
1221}
1222
1223/*
1224 * AtStart_ResourceOwner
1225 */
1226static void
1228{
1230
1231 /*
1232 * We shouldn't have a transaction resource owner already.
1233 */
1235
1236 /*
1237 * Create a toplevel resource owner for the transaction.
1238 */
1239 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1240
1244}
1245
1246/* ----------------------------------------------------------------
1247 * StartSubTransaction stuff
1248 * ----------------------------------------------------------------
1249 */
1250
1251/*
1252 * AtSubStart_Memory
1253 */
1254static void
1256{
1258
1260
1261 /*
1262 * Remember the context that was active prior to subtransaction start.
1263 */
1265
1266 /*
1267 * Create a CurTransactionContext, which will be used to hold data that
1268 * survives subtransaction commit but disappears on subtransaction abort.
1269 * We make it a child of the immediate parent's CurTransactionContext.
1270 */
1272 "CurTransactionContext",
1275
1276 /* Make the CurTransactionContext active. */
1278}
1279
1280/*
1281 * AtSubStart_ResourceOwner
1282 */
1283static void
1285{
1287
1288 Assert(s->parent != NULL);
1289
1290 /*
1291 * Create a resource owner for the subtransaction. We make it a child of
1292 * the immediate parent's resource owner.
1293 */
1296 "SubTransaction");
1297
1300}
1301
1302/* ----------------------------------------------------------------
1303 * CommitTransaction stuff
1304 * ----------------------------------------------------------------
1305 */
1306
1307/*
1308 * RecordTransactionCommit
1309 *
1310 * Returns latest XID among xact and its children, or InvalidTransactionId
1311 * if the xact has no XID. (We compute that here just because it's easier.)
1312 *
1313 * If you change this function, see RecordTransactionCommitPrepared also.
1314 */
1315static TransactionId
1317{
1321 int nrels;
1322 RelFileLocator *rels;
1323 int nchildren;
1324 TransactionId *children;
1325 int ndroppedstats = 0;
1327 int nmsgs = 0;
1329 bool RelcacheInitFileInval = false;
1330 bool wrote_xlog;
1331
1332 /*
1333 * Log pending invalidations for logical decoding of in-progress
1334 * transactions. Normally for DDLs, we log this at each command end,
1335 * however, for certain cases where we directly update the system table
1336 * without a transaction block, the invalidations are not logged till this
1337 * time.
1338 */
1341
1342 /* Get data needed for commit record */
1343 nrels = smgrGetPendingDeletes(true, &rels);
1348 &RelcacheInitFileInval);
1349 wrote_xlog = (XactLastRecEnd != 0);
1350
1351 /*
1352 * If we haven't been assigned an XID yet, we neither can, nor do we want
1353 * to write a COMMIT record.
1354 */
1355 if (!markXidCommitted)
1356 {
1357 /*
1358 * We expect that every RelationDropStorage is followed by a catalog
1359 * update, and hence XID assignment, so we shouldn't get here with any
1360 * pending deletes. Same is true for dropping stats.
1361 *
1362 * Use a real test not just an Assert to check this, since it's a bit
1363 * fragile.
1364 */
1365 if (nrels != 0 || ndroppedstats != 0)
1366 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
1367
1368 /* Can't have child XIDs either; AssignTransactionId enforces this */
1369 Assert(nchildren == 0);
1370
1371 /*
1372 * Transactions without an assigned xid can contain invalidation
1373 * messages. While inplace updates do this, this is not known to be
1374 * necessary; see comment at inplace CacheInvalidateHeapTuple().
1375 * Extensions might still rely on this capability, and standbys may
1376 * need to process those invals. We can't emit a commit record
1377 * without an xid, and we don't want to force assigning an xid,
1378 * because that'd be problematic for e.g. vacuum. Hence we emit a
1379 * bespoke record for the invalidations. We don't want to use that in
1380 * case a commit record is emitted, so they happen synchronously with
1381 * commits (besides not wanting to emit more WAL records).
1382 *
1383 * XXX Every known use of this capability is a defect. Since an XID
1384 * isn't controlling visibility of the change that prompted invals,
1385 * other sessions need the inval even if this transactions aborts.
1386 *
1387 * ON COMMIT DELETE ROWS does a nontransactional index_build(), which
1388 * queues a relcache inval, including in transactions without an xid
1389 * that had read the (empty) table. Standbys don't need any ON COMMIT
1390 * DELETE ROWS invals, but we've not done the work to withhold them.
1391 */
1392 if (nmsgs != 0)
1393 {
1395 RelcacheInitFileInval);
1396 wrote_xlog = true; /* not strictly necessary */
1397 }
1398
1399 /*
1400 * If we didn't create XLOG entries, we're done here; otherwise we
1401 * should trigger flushing those entries the same as a commit record
1402 * would. This will primarily happen for HOT pruning and the like; we
1403 * want these to be flushed to disk in due time.
1404 */
1405 if (!wrote_xlog)
1406 goto cleanup;
1407 }
1408 else
1409 {
1410 bool replorigin;
1411
1412 /*
1413 * Are we using the replication origins feature? Or, in other words,
1414 * are we replaying remote actions?
1415 */
1418
1419 /*
1420 * Mark ourselves as within our "commit critical section". This
1421 * forces any concurrent checkpoint to wait until we've updated
1422 * pg_xact. Without this, it is possible for the checkpoint to set
1423 * REDO after the XLOG record but fail to flush the pg_xact update to
1424 * disk, leading to loss of the transaction commit if the system
1425 * crashes a little later.
1426 *
1427 * Note: we could, but don't bother to, set this flag in
1428 * RecordTransactionAbort. That's because loss of a transaction abort
1429 * is noncritical; the presumption would be that it aborted, anyway.
1430 *
1431 * It's safe to change the delayChkptFlags flag of our own backend
1432 * without holding the ProcArrayLock, since we're the only one
1433 * modifying it. This makes checkpoint's determination of which xacts
1434 * are delaying the checkpoint a bit fuzzy, but it doesn't matter.
1435 *
1436 * Note, it is important to get the commit timestamp after marking the
1437 * transaction in the commit critical section. See
1438 * RecordTransactionCommitPrepared.
1439 */
1443
1445
1446 /*
1447 * Ensures the DELAY_CHKPT_IN_COMMIT flag write is globally visible
1448 * before commit time is written.
1449 */
1451
1452 /*
1453 * Insert the commit XLOG record.
1454 */
1456 nchildren, children, nrels, rels,
1458 nmsgs, invalMessages,
1459 RelcacheInitFileInval,
1461 InvalidTransactionId, NULL /* plain commit */ );
1462
1463 if (replorigin)
1464 /* Move LSNs forward for this replication origin */
1467
1468 /*
1469 * Record commit timestamp. The value comes from plain commit
1470 * timestamp if there's no replication origin; otherwise, the
1471 * timestamp was already set in replorigin_session_origin_timestamp by
1472 * replication.
1473 *
1474 * We don't need to WAL-log anything here, as the commit record
1475 * written above already contains the data.
1476 */
1477
1480
1484 }
1485
1486 /*
1487 * Check if we want to commit asynchronously. We can allow the XLOG flush
1488 * to happen asynchronously if synchronous_commit=off, or if the current
1489 * transaction has not performed any WAL-logged operation or didn't assign
1490 * an xid. The transaction can end up not writing any WAL, even if it has
1491 * an xid, if it only wrote to temporary and/or unlogged tables. It can
1492 * end up having written WAL without an xid if it did HOT pruning. In
1493 * case of a crash, the loss of such a transaction will be irrelevant;
1494 * temp tables will be lost anyway, unlogged tables will be truncated and
1495 * HOT pruning will be done again later. (Given the foregoing, you might
1496 * think that it would be unnecessary to emit the XLOG record at all in
1497 * this case, but we don't currently try to do that. It would certainly
1498 * cause problems at least in Hot Standby mode, where the
1499 * KnownAssignedXids machinery requires tracking every XID assignment. It
1500 * might be OK to skip it only when wal_level < replica, but for now we
1501 * don't.)
1502 *
1503 * However, if we're doing cleanup of any non-temp rels or committing any
1504 * command that wanted to force sync commit, then we must flush XLOG
1505 * immediately. (We must not allow asynchronous commit if there are any
1506 * non-temp tables to be deleted, because we might delete the files before
1507 * the COMMIT record is flushed to disk. We do allow asynchronous commit
1508 * if all to-be-deleted tables are temporary though, since they are lost
1509 * anyway if we crash.)
1510 */
1511 if ((wrote_xlog && markXidCommitted &&
1513 forceSyncCommit || nrels > 0)
1514 {
1516
1517 /*
1518 * Now we may update the CLOG, if we wrote a COMMIT record above
1519 */
1520 if (markXidCommitted)
1521 TransactionIdCommitTree(xid, nchildren, children);
1522 }
1523 else
1524 {
1525 /*
1526 * Asynchronous commit case:
1527 *
1528 * This enables possible committed transaction loss in the case of a
1529 * postmaster crash because WAL buffers are left unwritten. Ideally we
1530 * could issue the WAL write without the fsync, but some
1531 * wal_sync_methods do not allow separate write/fsync.
1532 *
1533 * Report the latest async commit LSN, so that the WAL writer knows to
1534 * flush this commit.
1535 */
1537
1538 /*
1539 * We must not immediately update the CLOG, since we didn't flush the
1540 * XLOG. Instead, we store the LSN up to which the XLOG must be
1541 * flushed before the CLOG may be updated.
1542 */
1543 if (markXidCommitted)
1545 }
1546
1547 /*
1548 * If we entered a commit critical section, leave it now, and let
1549 * checkpoints proceed.
1550 */
1551 if (markXidCommitted)
1552 {
1555 }
1556
1557 /* Compute latestXid while we have the child XIDs handy */
1558 latestXid = TransactionIdLatest(xid, nchildren, children);
1559
1560 /*
1561 * Wait for synchronous replication, if required. Similar to the decision
1562 * above about using committing asynchronously we only want to wait if
1563 * this backend assigned an xid and wrote WAL. No need to wait if an xid
1564 * was assigned due to temporary/unlogged tables or due to HOT pruning.
1565 *
1566 * Note that at this stage we have marked clog, but still show as running
1567 * in the procarray and continue to hold locks.
1568 */
1571
1572 /* remember end of last commit record */
1574
1575 /* Reset XactLastRecEnd until the next transaction writes something */
1576 XactLastRecEnd = 0;
1577cleanup:
1578 /* Clean up local data */
1579 if (rels)
1580 pfree(rels);
1581 if (ndroppedstats)
1583
1584 return latestXid;
1585}
1586
1587
1588/*
1589 * AtCCI_LocalCache
1590 */
1591static void
1593{
1594 /*
1595 * Make any pending relation map changes visible. We must do this before
1596 * processing local sinval messages, so that the map changes will get
1597 * reflected into the relcache when relcache invals are processed.
1598 */
1600
1601 /*
1602 * Make catalog changes visible to me for the next command.
1603 */
1605}
1606
1607/*
1608 * AtCommit_Memory
1609 */
1610static void
1612{
1614
1615 /*
1616 * Return to the memory context that was current before we started the
1617 * transaction. (In principle, this could not be any of the contexts we
1618 * are about to delete. If it somehow is, assertions in mcxt.c will
1619 * complain.)
1620 */
1622
1623 /*
1624 * Release all transaction-local memory. TopTransactionContext survives
1625 * but becomes empty; any sub-contexts go away.
1626 */
1629
1630 /*
1631 * Clear these pointers as a pro-forma matter. (Notionally, while
1632 * TopTransactionContext still exists, it's currently not associated with
1633 * this TransactionState struct.)
1634 */
1637}
1638
1639/* ----------------------------------------------------------------
1640 * CommitSubTransaction stuff
1641 * ----------------------------------------------------------------
1642 */
1643
1644/*
1645 * AtSubCommit_Memory
1646 */
1647static void
1649{
1651
1652 Assert(s->parent != NULL);
1653
1654 /* Return to parent transaction level's memory context. */
1657
1658 /*
1659 * Ordinarily we cannot throw away the child's CurTransactionContext,
1660 * since the data it contains will be needed at upper commit. However, if
1661 * there isn't actually anything in it, we can throw it away. This avoids
1662 * a small memory leak in the common case of "trivial" subxacts.
1663 */
1665 {
1668 }
1669}
1670
1671/*
1672 * AtSubCommit_childXids
1673 *
1674 * Pass my own XID and my child XIDs up to my parent as committed children.
1675 */
1676static void
1678{
1680 int new_nChildXids;
1681
1682 Assert(s->parent != NULL);
1683
1684 /*
1685 * The parent childXids array will need to hold my XID and all my
1686 * childXids, in addition to the XIDs already there.
1687 */
1689
1690 /* Allocate or enlarge the parent array if necessary */
1692 {
1693 int new_maxChildXids;
1695
1696 /*
1697 * Make it 2x what's needed right now, to avoid having to enlarge it
1698 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1699 * is what ensures that we don't need to worry about integer overflow
1700 * here or in the calculation of new_nChildXids.)
1701 */
1703 (int) (MaxAllocSize / sizeof(TransactionId)));
1704
1706 ereport(ERROR,
1708 errmsg("maximum number of committed subtransactions (%d) exceeded",
1709 (int) (MaxAllocSize / sizeof(TransactionId)))));
1710
1711 /*
1712 * We keep the child-XID arrays in TopTransactionContext; this avoids
1713 * setting up child-transaction contexts for what might be just a few
1714 * bytes of grandchild XIDs.
1715 */
1716 if (s->parent->childXids == NULL)
1720 else
1723
1726 }
1727
1728 /*
1729 * Copy all my XIDs to parent's array.
1730 *
1731 * Note: We rely on the fact that the XID of a child always follows that
1732 * of its parent. By copying the XID of this subtransaction before the
1733 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1734 * all XIDs already in the array belong to subtransactions started and
1735 * subcommitted before us, so their XIDs must precede ours.
1736 */
1738
1739 if (s->nChildXids > 0)
1740 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1741 s->childXids,
1742 s->nChildXids * sizeof(TransactionId));
1743
1745
1746 /* Release child's array to avoid leakage */
1747 if (s->childXids != NULL)
1748 pfree(s->childXids);
1749 /* We must reset these to avoid double-free if fail later in commit */
1750 s->childXids = NULL;
1751 s->nChildXids = 0;
1752 s->maxChildXids = 0;
1753}
1754
1755/* ----------------------------------------------------------------
1756 * AbortTransaction stuff
1757 * ----------------------------------------------------------------
1758 */
1759
1760/*
1761 * RecordTransactionAbort
1762 *
1763 * Returns latest XID among xact and its children, or InvalidTransactionId
1764 * if the xact has no XID. (We compute that here just because it's easier.)
1765 */
1766static TransactionId
1768{
1771 int nrels;
1772 RelFileLocator *rels;
1773 int ndroppedstats = 0;
1775 int nchildren;
1776 TransactionId *children;
1777 TimestampTz xact_time;
1778 bool replorigin;
1779
1780 /*
1781 * If we haven't been assigned an XID, nobody will care whether we aborted
1782 * or not. Hence, we're done in that case. It does not matter if we have
1783 * rels to delete (note that this routine is not responsible for actually
1784 * deleting 'em). We cannot have any child XIDs, either.
1785 */
1786 if (!TransactionIdIsValid(xid))
1787 {
1788 /* Reset XactLastRecEnd until the next transaction writes something */
1789 if (!isSubXact)
1790 XactLastRecEnd = 0;
1791 return InvalidTransactionId;
1792 }
1793
1794 /*
1795 * We have a valid XID, so we should write an ABORT record for it.
1796 *
1797 * We do not flush XLOG to disk here, since the default assumption after a
1798 * crash would be that we aborted, anyway. For the same reason, we don't
1799 * need to worry about interlocking against checkpoint start.
1800 */
1801
1802 /*
1803 * Check that we haven't aborted halfway through RecordTransactionCommit.
1804 */
1805 if (TransactionIdDidCommit(xid))
1806 elog(PANIC, "cannot abort transaction %u, it was already committed",
1807 xid);
1808
1809 /*
1810 * Are we using the replication origins feature? Or, in other words, are
1811 * we replaying remote actions?
1812 */
1815
1816 /* Fetch the data we need for the abort record */
1817 nrels = smgrGetPendingDeletes(false, &rels);
1820
1821 /* XXX do we really need a critical section here? */
1823
1824 /* Write the ABORT record */
1825 if (isSubXact)
1826 xact_time = GetCurrentTimestamp();
1827 else
1828 {
1830 }
1831
1832 XactLogAbortRecord(xact_time,
1833 nchildren, children,
1834 nrels, rels,
1837 NULL);
1838
1839 if (replorigin)
1840 /* Move LSNs forward for this replication origin */
1843
1844 /*
1845 * Report the latest async abort LSN, so that the WAL writer knows to
1846 * flush this abort. There's nothing to be gained by delaying this, since
1847 * WALWriter may as well do this when it can. This is important with
1848 * streaming replication because if we don't flush WAL regularly we will
1849 * find that large aborts leave us with a long backlog for when commits
1850 * occur after the abort, increasing our window of data loss should
1851 * problems occur at that point.
1852 */
1853 if (!isSubXact)
1855
1856 /*
1857 * Mark the transaction aborted in clog. This is not absolutely necessary
1858 * but we may as well do it while we are here; also, in the subxact case
1859 * it is helpful because XactLockTableWait makes use of it to avoid
1860 * waiting for already-aborted subtransactions. It is OK to do it without
1861 * having flushed the ABORT record to disk, because in event of a crash
1862 * we'd be assumed to have aborted anyway.
1863 */
1864 TransactionIdAbortTree(xid, nchildren, children);
1865
1867
1868 /* Compute latestXid while we have the child XIDs handy */
1869 latestXid = TransactionIdLatest(xid, nchildren, children);
1870
1871 /*
1872 * If we're aborting a subtransaction, we can immediately remove failed
1873 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1874 * subxacts, because we already have the child XID array at hand. For
1875 * main xacts, the equivalent happens just after this function returns.
1876 */
1877 if (isSubXact)
1879
1880 /* Reset XactLastRecEnd until the next transaction writes something */
1881 if (!isSubXact)
1882 XactLastRecEnd = 0;
1883
1884 /* And clean up local data */
1885 if (rels)
1886 pfree(rels);
1887 if (ndroppedstats)
1889
1890 return latestXid;
1891}
1892
1893/*
1894 * AtAbort_Memory
1895 */
1896static void
1898{
1899 /*
1900 * Switch into TransactionAbortContext, which should have some free space
1901 * even if nothing else does. We'll work in this context until we've
1902 * finished cleaning up.
1903 *
1904 * It is barely possible to get here when we've not been able to create
1905 * TransactionAbortContext yet; if so use TopMemoryContext.
1906 */
1909 else
1911}
1912
1913/*
1914 * AtSubAbort_Memory
1915 */
1916static void
1923
1924
1925/*
1926 * AtAbort_ResourceOwner
1927 */
1928static void
1930{
1931 /*
1932 * Make sure we have a valid ResourceOwner, if possible (else it will be
1933 * NULL, which is OK)
1934 */
1936}
1937
1938/*
1939 * AtSubAbort_ResourceOwner
1940 */
1941static void
1943{
1945
1946 /* Make sure we have a valid ResourceOwner */
1948}
1949
1950
1951/*
1952 * AtSubAbort_childXids
1953 */
1954static void
1956{
1958
1959 /*
1960 * We keep the child-XID arrays in TopTransactionContext (see
1961 * AtSubCommit_childXids). This means we'd better free the array
1962 * explicitly at abort to avoid leakage.
1963 */
1964 if (s->childXids != NULL)
1965 pfree(s->childXids);
1966 s->childXids = NULL;
1967 s->nChildXids = 0;
1968 s->maxChildXids = 0;
1969
1970 /*
1971 * We could prune the unreportedXids array here. But we don't bother. That
1972 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1973 * would likely introduce more CPU time into the more common paths, so we
1974 * choose not to do that.
1975 */
1976}
1977
1978/* ----------------------------------------------------------------
1979 * CleanupTransaction stuff
1980 * ----------------------------------------------------------------
1981 */
1982
1983/*
1984 * AtCleanup_Memory
1985 */
1986static void
1988{
1990
1991 /* Should be at top level */
1992 Assert(s->parent == NULL);
1993
1994 /*
1995 * Return to the memory context that was current before we started the
1996 * transaction. (In principle, this could not be any of the contexts we
1997 * are about to delete. If it somehow is, assertions in mcxt.c will
1998 * complain.)
1999 */
2001
2002 /*
2003 * Clear the special abort context for next time.
2004 */
2007
2008 /*
2009 * Release all transaction-local memory, the same as in AtCommit_Memory,
2010 * except we must cope with the possibility that we didn't get as far as
2011 * creating TopTransactionContext.
2012 */
2015
2016 /*
2017 * Clear these pointers as a pro-forma matter. (Notionally, while
2018 * TopTransactionContext still exists, it's currently not associated with
2019 * this TransactionState struct.)
2020 */
2023}
2024
2025
2026/* ----------------------------------------------------------------
2027 * CleanupSubTransaction stuff
2028 * ----------------------------------------------------------------
2029 */
2030
2031/*
2032 * AtSubCleanup_Memory
2033 */
2034static void
2036{
2038
2039 Assert(s->parent != NULL);
2040
2041 /*
2042 * Return to the memory context that was current before we started the
2043 * subtransaction. (In principle, this could not be any of the contexts
2044 * we are about to delete. If it somehow is, assertions in mcxt.c will
2045 * complain.)
2046 */
2048
2049 /* Update CurTransactionContext (might not be same as priorContext) */
2051
2052 /*
2053 * Clear the special abort context for next time.
2054 */
2057
2058 /*
2059 * Delete the subxact local memory contexts. Its CurTransactionContext can
2060 * go too (note this also kills CurTransactionContexts from any children
2061 * of the subxact).
2062 */
2063 if (s->curTransactionContext)
2066}
2067
2068/* ----------------------------------------------------------------
2069 * interface routines
2070 * ----------------------------------------------------------------
2071 */
2072
2073/*
2074 * StartTransaction
2075 */
2076static void
2078{
2081
2082 /*
2083 * Let's just make sure the state stack is empty
2084 */
2087
2089
2090 /* check the current transaction state */
2091 Assert(s->state == TRANS_DEFAULT);
2092
2093 /*
2094 * Set the current transaction state information appropriately during
2095 * start processing. Note that once the transaction status is switched
2096 * this process cannot fail until the user ID and the security context
2097 * flags are fetched below.
2098 */
2099 s->state = TRANS_START;
2100 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
2101
2102 /* Determine if statements are logged in this transaction */
2104 (log_xact_sample_rate == 1 ||
2106
2107 /*
2108 * initialize current transaction state fields
2109 *
2110 * note: prevXactReadOnly is not used at the outermost level
2111 */
2112 s->nestingLevel = 1;
2113 s->gucNestLevel = 1;
2114 s->childXids = NULL;
2115 s->nChildXids = 0;
2116 s->maxChildXids = 0;
2117
2118 /*
2119 * Once the current user ID and the security context flags are fetched,
2120 * both will be properly reset even if transaction startup fails.
2121 */
2123
2124 /* SecurityRestrictionContext should never be set outside a transaction */
2125 Assert(s->prevSecContext == 0);
2126
2127 /*
2128 * Make sure we've reset xact state variables
2129 *
2130 * If recovery is still in progress, mark this transaction as read-only.
2131 * We have lower level defences in XLogInsert and elsewhere to stop us
2132 * from modifying data during recovery, but this gives the normal
2133 * indication to the user that the transaction is read-only.
2134 */
2135 if (RecoveryInProgress())
2136 {
2137 s->startedInRecovery = true;
2138 XactReadOnly = true;
2139 }
2140 else
2141 {
2142 s->startedInRecovery = false;
2144 }
2147 forceSyncCommit = false;
2148 MyXactFlags = 0;
2149
2150 /*
2151 * reinitialize within-transaction counters
2152 */
2156 currentCommandIdUsed = false;
2157
2158 /*
2159 * initialize reported xid accounting
2160 */
2161 nUnreportedXids = 0;
2162 s->didLogXid = false;
2163
2164 /*
2165 * must initialize resource-management stuff first
2166 */
2169
2170 /*
2171 * Assign a new LocalTransactionId, and combine it with the proc number to
2172 * form a virtual transaction id.
2173 */
2174 vxid.procNumber = MyProcNumber;
2176
2177 /*
2178 * Lock the virtual transaction id before we announce it in the proc array
2179 */
2181
2182 /*
2183 * Advertise it in the proc array. We assume assignment of
2184 * localTransactionId is atomic, and the proc number should be set
2185 * already.
2186 */
2189
2191
2192 /*
2193 * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2194 * be the same as the first command's statement_timestamp(), so don't do a
2195 * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2196 * for transactions started inside procedures (i.e., nonatomic SPI
2197 * contexts), we do need to advance the timestamp. Also, in a parallel
2198 * worker, the timestamp should already have been provided by a call to
2199 * SetParallelStartTimestamps().
2200 */
2201 if (!IsParallelWorker())
2202 {
2205 else
2207 }
2208 else
2211 /* Mark xactStopTimestamp as unset. */
2213
2214 /*
2215 * initialize other subsystems for new transaction
2216 */
2217 AtStart_GUC();
2218 AtStart_Cache();
2220
2221 /*
2222 * done with start processing, set current transaction state to "in
2223 * progress"
2224 */
2226
2227 /* Schedule transaction timeout */
2228 if (TransactionTimeout > 0)
2230
2231 ShowTransactionState("StartTransaction");
2232}
2233
2234
2235/*
2236 * CommitTransaction
2237 *
2238 * NB: if you change this routine, better look at PrepareTransaction too!
2239 */
2240static void
2242{
2245 bool is_parallel_worker;
2246
2248
2249 /* Enforce parallel mode restrictions during parallel worker commit. */
2252
2253 ShowTransactionState("CommitTransaction");
2254
2255 /*
2256 * check the current transaction state
2257 */
2258 if (s->state != TRANS_INPROGRESS)
2259 elog(WARNING, "CommitTransaction while in %s state",
2261 Assert(s->parent == NULL);
2262
2263 /*
2264 * Do pre-commit processing that involves calling user-defined code, such
2265 * as triggers. SECURITY_RESTRICTED_OPERATION contexts must not queue an
2266 * action that would run here, because that would bypass the sandbox.
2267 * Since closing cursors could queue trigger actions, triggers could open
2268 * cursors, etc, we have to keep looping until there's nothing left to do.
2269 */
2270 for (;;)
2271 {
2272 /*
2273 * Fire all currently pending deferred triggers.
2274 */
2276
2277 /*
2278 * Close open portals (converting holdable ones into static portals).
2279 * If there weren't any, we are done ... otherwise loop back to check
2280 * if they queued deferred triggers. Lather, rinse, repeat.
2281 */
2282 if (!PreCommit_Portals(false))
2283 break;
2284 }
2285
2286 /*
2287 * The remaining actions cannot call any user-defined code, so it's safe
2288 * to start shutting down within-transaction services. But note that most
2289 * of this stuff could still throw an error, which would switch us into
2290 * the transaction-abort path.
2291 */
2292
2295
2296 /*
2297 * If this xact has started any unfinished parallel operation, clean up
2298 * its workers, warning about leaked resources. (But we don't actually
2299 * reset parallelModeLevel till entering TRANS_COMMIT, a bit below. This
2300 * keeps parallel mode restrictions active as long as possible in a
2301 * parallel worker.)
2302 */
2303 AtEOXact_Parallel(true);
2305 {
2306 if (s->parallelModeLevel != 1)
2307 elog(WARNING, "parallelModeLevel is %d not 1 at end of parallel worker transaction",
2309 }
2310 else
2311 {
2312 if (s->parallelModeLevel != 0)
2313 elog(WARNING, "parallelModeLevel is %d not 0 at end of transaction",
2315 }
2316
2317 /* Shut down the deferred-trigger manager */
2318 AfterTriggerEndXact(true);
2319
2320 /*
2321 * Let ON COMMIT management do its thing (must happen after closing
2322 * cursors, to avoid dangling-reference problems)
2323 */
2325
2326 /*
2327 * Synchronize files that are created and not WAL-logged during this
2328 * transaction. This must happen before AtEOXact_RelationMap(), so that we
2329 * don't see committed-but-broken files after a crash.
2330 */
2332
2333 /* close large objects before lower-level cleanup */
2335
2336 /*
2337 * Insert notifications sent by NOTIFY commands into the queue. This
2338 * should be late in the pre-commit sequence to minimize time spent
2339 * holding the notify-insertion lock. However, this could result in
2340 * creating a snapshot, so we must do it before serializable cleanup.
2341 */
2343
2344 /*
2345 * Mark serializable transaction as complete for predicate locking
2346 * purposes. This should be done as late as we can put it and still allow
2347 * errors to be raised for failure patterns found at commit. This is not
2348 * appropriate in a parallel worker however, because we aren't committing
2349 * the leader's transaction and its serializable state will live on.
2350 */
2351 if (!is_parallel_worker)
2353
2354 /* Prevent cancel/die interrupt while cleaning up */
2356
2357 /* Commit updates to the relation map --- do this as late as possible */
2359
2360 /*
2361 * set the current transaction state information appropriately during
2362 * commit processing
2363 */
2364 s->state = TRANS_COMMIT;
2365 s->parallelModeLevel = 0;
2366 s->parallelChildXact = false; /* should be false already */
2367
2368 /* Disable transaction timeout */
2369 if (TransactionTimeout > 0)
2371
2372 if (!is_parallel_worker)
2373 {
2374 /*
2375 * We need to mark our XIDs as committed in pg_xact. This is where we
2376 * durably commit.
2377 */
2379 }
2380 else
2381 {
2382 /*
2383 * We must not mark our XID committed; the parallel leader is
2384 * responsible for that.
2385 */
2387
2388 /*
2389 * Make sure the leader will know about any WAL we wrote before it
2390 * commits.
2391 */
2393 }
2394
2396
2397 /*
2398 * Let others know about no transaction in progress by me. Note that this
2399 * must be done _before_ releasing locks we hold and _after_
2400 * RecordTransactionCommit.
2401 */
2403
2404 /*
2405 * This is all post-commit cleanup. Note that if an error is raised here,
2406 * it's too late to abort the transaction. This should be just
2407 * noncritical resource releasing.
2408 *
2409 * The ordering of operations is not entirely random. The idea is:
2410 * release resources visible to other backends (eg, files, buffer pins);
2411 * then release locks; then release backend-local resources. We want to
2412 * release locks at the point where any backend waiting for us will see
2413 * our transaction as being fully cleaned up.
2414 *
2415 * Resources that can be associated with individual queries are handled by
2416 * the ResourceOwner mechanism. The other calls here are for backend-wide
2417 * state.
2418 */
2419
2422
2426 true, true);
2427
2428 AtEOXact_Aio(true);
2429
2430 /* Check we've released all buffer pins */
2431 AtEOXact_Buffers(true);
2432
2433 /* Clean up the relation cache */
2435
2436 /* Clean up the type cache */
2438
2439 /*
2440 * Make catalog changes visible to all backends. This has to happen after
2441 * relcache references are dropped (see comments for
2442 * AtEOXact_RelationCache), but before locks are released (if anyone is
2443 * waiting for lock on a relation we've modified, we want them to know
2444 * about the catalog change before they start using the relation).
2445 */
2446 AtEOXact_Inval(true);
2447
2449
2452 true, true);
2455 true, true);
2456
2457 /*
2458 * Likewise, dropping of files deleted during the transaction is best done
2459 * after releasing relcache and buffer pins. (This is not strictly
2460 * necessary during commit, since such pins should have been released
2461 * already, but this ordering is definitely critical during abort.) Since
2462 * this may take many seconds, also delay until after releasing locks.
2463 * Other backends will observe the attendant catalog changes and not
2464 * attempt to access affected files.
2465 */
2467
2468 /*
2469 * Send out notification signals to other backends (and do other
2470 * post-commit NOTIFY cleanup). This must not happen until after our
2471 * transaction is fully done from the viewpoint of other backends.
2472 */
2474
2475 /*
2476 * Everything after this should be purely internal-to-this-backend
2477 * cleanup.
2478 */
2479 AtEOXact_GUC(true, 1);
2480 AtEOXact_SPI(true);
2481 AtEOXact_Enum();
2484 AtEOXact_SMgr();
2485 AtEOXact_Files(true);
2487 AtEOXact_HashTables(true);
2489 AtEOXact_Snapshot(true, false);
2494
2499
2501
2504 s->nestingLevel = 0;
2505 s->gucNestLevel = 0;
2506 s->childXids = NULL;
2507 s->nChildXids = 0;
2508 s->maxChildXids = 0;
2509
2512
2513 /*
2514 * done with commit processing, set current transaction state back to
2515 * default
2516 */
2517 s->state = TRANS_DEFAULT;
2518
2520}
2521
2522
2523/*
2524 * PrepareTransaction
2525 *
2526 * NB: if you change this routine, better look at CommitTransaction too!
2527 */
2528static void
2530{
2534 TimestampTz prepared_at;
2535
2537
2538 ShowTransactionState("PrepareTransaction");
2539
2540 /*
2541 * check the current transaction state
2542 */
2543 if (s->state != TRANS_INPROGRESS)
2544 elog(WARNING, "PrepareTransaction while in %s state",
2546 Assert(s->parent == NULL);
2547
2548 /*
2549 * Do pre-commit processing that involves calling user-defined code, such
2550 * as triggers. Since closing cursors could queue trigger actions,
2551 * triggers could open cursors, etc, we have to keep looping until there's
2552 * nothing left to do.
2553 */
2554 for (;;)
2555 {
2556 /*
2557 * Fire all currently pending deferred triggers.
2558 */
2560
2561 /*
2562 * Close open portals (converting holdable ones into static portals).
2563 * If there weren't any, we are done ... otherwise loop back to check
2564 * if they queued deferred triggers. Lather, rinse, repeat.
2565 */
2566 if (!PreCommit_Portals(true))
2567 break;
2568 }
2569
2571
2572 /*
2573 * The remaining actions cannot call any user-defined code, so it's safe
2574 * to start shutting down within-transaction services. But note that most
2575 * of this stuff could still throw an error, which would switch us into
2576 * the transaction-abort path.
2577 */
2578
2579 /* Shut down the deferred-trigger manager */
2580 AfterTriggerEndXact(true);
2581
2582 /*
2583 * Let ON COMMIT management do its thing (must happen after closing
2584 * cursors, to avoid dangling-reference problems)
2585 */
2587
2588 /*
2589 * Synchronize files that are created and not WAL-logged during this
2590 * transaction. This must happen before EndPrepare(), so that we don't see
2591 * committed-but-broken files after a crash and COMMIT PREPARED.
2592 */
2593 smgrDoPendingSyncs(true, false);
2594
2595 /* close large objects before lower-level cleanup */
2597
2598 /* NOTIFY requires no work at this point */
2599
2600 /*
2601 * Mark serializable transaction as complete for predicate locking
2602 * purposes. This should be done as late as we can put it and still allow
2603 * errors to be raised for failure patterns found at commit.
2604 */
2606
2607 /*
2608 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2609 * this transaction. Having the prepared xact hold locks on another
2610 * backend's temp table seems a bad idea --- for instance it would prevent
2611 * the backend from exiting. There are other problems too, such as how to
2612 * clean up the source backend's local buffers and ON COMMIT state if the
2613 * prepared xact includes a DROP of a temp table.
2614 *
2615 * Other objects types, like functions, operators or extensions, share the
2616 * same restriction as they should not be created, locked or dropped as
2617 * this can mess up with this session or even a follow-up session trying
2618 * to use the same temporary namespace.
2619 *
2620 * We must check this after executing any ON COMMIT actions, because they
2621 * might still access a temp relation.
2622 *
2623 * XXX In principle this could be relaxed to allow some useful special
2624 * cases, such as a temp table created and dropped all within the
2625 * transaction. That seems to require much more bookkeeping though.
2626 */
2628 ereport(ERROR,
2630 errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2631
2632 /*
2633 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2634 * supported if we added cleanup logic to twophase.c, but for now it
2635 * doesn't seem worth the trouble.
2636 */
2638 ereport(ERROR,
2640 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2641
2642 /* Prevent cancel/die interrupt while cleaning up */
2644
2645 /*
2646 * set the current transaction state information appropriately during
2647 * prepare processing
2648 */
2649 s->state = TRANS_PREPARE;
2650
2651 /* Disable transaction timeout */
2652 if (TransactionTimeout > 0)
2654
2655 prepared_at = GetCurrentTimestamp();
2656
2657 /*
2658 * Reserve the GID for this transaction. This could fail if the requested
2659 * GID is invalid or already in use.
2660 */
2661 gxact = MarkAsPreparing(fxid, prepareGID, prepared_at,
2663 prepareGID = NULL;
2664
2665 /*
2666 * Collect data for the 2PC state file. Note that in general, no actual
2667 * state change should happen in the called modules during this step,
2668 * since it's still possible to fail before commit, and in that case we
2669 * want transaction abort to be able to clean up. (In particular, the
2670 * AtPrepare routines may error out if they find cases they cannot
2671 * handle.) State cleanup should happen in the PostPrepare routines
2672 * below. However, some modules can go ahead and clear state here because
2673 * they wouldn't do anything with it during abort anyway.
2674 *
2675 * Note: because the 2PC state file records will be replayed in the same
2676 * order they are made, the order of these calls has to match the order in
2677 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2678 * PREPARED; in particular, pay attention to whether things should happen
2679 * before or after releasing the transaction's locks.
2680 */
2682
2689
2690 /*
2691 * Here is where we really truly prepare.
2692 *
2693 * We have to record transaction prepares even if we didn't make any
2694 * updates, because the transaction manager might get confused if we lose
2695 * a global transaction.
2696 */
2698
2699 /*
2700 * Now we clean up backend-internal state and release internal resources.
2701 */
2702
2703 /* Reset XactLastRecEnd until the next transaction writes something */
2704 XactLastRecEnd = 0;
2705
2706 /*
2707 * Transfer our locks to a dummy PGPROC. This has to be done before
2708 * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2709 * conclude "xact already committed or aborted" for our locks.
2710 */
2711 PostPrepare_Locks(fxid);
2712
2713 /*
2714 * Let others know about no transaction in progress by me. This has to be
2715 * done *after* the prepared transaction has been marked valid, else
2716 * someone may think it is unlocked and recyclable.
2717 */
2719
2720 /*
2721 * In normal commit-processing, this is all non-critical post-transaction
2722 * cleanup. When the transaction is prepared, however, it's important
2723 * that the locks and other per-backend resources are transferred to the
2724 * prepared transaction's PGPROC entry. Note that if an error is raised
2725 * here, it's too late to abort the transaction. XXX: This probably should
2726 * be in a critical section, to force a PANIC if any of this fails, but
2727 * that cure could be worse than the disease.
2728 */
2729
2731
2734 true, true);
2735
2736 AtEOXact_Aio(true);
2737
2738 /* Check we've released all buffer pins */
2739 AtEOXact_Buffers(true);
2740
2741 /* Clean up the relation cache */
2743
2744 /* Clean up the type cache */
2746
2747 /* notify doesn't need a postprepare call */
2748
2750
2752
2754
2756
2758
2761 true, true);
2764 true, true);
2765
2766 /*
2767 * Allow another backend to finish the transaction. After
2768 * PostPrepare_Twophase(), the transaction is completely detached from our
2769 * backend. The rest is just non-critical cleanup of backend-local state.
2770 */
2772
2773 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2774 AtEOXact_GUC(true, 1);
2775 AtEOXact_SPI(true);
2776 AtEOXact_Enum();
2778 AtEOXact_Namespace(true, false);
2779 AtEOXact_SMgr();
2780 AtEOXact_Files(true);
2782 AtEOXact_HashTables(true);
2783 /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2784 AtEOXact_Snapshot(true, true);
2785 /* we treat PREPARE as ROLLBACK so far as waking workers goes */
2790
2796
2798
2801 s->nestingLevel = 0;
2802 s->gucNestLevel = 0;
2803 s->childXids = NULL;
2804 s->nChildXids = 0;
2805 s->maxChildXids = 0;
2806
2809
2810 /*
2811 * done with 1st phase commit processing, set current transaction state
2812 * back to default
2813 */
2814 s->state = TRANS_DEFAULT;
2815
2817}
2818
2819
2820/*
2821 * AbortTransaction
2822 */
2823static void
2825{
2828 bool is_parallel_worker;
2829
2830 /* Prevent cancel/die interrupt while cleaning up */
2832
2833 /* Disable transaction timeout */
2834 if (TransactionTimeout > 0)
2836
2837 /* Make sure we have a valid memory context and resource owner */
2840
2841 /*
2842 * Release any LW locks we might be holding as quickly as possible.
2843 * (Regular locks, however, must be held till we finish aborting.)
2844 * Releasing LW locks is critical since we might try to grab them again
2845 * while cleaning up!
2846 */
2848
2849 /*
2850 * Cleanup waiting for LSN if any.
2851 */
2853
2854 /* Clear wait information and command progress indicator */
2857
2859
2860 /* Clean up buffer content locks, too */
2861 UnlockBuffers();
2862
2863 /* Reset WAL record construction state */
2865
2866 /* Cancel condition variable sleep */
2868
2869 /*
2870 * Also clean up any open wait for lock, since the lock manager will choke
2871 * if we try to wait for another lock before doing this.
2872 */
2874
2875 /*
2876 * If any timeout events are still active, make sure the timeout interrupt
2877 * is scheduled. This covers possible loss of a timeout interrupt due to
2878 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2879 * We delay this till after LockErrorCleanup so that we don't uselessly
2880 * reschedule lock or deadlock check timeouts.
2881 */
2883
2884 /*
2885 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2886 * handler. We do this fairly early in the sequence so that the timeout
2887 * infrastructure will be functional if needed while aborting.
2888 */
2890
2891 /*
2892 * check the current transaction state
2893 */
2895 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2896 elog(WARNING, "AbortTransaction while in %s state",
2898 Assert(s->parent == NULL);
2899
2900 /*
2901 * set the current transaction state information appropriately during the
2902 * abort processing
2903 */
2904 s->state = TRANS_ABORT;
2905
2906 /*
2907 * Reset user ID which might have been changed transiently. We need this
2908 * to clean up in case control escaped out of a SECURITY DEFINER function
2909 * or other local change of CurrentUserId; therefore, the prior value of
2910 * SecurityRestrictionContext also needs to be restored.
2911 *
2912 * (Note: it is not necessary to restore session authorization or role
2913 * settings here because those can only be changed via GUC, and GUC will
2914 * take care of rolling them back if need be.)
2915 */
2917
2918 /* Forget about any active REINDEX. */
2920
2921 /* Reset logical streaming state. */
2923
2924 /* Reset snapshot export state. */
2926
2927 /*
2928 * If this xact has started any unfinished parallel operation, clean up
2929 * its workers and exit parallel mode. Don't warn about leaked resources.
2930 */
2931 AtEOXact_Parallel(false);
2932 s->parallelModeLevel = 0;
2933 s->parallelChildXact = false; /* should be false already */
2934
2935 /*
2936 * do abort processing
2937 */
2938 AfterTriggerEndXact(false); /* 'false' means it's abort */
2941 AtEOXact_LargeObject(false);
2945
2946 /*
2947 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2948 * far as assigning an XID to advertise). But if we're inside a parallel
2949 * worker, skip this; the user backend must be the one to write the abort
2950 * record.
2951 */
2952 if (!is_parallel_worker)
2954 else
2955 {
2957
2958 /*
2959 * Since the parallel leader won't get our value of XactLastRecEnd in
2960 * this case, we nudge WAL-writer ourselves in this case. See related
2961 * comments in RecordTransactionAbort for why this matters.
2962 */
2964 }
2965
2967
2968 /*
2969 * Let others know about no transaction in progress by me. Note that this
2970 * must be done _before_ releasing locks we hold and _after_
2971 * RecordTransactionAbort.
2972 */
2974
2975 /*
2976 * Post-abort cleanup. See notes in CommitTransaction() concerning
2977 * ordering. We can skip all of it if the transaction failed before
2978 * creating a resource owner.
2979 */
2981 {
2984 else
2986
2989 false, true);
2990 AtEOXact_Aio(false);
2991 AtEOXact_Buffers(false);
2994 AtEOXact_Inval(false);
2998 false, true);
3001 false, true);
3002 smgrDoPendingDeletes(false);
3003
3004 AtEOXact_GUC(false, 1);
3005 AtEOXact_SPI(false);
3006 AtEOXact_Enum();
3009 AtEOXact_SMgr();
3010 AtEOXact_Files(false);
3012 AtEOXact_HashTables(false);
3018 }
3019
3020 /*
3021 * State remains TRANS_ABORT until CleanupTransaction().
3022 */
3024}
3025
3026/*
3027 * CleanupTransaction
3028 */
3029static void
3031{
3033
3034 /*
3035 * State should still be TRANS_ABORT from AbortTransaction().
3036 */
3037 if (s->state != TRANS_ABORT)
3038 elog(FATAL, "CleanupTransaction: unexpected state %s",
3040
3041 /*
3042 * do abort cleanup processing
3043 */
3044 AtCleanup_Portals(); /* now safe to release portal memory */
3045 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
3046
3047 CurrentResourceOwner = NULL; /* and resource owner */
3053
3054 AtCleanup_Memory(); /* and transaction memory */
3055
3058 s->nestingLevel = 0;
3059 s->gucNestLevel = 0;
3060 s->childXids = NULL;
3061 s->nChildXids = 0;
3062 s->maxChildXids = 0;
3063 s->parallelModeLevel = 0;
3064 s->parallelChildXact = false;
3065
3068
3069 /*
3070 * done with abort processing, set current transaction state back to
3071 * default
3072 */
3073 s->state = TRANS_DEFAULT;
3074}
3075
3076/*
3077 * StartTransactionCommand
3078 */
3079void
3081{
3083
3084 switch (s->blockState)
3085 {
3086 /*
3087 * if we aren't in a transaction block, we just do our usual start
3088 * transaction.
3089 */
3090 case TBLOCK_DEFAULT:
3093 break;
3094
3095 /*
3096 * We are somewhere in a transaction block or subtransaction and
3097 * about to start a new command. For now we do nothing, but
3098 * someday we may do command-local resource initialization. (Note
3099 * that any needed CommandCounterIncrement was done by the
3100 * previous CommitTransactionCommand.)
3101 */
3102 case TBLOCK_INPROGRESS:
3105 break;
3106
3107 /*
3108 * Here we are in a failed transaction block (one of the commands
3109 * caused an abort) so we do nothing but remain in the abort
3110 * state. Eventually we will get a ROLLBACK command which will
3111 * get us out of this state. (It is up to other code to ensure
3112 * that no commands other than ROLLBACK will be processed in these
3113 * states.)
3114 */
3115 case TBLOCK_ABORT:
3116 case TBLOCK_SUBABORT:
3117 break;
3118
3119 /* These cases are invalid. */
3120 case TBLOCK_STARTED:
3121 case TBLOCK_BEGIN:
3123 case TBLOCK_SUBBEGIN:
3124 case TBLOCK_END:
3125 case TBLOCK_SUBRELEASE:
3126 case TBLOCK_SUBCOMMIT:
3127 case TBLOCK_ABORT_END:
3131 case TBLOCK_SUBRESTART:
3133 case TBLOCK_PREPARE:
3134 elog(ERROR, "StartTransactionCommand: unexpected state %s",
3136 break;
3137 }
3138
3139 /*
3140 * We must switch to CurTransactionContext before returning. This is
3141 * already done if we called StartTransaction, otherwise not.
3142 */
3145}
3146
3147
3148/*
3149 * Simple system for saving and restoring transaction characteristics
3150 * (isolation level, read only, deferrable). We need this for transaction
3151 * chaining, so that we can set the characteristics of the new transaction to
3152 * be the same as the previous one. (We need something like this because the
3153 * GUC system resets the characteristics at transaction end, so for example
3154 * just skipping the reset in StartTransaction() won't work.)
3155 */
3156void
3163
3164void
3171
3172/*
3173 * CommitTransactionCommand -- a wrapper function handling the
3174 * loop over subtransactions to avoid a potentially dangerous recursion
3175 * in CommitTransactionCommandInternal().
3176 */
3177void
3179{
3180 /*
3181 * Repeatedly call CommitTransactionCommandInternal() until all the work
3182 * is done.
3183 */
3185 {
3186 }
3187}
3188
3189/*
3190 * CommitTransactionCommandInternal - a function doing an iteration of work
3191 * regarding handling the commit transaction command. In the case of
3192 * subtransactions more than one iterations could be required. Returns
3193 * true when no more iterations required, false otherwise.
3194 */
3195static bool
3197{
3200
3201 /* Must save in case we need to restore below */
3203
3204 switch (s->blockState)
3205 {
3206 /*
3207 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3208 * StartTransactionCommand didn't set the STARTED state
3209 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3210 * by EndParallelWorkerTransaction(), not this function.
3211 */
3212 case TBLOCK_DEFAULT:
3214 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3216 break;
3217
3218 /*
3219 * If we aren't in a transaction block, just do our usual
3220 * transaction commit, and return to the idle state.
3221 */
3222 case TBLOCK_STARTED:
3225 break;
3226
3227 /*
3228 * We are completing a "BEGIN TRANSACTION" command, so we change
3229 * to the "transaction block in progress" state and return. (We
3230 * assume the BEGIN did nothing to the database, so we need no
3231 * CommandCounterIncrement.)
3232 */
3233 case TBLOCK_BEGIN:
3235 break;
3236
3237 /*
3238 * This is the case when we have finished executing a command
3239 * someplace within a transaction block. We increment the command
3240 * counter and return.
3241 */
3242 case TBLOCK_INPROGRESS:
3246 break;
3247
3248 /*
3249 * We are completing a "COMMIT" command. Do it and return to the
3250 * idle state.
3251 */
3252 case TBLOCK_END:
3255 if (s->chain)
3256 {
3259 s->chain = false;
3261 }
3262 break;
3263
3264 /*
3265 * Here we are in the middle of a transaction block but one of the
3266 * commands caused an abort so we do nothing but remain in the
3267 * abort state. Eventually we will get a ROLLBACK command.
3268 */
3269 case TBLOCK_ABORT:
3270 case TBLOCK_SUBABORT:
3271 break;
3272
3273 /*
3274 * Here we were in an aborted transaction block and we just got
3275 * the ROLLBACK command from the user, so clean up the
3276 * already-aborted transaction and return to the idle state.
3277 */
3278 case TBLOCK_ABORT_END:
3281 if (s->chain)
3282 {
3285 s->chain = false;
3287 }
3288 break;
3289
3290 /*
3291 * Here we were in a perfectly good transaction block but the user
3292 * told us to ROLLBACK anyway. We have to abort the transaction
3293 * and then clean up.
3294 */
3299 if (s->chain)
3300 {
3303 s->chain = false;
3305 }
3306 break;
3307
3308 /*
3309 * We are completing a "PREPARE TRANSACTION" command. Do it and
3310 * return to the idle state.
3311 */
3312 case TBLOCK_PREPARE:
3315 break;
3316
3317 /*
3318 * The user issued a SAVEPOINT inside a transaction block. Start a
3319 * subtransaction. (DefineSavepoint already did PushTransaction,
3320 * so as to have someplace to put the SUBBEGIN state.)
3321 */
3322 case TBLOCK_SUBBEGIN:
3325 break;
3326
3327 /*
3328 * The user issued a RELEASE command, so we end the current
3329 * subtransaction and return to the parent transaction. The parent
3330 * might be ended too, so repeat till we find an INPROGRESS
3331 * transaction or subtransaction.
3332 */
3333 case TBLOCK_SUBRELEASE:
3334 do
3335 {
3337 s = CurrentTransactionState; /* changed by pop */
3338 } while (s->blockState == TBLOCK_SUBRELEASE);
3339
3342 break;
3343
3344 /*
3345 * The user issued a COMMIT, so we end the current subtransaction
3346 * hierarchy and perform final commit. We do this by rolling up
3347 * any subtransactions into their parent, which leads to O(N^2)
3348 * operations with respect to resource owners - this isn't that
3349 * bad until we approach a thousands of savepoints but is
3350 * necessary for correctness should after triggers create new
3351 * resource owners.
3352 */
3353 case TBLOCK_SUBCOMMIT:
3354 do
3355 {
3357 s = CurrentTransactionState; /* changed by pop */
3358 } while (s->blockState == TBLOCK_SUBCOMMIT);
3359 /* If we had a COMMIT command, finish off the main xact too */
3360 if (s->blockState == TBLOCK_END)
3361 {
3362 Assert(s->parent == NULL);
3365 if (s->chain)
3366 {
3369 s->chain = false;
3371 }
3372 }
3373 else if (s->blockState == TBLOCK_PREPARE)
3374 {
3375 Assert(s->parent == NULL);
3378 }
3379 else
3380 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3382 break;
3383
3384 /*
3385 * The current already-failed subtransaction is ending due to a
3386 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3387 * examine the parent (which could be in any of several states).
3388 * As we need to examine the parent, return false to request the
3389 * caller to do the next iteration.
3390 */
3393 return false;
3394
3395 /*
3396 * As above, but it's not dead yet, so abort first.
3397 */
3401 return false;
3402
3403 /*
3404 * The current subtransaction is the target of a ROLLBACK TO
3405 * command. Abort and pop it, then start a new subtransaction
3406 * with the same name.
3407 */
3408 case TBLOCK_SUBRESTART:
3409 {
3410 char *name;
3411 int savepointLevel;
3412
3413 /* save name and keep Cleanup from freeing it */
3414 name = s->name;
3415 s->name = NULL;
3416 savepointLevel = s->savepointLevel;
3417
3420
3422 s = CurrentTransactionState; /* changed by push */
3423 s->name = name;
3424 s->savepointLevel = savepointLevel;
3425
3426 /* This is the same as TBLOCK_SUBBEGIN case */
3430 }
3431 break;
3432
3433 /*
3434 * Same as above, but the subtransaction had already failed, so we
3435 * don't need AbortSubTransaction.
3436 */
3438 {
3439 char *name;
3440 int savepointLevel;
3441
3442 /* save name and keep Cleanup from freeing it */
3443 name = s->name;
3444 s->name = NULL;
3445 savepointLevel = s->savepointLevel;
3446
3448
3450 s = CurrentTransactionState; /* changed by push */
3451 s->name = name;
3452 s->savepointLevel = savepointLevel;
3453
3454 /* This is the same as TBLOCK_SUBBEGIN case */
3458 }
3459 break;
3460 }
3461
3462 /* Done, no more iterations required */
3463 return true;
3464}
3465
3466/*
3467 * AbortCurrentTransaction -- a wrapper function handling the
3468 * loop over subtransactions to avoid potentially dangerous recursion in
3469 * AbortCurrentTransactionInternal().
3470 */
3471void
3473{
3474 /*
3475 * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3476 * done.
3477 */
3479 {
3480 }
3481}
3482
3483/*
3484 * AbortCurrentTransactionInternal - a function doing an iteration of work
3485 * regarding handling the current transaction abort. In the case of
3486 * subtransactions more than one iterations could be required. Returns
3487 * true when no more iterations required, false otherwise.
3488 */
3489static bool
3491{
3493
3494 switch (s->blockState)
3495 {
3496 case TBLOCK_DEFAULT:
3497 if (s->state == TRANS_DEFAULT)
3498 {
3499 /* we are idle, so nothing to do */
3500 }
3501 else
3502 {
3503 /*
3504 * We can get here after an error during transaction start
3505 * (state will be TRANS_START). Need to clean up the
3506 * incompletely started transaction. First, adjust the
3507 * low-level state to suppress warning message from
3508 * AbortTransaction.
3509 */
3510 if (s->state == TRANS_START)
3514 }
3515 break;
3516
3517 /*
3518 * If we aren't in a transaction block, we just do the basic abort
3519 * & cleanup transaction. For this purpose, we treat an implicit
3520 * transaction block as if it were a simple statement.
3521 */
3522 case TBLOCK_STARTED:
3527 break;
3528
3529 /*
3530 * If we are in TBLOCK_BEGIN it means something screwed up right
3531 * after reading "BEGIN TRANSACTION". We assume that the user
3532 * will interpret the error as meaning the BEGIN failed to get him
3533 * into a transaction block, so we should abort and return to idle
3534 * state.
3535 */
3536 case TBLOCK_BEGIN:
3540 break;
3541
3542 /*
3543 * We are somewhere in a transaction block and we've gotten a
3544 * failure, so we abort the transaction and set up the persistent
3545 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3546 */
3547 case TBLOCK_INPROGRESS:
3551 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3552 break;
3553
3554 /*
3555 * Here, we failed while trying to COMMIT. Clean up the
3556 * transaction and return to idle state (we do not want to stay in
3557 * the transaction).
3558 */
3559 case TBLOCK_END:
3563 break;
3564
3565 /*
3566 * Here, we are already in an aborted transaction state and are
3567 * waiting for a ROLLBACK, but for some reason we failed again! So
3568 * we just remain in the abort state.
3569 */
3570 case TBLOCK_ABORT:
3571 case TBLOCK_SUBABORT:
3572 break;
3573
3574 /*
3575 * We are in a failed transaction and we got the ROLLBACK command.
3576 * We have already aborted, we just need to cleanup and go to idle
3577 * state.
3578 */
3579 case TBLOCK_ABORT_END:
3582 break;
3583
3584 /*
3585 * We are in a live transaction and we got a ROLLBACK command.
3586 * Abort, cleanup, go to idle state.
3587 */
3592 break;
3593
3594 /*
3595 * Here, we failed while trying to PREPARE. Clean up the
3596 * transaction and return to idle state (we do not want to stay in
3597 * the transaction).
3598 */
3599 case TBLOCK_PREPARE:
3603 break;
3604
3605 /*
3606 * We got an error inside a subtransaction. Abort just the
3607 * subtransaction, and go to the persistent SUBABORT state until
3608 * we get ROLLBACK.
3609 */
3613 break;
3614
3615 /*
3616 * If we failed while trying to create a subtransaction, clean up
3617 * the broken subtransaction and abort the parent. The same
3618 * applies if we get a failure while ending a subtransaction. As
3619 * we need to abort the parent, return false to request the caller
3620 * to do the next iteration.
3621 */
3622 case TBLOCK_SUBBEGIN:
3623 case TBLOCK_SUBRELEASE:
3624 case TBLOCK_SUBCOMMIT:
3626 case TBLOCK_SUBRESTART:
3629 return false;
3630
3631 /*
3632 * Same as above, except the Abort() was already done.
3633 */
3637 return false;
3638 }
3639
3640 /* Done, no more iterations required */
3641 return true;
3642}
3643
3644/*
3645 * PreventInTransactionBlock
3646 *
3647 * This routine is to be called by statements that must not run inside
3648 * a transaction block, typically because they have non-rollback-able
3649 * side effects or do internal commits.
3650 *
3651 * If this routine completes successfully, then the calling statement is
3652 * guaranteed that if it completes without error, its results will be
3653 * committed immediately.
3654 *
3655 * If we have already started a transaction block, issue an error; also issue
3656 * an error if we appear to be running inside a user-defined function (which
3657 * could issue more commands and possibly cause a failure after the statement
3658 * completes). Subtransactions are verboten too.
3659 *
3660 * We must also set XACT_FLAGS_NEEDIMMEDIATECOMMIT in MyXactFlags, to ensure
3661 * that postgres.c follows through by committing after the statement is done.
3662 *
3663 * isTopLevel: passed down from ProcessUtility to determine whether we are
3664 * inside a function. (We will always fail if this is false, but it's
3665 * convenient to centralize the check here instead of making callers do it.)
3666 * stmtType: statement type name, for error messages.
3667 */
3668void
3669PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
3670{
3671 /*
3672 * xact block already started?
3673 */
3674 if (IsTransactionBlock())
3675 ereport(ERROR,
3677 /* translator: %s represents an SQL statement name */
3678 errmsg("%s cannot run inside a transaction block",
3679 stmtType)));
3680
3681 /*
3682 * subtransaction?
3683 */
3684 if (IsSubTransaction())
3685 ereport(ERROR,
3687 /* translator: %s represents an SQL statement name */
3688 errmsg("%s cannot run inside a subtransaction",
3689 stmtType)));
3690
3691 /*
3692 * inside a function call?
3693 */
3694 if (!isTopLevel)
3695 ereport(ERROR,
3697 /* translator: %s represents an SQL statement name */
3698 errmsg("%s cannot be executed from a function or procedure",
3699 stmtType)));
3700
3701 /* If we got past IsTransactionBlock test, should be in default state */
3704 elog(FATAL, "cannot prevent transaction chain");
3705
3706 /* All okay. Set the flag to make sure the right thing happens later. */
3708}
3709
3710/*
3711 * WarnNoTransactionBlock
3712 * RequireTransactionBlock
3713 *
3714 * These two functions allow for warnings or errors if a command is executed
3715 * outside of a transaction block. This is useful for commands that have no
3716 * effects that persist past transaction end (and so calling them outside a
3717 * transaction block is presumably an error). DECLARE CURSOR is an example.
3718 * While top-level transaction control commands (BEGIN/COMMIT/ABORT) and SET
3719 * that have no effect issue warnings, all other no-effect commands generate
3720 * errors.
3721 *
3722 * If we appear to be running inside a user-defined function, we do not
3723 * issue anything, since the function could issue more commands that make
3724 * use of the current statement's results. Likewise subtransactions.
3725 * Thus these are inverses for PreventInTransactionBlock.
3726 *
3727 * isTopLevel: passed down from ProcessUtility to determine whether we are
3728 * inside a function.
3729 * stmtType: statement type name, for warning or error messages.
3730 */
3731void
3732WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
3733{
3734 CheckTransactionBlock(isTopLevel, false, stmtType);
3735}
3736
3737void
3738RequireTransactionBlock(bool isTopLevel, const char *stmtType)
3739{
3740 CheckTransactionBlock(isTopLevel, true, stmtType);
3741}
3742
3743/*
3744 * This is the implementation of the above two.
3745 */
3746static void
3747CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
3748{
3749 /*
3750 * xact block already started?
3751 */
3752 if (IsTransactionBlock())
3753 return;
3754
3755 /*
3756 * subtransaction?
3757 */
3758 if (IsSubTransaction())
3759 return;
3760
3761 /*
3762 * inside a function call?
3763 */
3764 if (!isTopLevel)
3765 return;
3766
3769 /* translator: %s represents an SQL statement name */
3770 errmsg("%s can only be used in transaction blocks",
3771 stmtType)));
3772}
3773
3774/*
3775 * IsInTransactionBlock
3776 *
3777 * This routine is for statements that need to behave differently inside
3778 * a transaction block than when running as single commands. ANALYZE is
3779 * currently the only example.
3780 *
3781 * If this routine returns "false", then the calling statement is allowed
3782 * to perform internal transaction-commit-and-start cycles; there is not a
3783 * risk of messing up any transaction already in progress. (Note that this
3784 * is not the identical guarantee provided by PreventInTransactionBlock,
3785 * since we will not force a post-statement commit.)
3786 *
3787 * isTopLevel: passed down from ProcessUtility to determine whether we are
3788 * inside a function.
3789 */
3790bool
3792{
3793 /*
3794 * Return true on same conditions that would make
3795 * PreventInTransactionBlock error out
3796 */
3797 if (IsTransactionBlock())
3798 return true;
3799
3800 if (IsSubTransaction())
3801 return true;
3802
3803 if (!isTopLevel)
3804 return true;
3805
3808 return true;
3809
3810 return false;
3811}
3812
3813
3814/*
3815 * Register or deregister callback functions for start- and end-of-xact
3816 * operations.
3817 *
3818 * These functions are intended for use by dynamically loaded modules.
3819 * For built-in modules we generally just hardwire the appropriate calls
3820 * (mainly because it's easier to control the order that way, where needed).
3821 *
3822 * At transaction end, the callback occurs post-commit or post-abort, so the
3823 * callback functions can only do noncritical cleanup.
3824 */
3825void
3827{
3828 XactCallbackItem *item;
3829
3830 item = (XactCallbackItem *)
3832 item->callback = callback;
3833 item->arg = arg;
3834 item->next = Xact_callbacks;
3835 Xact_callbacks = item;
3836}
3837
3838void
3840{
3841 XactCallbackItem *item;
3842 XactCallbackItem *prev;
3843
3844 prev = NULL;
3845 for (item = Xact_callbacks; item; prev = item, item = item->next)
3846 {
3847 if (item->callback == callback && item->arg == arg)
3848 {
3849 if (prev)
3850 prev->next = item->next;
3851 else
3852 Xact_callbacks = item->next;
3853 pfree(item);
3854 break;
3855 }
3856 }
3857}
3858
3859static void
3861{
3862 XactCallbackItem *item;
3864
3865 for (item = Xact_callbacks; item; item = next)
3866 {
3867 /* allow callbacks to unregister themselves when called */
3868 next = item->next;
3869 item->callback(event, item->arg);
3870 }
3871}
3872
3873
3874/*
3875 * Register or deregister callback functions for start- and end-of-subxact
3876 * operations.
3877 *
3878 * Pretty much same as above, but for subtransaction events.
3879 *
3880 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3881 * so the callback functions can only do noncritical cleanup. At
3882 * subtransaction start, the callback is called when the subtransaction has
3883 * finished initializing.
3884 */
3885void
3887{
3888 SubXactCallbackItem *item;
3889
3890 item = (SubXactCallbackItem *)
3892 item->callback = callback;
3893 item->arg = arg;
3894 item->next = SubXact_callbacks;
3895 SubXact_callbacks = item;
3896}
3897
3898void
3900{
3901 SubXactCallbackItem *item;
3902 SubXactCallbackItem *prev;
3903
3904 prev = NULL;
3905 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3906 {
3907 if (item->callback == callback && item->arg == arg)
3908 {
3909 if (prev)
3910 prev->next = item->next;
3911 else
3912 SubXact_callbacks = item->next;
3913 pfree(item);
3914 break;
3915 }
3916 }
3917}
3918
3919static void
3923{
3924 SubXactCallbackItem *item;
3926
3927 for (item = SubXact_callbacks; item; item = next)
3928 {
3929 /* allow callbacks to unregister themselves when called */
3930 next = item->next;
3931 item->callback(event, mySubid, parentSubid, item->arg);
3932 }
3933}
3934
3935
3936/* ----------------------------------------------------------------
3937 * transaction block support
3938 * ----------------------------------------------------------------
3939 */
3940
3941/*
3942 * BeginTransactionBlock
3943 * This executes a BEGIN command.
3944 */
3945void
3947{
3949
3950 switch (s->blockState)
3951 {
3952 /*
3953 * We are not inside a transaction block, so allow one to begin.
3954 */
3955 case TBLOCK_STARTED:
3957 break;
3958
3959 /*
3960 * BEGIN converts an implicit transaction block to a regular one.
3961 * (Note that we allow this even if we've already done some
3962 * commands, which is a bit odd but matches historical practice.)
3963 */
3966 break;
3967
3968 /*
3969 * Already a transaction block in progress.
3970 */
3971 case TBLOCK_INPROGRESS:
3974 case TBLOCK_ABORT:
3975 case TBLOCK_SUBABORT:
3978 errmsg("there is already a transaction in progress")));
3979 break;
3980
3981 /* These cases are invalid. */
3982 case TBLOCK_DEFAULT:
3983 case TBLOCK_BEGIN:
3984 case TBLOCK_SUBBEGIN:
3985 case TBLOCK_END:
3986 case TBLOCK_SUBRELEASE:
3987 case TBLOCK_SUBCOMMIT:
3988 case TBLOCK_ABORT_END:
3992 case TBLOCK_SUBRESTART:
3994 case TBLOCK_PREPARE:
3995 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3997 break;
3998 }
3999}
4000
4001/*
4002 * PrepareTransactionBlock
4003 * This executes a PREPARE command.
4004 *
4005 * Since PREPARE may actually do a ROLLBACK, the result indicates what
4006 * happened: true for PREPARE, false for ROLLBACK.
4007 *
4008 * Note that we don't actually do anything here except change blockState.
4009 * The real work will be done in the upcoming PrepareTransaction().
4010 * We do it this way because it's not convenient to change memory context,
4011 * resource owner, etc while executing inside a Portal.
4012 */
4013bool
4015{
4017 bool result;
4018
4019 /* Set up to commit the current transaction */
4020 result = EndTransactionBlock(false);
4021
4022 /* If successful, change outer tblock state to PREPARE */
4023 if (result)
4024 {
4026
4027 while (s->parent != NULL)
4028 s = s->parent;
4029
4030 if (s->blockState == TBLOCK_END)
4031 {
4032 /* Save GID where PrepareTransaction can find it again */
4034
4036 }
4037 else
4038 {
4039 /*
4040 * ignore case where we are not in a transaction;
4041 * EndTransactionBlock already issued a warning.
4042 */
4045 /* Don't send back a PREPARE result tag... */
4046 result = false;
4047 }
4048 }
4049
4050 return result;
4051}
4052
4053/*
4054 * EndTransactionBlock
4055 * This executes a COMMIT command.
4056 *
4057 * Since COMMIT may actually do a ROLLBACK, the result indicates what
4058 * happened: true for COMMIT, false for ROLLBACK.
4059 *
4060 * Note that we don't actually do anything here except change blockState.
4061 * The real work will be done in the upcoming CommitTransactionCommand().
4062 * We do it this way because it's not convenient to change memory context,
4063 * resource owner, etc while executing inside a Portal.
4064 */
4065bool
4067{
4069 bool result = false;
4070
4071 switch (s->blockState)
4072 {
4073 /*
4074 * We are in a transaction block, so tell CommitTransactionCommand
4075 * to COMMIT.
4076 */
4077 case TBLOCK_INPROGRESS:
4079 result = true;
4080 break;
4081
4082 /*
4083 * We are in an implicit transaction block. If AND CHAIN was
4084 * specified, error. Otherwise commit, but issue a warning
4085 * because there was no explicit BEGIN before this.
4086 */
4088 if (chain)
4089 ereport(ERROR,
4091 /* translator: %s represents an SQL statement name */
4092 errmsg("%s can only be used in transaction blocks",
4093 "COMMIT AND CHAIN")));
4094 else
4097 errmsg("there is no transaction in progress")));
4099 result = true;
4100 break;
4101
4102 /*
4103 * We are in a failed transaction block. Tell
4104 * CommitTransactionCommand it's time to exit the block.
4105 */
4106 case TBLOCK_ABORT:
4108 break;
4109
4110 /*
4111 * We are in a live subtransaction block. Set up to subcommit all
4112 * open subtransactions and then commit the main transaction.
4113 */
4115 while (s->parent != NULL)
4116 {
4119 else
4120 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4122 s = s->parent;
4123 }
4124 if (s->blockState == TBLOCK_INPROGRESS)
4126 else
4127 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4129 result = true;
4130 break;
4131
4132 /*
4133 * Here we are inside an aborted subtransaction. Treat the COMMIT
4134 * as ROLLBACK: set up to abort everything and exit the main
4135 * transaction.
4136 */
4137 case TBLOCK_SUBABORT:
4138 while (s->parent != NULL)
4139 {
4142 else if (s->blockState == TBLOCK_SUBABORT)
4144 else
4145 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4147 s = s->parent;
4148 }
4149 if (s->blockState == TBLOCK_INPROGRESS)
4151 else if (s->blockState == TBLOCK_ABORT)
4153 else
4154 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4156 break;
4157
4158 /*
4159 * The user issued COMMIT when not inside a transaction. For
4160 * COMMIT without CHAIN, issue a WARNING, staying in
4161 * TBLOCK_STARTED state. The upcoming call to
4162 * CommitTransactionCommand() will then close the transaction and
4163 * put us back into the default state. For COMMIT AND CHAIN,
4164 * error.
4165 */
4166 case TBLOCK_STARTED:
4167 if (chain)
4168 ereport(ERROR,
4170 /* translator: %s represents an SQL statement name */
4171 errmsg("%s can only be used in transaction blocks",
4172 "COMMIT AND CHAIN")));
4173 else
4176 errmsg("there is no transaction in progress")));
4177 result = true;
4178 break;
4179
4180 /*
4181 * The user issued a COMMIT that somehow ran inside a parallel
4182 * worker. We can't cope with that.
4183 */
4185 ereport(FATAL,
4187 errmsg("cannot commit during a parallel operation")));
4188 break;
4189
4190 /* These cases are invalid. */
4191 case TBLOCK_DEFAULT:
4192 case TBLOCK_BEGIN:
4193 case TBLOCK_SUBBEGIN:
4194 case TBLOCK_END:
4195 case TBLOCK_SUBRELEASE:
4196 case TBLOCK_SUBCOMMIT:
4197 case TBLOCK_ABORT_END:
4201 case TBLOCK_SUBRESTART:
4203 case TBLOCK_PREPARE:
4204 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4206 break;
4207 }
4208
4210 s->blockState == TBLOCK_END ||
4213
4214 s->chain = chain;
4215
4216 return result;
4217}
4218
4219/*
4220 * UserAbortTransactionBlock
4221 * This executes a ROLLBACK command.
4222 *
4223 * As above, we don't actually do anything here except change blockState.
4224 */
4225void
4227{
4229
4230 switch (s->blockState)
4231 {
4232 /*
4233 * We are inside a transaction block and we got a ROLLBACK command
4234 * from the user, so tell CommitTransactionCommand to abort and
4235 * exit the transaction block.
4236 */
4237 case TBLOCK_INPROGRESS:
4239 break;
4240
4241 /*
4242 * We are inside a failed transaction block and we got a ROLLBACK
4243 * command from the user. Abort processing is already done, so
4244 * CommitTransactionCommand just has to cleanup and go back to
4245 * idle state.
4246 */
4247 case TBLOCK_ABORT:
4249 break;
4250
4251 /*
4252 * We are inside a subtransaction. Mark everything up to top
4253 * level as exitable.
4254 */
4256 case TBLOCK_SUBABORT:
4257 while (s->parent != NULL)
4258 {
4261 else if (s->blockState == TBLOCK_SUBABORT)
4263 else
4264 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4266 s = s->parent;
4267 }
4268 if (s->blockState == TBLOCK_INPROGRESS)
4270 else if (s->blockState == TBLOCK_ABORT)
4272 else
4273 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4275 break;
4276
4277 /*
4278 * The user issued ABORT when not inside a transaction. For
4279 * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4280 * The upcoming call to CommitTransactionCommand() will then put
4281 * us back into the default state. For ROLLBACK AND CHAIN, error.
4282 *
4283 * We do the same thing with ABORT inside an implicit transaction,
4284 * although in this case we might be rolling back actual database
4285 * state changes. (It's debatable whether we should issue a
4286 * WARNING in this case, but we have done so historically.)
4287 */
4288 case TBLOCK_STARTED:
4290 if (chain)
4291 ereport(ERROR,
4293 /* translator: %s represents an SQL statement name */
4294 errmsg("%s can only be used in transaction blocks",
4295 "ROLLBACK AND CHAIN")));
4296 else
4299 errmsg("there is no transaction in progress")));
4301 break;
4302
4303 /*
4304 * The user issued an ABORT that somehow ran inside a parallel
4305 * worker. We can't cope with that.
4306 */
4308 ereport(FATAL,
4310 errmsg("cannot abort during a parallel operation")));
4311 break;
4312
4313 /* These cases are invalid. */
4314 case TBLOCK_DEFAULT:
4315 case TBLOCK_BEGIN:
4316 case TBLOCK_SUBBEGIN:
4317 case TBLOCK_END:
4318 case TBLOCK_SUBRELEASE:
4319 case TBLOCK_SUBCOMMIT:
4320 case TBLOCK_ABORT_END:
4324 case TBLOCK_SUBRESTART:
4326 case TBLOCK_PREPARE:
4327 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4329 break;
4330 }
4331
4334
4335 s->chain = chain;
4336}
4337
4338/*
4339 * BeginImplicitTransactionBlock
4340 * Start an implicit transaction block if we're not already in one.
4341 *
4342 * Unlike BeginTransactionBlock, this is called directly from the main loop
4343 * in postgres.c, not within a Portal. So we can just change blockState
4344 * without a lot of ceremony. We do not expect caller to do
4345 * CommitTransactionCommand/StartTransactionCommand.
4346 */
4347void
4349{
4351
4352 /*
4353 * If we are in STARTED state (that is, no transaction block is open),
4354 * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4355 * block.
4356 *
4357 * For caller convenience, we consider all other transaction states as
4358 * legal here; otherwise the caller would need its own state check, which
4359 * seems rather pointless.
4360 */
4361 if (s->blockState == TBLOCK_STARTED)
4363}
4364
4365/*
4366 * EndImplicitTransactionBlock
4367 * End an implicit transaction block, if we're in one.
4368 *
4369 * Like EndTransactionBlock, we just make any needed blockState change here.
4370 * The real work will be done in the upcoming CommitTransactionCommand().
4371 */
4372void
4374{
4376
4377 /*
4378 * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4379 * allowing CommitTransactionCommand to commit whatever happened during
4380 * the implicit transaction block as though it were a single statement.
4381 *
4382 * For caller convenience, we consider all other transaction states as
4383 * legal here; otherwise the caller would need its own state check, which
4384 * seems rather pointless.
4385 */
4388}
4389
4390/*
4391 * DefineSavepoint
4392 * This executes a SAVEPOINT command.
4393 */
4394void
4396{
4398
4399 /*
4400 * Workers synchronize transaction state at the beginning of each parallel
4401 * operation, so we can't account for new subtransactions after that
4402 * point. (Note that this check will certainly error out if s->blockState
4403 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4404 * below.)
4405 */
4407 ereport(ERROR,
4409 errmsg("cannot define savepoints during a parallel operation")));
4410
4411 switch (s->blockState)
4412 {
4413 case TBLOCK_INPROGRESS:
4415 /* Normal subtransaction start */
4417 s = CurrentTransactionState; /* changed by push */
4418
4419 /*
4420 * Savepoint names, like the TransactionState block itself, live
4421 * in TopTransactionContext.
4422 */
4423 if (name)
4425 break;
4426
4427 /*
4428 * We disallow savepoint commands in implicit transaction blocks.
4429 * There would be no great difficulty in allowing them so far as
4430 * this module is concerned, but a savepoint seems inconsistent
4431 * with exec_simple_query's behavior of abandoning the whole query
4432 * string upon error. Also, the point of an implicit transaction
4433 * block (as opposed to a regular one) is to automatically close
4434 * after an error, so it's hard to see how a savepoint would fit
4435 * into that.
4436 *
4437 * The error messages for this are phrased as if there were no
4438 * active transaction block at all, which is historical but
4439 * perhaps could be improved.
4440 */
4442 ereport(ERROR,
4444 /* translator: %s represents an SQL statement name */
4445 errmsg("%s can only be used in transaction blocks",
4446 "SAVEPOINT")));
4447 break;
4448
4449 /* These cases are invalid. */
4450 case TBLOCK_DEFAULT:
4451 case TBLOCK_STARTED:
4452 case TBLOCK_BEGIN:
4454 case TBLOCK_SUBBEGIN:
4455 case TBLOCK_END:
4456 case TBLOCK_SUBRELEASE:
4457 case TBLOCK_SUBCOMMIT:
4458 case TBLOCK_ABORT:
4459 case TBLOCK_SUBABORT:
4460 case TBLOCK_ABORT_END:
4464 case TBLOCK_SUBRESTART:
4466 case TBLOCK_PREPARE:
4467 elog(FATAL, "DefineSavepoint: unexpected state %s",
4469 break;
4470 }
4471}
4472
4473/*
4474 * ReleaseSavepoint
4475 * This executes a RELEASE command.
4476 *
4477 * As above, we don't actually do anything here except change blockState.
4478 */
4479void
4481{
4483 TransactionState target,
4484 xact;
4485
4486 /*
4487 * Workers synchronize transaction state at the beginning of each parallel
4488 * operation, so we can't account for transaction state change after that
4489 * point. (Note that this check will certainly error out if s->blockState
4490 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4491 * below.)
4492 */
4494 ereport(ERROR,
4496 errmsg("cannot release savepoints during a parallel operation")));
4497
4498 switch (s->blockState)
4499 {
4500 /*
4501 * We can't release a savepoint if there is no savepoint defined.
4502 */
4503 case TBLOCK_INPROGRESS:
4504 ereport(ERROR,
4506 errmsg("savepoint \"%s\" does not exist", name)));
4507 break;
4508
4510 /* See comment about implicit transactions in DefineSavepoint */
4511 ereport(ERROR,
4513 /* translator: %s represents an SQL statement name */
4514 errmsg("%s can only be used in transaction blocks",
4515 "RELEASE SAVEPOINT")));
4516 break;
4517
4518 /*
4519 * We are in a non-aborted subtransaction. This is the only valid
4520 * case.
4521 */
4523 break;
4524
4525 /* These cases are invalid. */
4526 case TBLOCK_DEFAULT:
4527 case TBLOCK_STARTED:
4528 case TBLOCK_BEGIN:
4530 case TBLOCK_SUBBEGIN:
4531 case TBLOCK_END:
4532 case TBLOCK_SUBRELEASE:
4533 case TBLOCK_SUBCOMMIT:
4534 case TBLOCK_ABORT:
4535 case TBLOCK_SUBABORT:
4536 case TBLOCK_ABORT_END:
4540 case TBLOCK_SUBRESTART:
4542 case TBLOCK_PREPARE:
4543 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4545 break;
4546 }
4547
4548 for (target = s; target; target = target->parent)
4549 {
4550 if (target->name && strcmp(target->name, name) == 0)
4551 break;
4552 }
4553
4554 if (!target)
4555 ereport(ERROR,
4557 errmsg("savepoint \"%s\" does not exist", name)));
4558
4559 /* disallow crossing savepoint level boundaries */
4560 if (target->savepointLevel != s->savepointLevel)
4561 ereport(ERROR,
4563 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4564
4565 /*
4566 * Mark "commit pending" all subtransactions up to the target
4567 * subtransaction. The actual commits will happen when control gets to
4568 * CommitTransactionCommand.
4569 */
4571 for (;;)
4572 {
4573 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
4574 xact->blockState = TBLOCK_SUBRELEASE;
4575 if (xact == target)
4576 break;
4577 xact = xact->parent;
4578 Assert(xact);
4579 }
4580}
4581
4582/*
4583 * RollbackToSavepoint
4584 * This executes a ROLLBACK TO <savepoint> command.
4585 *
4586 * As above, we don't actually do anything here except change blockState.
4587 */
4588void
4590{
4592 TransactionState target,
4593 xact;
4594
4595 /*
4596 * Workers synchronize transaction state at the beginning of each parallel
4597 * operation, so we can't account for transaction state change after that
4598 * point. (Note that this check will certainly error out if s->blockState
4599 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4600 * below.)
4601 */
4603 ereport(ERROR,
4605 errmsg("cannot rollback to savepoints during a parallel operation")));
4606
4607 switch (s->blockState)
4608 {
4609 /*
4610 * We can't rollback to a savepoint if there is no savepoint
4611 * defined.
4612 */
4613 case TBLOCK_INPROGRESS:
4614 case TBLOCK_ABORT:
4615 ereport(ERROR,
4617 errmsg("savepoint \"%s\" does not exist", name)));
4618 break;
4619
4621 /* See comment about implicit transactions in DefineSavepoint */
4622 ereport(ERROR,
4624 /* translator: %s represents an SQL statement name */
4625 errmsg("%s can only be used in transaction blocks",
4626 "ROLLBACK TO SAVEPOINT")));
4627 break;
4628
4629 /*
4630 * There is at least one savepoint, so proceed.
4631 */
4633 case TBLOCK_SUBABORT:
4634 break;
4635
4636 /* These cases are invalid. */
4637 case TBLOCK_DEFAULT:
4638 case TBLOCK_STARTED:
4639 case TBLOCK_BEGIN:
4641 case TBLOCK_SUBBEGIN:
4642 case TBLOCK_END:
4643 case TBLOCK_SUBRELEASE:
4644 case TBLOCK_SUBCOMMIT:
4645 case TBLOCK_ABORT_END:
4649 case TBLOCK_SUBRESTART:
4651 case TBLOCK_PREPARE:
4652 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4654 break;
4655 }
4656
4657 for (target = s; target; target = target->parent)
4658 {
4659 if (target->name && strcmp(target->name, name) == 0)
4660 break;
4661 }
4662
4663 if (!target)
4664 ereport(ERROR,
4666 errmsg("savepoint \"%s\" does not exist", name)));
4667
4668 /* disallow crossing savepoint level boundaries */
4669 if (target->savepointLevel != s->savepointLevel)
4670 ereport(ERROR,
4672 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4673
4674 /*
4675 * Mark "abort pending" all subtransactions up to the target
4676 * subtransaction. The actual aborts will happen when control gets to
4677 * CommitTransactionCommand.
4678 */
4680 for (;;)
4681 {
4682 if (xact == target)
4683 break;
4684 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4686 else if (xact->blockState == TBLOCK_SUBABORT)
4687 xact->blockState = TBLOCK_SUBABORT_END;
4688 else
4689 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4690 BlockStateAsString(xact->blockState));
4691 xact = xact->parent;
4692 Assert(xact);
4693 }
4694
4695 /* And mark the target as "restart pending" */
4696 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4697 xact->blockState = TBLOCK_SUBRESTART;
4698 else if (xact->blockState == TBLOCK_SUBABORT)
4699 xact->blockState = TBLOCK_SUBABORT_RESTART;
4700 else
4701 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4702 BlockStateAsString(xact->blockState));
4703}
4704
4705/*
4706 * BeginInternalSubTransaction
4707 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
4708 * TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_END,
4709 * and TBLOCK_PREPARE states, and therefore it can safely be used in
4710 * functions that might be called when not inside a BEGIN block or when
4711 * running deferred triggers at COMMIT/PREPARE time. Also, it
4712 * automatically does CommitTransactionCommand/StartTransactionCommand
4713 * instead of expecting the caller to do it.
4714 */
4715void
4717{
4720
4721 /*
4722 * Errors within this function are improbable, but if one does happen we
4723 * force a FATAL exit. Callers generally aren't prepared to handle losing
4724 * control, and moreover our transaction state is probably corrupted if we
4725 * fail partway through; so an ordinary ERROR longjmp isn't okay.
4726 */
4727 ExitOnAnyError = true;
4728
4729 /*
4730 * We do not check for parallel mode here. It's permissible to start and
4731 * end "internal" subtransactions while in parallel mode, so long as no
4732 * new XIDs or command IDs are assigned. Enforcement of that occurs in
4733 * AssignTransactionId() and CommandCounterIncrement().
4734 */
4735
4736 switch (s->blockState)
4737 {
4738 case TBLOCK_STARTED:
4739 case TBLOCK_INPROGRESS:
4742 case TBLOCK_END:
4743 case TBLOCK_PREPARE:
4745 /* Normal subtransaction start */
4747 s = CurrentTransactionState; /* changed by push */
4748
4749 /*
4750 * Savepoint names, like the TransactionState block itself, live
4751 * in TopTransactionContext.
4752 */
4753 if (name)
4755 break;
4756
4757 /* These cases are invalid. */
4758 case TBLOCK_DEFAULT:
4759 case TBLOCK_BEGIN:
4760 case TBLOCK_SUBBEGIN:
4761 case TBLOCK_SUBRELEASE:
4762 case TBLOCK_SUBCOMMIT:
4763 case TBLOCK_ABORT:
4764 case TBLOCK_SUBABORT:
4765 case TBLOCK_ABORT_END:
4769 case TBLOCK_SUBRESTART:
4771 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4773 break;
4774 }
4775
4778
4780}
4781
4782/*
4783 * ReleaseCurrentSubTransaction
4784 *
4785 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
4786 * savepoint name (if any).
4787 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4788 */
4789void
4791{
4793
4794 /*
4795 * We do not check for parallel mode here. It's permissible to start and
4796 * end "internal" subtransactions while in parallel mode, so long as no
4797 * new XIDs or command IDs are assigned.
4798 */
4799
4801 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4806 s = CurrentTransactionState; /* changed by pop */
4808}
4809
4810/*
4811 * RollbackAndReleaseCurrentSubTransaction
4812 *
4813 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
4814 * of its savepoint name (if any).
4815 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4816 */
4817void
4819{
4821
4822 /*
4823 * We do not check for parallel mode here. It's permissible to start and
4824 * end "internal" subtransactions while in parallel mode, so long as no
4825 * new XIDs or command IDs are assigned.
4826 */
4827
4828 switch (s->blockState)
4829 {
4830 /* Must be in a subtransaction */
4832 case TBLOCK_SUBABORT:
4833 break;
4834
4835 /* These cases are invalid. */
4836 case TBLOCK_DEFAULT:
4837 case TBLOCK_STARTED:
4838 case TBLOCK_BEGIN:
4841 case TBLOCK_SUBBEGIN:
4842 case TBLOCK_INPROGRESS:
4843 case TBLOCK_END:
4844 case TBLOCK_SUBRELEASE:
4845 case TBLOCK_SUBCOMMIT:
4846 case TBLOCK_ABORT:
4847 case TBLOCK_ABORT_END:
4851 case TBLOCK_SUBRESTART:
4853 case TBLOCK_PREPARE:
4854 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4856 break;
4857 }
4858
4859 /*
4860 * Abort the current subtransaction, if needed.
4861 */
4864
4865 /* And clean it up, too */
4867
4868 s = CurrentTransactionState; /* changed by pop */
4874}
4875
4876/*
4877 * AbortOutOfAnyTransaction
4878 *
4879 * This routine is provided for error recovery purposes. It aborts any
4880 * active transaction or transaction block, leaving the system in a known
4881 * idle state.
4882 */
4883void
4885{
4887
4888 /* Ensure we're not running in a doomed memory context */
4890
4891 /*
4892 * Get out of any transaction or nested transaction
4893 */
4894 do
4895 {
4896 switch (s->blockState)
4897 {
4898 case TBLOCK_DEFAULT:
4899 if (s->state == TRANS_DEFAULT)
4900 {
4901 /* Not in a transaction, do nothing */
4902 }
4903 else
4904 {
4905 /*
4906 * We can get here after an error during transaction start
4907 * (state will be TRANS_START). Need to clean up the
4908 * incompletely started transaction. First, adjust the
4909 * low-level state to suppress warning message from
4910 * AbortTransaction.
4911 */
4912 if (s->state == TRANS_START)
4916 }
4917 break;
4918 case TBLOCK_STARTED:
4919 case TBLOCK_BEGIN:
4920 case TBLOCK_INPROGRESS:
4923 case TBLOCK_END:
4925 case TBLOCK_PREPARE:
4926 /* In a transaction, so clean up */
4930 break;
4931 case TBLOCK_ABORT:
4932 case TBLOCK_ABORT_END:
4933
4934 /*
4935 * AbortTransaction is already done, still need Cleanup.
4936 * However, if we failed partway through running ROLLBACK,
4937 * there will be an active portal running that command, which
4938 * we need to shut down before doing CleanupTransaction.
4939 */
4943 break;
4944
4945 /*
4946 * In a subtransaction, so clean it up and abort parent too
4947 */
4948 case TBLOCK_SUBBEGIN:
4950 case TBLOCK_SUBRELEASE:
4951 case TBLOCK_SUBCOMMIT:
4953 case TBLOCK_SUBRESTART:
4956 s = CurrentTransactionState; /* changed by pop */
4957 break;
4958
4959 case TBLOCK_SUBABORT:
4962 /* As above, but AbortSubTransaction already done */
4963 if (s->curTransactionOwner)
4964 {
4965 /* As in TBLOCK_ABORT, might have a live portal to zap */
4970 }
4972 s = CurrentTransactionState; /* changed by pop */
4973 break;
4974 }
4975 } while (s->blockState != TBLOCK_DEFAULT);
4976
4977 /* Should be out of all subxacts now */
4978 Assert(s->parent == NULL);
4979
4980 /*
4981 * Revert to TopMemoryContext, to ensure we exit in a well-defined state
4982 * whether there were any transactions to close or not. (Callers that
4983 * don't intend to exit soon should switch to some other context to avoid
4984 * long-term memory leaks.)
4985 */
4987}
4988
4989/*
4990 * IsTransactionBlock --- are we within a transaction block?
4991 */
4992bool
4994{
4996
4998 return false;
4999
5000 return true;
5001}
5002
5003/*
5004 * IsTransactionOrTransactionBlock --- are we within either a transaction
5005 * or a transaction block? (The backend is only really "idle" when this
5006 * returns false.)
5007 *
5008 * This should match up with IsTransactionBlock and IsTransactionState.
5009 */
5010bool
5012{
5014
5015 if (s->blockState == TBLOCK_DEFAULT)
5016 return false;
5017
5018 return true;
5019}
5020
5021/*
5022 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
5023 */
5024char
5026{
5028
5029 switch (s->blockState)
5030 {
5031 case TBLOCK_DEFAULT:
5032 case TBLOCK_STARTED:
5033 return 'I'; /* idle --- not in transaction */
5034 case TBLOCK_BEGIN:
5035 case TBLOCK_SUBBEGIN:
5036 case TBLOCK_INPROGRESS:
5040 case TBLOCK_END:
5041 case TBLOCK_SUBRELEASE:
5042 case TBLOCK_SUBCOMMIT:
5043 case TBLOCK_PREPARE:
5044 return 'T'; /* in transaction */
5045 case TBLOCK_ABORT:
5046 case TBLOCK_SUBABORT:
5047 case TBLOCK_ABORT_END:
5051 case TBLOCK_SUBRESTART:
5053 return 'E'; /* in failed transaction */
5054 }
5055
5056 /* should never get here */
5057 elog(FATAL, "invalid transaction block state: %s",
5059 return 0; /* keep compiler quiet */
5060}
5061
5062/*
5063 * IsSubTransaction
5064 */
5065bool
5067{
5069
5070 if (s->nestingLevel >= 2)
5071 return true;
5072
5073 return false;
5074}
5075
5076/*
5077 * StartSubTransaction
5078 *
5079 * If you're wondering why this is separate from PushTransaction: it's because
5080 * we can't conveniently do this stuff right inside DefineSavepoint. The
5081 * SAVEPOINT utility command will be executed inside a Portal, and if we
5082 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
5083 * the Portal will undo those settings. So we make DefineSavepoint just
5084 * push a dummy transaction block, and when control returns to the main
5085 * idle loop, CommitTransactionCommand will be called, and we'll come here
5086 * to finish starting the subtransaction.
5087 */
5088static void
5090{
5092
5093 if (s->state != TRANS_DEFAULT)
5094 elog(WARNING, "StartSubTransaction while in %s state",
5096
5097 s->state = TRANS_START;
5098
5099 /*
5100 * Initialize subsystems for new subtransaction
5101 *
5102 * must initialize resource-management stuff first
5103 */
5107
5109
5110 /*
5111 * Call start-of-subxact callbacks
5112 */
5115
5116 ShowTransactionState("StartSubTransaction");
5117}
5118
5119/*
5120 * CommitSubTransaction
5121 *
5122 * The caller has to make sure to always reassign CurrentTransactionState
5123 * if it has a local pointer to it after calling this function.
5124 */
5125static void
5127{
5129
5130 ShowTransactionState("CommitSubTransaction");
5131
5132 if (s->state != TRANS_INPROGRESS)
5133 elog(WARNING, "CommitSubTransaction while in %s state",
5135
5136 /* Pre-commit processing goes here */
5137
5140
5141 /*
5142 * If this subxact has started any unfinished parallel operation, clean up
5143 * its workers and exit parallel mode. Warn about leaked resources.
5144 */
5146 if (s->parallelModeLevel != 0)
5147 {
5148 elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5150 s->parallelModeLevel = 0;
5151 }
5152
5153 /* Do the actual "commit", such as it is */
5154 s->state = TRANS_COMMIT;
5155
5156 /* Must CCI to ensure commands of subtransaction are seen as done */
5158
5159 /*
5160 * Prior to 8.4 we marked subcommit in clog at this point. We now only
5161 * perform that step, if required, as part of the atomic update of the
5162 * whole transaction tree at top level commit or abort.
5163 */
5164
5165 /* Post-commit cleanup */
5171 s->parent->nestingLevel,
5176
5179
5182 true, false);
5186 AtEOSubXact_Inval(true);
5188
5189 /*
5190 * The only lock we actually release here is the subtransaction XID lock.
5191 */
5195
5196 /*
5197 * Other locks should get transferred to their parent resource owner.
5198 */
5201 true, false);
5204 true, false);
5205
5206 AtEOXact_GUC(true, s->gucNestLevel);
5217
5218 /*
5219 * We need to restore the upper transaction's read-only state, in case the
5220 * upper is read-write while the child is read-only; GUC will incorrectly
5221 * think it should leave the child state in place.
5222 */
5224
5229
5231
5232 s->state = TRANS_DEFAULT;
5233
5235}
5236
5237/*
5238 * AbortSubTransaction
5239 */
5240static void
5242{
5244
5245 /* Prevent cancel/die interrupt while cleaning up */
5247
5248 /* Make sure we have a valid memory context and resource owner */
5251
5252 /*
5253 * Release any LW locks we might be holding as quickly as possible.
5254 * (Regular locks, however, must be held till we finish aborting.)
5255 * Releasing LW locks is critical since we might try to grab them again
5256 * while cleaning up!
5257 *
5258 * FIXME This may be incorrect --- Are there some locks we should keep?
5259 * Buffer locks, for example? I don't think so but I'm not sure.
5260 */
5262
5265
5267
5268 UnlockBuffers();
5269
5270 /* Reset WAL record construction state */
5272
5273 /* Cancel condition variable sleep */
5275
5276 /*
5277 * Also clean up any open wait for lock, since the lock manager will choke
5278 * if we try to wait for another lock before doing this.
5279 */
5281
5282 /*
5283 * If any timeout events are still active, make sure the timeout interrupt
5284 * is scheduled. This covers possible loss of a timeout interrupt due to
5285 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5286 * We delay this till after LockErrorCleanup so that we don't uselessly
5287 * reschedule lock or deadlock check timeouts.
5288 */
5290
5291 /*
5292 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5293 * handler. We do this fairly early in the sequence so that the timeout
5294 * infrastructure will be functional if needed while aborting.
5295 */
5297
5298 /*
5299 * check the current transaction state
5300 */
5301 ShowTransactionState("AbortSubTransaction");
5302
5303 if (s->state != TRANS_INPROGRESS)
5304 elog(WARNING, "AbortSubTransaction while in %s state",
5306
5307 s->state = TRANS_ABORT;
5308
5309 /*
5310 * Reset user ID which might have been changed transiently. (See notes in
5311 * AbortTransaction.)
5312 */
5314
5315 /* Forget about any active REINDEX. */
5317
5318 /* Reset logical streaming state. */
5320
5321 /*
5322 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5323 * exports are not supported in subtransactions.
5324 */
5325
5326 /*
5327 * If this subxact has started any unfinished parallel operation, clean up
5328 * its workers and exit parallel mode. Don't warn about leaked resources.
5329 */
5331 s->parallelModeLevel = 0;
5332
5333 /*
5334 * We can skip all this stuff if the subxact failed before creating a
5335 * ResourceOwner...
5336 */
5337 if (s->curTransactionOwner)
5338 {
5347
5348 /* Advertise the fact that we aborted in pg_xact. */
5350
5351 /* Post-abort cleanup */
5354
5357
5360 false, false);
5361
5362 AtEOXact_Aio(false);
5366 AtEOSubXact_Inval(false);
5369 false, false);
5372 false, false);
5374
5375 AtEOXact_GUC(false, s->gucNestLevel);
5386 }
5387
5388 /*
5389 * Restore the upper transaction's read-only state, too. This should be
5390 * redundant with GUC's cleanup but we may as well do it for consistency
5391 * with the commit case.
5392 */
5394
5396}
5397
5398/*
5399 * CleanupSubTransaction
5400 *
5401 * The caller has to make sure to always reassign CurrentTransactionState
5402 * if it has a local pointer to it after calling this function.
5403 */
5404static void
5406{
5408
5409 ShowTransactionState("CleanupSubTransaction");
5410
5411 if (s->state != TRANS_ABORT)
5412 elog(WARNING, "CleanupSubTransaction while in %s state",
5414
5416
5419 if (s->curTransactionOwner)
5422
5424
5425 s->state = TRANS_DEFAULT;
5426
5428}
5429
5430/*
5431 * PushTransaction
5432 * Create transaction state stack entry for a subtransaction
5433 *
5434 * The caller has to make sure to always reassign CurrentTransactionState
5435 * if it has a local pointer to it after calling this function.
5436 */
5437static void
5439{
5442
5443 /*
5444 * We keep subtransaction state nodes in TopTransactionContext.
5445 */
5446 s = (TransactionState)
5448 sizeof(TransactionStateData));
5449
5450 /*
5451 * Assign a subtransaction ID, watching out for counter wraparound.
5452 */
5455 {
5457 pfree(s);
5458 ereport(ERROR,
5460 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5461 }
5462
5463 /*
5464 * We can now stack a minimally valid subtransaction without fear of
5465 * failure.
5466 */
5467 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5469 s->parent = p;
5470 s->nestingLevel = p->nestingLevel + 1;
5473 s->state = TRANS_DEFAULT;
5478 s->parallelModeLevel = 0;
5480 s->topXidLogged = false;
5481
5483
5484 /*
5485 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5486 * with the subtransaction from here on out; in particular they should not
5487 * assume that it necessarily has a transaction context, resource owner,
5488 * or XID.
5489 */
5490}
5491
5492/*
5493 * PopTransaction
5494 * Pop back to parent transaction state
5495 *
5496 * The caller has to make sure to always reassign CurrentTransactionState
5497 * if it has a local pointer to it after calling this function.
5498 */
5499static void
5501{
5503
5504 if (s->state != TRANS_DEFAULT)
5505 elog(WARNING, "PopTransaction while in %s state",
5507
5508 if (s->parent == NULL)
5509 elog(FATAL, "PopTransaction with no parent");
5510
5512
5513 /* Let's just make sure CurTransactionContext is good */
5516
5517 /* Ditto for ResourceOwner links */
5520
5521 /* Free the old child structure */
5522 if (s->name)
5523 pfree(s->name);
5524 pfree(s);
5525}
5526
5527/*
5528 * EstimateTransactionStateSpace
5529 * Estimate the amount of space that will be needed by
5530 * SerializeTransactionState. It would be OK to overestimate slightly,
5531 * but it's simple for us to work out the precise value, so we do.
5532 */
5533Size
5535{
5537 Size nxids = 0;
5539
5540 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5541 {
5543 nxids = add_size(nxids, 1);
5545 }
5546
5547 return add_size(size, mul_size(sizeof(TransactionId), nxids));
5548}
5549
5550/*
5551 * SerializeTransactionState
5552 * Write out relevant details of our transaction state that will be
5553 * needed by a parallel worker.
5554 *
5555 * We need to save and restore XactDeferrable, XactIsoLevel, and the XIDs
5556 * associated with this transaction. These are serialized into a
5557 * caller-supplied buffer big enough to hold the number of bytes reported by
5558 * EstimateTransactionStateSpace(). We emit the XIDs in sorted order for the
5559 * convenience of the receiving process.
5560 */
5561void
5563{
5565 Size nxids = 0;
5566 Size i = 0;
5567 TransactionId *workspace;
5569
5571
5572 result->xactIsoLevel = XactIsoLevel;
5575 result->currentFullTransactionId =
5578
5579 /*
5580 * If we're running in a parallel worker and launching a parallel worker
5581 * of our own, we can just pass along the information that was passed to
5582 * us.
5583 */
5584 if (nParallelCurrentXids > 0)
5585 {
5589 return;
5590 }
5591
5592 /*
5593 * OK, we need to generate a sorted list of XIDs that our workers should
5594 * view as current. First, figure out how many there are.
5595 */
5596 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5597 {
5599 nxids = add_size(nxids, 1);
5601 }
5603 <= maxsize);
5604
5605 /* Copy them to our scratch space. */
5606 workspace = palloc(nxids * sizeof(TransactionId));
5607 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5608 {
5610 workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5611 if (s->nChildXids > 0)
5612 memcpy(&workspace[i], s->childXids,
5613 s->nChildXids * sizeof(TransactionId));
5614 i += s->nChildXids;
5615 }
5616 Assert(i == nxids);
5617
5618 /* Sort them. */
5619 qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5620
5621 /* Copy data into output area. */
5622 result->nParallelCurrentXids = nxids;
5623 memcpy(&result->parallelCurrentXids[0], workspace,
5624 nxids * sizeof(TransactionId));
5625}
5626
5627/*
5628 * StartParallelWorkerTransaction
5629 * Start a parallel worker transaction, restoring the relevant
5630 * transaction state serialized by SerializeTransactionState.
5631 */
5632void
5634{
5636
5639
5641 XactIsoLevel = tstate->xactIsoLevel;
5642 XactDeferrable = tstate->xactDeferrable;
5643 XactTopFullTransactionId = tstate->topFullTransactionId;
5645 tstate->currentFullTransactionId;
5646 currentCommandId = tstate->currentCommandId;
5647 nParallelCurrentXids = tstate->nParallelCurrentXids;
5648 ParallelCurrentXids = &tstate->parallelCurrentXids[0];
5649
5651}
5652
5653/*
5654 * EndParallelWorkerTransaction
5655 * End a parallel worker transaction.
5656 */
5657void
5664
5665/*
5666 * ShowTransactionState
5667 * Debug support
5668 */
5669static void
5671{
5672 /* skip work if message will definitely not be printed */
5675}
5676
5677/*
5678 * ShowTransactionStateRec
5679 * Recursive subroutine for ShowTransactionState
5680 */
5681static void
5683{
5685
5686 if (s->parent)
5687 {
5688 /*
5689 * Since this function recurses, it could be driven to stack overflow.
5690 * This is just a debugging aid, so we can leave out some details
5691 * instead of erroring out with check_stack_depth().
5692 */
5693 if (stack_is_too_deep())
5695 (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5696 str, s->nestingLevel)));
5697 else
5699 }
5700
5702 if (s->nChildXids > 0)
5703 {
5704 int i;
5705
5706 appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5707 for (i = 1; i < s->nChildXids; i++)
5708 appendStringInfo(&buf, " %u", s->childXids[i]);
5709 }
5711 (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5712 str, s->nestingLevel,
5713 s->name ? s->name : "unnamed",
5719 currentCommandIdUsed ? " (used)" : "",
5720 buf.data)));
5721 pfree(buf.data);
5722}
5723
5724/*
5725 * BlockStateAsString
5726 * Debug support
5727 */
5728static const char *
5730{
5731 switch (blockState)
5732 {
5733 case TBLOCK_DEFAULT:
5734 return "DEFAULT";
5735 case TBLOCK_STARTED:
5736 return "STARTED";
5737 case TBLOCK_BEGIN:
5738 return "BEGIN";
5739 case TBLOCK_INPROGRESS:
5740 return "INPROGRESS";
5742 return "IMPLICIT_INPROGRESS";
5744 return "PARALLEL_INPROGRESS";
5745 case TBLOCK_END:
5746 return "END";
5747 case TBLOCK_ABORT:
5748 return "ABORT";
5749 case TBLOCK_ABORT_END:
5750 return "ABORT_END";
5752 return "ABORT_PENDING";
5753 case TBLOCK_PREPARE:
5754 return "PREPARE";
5755 case TBLOCK_SUBBEGIN:
5756 return "SUBBEGIN";
5758 return "SUBINPROGRESS";
5759 case TBLOCK_SUBRELEASE:
5760 return "SUBRELEASE";
5761 case TBLOCK_SUBCOMMIT:
5762 return "SUBCOMMIT";
5763 case TBLOCK_SUBABORT:
5764 return "SUBABORT";
5766 return "SUBABORT_END";
5768 return "SUBABORT_PENDING";
5769 case TBLOCK_SUBRESTART:
5770 return "SUBRESTART";
5772 return "SUBABORT_RESTART";
5773 }
5774 return "UNRECOGNIZED";
5775}
5776
5777/*
5778 * TransStateAsString
5779 * Debug support
5780 */
5781static const char *
5783{
5784 switch (state)
5785 {
5786 case TRANS_DEFAULT:
5787 return "DEFAULT";
5788 case TRANS_START:
5789 return "START";
5790 case TRANS_INPROGRESS:
5791 return "INPROGRESS";
5792 case TRANS_COMMIT:
5793 return "COMMIT";
5794 case TRANS_ABORT:
5795 return "ABORT";
5796 case TRANS_PREPARE:
5797 return "PREPARE";
5798 }
5799 return "UNRECOGNIZED";
5800}
5801
5802/*
5803 * xactGetCommittedChildren
5804 *
5805 * Gets the list of committed children of the current transaction. The return
5806 * value is the number of child transactions. *ptr is set to point to an
5807 * array of TransactionIds. The array is allocated in TopTransactionContext;
5808 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
5809 * If there are no subxacts, *ptr is set to NULL.
5810 */
5811int
5813{
5815
5816 if (s->nChildXids == 0)
5817 *ptr = NULL;
5818 else
5819 *ptr = s->childXids;
5820
5821 return s->nChildXids;
5822}
5823
5824/*
5825 * XLOG support routines
5826 */
5827
5828
5829/*
5830 * Log the commit record for a plain or twophase transaction commit.
5831 *
5832 * A 2pc commit will be emitted when twophase_xid is valid, a plain one
5833 * otherwise.
5834 */
5837 int nsubxacts, TransactionId *subxacts,
5838 int nrels, RelFileLocator *rels,
5840 int nmsgs, SharedInvalidationMessage *msgs,
5841 bool relcacheInval,
5842 int xactflags, TransactionId twophase_xid,
5843 const char *twophase_gid)
5844{
5854 uint8 info;
5855
5857
5858 xl_xinfo.xinfo = 0;
5859
5860 /* decide between a plain and 2pc commit */
5861 if (!TransactionIdIsValid(twophase_xid))
5862 info = XLOG_XACT_COMMIT;
5863 else
5865
5866 /* First figure out and collect all the information needed */
5867
5868 xlrec.xact_time = commit_time;
5869
5870 if (relcacheInval)
5872 if (forceSyncCommit)
5876
5877 /*
5878 * Check if the caller would like to ask standbys for immediate feedback
5879 * once this commit is applied.
5880 */
5883
5884 /*
5885 * Relcache invalidations requires information about the current database
5886 * and so does logical decoding.
5887 */
5888 if (nmsgs > 0 || XLogLogicalInfoActive())
5889 {
5891 xl_dbinfo.dbId = MyDatabaseId;
5893 }
5894
5895 if (nsubxacts > 0)
5896 {
5898 xl_subxacts.nsubxacts = nsubxacts;
5899 }
5900
5901 if (nrels > 0)
5902 {
5904 xl_relfilelocators.nrels = nrels;
5905 info |= XLR_SPECIAL_REL_UPDATE;
5906 }
5907
5908 if (ndroppedstats > 0)
5909 {
5912 }
5913
5914 if (nmsgs > 0)
5915 {
5917 xl_invals.nmsgs = nmsgs;
5918 }
5919
5920 if (TransactionIdIsValid(twophase_xid))
5921 {
5923 xl_twophase.xid = twophase_xid;
5924 Assert(twophase_gid != NULL);
5925
5928 }
5929
5930 /* dump transaction origin information */
5932 {
5934
5937 }
5938
5939 if (xl_xinfo.xinfo != 0)
5940 info |= XLOG_XACT_HAS_INFO;
5941
5942 /* Then include all the collected data into the commit record. */
5943
5945
5947
5948 if (xl_xinfo.xinfo != 0)
5949 XLogRegisterData(&xl_xinfo.xinfo, sizeof(xl_xinfo.xinfo));
5950
5951 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5953
5955 {
5958 XLogRegisterData(subxacts,
5959 nsubxacts * sizeof(TransactionId));
5960 }
5961
5963 {
5966 XLogRegisterData(rels,
5967 nrels * sizeof(RelFileLocator));
5968 }
5969
5971 {
5976 }
5977
5978 if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
5979 {
5981 XLogRegisterData(msgs,
5982 nmsgs * sizeof(SharedInvalidationMessage));
5983 }
5984
5986 {
5988 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
5989 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
5990 }
5991
5992 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5994
5995 /* we allow filtering by xacts */
5997
5998 return XLogInsert(RM_XACT_ID, info);
5999}
6000
6001/*
6002 * Log the commit record for a plain or twophase transaction abort.
6003 *
6004 * A 2pc abort will be emitted when twophase_xid is valid, a plain one
6005 * otherwise.
6006 */
6009 int nsubxacts, TransactionId *subxacts,
6010 int nrels, RelFileLocator *rels,
6012 int xactflags, TransactionId twophase_xid,
6013 const char *twophase_gid)
6014{
6023
6024 uint8 info;
6025
6027
6028 xl_xinfo.xinfo = 0;
6029
6030 /* decide between a plain and 2pc abort */
6031 if (!TransactionIdIsValid(twophase_xid))
6032 info = XLOG_XACT_ABORT;
6033 else
6035
6036
6037 /* First figure out and collect all the information needed */
6038
6039 xlrec.xact_time = abort_time;
6040
6043
6044 if (nsubxacts > 0)
6045 {
6047 xl_subxacts.nsubxacts = nsubxacts;
6048 }
6049
6050 if (nrels > 0)
6051 {
6053 xl_relfilelocators.nrels = nrels;
6054 info |= XLR_SPECIAL_REL_UPDATE;
6055 }
6056
6057 if (ndroppedstats > 0)
6058 {
6061 }
6062
6063 if (TransactionIdIsValid(twophase_xid))
6064 {
6066 xl_twophase.xid = twophase_xid;
6067 Assert(twophase_gid != NULL);
6068
6071 }
6072
6073 if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6074 {
6076 xl_dbinfo.dbId = MyDatabaseId;
6078 }
6079
6080 /*
6081 * Dump transaction origin information. We need this during recovery to
6082 * update the replication origin progress.
6083 */
6085 {
6087
6090 }
6091
6092 if (xl_xinfo.xinfo != 0)
6093 info |= XLOG_XACT_HAS_INFO;
6094
6095 /* Then include all the collected data into the abort record. */
6096
6098
6100
6101 if (xl_xinfo.xinfo != 0)
6103
6104 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6106
6108 {
6111 XLogRegisterData(subxacts,
6112 nsubxacts * sizeof(TransactionId));
6113 }
6114
6116 {
6119 XLogRegisterData(rels,
6120 nrels * sizeof(RelFileLocator));
6121 }
6122
6124 {
6129 }
6130
6132 {
6134 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6135 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6136 }
6137
6138 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6140
6141 /* Include the replication origin */
6143
6144 return XLogInsert(RM_XACT_ID, info);
6145}
6146
6147/*
6148 * Before 9.0 this was a fairly short function, but now it performs many
6149 * actions for which the order of execution is critical.
6150 */
6151static void
6153 TransactionId xid,
6154 XLogRecPtr lsn,
6155 RepOriginId origin_id)
6156{
6158 TimestampTz commit_time;
6159
6161
6162 max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
6163
6164 /* Make sure nextXid is beyond any XID mentioned in the record. */
6166
6167 Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) ==
6168 (origin_id == InvalidRepOriginId));
6169
6170 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6171 commit_time = parsed->origin_timestamp;
6172 else
6173 commit_time = parsed->xact_time;
6174
6175 /* Set the transaction commit timestamp and metadata */
6176 TransactionTreeSetCommitTsData(xid, parsed->nsubxacts, parsed->subxacts,
6177 commit_time, origin_id);
6178
6180 {
6181 /*
6182 * Mark the transaction committed in pg_xact.
6183 */
6184 TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
6185 }
6186 else
6187 {
6188 /*
6189 * If a transaction completion record arrives that has as-yet
6190 * unobserved subtransactions then this will not have been fully
6191 * handled by the call to RecordKnownAssignedTransactionIds() in the
6192 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6193 * cover that case. This is confusing and it is easy to think this
6194 * call is irrelevant, which has happened three times in development
6195 * already. Leave it in.
6196 */
6198
6199 /*
6200 * Mark the transaction committed in pg_xact. We use async commit
6201 * protocol during recovery to provide information on database
6202 * consistency for when users try to set hint bits. It is important
6203 * that we do not set hint bits until the minRecoveryPoint is past
6204 * this commit record. This ensures that if we crash we don't see hint
6205 * bits set on changes made by transactions that haven't yet
6206 * recovered. It's unlikely but it's good to be safe.
6207 */
6208 TransactionIdAsyncCommitTree(xid, parsed->nsubxacts, parsed->subxacts, lsn);
6209
6210 /*
6211 * We must mark clog before we update the ProcArray.
6212 */
6213 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6214
6215 /*
6216 * Send any cache invalidations attached to the commit. We must
6217 * maintain the same order of invalidation then release locks as
6218 * occurs in CommitTransaction().
6219 */
6222 parsed->dbId, parsed->tsId);
6223
6224 /*
6225 * Release locks, if any. We do this for both two phase and normal one
6226 * phase transactions. In effect we are ignoring the prepare phase and
6227 * just going straight to lock release.
6228 */
6229 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6230 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6231 }
6232
6233 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6234 {
6235 /* recover apply progress */
6236 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6237 false /* backward */ , false /* WAL */ );
6238 }
6239
6240 /* Make sure files supposed to be dropped are dropped */
6241 if (parsed->nrels > 0)
6242 {
6243 /*
6244 * First update minimum recovery point to cover this WAL record. Once
6245 * a relation is deleted, there's no going back. The buffer manager
6246 * enforces the WAL-first rule for normal updates to relation files,
6247 * so that the minimum recovery point is always updated before the
6248 * corresponding change in the data file is flushed to disk, but we
6249 * have to do the same here since we're bypassing the buffer manager.
6250 *
6251 * Doing this before deleting the files means that if a deletion fails
6252 * for some reason, you cannot start up the system even after restart,
6253 * until you fix the underlying situation so that the deletion will
6254 * succeed. Alternatively, we could update the minimum recovery point
6255 * after deletion, but that would leave a small window where the
6256 * WAL-first rule would be violated.
6257 */
6258 XLogFlush(lsn);
6259
6260 /* Make sure files supposed to be dropped are dropped */
6261 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6262 }
6263
6264 if (parsed->nstats > 0)
6265 {
6266 /* see equivalent call for relations above */
6267 XLogFlush(lsn);
6268
6269 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6270 }
6271
6272 /*
6273 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
6274 * in normal operation. For example, in CREATE DATABASE, we copy all files
6275 * from the template database, and then commit the transaction. If we
6276 * crash after all the files have been copied but before the commit, you
6277 * have files in the data directory without an entry in pg_database. To
6278 * minimize the window for that, we use ForceSyncCommit() to rush the
6279 * commit record to disk as quick as possible. We have the same window
6280 * during recovery, and forcing an XLogFlush() (which updates
6281 * minRecoveryPoint during recovery) helps to reduce that problem window,
6282 * for any user that requested ForceSyncCommit().
6283 */
6285 XLogFlush(lsn);
6286
6287 /*
6288 * If asked by the primary (because someone is waiting for a synchronous
6289 * commit = remote_apply), we will need to ask walreceiver to send a reply
6290 * immediately.
6291 */
6294}
6295
6296/*
6297 * Be careful with the order of execution, as with xact_redo_commit().
6298 * The two functions are similar but differ in key places.
6299 *
6300 * Note also that an abort can be for a subtransaction and its children,
6301 * not just for a top level abort. That means we have to consider
6302 * topxid != xid, whereas in commit we would find topxid == xid always
6303 * because subtransaction commit is never WAL logged.
6304 */
6305static void
6307 XLogRecPtr lsn, RepOriginId origin_id)
6308{
6310
6312
6313 /* Make sure nextXid is beyond any XID mentioned in the record. */
6315 parsed->nsubxacts,
6316 parsed->subxacts);
6318
6320 {
6321 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6322 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6323 }
6324 else
6325 {
6326 /*
6327 * If a transaction completion record arrives that has as-yet
6328 * unobserved subtransactions then this will not have been fully
6329 * handled by the call to RecordKnownAssignedTransactionIds() in the
6330 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6331 * cover that case. This is confusing and it is easy to think this
6332 * call is irrelevant, which has happened three times in development
6333 * already. Leave it in.
6334 */
6336
6337 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6338 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6339
6340 /*
6341 * We must update the ProcArray after we have marked clog.
6342 */
6343 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6344
6345 /*
6346 * There are no invalidation messages to send or undo.
6347 */
6348
6349 /*
6350 * Release locks, if any. There are no invalidations to send.
6351 */
6352 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6353 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6354 }
6355
6356 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6357 {
6358 /* recover apply progress */
6359 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6360 false /* backward */ , false /* WAL */ );
6361 }
6362
6363 /* Make sure files supposed to be dropped are dropped */
6364 if (parsed->nrels > 0)
6365 {
6366 /*
6367 * See comments about update of minimum recovery point on truncation,
6368 * in xact_redo_commit().
6369 */
6370 XLogFlush(lsn);
6371
6372 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6373 }
6374
6375 if (parsed->nstats > 0)
6376 {
6377 /* see equivalent call for relations above */
6378 XLogFlush(lsn);
6379
6380 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6381 }
6382}
6383
6384void
6386{
6387 uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6388
6389 /* Backup blocks are not used in xact records */
6391
6392 if (info == XLOG_XACT_COMMIT)
6393 {
6396
6399 record->EndRecPtr, XLogRecGetOrigin(record));
6400 }
6401 else if (info == XLOG_XACT_COMMIT_PREPARED)
6402 {
6405
6407 xact_redo_commit(&parsed, parsed.twophase_xid,
6408 record->EndRecPtr, XLogRecGetOrigin(record));
6409
6410 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6412 PrepareRedoRemove(parsed.twophase_xid, false);
6414 }
6415 else if (info == XLOG_XACT_ABORT)
6416 {
6419
6422 record->EndRecPtr, XLogRecGetOrigin(record));
6423 }
6424 else if (info == XLOG_XACT_ABORT_PREPARED)
6425 {
6428
6430 xact_redo_abort(&parsed, parsed.twophase_xid,
6431 record->EndRecPtr, XLogRecGetOrigin(record));
6432
6433 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6435 PrepareRedoRemove(parsed.twophase_xid, false);
6437 }
6438 else if (info == XLOG_XACT_PREPARE)
6439 {
6440 /*
6441 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6442 * gxact entry.
6443 */
6446 XLogRecGetData(record),
6447 record->ReadRecPtr,
6448 record->EndRecPtr,
6449 XLogRecGetOrigin(record));
6451 }
6452 else if (info == XLOG_XACT_ASSIGNMENT)
6453 {
6455
6458 xlrec->nsubxacts, xlrec->xsub);
6459 }
6460 else if (info == XLOG_XACT_INVALIDATIONS)
6461 {
6462 /*
6463 * XXX we do ignore this for now, what matters are invalidations
6464 * written into the commit record.
6465 */
6466 }
6467 else
6468 elog(PANIC, "xact_redo: unknown op code %u", info);
6469}
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:1369
void AtAbort_Notify(void)
Definition async.c:2410
void PreCommit_Notify(void)
Definition async.c:1176
void AtSubAbort_Notify(void)
Definition async.c:2499
void AtPrepare_Notify(void)
Definition async.c:1151
void AtSubCommit_Notify(void)
Definition async.c:2429
#define pg_write_barrier()
Definition atomics.h:155
void ParallelWorkerReportLastRecEnd(XLogRecPtr last_xlog_end)
Definition parallel.c:1593
bool ParallelContextActive(void)
Definition parallel.c:1031
void AtEOSubXact_Parallel(bool isCommit, SubTransactionId mySubId)
Definition parallel.c:1261
void AtEOXact_Parallel(bool isCommit)
Definition parallel.c:1282
sigset_t UnBlockSig
Definition pqsignal.c:22
void AtEOXact_LogicalRepWorkers(bool isCommit)
Definition worker.c:6273
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1645
void pgstat_progress_end_command(void)
void pgstat_report_xact_timestamp(TimestampTz tstamp)
void AtEOXact_LargeObject(bool isCommit)
Definition be-fsstubs.c:607
void AtEOSubXact_LargeObject(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition be-fsstubs.c:653
static int32 next
Definition blutils.c:225
static void cleanup(void)
Definition bootstrap.c:717
void AtEOXact_Buffers(bool isCommit)
Definition bufmgr.c:4103
void UnlockBuffers(void)
Definition bufmgr.c:5709
#define InvalidCommandId
Definition c.h:693
#define TopSubTransactionId
Definition c.h:683
#define Min(x, y)
Definition c.h:1007
uint8_t uint8
Definition c.h:554
uint32 SubTransactionId
Definition c.h:680
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:223
#define InvalidSubTransactionId
Definition c.h:682
#define Assert(condition)
Definition c.h:883
#define FLEXIBLE_ARRAY_MEMBER
Definition c.h:490
#define FirstCommandId
Definition c.h:692
uint32 LocalTransactionId
Definition c.h:678
uint32 CommandId
Definition c.h:690
uint32 TransactionId
Definition c.h:676
size_t Size
Definition c.h:629
void AtEOXact_ComboCid(void)
Definition combocid.c:182
void TransactionTreeSetCommitTsData(TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz timestamp, RepOriginId nodeid)
Definition commit_ts.c:139
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
int errmsg_internal(const char *fmt,...)
Definition elog.c:1170
bool message_level_is_interesting(int elevel)
Definition elog.c:273
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define FATAL
Definition elog.h:41
#define WARNING
Definition elog.h:36
#define PANIC
Definition elog.h:42
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
#define DEBUG5
Definition elog.h:26
void AtEOXact_Files(bool isCommit)
Definition fd.c:3210
void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition fd.c:3177
#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:2110
void AtStart_GUC(void)
Definition guc.c:2090
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition guc.c:2137
double log_xact_sample_rate
Definition guc_tables.c:548
const char * str
#define IsParallelWorker()
Definition parallel.h:60
void ResetReindexState(int nestLevel)
Definition index.c:4211
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:1165
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:4620
void AtPrepare_Locks(void)
Definition lock.c:3476
#define InvalidLocalTransactionId
Definition lock.h:67
void ResetLogicalStreamingState(void)
Definition logical.c:1933
void AtEOXact_LogicalCtl(void)
Definition logicalctl.c:235
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1176
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1793
void LWLockReleaseAll(void)
Definition lwlock.c:1892
@ 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:1600
#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:612
Oid GetUserId(void)
Definition miscinit.c:469
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition miscinit.c:619
void PostPrepare_MultiXact(FullTransactionId fxid)
Definition multixact.c:1610
void AtPrepare_MultiXact(void)
Definition multixact.c:1596
void AtEOXact_MultiXact(void)
Definition multixact.c:1568
void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition namespace.c:4628
void AtEOXact_Namespace(bool isCommit, bool parallel)
Definition namespace.c:4582
TimestampTz replorigin_session_origin_timestamp
Definition origin.c:168
void replorigin_session_advance(XLogRecPtr remote_commit, XLogRecPtr local_commit)
Definition origin.c:1308
RepOriginId replorigin_session_origin
Definition origin.c:166
void replorigin_advance(RepOriginId node, XLogRecPtr remote_commit, XLogRecPtr local_commit, bool go_backward, bool wal_log)
Definition origin.c:916
XLogRecPtr replorigin_session_origin_lsn
Definition origin.c:167
#define DoNotReplicateId
Definition origin.h:34
#define InvalidRepOriginId
Definition origin.h:33
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
void * arg
void AtEOXact_Enum(void)
Definition pg_enum.c: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:781
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition portalmem.c:980
bool PreCommit_Portals(bool isPrepare)
Definition portalmem.c:677
void AtSubCommit_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, int parentLevel, ResourceOwner parentXactOwner)
Definition portalmem.c:944
void AtCleanup_Portals(void)
Definition portalmem.c:859
void AtSubCleanup_Portals(SubTransactionId mySubid)
Definition portalmem.c:1093
unsigned int Oid
void PreCommit_CheckForSerializationFailure(void)
Definition predicate.c:4701
void PostPrepare_PredicateLocks(FullTransactionId fxid)
Definition predicate.c:4857
void AtPrepare_PredicateLocks(void)
Definition predicate.c:4788
void RegisterPredicateLockingXid(TransactionId xid)
Definition predicate.c:1957
static int fb(int x)
#define DELAY_CHKPT_IN_COMMIT
Definition proc.h:137
#define PGPROC_MAX_CACHED_SUBXIDS
Definition proc.h:39
void XidCacheRemoveRunningXids(TransactionId xid, int nxids, const TransactionId *xids, TransactionId latestXid)
Definition procarray.c:3970
void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
Definition procarray.c:669
void RecordKnownAssignedTransactionIds(TransactionId xid)
Definition procarray.c:4382
void ProcArrayClearTransaction(PGPROC *proc)
Definition procarray.c:909
void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)
Definition procarray.c:1320
void ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids, TransactionId *subxids, TransactionId max_xid)
Definition procarray.c:4451
void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition relcache.c:3373
void AtEOXact_RelationCache(bool isCommit)
Definition relcache.c:3221
void AtPrepare_RelationMap(void)
Definition relmapper.c:588
void AtEOXact_RelationMap(bool isCommit, bool isParallelWorker)
Definition relmapper.c:541
void AtCCI_RelationMap(void)
Definition relmapper.c:504
ResourceOwner TopTransactionResourceOwner
Definition resowner.c:175
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition resowner.c: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:495
Size mul_size(Size s1, Size s2)
Definition shmem.c:510
LocalTransactionId GetNextLocalTransactionId(void)
Definition sinvaladt.c:701
void AtEOXact_SMgr(void)
Definition smgr.c:1017
void SnapBuildResetExportedSnapshotState(void)
Definition snapbuild.c:626
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:482
bool SPI_inside_nonatomic_context(void)
Definition spi.c:581
void AtEOXact_SPI(bool isCommit)
Definition spi.c:428
PGPROC * MyProc
Definition proc.c:67
int TransactionTimeout
Definition proc.c:62
void LockErrorCleanup(void)
Definition proc.c:818
bool stack_is_too_deep(void)
void StandbyReleaseLockTree(TransactionId xid, int nsubxids, TransactionId *subxids)
Definition standby.c:1092
void LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInitFileInval)
Definition standby.c:1471
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:217
ProcNumber procNumber
Definition proc.h:212
struct PGPROC::@131 vxid
int delayChkptFlags
Definition proc.h:263
FullTransactionId currentFullTransactionId
Definition xact.c:233
FullTransactionId topFullTransactionId
Definition xact.c:232
CommandId currentCommandId
Definition xact.c:234
TransactionId parallelCurrentXids[FLEXIBLE_ARRAY_MEMBER]
Definition xact.c:236
struct SubXactCallbackItem * next
Definition xact.c:323
SubXactCallback callback
Definition xact.c:324
TransState state
Definition xact.c:200
SubTransactionId subTransactionId
Definition xact.c:197
FullTransactionId fullTransactionId
Definition xact.c:196
struct TransactionStateData * parent
Definition xact.c:219
MemoryContext priorContext
Definition xact.c:206
bool parallelChildXact
Definition xact.c:216
MemoryContext curTransactionContext
Definition xact.c:204
TBlockState blockState
Definition xact.c:201
bool prevXactReadOnly
Definition xact.c:212
TransactionId * childXids
Definition xact.c:207
bool startedInRecovery
Definition xact.c:213
ResourceOwner curTransactionOwner
Definition xact.c:205
LocalTransactionId localTransactionId
Definition lock.h:64
ProcNumber procNumber
Definition lock.h:63
XLogRecPtr EndRecPtr
Definition xlogreader.h:206
XLogRecPtr ReadRecPtr
Definition xlogreader.h:205
struct XactCallbackItem * next
Definition xact.c:311
void * arg
Definition xact.c:313
XactCallback callback
Definition xact.c:312
TransactionId xtop
Definition xact.h:221
void SubTransSetParent(TransactionId xid, TransactionId parent)
Definition subtrans.c:84
void SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
Definition syncrep.c:148
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:5083
void AfterTriggerEndSubXact(bool isCommit)
Definition trigger.c:5438
void AfterTriggerFireDeferred(void)
Definition trigger.c:5286
void AfterTriggerEndXact(bool isCommit)
Definition trigger.c:5342
void AfterTriggerBeginSubXact(void)
Definition trigger.c:5390
GlobalTransaction MarkAsPreparing(FullTransactionId fxid, const char *gid, TimestampTz prepared_at, Oid owner, Oid databaseid)
Definition twophase.c:361
void AtAbort_Twophase(void)
Definition twophase.c:306
void PrepareRedoRemove(TransactionId xid, bool giveWarning)
Definition twophase.c:2664
void EndPrepare(GlobalTransaction gxact)
Definition twophase.c:1145
void StartPrepare(GlobalTransaction gxact)
Definition twophase.c:1052
void PostPrepare_Twophase(void)
Definition twophase.c:346
void PrepareRedoAdd(FullTransactionId fxid, char *buf, XLogRecPtr start_lsn, XLogRecPtr end_lsn, RepOriginId origin_id)
Definition twophase.c:2507
void AtEOXact_TypeCache(void)
Definition typcache.c:3191
void AtEOSubXact_TypeCache(void)
Definition typcache.c:3197
void AdvanceNextFullTransactionIdPastXid(TransactionId xid)
Definition varsup.c:304
FullTransactionId GetNewTransactionId(bool isSubXact)
Definition varsup.c:77
static void pgstat_report_wait_end(void)
Definition wait_event.h:85
const char * name
static bool CommitTransactionCommandInternal(void)
Definition xact.c:3196
bool IsTransactionOrTransactionBlock(void)
Definition xact.c:5011
void SerializeTransactionState(Size maxsize, char *start_address)
Definition xact.c:5562
void ExitParallelMode(void)
Definition xact.c:1065
static TimestampTz xactStartTimestamp
Definition xact.c:281
static bool currentCommandIdUsed
Definition xact.c:269
static void AtSubCommit_Memory(void)
Definition xact.c:1648
void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
Definition xact.c:3157
static void CleanupSubTransaction(void)
Definition xact.c:5405
void BeginInternalSubTransaction(const char *name)
Definition xact.c:4716
static void AtStart_Memory(void)
Definition xact.c:1177
FullTransactionId GetCurrentFullTransactionId(void)
Definition xact.c:513
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition xact.c:3165
static XactCallbackItem * Xact_callbacks
Definition xact.c:316
void WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
Definition xact.c:3732
static TimestampTz stmtStartTimestamp
Definition xact.c:282
SubTransactionId GetCurrentSubTransactionId(void)
Definition xact.c:792
int synchronous_commit
Definition xact.c:88
void UserAbortTransactionBlock(bool chain)
Definition xact.c:4226
bool IsInTransactionBlock(bool isTopLevel)
Definition xact.c:3791
bool PrepareTransactionBlock(const char *gid)
Definition xact.c:4014
static void AtSubCleanup_Memory(void)
Definition xact.c:2035
static void StartTransaction(void)
Definition xact.c:2077
int GetCurrentTransactionNestLevel(void)
Definition xact.c:930
void xact_redo(XLogReaderState *record)
Definition xact.c:6385
TransactionId GetTopTransactionId(void)
Definition xact.c:427
static void AtSubCommit_childXids(void)
Definition xact.c:1677
static void CallSubXactCallbacks(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition xact.c:3920
void EnterParallelMode(void)
Definition xact.c:1052
static void AtAbort_ResourceOwner(void)
Definition xact.c:1929
TransactionId GetStableLatestTransactionId(void)
Definition xact.c:608
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition xact.c:3747
void UnregisterSubXactCallback(SubXactCallback callback, void *arg)
Definition xact.c:3899
bool XactDeferrable
Definition xact.c:86
static bool forceSyncCommit
Definition xact.c:294
void BeginImplicitTransactionBlock(void)
Definition xact.c:4348
static void CallXactCallbacks(XactEvent event)
Definition xact.c:3860
static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS]
Definition xact.c:259
static void xact_redo_commit(xl_xact_parsed_commit *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition xact.c:6152
void RequireTransactionBlock(bool isTopLevel, const char *stmtType)
Definition xact.c:3738
static void AtSubAbort_Memory(void)
Definition xact.c:1917
static SubXactCallbackItem * SubXact_callbacks
Definition xact.c:328
void DefineSavepoint(const char *name)
Definition xact.c:4395
bool DefaultXactDeferrable
Definition xact.c:85
static void CleanupTransaction(void)
Definition xact.c:3030
static int nUnreportedXids
Definition xact.c:258
static const char * TransStateAsString(TransState state)
Definition xact.c:5782
static TimestampTz xactStopTimestamp
Definition xact.c:283
bool TransactionStartedDuringRecovery(void)
Definition xact.c:1043
static void CommitSubTransaction(void)
Definition xact.c:5126
bool XactReadOnly
Definition xact.c:83
static void PushTransaction(void)
Definition xact.c:5438
bool bsysscan
Definition xact.c:101
TransactionId CheckXidAlive
Definition xact.c:100
static TransactionId RecordTransactionCommit(void)
Definition xact.c:1316
static char * prepareGID
Definition xact.c:289
void UnregisterXactCallback(XactCallback callback, void *arg)
Definition xact.c:3839
bool IsTransactionState(void)
Definition xact.c:388
static MemoryContext TransactionAbortContext
Definition xact.c:304
void CommandCounterIncrement(void)
Definition xact.c:1101
TransState
Definition xact.c:143
@ TRANS_INPROGRESS
Definition xact.c:146
@ TRANS_START
Definition xact.c:145
@ TRANS_COMMIT
Definition xact.c:147
@ TRANS_ABORT
Definition xact.c:148
@ TRANS_DEFAULT
Definition xact.c:144
@ TRANS_PREPARE
Definition xact.c:149
void PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
Definition xact.c:3669
static void AtCleanup_Memory(void)
Definition xact.c:1987
Size EstimateTransactionStateSpace(void)
Definition xact.c:5534
TransactionStateData * TransactionState
Definition xact.c:222
static void AtSubAbort_childXids(void)
Definition xact.c:1955
TransactionId GetTopTransactionIdIfAny(void)
Definition xact.c:442
static bool AbortCurrentTransactionInternal(void)
Definition xact.c:3490
static SubTransactionId currentSubTransactionId
Definition xact.c:267
static void AssignTransactionId(TransactionState s)
Definition xact.c:636
static void xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition xact.c:6306
char TransactionBlockStatusCode(void)
Definition xact.c:5025
void RollbackAndReleaseCurrentSubTransaction(void)
Definition xact.c:4818
static int nParallelCurrentXids
Definition xact.c:127
FullTransactionId GetCurrentFullTransactionIdIfAny(void)
Definition xact.c:531
static void CommitTransaction(void)
Definition xact.c:2241
void StartTransactionCommand(void)
Definition xact.c:3080
static void PopTransaction(void)
Definition xact.c:5500
bool IsAbortedTransactionBlockState(void)
Definition xact.c:408
void ReleaseCurrentSubTransaction(void)
Definition xact.c:4790
void EndImplicitTransactionBlock(void)
Definition xact.c:4373
void StartParallelWorkerTransaction(char *tstatespace)
Definition xact.c:5633
void SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts)
Definition xact.c:860
static void AtSubAbort_ResourceOwner(void)
Definition xact.c:1942
void ReleaseSavepoint(const char *name)
Definition xact.c:4480
static TransactionStateData TopTransactionStateData
Definition xact.c:248
static FullTransactionId XactTopFullTransactionId
Definition xact.c:126
static void ShowTransactionState(const char *str)
Definition xact.c:5670
int XactIsoLevel
Definition xact.c:80
static void PrepareTransaction(void)
Definition xact.c:2529
FullTransactionId GetTopFullTransactionId(void)
Definition xact.c:484
static CommandId currentCommandId
Definition xact.c:268
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:5836
void ForceSyncCommit(void)
Definition xact.c:1153
static TransactionId RecordTransactionAbort(bool isSubXact)
Definition xact.c:1767
static void AtCommit_Memory(void)
Definition xact.c:1611
static void AbortSubTransaction(void)
Definition xact.c:5241
bool IsSubTransaction(void)
Definition xact.c:5066
void MarkSubxactTopXidLogged(void)
Definition xact.c:592
void SetCurrentStatementStartTimestamp(void)
Definition xact.c:915
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition xact.c:942
bool IsTransactionBlock(void)
Definition xact.c:4993
bool IsInParallelMode(void)
Definition xact.c:1090
int xactGetCommittedChildren(TransactionId **ptr)
Definition xact.c:5812
TransactionId GetCurrentTransactionIdIfAny(void)
Definition xact.c:472
void BeginTransactionBlock(void)
Definition xact.c:3946
static void AtStart_ResourceOwner(void)
Definition xact.c:1227
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition xact.c:880
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition xact.c:871
static const char * BlockStateAsString(TBlockState blockState)
Definition xact.c:5729
void EndParallelWorkerTransaction(void)
Definition xact.c:5658
static void AtAbort_Memory(void)
Definition xact.c:1897
void RegisterXactCallback(XactCallback callback, void *arg)
Definition xact.c:3826
void CommitTransactionCommand(void)
Definition xact.c:3178
void RollbackToSavepoint(const char *name)
Definition xact.c:4589
bool SubTransactionIsActive(SubTransactionId subxid)
Definition xact.c:806
TBlockState
Definition xact.c:159
@ TBLOCK_DEFAULT
Definition xact.c:161
@ TBLOCK_SUBABORT_END
Definition xact.c:181
@ TBLOCK_STARTED
Definition xact.c:162
@ TBLOCK_SUBCOMMIT
Definition xact.c:179
@ TBLOCK_IMPLICIT_INPROGRESS
Definition xact.c:167
@ TBLOCK_ABORT_END
Definition xact.c:171
@ TBLOCK_PREPARE
Definition xact.c:173
@ TBLOCK_ABORT_PENDING
Definition xact.c:172
@ TBLOCK_ABORT
Definition xact.c:170
@ TBLOCK_SUBRELEASE
Definition xact.c:178
@ TBLOCK_SUBBEGIN
Definition xact.c:176
@ TBLOCK_SUBABORT
Definition xact.c:180
@ TBLOCK_SUBRESTART
Definition xact.c:183
@ TBLOCK_INPROGRESS
Definition xact.c:166
@ TBLOCK_END
Definition xact.c:169
@ TBLOCK_PARALLEL_INPROGRESS
Definition xact.c:168
@ TBLOCK_SUBABORT_RESTART
Definition xact.c:184
@ TBLOCK_SUBABORT_PENDING
Definition xact.c:182
@ TBLOCK_BEGIN
Definition xact.c:165
@ TBLOCK_SUBINPROGRESS
Definition xact.c:177
void RegisterSubXactCallback(SubXactCallback callback, void *arg)
Definition xact.c:3886
FullTransactionId GetTopFullTransactionIdIfAny(void)
Definition xact.c:500
TransactionId GetCurrentTransactionId(void)
Definition xact.c:455
static void AbortTransaction(void)
Definition xact.c:2824
static void AtStart_Cache(void)
Definition xact.c:1168
static void AtSubStart_ResourceOwner(void)
Definition xact.c:1284
int DefaultXactIsoLevel
Definition xact.c:79
static void AtSubStart_Memory(void)
Definition xact.c:1255
bool xact_is_sampled
Definition xact.c:297
bool EndTransactionBlock(bool chain)
Definition xact.c:4066
bool IsSubxactTopXidLogPending(void)
Definition xact.c:560
#define SerializedTransactionStateHeaderSize
Definition xact.c:240
void AbortOutOfAnyTransaction(void)
Definition xact.c:4884
int MyXactFlags
Definition xact.c:137
static void ShowTransactionStateRec(const char *str, TransactionState s)
Definition xact.c:5682
static TransactionState CurrentTransactionState
Definition xact.c:261
void AbortCurrentTransaction(void)
Definition xact.c:3472
static void StartSubTransaction(void)
Definition xact.c:5089
static TransactionId * ParallelCurrentXids
Definition xact.c:128
bool DefaultXactReadOnly
Definition xact.c:82
TimestampTz GetCurrentTransactionStopTimestamp(void)
Definition xact.c:892
static void AtCCI_LocalCache(void)
Definition xact.c:1592
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:6008
void MarkCurrentTransactionIdLoggedIfAny(void)
Definition xact.c:542
CommandId GetCurrentCommandId(bool used)
Definition xact.c:830
#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:6461
XLogRecPtr XactLastRecEnd
Definition xlog.c:257
XLogRecPtr XactLastCommitEnd
Definition xlog.c:258
void XLogFlush(XLogRecPtr record)
Definition xlog.c:2784
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition xlog.c:2613
#define XLogLogicalInfoActive()
Definition xlog.h:136
#define XLOG_INCLUDE_ORIGIN
Definition xlog.h:165
#define XLogStandbyInfoActive()
Definition xlog.h:125
uint16 RepOriginId
Definition xlogdefs.h:69
uint64 XLogRecPtr
Definition xlogdefs.h:21
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition xloginsert.c:478
void XLogRegisterData(const void *data, uint32 len)
Definition xloginsert.c:368
void XLogSetRecordFlags(uint8 flags)
Definition xloginsert.c:460
void XLogResetInsertion(void)
Definition xloginsert.c:225
void XLogBeginInsert(void)
Definition xloginsert.c:152
#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:338