PostgreSQL Source Code git master
xact.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * xact.c
4 * top level transaction system support routines
5 *
6 * See src/backend/access/transam/README for more information.
7 *
8 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
10 *
11 *
12 * IDENTIFICATION
13 * src/backend/access/transam/xact.c
14 *
15 *-------------------------------------------------------------------------
16 */
17
18#include "postgres.h"
19
20#include <time.h>
21#include <unistd.h>
22
23#include "access/commit_ts.h"
24#include "access/multixact.h"
25#include "access/parallel.h"
26#include "access/subtrans.h"
27#include "access/transam.h"
28#include "access/twophase.h"
29#include "access/xact.h"
30#include "access/xlog.h"
31#include "access/xloginsert.h"
32#include "access/xlogrecovery.h"
33#include "access/xlogutils.h"
34#include "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 */
229{
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 */
309typedef struct XactCallbackItem
310{
313 void *arg;
315
317
318/*
319 * List of add-on start- and end-of-subxact callbacks
320 */
322{
325 void *arg;
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,
344 SubTransactionId mySubid,
345 SubTransactionId parentSubid);
346static void CleanupTransaction(void);
347static void CheckTransactionBlock(bool isTopLevel, bool throwError,
348 const char *stmtType);
349static void CommitTransaction(void);
350static TransactionId RecordTransactionAbort(bool isSubXact);
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 */
428{
432}
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 */
443{
445}
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 */
456{
458
462}
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 */
473{
475}
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 */
485{
489}
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 */
501{
503}
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 */
514{
516
519 return s->fullTransactionId;
520}
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 */
532{
534}
535
536/*
537 * MarkCurrentTransactionIdLoggedIfAny
538 *
539 * Remember that the current xid - if it is assigned - now has been wal logged.
540 */
541void
543{
546}
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 wal_level >= logical and we are inside a valid
556 * subtransaction, for which the assignment was not yet written to any WAL
557 * record.
558 */
559bool
561{
562 /* check whether it is already logged */
564 return false;
565
566 /* 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
593{
595
597}
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 */
609{
611 static TransactionId stablexid = InvalidTransactionId;
612
613 if (lxid != MyProc->vxid.lxid)
614 {
615 lxid = MyProc->vxid.lxid;
616 stablexid = GetTopTransactionIdIfAny();
617 if (!TransactionIdIsValid(stablexid))
618 stablexid = ReadNextTransactionId();
619 }
620
621 Assert(TransactionIdIsValid(stablexid));
622
623 return stablexid;
624}
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);
639 ResourceOwner currentOwner;
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 */
652 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
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
667 parents = palloc(sizeof(TransactionState) * s->nestingLevel);
668 while (p != NULL && !FullTransactionIdIsValid(p->fullTransactionId))
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 wal_level=logical, guarantee that a subtransaction's xid can only
686 * be seen in the WAL stream if its toplevel xid has been logged before.
687 * If necessary we log an xact_assignment record with fewer than
688 * PGPROC_MAX_CACHED_SUBXIDS. Note that it is fine if didLogXid isn't set
689 * for a transaction even though it appears in a WAL record, we just might
690 * superfluously log something. That can happen when an xid is included
691 * somewhere inside a wal record, but not in XLogRecord->xl_xid, like in
692 * xl_standby_locks.
693 */
694 if (isSubXact && XLogLogicalInfoActive() &&
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 */
727 currentOwner = CurrentResourceOwner;
729
731
732 CurrentResourceOwner = currentOwner;
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 */
752 if (isSubXact && XLogStandbyInfoActive())
753 {
756
757 /*
758 * ensure this test matches similar one in
759 * RecoverPreparedTransactions()
760 */
762 log_unknown_top)
763 {
764 xl_xact_assignment xlrec;
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 */
770 xlrec.xtop = GetTopTransactionId();
773
778
779 (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT);
780
781 nUnreportedXids = 0;
782 /* mark top, not current xact as having been logged */
784 }
785 }
786}
787
788/*
789 * GetCurrentSubTransactionId
790 */
793{
795
796 return s->subTransactionId;
797}
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())
843 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
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
861{
863 xactStartTimestamp = xact_ts;
864 stmtStartTimestamp = stmt_ts;
865}
866
867/*
868 * GetCurrentTransactionStartTimestamp
869 */
872{
873 return xactStartTimestamp;
874}
875
876/*
877 * GetCurrentStatementStartTimestamp
878 */
881{
882 return stmtStartTimestamp;
883}
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
916{
917 if (!IsParallelWorker())
919 else
921}
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
931{
933
934 return s->nestingLevel;
935}
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;
981 TransactionId probe;
982
983 middle = low + (high - low) / 2;
984 probe = ParallelCurrentXids[middle];
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;
1019 TransactionId probe;
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
1044{
1046}
1047
1048/*
1049 * EnterParallelMode
1050 */
1051void
1053{
1055
1056 Assert(s->parallelModeLevel >= 0);
1057
1058 ++s->parallelModeLevel;
1059}
1060
1061/*
1062 * ExitParallelMode
1063 */
1064void
1066{
1068
1069 Assert(s->parallelModeLevel > 0);
1072
1073 --s->parallelModeLevel;
1074}
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,
1118 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
1119 errmsg("cannot start commands during a parallel operation")));
1120
1121 currentCommandId += 1;
1123 {
1124 currentCommandId -= 1;
1125 ereport(ERROR,
1126 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
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
1169{
1171}
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 */
1193 if (TransactionAbortContext == NULL)
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 */
1206 if (TopTransactionContext == NULL)
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{
1319 bool markXidCommitted = TransactionIdIsValid(xid);
1321 int nrels;
1322 RelFileLocator *rels;
1323 int nchildren;
1324 TransactionId *children;
1325 int ndroppedstats = 0;
1326 xl_xact_stats_item *droppedstats = NULL;
1327 int nmsgs = 0;
1328 SharedInvalidationMessage *invalMessages = NULL;
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);
1344 nchildren = xactGetCommittedChildren(&children);
1345 ndroppedstats = pgstat_get_transactional_drops(true, &droppedstats);
1347 nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
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 {
1394 LogStandbyInvalidations(nmsgs, invalMessages,
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,
1457 ndroppedstats, droppedstats,
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
1478 if (!replorigin || replorigin_session_origin_timestamp == 0)
1480
1481 TransactionTreeSetCommitTsData(xid, nchildren, children,
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)
1544 TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1545 }
1546
1547 /*
1548 * If we entered a commit critical section, leave it now, and let
1549 * checkpoints proceed.
1550 */
1551 if (markXidCommitted)
1552 {
1553 MyProc->delayChkptFlags &= ~DELAY_CHKPT_IN_COMMIT;
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 */
1569 if (wrote_xlog && markXidCommitted)
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)
1582 pfree(droppedstats);
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 */
1635 CurTransactionContext = NULL;
1636 s->curTransactionContext = NULL;
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 {
1667 s->curTransactionContext = NULL;
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 */
1688 new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1689
1690 /* Allocate or enlarge the parent array if necessary */
1691 if (s->parent->maxChildXids < new_nChildXids)
1692 {
1693 int new_maxChildXids;
1694 TransactionId *new_childXids;
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 */
1702 new_maxChildXids = Min(new_nChildXids * 2,
1703 (int) (MaxAllocSize / sizeof(TransactionId)));
1704
1705 if (new_maxChildXids < new_nChildXids)
1706 ereport(ERROR,
1707 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
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)
1717 new_childXids =
1719 new_maxChildXids * sizeof(TransactionId));
1720 else
1721 new_childXids = repalloc(s->parent->childXids,
1722 new_maxChildXids * sizeof(TransactionId));
1723
1724 s->parent->childXids = new_childXids;
1725 s->parent->maxChildXids = new_maxChildXids;
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
1744 s->parent->nChildXids = new_nChildXids;
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{
1770 TransactionId latestXid;
1771 int nrels;
1772 RelFileLocator *rels;
1773 int ndroppedstats = 0;
1774 xl_xact_stats_item *droppedstats = NULL;
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);
1818 nchildren = xactGetCommittedChildren(&children);
1819 ndroppedstats = pgstat_get_transactional_drops(false, &droppedstats);
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,
1835 ndroppedstats, droppedstats,
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)
1878 XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
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)
1888 pfree(droppedstats);
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 */
1907 if (TransactionAbortContext != NULL)
1909 else
1911}
1912
1913/*
1914 * AtSubAbort_Memory
1915 */
1916static void
1918{
1920
1922}
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 */
2005 if (TransactionAbortContext != NULL)
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 */
2013 if (TopTransactionContext != NULL)
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 */
2021 CurTransactionContext = NULL;
2022 s->curTransactionContext = NULL;
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 */
2055 if (TransactionAbortContext != NULL)
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)
2065 s->curTransactionContext = NULL;
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
2190 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
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{
2244 TransactionId latestXid;
2245 bool is_parallel_worker;
2246
2247 is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2248
2249 /* Enforce parallel mode restrictions during parallel worker commit. */
2250 if (is_parallel_worker)
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);
2304 if (is_parallel_worker)
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 */
2331 smgrDoPendingSyncs(true, is_parallel_worker);
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 */
2358 AtEOXact_RelationMap(true, is_parallel_worker);
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 */
2378 latestXid = RecordTransactionCommit();
2379 }
2380 else
2381 {
2382 /*
2383 * We must not mark our XID committed; the parallel leader is
2384 * responsible for that.
2385 */
2386 latestXid = InvalidTransactionId;
2387
2388 /*
2389 * Make sure the leader will know about any WAL we wrote before it
2390 * commits.
2391 */
2393 }
2394
2395 TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->vxid.lxid);
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 */
2402 ProcArrayEndTransaction(MyProc, latestXid);
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
2423 CurrentResourceOwner = NULL;
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();
2483 AtEOXact_Namespace(true, is_parallel_worker);
2484 AtEOXact_SMgr();
2485 AtEOXact_Files(true);
2487 AtEOXact_HashTables(true);
2488 AtEOXact_PgStat(true, is_parallel_worker);
2489 AtEOXact_Snapshot(true, false);
2493
2495 s->curTransactionOwner = NULL;
2498
2500
2503 s->nestingLevel = 0;
2504 s->gucNestLevel = 0;
2505 s->childXids = NULL;
2506 s->nChildXids = 0;
2507 s->maxChildXids = 0;
2508
2511
2512 /*
2513 * done with commit processing, set current transaction state back to
2514 * default
2515 */
2516 s->state = TRANS_DEFAULT;
2517
2519}
2520
2521
2522/*
2523 * PrepareTransaction
2524 *
2525 * NB: if you change this routine, better look at CommitTransaction too!
2526 */
2527static void
2529{
2532 GlobalTransaction gxact;
2533 TimestampTz prepared_at;
2534
2536
2537 ShowTransactionState("PrepareTransaction");
2538
2539 /*
2540 * check the current transaction state
2541 */
2542 if (s->state != TRANS_INPROGRESS)
2543 elog(WARNING, "PrepareTransaction while in %s state",
2545 Assert(s->parent == NULL);
2546
2547 /*
2548 * Do pre-commit processing that involves calling user-defined code, such
2549 * as triggers. Since closing cursors could queue trigger actions,
2550 * triggers could open cursors, etc, we have to keep looping until there's
2551 * nothing left to do.
2552 */
2553 for (;;)
2554 {
2555 /*
2556 * Fire all currently pending deferred triggers.
2557 */
2559
2560 /*
2561 * Close open portals (converting holdable ones into static portals).
2562 * If there weren't any, we are done ... otherwise loop back to check
2563 * if they queued deferred triggers. Lather, rinse, repeat.
2564 */
2565 if (!PreCommit_Portals(true))
2566 break;
2567 }
2568
2570
2571 /*
2572 * The remaining actions cannot call any user-defined code, so it's safe
2573 * to start shutting down within-transaction services. But note that most
2574 * of this stuff could still throw an error, which would switch us into
2575 * the transaction-abort path.
2576 */
2577
2578 /* Shut down the deferred-trigger manager */
2579 AfterTriggerEndXact(true);
2580
2581 /*
2582 * Let ON COMMIT management do its thing (must happen after closing
2583 * cursors, to avoid dangling-reference problems)
2584 */
2586
2587 /*
2588 * Synchronize files that are created and not WAL-logged during this
2589 * transaction. This must happen before EndPrepare(), so that we don't see
2590 * committed-but-broken files after a crash and COMMIT PREPARED.
2591 */
2592 smgrDoPendingSyncs(true, false);
2593
2594 /* close large objects before lower-level cleanup */
2596
2597 /* NOTIFY requires no work at this point */
2598
2599 /*
2600 * Mark serializable transaction as complete for predicate locking
2601 * purposes. This should be done as late as we can put it and still allow
2602 * errors to be raised for failure patterns found at commit.
2603 */
2605
2606 /*
2607 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2608 * this transaction. Having the prepared xact hold locks on another
2609 * backend's temp table seems a bad idea --- for instance it would prevent
2610 * the backend from exiting. There are other problems too, such as how to
2611 * clean up the source backend's local buffers and ON COMMIT state if the
2612 * prepared xact includes a DROP of a temp table.
2613 *
2614 * Other objects types, like functions, operators or extensions, share the
2615 * same restriction as they should not be created, locked or dropped as
2616 * this can mess up with this session or even a follow-up session trying
2617 * to use the same temporary namespace.
2618 *
2619 * We must check this after executing any ON COMMIT actions, because they
2620 * might still access a temp relation.
2621 *
2622 * XXX In principle this could be relaxed to allow some useful special
2623 * cases, such as a temp table created and dropped all within the
2624 * transaction. That seems to require much more bookkeeping though.
2625 */
2627 ereport(ERROR,
2628 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2629 errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2630
2631 /*
2632 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2633 * supported if we added cleanup logic to twophase.c, but for now it
2634 * doesn't seem worth the trouble.
2635 */
2637 ereport(ERROR,
2638 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2639 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2640
2641 /* Prevent cancel/die interrupt while cleaning up */
2643
2644 /*
2645 * set the current transaction state information appropriately during
2646 * prepare processing
2647 */
2648 s->state = TRANS_PREPARE;
2649
2650 /* Disable transaction timeout */
2651 if (TransactionTimeout > 0)
2653
2654 prepared_at = GetCurrentTimestamp();
2655
2656 /*
2657 * Reserve the GID for this transaction. This could fail if the requested
2658 * GID is invalid or already in use.
2659 */
2660 gxact = MarkAsPreparing(fxid, prepareGID, prepared_at,
2662 prepareGID = NULL;
2663
2664 /*
2665 * Collect data for the 2PC state file. Note that in general, no actual
2666 * state change should happen in the called modules during this step,
2667 * since it's still possible to fail before commit, and in that case we
2668 * want transaction abort to be able to clean up. (In particular, the
2669 * AtPrepare routines may error out if they find cases they cannot
2670 * handle.) State cleanup should happen in the PostPrepare routines
2671 * below. However, some modules can go ahead and clear state here because
2672 * they wouldn't do anything with it during abort anyway.
2673 *
2674 * Note: because the 2PC state file records will be replayed in the same
2675 * order they are made, the order of these calls has to match the order in
2676 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2677 * PREPARED; in particular, pay attention to whether things should happen
2678 * before or after releasing the transaction's locks.
2679 */
2680 StartPrepare(gxact);
2681
2688
2689 /*
2690 * Here is where we really truly prepare.
2691 *
2692 * We have to record transaction prepares even if we didn't make any
2693 * updates, because the transaction manager might get confused if we lose
2694 * a global transaction.
2695 */
2696 EndPrepare(gxact);
2697
2698 /*
2699 * Now we clean up backend-internal state and release internal resources.
2700 */
2701
2702 /* Reset XactLastRecEnd until the next transaction writes something */
2703 XactLastRecEnd = 0;
2704
2705 /*
2706 * Transfer our locks to a dummy PGPROC. This has to be done before
2707 * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2708 * conclude "xact already committed or aborted" for our locks.
2709 */
2710 PostPrepare_Locks(fxid);
2711
2712 /*
2713 * Let others know about no transaction in progress by me. This has to be
2714 * done *after* the prepared transaction has been marked valid, else
2715 * someone may think it is unlocked and recyclable.
2716 */
2718
2719 /*
2720 * In normal commit-processing, this is all non-critical post-transaction
2721 * cleanup. When the transaction is prepared, however, it's important
2722 * that the locks and other per-backend resources are transferred to the
2723 * prepared transaction's PGPROC entry. Note that if an error is raised
2724 * here, it's too late to abort the transaction. XXX: This probably should
2725 * be in a critical section, to force a PANIC if any of this fails, but
2726 * that cure could be worse than the disease.
2727 */
2728
2730
2733 true, true);
2734
2735 AtEOXact_Aio(true);
2736
2737 /* Check we've released all buffer pins */
2738 AtEOXact_Buffers(true);
2739
2740 /* Clean up the relation cache */
2742
2743 /* Clean up the type cache */
2745
2746 /* notify doesn't need a postprepare call */
2747
2749
2751
2753
2755
2757
2760 true, true);
2763 true, true);
2764
2765 /*
2766 * Allow another backend to finish the transaction. After
2767 * PostPrepare_Twophase(), the transaction is completely detached from our
2768 * backend. The rest is just non-critical cleanup of backend-local state.
2769 */
2771
2772 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2773 AtEOXact_GUC(true, 1);
2774 AtEOXact_SPI(true);
2775 AtEOXact_Enum();
2777 AtEOXact_Namespace(true, false);
2778 AtEOXact_SMgr();
2779 AtEOXact_Files(true);
2781 AtEOXact_HashTables(true);
2782 /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2783 AtEOXact_Snapshot(true, true);
2784 /* we treat PREPARE as ROLLBACK so far as waking workers goes */
2788
2789 CurrentResourceOwner = NULL;
2791 s->curTransactionOwner = NULL;
2794
2796
2799 s->nestingLevel = 0;
2800 s->gucNestLevel = 0;
2801 s->childXids = NULL;
2802 s->nChildXids = 0;
2803 s->maxChildXids = 0;
2804
2807
2808 /*
2809 * done with 1st phase commit processing, set current transaction state
2810 * back to default
2811 */
2812 s->state = TRANS_DEFAULT;
2813
2815}
2816
2817
2818/*
2819 * AbortTransaction
2820 */
2821static void
2823{
2825 TransactionId latestXid;
2826 bool is_parallel_worker;
2827
2828 /* Prevent cancel/die interrupt while cleaning up */
2830
2831 /* Disable transaction timeout */
2832 if (TransactionTimeout > 0)
2834
2835 /* Make sure we have a valid memory context and resource owner */
2838
2839 /*
2840 * Release any LW locks we might be holding as quickly as possible.
2841 * (Regular locks, however, must be held till we finish aborting.)
2842 * Releasing LW locks is critical since we might try to grab them again
2843 * while cleaning up!
2844 */
2846
2847 /*
2848 * Cleanup waiting for LSN if any.
2849 */
2851
2852 /* Clear wait information and command progress indicator */
2855
2857
2858 /* Clean up buffer content locks, too */
2859 UnlockBuffers();
2860
2861 /* Reset WAL record construction state */
2863
2864 /* Cancel condition variable sleep */
2866
2867 /*
2868 * Also clean up any open wait for lock, since the lock manager will choke
2869 * if we try to wait for another lock before doing this.
2870 */
2872
2873 /*
2874 * If any timeout events are still active, make sure the timeout interrupt
2875 * is scheduled. This covers possible loss of a timeout interrupt due to
2876 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2877 * We delay this till after LockErrorCleanup so that we don't uselessly
2878 * reschedule lock or deadlock check timeouts.
2879 */
2881
2882 /*
2883 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2884 * handler. We do this fairly early in the sequence so that the timeout
2885 * infrastructure will be functional if needed while aborting.
2886 */
2887 sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
2888
2889 /*
2890 * check the current transaction state
2891 */
2892 is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2893 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2894 elog(WARNING, "AbortTransaction while in %s state",
2896 Assert(s->parent == NULL);
2897
2898 /*
2899 * set the current transaction state information appropriately during the
2900 * abort processing
2901 */
2902 s->state = TRANS_ABORT;
2903
2904 /*
2905 * Reset user ID which might have been changed transiently. We need this
2906 * to clean up in case control escaped out of a SECURITY DEFINER function
2907 * or other local change of CurrentUserId; therefore, the prior value of
2908 * SecurityRestrictionContext also needs to be restored.
2909 *
2910 * (Note: it is not necessary to restore session authorization or role
2911 * settings here because those can only be changed via GUC, and GUC will
2912 * take care of rolling them back if need be.)
2913 */
2915
2916 /* Forget about any active REINDEX. */
2918
2919 /* Reset logical streaming state. */
2921
2922 /* Reset snapshot export state. */
2924
2925 /*
2926 * If this xact has started any unfinished parallel operation, clean up
2927 * its workers and exit parallel mode. Don't warn about leaked resources.
2928 */
2929 AtEOXact_Parallel(false);
2930 s->parallelModeLevel = 0;
2931 s->parallelChildXact = false; /* should be false already */
2932
2933 /*
2934 * do abort processing
2935 */
2936 AfterTriggerEndXact(false); /* 'false' means it's abort */
2938 smgrDoPendingSyncs(false, is_parallel_worker);
2939 AtEOXact_LargeObject(false);
2941 AtEOXact_RelationMap(false, is_parallel_worker);
2943
2944 /*
2945 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2946 * far as assigning an XID to advertise). But if we're inside a parallel
2947 * worker, skip this; the user backend must be the one to write the abort
2948 * record.
2949 */
2950 if (!is_parallel_worker)
2951 latestXid = RecordTransactionAbort(false);
2952 else
2953 {
2954 latestXid = InvalidTransactionId;
2955
2956 /*
2957 * Since the parallel leader won't get our value of XactLastRecEnd in
2958 * this case, we nudge WAL-writer ourselves in this case. See related
2959 * comments in RecordTransactionAbort for why this matters.
2960 */
2962 }
2963
2964 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->vxid.lxid);
2965
2966 /*
2967 * Let others know about no transaction in progress by me. Note that this
2968 * must be done _before_ releasing locks we hold and _after_
2969 * RecordTransactionAbort.
2970 */
2971 ProcArrayEndTransaction(MyProc, latestXid);
2972
2973 /*
2974 * Post-abort cleanup. See notes in CommitTransaction() concerning
2975 * ordering. We can skip all of it if the transaction failed before
2976 * creating a resource owner.
2977 */
2978 if (TopTransactionResourceOwner != NULL)
2979 {
2980 if (is_parallel_worker)
2982 else
2984
2987 false, true);
2988 AtEOXact_Aio(false);
2989 AtEOXact_Buffers(false);
2992 AtEOXact_Inval(false);
2996 false, true);
2999 false, true);
3000 smgrDoPendingDeletes(false);
3001
3002 AtEOXact_GUC(false, 1);
3003 AtEOXact_SPI(false);
3004 AtEOXact_Enum();
3006 AtEOXact_Namespace(false, is_parallel_worker);
3007 AtEOXact_SMgr();
3008 AtEOXact_Files(false);
3010 AtEOXact_HashTables(false);
3011 AtEOXact_PgStat(false, is_parallel_worker);
3015 }
3016
3017 /*
3018 * State remains TRANS_ABORT until CleanupTransaction().
3019 */
3021}
3022
3023/*
3024 * CleanupTransaction
3025 */
3026static void
3028{
3030
3031 /*
3032 * State should still be TRANS_ABORT from AbortTransaction().
3033 */
3034 if (s->state != TRANS_ABORT)
3035 elog(FATAL, "CleanupTransaction: unexpected state %s",
3037
3038 /*
3039 * do abort cleanup processing
3040 */
3041 AtCleanup_Portals(); /* now safe to release portal memory */
3042 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
3043
3044 CurrentResourceOwner = NULL; /* and resource owner */
3047 s->curTransactionOwner = NULL;
3050
3051 AtCleanup_Memory(); /* and transaction memory */
3052
3055 s->nestingLevel = 0;
3056 s->gucNestLevel = 0;
3057 s->childXids = NULL;
3058 s->nChildXids = 0;
3059 s->maxChildXids = 0;
3060 s->parallelModeLevel = 0;
3061 s->parallelChildXact = false;
3062
3065
3066 /*
3067 * done with abort processing, set current transaction state back to
3068 * default
3069 */
3070 s->state = TRANS_DEFAULT;
3071}
3072
3073/*
3074 * StartTransactionCommand
3075 */
3076void
3078{
3080
3081 switch (s->blockState)
3082 {
3083 /*
3084 * if we aren't in a transaction block, we just do our usual start
3085 * transaction.
3086 */
3087 case TBLOCK_DEFAULT:
3090 break;
3091
3092 /*
3093 * We are somewhere in a transaction block or subtransaction and
3094 * about to start a new command. For now we do nothing, but
3095 * someday we may do command-local resource initialization. (Note
3096 * that any needed CommandCounterIncrement was done by the
3097 * previous CommitTransactionCommand.)
3098 */
3099 case TBLOCK_INPROGRESS:
3102 break;
3103
3104 /*
3105 * Here we are in a failed transaction block (one of the commands
3106 * caused an abort) so we do nothing but remain in the abort
3107 * state. Eventually we will get a ROLLBACK command which will
3108 * get us out of this state. (It is up to other code to ensure
3109 * that no commands other than ROLLBACK will be processed in these
3110 * states.)
3111 */
3112 case TBLOCK_ABORT:
3113 case TBLOCK_SUBABORT:
3114 break;
3115
3116 /* These cases are invalid. */
3117 case TBLOCK_STARTED:
3118 case TBLOCK_BEGIN:
3120 case TBLOCK_SUBBEGIN:
3121 case TBLOCK_END:
3122 case TBLOCK_SUBRELEASE:
3123 case TBLOCK_SUBCOMMIT:
3124 case TBLOCK_ABORT_END:
3128 case TBLOCK_SUBRESTART:
3130 case TBLOCK_PREPARE:
3131 elog(ERROR, "StartTransactionCommand: unexpected state %s",
3133 break;
3134 }
3135
3136 /*
3137 * We must switch to CurTransactionContext before returning. This is
3138 * already done if we called StartTransaction, otherwise not.
3139 */
3142}
3143
3144
3145/*
3146 * Simple system for saving and restoring transaction characteristics
3147 * (isolation level, read only, deferrable). We need this for transaction
3148 * chaining, so that we can set the characteristics of the new transaction to
3149 * be the same as the previous one. (We need something like this because the
3150 * GUC system resets the characteristics at transaction end, so for example
3151 * just skipping the reset in StartTransaction() won't work.)
3152 */
3153void
3155{
3159}
3160
3161void
3163{
3167}
3168
3169/*
3170 * CommitTransactionCommand -- a wrapper function handling the
3171 * loop over subtransactions to avoid a potentially dangerous recursion
3172 * in CommitTransactionCommandInternal().
3173 */
3174void
3176{
3177 /*
3178 * Repeatedly call CommitTransactionCommandInternal() until all the work
3179 * is done.
3180 */
3182 {
3183 }
3184}
3185
3186/*
3187 * CommitTransactionCommandInternal - a function doing an iteration of work
3188 * regarding handling the commit transaction command. In the case of
3189 * subtransactions more than one iterations could be required. Returns
3190 * true when no more iterations required, false otherwise.
3191 */
3192static bool
3194{
3197
3198 /* Must save in case we need to restore below */
3200
3201 switch (s->blockState)
3202 {
3203 /*
3204 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3205 * StartTransactionCommand didn't set the STARTED state
3206 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3207 * by EndParallelWorkerTransaction(), not this function.
3208 */
3209 case TBLOCK_DEFAULT:
3211 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3213 break;
3214
3215 /*
3216 * If we aren't in a transaction block, just do our usual
3217 * transaction commit, and return to the idle state.
3218 */
3219 case TBLOCK_STARTED:
3222 break;
3223
3224 /*
3225 * We are completing a "BEGIN TRANSACTION" command, so we change
3226 * to the "transaction block in progress" state and return. (We
3227 * assume the BEGIN did nothing to the database, so we need no
3228 * CommandCounterIncrement.)
3229 */
3230 case TBLOCK_BEGIN:
3232 break;
3233
3234 /*
3235 * This is the case when we have finished executing a command
3236 * someplace within a transaction block. We increment the command
3237 * counter and return.
3238 */
3239 case TBLOCK_INPROGRESS:
3243 break;
3244
3245 /*
3246 * We are completing a "COMMIT" command. Do it and return to the
3247 * idle state.
3248 */
3249 case TBLOCK_END:
3252 if (s->chain)
3253 {
3256 s->chain = false;
3258 }
3259 break;
3260
3261 /*
3262 * Here we are in the middle of a transaction block but one of the
3263 * commands caused an abort so we do nothing but remain in the
3264 * abort state. Eventually we will get a ROLLBACK command.
3265 */
3266 case TBLOCK_ABORT:
3267 case TBLOCK_SUBABORT:
3268 break;
3269
3270 /*
3271 * Here we were in an aborted transaction block and we just got
3272 * the ROLLBACK command from the user, so clean up the
3273 * already-aborted transaction and return to the idle state.
3274 */
3275 case TBLOCK_ABORT_END:
3278 if (s->chain)
3279 {
3282 s->chain = false;
3284 }
3285 break;
3286
3287 /*
3288 * Here we were in a perfectly good transaction block but the user
3289 * told us to ROLLBACK anyway. We have to abort the transaction
3290 * and then clean up.
3291 */
3296 if (s->chain)
3297 {
3300 s->chain = false;
3302 }
3303 break;
3304
3305 /*
3306 * We are completing a "PREPARE TRANSACTION" command. Do it and
3307 * return to the idle state.
3308 */
3309 case TBLOCK_PREPARE:
3312 break;
3313
3314 /*
3315 * The user issued a SAVEPOINT inside a transaction block. Start a
3316 * subtransaction. (DefineSavepoint already did PushTransaction,
3317 * so as to have someplace to put the SUBBEGIN state.)
3318 */
3319 case TBLOCK_SUBBEGIN:
3322 break;
3323
3324 /*
3325 * The user issued a RELEASE command, so we end the current
3326 * subtransaction and return to the parent transaction. The parent
3327 * might be ended too, so repeat till we find an INPROGRESS
3328 * transaction or subtransaction.
3329 */
3330 case TBLOCK_SUBRELEASE:
3331 do
3332 {
3334 s = CurrentTransactionState; /* changed by pop */
3335 } while (s->blockState == TBLOCK_SUBRELEASE);
3336
3339 break;
3340
3341 /*
3342 * The user issued a COMMIT, so we end the current subtransaction
3343 * hierarchy and perform final commit. We do this by rolling up
3344 * any subtransactions into their parent, which leads to O(N^2)
3345 * operations with respect to resource owners - this isn't that
3346 * bad until we approach a thousands of savepoints but is
3347 * necessary for correctness should after triggers create new
3348 * resource owners.
3349 */
3350 case TBLOCK_SUBCOMMIT:
3351 do
3352 {
3354 s = CurrentTransactionState; /* changed by pop */
3355 } while (s->blockState == TBLOCK_SUBCOMMIT);
3356 /* If we had a COMMIT command, finish off the main xact too */
3357 if (s->blockState == TBLOCK_END)
3358 {
3359 Assert(s->parent == NULL);
3362 if (s->chain)
3363 {
3366 s->chain = false;
3368 }
3369 }
3370 else if (s->blockState == TBLOCK_PREPARE)
3371 {
3372 Assert(s->parent == NULL);
3375 }
3376 else
3377 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3379 break;
3380
3381 /*
3382 * The current already-failed subtransaction is ending due to a
3383 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3384 * examine the parent (which could be in any of several states).
3385 * As we need to examine the parent, return false to request the
3386 * caller to do the next iteration.
3387 */
3390 return false;
3391
3392 /*
3393 * As above, but it's not dead yet, so abort first.
3394 */
3398 return false;
3399
3400 /*
3401 * The current subtransaction is the target of a ROLLBACK TO
3402 * command. Abort and pop it, then start a new subtransaction
3403 * with the same name.
3404 */
3405 case TBLOCK_SUBRESTART:
3406 {
3407 char *name;
3408 int savepointLevel;
3409
3410 /* save name and keep Cleanup from freeing it */
3411 name = s->name;
3412 s->name = NULL;
3413 savepointLevel = s->savepointLevel;
3414
3417
3418 DefineSavepoint(NULL);
3419 s = CurrentTransactionState; /* changed by push */
3420 s->name = name;
3421 s->savepointLevel = savepointLevel;
3422
3423 /* This is the same as TBLOCK_SUBBEGIN case */
3427 }
3428 break;
3429
3430 /*
3431 * Same as above, but the subtransaction had already failed, so we
3432 * don't need AbortSubTransaction.
3433 */
3435 {
3436 char *name;
3437 int savepointLevel;
3438
3439 /* save name and keep Cleanup from freeing it */
3440 name = s->name;
3441 s->name = NULL;
3442 savepointLevel = s->savepointLevel;
3443
3445
3446 DefineSavepoint(NULL);
3447 s = CurrentTransactionState; /* changed by push */
3448 s->name = name;
3449 s->savepointLevel = savepointLevel;
3450
3451 /* This is the same as TBLOCK_SUBBEGIN case */
3455 }
3456 break;
3457 }
3458
3459 /* Done, no more iterations required */
3460 return true;
3461}
3462
3463/*
3464 * AbortCurrentTransaction -- a wrapper function handling the
3465 * loop over subtransactions to avoid potentially dangerous recursion in
3466 * AbortCurrentTransactionInternal().
3467 */
3468void
3470{
3471 /*
3472 * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3473 * done.
3474 */
3476 {
3477 }
3478}
3479
3480/*
3481 * AbortCurrentTransactionInternal - a function doing an iteration of work
3482 * regarding handling the current transaction abort. In the case of
3483 * subtransactions more than one iterations could be required. Returns
3484 * true when no more iterations required, false otherwise.
3485 */
3486static bool
3488{
3490
3491 switch (s->blockState)
3492 {
3493 case TBLOCK_DEFAULT:
3494 if (s->state == TRANS_DEFAULT)
3495 {
3496 /* we are idle, so nothing to do */
3497 }
3498 else
3499 {
3500 /*
3501 * We can get here after an error during transaction start
3502 * (state will be TRANS_START). Need to clean up the
3503 * incompletely started transaction. First, adjust the
3504 * low-level state to suppress warning message from
3505 * AbortTransaction.
3506 */
3507 if (s->state == TRANS_START)
3511 }
3512 break;
3513
3514 /*
3515 * If we aren't in a transaction block, we just do the basic abort
3516 * & cleanup transaction. For this purpose, we treat an implicit
3517 * transaction block as if it were a simple statement.
3518 */
3519 case TBLOCK_STARTED:
3524 break;
3525
3526 /*
3527 * If we are in TBLOCK_BEGIN it means something screwed up right
3528 * after reading "BEGIN TRANSACTION". We assume that the user
3529 * will interpret the error as meaning the BEGIN failed to get him
3530 * into a transaction block, so we should abort and return to idle
3531 * state.
3532 */
3533 case TBLOCK_BEGIN:
3537 break;
3538
3539 /*
3540 * We are somewhere in a transaction block and we've gotten a
3541 * failure, so we abort the transaction and set up the persistent
3542 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3543 */
3544 case TBLOCK_INPROGRESS:
3548 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3549 break;
3550
3551 /*
3552 * Here, we failed while trying to COMMIT. Clean up the
3553 * transaction and return to idle state (we do not want to stay in
3554 * the transaction).
3555 */
3556 case TBLOCK_END:
3560 break;
3561
3562 /*
3563 * Here, we are already in an aborted transaction state and are
3564 * waiting for a ROLLBACK, but for some reason we failed again! So
3565 * we just remain in the abort state.
3566 */
3567 case TBLOCK_ABORT:
3568 case TBLOCK_SUBABORT:
3569 break;
3570
3571 /*
3572 * We are in a failed transaction and we got the ROLLBACK command.
3573 * We have already aborted, we just need to cleanup and go to idle
3574 * state.
3575 */
3576 case TBLOCK_ABORT_END:
3579 break;
3580
3581 /*
3582 * We are in a live transaction and we got a ROLLBACK command.
3583 * Abort, cleanup, go to idle state.
3584 */
3589 break;
3590
3591 /*
3592 * Here, we failed while trying to PREPARE. Clean up the
3593 * transaction and return to idle state (we do not want to stay in
3594 * the transaction).
3595 */
3596 case TBLOCK_PREPARE:
3600 break;
3601
3602 /*
3603 * We got an error inside a subtransaction. Abort just the
3604 * subtransaction, and go to the persistent SUBABORT state until
3605 * we get ROLLBACK.
3606 */
3610 break;
3611
3612 /*
3613 * If we failed while trying to create a subtransaction, clean up
3614 * the broken subtransaction and abort the parent. The same
3615 * applies if we get a failure while ending a subtransaction. As
3616 * we need to abort the parent, return false to request the caller
3617 * to do the next iteration.
3618 */
3619 case TBLOCK_SUBBEGIN:
3620 case TBLOCK_SUBRELEASE:
3621 case TBLOCK_SUBCOMMIT:
3623 case TBLOCK_SUBRESTART:
3626 return false;
3627
3628 /*
3629 * Same as above, except the Abort() was already done.
3630 */
3634 return false;
3635 }
3636
3637 /* Done, no more iterations required */
3638 return true;
3639}
3640
3641/*
3642 * PreventInTransactionBlock
3643 *
3644 * This routine is to be called by statements that must not run inside
3645 * a transaction block, typically because they have non-rollback-able
3646 * side effects or do internal commits.
3647 *
3648 * If this routine completes successfully, then the calling statement is
3649 * guaranteed that if it completes without error, its results will be
3650 * committed immediately.
3651 *
3652 * If we have already started a transaction block, issue an error; also issue
3653 * an error if we appear to be running inside a user-defined function (which
3654 * could issue more commands and possibly cause a failure after the statement
3655 * completes). Subtransactions are verboten too.
3656 *
3657 * We must also set XACT_FLAGS_NEEDIMMEDIATECOMMIT in MyXactFlags, to ensure
3658 * that postgres.c follows through by committing after the statement is done.
3659 *
3660 * isTopLevel: passed down from ProcessUtility to determine whether we are
3661 * inside a function. (We will always fail if this is false, but it's
3662 * convenient to centralize the check here instead of making callers do it.)
3663 * stmtType: statement type name, for error messages.
3664 */
3665void
3666PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
3667{
3668 /*
3669 * xact block already started?
3670 */
3671 if (IsTransactionBlock())
3672 ereport(ERROR,
3673 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3674 /* translator: %s represents an SQL statement name */
3675 errmsg("%s cannot run inside a transaction block",
3676 stmtType)));
3677
3678 /*
3679 * subtransaction?
3680 */
3681 if (IsSubTransaction())
3682 ereport(ERROR,
3683 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3684 /* translator: %s represents an SQL statement name */
3685 errmsg("%s cannot run inside a subtransaction",
3686 stmtType)));
3687
3688 /*
3689 * inside a function call?
3690 */
3691 if (!isTopLevel)
3692 ereport(ERROR,
3693 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3694 /* translator: %s represents an SQL statement name */
3695 errmsg("%s cannot be executed from a function", stmtType)));
3696
3697 /* If we got past IsTransactionBlock test, should be in default state */
3700 elog(FATAL, "cannot prevent transaction chain");
3701
3702 /* All okay. Set the flag to make sure the right thing happens later. */
3704}
3705
3706/*
3707 * WarnNoTransactionBlock
3708 * RequireTransactionBlock
3709 *
3710 * These two functions allow for warnings or errors if a command is executed
3711 * outside of a transaction block. This is useful for commands that have no
3712 * effects that persist past transaction end (and so calling them outside a
3713 * transaction block is presumably an error). DECLARE CURSOR is an example.
3714 * While top-level transaction control commands (BEGIN/COMMIT/ABORT) and SET
3715 * that have no effect issue warnings, all other no-effect commands generate
3716 * errors.
3717 *
3718 * If we appear to be running inside a user-defined function, we do not
3719 * issue anything, since the function could issue more commands that make
3720 * use of the current statement's results. Likewise subtransactions.
3721 * Thus these are inverses for PreventInTransactionBlock.
3722 *
3723 * isTopLevel: passed down from ProcessUtility to determine whether we are
3724 * inside a function.
3725 * stmtType: statement type name, for warning or error messages.
3726 */
3727void
3728WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
3729{
3730 CheckTransactionBlock(isTopLevel, false, stmtType);
3731}
3732
3733void
3734RequireTransactionBlock(bool isTopLevel, const char *stmtType)
3735{
3736 CheckTransactionBlock(isTopLevel, true, stmtType);
3737}
3738
3739/*
3740 * This is the implementation of the above two.
3741 */
3742static void
3743CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
3744{
3745 /*
3746 * xact block already started?
3747 */
3748 if (IsTransactionBlock())
3749 return;
3750
3751 /*
3752 * subtransaction?
3753 */
3754 if (IsSubTransaction())
3755 return;
3756
3757 /*
3758 * inside a function call?
3759 */
3760 if (!isTopLevel)
3761 return;
3762
3763 ereport(throwError ? ERROR : WARNING,
3764 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3765 /* translator: %s represents an SQL statement name */
3766 errmsg("%s can only be used in transaction blocks",
3767 stmtType)));
3768}
3769
3770/*
3771 * IsInTransactionBlock
3772 *
3773 * This routine is for statements that need to behave differently inside
3774 * a transaction block than when running as single commands. ANALYZE is
3775 * currently the only example.
3776 *
3777 * If this routine returns "false", then the calling statement is allowed
3778 * to perform internal transaction-commit-and-start cycles; there is not a
3779 * risk of messing up any transaction already in progress. (Note that this
3780 * is not the identical guarantee provided by PreventInTransactionBlock,
3781 * since we will not force a post-statement commit.)
3782 *
3783 * isTopLevel: passed down from ProcessUtility to determine whether we are
3784 * inside a function.
3785 */
3786bool
3787IsInTransactionBlock(bool isTopLevel)
3788{
3789 /*
3790 * Return true on same conditions that would make
3791 * PreventInTransactionBlock error out
3792 */
3793 if (IsTransactionBlock())
3794 return true;
3795
3796 if (IsSubTransaction())
3797 return true;
3798
3799 if (!isTopLevel)
3800 return true;
3801
3804 return true;
3805
3806 return false;
3807}
3808
3809
3810/*
3811 * Register or deregister callback functions for start- and end-of-xact
3812 * operations.
3813 *
3814 * These functions are intended for use by dynamically loaded modules.
3815 * For built-in modules we generally just hardwire the appropriate calls
3816 * (mainly because it's easier to control the order that way, where needed).
3817 *
3818 * At transaction end, the callback occurs post-commit or post-abort, so the
3819 * callback functions can only do noncritical cleanup.
3820 */
3821void
3823{
3824 XactCallbackItem *item;
3825
3826 item = (XactCallbackItem *)
3828 item->callback = callback;
3829 item->arg = arg;
3830 item->next = Xact_callbacks;
3831 Xact_callbacks = item;
3832}
3833
3834void
3836{
3837 XactCallbackItem *item;
3838 XactCallbackItem *prev;
3839
3840 prev = NULL;
3841 for (item = Xact_callbacks; item; prev = item, item = item->next)
3842 {
3843 if (item->callback == callback && item->arg == arg)
3844 {
3845 if (prev)
3846 prev->next = item->next;
3847 else
3848 Xact_callbacks = item->next;
3849 pfree(item);
3850 break;
3851 }
3852 }
3853}
3854
3855static void
3857{
3858 XactCallbackItem *item;
3860
3861 for (item = Xact_callbacks; item; item = next)
3862 {
3863 /* allow callbacks to unregister themselves when called */
3864 next = item->next;
3865 item->callback(event, item->arg);
3866 }
3867}
3868
3869
3870/*
3871 * Register or deregister callback functions for start- and end-of-subxact
3872 * operations.
3873 *
3874 * Pretty much same as above, but for subtransaction events.
3875 *
3876 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3877 * so the callback functions can only do noncritical cleanup. At
3878 * subtransaction start, the callback is called when the subtransaction has
3879 * finished initializing.
3880 */
3881void
3883{
3884 SubXactCallbackItem *item;
3885
3886 item = (SubXactCallbackItem *)
3888 item->callback = callback;
3889 item->arg = arg;
3890 item->next = SubXact_callbacks;
3891 SubXact_callbacks = item;
3892}
3893
3894void
3896{
3897 SubXactCallbackItem *item;
3898 SubXactCallbackItem *prev;
3899
3900 prev = NULL;
3901 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3902 {
3903 if (item->callback == callback && item->arg == arg)
3904 {
3905 if (prev)
3906 prev->next = item->next;
3907 else
3908 SubXact_callbacks = item->next;
3909 pfree(item);
3910 break;
3911 }
3912 }
3913}
3914
3915static void
3917 SubTransactionId mySubid,
3918 SubTransactionId parentSubid)
3919{
3920 SubXactCallbackItem *item;
3922
3923 for (item = SubXact_callbacks; item; item = next)
3924 {
3925 /* allow callbacks to unregister themselves when called */
3926 next = item->next;
3927 item->callback(event, mySubid, parentSubid, item->arg);
3928 }
3929}
3930
3931
3932/* ----------------------------------------------------------------
3933 * transaction block support
3934 * ----------------------------------------------------------------
3935 */
3936
3937/*
3938 * BeginTransactionBlock
3939 * This executes a BEGIN command.
3940 */
3941void
3943{
3945
3946 switch (s->blockState)
3947 {
3948 /*
3949 * We are not inside a transaction block, so allow one to begin.
3950 */
3951 case TBLOCK_STARTED:
3953 break;
3954
3955 /*
3956 * BEGIN converts an implicit transaction block to a regular one.
3957 * (Note that we allow this even if we've already done some
3958 * commands, which is a bit odd but matches historical practice.)
3959 */
3962 break;
3963
3964 /*
3965 * Already a transaction block in progress.
3966 */
3967 case TBLOCK_INPROGRESS:
3970 case TBLOCK_ABORT:
3971 case TBLOCK_SUBABORT:
3973 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3974 errmsg("there is already a transaction in progress")));
3975 break;
3976
3977 /* These cases are invalid. */
3978 case TBLOCK_DEFAULT:
3979 case TBLOCK_BEGIN:
3980 case TBLOCK_SUBBEGIN:
3981 case TBLOCK_END:
3982 case TBLOCK_SUBRELEASE:
3983 case TBLOCK_SUBCOMMIT:
3984 case TBLOCK_ABORT_END:
3988 case TBLOCK_SUBRESTART:
3990 case TBLOCK_PREPARE:
3991 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3993 break;
3994 }
3995}
3996
3997/*
3998 * PrepareTransactionBlock
3999 * This executes a PREPARE command.
4000 *
4001 * Since PREPARE may actually do a ROLLBACK, the result indicates what
4002 * happened: true for PREPARE, false for ROLLBACK.
4003 *
4004 * Note that we don't actually do anything here except change blockState.
4005 * The real work will be done in the upcoming PrepareTransaction().
4006 * We do it this way because it's not convenient to change memory context,
4007 * resource owner, etc while executing inside a Portal.
4008 */
4009bool
4011{
4013 bool result;
4014
4015 /* Set up to commit the current transaction */
4016 result = EndTransactionBlock(false);
4017
4018 /* If successful, change outer tblock state to PREPARE */
4019 if (result)
4020 {
4022
4023 while (s->parent != NULL)
4024 s = s->parent;
4025
4026 if (s->blockState == TBLOCK_END)
4027 {
4028 /* Save GID where PrepareTransaction can find it again */
4030
4032 }
4033 else
4034 {
4035 /*
4036 * ignore case where we are not in a transaction;
4037 * EndTransactionBlock already issued a warning.
4038 */
4041 /* Don't send back a PREPARE result tag... */
4042 result = false;
4043 }
4044 }
4045
4046 return result;
4047}
4048
4049/*
4050 * EndTransactionBlock
4051 * This executes a COMMIT command.
4052 *
4053 * Since COMMIT may actually do a ROLLBACK, the result indicates what
4054 * happened: true for COMMIT, false for ROLLBACK.
4055 *
4056 * Note that we don't actually do anything here except change blockState.
4057 * The real work will be done in the upcoming CommitTransactionCommand().
4058 * We do it this way because it's not convenient to change memory context,
4059 * resource owner, etc while executing inside a Portal.
4060 */
4061bool
4063{
4065 bool result = false;
4066
4067 switch (s->blockState)
4068 {
4069 /*
4070 * We are in a transaction block, so tell CommitTransactionCommand
4071 * to COMMIT.
4072 */
4073 case TBLOCK_INPROGRESS:
4075 result = true;
4076 break;
4077
4078 /*
4079 * We are in an implicit transaction block. If AND CHAIN was
4080 * specified, error. Otherwise commit, but issue a warning
4081 * because there was no explicit BEGIN before this.
4082 */
4084 if (chain)
4085 ereport(ERROR,
4086 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4087 /* translator: %s represents an SQL statement name */
4088 errmsg("%s can only be used in transaction blocks",
4089 "COMMIT AND CHAIN")));
4090 else
4092 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4093 errmsg("there is no transaction in progress")));
4095 result = true;
4096 break;
4097
4098 /*
4099 * We are in a failed transaction block. Tell
4100 * CommitTransactionCommand it's time to exit the block.
4101 */
4102 case TBLOCK_ABORT:
4104 break;
4105
4106 /*
4107 * We are in a live subtransaction block. Set up to subcommit all
4108 * open subtransactions and then commit the main transaction.
4109 */
4111 while (s->parent != NULL)
4112 {
4115 else
4116 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4118 s = s->parent;
4119 }
4120 if (s->blockState == TBLOCK_INPROGRESS)
4122 else
4123 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4125 result = true;
4126 break;
4127
4128 /*
4129 * Here we are inside an aborted subtransaction. Treat the COMMIT
4130 * as ROLLBACK: set up to abort everything and exit the main
4131 * transaction.
4132 */
4133 case TBLOCK_SUBABORT:
4134 while (s->parent != NULL)
4135 {
4138 else if (s->blockState == TBLOCK_SUBABORT)
4140 else
4141 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4143 s = s->parent;
4144 }
4145 if (s->blockState == TBLOCK_INPROGRESS)
4147 else if (s->blockState == TBLOCK_ABORT)
4149 else
4150 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4152 break;
4153
4154 /*
4155 * The user issued COMMIT when not inside a transaction. For
4156 * COMMIT without CHAIN, issue a WARNING, staying in
4157 * TBLOCK_STARTED state. The upcoming call to
4158 * CommitTransactionCommand() will then close the transaction and
4159 * put us back into the default state. For COMMIT AND CHAIN,
4160 * error.
4161 */
4162 case TBLOCK_STARTED:
4163 if (chain)
4164 ereport(ERROR,
4165 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4166 /* translator: %s represents an SQL statement name */
4167 errmsg("%s can only be used in transaction blocks",
4168 "COMMIT AND CHAIN")));
4169 else
4171 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4172 errmsg("there is no transaction in progress")));
4173 result = true;
4174 break;
4175
4176 /*
4177 * The user issued a COMMIT that somehow ran inside a parallel
4178 * worker. We can't cope with that.
4179 */
4181 ereport(FATAL,
4182 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4183 errmsg("cannot commit during a parallel operation")));
4184 break;
4185
4186 /* These cases are invalid. */
4187 case TBLOCK_DEFAULT:
4188 case TBLOCK_BEGIN:
4189 case TBLOCK_SUBBEGIN:
4190 case TBLOCK_END:
4191 case TBLOCK_SUBRELEASE:
4192 case TBLOCK_SUBCOMMIT:
4193 case TBLOCK_ABORT_END:
4197 case TBLOCK_SUBRESTART:
4199 case TBLOCK_PREPARE:
4200 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4202 break;
4203 }
4204
4206 s->blockState == TBLOCK_END ||
4209
4210 s->chain = chain;
4211
4212 return result;
4213}
4214
4215/*
4216 * UserAbortTransactionBlock
4217 * This executes a ROLLBACK command.
4218 *
4219 * As above, we don't actually do anything here except change blockState.
4220 */
4221void
4223{
4225
4226 switch (s->blockState)
4227 {
4228 /*
4229 * We are inside a transaction block and we got a ROLLBACK command
4230 * from the user, so tell CommitTransactionCommand to abort and
4231 * exit the transaction block.
4232 */
4233 case TBLOCK_INPROGRESS:
4235 break;
4236
4237 /*
4238 * We are inside a failed transaction block and we got a ROLLBACK
4239 * command from the user. Abort processing is already done, so
4240 * CommitTransactionCommand just has to cleanup and go back to
4241 * idle state.
4242 */
4243 case TBLOCK_ABORT:
4245 break;
4246
4247 /*
4248 * We are inside a subtransaction. Mark everything up to top
4249 * level as exitable.
4250 */
4252 case TBLOCK_SUBABORT:
4253 while (s->parent != NULL)
4254 {
4257 else if (s->blockState == TBLOCK_SUBABORT)
4259 else
4260 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4262 s = s->parent;
4263 }
4264 if (s->blockState == TBLOCK_INPROGRESS)
4266 else if (s->blockState == TBLOCK_ABORT)
4268 else
4269 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4271 break;
4272
4273 /*
4274 * The user issued ABORT when not inside a transaction. For
4275 * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4276 * The upcoming call to CommitTransactionCommand() will then put
4277 * us back into the default state. For ROLLBACK AND CHAIN, error.
4278 *
4279 * We do the same thing with ABORT inside an implicit transaction,
4280 * although in this case we might be rolling back actual database
4281 * state changes. (It's debatable whether we should issue a
4282 * WARNING in this case, but we have done so historically.)
4283 */
4284 case TBLOCK_STARTED:
4286 if (chain)
4287 ereport(ERROR,
4288 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4289 /* translator: %s represents an SQL statement name */
4290 errmsg("%s can only be used in transaction blocks",
4291 "ROLLBACK AND CHAIN")));
4292 else
4294 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4295 errmsg("there is no transaction in progress")));
4297 break;
4298
4299 /*
4300 * The user issued an ABORT that somehow ran inside a parallel
4301 * worker. We can't cope with that.
4302 */
4304 ereport(FATAL,
4305 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4306 errmsg("cannot abort during a parallel operation")));
4307 break;
4308
4309 /* These cases are invalid. */
4310 case TBLOCK_DEFAULT:
4311 case TBLOCK_BEGIN:
4312 case TBLOCK_SUBBEGIN:
4313 case TBLOCK_END:
4314 case TBLOCK_SUBRELEASE:
4315 case TBLOCK_SUBCOMMIT:
4316 case TBLOCK_ABORT_END:
4320 case TBLOCK_SUBRESTART:
4322 case TBLOCK_PREPARE:
4323 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4325 break;
4326 }
4327
4330
4331 s->chain = chain;
4332}
4333
4334/*
4335 * BeginImplicitTransactionBlock
4336 * Start an implicit transaction block if we're not already in one.
4337 *
4338 * Unlike BeginTransactionBlock, this is called directly from the main loop
4339 * in postgres.c, not within a Portal. So we can just change blockState
4340 * without a lot of ceremony. We do not expect caller to do
4341 * CommitTransactionCommand/StartTransactionCommand.
4342 */
4343void
4345{
4347
4348 /*
4349 * If we are in STARTED state (that is, no transaction block is open),
4350 * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4351 * block.
4352 *
4353 * For caller convenience, we consider all other transaction states as
4354 * legal here; otherwise the caller would need its own state check, which
4355 * seems rather pointless.
4356 */
4357 if (s->blockState == TBLOCK_STARTED)
4359}
4360
4361/*
4362 * EndImplicitTransactionBlock
4363 * End an implicit transaction block, if we're in one.
4364 *
4365 * Like EndTransactionBlock, we just make any needed blockState change here.
4366 * The real work will be done in the upcoming CommitTransactionCommand().
4367 */
4368void
4370{
4372
4373 /*
4374 * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4375 * allowing CommitTransactionCommand to commit whatever happened during
4376 * the implicit transaction block as though it were a single statement.
4377 *
4378 * For caller convenience, we consider all other transaction states as
4379 * legal here; otherwise the caller would need its own state check, which
4380 * seems rather pointless.
4381 */
4384}
4385
4386/*
4387 * DefineSavepoint
4388 * This executes a SAVEPOINT command.
4389 */
4390void
4392{
4394
4395 /*
4396 * Workers synchronize transaction state at the beginning of each parallel
4397 * operation, so we can't account for new subtransactions after that
4398 * point. (Note that this check will certainly error out if s->blockState
4399 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4400 * below.)
4401 */
4403 ereport(ERROR,
4404 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4405 errmsg("cannot define savepoints during a parallel operation")));
4406
4407 switch (s->blockState)
4408 {
4409 case TBLOCK_INPROGRESS:
4411 /* Normal subtransaction start */
4413 s = CurrentTransactionState; /* changed by push */
4414
4415 /*
4416 * Savepoint names, like the TransactionState block itself, live
4417 * in TopTransactionContext.
4418 */
4419 if (name)
4421 break;
4422
4423 /*
4424 * We disallow savepoint commands in implicit transaction blocks.
4425 * There would be no great difficulty in allowing them so far as
4426 * this module is concerned, but a savepoint seems inconsistent
4427 * with exec_simple_query's behavior of abandoning the whole query
4428 * string upon error. Also, the point of an implicit transaction
4429 * block (as opposed to a regular one) is to automatically close
4430 * after an error, so it's hard to see how a savepoint would fit
4431 * into that.
4432 *
4433 * The error messages for this are phrased as if there were no
4434 * active transaction block at all, which is historical but
4435 * perhaps could be improved.
4436 */
4438 ereport(ERROR,
4439 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4440 /* translator: %s represents an SQL statement name */
4441 errmsg("%s can only be used in transaction blocks",
4442 "SAVEPOINT")));
4443 break;
4444
4445 /* These cases are invalid. */
4446 case TBLOCK_DEFAULT:
4447 case TBLOCK_STARTED:
4448 case TBLOCK_BEGIN:
4450 case TBLOCK_SUBBEGIN:
4451 case TBLOCK_END:
4452 case TBLOCK_SUBRELEASE:
4453 case TBLOCK_SUBCOMMIT:
4454 case TBLOCK_ABORT:
4455 case TBLOCK_SUBABORT:
4456 case TBLOCK_ABORT_END:
4460 case TBLOCK_SUBRESTART:
4462 case TBLOCK_PREPARE:
4463 elog(FATAL, "DefineSavepoint: unexpected state %s",
4465 break;
4466 }
4467}
4468
4469/*
4470 * ReleaseSavepoint
4471 * This executes a RELEASE command.
4472 *
4473 * As above, we don't actually do anything here except change blockState.
4474 */
4475void
4477{
4479 TransactionState target,
4480 xact;
4481
4482 /*
4483 * Workers synchronize transaction state at the beginning of each parallel
4484 * operation, so we can't account for transaction state change after that
4485 * point. (Note that this check will certainly error out if s->blockState
4486 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4487 * below.)
4488 */
4490 ereport(ERROR,
4491 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4492 errmsg("cannot release savepoints during a parallel operation")));
4493
4494 switch (s->blockState)
4495 {
4496 /*
4497 * We can't release a savepoint if there is no savepoint defined.
4498 */
4499 case TBLOCK_INPROGRESS:
4500 ereport(ERROR,
4501 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4502 errmsg("savepoint \"%s\" does not exist", name)));
4503 break;
4504
4506 /* See comment about implicit transactions in DefineSavepoint */
4507 ereport(ERROR,
4508 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4509 /* translator: %s represents an SQL statement name */
4510 errmsg("%s can only be used in transaction blocks",
4511 "RELEASE SAVEPOINT")));
4512 break;
4513
4514 /*
4515 * We are in a non-aborted subtransaction. This is the only valid
4516 * case.
4517 */
4519 break;
4520
4521 /* These cases are invalid. */
4522 case TBLOCK_DEFAULT:
4523 case TBLOCK_STARTED:
4524 case TBLOCK_BEGIN:
4526 case TBLOCK_SUBBEGIN:
4527 case TBLOCK_END:
4528 case TBLOCK_SUBRELEASE:
4529 case TBLOCK_SUBCOMMIT:
4530 case TBLOCK_ABORT:
4531 case TBLOCK_SUBABORT:
4532 case TBLOCK_ABORT_END:
4536 case TBLOCK_SUBRESTART:
4538 case TBLOCK_PREPARE:
4539 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4541 break;
4542 }
4543
4544 for (target = s; target; target = target->parent)
4545 {
4546 if (target->name && strcmp(target->name, name) == 0)
4547 break;
4548 }
4549
4550 if (!target)
4551 ereport(ERROR,
4552 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4553 errmsg("savepoint \"%s\" does not exist", name)));
4554
4555 /* disallow crossing savepoint level boundaries */
4556 if (target->savepointLevel != s->savepointLevel)
4557 ereport(ERROR,
4558 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4559 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4560
4561 /*
4562 * Mark "commit pending" all subtransactions up to the target
4563 * subtransaction. The actual commits will happen when control gets to
4564 * CommitTransactionCommand.
4565 */
4567 for (;;)
4568 {
4571 if (xact == target)
4572 break;
4573 xact = xact->parent;
4574 Assert(xact);
4575 }
4576}
4577
4578/*
4579 * RollbackToSavepoint
4580 * This executes a ROLLBACK TO <savepoint> command.
4581 *
4582 * As above, we don't actually do anything here except change blockState.
4583 */
4584void
4586{
4588 TransactionState target,
4589 xact;
4590
4591 /*
4592 * Workers synchronize transaction state at the beginning of each parallel
4593 * operation, so we can't account for transaction state change after that
4594 * point. (Note that this check will certainly error out if s->blockState
4595 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4596 * below.)
4597 */
4599 ereport(ERROR,
4600 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4601 errmsg("cannot rollback to savepoints during a parallel operation")));
4602
4603 switch (s->blockState)
4604 {
4605 /*
4606 * We can't rollback to a savepoint if there is no savepoint
4607 * defined.
4608 */
4609 case TBLOCK_INPROGRESS:
4610 case TBLOCK_ABORT:
4611 ereport(ERROR,
4612 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4613 errmsg("savepoint \"%s\" does not exist", name)));
4614 break;
4615
4617 /* See comment about implicit transactions in DefineSavepoint */
4618 ereport(ERROR,
4619 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4620 /* translator: %s represents an SQL statement name */
4621 errmsg("%s can only be used in transaction blocks",
4622 "ROLLBACK TO SAVEPOINT")));
4623 break;
4624
4625 /*
4626 * There is at least one savepoint, so proceed.
4627 */
4629 case TBLOCK_SUBABORT:
4630 break;
4631
4632 /* These cases are invalid. */
4633 case TBLOCK_DEFAULT:
4634 case TBLOCK_STARTED:
4635 case TBLOCK_BEGIN:
4637 case TBLOCK_SUBBEGIN:
4638 case TBLOCK_END:
4639 case TBLOCK_SUBRELEASE:
4640 case TBLOCK_SUBCOMMIT:
4641 case TBLOCK_ABORT_END:
4645 case TBLOCK_SUBRESTART:
4647 case TBLOCK_PREPARE:
4648 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4650 break;
4651 }
4652
4653 for (target = s; target; target = target->parent)
4654 {
4655 if (target->name && strcmp(target->name, name) == 0)
4656 break;
4657 }
4658
4659 if (!target)
4660 ereport(ERROR,
4661 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4662 errmsg("savepoint \"%s\" does not exist", name)));
4663
4664 /* disallow crossing savepoint level boundaries */
4665 if (target->savepointLevel != s->savepointLevel)
4666 ereport(ERROR,
4667 (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4668 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4669
4670 /*
4671 * Mark "abort pending" all subtransactions up to the target
4672 * subtransaction. The actual aborts will happen when control gets to
4673 * CommitTransactionCommand.
4674 */
4676 for (;;)
4677 {
4678 if (xact == target)
4679 break;
4680 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4682 else if (xact->blockState == TBLOCK_SUBABORT)
4684 else
4685 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4687 xact = xact->parent;
4688 Assert(xact);
4689 }
4690
4691 /* And mark the target as "restart pending" */
4692 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4694 else if (xact->blockState == TBLOCK_SUBABORT)
4696 else
4697 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4699}
4700
4701/*
4702 * BeginInternalSubTransaction
4703 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
4704 * TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_END,
4705 * and TBLOCK_PREPARE states, and therefore it can safely be used in
4706 * functions that might be called when not inside a BEGIN block or when
4707 * running deferred triggers at COMMIT/PREPARE time. Also, it
4708 * automatically does CommitTransactionCommand/StartTransactionCommand
4709 * instead of expecting the caller to do it.
4710 */
4711void
4713{
4715 bool save_ExitOnAnyError = ExitOnAnyError;
4716
4717 /*
4718 * Errors within this function are improbable, but if one does happen we
4719 * force a FATAL exit. Callers generally aren't prepared to handle losing
4720 * control, and moreover our transaction state is probably corrupted if we
4721 * fail partway through; so an ordinary ERROR longjmp isn't okay.
4722 */
4723 ExitOnAnyError = true;
4724
4725 /*
4726 * We do not check for parallel mode here. It's permissible to start and
4727 * end "internal" subtransactions while in parallel mode, so long as no
4728 * new XIDs or command IDs are assigned. Enforcement of that occurs in
4729 * AssignTransactionId() and CommandCounterIncrement().
4730 */
4731
4732 switch (s->blockState)
4733 {
4734 case TBLOCK_STARTED:
4735 case TBLOCK_INPROGRESS:
4738 case TBLOCK_END:
4739 case TBLOCK_PREPARE:
4741 /* Normal subtransaction start */
4743 s = CurrentTransactionState; /* changed by push */
4744
4745 /*
4746 * Savepoint names, like the TransactionState block itself, live
4747 * in TopTransactionContext.
4748 */
4749 if (name)
4751 break;
4752
4753 /* These cases are invalid. */
4754 case TBLOCK_DEFAULT:
4755 case TBLOCK_BEGIN:
4756 case TBLOCK_SUBBEGIN:
4757 case TBLOCK_SUBRELEASE:
4758 case TBLOCK_SUBCOMMIT:
4759 case TBLOCK_ABORT:
4760 case TBLOCK_SUBABORT:
4761 case TBLOCK_ABORT_END:
4765 case TBLOCK_SUBRESTART:
4767 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4769 break;
4770 }
4771
4774
4775 ExitOnAnyError = save_ExitOnAnyError;
4776}
4777
4778/*
4779 * ReleaseCurrentSubTransaction
4780 *
4781 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
4782 * savepoint name (if any).
4783 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4784 */
4785void
4787{
4789
4790 /*
4791 * We do not check for parallel mode here. It's permissible to start and
4792 * end "internal" subtransactions while in parallel mode, so long as no
4793 * new XIDs or command IDs are assigned.
4794 */
4795
4797 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4802 s = CurrentTransactionState; /* changed by pop */
4804}
4805
4806/*
4807 * RollbackAndReleaseCurrentSubTransaction
4808 *
4809 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
4810 * of its savepoint name (if any).
4811 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4812 */
4813void
4815{
4817
4818 /*
4819 * We do not check for parallel mode here. It's permissible to start and
4820 * end "internal" subtransactions while in parallel mode, so long as no
4821 * new XIDs or command IDs are assigned.
4822 */
4823
4824 switch (s->blockState)
4825 {
4826 /* Must be in a subtransaction */
4828 case TBLOCK_SUBABORT:
4829 break;
4830
4831 /* These cases are invalid. */
4832 case TBLOCK_DEFAULT:
4833 case TBLOCK_STARTED:
4834 case TBLOCK_BEGIN:
4837 case TBLOCK_SUBBEGIN:
4838 case TBLOCK_INPROGRESS:
4839 case TBLOCK_END:
4840 case TBLOCK_SUBRELEASE:
4841 case TBLOCK_SUBCOMMIT:
4842 case TBLOCK_ABORT:
4843 case TBLOCK_ABORT_END:
4847 case TBLOCK_SUBRESTART:
4849 case TBLOCK_PREPARE:
4850 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4852 break;
4853 }
4854
4855 /*
4856 * Abort the current subtransaction, if needed.
4857 */
4860
4861 /* And clean it up, too */
4863
4864 s = CurrentTransactionState; /* changed by pop */
4870}
4871
4872/*
4873 * AbortOutOfAnyTransaction
4874 *
4875 * This routine is provided for error recovery purposes. It aborts any
4876 * active transaction or transaction block, leaving the system in a known
4877 * idle state.
4878 */
4879void
4881{
4883
4884 /* Ensure we're not running in a doomed memory context */
4886
4887 /*
4888 * Get out of any transaction or nested transaction
4889 */
4890 do
4891 {
4892 switch (s->blockState)
4893 {
4894 case TBLOCK_DEFAULT:
4895 if (s->state == TRANS_DEFAULT)
4896 {
4897 /* Not in a transaction, do nothing */
4898 }
4899 else
4900 {
4901 /*
4902 * We can get here after an error during transaction start
4903 * (state will be TRANS_START). Need to clean up the
4904 * incompletely started transaction. First, adjust the
4905 * low-level state to suppress warning message from
4906 * AbortTransaction.
4907 */
4908 if (s->state == TRANS_START)
4912 }
4913 break;
4914 case TBLOCK_STARTED:
4915 case TBLOCK_BEGIN:
4916 case TBLOCK_INPROGRESS:
4919 case TBLOCK_END:
4921 case TBLOCK_PREPARE:
4922 /* In a transaction, so clean up */
4926 break;
4927 case TBLOCK_ABORT:
4928 case TBLOCK_ABORT_END:
4929
4930 /*
4931 * AbortTransaction is already done, still need Cleanup.
4932 * However, if we failed partway through running ROLLBACK,
4933 * there will be an active portal running that command, which
4934 * we need to shut down before doing CleanupTransaction.
4935 */
4939 break;
4940
4941 /*
4942 * In a subtransaction, so clean it up and abort parent too
4943 */
4944 case TBLOCK_SUBBEGIN:
4946 case TBLOCK_SUBRELEASE:
4947 case TBLOCK_SUBCOMMIT:
4949 case TBLOCK_SUBRESTART:
4952 s = CurrentTransactionState; /* changed by pop */
4953 break;
4954
4955 case TBLOCK_SUBABORT:
4958 /* As above, but AbortSubTransaction already done */
4959 if (s->curTransactionOwner)
4960 {
4961 /* As in TBLOCK_ABORT, might have a live portal to zap */
4966 }
4968 s = CurrentTransactionState; /* changed by pop */
4969 break;
4970 }
4971 } while (s->blockState != TBLOCK_DEFAULT);
4972
4973 /* Should be out of all subxacts now */
4974 Assert(s->parent == NULL);
4975
4976 /*
4977 * Revert to TopMemoryContext, to ensure we exit in a well-defined state
4978 * whether there were any transactions to close or not. (Callers that
4979 * don't intend to exit soon should switch to some other context to avoid
4980 * long-term memory leaks.)
4981 */
4983}
4984
4985/*
4986 * IsTransactionBlock --- are we within a transaction block?
4987 */
4988bool
4990{
4992
4994 return false;
4995
4996 return true;
4997}
4998
4999/*
5000 * IsTransactionOrTransactionBlock --- are we within either a transaction
5001 * or a transaction block? (The backend is only really "idle" when this
5002 * returns false.)
5003 *
5004 * This should match up with IsTransactionBlock and IsTransactionState.
5005 */
5006bool
5008{
5010
5011 if (s->blockState == TBLOCK_DEFAULT)
5012 return false;
5013
5014 return true;
5015}
5016
5017/*
5018 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
5019 */
5020char
5022{
5024
5025 switch (s->blockState)
5026 {
5027 case TBLOCK_DEFAULT:
5028 case TBLOCK_STARTED:
5029 return 'I'; /* idle --- not in transaction */
5030 case TBLOCK_BEGIN:
5031 case TBLOCK_SUBBEGIN:
5032 case TBLOCK_INPROGRESS:
5036 case TBLOCK_END:
5037 case TBLOCK_SUBRELEASE:
5038 case TBLOCK_SUBCOMMIT:
5039 case TBLOCK_PREPARE:
5040 return 'T'; /* in transaction */
5041 case TBLOCK_ABORT:
5042 case TBLOCK_SUBABORT:
5043 case TBLOCK_ABORT_END:
5047 case TBLOCK_SUBRESTART:
5049 return 'E'; /* in failed transaction */
5050 }
5051
5052 /* should never get here */
5053 elog(FATAL, "invalid transaction block state: %s",
5055 return 0; /* keep compiler quiet */
5056}
5057
5058/*
5059 * IsSubTransaction
5060 */
5061bool
5063{
5065
5066 if (s->nestingLevel >= 2)
5067 return true;
5068
5069 return false;
5070}
5071
5072/*
5073 * StartSubTransaction
5074 *
5075 * If you're wondering why this is separate from PushTransaction: it's because
5076 * we can't conveniently do this stuff right inside DefineSavepoint. The
5077 * SAVEPOINT utility command will be executed inside a Portal, and if we
5078 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
5079 * the Portal will undo those settings. So we make DefineSavepoint just
5080 * push a dummy transaction block, and when control returns to the main
5081 * idle loop, CommitTransactionCommand will be called, and we'll come here
5082 * to finish starting the subtransaction.
5083 */
5084static void
5086{
5088
5089 if (s->state != TRANS_DEFAULT)
5090 elog(WARNING, "StartSubTransaction while in %s state",
5092
5093 s->state = TRANS_START;
5094
5095 /*
5096 * Initialize subsystems for new subtransaction
5097 *
5098 * must initialize resource-management stuff first
5099 */
5103
5105
5106 /*
5107 * Call start-of-subxact callbacks
5108 */
5111
5112 ShowTransactionState("StartSubTransaction");
5113}
5114
5115/*
5116 * CommitSubTransaction
5117 *
5118 * The caller has to make sure to always reassign CurrentTransactionState
5119 * if it has a local pointer to it after calling this function.
5120 */
5121static void
5123{
5125
5126 ShowTransactionState("CommitSubTransaction");
5127
5128 if (s->state != TRANS_INPROGRESS)
5129 elog(WARNING, "CommitSubTransaction while in %s state",
5131
5132 /* Pre-commit processing goes here */
5133
5136
5137 /*
5138 * If this subxact has started any unfinished parallel operation, clean up
5139 * its workers and exit parallel mode. Warn about leaked resources.
5140 */
5142 if (s->parallelModeLevel != 0)
5143 {
5144 elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5146 s->parallelModeLevel = 0;
5147 }
5148
5149 /* Do the actual "commit", such as it is */
5150 s->state = TRANS_COMMIT;
5151
5152 /* Must CCI to ensure commands of subtransaction are seen as done */
5154
5155 /*
5156 * Prior to 8.4 we marked subcommit in clog at this point. We now only
5157 * perform that step, if required, as part of the atomic update of the
5158 * whole transaction tree at top level commit or abort.
5159 */
5160
5161 /* Post-commit cleanup */
5167 s->parent->nestingLevel,
5172
5175
5178 true, false);
5182 AtEOSubXact_Inval(true);
5184
5185 /*
5186 * The only lock we actually release here is the subtransaction XID lock.
5187 */
5191
5192 /*
5193 * Other locks should get transferred to their parent resource owner.
5194 */
5197 true, false);
5200 true, false);
5201
5202 AtEOXact_GUC(true, s->gucNestLevel);
5213
5214 /*
5215 * We need to restore the upper transaction's read-only state, in case the
5216 * upper is read-write while the child is read-only; GUC will incorrectly
5217 * think it should leave the child state in place.
5218 */
5220
5224 s->curTransactionOwner = NULL;
5225
5227
5228 s->state = TRANS_DEFAULT;
5229
5231}
5232
5233/*
5234 * AbortSubTransaction
5235 */
5236static void
5238{
5240
5241 /* Prevent cancel/die interrupt while cleaning up */
5243
5244 /* Make sure we have a valid memory context and resource owner */
5247
5248 /*
5249 * Release any LW locks we might be holding as quickly as possible.
5250 * (Regular locks, however, must be held till we finish aborting.)
5251 * Releasing LW locks is critical since we might try to grab them again
5252 * while cleaning up!
5253 *
5254 * FIXME This may be incorrect --- Are there some locks we should keep?
5255 * Buffer locks, for example? I don't think so but I'm not sure.
5256 */
5258
5261
5263
5264 UnlockBuffers();
5265
5266 /* Reset WAL record construction state */
5268
5269 /* Cancel condition variable sleep */
5271
5272 /*
5273 * Also clean up any open wait for lock, since the lock manager will choke
5274 * if we try to wait for another lock before doing this.
5275 */
5277
5278 /*
5279 * If any timeout events are still active, make sure the timeout interrupt
5280 * is scheduled. This covers possible loss of a timeout interrupt due to
5281 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5282 * We delay this till after LockErrorCleanup so that we don't uselessly
5283 * reschedule lock or deadlock check timeouts.
5284 */
5286
5287 /*
5288 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5289 * handler. We do this fairly early in the sequence so that the timeout
5290 * infrastructure will be functional if needed while aborting.
5291 */
5292 sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
5293
5294 /*
5295 * check the current transaction state
5296 */
5297 ShowTransactionState("AbortSubTransaction");
5298
5299 if (s->state != TRANS_INPROGRESS)
5300 elog(WARNING, "AbortSubTransaction while in %s state",
5302
5303 s->state = TRANS_ABORT;
5304
5305 /*
5306 * Reset user ID which might have been changed transiently. (See notes in
5307 * AbortTransaction.)
5308 */
5310
5311 /* Forget about any active REINDEX. */
5313
5314 /* Reset logical streaming state. */
5316
5317 /*
5318 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5319 * exports are not supported in subtransactions.
5320 */
5321
5322 /*
5323 * If this subxact has started any unfinished parallel operation, clean up
5324 * its workers and exit parallel mode. Don't warn about leaked resources.
5325 */
5327 s->parallelModeLevel = 0;
5328
5329 /*
5330 * We can skip all this stuff if the subxact failed before creating a
5331 * ResourceOwner...
5332 */
5333 if (s->curTransactionOwner)
5334 {
5343
5344 /* Advertise the fact that we aborted in pg_xact. */
5345 (void) RecordTransactionAbort(true);
5346
5347 /* Post-abort cleanup */
5350
5353
5356 false, false);
5357
5358 AtEOXact_Aio(false);
5362 AtEOSubXact_Inval(false);
5365 false, false);
5368 false, false);
5370
5371 AtEOXact_GUC(false, s->gucNestLevel);
5382 }
5383
5384 /*
5385 * Restore the upper transaction's read-only state, too. This should be
5386 * redundant with GUC's cleanup but we may as well do it for consistency
5387 * with the commit case.
5388 */
5390
5392}
5393
5394/*
5395 * CleanupSubTransaction
5396 *
5397 * The caller has to make sure to always reassign CurrentTransactionState
5398 * if it has a local pointer to it after calling this function.
5399 */
5400static void
5402{
5404
5405 ShowTransactionState("CleanupSubTransaction");
5406
5407 if (s->state != TRANS_ABORT)
5408 elog(WARNING, "CleanupSubTransaction while in %s state",
5410
5412
5415 if (s->curTransactionOwner)
5417 s->curTransactionOwner = NULL;
5418
5420
5421 s->state = TRANS_DEFAULT;
5422
5424}
5425
5426/*
5427 * PushTransaction
5428 * Create transaction state stack entry for a subtransaction
5429 *
5430 * The caller has to make sure to always reassign CurrentTransactionState
5431 * if it has a local pointer to it after calling this function.
5432 */
5433static void
5435{
5438
5439 /*
5440 * We keep subtransaction state nodes in TopTransactionContext.
5441 */
5442 s = (TransactionState)
5444 sizeof(TransactionStateData));
5445
5446 /*
5447 * Assign a subtransaction ID, watching out for counter wraparound.
5448 */
5451 {
5453 pfree(s);
5454 ereport(ERROR,
5455 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5456 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5457 }
5458
5459 /*
5460 * We can now stack a minimally valid subtransaction without fear of
5461 * failure.
5462 */
5463 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5465 s->parent = p;
5466 s->nestingLevel = p->nestingLevel + 1;
5469 s->state = TRANS_DEFAULT;
5474 s->parallelModeLevel = 0;
5476 s->topXidLogged = false;
5477
5479
5480 /*
5481 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5482 * with the subtransaction from here on out; in particular they should not
5483 * assume that it necessarily has a transaction context, resource owner,
5484 * or XID.
5485 */
5486}
5487
5488/*
5489 * PopTransaction
5490 * Pop back to parent transaction state
5491 *
5492 * The caller has to make sure to always reassign CurrentTransactionState
5493 * if it has a local pointer to it after calling this function.
5494 */
5495static void
5497{
5499
5500 if (s->state != TRANS_DEFAULT)
5501 elog(WARNING, "PopTransaction while in %s state",
5503
5504 if (s->parent == NULL)
5505 elog(FATAL, "PopTransaction with no parent");
5506
5508
5509 /* Let's just make sure CurTransactionContext is good */
5512
5513 /* Ditto for ResourceOwner links */
5516
5517 /* Free the old child structure */
5518 if (s->name)
5519 pfree(s->name);
5520 pfree(s);
5521}
5522
5523/*
5524 * EstimateTransactionStateSpace
5525 * Estimate the amount of space that will be needed by
5526 * SerializeTransactionState. It would be OK to overestimate slightly,
5527 * but it's simple for us to work out the precise value, so we do.
5528 */
5529Size
5531{
5533 Size nxids = 0;
5535
5536 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5537 {
5539 nxids = add_size(nxids, 1);
5540 nxids = add_size(nxids, s->nChildXids);
5541 }
5542
5543 return add_size(size, mul_size(sizeof(TransactionId), nxids));
5544}
5545
5546/*
5547 * SerializeTransactionState
5548 * Write out relevant details of our transaction state that will be
5549 * needed by a parallel worker.
5550 *
5551 * We need to save and restore XactDeferrable, XactIsoLevel, and the XIDs
5552 * associated with this transaction. These are serialized into a
5553 * caller-supplied buffer big enough to hold the number of bytes reported by
5554 * EstimateTransactionStateSpace(). We emit the XIDs in sorted order for the
5555 * convenience of the receiving process.
5556 */
5557void
5558SerializeTransactionState(Size maxsize, char *start_address)
5559{
5561 Size nxids = 0;
5562 Size i = 0;
5563 TransactionId *workspace;
5565
5566 result = (SerializedTransactionState *) start_address;
5567
5568 result->xactIsoLevel = XactIsoLevel;
5571 result->currentFullTransactionId =
5574
5575 /*
5576 * If we're running in a parallel worker and launching a parallel worker
5577 * of our own, we can just pass along the information that was passed to
5578 * us.
5579 */
5580 if (nParallelCurrentXids > 0)
5581 {
5583 memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
5585 return;
5586 }
5587
5588 /*
5589 * OK, we need to generate a sorted list of XIDs that our workers should
5590 * view as current. First, figure out how many there are.
5591 */
5592 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5593 {
5595 nxids = add_size(nxids, 1);
5596 nxids = add_size(nxids, s->nChildXids);
5597 }
5599 <= maxsize);
5600
5601 /* Copy them to our scratch space. */
5602 workspace = palloc(nxids * sizeof(TransactionId));
5603 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5604 {
5606 workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5607 if (s->nChildXids > 0)
5608 memcpy(&workspace[i], s->childXids,
5609 s->nChildXids * sizeof(TransactionId));
5610 i += s->nChildXids;
5611 }
5612 Assert(i == nxids);
5613
5614 /* Sort them. */
5615 qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5616
5617 /* Copy data into output area. */
5618 result->nParallelCurrentXids = nxids;
5619 memcpy(&result->parallelCurrentXids[0], workspace,
5620 nxids * sizeof(TransactionId));
5621}
5622
5623/*
5624 * StartParallelWorkerTransaction
5625 * Start a parallel worker transaction, restoring the relevant
5626 * transaction state serialized by SerializeTransactionState.
5627 */
5628void
5630{
5632
5635
5636 tstate = (SerializedTransactionState *) tstatespace;
5637 XactIsoLevel = tstate->xactIsoLevel;
5645
5647}
5648
5649/*
5650 * EndParallelWorkerTransaction
5651 * End a parallel worker transaction.
5652 */
5653void
5655{
5659}
5660
5661/*
5662 * ShowTransactionState
5663 * Debug support
5664 */
5665static void
5667{
5668 /* skip work if message will definitely not be printed */
5671}
5672
5673/*
5674 * ShowTransactionStateRec
5675 * Recursive subroutine for ShowTransactionState
5676 */
5677static void
5679{
5681
5682 if (s->parent)
5683 {
5684 /*
5685 * Since this function recurses, it could be driven to stack overflow.
5686 * This is just a debugging aid, so we can leave out some details
5687 * instead of erroring out with check_stack_depth().
5688 */
5689 if (stack_is_too_deep())
5691 (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5692 str, s->nestingLevel)));
5693 else
5695 }
5696
5698 if (s->nChildXids > 0)
5699 {
5700 int i;
5701
5702 appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5703 for (i = 1; i < s->nChildXids; i++)
5704 appendStringInfo(&buf, " %u", s->childXids[i]);
5705 }
5707 (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5708 str, s->nestingLevel,
5709 s->name ? s->name : "unnamed",
5713 (unsigned int) s->subTransactionId,
5714 (unsigned int) currentCommandId,
5715 currentCommandIdUsed ? " (used)" : "",
5716 buf.data)));
5717 pfree(buf.data);
5718}
5719
5720/*
5721 * BlockStateAsString
5722 * Debug support
5723 */
5724static const char *
5726{
5727 switch (blockState)
5728 {
5729 case TBLOCK_DEFAULT:
5730 return "DEFAULT";
5731 case TBLOCK_STARTED:
5732 return "STARTED";
5733 case TBLOCK_BEGIN:
5734 return "BEGIN";
5735 case TBLOCK_INPROGRESS:
5736 return "INPROGRESS";
5738 return "IMPLICIT_INPROGRESS";
5740 return "PARALLEL_INPROGRESS";
5741 case TBLOCK_END:
5742 return "END";
5743 case TBLOCK_ABORT:
5744 return "ABORT";
5745 case TBLOCK_ABORT_END:
5746 return "ABORT_END";
5748 return "ABORT_PENDING";
5749 case TBLOCK_PREPARE:
5750 return "PREPARE";
5751 case TBLOCK_SUBBEGIN:
5752 return "SUBBEGIN";
5754 return "SUBINPROGRESS";
5755 case TBLOCK_SUBRELEASE:
5756 return "SUBRELEASE";
5757 case TBLOCK_SUBCOMMIT:
5758 return "SUBCOMMIT";
5759 case TBLOCK_SUBABORT:
5760 return "SUBABORT";
5762 return "SUBABORT_END";
5764 return "SUBABORT_PENDING";
5765 case TBLOCK_SUBRESTART:
5766 return "SUBRESTART";
5768 return "SUBABORT_RESTART";
5769 }
5770 return "UNRECOGNIZED";
5771}
5772
5773/*
5774 * TransStateAsString
5775 * Debug support
5776 */
5777static const char *
5779{
5780 switch (state)
5781 {
5782 case TRANS_DEFAULT:
5783 return "DEFAULT";
5784 case TRANS_START:
5785 return "START";
5786 case TRANS_INPROGRESS:
5787 return "INPROGRESS";
5788 case TRANS_COMMIT:
5789 return "COMMIT";
5790 case TRANS_ABORT:
5791 return "ABORT";
5792 case TRANS_PREPARE:
5793 return "PREPARE";
5794 }
5795 return "UNRECOGNIZED";
5796}
5797
5798/*
5799 * xactGetCommittedChildren
5800 *
5801 * Gets the list of committed children of the current transaction. The return
5802 * value is the number of child transactions. *ptr is set to point to an
5803 * array of TransactionIds. The array is allocated in TopTransactionContext;
5804 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
5805 * If there are no subxacts, *ptr is set to NULL.
5806 */
5807int
5809{
5811
5812 if (s->nChildXids == 0)
5813 *ptr = NULL;
5814 else
5815 *ptr = s->childXids;
5816
5817 return s->nChildXids;
5818}
5819
5820/*
5821 * XLOG support routines
5822 */
5823
5824
5825/*
5826 * Log the commit record for a plain or twophase transaction commit.
5827 *
5828 * A 2pc commit will be emitted when twophase_xid is valid, a plain one
5829 * otherwise.
5830 */
5833 int nsubxacts, TransactionId *subxacts,
5834 int nrels, RelFileLocator *rels,
5835 int ndroppedstats, xl_xact_stats_item *droppedstats,
5836 int nmsgs, SharedInvalidationMessage *msgs,
5837 bool relcacheInval,
5838 int xactflags, TransactionId twophase_xid,
5839 const char *twophase_gid)
5840{
5841 xl_xact_commit xlrec;
5842 xl_xact_xinfo xl_xinfo;
5843 xl_xact_dbinfo xl_dbinfo;
5844 xl_xact_subxacts xl_subxacts;
5845 xl_xact_relfilelocators xl_relfilelocators;
5846 xl_xact_stats_items xl_dropped_stats;
5847 xl_xact_invals xl_invals;
5848 xl_xact_twophase xl_twophase;
5849 xl_xact_origin xl_origin;
5850 uint8 info;
5851
5853
5854 xl_xinfo.xinfo = 0;
5855
5856 /* decide between a plain and 2pc commit */
5857 if (!TransactionIdIsValid(twophase_xid))
5858 info = XLOG_XACT_COMMIT;
5859 else
5861
5862 /* First figure out and collect all the information needed */
5863
5864 xlrec.xact_time = commit_time;
5865
5866 if (relcacheInval)
5868 if (forceSyncCommit)
5871 xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5872
5873 /*
5874 * Check if the caller would like to ask standbys for immediate feedback
5875 * once this commit is applied.
5876 */
5879
5880 /*
5881 * Relcache invalidations requires information about the current database
5882 * and so does logical decoding.
5883 */
5884 if (nmsgs > 0 || XLogLogicalInfoActive())
5885 {
5886 xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5887 xl_dbinfo.dbId = MyDatabaseId;
5888 xl_dbinfo.tsId = MyDatabaseTableSpace;
5889 }
5890
5891 if (nsubxacts > 0)
5892 {
5893 xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5894 xl_subxacts.nsubxacts = nsubxacts;
5895 }
5896
5897 if (nrels > 0)
5898 {
5900 xl_relfilelocators.nrels = nrels;
5901 info |= XLR_SPECIAL_REL_UPDATE;
5902 }
5903
5904 if (ndroppedstats > 0)
5905 {
5907 xl_dropped_stats.nitems = ndroppedstats;
5908 }
5909
5910 if (nmsgs > 0)
5911 {
5912 xl_xinfo.xinfo |= XACT_XINFO_HAS_INVALS;
5913 xl_invals.nmsgs = nmsgs;
5914 }
5915
5916 if (TransactionIdIsValid(twophase_xid))
5917 {
5918 xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5919 xl_twophase.xid = twophase_xid;
5920 Assert(twophase_gid != NULL);
5921
5923 xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
5924 }
5925
5926 /* dump transaction origin information */
5928 {
5929 xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
5930
5933 }
5934
5935 if (xl_xinfo.xinfo != 0)
5936 info |= XLOG_XACT_HAS_INFO;
5937
5938 /* Then include all the collected data into the commit record. */
5939
5941
5942 XLogRegisterData(&xlrec, sizeof(xl_xact_commit));
5943
5944 if (xl_xinfo.xinfo != 0)
5945 XLogRegisterData(&xl_xinfo.xinfo, sizeof(xl_xinfo.xinfo));
5946
5947 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5948 XLogRegisterData(&xl_dbinfo, sizeof(xl_dbinfo));
5949
5950 if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5951 {
5952 XLogRegisterData(&xl_subxacts,
5954 XLogRegisterData(subxacts,
5955 nsubxacts * sizeof(TransactionId));
5956 }
5957
5959 {
5960 XLogRegisterData(&xl_relfilelocators,
5962 XLogRegisterData(rels,
5963 nrels * sizeof(RelFileLocator));
5964 }
5965
5966 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
5967 {
5968 XLogRegisterData(&xl_dropped_stats,
5970 XLogRegisterData(droppedstats,
5971 ndroppedstats * sizeof(xl_xact_stats_item));
5972 }
5973
5974 if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
5975 {
5977 XLogRegisterData(msgs,
5978 nmsgs * sizeof(SharedInvalidationMessage));
5979 }
5980
5981 if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5982 {
5983 XLogRegisterData(&xl_twophase, sizeof(xl_xact_twophase));
5984 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
5985 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
5986 }
5987
5988 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5989 XLogRegisterData(&xl_origin, sizeof(xl_xact_origin));
5990
5991 /* we allow filtering by xacts */
5993
5994 return XLogInsert(RM_XACT_ID, info);
5995}
5996
5997/*
5998 * Log the commit record for a plain or twophase transaction abort.
5999 *
6000 * A 2pc abort will be emitted when twophase_xid is valid, a plain one
6001 * otherwise.
6002 */
6005 int nsubxacts, TransactionId *subxacts,
6006 int nrels, RelFileLocator *rels,
6007 int ndroppedstats, xl_xact_stats_item *droppedstats,
6008 int xactflags, TransactionId twophase_xid,
6009 const char *twophase_gid)
6010{
6011 xl_xact_abort xlrec;
6012 xl_xact_xinfo xl_xinfo;
6013 xl_xact_subxacts xl_subxacts;
6014 xl_xact_relfilelocators xl_relfilelocators;
6015 xl_xact_stats_items xl_dropped_stats;
6016 xl_xact_twophase xl_twophase;
6017 xl_xact_dbinfo xl_dbinfo;
6018 xl_xact_origin xl_origin;
6019
6020 uint8 info;
6021
6023
6024 xl_xinfo.xinfo = 0;
6025
6026 /* decide between a plain and 2pc abort */
6027 if (!TransactionIdIsValid(twophase_xid))
6028 info = XLOG_XACT_ABORT;
6029 else
6031
6032
6033 /* First figure out and collect all the information needed */
6034
6035 xlrec.xact_time = abort_time;
6036
6038 xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
6039
6040 if (nsubxacts > 0)
6041 {
6042 xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
6043 xl_subxacts.nsubxacts = nsubxacts;
6044 }
6045
6046 if (nrels > 0)
6047 {
6049 xl_relfilelocators.nrels = nrels;
6050 info |= XLR_SPECIAL_REL_UPDATE;
6051 }
6052
6053 if (ndroppedstats > 0)
6054 {
6056 xl_dropped_stats.nitems = ndroppedstats;
6057 }
6058
6059 if (TransactionIdIsValid(twophase_xid))
6060 {
6061 xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
6062 xl_twophase.xid = twophase_xid;
6063 Assert(twophase_gid != NULL);
6064
6066 xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
6067 }
6068
6069 if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6070 {
6071 xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
6072 xl_dbinfo.dbId = MyDatabaseId;
6073 xl_dbinfo.tsId = MyDatabaseTableSpace;
6074 }
6075
6076 /*
6077 * Dump transaction origin information. We need this during recovery to
6078 * update the replication origin progress.
6079 */
6081 {
6082 xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
6083
6086 }
6087
6088 if (xl_xinfo.xinfo != 0)
6089 info |= XLOG_XACT_HAS_INFO;
6090
6091 /* Then include all the collected data into the abort record. */
6092
6094
6096
6097 if (xl_xinfo.xinfo != 0)
6098 XLogRegisterData(&xl_xinfo, sizeof(xl_xinfo));
6099
6100 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6101 XLogRegisterData(&xl_dbinfo, sizeof(xl_dbinfo));
6102
6103 if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
6104 {
6105 XLogRegisterData(&xl_subxacts,
6107 XLogRegisterData(subxacts,
6108 nsubxacts * sizeof(TransactionId));
6109 }
6110
6112 {
6113 XLogRegisterData(&xl_relfilelocators,
6115 XLogRegisterData(rels,
6116 nrels * sizeof(RelFileLocator));
6117 }
6118
6119 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
6120 {
6121 XLogRegisterData(&xl_dropped_stats,
6123 XLogRegisterData(droppedstats,
6124 ndroppedstats * sizeof(xl_xact_stats_item));
6125 }
6126
6127 if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
6128 {
6129 XLogRegisterData(&xl_twophase, sizeof(xl_xact_twophase));
6130 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6131 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6132 }
6133
6134 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6135 XLogRegisterData(&xl_origin, sizeof(xl_xact_origin));
6136
6137 /* Include the replication origin */
6139
6140 return XLogInsert(RM_XACT_ID, info);
6141}
6142
6143/*
6144 * Before 9.0 this was a fairly short function, but now it performs many
6145 * actions for which the order of execution is critical.
6146 */
6147static void
6149 TransactionId xid,
6150 XLogRecPtr lsn,
6151 RepOriginId origin_id)
6152{
6153 TransactionId max_xid;
6154 TimestampTz commit_time;
6155
6157
6158 max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
6159
6160 /* Make sure nextXid is beyond any XID mentioned in the record. */
6162
6163 Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) ==
6164 (origin_id == InvalidRepOriginId));
6165
6166 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6167 commit_time = parsed->origin_timestamp;
6168 else
6169 commit_time = parsed->xact_time;
6170
6171 /* Set the transaction commit timestamp and metadata */
6173 commit_time, origin_id);
6174
6176 {
6177 /*
6178 * Mark the transaction committed in pg_xact.
6179 */
6180 TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
6181 }
6182 else
6183 {
6184 /*
6185 * If a transaction completion record arrives that has as-yet
6186 * unobserved subtransactions then this will not have been fully
6187 * handled by the call to RecordKnownAssignedTransactionIds() in the
6188 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6189 * cover that case. This is confusing and it is easy to think this
6190 * call is irrelevant, which has happened three times in development
6191 * already. Leave it in.
6192 */
6194
6195 /*
6196 * Mark the transaction committed in pg_xact. We use async commit
6197 * protocol during recovery to provide information on database
6198 * consistency for when users try to set hint bits. It is important
6199 * that we do not set hint bits until the minRecoveryPoint is past
6200 * this commit record. This ensures that if we crash we don't see hint
6201 * bits set on changes made by transactions that haven't yet
6202 * recovered. It's unlikely but it's good to be safe.
6203 */
6204 TransactionIdAsyncCommitTree(xid, parsed->nsubxacts, parsed->subxacts, lsn);
6205
6206 /*
6207 * We must mark clog before we update the ProcArray.
6208 */
6209 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6210
6211 /*
6212 * Send any cache invalidations attached to the commit. We must
6213 * maintain the same order of invalidation then release locks as
6214 * occurs in CommitTransaction().
6215 */
6218 parsed->dbId, parsed->tsId);
6219
6220 /*
6221 * Release locks, if any. We do this for both two phase and normal one
6222 * phase transactions. In effect we are ignoring the prepare phase and
6223 * just going straight to lock release.
6224 */
6225 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6226 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6227 }
6228
6229 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6230 {
6231 /* recover apply progress */
6232 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6233 false /* backward */ , false /* WAL */ );
6234 }
6235
6236 /* Make sure files supposed to be dropped are dropped */
6237 if (parsed->nrels > 0)
6238 {
6239 /*
6240 * First update minimum recovery point to cover this WAL record. Once
6241 * a relation is deleted, there's no going back. The buffer manager
6242 * enforces the WAL-first rule for normal updates to relation files,
6243 * so that the minimum recovery point is always updated before the
6244 * corresponding change in the data file is flushed to disk, but we
6245 * have to do the same here since we're bypassing the buffer manager.
6246 *
6247 * Doing this before deleting the files means that if a deletion fails
6248 * for some reason, you cannot start up the system even after restart,
6249 * until you fix the underlying situation so that the deletion will
6250 * succeed. Alternatively, we could update the minimum recovery point
6251 * after deletion, but that would leave a small window where the
6252 * WAL-first rule would be violated.
6253 */
6254 XLogFlush(lsn);
6255
6256 /* Make sure files supposed to be dropped are dropped */
6257 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6258 }
6259
6260 if (parsed->nstats > 0)
6261 {
6262 /* see equivalent call for relations above */
6263 XLogFlush(lsn);
6264
6265 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6266 }
6267
6268 /*
6269 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
6270 * in normal operation. For example, in CREATE DATABASE, we copy all files
6271 * from the template database, and then commit the transaction. If we
6272 * crash after all the files have been copied but before the commit, you
6273 * have files in the data directory without an entry in pg_database. To
6274 * minimize the window for that, we use ForceSyncCommit() to rush the
6275 * commit record to disk as quick as possible. We have the same window
6276 * during recovery, and forcing an XLogFlush() (which updates
6277 * minRecoveryPoint during recovery) helps to reduce that problem window,
6278 * for any user that requested ForceSyncCommit().
6279 */
6281 XLogFlush(lsn);
6282
6283 /*
6284 * If asked by the primary (because someone is waiting for a synchronous
6285 * commit = remote_apply), we will need to ask walreceiver to send a reply
6286 * immediately.
6287 */
6290}
6291
6292/*
6293 * Be careful with the order of execution, as with xact_redo_commit().
6294 * The two functions are similar but differ in key places.
6295 *
6296 * Note also that an abort can be for a subtransaction and its children,
6297 * not just for a top level abort. That means we have to consider
6298 * topxid != xid, whereas in commit we would find topxid == xid always
6299 * because subtransaction commit is never WAL logged.
6300 */
6301static void
6303 XLogRecPtr lsn, RepOriginId origin_id)
6304{
6305 TransactionId max_xid;
6306
6308
6309 /* Make sure nextXid is beyond any XID mentioned in the record. */
6310 max_xid = TransactionIdLatest(xid,
6311 parsed->nsubxacts,
6312 parsed->subxacts);
6314
6316 {
6317 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6318 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6319 }
6320 else
6321 {
6322 /*
6323 * If a transaction completion record arrives that has as-yet
6324 * unobserved subtransactions then this will not have been fully
6325 * handled by the call to RecordKnownAssignedTransactionIds() in the
6326 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6327 * cover that case. This is confusing and it is easy to think this
6328 * call is irrelevant, which has happened three times in development
6329 * already. Leave it in.
6330 */
6332
6333 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6334 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6335
6336 /*
6337 * We must update the ProcArray after we have marked clog.
6338 */
6339 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6340
6341 /*
6342 * There are no invalidation messages to send or undo.
6343 */
6344
6345 /*
6346 * Release locks, if any. There are no invalidations to send.
6347 */
6348 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6349 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6350 }
6351
6352 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6353 {
6354 /* recover apply progress */
6355 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6356 false /* backward */ , false /* WAL */ );
6357 }
6358
6359 /* Make sure files supposed to be dropped are dropped */
6360 if (parsed->nrels > 0)
6361 {
6362 /*
6363 * See comments about update of minimum recovery point on truncation,
6364 * in xact_redo_commit().
6365 */
6366 XLogFlush(lsn);
6367
6368 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6369 }
6370
6371 if (parsed->nstats > 0)
6372 {
6373 /* see equivalent call for relations above */
6374 XLogFlush(lsn);
6375
6376 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6377 }
6378}
6379
6380void
6382{
6383 uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6384
6385 /* Backup blocks are not used in xact records */
6387
6388 if (info == XLOG_XACT_COMMIT)
6389 {
6390 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6391 xl_xact_parsed_commit parsed;
6392
6393 ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6394 xact_redo_commit(&parsed, XLogRecGetXid(record),
6395 record->EndRecPtr, XLogRecGetOrigin(record));
6396 }
6397 else if (info == XLOG_XACT_COMMIT_PREPARED)
6398 {
6399 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6400 xl_xact_parsed_commit parsed;
6401
6402 ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6403 xact_redo_commit(&parsed, parsed.twophase_xid,
6404 record->EndRecPtr, XLogRecGetOrigin(record));
6405
6406 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6407 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6408 PrepareRedoRemove(parsed.twophase_xid, false);
6409 LWLockRelease(TwoPhaseStateLock);
6410 }
6411 else if (info == XLOG_XACT_ABORT)
6412 {
6413 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6414 xl_xact_parsed_abort parsed;
6415
6416 ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6417 xact_redo_abort(&parsed, XLogRecGetXid(record),
6418 record->EndRecPtr, XLogRecGetOrigin(record));
6419 }
6420 else if (info == XLOG_XACT_ABORT_PREPARED)
6421 {
6422 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6423 xl_xact_parsed_abort parsed;
6424
6425 ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6426 xact_redo_abort(&parsed, parsed.twophase_xid,
6427 record->EndRecPtr, XLogRecGetOrigin(record));
6428
6429 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6430 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6431 PrepareRedoRemove(parsed.twophase_xid, false);
6432 LWLockRelease(TwoPhaseStateLock);
6433 }
6434 else if (info == XLOG_XACT_PREPARE)
6435 {
6436 /*
6437 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6438 * gxact entry.
6439 */
6440 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6442 XLogRecGetData(record),
6443 record->ReadRecPtr,
6444 record->EndRecPtr,
6445 XLogRecGetOrigin(record));
6446 LWLockRelease(TwoPhaseStateLock);
6447 }
6448 else if (info == XLOG_XACT_ASSIGNMENT)
6449 {
6451
6454 xlrec->nsubxacts, xlrec->xsub);
6455 }
6456 else if (info == XLOG_XACT_INVALIDATIONS)
6457 {
6458 /*
6459 * XXX we do ignore this for now, what matters are invalidations
6460 * written into the commit record.
6461 */
6462 }
6463 else
6464 elog(PANIC, "xact_redo: unknown op code %u", info);
6465}
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:967
void AtAbort_Notify(void)
Definition: async.c:1671
void PreCommit_Notify(void)
Definition: async.c:860
void AtSubAbort_Notify(void)
Definition: async.c:1761
void AtPrepare_Notify(void)
Definition: async.c:835
void AtSubCommit_Notify(void)
Definition: async.c:1691
#define pg_write_barrier()
Definition: atomics.h:155
void ParallelWorkerReportLastRecEnd(XLogRecPtr last_xlog_end)
Definition: parallel.c:1586
bool ParallelContextActive(void)
Definition: parallel.c:1024
void AtEOSubXact_Parallel(bool isCommit, SubTransactionId mySubId)
Definition: parallel.c:1254
void AtEOXact_Parallel(bool isCommit)
Definition: parallel.c:1275
sigset_t UnBlockSig
Definition: pqsignal.c:22
void AtEOXact_LogicalRepWorkers(bool isCommit)
Definition: worker.c:6269
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1645
void pgstat_progress_end_command(void)
void pgstat_report_xact_timestamp(TimestampTz tstamp)
void AtEOXact_LargeObject(bool isCommit)
Definition: be-fsstubs.c:607
void AtEOSubXact_LargeObject(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: be-fsstubs.c:653
static int32 next
Definition: blutils.c:224
static void cleanup(void)
Definition: bootstrap.c:715
void AtEOXact_Buffers(bool isCommit)
Definition: bufmgr.c:3990
void UnlockBuffers(void)
Definition: bufmgr.c:5573
#define InvalidCommandId
Definition: c.h:679
#define TopSubTransactionId
Definition: c.h:669
#define Min(x, y)
Definition: c.h:1008
uint8_t uint8
Definition: c.h:541
uint32 SubTransactionId
Definition: c.h:666
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:228
#define InvalidSubTransactionId
Definition: c.h:668
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:475
#define FirstCommandId
Definition: c.h:678
uint32 LocalTransactionId
Definition: c.h:664
uint32 CommandId
Definition: c.h:676
uint32 TransactionId
Definition: c.h:662
size_t Size
Definition: c.h:615
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:3226
void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: fd.c:3193
#define MaxAllocSize
Definition: fe_memutils.h:22
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
Assert(PointerIsAligned(start, uint64))
const char * str
#define IsParallelWorker()
Definition: parallel.h:60
void ResetReindexState(int nestLevel)
Definition: index.c:4213
void PostPrepare_Inval(void)
Definition: inval.c:993
void LogLogicalInvalidations(void)
Definition: inval.c:1935
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:3574
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
Definition: lock.c:4622
void AtPrepare_Locks(void)
Definition: lock.c:3478
#define InvalidLocalTransactionId
Definition: lock.h:67
void ResetLogicalStreamingState(void)
Definition: logical.c:1942
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1174
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1894
void LWLockReleaseAll(void)
Definition: lwlock.c:1945
@ LW_EXCLUSIVE
Definition: lwlock.h:112
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1746
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1229
bool MemoryContextIsEmpty(MemoryContext context)
Definition: mcxt.c:789
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:400
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1263
MemoryContext TopTransactionContext
Definition: mcxt.c:171
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1610
void pfree(void *pointer)
Definition: mcxt.c:1594
MemoryContext TopMemoryContext
Definition: mcxt.c:166
void * palloc(Size size)
Definition: mcxt.c:1365
MemoryContext CurTransactionContext
Definition: mcxt.c:172
MemoryContext CurrentMemoryContext
Definition: mcxt.c:160
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:469
void DropRelationFiles(RelFileLocator *delrels, int ndelrels, bool isRedo)
Definition: md.c:1597
#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:1841
void AtPrepare_MultiXact(void)
Definition: multixact.c:1827
void AtEOXact_MultiXact(void)
Definition: multixact.c:1799
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:165
void replorigin_session_advance(XLogRecPtr remote_commit, XLogRecPtr local_commit)
Definition: origin.c:1255
RepOriginId replorigin_session_origin
Definition: origin.c:163
void replorigin_advance(RepOriginId node, XLogRecPtr remote_commit, XLogRecPtr local_commit, bool go_backward, bool wal_log)
Definition: origin.c:911
XLogRecPtr replorigin_session_origin_lsn
Definition: origin.c:164
#define DoNotReplicateId
Definition: origin.h:34
#define InvalidRepOriginId
Definition: origin.h:33
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
void * arg
void AtEOXact_Enum(void)
Definition: pg_enum.c: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
Definition: pg_test_fsync.c:72
void AtPrepare_PgStat(void)
Definition: pgstat_xact.c:191
void pgstat_execute_transactional_drops(int ndrops, struct xl_xact_stats_item *items, bool is_redo)
Definition: pgstat_xact.c:314
void AtEOXact_PgStat(bool isCommit, bool parallel)
Definition: pgstat_xact.c:40
void PostPrepare_PgStat(void)
Definition: pgstat_xact.c:211
int pgstat_get_transactional_drops(bool isCommit, xl_xact_stats_item **items)
Definition: pgstat_xact.c:272
void AtEOSubXact_PgStat(bool isCommit, int nestDepth)
Definition: pgstat_xact.c:113
#define qsort(a, b, c, d)
Definition: port.h:479
void AtAbort_Portals(void)
Definition: portalmem.c:781
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition: portalmem.c:979
bool PreCommit_Portals(bool isPrepare)
Definition: portalmem.c:677
void AtSubCommit_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, int parentLevel, ResourceOwner parentXactOwner)
Definition: portalmem.c:943
void AtCleanup_Portals(void)
Definition: portalmem.c:858
void AtSubCleanup_Portals(SubTransactionId mySubid)
Definition: portalmem.c:1092
unsigned int Oid
Definition: postgres_ext.h:32
void PreCommit_CheckForSerializationFailure(void)
Definition: predicate.c:4703
void PostPrepare_PredicateLocks(FullTransactionId fxid)
Definition: predicate.c:4859
void AtPrepare_PredicateLocks(void)
Definition: predicate.c:4790
void RegisterPredicateLockingXid(TransactionId xid)
Definition: predicate.c:1959
#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:3953
void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
Definition: procarray.c:667
void RecordKnownAssignedTransactionIds(TransactionId xid)
Definition: procarray.c:4365
void ProcArrayClearTransaction(PGPROC *proc)
Definition: procarray.c:907
void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)
Definition: procarray.c:1318
void ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids, TransactionId *subxids, TransactionId max_xid)
Definition: procarray.c:4434
void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: relcache.c:3378
void AtEOXact_RelationCache(bool isCommit)
Definition: relcache.c:3226
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:494
Size mul_size(Size s1, Size s2)
Definition: shmem.c:511
LocalTransactionId GetNextLocalTransactionId(void)
Definition: sinvaladt.c:701
void AtEOXact_SMgr(void)
Definition: smgr.c:1008
void SnapBuildResetExportedSnapshotState(void)
Definition: snapbuild.c:627
void AtSubAbort_Snapshot(int level)
Definition: snapmgr.c:980
void AtEOXact_Snapshot(bool isCommit, bool resetXmin)
Definition: snapmgr.c:1014
void AtSubCommit_Snapshot(int level)
Definition: snapmgr.c:959
bool XactHasExportedSnapshots(void)
Definition: snapmgr.c:1572
void SnapshotSetCommandId(CommandId curcid)
Definition: snapmgr.c:488
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)
Definition: stack_depth.c:109
void StandbyReleaseLockTree(TransactionId xid, int nsubxids, TransactionId *subxids)
Definition: standby.c:1092
void LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInitFileInval)
Definition: standby.c:1470
void AtSubCommit_smgr(void)
Definition: storage.c:955
void AtSubAbort_smgr(void)
Definition: storage.c:975
int smgrGetPendingDeletes(bool forCommit, RelFileLocator **ptr)
Definition: storage.c:893
void PostPrepare_smgr(void)
Definition: storage.c:934
void smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
Definition: storage.c:741
void smgrDoPendingDeletes(bool isCommit)
Definition: storage.c:673
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
LocalTransactionId lxid
Definition: proc.h:217
struct PGPROC::@130 vxid
ProcNumber procNumber
Definition: proc.h:212
int delayChkptFlags
Definition: proc.h:257
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
int parallelModeLevel
Definition: xact.c:215
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
Definition: regguts.h:323
TimestampTz xact_time
Definition: xact.h:339
TransactionId xtop
Definition: xact.h:221
TransactionId xsub[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:223
TimestampTz xact_time
Definition: xact.h:323
Oid tsId
Definition: xact.h:259
Oid dbId
Definition: xact.h:258
int nmsgs
Definition: xact.h:305
TimestampTz origin_timestamp
Definition: xact.h:318
XLogRecPtr origin_lsn
Definition: xact.h:317
xl_xact_stats_item * stats
Definition: xact.h:426
RelFileLocator * xlocators
Definition: xact.h:423
TransactionId twophase_xid
Definition: xact.h:428
TransactionId * subxacts
Definition: xact.h:420
XLogRecPtr origin_lsn
Definition: xact.h:431
xl_xact_stats_item * stats
Definition: xact.h:393
TimestampTz xact_time
Definition: xact.h:380
TransactionId twophase_xid
Definition: xact.h:398
RelFileLocator * xlocators
Definition: xact.h:390
TimestampTz origin_timestamp
Definition: xact.h:406
TransactionId * subxacts
Definition: xact.h:387
XLogRecPtr origin_lsn
Definition: xact.h:405
SharedInvalidationMessage * msgs
Definition: xact.h:396
int nsubxacts
Definition: xact.h:264
TransactionId xid
Definition: xact.h:312
uint32 xinfo
Definition: xact.h:253
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)
Definition: tablecmds.c:19449
void PreCommit_on_commit_actions(void)
Definition: tablecmds.c:19310
void AtEOXact_on_commit_actions(bool isCommit)
Definition: tablecmds.c:19417
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:46
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition: timeout.c:560
void reschedule_timeouts(void)
Definition: timeout.c:540
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition: timeout.c:685
@ TRANSACTION_TIMEOUT
Definition: timeout.h:34
void TransactionIdAsyncCommitTree(TransactionId xid, int nxids, TransactionId *xids, XLogRecPtr lsn)
Definition: transam.c:252
TransactionId TransactionIdLatest(TransactionId mainxid, int nxids, const TransactionId *xids)
Definition: transam.c: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:5072
void AfterTriggerEndSubXact(bool isCommit)
Definition: trigger.c:5435
void AfterTriggerFireDeferred(void)
Definition: trigger.c:5283
void AfterTriggerEndXact(bool isCommit)
Definition: trigger.c:5339
void AfterTriggerBeginSubXact(void)
Definition: trigger.c:5387
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:3193
bool IsTransactionOrTransactionBlock(void)
Definition: xact.c:5007
struct SerializedTransactionState SerializedTransactionState
void SerializeTransactionState(Size maxsize, char *start_address)
Definition: xact.c:5558
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:3154
static void CleanupSubTransaction(void)
Definition: xact.c:5401
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4712
static void AtStart_Memory(void)
Definition: xact.c:1177
FullTransactionId GetCurrentFullTransactionId(void)
Definition: xact.c:513
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition: xact.c:3162
static XactCallbackItem * Xact_callbacks
Definition: xact.c:316
void WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
Definition: xact.c:3728
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:4222
bool IsInTransactionBlock(bool isTopLevel)
Definition: xact.c:3787
bool PrepareTransactionBlock(const char *gid)
Definition: xact.c:4010
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:6381
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:3916
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:3743
void UnregisterSubXactCallback(SubXactCallback callback, void *arg)
Definition: xact.c:3895
bool XactDeferrable
Definition: xact.c:86
static bool forceSyncCommit
Definition: xact.c:294
void BeginImplicitTransactionBlock(void)
Definition: xact.c:4344
static void CallXactCallbacks(XactEvent event)
Definition: xact.c:3856
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:6148
void RequireTransactionBlock(bool isTopLevel, const char *stmtType)
Definition: xact.c:3734
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:4391
bool DefaultXactDeferrable
Definition: xact.c:85
static void CleanupTransaction(void)
Definition: xact.c:3027
static int nUnreportedXids
Definition: xact.c:258
static const char * TransStateAsString(TransState state)
Definition: xact.c:5778
static TimestampTz xactStopTimestamp
Definition: xact.c:283
bool TransactionStartedDuringRecovery(void)
Definition: xact.c:1043
static void CommitSubTransaction(void)
Definition: xact.c:5122
bool XactReadOnly
Definition: xact.c:83
static void PushTransaction(void)
Definition: xact.c:5434
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:3835
bool IsTransactionState(void)
Definition: xact.c:388
struct SubXactCallbackItem SubXactCallbackItem
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:3666
static void AtCleanup_Memory(void)
Definition: xact.c:1987
Size EstimateTransactionStateSpace(void)
Definition: xact.c:5530
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:3487
struct XactCallbackItem XactCallbackItem
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:6302
char TransactionBlockStatusCode(void)
Definition: xact.c:5021
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4814
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:3077
static void PopTransaction(void)
Definition: xact.c:5496
bool IsAbortedTransactionBlockState(void)
Definition: xact.c:408
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4786
void EndImplicitTransactionBlock(void)
Definition: xact.c:4369
void StartParallelWorkerTransaction(char *tstatespace)
Definition: xact.c:5629
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:4476
static TransactionStateData TopTransactionStateData
Definition: xact.c:248
static FullTransactionId XactTopFullTransactionId
Definition: xact.c:126
static void ShowTransactionState(const char *str)
Definition: xact.c:5666
int XactIsoLevel
Definition: xact.c:80
static void PrepareTransaction(void)
Definition: xact.c:2528
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:5832
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:5237
bool IsSubTransaction(void)
Definition: xact.c:5062
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:4989
bool IsInParallelMode(void)
Definition: xact.c:1090
int xactGetCommittedChildren(TransactionId **ptr)
Definition: xact.c:5808
struct TransactionStateData TransactionStateData
TransactionId GetCurrentTransactionIdIfAny(void)
Definition: xact.c:472
void BeginTransactionBlock(void)
Definition: xact.c:3942
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:5725
void EndParallelWorkerTransaction(void)
Definition: xact.c:5654
static void AtAbort_Memory(void)
Definition: xact.c:1897
void RegisterXactCallback(XactCallback callback, void *arg)
Definition: xact.c:3822
void CommitTransactionCommand(void)
Definition: xact.c:3175
void RollbackToSavepoint(const char *name)
Definition: xact.c:4585
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:3882
FullTransactionId GetTopFullTransactionIdIfAny(void)
Definition: xact.c:500
TransactionId GetCurrentTransactionId(void)
Definition: xact.c:455
static void AbortTransaction(void)
Definition: xact.c:2822
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:4062
bool IsSubxactTopXidLogPending(void)
Definition: xact.c:560
#define SerializedTransactionStateHeaderSize
Definition: xact.c:240
void AbortOutOfAnyTransaction(void)
Definition: xact.c:4880
int MyXactFlags
Definition: xact.c:137
static void ShowTransactionStateRec(const char *str, TransactionState s)
Definition: xact.c:5678
static TransactionState CurrentTransactionState
Definition: xact.c:261
void AbortCurrentTransaction(void)
Definition: xact.c:3469
static void StartSubTransaction(void)
Definition: xact.c:5085
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:6004
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:6406
XLogRecPtr XactLastRecEnd
Definition: xlog.c:256
XLogRecPtr XactLastCommitEnd
Definition: xlog.c:257
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2783
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition: xlog.c:2612
#define XLogLogicalInfoActive()
Definition: xlog.h:126
#define XLOG_INCLUDE_ORIGIN
Definition: xlog.h:154
#define XLogStandbyInfoActive()
Definition: xlog.h:123
uint16 RepOriginId
Definition: xlogdefs.h: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:290