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-2024, 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 "catalog/index.h"
35 #include "catalog/namespace.h"
36 #include "catalog/pg_enum.h"
37 #include "catalog/storage.h"
38 #include "commands/async.h"
39 #include "commands/tablecmds.h"
40 #include "commands/trigger.h"
41 #include "common/pg_prng.h"
42 #include "executor/spi.h"
43 #include "libpq/be-fsstubs.h"
44 #include "libpq/pqsignal.h"
45 #include "miscadmin.h"
46 #include "pg_trace.h"
47 #include "pgstat.h"
48 #include "replication/logical.h"
51 #include "replication/origin.h"
52 #include "replication/snapbuild.h"
53 #include "replication/syncrep.h"
55 #include "storage/fd.h"
56 #include "storage/lmgr.h"
57 #include "storage/md.h"
58 #include "storage/predicate.h"
59 #include "storage/proc.h"
60 #include "storage/procarray.h"
61 #include "storage/sinvaladt.h"
62 #include "storage/smgr.h"
63 #include "utils/builtins.h"
64 #include "utils/combocid.h"
65 #include "utils/guc.h"
66 #include "utils/inval.h"
67 #include "utils/memutils.h"
68 #include "utils/relmapper.h"
69 #include "utils/snapmgr.h"
70 #include "utils/timeout.h"
71 #include "utils/timestamp.h"
72 
73 /*
74  * User-tweakable parameters
75  */
78 
79 bool DefaultXactReadOnly = false;
81 
82 bool DefaultXactDeferrable = false;
84 
86 
87 /*
88  * CheckXidAlive is a xid value pointing to a possibly ongoing (sub)
89  * transaction. Currently, it is used in logical decoding. It's possible
90  * that such transactions can get aborted while the decoding is ongoing in
91  * which case we skip decoding that particular transaction. To ensure that we
92  * check whether the CheckXidAlive is aborted after fetching the tuple from
93  * system tables. We also ensure that during logical decoding we never
94  * directly access the tableam or heap APIs because we are checking for the
95  * concurrent aborts only in systable_* APIs.
96  */
98 bool bsysscan = false;
99 
100 /*
101  * When running as a parallel worker, we place only a single
102  * TransactionStateData on the parallel worker's state stack, and the XID
103  * reflected there will be that of the *innermost* currently-active
104  * subtransaction in the backend that initiated parallelism. However,
105  * GetTopTransactionId() and TransactionIdIsCurrentTransactionId()
106  * need to return the same answers in the parallel worker as they would have
107  * in the user backend, so we need some additional bookkeeping.
108  *
109  * XactTopFullTransactionId stores the XID of our toplevel transaction, which
110  * will be the same as TopTransactionStateData.fullTransactionId in an
111  * ordinary backend; but in a parallel backend, which does not have the entire
112  * transaction state, it will instead be copied from the backend that started
113  * the parallel operation.
114  *
115  * nParallelCurrentXids will be 0 and ParallelCurrentXids NULL in an ordinary
116  * backend, but in a parallel backend, nParallelCurrentXids will contain the
117  * number of XIDs that need to be considered current, and ParallelCurrentXids
118  * will contain the XIDs themselves. This includes all XIDs that were current
119  * or sub-committed in the parent at the time the parallel operation began.
120  * The XIDs are stored sorted in numerical order (not logical order) to make
121  * lookups as fast as possible.
122  */
124 static int nParallelCurrentXids = 0;
126 
127 /*
128  * Miscellaneous flag bits to record events which occur on the top level
129  * transaction. These flags are only persisted in MyXactFlags and are intended
130  * so we remember to do certain things later on in the transaction. This is
131  * globally accessible, so can be set from anywhere in the code that requires
132  * recording flags.
133  */
135 
136 /*
137  * transaction states - transaction state from server perspective
138  */
139 typedef enum TransState
140 {
141  TRANS_DEFAULT, /* idle */
142  TRANS_START, /* transaction starting */
143  TRANS_INPROGRESS, /* inside a valid transaction */
144  TRANS_COMMIT, /* commit in progress */
145  TRANS_ABORT, /* abort in progress */
146  TRANS_PREPARE, /* prepare in progress */
148 
149 /*
150  * transaction block states - transaction state of client queries
151  *
152  * Note: the subtransaction states are used only for non-topmost
153  * transactions; the others appear only in the topmost transaction.
154  */
155 typedef enum TBlockState
156 {
157  /* not-in-transaction-block states */
158  TBLOCK_DEFAULT, /* idle */
159  TBLOCK_STARTED, /* running single-query transaction */
160 
161  /* transaction block states */
162  TBLOCK_BEGIN, /* starting transaction block */
163  TBLOCK_INPROGRESS, /* live transaction */
164  TBLOCK_IMPLICIT_INPROGRESS, /* live transaction after implicit BEGIN */
165  TBLOCK_PARALLEL_INPROGRESS, /* live transaction inside parallel worker */
166  TBLOCK_END, /* COMMIT received */
167  TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
168  TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
169  TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
170  TBLOCK_PREPARE, /* live xact, PREPARE received */
171 
172  /* subtransaction states */
173  TBLOCK_SUBBEGIN, /* starting a subtransaction */
174  TBLOCK_SUBINPROGRESS, /* live subtransaction */
175  TBLOCK_SUBRELEASE, /* RELEASE received */
176  TBLOCK_SUBCOMMIT, /* COMMIT received while TBLOCK_SUBINPROGRESS */
177  TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
178  TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
179  TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
180  TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
181  TBLOCK_SUBABORT_RESTART, /* failed subxact, ROLLBACK TO received */
183 
184 /*
185  * transaction state structure
186  *
187  * Note: parallelModeLevel counts the number of unmatched EnterParallelMode
188  * calls done at this transaction level. parallelChildXact is true if any
189  * upper transaction level has nonzero parallelModeLevel.
190  */
191 typedef struct TransactionStateData
192 {
193  FullTransactionId fullTransactionId; /* my FullTransactionId */
194  SubTransactionId subTransactionId; /* my subxact ID */
195  char *name; /* savepoint name, if any */
196  int savepointLevel; /* savepoint level */
197  TransState state; /* low-level state */
198  TBlockState blockState; /* high-level state */
199  int nestingLevel; /* transaction nesting depth */
200  int gucNestLevel; /* GUC context nesting depth */
201  MemoryContext curTransactionContext; /* my xact-lifetime context */
202  ResourceOwner curTransactionOwner; /* my query resources */
203  TransactionId *childXids; /* subcommitted child XIDs, in XID order */
204  int nChildXids; /* # of subcommitted child XIDs */
205  int maxChildXids; /* allocated size of childXids[] */
206  Oid prevUser; /* previous CurrentUserId setting */
207  int prevSecContext; /* previous SecurityRestrictionContext */
208  bool prevXactReadOnly; /* entry-time xact r/o state */
209  bool startedInRecovery; /* did we start in recovery? */
210  bool didLogXid; /* has xid been included in WAL record? */
211  int parallelModeLevel; /* Enter/ExitParallelMode counter */
212  bool parallelChildXact; /* is any parent transaction parallel? */
213  bool chain; /* start a new block after this one */
214  bool topXidLogged; /* for a subxact: is top-level XID logged? */
215  struct TransactionStateData *parent; /* back link to parent */
217 
219 
220 /*
221  * Serialized representation used to transmit transaction state to parallel
222  * workers through shared memory.
223  */
225 {
234 
235 /* The size of SerializedTransactionState, not including the final array. */
236 #define SerializedTransactionStateHeaderSize \
237  offsetof(SerializedTransactionState, parallelCurrentXids)
238 
239 /*
240  * CurrentTransactionState always points to the current transaction state
241  * block. It will point to TopTransactionStateData when not in a
242  * transaction at all, or when in a top-level transaction.
243  */
245  .state = TRANS_DEFAULT,
246  .blockState = TBLOCK_DEFAULT,
247  .topXidLogged = false,
248 };
249 
250 /*
251  * unreportedXids holds XIDs of all subtransactions that have not yet been
252  * reported in an XLOG_XACT_ASSIGNMENT record.
253  */
254 static int nUnreportedXids;
256 
258 
259 /*
260  * The subtransaction ID and command ID assignment counters are global
261  * to a whole transaction, so we do not keep them in the state stack.
262  */
266 
267 /*
268  * xactStartTimestamp is the value of transaction_timestamp().
269  * stmtStartTimestamp is the value of statement_timestamp().
270  * xactStopTimestamp is the time at which we log a commit / abort WAL record,
271  * or if that was skipped, the time of the first subsequent
272  * GetCurrentTransactionStopTimestamp() call.
273  *
274  * These do not change as we enter and exit subtransactions, so we don't
275  * keep them inside the TransactionState stack.
276  */
280 
281 /*
282  * GID to be used for preparing the current transaction. This is also
283  * global to a whole transaction, so we don't keep it in the state stack.
284  */
285 static char *prepareGID;
286 
287 /*
288  * Some commands want to force synchronous commit.
289  */
290 static bool forceSyncCommit = false;
291 
292 /* Flag for logging statements in a transaction. */
293 bool xact_is_sampled = false;
294 
295 /*
296  * Private context for transaction-abort work --- we reserve space for this
297  * at startup to ensure that AbortTransaction and AbortSubTransaction can work
298  * when we've run out of memory.
299  */
301 
302 /*
303  * List of add-on start- and end-of-xact callbacks
304  */
305 typedef struct XactCallbackItem
306 {
309  void *arg;
311 
313 
314 /*
315  * List of add-on start- and end-of-subxact callbacks
316  */
317 typedef struct SubXactCallbackItem
318 {
321  void *arg;
323 
325 
326 
327 /* local function prototypes */
329 static void AbortTransaction(void);
330 static void AtAbort_Memory(void);
331 static void AtCleanup_Memory(void);
332 static void AtAbort_ResourceOwner(void);
333 static void AtCCI_LocalCache(void);
334 static void AtCommit_Memory(void);
335 static void AtStart_Cache(void);
336 static void AtStart_Memory(void);
337 static void AtStart_ResourceOwner(void);
338 static void CallXactCallbacks(XactEvent event);
339 static void CallSubXactCallbacks(SubXactEvent event,
340  SubTransactionId mySubid,
341  SubTransactionId parentSubid);
342 static void CleanupTransaction(void);
343 static void CheckTransactionBlock(bool isTopLevel, bool throwError,
344  const char *stmtType);
345 static void CommitTransaction(void);
346 static TransactionId RecordTransactionAbort(bool isSubXact);
347 static void StartTransaction(void);
348 
349 static bool CommitTransactionCommandInternal(void);
350 static bool AbortCurrentTransactionInternal(void);
351 
352 static void StartSubTransaction(void);
353 static void CommitSubTransaction(void);
354 static void AbortSubTransaction(void);
355 static void CleanupSubTransaction(void);
356 static void PushTransaction(void);
357 static void PopTransaction(void);
358 
359 static void AtSubAbort_Memory(void);
360 static void AtSubCleanup_Memory(void);
361 static void AtSubAbort_ResourceOwner(void);
362 static void AtSubCommit_Memory(void);
363 static void AtSubStart_Memory(void);
364 static void AtSubStart_ResourceOwner(void);
365 
366 static void ShowTransactionState(const char *str);
367 static void ShowTransactionStateRec(const char *str, TransactionState s);
368 static const char *BlockStateAsString(TBlockState blockState);
369 static const char *TransStateAsString(TransState state);
370 
371 
372 /* ----------------------------------------------------------------
373  * transaction state accessors
374  * ----------------------------------------------------------------
375  */
376 
377 /*
378  * IsTransactionState
379  *
380  * This returns true if we are inside a valid transaction; that is,
381  * it is safe to initiate database access, take heavyweight locks, etc.
382  */
383 bool
385 {
387 
388  /*
389  * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
390  * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
391  * TRANS_PREPARE since it might be too soon or too late within those
392  * transition states to do anything interesting. Hence, the only "valid"
393  * state is TRANS_INPROGRESS.
394  */
395  return (s->state == TRANS_INPROGRESS);
396 }
397 
398 /*
399  * IsAbortedTransactionBlockState
400  *
401  * This returns true if we are within an aborted transaction block.
402  */
403 bool
405 {
407 
408  if (s->blockState == TBLOCK_ABORT ||
410  return true;
411 
412  return false;
413 }
414 
415 
416 /*
417  * GetTopTransactionId
418  *
419  * This will return the XID of the main transaction, assigning one if
420  * it's not yet set. Be careful to call this only inside a valid xact.
421  */
424 {
428 }
429 
430 /*
431  * GetTopTransactionIdIfAny
432  *
433  * This will return the XID of the main transaction, if one is assigned.
434  * It will return InvalidTransactionId if we are not currently inside a
435  * transaction, or inside a transaction that hasn't yet been assigned an XID.
436  */
439 {
441 }
442 
443 /*
444  * GetCurrentTransactionId
445  *
446  * This will return the XID of the current transaction (main or sub
447  * transaction), assigning one if it's not yet set. Be careful to call this
448  * only inside a valid xact.
449  */
452 {
454 
458 }
459 
460 /*
461  * GetCurrentTransactionIdIfAny
462  *
463  * This will return the XID of the current sub xact, if one is assigned.
464  * It will return InvalidTransactionId if we are not currently inside a
465  * transaction, or inside a transaction that hasn't been assigned an XID yet.
466  */
469 {
471 }
472 
473 /*
474  * GetTopFullTransactionId
475  *
476  * This will return the FullTransactionId of the main transaction, assigning
477  * one if it's not yet set. Be careful to call this only inside a valid xact.
478  */
481 {
485 }
486 
487 /*
488  * GetTopFullTransactionIdIfAny
489  *
490  * This will return the FullTransactionId of the main transaction, if one is
491  * assigned. It will return InvalidFullTransactionId if we are not currently
492  * inside a transaction, or inside a transaction that hasn't yet been assigned
493  * one.
494  */
497 {
499 }
500 
501 /*
502  * GetCurrentFullTransactionId
503  *
504  * This will return the FullTransactionId of the current transaction (main or
505  * sub transaction), assigning one if it's not yet set. Be careful to call
506  * this only inside a valid xact.
507  */
510 {
512 
515  return s->fullTransactionId;
516 }
517 
518 /*
519  * GetCurrentFullTransactionIdIfAny
520  *
521  * This will return the FullTransactionId of the current sub xact, if one is
522  * assigned. It will return InvalidFullTransactionId if we are not currently
523  * inside a transaction, or inside a transaction that hasn't been assigned one
524  * yet.
525  */
528 {
530 }
531 
532 /*
533  * MarkCurrentTransactionIdLoggedIfAny
534  *
535  * Remember that the current xid - if it is assigned - now has been wal logged.
536  */
537 void
539 {
542 }
543 
544 /*
545  * IsSubxactTopXidLogPending
546  *
547  * This is used to decide whether we need to WAL log the top-level XID for
548  * operation in a subtransaction. We require that for logical decoding, see
549  * LogicalDecodingProcessRecord.
550  *
551  * This returns true if wal_level >= logical and we are inside a valid
552  * subtransaction, for which the assignment was not yet written to any WAL
553  * record.
554  */
555 bool
557 {
558  /* check whether it is already logged */
560  return false;
561 
562  /* wal_level has to be logical */
563  if (!XLogLogicalInfoActive())
564  return false;
565 
566  /* we need to be in a transaction state */
567  if (!IsTransactionState())
568  return false;
569 
570  /* it has to be a subtransaction */
571  if (!IsSubTransaction())
572  return false;
573 
574  /* the subtransaction has to have a XID assigned */
576  return false;
577 
578  return true;
579 }
580 
581 /*
582  * MarkSubxactTopXidLogged
583  *
584  * Remember that the top transaction id for the current subtransaction is WAL
585  * logged now.
586  */
587 void
589 {
591 
593 }
594 
595 /*
596  * GetStableLatestTransactionId
597  *
598  * Get the transaction's XID if it has one, else read the next-to-be-assigned
599  * XID. Once we have a value, return that same value for the remainder of the
600  * current transaction. This is meant to provide the reference point for the
601  * age(xid) function, but might be useful for other maintenance tasks as well.
602  */
605 {
607  static TransactionId stablexid = InvalidTransactionId;
608 
609  if (lxid != MyProc->vxid.lxid)
610  {
611  lxid = MyProc->vxid.lxid;
612  stablexid = GetTopTransactionIdIfAny();
613  if (!TransactionIdIsValid(stablexid))
614  stablexid = ReadNextTransactionId();
615  }
616 
617  Assert(TransactionIdIsValid(stablexid));
618 
619  return stablexid;
620 }
621 
622 /*
623  * AssignTransactionId
624  *
625  * Assigns a new permanent FullTransactionId to the given TransactionState.
626  * We do not assign XIDs to transactions until/unless this is called.
627  * Also, any parent TransactionStates that don't yet have XIDs are assigned
628  * one; this maintains the invariant that a child transaction has an XID
629  * following its parent's.
630  */
631 static void
633 {
634  bool isSubXact = (s->parent != NULL);
635  ResourceOwner currentOwner;
636  bool log_unknown_top = false;
637 
638  /* Assert that caller didn't screw up */
641 
642  /*
643  * Workers synchronize transaction state at the beginning of each parallel
644  * operation, so we can't account for new XIDs at this point.
645  */
647  ereport(ERROR,
648  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
649  errmsg("cannot assign XIDs during a parallel operation")));
650 
651  /*
652  * Ensure parent(s) have XIDs, so that a child always has an XID later
653  * than its parent. Mustn't recurse here, or we might get a stack
654  * overflow if we're at the bottom of a huge stack of subtransactions none
655  * of which have XIDs yet.
656  */
657  if (isSubXact && !FullTransactionIdIsValid(s->parent->fullTransactionId))
658  {
659  TransactionState p = s->parent;
660  TransactionState *parents;
661  size_t parentOffset = 0;
662 
663  parents = palloc(sizeof(TransactionState) * s->nestingLevel);
664  while (p != NULL && !FullTransactionIdIsValid(p->fullTransactionId))
665  {
666  parents[parentOffset++] = p;
667  p = p->parent;
668  }
669 
670  /*
671  * This is technically a recursive call, but the recursion will never
672  * be more than one layer deep.
673  */
674  while (parentOffset != 0)
675  AssignTransactionId(parents[--parentOffset]);
676 
677  pfree(parents);
678  }
679 
680  /*
681  * When wal_level=logical, guarantee that a subtransaction's xid can only
682  * be seen in the WAL stream if its toplevel xid has been logged before.
683  * If necessary we log an xact_assignment record with fewer than
684  * PGPROC_MAX_CACHED_SUBXIDS. Note that it is fine if didLogXid isn't set
685  * for a transaction even though it appears in a WAL record, we just might
686  * superfluously log something. That can happen when an xid is included
687  * somewhere inside a wal record, but not in XLogRecord->xl_xid, like in
688  * xl_standby_locks.
689  */
690  if (isSubXact && XLogLogicalInfoActive() &&
692  log_unknown_top = true;
693 
694  /*
695  * Generate a new FullTransactionId and record its xid in PGPROC and
696  * pg_subtrans.
697  *
698  * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
699  * shared storage other than PGPROC; because if there's no room for it in
700  * PGPROC, the subtrans entry is needed to ensure that other backends see
701  * the Xid as "running". See GetNewTransactionId.
702  */
703  s->fullTransactionId = GetNewTransactionId(isSubXact);
704  if (!isSubXact)
706 
707  if (isSubXact)
710 
711  /*
712  * If it's a top-level transaction, the predicate locking system needs to
713  * be told about it too.
714  */
715  if (!isSubXact)
717 
718  /*
719  * Acquire lock on the transaction XID. (We assume this cannot block.) We
720  * have to ensure that the lock is assigned to the transaction's own
721  * ResourceOwner.
722  */
723  currentOwner = CurrentResourceOwner;
725 
727 
728  CurrentResourceOwner = currentOwner;
729 
730  /*
731  * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
732  * top-level transaction we issue a WAL record for the assignment. We
733  * include the top-level xid and all the subxids that have not yet been
734  * reported using XLOG_XACT_ASSIGNMENT records.
735  *
736  * This is required to limit the amount of shared memory required in a hot
737  * standby server to keep track of in-progress XIDs. See notes for
738  * RecordKnownAssignedTransactionIds().
739  *
740  * We don't keep track of the immediate parent of each subxid, only the
741  * top-level transaction that each subxact belongs to. This is correct in
742  * recovery only because aborted subtransactions are separately WAL
743  * logged.
744  *
745  * This is correct even for the case where several levels above us didn't
746  * have an xid assigned as we recursed up to them beforehand.
747  */
748  if (isSubXact && XLogStandbyInfoActive())
749  {
751  nUnreportedXids++;
752 
753  /*
754  * ensure this test matches similar one in
755  * RecoverPreparedTransactions()
756  */
758  log_unknown_top)
759  {
760  xl_xact_assignment xlrec;
761 
762  /*
763  * xtop is always set by now because we recurse up transaction
764  * stack to the highest unassigned xid and then come back down
765  */
766  xlrec.xtop = GetTopTransactionId();
768  xlrec.nsubxacts = nUnreportedXids;
769 
770  XLogBeginInsert();
771  XLogRegisterData((char *) &xlrec, MinSizeOfXactAssignment);
773  nUnreportedXids * sizeof(TransactionId));
774 
775  (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT);
776 
777  nUnreportedXids = 0;
778  /* mark top, not current xact as having been logged */
780  }
781  }
782 }
783 
784 /*
785  * GetCurrentSubTransactionId
786  */
789 {
791 
792  return s->subTransactionId;
793 }
794 
795 /*
796  * SubTransactionIsActive
797  *
798  * Test if the specified subxact ID is still active. Note caller is
799  * responsible for checking whether this ID is relevant to the current xact.
800  */
801 bool
803 {
805 
806  for (s = CurrentTransactionState; s != NULL; s = s->parent)
807  {
808  if (s->state == TRANS_ABORT)
809  continue;
810  if (s->subTransactionId == subxid)
811  return true;
812  }
813  return false;
814 }
815 
816 
817 /*
818  * GetCurrentCommandId
819  *
820  * "used" must be true if the caller intends to use the command ID to mark
821  * inserted/updated/deleted tuples. false means the ID is being fetched
822  * for read-only purposes (ie, as a snapshot validity cutoff). See
823  * CommandCounterIncrement() for discussion.
824  */
825 CommandId
827 {
828  /* this is global to a transaction, not subtransaction-local */
829  if (used)
830  {
831  /*
832  * Forbid setting currentCommandIdUsed in a parallel worker, because
833  * we have no provision for communicating this back to the leader. We
834  * could relax this restriction when currentCommandIdUsed was already
835  * true at the start of the parallel operation.
836  */
837  if (IsParallelWorker())
838  ereport(ERROR,
839  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
840  errmsg("cannot modify data in a parallel worker")));
841 
842  currentCommandIdUsed = true;
843  }
844  return currentCommandId;
845 }
846 
847 /*
848  * SetParallelStartTimestamps
849  *
850  * In a parallel worker, we should inherit the parent transaction's
851  * timestamps rather than setting our own. The parallel worker
852  * infrastructure must call this to provide those values before
853  * calling StartTransaction() or SetCurrentStatementStartTimestamp().
854  */
855 void
857 {
859  xactStartTimestamp = xact_ts;
860  stmtStartTimestamp = stmt_ts;
861 }
862 
863 /*
864  * GetCurrentTransactionStartTimestamp
865  */
868 {
869  return xactStartTimestamp;
870 }
871 
872 /*
873  * GetCurrentStatementStartTimestamp
874  */
877 {
878  return stmtStartTimestamp;
879 }
880 
881 /*
882  * GetCurrentTransactionStopTimestamp
883  *
884  * If the transaction stop time hasn't already been set, which can happen if
885  * we decided we don't need to log an XLOG record, set xactStopTimestamp.
886  */
889 {
891 
892  /* should only be called after commit / abort processing */
893  Assert(s->state == TRANS_DEFAULT ||
894  s->state == TRANS_COMMIT ||
895  s->state == TRANS_ABORT ||
896  s->state == TRANS_PREPARE);
897 
898  if (xactStopTimestamp == 0)
900 
901  return xactStopTimestamp;
902 }
903 
904 /*
905  * SetCurrentStatementStartTimestamp
906  *
907  * In a parallel worker, this should already have been provided by a call
908  * to SetParallelStartTimestamps().
909  */
910 void
912 {
913  if (!IsParallelWorker())
915  else
917 }
918 
919 /*
920  * GetCurrentTransactionNestLevel
921  *
922  * Note: this will return zero when not inside any transaction, one when
923  * inside a top-level transaction, etc.
924  */
925 int
927 {
929 
930  return s->nestingLevel;
931 }
932 
933 
934 /*
935  * TransactionIdIsCurrentTransactionId
936  */
937 bool
939 {
941 
942  /*
943  * We always say that BootstrapTransactionId is "not my transaction ID"
944  * even when it is (ie, during bootstrap). Along with the fact that
945  * transam.c always treats BootstrapTransactionId as already committed,
946  * this causes the heapam_visibility.c routines to see all tuples as
947  * committed, which is what we need during bootstrap. (Bootstrap mode
948  * only inserts tuples, it never updates or deletes them, so all tuples
949  * can be presumed good immediately.)
950  *
951  * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
952  * not my transaction ID, so we can just return "false" immediately for
953  * any non-normal XID.
954  */
955  if (!TransactionIdIsNormal(xid))
956  return false;
957 
959  return true;
960 
961  /*
962  * In parallel workers, the XIDs we must consider as current are stored in
963  * ParallelCurrentXids rather than the transaction-state stack. Note that
964  * the XIDs in this array are sorted numerically rather than according to
965  * transactionIdPrecedes order.
966  */
967  if (nParallelCurrentXids > 0)
968  {
969  int low,
970  high;
971 
972  low = 0;
973  high = nParallelCurrentXids - 1;
974  while (low <= high)
975  {
976  int middle;
977  TransactionId probe;
978 
979  middle = low + (high - low) / 2;
980  probe = ParallelCurrentXids[middle];
981  if (probe == xid)
982  return true;
983  else if (probe < xid)
984  low = middle + 1;
985  else
986  high = middle - 1;
987  }
988  return false;
989  }
990 
991  /*
992  * We will return true for the Xid of the current subtransaction, any of
993  * its subcommitted children, any of its parents, or any of their
994  * previously subcommitted children. However, a transaction being aborted
995  * is no longer "current", even though it may still have an entry on the
996  * state stack.
997  */
998  for (s = CurrentTransactionState; s != NULL; s = s->parent)
999  {
1000  int low,
1001  high;
1002 
1003  if (s->state == TRANS_ABORT)
1004  continue;
1006  continue; /* it can't have any child XIDs either */
1008  return true;
1009  /* As the childXids array is ordered, we can use binary search */
1010  low = 0;
1011  high = s->nChildXids - 1;
1012  while (low <= high)
1013  {
1014  int middle;
1015  TransactionId probe;
1016 
1017  middle = low + (high - low) / 2;
1018  probe = s->childXids[middle];
1019  if (TransactionIdEquals(probe, xid))
1020  return true;
1021  else if (TransactionIdPrecedes(probe, xid))
1022  low = middle + 1;
1023  else
1024  high = middle - 1;
1025  }
1026  }
1027 
1028  return false;
1029 }
1030 
1031 /*
1032  * TransactionStartedDuringRecovery
1033  *
1034  * Returns true if the current transaction started while recovery was still
1035  * in progress. Recovery might have ended since so RecoveryInProgress() might
1036  * return false already.
1037  */
1038 bool
1040 {
1042 }
1043 
1044 /*
1045  * EnterParallelMode
1046  */
1047 void
1049 {
1051 
1052  Assert(s->parallelModeLevel >= 0);
1053 
1054  ++s->parallelModeLevel;
1055 }
1056 
1057 /*
1058  * ExitParallelMode
1059  */
1060 void
1062 {
1064 
1065  Assert(s->parallelModeLevel > 0);
1068 
1069  --s->parallelModeLevel;
1070 }
1071 
1072 /*
1073  * IsInParallelMode
1074  *
1075  * Are we in a parallel operation, as either the leader or a worker? Check
1076  * this to prohibit operations that change backend-local state expected to
1077  * match across all workers. Mere caches usually don't require such a
1078  * restriction. State modified in a strict push/pop fashion, such as the
1079  * active snapshot stack, is often fine.
1080  *
1081  * We say we are in parallel mode if we are in a subxact of a transaction
1082  * that's initiated a parallel operation; for most purposes that context
1083  * has all the same restrictions.
1084  */
1085 bool
1087 {
1089 
1090  return s->parallelModeLevel != 0 || s->parallelChildXact;
1091 }
1092 
1093 /*
1094  * CommandCounterIncrement
1095  */
1096 void
1098 {
1099  /*
1100  * If the current value of the command counter hasn't been "used" to mark
1101  * tuples, we need not increment it, since there's no need to distinguish
1102  * a read-only command from others. This helps postpone command counter
1103  * overflow, and keeps no-op CommandCounterIncrement operations cheap.
1104  */
1106  {
1107  /*
1108  * Workers synchronize transaction state at the beginning of each
1109  * parallel operation, so we can't account for new commands after that
1110  * point.
1111  */
1113  ereport(ERROR,
1114  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
1115  errmsg("cannot start commands during a parallel operation")));
1116 
1117  currentCommandId += 1;
1119  {
1120  currentCommandId -= 1;
1121  ereport(ERROR,
1122  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1123  errmsg("cannot have more than 2^32-2 commands in a transaction")));
1124  }
1125  currentCommandIdUsed = false;
1126 
1127  /* Propagate new command ID into static snapshots */
1129 
1130  /*
1131  * Make any catalog changes done by the just-completed command visible
1132  * in the local syscache. We obviously don't need to do this after a
1133  * read-only command. (But see hacks in inval.c to make real sure we
1134  * don't think a command that queued inval messages was read-only.)
1135  */
1136  AtCCI_LocalCache();
1137  }
1138 }
1139 
1140 /*
1141  * ForceSyncCommit
1142  *
1143  * Interface routine to allow commands to force a synchronous commit of the
1144  * current top-level transaction. Currently, two-phase commit does not
1145  * persist and restore this variable. So long as all callers use
1146  * PreventInTransactionBlock(), that omission has no consequences.
1147  */
1148 void
1150 {
1151  forceSyncCommit = true;
1152 }
1153 
1154 
1155 /* ----------------------------------------------------------------
1156  * StartTransaction stuff
1157  * ----------------------------------------------------------------
1158  */
1159 
1160 /*
1161  * AtStart_Cache
1162  */
1163 static void
1165 {
1167 }
1168 
1169 /*
1170  * AtStart_Memory
1171  */
1172 static void
1174 {
1176 
1177  /*
1178  * If this is the first time through, create a private context for
1179  * AbortTransaction to work in. By reserving some space now, we can
1180  * insulate AbortTransaction from out-of-memory scenarios. Like
1181  * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1182  * size, so that space will be reserved immediately.
1183  */
1184  if (TransactionAbortContext == NULL)
1187  "TransactionAbortContext",
1188  32 * 1024,
1189  32 * 1024,
1190  32 * 1024);
1191 
1192  /*
1193  * We shouldn't have a transaction context already.
1194  */
1195  Assert(TopTransactionContext == NULL);
1196 
1197  /*
1198  * Create a toplevel context for the transaction.
1199  */
1202  "TopTransactionContext",
1204 
1205  /*
1206  * In a top-level transaction, CurTransactionContext is the same as
1207  * TopTransactionContext.
1208  */
1211 
1212  /* Make the CurTransactionContext active. */
1214 }
1215 
1216 /*
1217  * AtStart_ResourceOwner
1218  */
1219 static void
1221 {
1223 
1224  /*
1225  * We shouldn't have a transaction resource owner already.
1226  */
1228 
1229  /*
1230  * Create a toplevel resource owner for the transaction.
1231  */
1232  s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1233 
1237 }
1238 
1239 /* ----------------------------------------------------------------
1240  * StartSubTransaction stuff
1241  * ----------------------------------------------------------------
1242  */
1243 
1244 /*
1245  * AtSubStart_Memory
1246  */
1247 static void
1249 {
1251 
1252  Assert(CurTransactionContext != NULL);
1253 
1254  /*
1255  * Create a CurTransactionContext, which will be used to hold data that
1256  * survives subtransaction commit but disappears on subtransaction abort.
1257  * We make it a child of the immediate parent's CurTransactionContext.
1258  */
1260  "CurTransactionContext",
1263 
1264  /* Make the CurTransactionContext active. */
1266 }
1267 
1268 /*
1269  * AtSubStart_ResourceOwner
1270  */
1271 static void
1273 {
1275 
1276  Assert(s->parent != NULL);
1277 
1278  /*
1279  * Create a resource owner for the subtransaction. We make it a child of
1280  * the immediate parent's resource owner.
1281  */
1282  s->curTransactionOwner =
1284  "SubTransaction");
1285 
1288 }
1289 
1290 /* ----------------------------------------------------------------
1291  * CommitTransaction stuff
1292  * ----------------------------------------------------------------
1293  */
1294 
1295 /*
1296  * RecordTransactionCommit
1297  *
1298  * Returns latest XID among xact and its children, or InvalidTransactionId
1299  * if the xact has no XID. (We compute that here just because it's easier.)
1300  *
1301  * If you change this function, see RecordTransactionCommitPrepared also.
1302  */
1303 static TransactionId
1305 {
1307  bool markXidCommitted = TransactionIdIsValid(xid);
1308  TransactionId latestXid = InvalidTransactionId;
1309  int nrels;
1310  RelFileLocator *rels;
1311  int nchildren;
1312  TransactionId *children;
1313  int ndroppedstats = 0;
1314  xl_xact_stats_item *droppedstats = NULL;
1315  int nmsgs = 0;
1316  SharedInvalidationMessage *invalMessages = NULL;
1317  bool RelcacheInitFileInval = false;
1318  bool wrote_xlog;
1319 
1320  /*
1321  * Log pending invalidations for logical decoding of in-progress
1322  * transactions. Normally for DDLs, we log this at each command end,
1323  * however, for certain cases where we directly update the system table
1324  * without a transaction block, the invalidations are not logged till this
1325  * time.
1326  */
1327  if (XLogLogicalInfoActive())
1329 
1330  /* Get data needed for commit record */
1331  nrels = smgrGetPendingDeletes(true, &rels);
1332  nchildren = xactGetCommittedChildren(&children);
1333  ndroppedstats = pgstat_get_transactional_drops(true, &droppedstats);
1334  if (XLogStandbyInfoActive())
1335  nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
1336  &RelcacheInitFileInval);
1337  wrote_xlog = (XactLastRecEnd != 0);
1338 
1339  /*
1340  * If we haven't been assigned an XID yet, we neither can, nor do we want
1341  * to write a COMMIT record.
1342  */
1343  if (!markXidCommitted)
1344  {
1345  /*
1346  * We expect that every RelationDropStorage is followed by a catalog
1347  * update, and hence XID assignment, so we shouldn't get here with any
1348  * pending deletes. Same is true for dropping stats.
1349  *
1350  * Use a real test not just an Assert to check this, since it's a bit
1351  * fragile.
1352  */
1353  if (nrels != 0 || ndroppedstats != 0)
1354  elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
1355 
1356  /* Can't have child XIDs either; AssignTransactionId enforces this */
1357  Assert(nchildren == 0);
1358 
1359  /*
1360  * Transactions without an assigned xid can contain invalidation
1361  * messages (e.g. explicit relcache invalidations or catcache
1362  * invalidations for inplace updates); standbys need to process those.
1363  * We can't emit a commit record without an xid, and we don't want to
1364  * force assigning an xid, because that'd be problematic for e.g.
1365  * vacuum. Hence we emit a bespoke record for the invalidations. We
1366  * don't want to use that in case a commit record is emitted, so they
1367  * happen synchronously with commits (besides not wanting to emit more
1368  * WAL records).
1369  */
1370  if (nmsgs != 0)
1371  {
1372  LogStandbyInvalidations(nmsgs, invalMessages,
1373  RelcacheInitFileInval);
1374  wrote_xlog = true; /* not strictly necessary */
1375  }
1376 
1377  /*
1378  * If we didn't create XLOG entries, we're done here; otherwise we
1379  * should trigger flushing those entries the same as a commit record
1380  * would. This will primarily happen for HOT pruning and the like; we
1381  * want these to be flushed to disk in due time.
1382  */
1383  if (!wrote_xlog)
1384  goto cleanup;
1385  }
1386  else
1387  {
1388  bool replorigin;
1389 
1390  /*
1391  * Are we using the replication origins feature? Or, in other words,
1392  * are we replaying remote actions?
1393  */
1394  replorigin = (replorigin_session_origin != InvalidRepOriginId &&
1396 
1397  /*
1398  * Mark ourselves as within our "commit critical section". This
1399  * forces any concurrent checkpoint to wait until we've updated
1400  * pg_xact. Without this, it is possible for the checkpoint to set
1401  * REDO after the XLOG record but fail to flush the pg_xact update to
1402  * disk, leading to loss of the transaction commit if the system
1403  * crashes a little later.
1404  *
1405  * Note: we could, but don't bother to, set this flag in
1406  * RecordTransactionAbort. That's because loss of a transaction abort
1407  * is noncritical; the presumption would be that it aborted, anyway.
1408  *
1409  * It's safe to change the delayChkptFlags flag of our own backend
1410  * without holding the ProcArrayLock, since we're the only one
1411  * modifying it. This makes checkpoint's determination of which xacts
1412  * are delaying the checkpoint a bit fuzzy, but it doesn't matter.
1413  */
1417 
1418  /*
1419  * Insert the commit XLOG record.
1420  */
1422  nchildren, children, nrels, rels,
1423  ndroppedstats, droppedstats,
1424  nmsgs, invalMessages,
1425  RelcacheInitFileInval,
1426  MyXactFlags,
1427  InvalidTransactionId, NULL /* plain commit */ );
1428 
1429  if (replorigin)
1430  /* Move LSNs forward for this replication origin */
1432  XactLastRecEnd);
1433 
1434  /*
1435  * Record commit timestamp. The value comes from plain commit
1436  * timestamp if there's no replication origin; otherwise, the
1437  * timestamp was already set in replorigin_session_origin_timestamp by
1438  * replication.
1439  *
1440  * We don't need to WAL-log anything here, as the commit record
1441  * written above already contains the data.
1442  */
1443 
1444  if (!replorigin || replorigin_session_origin_timestamp == 0)
1446 
1447  TransactionTreeSetCommitTsData(xid, nchildren, children,
1450  }
1451 
1452  /*
1453  * Check if we want to commit asynchronously. We can allow the XLOG flush
1454  * to happen asynchronously if synchronous_commit=off, or if the current
1455  * transaction has not performed any WAL-logged operation or didn't assign
1456  * an xid. The transaction can end up not writing any WAL, even if it has
1457  * an xid, if it only wrote to temporary and/or unlogged tables. It can
1458  * end up having written WAL without an xid if it did HOT pruning. In
1459  * case of a crash, the loss of such a transaction will be irrelevant;
1460  * temp tables will be lost anyway, unlogged tables will be truncated and
1461  * HOT pruning will be done again later. (Given the foregoing, you might
1462  * think that it would be unnecessary to emit the XLOG record at all in
1463  * this case, but we don't currently try to do that. It would certainly
1464  * cause problems at least in Hot Standby mode, where the
1465  * KnownAssignedXids machinery requires tracking every XID assignment. It
1466  * might be OK to skip it only when wal_level < replica, but for now we
1467  * don't.)
1468  *
1469  * However, if we're doing cleanup of any non-temp rels or committing any
1470  * command that wanted to force sync commit, then we must flush XLOG
1471  * immediately. (We must not allow asynchronous commit if there are any
1472  * non-temp tables to be deleted, because we might delete the files before
1473  * the COMMIT record is flushed to disk. We do allow asynchronous commit
1474  * if all to-be-deleted tables are temporary though, since they are lost
1475  * anyway if we crash.)
1476  */
1477  if ((wrote_xlog && markXidCommitted &&
1479  forceSyncCommit || nrels > 0)
1480  {
1482 
1483  /*
1484  * Now we may update the CLOG, if we wrote a COMMIT record above
1485  */
1486  if (markXidCommitted)
1487  TransactionIdCommitTree(xid, nchildren, children);
1488  }
1489  else
1490  {
1491  /*
1492  * Asynchronous commit case:
1493  *
1494  * This enables possible committed transaction loss in the case of a
1495  * postmaster crash because WAL buffers are left unwritten. Ideally we
1496  * could issue the WAL write without the fsync, but some
1497  * wal_sync_methods do not allow separate write/fsync.
1498  *
1499  * Report the latest async commit LSN, so that the WAL writer knows to
1500  * flush this commit.
1501  */
1503 
1504  /*
1505  * We must not immediately update the CLOG, since we didn't flush the
1506  * XLOG. Instead, we store the LSN up to which the XLOG must be
1507  * flushed before the CLOG may be updated.
1508  */
1509  if (markXidCommitted)
1510  TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1511  }
1512 
1513  /*
1514  * If we entered a commit critical section, leave it now, and let
1515  * checkpoints proceed.
1516  */
1517  if (markXidCommitted)
1518  {
1520  END_CRIT_SECTION();
1521  }
1522 
1523  /* Compute latestXid while we have the child XIDs handy */
1524  latestXid = TransactionIdLatest(xid, nchildren, children);
1525 
1526  /*
1527  * Wait for synchronous replication, if required. Similar to the decision
1528  * above about using committing asynchronously we only want to wait if
1529  * this backend assigned an xid and wrote WAL. No need to wait if an xid
1530  * was assigned due to temporary/unlogged tables or due to HOT pruning.
1531  *
1532  * Note that at this stage we have marked clog, but still show as running
1533  * in the procarray and continue to hold locks.
1534  */
1535  if (wrote_xlog && markXidCommitted)
1537 
1538  /* remember end of last commit record */
1540 
1541  /* Reset XactLastRecEnd until the next transaction writes something */
1542  XactLastRecEnd = 0;
1543 cleanup:
1544  /* Clean up local data */
1545  if (rels)
1546  pfree(rels);
1547  if (ndroppedstats)
1548  pfree(droppedstats);
1549 
1550  return latestXid;
1551 }
1552 
1553 
1554 /*
1555  * AtCCI_LocalCache
1556  */
1557 static void
1559 {
1560  /*
1561  * Make any pending relation map changes visible. We must do this before
1562  * processing local sinval messages, so that the map changes will get
1563  * reflected into the relcache when relcache invals are processed.
1564  */
1566 
1567  /*
1568  * Make catalog changes visible to me for the next command.
1569  */
1571 }
1572 
1573 /*
1574  * AtCommit_Memory
1575  */
1576 static void
1578 {
1579  /*
1580  * Now that we're "out" of a transaction, have the system allocate things
1581  * in the top memory context instead of per-transaction contexts.
1582  */
1584 
1585  /*
1586  * Release all transaction-local memory.
1587  */
1588  Assert(TopTransactionContext != NULL);
1590  TopTransactionContext = NULL;
1591  CurTransactionContext = NULL;
1593 }
1594 
1595 /* ----------------------------------------------------------------
1596  * CommitSubTransaction stuff
1597  * ----------------------------------------------------------------
1598  */
1599 
1600 /*
1601  * AtSubCommit_Memory
1602  */
1603 static void
1605 {
1607 
1608  Assert(s->parent != NULL);
1609 
1610  /* Return to parent transaction level's memory context. */
1613 
1614  /*
1615  * Ordinarily we cannot throw away the child's CurTransactionContext,
1616  * since the data it contains will be needed at upper commit. However, if
1617  * there isn't actually anything in it, we can throw it away. This avoids
1618  * a small memory leak in the common case of "trivial" subxacts.
1619  */
1621  {
1623  s->curTransactionContext = NULL;
1624  }
1625 }
1626 
1627 /*
1628  * AtSubCommit_childXids
1629  *
1630  * Pass my own XID and my child XIDs up to my parent as committed children.
1631  */
1632 static void
1634 {
1636  int new_nChildXids;
1637 
1638  Assert(s->parent != NULL);
1639 
1640  /*
1641  * The parent childXids array will need to hold my XID and all my
1642  * childXids, in addition to the XIDs already there.
1643  */
1644  new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1645 
1646  /* Allocate or enlarge the parent array if necessary */
1647  if (s->parent->maxChildXids < new_nChildXids)
1648  {
1649  int new_maxChildXids;
1650  TransactionId *new_childXids;
1651 
1652  /*
1653  * Make it 2x what's needed right now, to avoid having to enlarge it
1654  * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1655  * is what ensures that we don't need to worry about integer overflow
1656  * here or in the calculation of new_nChildXids.)
1657  */
1658  new_maxChildXids = Min(new_nChildXids * 2,
1659  (int) (MaxAllocSize / sizeof(TransactionId)));
1660 
1661  if (new_maxChildXids < new_nChildXids)
1662  ereport(ERROR,
1663  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1664  errmsg("maximum number of committed subtransactions (%d) exceeded",
1665  (int) (MaxAllocSize / sizeof(TransactionId)))));
1666 
1667  /*
1668  * We keep the child-XID arrays in TopTransactionContext; this avoids
1669  * setting up child-transaction contexts for what might be just a few
1670  * bytes of grandchild XIDs.
1671  */
1672  if (s->parent->childXids == NULL)
1673  new_childXids =
1675  new_maxChildXids * sizeof(TransactionId));
1676  else
1677  new_childXids = repalloc(s->parent->childXids,
1678  new_maxChildXids * sizeof(TransactionId));
1679 
1680  s->parent->childXids = new_childXids;
1681  s->parent->maxChildXids = new_maxChildXids;
1682  }
1683 
1684  /*
1685  * Copy all my XIDs to parent's array.
1686  *
1687  * Note: We rely on the fact that the XID of a child always follows that
1688  * of its parent. By copying the XID of this subtransaction before the
1689  * XIDs of its children, we ensure that the array stays ordered. Likewise,
1690  * all XIDs already in the array belong to subtransactions started and
1691  * subcommitted before us, so their XIDs must precede ours.
1692  */
1694 
1695  if (s->nChildXids > 0)
1696  memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1697  s->childXids,
1698  s->nChildXids * sizeof(TransactionId));
1699 
1700  s->parent->nChildXids = new_nChildXids;
1701 
1702  /* Release child's array to avoid leakage */
1703  if (s->childXids != NULL)
1704  pfree(s->childXids);
1705  /* We must reset these to avoid double-free if fail later in commit */
1706  s->childXids = NULL;
1707  s->nChildXids = 0;
1708  s->maxChildXids = 0;
1709 }
1710 
1711 /* ----------------------------------------------------------------
1712  * AbortTransaction stuff
1713  * ----------------------------------------------------------------
1714  */
1715 
1716 /*
1717  * RecordTransactionAbort
1718  *
1719  * Returns latest XID among xact and its children, or InvalidTransactionId
1720  * if the xact has no XID. (We compute that here just because it's easier.)
1721  */
1722 static TransactionId
1723 RecordTransactionAbort(bool isSubXact)
1724 {
1726  TransactionId latestXid;
1727  int nrels;
1728  RelFileLocator *rels;
1729  int ndroppedstats = 0;
1730  xl_xact_stats_item *droppedstats = NULL;
1731  int nchildren;
1732  TransactionId *children;
1733  TimestampTz xact_time;
1734  bool replorigin;
1735 
1736  /*
1737  * If we haven't been assigned an XID, nobody will care whether we aborted
1738  * or not. Hence, we're done in that case. It does not matter if we have
1739  * rels to delete (note that this routine is not responsible for actually
1740  * deleting 'em). We cannot have any child XIDs, either.
1741  */
1742  if (!TransactionIdIsValid(xid))
1743  {
1744  /* Reset XactLastRecEnd until the next transaction writes something */
1745  if (!isSubXact)
1746  XactLastRecEnd = 0;
1747  return InvalidTransactionId;
1748  }
1749 
1750  /*
1751  * We have a valid XID, so we should write an ABORT record for it.
1752  *
1753  * We do not flush XLOG to disk here, since the default assumption after a
1754  * crash would be that we aborted, anyway. For the same reason, we don't
1755  * need to worry about interlocking against checkpoint start.
1756  */
1757 
1758  /*
1759  * Check that we haven't aborted halfway through RecordTransactionCommit.
1760  */
1761  if (TransactionIdDidCommit(xid))
1762  elog(PANIC, "cannot abort transaction %u, it was already committed",
1763  xid);
1764 
1765  /*
1766  * Are we using the replication origins feature? Or, in other words, are
1767  * we replaying remote actions?
1768  */
1769  replorigin = (replorigin_session_origin != InvalidRepOriginId &&
1771 
1772  /* Fetch the data we need for the abort record */
1773  nrels = smgrGetPendingDeletes(false, &rels);
1774  nchildren = xactGetCommittedChildren(&children);
1775  ndroppedstats = pgstat_get_transactional_drops(false, &droppedstats);
1776 
1777  /* XXX do we really need a critical section here? */
1779 
1780  /* Write the ABORT record */
1781  if (isSubXact)
1782  xact_time = GetCurrentTimestamp();
1783  else
1784  {
1785  xact_time = GetCurrentTransactionStopTimestamp();
1786  }
1787 
1788  XactLogAbortRecord(xact_time,
1789  nchildren, children,
1790  nrels, rels,
1791  ndroppedstats, droppedstats,
1793  NULL);
1794 
1795  if (replorigin)
1796  /* Move LSNs forward for this replication origin */
1798  XactLastRecEnd);
1799 
1800  /*
1801  * Report the latest async abort LSN, so that the WAL writer knows to
1802  * flush this abort. There's nothing to be gained by delaying this, since
1803  * WALWriter may as well do this when it can. This is important with
1804  * streaming replication because if we don't flush WAL regularly we will
1805  * find that large aborts leave us with a long backlog for when commits
1806  * occur after the abort, increasing our window of data loss should
1807  * problems occur at that point.
1808  */
1809  if (!isSubXact)
1811 
1812  /*
1813  * Mark the transaction aborted in clog. This is not absolutely necessary
1814  * but we may as well do it while we are here; also, in the subxact case
1815  * it is helpful because XactLockTableWait makes use of it to avoid
1816  * waiting for already-aborted subtransactions. It is OK to do it without
1817  * having flushed the ABORT record to disk, because in event of a crash
1818  * we'd be assumed to have aborted anyway.
1819  */
1820  TransactionIdAbortTree(xid, nchildren, children);
1821 
1822  END_CRIT_SECTION();
1823 
1824  /* Compute latestXid while we have the child XIDs handy */
1825  latestXid = TransactionIdLatest(xid, nchildren, children);
1826 
1827  /*
1828  * If we're aborting a subtransaction, we can immediately remove failed
1829  * XIDs from PGPROC's cache of running child XIDs. We do that here for
1830  * subxacts, because we already have the child XID array at hand. For
1831  * main xacts, the equivalent happens just after this function returns.
1832  */
1833  if (isSubXact)
1834  XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1835 
1836  /* Reset XactLastRecEnd until the next transaction writes something */
1837  if (!isSubXact)
1838  XactLastRecEnd = 0;
1839 
1840  /* And clean up local data */
1841  if (rels)
1842  pfree(rels);
1843  if (ndroppedstats)
1844  pfree(droppedstats);
1845 
1846  return latestXid;
1847 }
1848 
1849 /*
1850  * AtAbort_Memory
1851  */
1852 static void
1854 {
1855  /*
1856  * Switch into TransactionAbortContext, which should have some free space
1857  * even if nothing else does. We'll work in this context until we've
1858  * finished cleaning up.
1859  *
1860  * It is barely possible to get here when we've not been able to create
1861  * TransactionAbortContext yet; if so use TopMemoryContext.
1862  */
1863  if (TransactionAbortContext != NULL)
1865  else
1867 }
1868 
1869 /*
1870  * AtSubAbort_Memory
1871  */
1872 static void
1874 {
1876 
1878 }
1879 
1880 
1881 /*
1882  * AtAbort_ResourceOwner
1883  */
1884 static void
1886 {
1887  /*
1888  * Make sure we have a valid ResourceOwner, if possible (else it will be
1889  * NULL, which is OK)
1890  */
1892 }
1893 
1894 /*
1895  * AtSubAbort_ResourceOwner
1896  */
1897 static void
1899 {
1901 
1902  /* Make sure we have a valid ResourceOwner */
1904 }
1905 
1906 
1907 /*
1908  * AtSubAbort_childXids
1909  */
1910 static void
1912 {
1914 
1915  /*
1916  * We keep the child-XID arrays in TopTransactionContext (see
1917  * AtSubCommit_childXids). This means we'd better free the array
1918  * explicitly at abort to avoid leakage.
1919  */
1920  if (s->childXids != NULL)
1921  pfree(s->childXids);
1922  s->childXids = NULL;
1923  s->nChildXids = 0;
1924  s->maxChildXids = 0;
1925 
1926  /*
1927  * We could prune the unreportedXids array here. But we don't bother. That
1928  * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1929  * would likely introduce more CPU time into the more common paths, so we
1930  * choose not to do that.
1931  */
1932 }
1933 
1934 /* ----------------------------------------------------------------
1935  * CleanupTransaction stuff
1936  * ----------------------------------------------------------------
1937  */
1938 
1939 /*
1940  * AtCleanup_Memory
1941  */
1942 static void
1944 {
1946 
1947  /*
1948  * Now that we're "out" of a transaction, have the system allocate things
1949  * in the top memory context instead of per-transaction contexts.
1950  */
1952 
1953  /*
1954  * Clear the special abort context for next time.
1955  */
1956  if (TransactionAbortContext != NULL)
1958 
1959  /*
1960  * Release all transaction-local memory.
1961  */
1962  if (TopTransactionContext != NULL)
1964  TopTransactionContext = NULL;
1965  CurTransactionContext = NULL;
1967 }
1968 
1969 
1970 /* ----------------------------------------------------------------
1971  * CleanupSubTransaction stuff
1972  * ----------------------------------------------------------------
1973  */
1974 
1975 /*
1976  * AtSubCleanup_Memory
1977  */
1978 static void
1980 {
1982 
1983  Assert(s->parent != NULL);
1984 
1985  /* Make sure we're not in an about-to-be-deleted context */
1988 
1989  /*
1990  * Clear the special abort context for next time.
1991  */
1992  if (TransactionAbortContext != NULL)
1994 
1995  /*
1996  * Delete the subxact local memory contexts. Its CurTransactionContext can
1997  * go too (note this also kills CurTransactionContexts from any children
1998  * of the subxact).
1999  */
2000  if (s->curTransactionContext)
2002  s->curTransactionContext = NULL;
2003 }
2004 
2005 /* ----------------------------------------------------------------
2006  * interface routines
2007  * ----------------------------------------------------------------
2008  */
2009 
2010 /*
2011  * StartTransaction
2012  */
2013 static void
2015 {
2016  TransactionState s;
2017  VirtualTransactionId vxid;
2018 
2019  /*
2020  * Let's just make sure the state stack is empty
2021  */
2024 
2026 
2027  /* check the current transaction state */
2028  Assert(s->state == TRANS_DEFAULT);
2029 
2030  /*
2031  * Set the current transaction state information appropriately during
2032  * start processing. Note that once the transaction status is switched
2033  * this process cannot fail until the user ID and the security context
2034  * flags are fetched below.
2035  */
2036  s->state = TRANS_START;
2037  s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
2038 
2039  /* Determine if statements are logged in this transaction */
2041  (log_xact_sample_rate == 1 ||
2043 
2044  /*
2045  * initialize current transaction state fields
2046  *
2047  * note: prevXactReadOnly is not used at the outermost level
2048  */
2049  s->nestingLevel = 1;
2050  s->gucNestLevel = 1;
2051  s->childXids = NULL;
2052  s->nChildXids = 0;
2053  s->maxChildXids = 0;
2054 
2055  /*
2056  * Once the current user ID and the security context flags are fetched,
2057  * both will be properly reset even if transaction startup fails.
2058  */
2060 
2061  /* SecurityRestrictionContext should never be set outside a transaction */
2062  Assert(s->prevSecContext == 0);
2063 
2064  /*
2065  * Make sure we've reset xact state variables
2066  *
2067  * If recovery is still in progress, mark this transaction as read-only.
2068  * We have lower level defences in XLogInsert and elsewhere to stop us
2069  * from modifying data during recovery, but this gives the normal
2070  * indication to the user that the transaction is read-only.
2071  */
2072  if (RecoveryInProgress())
2073  {
2074  s->startedInRecovery = true;
2075  XactReadOnly = true;
2076  }
2077  else
2078  {
2079  s->startedInRecovery = false;
2081  }
2084  forceSyncCommit = false;
2085  MyXactFlags = 0;
2086 
2087  /*
2088  * reinitialize within-transaction counters
2089  */
2093  currentCommandIdUsed = false;
2094 
2095  /*
2096  * initialize reported xid accounting
2097  */
2098  nUnreportedXids = 0;
2099  s->didLogXid = false;
2100 
2101  /*
2102  * must initialize resource-management stuff first
2103  */
2104  AtStart_Memory();
2106 
2107  /*
2108  * Assign a new LocalTransactionId, and combine it with the proc number to
2109  * form a virtual transaction id.
2110  */
2111  vxid.procNumber = MyProcNumber;
2113 
2114  /*
2115  * Lock the virtual transaction id before we announce it in the proc array
2116  */
2118 
2119  /*
2120  * Advertise it in the proc array. We assume assignment of
2121  * localTransactionId is atomic, and the proc number should be set
2122  * already.
2123  */
2126 
2127  TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
2128 
2129  /*
2130  * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2131  * be the same as the first command's statement_timestamp(), so don't do a
2132  * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2133  * for transactions started inside procedures (i.e., nonatomic SPI
2134  * contexts), we do need to advance the timestamp. Also, in a parallel
2135  * worker, the timestamp should already have been provided by a call to
2136  * SetParallelStartTimestamps().
2137  */
2138  if (!IsParallelWorker())
2139  {
2142  else
2144  }
2145  else
2146  Assert(xactStartTimestamp != 0);
2148  /* Mark xactStopTimestamp as unset. */
2149  xactStopTimestamp = 0;
2150 
2151  /*
2152  * initialize other subsystems for new transaction
2153  */
2154  AtStart_GUC();
2155  AtStart_Cache();
2157 
2158  /*
2159  * done with start processing, set current transaction state to "in
2160  * progress"
2161  */
2162  s->state = TRANS_INPROGRESS;
2163 
2164  /* Schedule transaction timeout */
2165  if (TransactionTimeout > 0)
2167 
2168  ShowTransactionState("StartTransaction");
2169 }
2170 
2171 
2172 /*
2173  * CommitTransaction
2174  *
2175  * NB: if you change this routine, better look at PrepareTransaction too!
2176  */
2177 static void
2179 {
2181  TransactionId latestXid;
2182  bool is_parallel_worker;
2183 
2184  is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2185 
2186  /* Enforce parallel mode restrictions during parallel worker commit. */
2187  if (is_parallel_worker)
2189 
2190  ShowTransactionState("CommitTransaction");
2191 
2192  /*
2193  * check the current transaction state
2194  */
2195  if (s->state != TRANS_INPROGRESS)
2196  elog(WARNING, "CommitTransaction while in %s state",
2198  Assert(s->parent == NULL);
2199 
2200  /*
2201  * Do pre-commit processing that involves calling user-defined code, such
2202  * as triggers. SECURITY_RESTRICTED_OPERATION contexts must not queue an
2203  * action that would run here, because that would bypass the sandbox.
2204  * Since closing cursors could queue trigger actions, triggers could open
2205  * cursors, etc, we have to keep looping until there's nothing left to do.
2206  */
2207  for (;;)
2208  {
2209  /*
2210  * Fire all currently pending deferred triggers.
2211  */
2213 
2214  /*
2215  * Close open portals (converting holdable ones into static portals).
2216  * If there weren't any, we are done ... otherwise loop back to check
2217  * if they queued deferred triggers. Lather, rinse, repeat.
2218  */
2219  if (!PreCommit_Portals(false))
2220  break;
2221  }
2222 
2223  /*
2224  * The remaining actions cannot call any user-defined code, so it's safe
2225  * to start shutting down within-transaction services. But note that most
2226  * of this stuff could still throw an error, which would switch us into
2227  * the transaction-abort path.
2228  */
2229 
2232 
2233  /*
2234  * If this xact has started any unfinished parallel operation, clean up
2235  * its workers, warning about leaked resources. (But we don't actually
2236  * reset parallelModeLevel till entering TRANS_COMMIT, a bit below. This
2237  * keeps parallel mode restrictions active as long as possible in a
2238  * parallel worker.)
2239  */
2240  AtEOXact_Parallel(true);
2241  if (is_parallel_worker)
2242  {
2243  if (s->parallelModeLevel != 1)
2244  elog(WARNING, "parallelModeLevel is %d not 1 at end of parallel worker transaction",
2245  s->parallelModeLevel);
2246  }
2247  else
2248  {
2249  if (s->parallelModeLevel != 0)
2250  elog(WARNING, "parallelModeLevel is %d not 0 at end of transaction",
2251  s->parallelModeLevel);
2252  }
2253 
2254  /* Shut down the deferred-trigger manager */
2255  AfterTriggerEndXact(true);
2256 
2257  /*
2258  * Let ON COMMIT management do its thing (must happen after closing
2259  * cursors, to avoid dangling-reference problems)
2260  */
2262 
2263  /*
2264  * Synchronize files that are created and not WAL-logged during this
2265  * transaction. This must happen before AtEOXact_RelationMap(), so that we
2266  * don't see committed-but-broken files after a crash.
2267  */
2268  smgrDoPendingSyncs(true, is_parallel_worker);
2269 
2270  /* close large objects before lower-level cleanup */
2271  AtEOXact_LargeObject(true);
2272 
2273  /*
2274  * Insert notifications sent by NOTIFY commands into the queue. This
2275  * should be late in the pre-commit sequence to minimize time spent
2276  * holding the notify-insertion lock. However, this could result in
2277  * creating a snapshot, so we must do it before serializable cleanup.
2278  */
2279  PreCommit_Notify();
2280 
2281  /*
2282  * Mark serializable transaction as complete for predicate locking
2283  * purposes. This should be done as late as we can put it and still allow
2284  * errors to be raised for failure patterns found at commit. This is not
2285  * appropriate in a parallel worker however, because we aren't committing
2286  * the leader's transaction and its serializable state will live on.
2287  */
2288  if (!is_parallel_worker)
2290 
2291  /* Prevent cancel/die interrupt while cleaning up */
2292  HOLD_INTERRUPTS();
2293 
2294  /* Commit updates to the relation map --- do this as late as possible */
2295  AtEOXact_RelationMap(true, is_parallel_worker);
2296 
2297  /*
2298  * set the current transaction state information appropriately during
2299  * commit processing
2300  */
2301  s->state = TRANS_COMMIT;
2302  s->parallelModeLevel = 0;
2303  s->parallelChildXact = false; /* should be false already */
2304 
2305  /* Disable transaction timeout */
2306  if (TransactionTimeout > 0)
2308 
2309  if (!is_parallel_worker)
2310  {
2311  /*
2312  * We need to mark our XIDs as committed in pg_xact. This is where we
2313  * durably commit.
2314  */
2315  latestXid = RecordTransactionCommit();
2316  }
2317  else
2318  {
2319  /*
2320  * We must not mark our XID committed; the parallel leader is
2321  * responsible for that.
2322  */
2323  latestXid = InvalidTransactionId;
2324 
2325  /*
2326  * Make sure the leader will know about any WAL we wrote before it
2327  * commits.
2328  */
2330  }
2331 
2332  TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->vxid.lxid);
2333 
2334  /*
2335  * Let others know about no transaction in progress by me. Note that this
2336  * must be done _before_ releasing locks we hold and _after_
2337  * RecordTransactionCommit.
2338  */
2339  ProcArrayEndTransaction(MyProc, latestXid);
2340 
2341  /*
2342  * This is all post-commit cleanup. Note that if an error is raised here,
2343  * it's too late to abort the transaction. This should be just
2344  * noncritical resource releasing.
2345  *
2346  * The ordering of operations is not entirely random. The idea is:
2347  * release resources visible to other backends (eg, files, buffer pins);
2348  * then release locks; then release backend-local resources. We want to
2349  * release locks at the point where any backend waiting for us will see
2350  * our transaction as being fully cleaned up.
2351  *
2352  * Resources that can be associated with individual queries are handled by
2353  * the ResourceOwner mechanism. The other calls here are for backend-wide
2354  * state.
2355  */
2356 
2357  CallXactCallbacks(is_parallel_worker ? XACT_EVENT_PARALLEL_COMMIT
2358  : XACT_EVENT_COMMIT);
2359 
2360  CurrentResourceOwner = NULL;
2363  true, true);
2364 
2365  /* Check we've released all buffer pins */
2366  AtEOXact_Buffers(true);
2367 
2368  /* Clean up the relation cache */
2369  AtEOXact_RelationCache(true);
2370 
2371  /*
2372  * Make catalog changes visible to all backends. This has to happen after
2373  * relcache references are dropped (see comments for
2374  * AtEOXact_RelationCache), but before locks are released (if anyone is
2375  * waiting for lock on a relation we've modified, we want them to know
2376  * about the catalog change before they start using the relation).
2377  */
2378  AtEOXact_Inval(true);
2379 
2381 
2384  true, true);
2387  true, true);
2388 
2389  /*
2390  * Likewise, dropping of files deleted during the transaction is best done
2391  * after releasing relcache and buffer pins. (This is not strictly
2392  * necessary during commit, since such pins should have been released
2393  * already, but this ordering is definitely critical during abort.) Since
2394  * this may take many seconds, also delay until after releasing locks.
2395  * Other backends will observe the attendant catalog changes and not
2396  * attempt to access affected files.
2397  */
2398  smgrDoPendingDeletes(true);
2399 
2400  /*
2401  * Send out notification signals to other backends (and do other
2402  * post-commit NOTIFY cleanup). This must not happen until after our
2403  * transaction is fully done from the viewpoint of other backends.
2404  */
2405  AtCommit_Notify();
2406 
2407  /*
2408  * Everything after this should be purely internal-to-this-backend
2409  * cleanup.
2410  */
2411  AtEOXact_GUC(true, 1);
2412  AtEOXact_SPI(true);
2413  AtEOXact_Enum();
2415  AtEOXact_Namespace(true, is_parallel_worker);
2416  AtEOXact_SMgr();
2417  AtEOXact_Files(true);
2419  AtEOXact_HashTables(true);
2420  AtEOXact_PgStat(true, is_parallel_worker);
2421  AtEOXact_Snapshot(true, false);
2422  AtEOXact_ApplyLauncher(true);
2425 
2427  s->curTransactionOwner = NULL;
2430 
2431  AtCommit_Memory();
2432 
2435  s->nestingLevel = 0;
2436  s->gucNestLevel = 0;
2437  s->childXids = NULL;
2438  s->nChildXids = 0;
2439  s->maxChildXids = 0;
2440 
2443 
2444  /*
2445  * done with commit processing, set current transaction state back to
2446  * default
2447  */
2448  s->state = TRANS_DEFAULT;
2449 
2451 }
2452 
2453 
2454 /*
2455  * PrepareTransaction
2456  *
2457  * NB: if you change this routine, better look at CommitTransaction too!
2458  */
2459 static void
2461 {
2464  GlobalTransaction gxact;
2465  TimestampTz prepared_at;
2466 
2468 
2469  ShowTransactionState("PrepareTransaction");
2470 
2471  /*
2472  * check the current transaction state
2473  */
2474  if (s->state != TRANS_INPROGRESS)
2475  elog(WARNING, "PrepareTransaction while in %s state",
2477  Assert(s->parent == NULL);
2478 
2479  /*
2480  * Do pre-commit processing that involves calling user-defined code, such
2481  * as triggers. Since closing cursors could queue trigger actions,
2482  * triggers could open cursors, etc, we have to keep looping until there's
2483  * nothing left to do.
2484  */
2485  for (;;)
2486  {
2487  /*
2488  * Fire all currently pending deferred triggers.
2489  */
2491 
2492  /*
2493  * Close open portals (converting holdable ones into static portals).
2494  * If there weren't any, we are done ... otherwise loop back to check
2495  * if they queued deferred triggers. Lather, rinse, repeat.
2496  */
2497  if (!PreCommit_Portals(true))
2498  break;
2499  }
2500 
2502 
2503  /*
2504  * The remaining actions cannot call any user-defined code, so it's safe
2505  * to start shutting down within-transaction services. But note that most
2506  * of this stuff could still throw an error, which would switch us into
2507  * the transaction-abort path.
2508  */
2509 
2510  /* Shut down the deferred-trigger manager */
2511  AfterTriggerEndXact(true);
2512 
2513  /*
2514  * Let ON COMMIT management do its thing (must happen after closing
2515  * cursors, to avoid dangling-reference problems)
2516  */
2518 
2519  /*
2520  * Synchronize files that are created and not WAL-logged during this
2521  * transaction. This must happen before EndPrepare(), so that we don't see
2522  * committed-but-broken files after a crash and COMMIT PREPARED.
2523  */
2524  smgrDoPendingSyncs(true, false);
2525 
2526  /* close large objects before lower-level cleanup */
2527  AtEOXact_LargeObject(true);
2528 
2529  /* NOTIFY requires no work at this point */
2530 
2531  /*
2532  * Mark serializable transaction as complete for predicate locking
2533  * purposes. This should be done as late as we can put it and still allow
2534  * errors to be raised for failure patterns found at commit.
2535  */
2537 
2538  /*
2539  * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2540  * this transaction. Having the prepared xact hold locks on another
2541  * backend's temp table seems a bad idea --- for instance it would prevent
2542  * the backend from exiting. There are other problems too, such as how to
2543  * clean up the source backend's local buffers and ON COMMIT state if the
2544  * prepared xact includes a DROP of a temp table.
2545  *
2546  * Other objects types, like functions, operators or extensions, share the
2547  * same restriction as they should not be created, locked or dropped as
2548  * this can mess up with this session or even a follow-up session trying
2549  * to use the same temporary namespace.
2550  *
2551  * We must check this after executing any ON COMMIT actions, because they
2552  * might still access a temp relation.
2553  *
2554  * XXX In principle this could be relaxed to allow some useful special
2555  * cases, such as a temp table created and dropped all within the
2556  * transaction. That seems to require much more bookkeeping though.
2557  */
2559  ereport(ERROR,
2560  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2561  errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2562 
2563  /*
2564  * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2565  * supported if we added cleanup logic to twophase.c, but for now it
2566  * doesn't seem worth the trouble.
2567  */
2569  ereport(ERROR,
2570  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2571  errmsg("cannot PREPARE a transaction that has exported snapshots")));
2572 
2573  /* Prevent cancel/die interrupt while cleaning up */
2574  HOLD_INTERRUPTS();
2575 
2576  /*
2577  * set the current transaction state information appropriately during
2578  * prepare processing
2579  */
2580  s->state = TRANS_PREPARE;
2581 
2582  /* Disable transaction timeout */
2583  if (TransactionTimeout > 0)
2585 
2586  prepared_at = GetCurrentTimestamp();
2587 
2588  /*
2589  * Reserve the GID for this transaction. This could fail if the requested
2590  * GID is invalid or already in use.
2591  */
2592  gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
2593  GetUserId(), MyDatabaseId);
2594  prepareGID = NULL;
2595 
2596  /*
2597  * Collect data for the 2PC state file. Note that in general, no actual
2598  * state change should happen in the called modules during this step,
2599  * since it's still possible to fail before commit, and in that case we
2600  * want transaction abort to be able to clean up. (In particular, the
2601  * AtPrepare routines may error out if they find cases they cannot
2602  * handle.) State cleanup should happen in the PostPrepare routines
2603  * below. However, some modules can go ahead and clear state here because
2604  * they wouldn't do anything with it during abort anyway.
2605  *
2606  * Note: because the 2PC state file records will be replayed in the same
2607  * order they are made, the order of these calls has to match the order in
2608  * which we want things to happen during COMMIT PREPARED or ROLLBACK
2609  * PREPARED; in particular, pay attention to whether things should happen
2610  * before or after releasing the transaction's locks.
2611  */
2612  StartPrepare(gxact);
2613 
2614  AtPrepare_Notify();
2615  AtPrepare_Locks();
2617  AtPrepare_PgStat();
2620 
2621  /*
2622  * Here is where we really truly prepare.
2623  *
2624  * We have to record transaction prepares even if we didn't make any
2625  * updates, because the transaction manager might get confused if we lose
2626  * a global transaction.
2627  */
2628  EndPrepare(gxact);
2629 
2630  /*
2631  * Now we clean up backend-internal state and release internal resources.
2632  */
2633 
2634  /* Reset XactLastRecEnd until the next transaction writes something */
2635  XactLastRecEnd = 0;
2636 
2637  /*
2638  * Transfer our locks to a dummy PGPROC. This has to be done before
2639  * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2640  * conclude "xact already committed or aborted" for our locks.
2641  */
2642  PostPrepare_Locks(xid);
2643 
2644  /*
2645  * Let others know about no transaction in progress by me. This has to be
2646  * done *after* the prepared transaction has been marked valid, else
2647  * someone may think it is unlocked and recyclable.
2648  */
2650 
2651  /*
2652  * In normal commit-processing, this is all non-critical post-transaction
2653  * cleanup. When the transaction is prepared, however, it's important
2654  * that the locks and other per-backend resources are transferred to the
2655  * prepared transaction's PGPROC entry. Note that if an error is raised
2656  * here, it's too late to abort the transaction. XXX: This probably should
2657  * be in a critical section, to force a PANIC if any of this fails, but
2658  * that cure could be worse than the disease.
2659  */
2660 
2662 
2665  true, true);
2666 
2667  /* Check we've released all buffer pins */
2668  AtEOXact_Buffers(true);
2669 
2670  /* Clean up the relation cache */
2671  AtEOXact_RelationCache(true);
2672 
2673  /* notify doesn't need a postprepare call */
2674 
2676 
2678 
2679  PostPrepare_smgr();
2680 
2681  PostPrepare_MultiXact(xid);
2682 
2684 
2687  true, true);
2690  true, true);
2691 
2692  /*
2693  * Allow another backend to finish the transaction. After
2694  * PostPrepare_Twophase(), the transaction is completely detached from our
2695  * backend. The rest is just non-critical cleanup of backend-local state.
2696  */
2698 
2699  /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2700  AtEOXact_GUC(true, 1);
2701  AtEOXact_SPI(true);
2702  AtEOXact_Enum();
2704  AtEOXact_Namespace(true, false);
2705  AtEOXact_SMgr();
2706  AtEOXact_Files(true);
2708  AtEOXact_HashTables(true);
2709  /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2710  AtEOXact_Snapshot(true, true);
2711  /* we treat PREPARE as ROLLBACK so far as waking workers goes */
2712  AtEOXact_ApplyLauncher(false);
2715 
2716  CurrentResourceOwner = NULL;
2718  s->curTransactionOwner = NULL;
2721 
2722  AtCommit_Memory();
2723 
2726  s->nestingLevel = 0;
2727  s->gucNestLevel = 0;
2728  s->childXids = NULL;
2729  s->nChildXids = 0;
2730  s->maxChildXids = 0;
2731 
2734 
2735  /*
2736  * done with 1st phase commit processing, set current transaction state
2737  * back to default
2738  */
2739  s->state = TRANS_DEFAULT;
2740 
2742 }
2743 
2744 
2745 /*
2746  * AbortTransaction
2747  */
2748 static void
2750 {
2752  TransactionId latestXid;
2753  bool is_parallel_worker;
2754 
2755  /* Prevent cancel/die interrupt while cleaning up */
2756  HOLD_INTERRUPTS();
2757 
2758  /* Disable transaction timeout */
2759  if (TransactionTimeout > 0)
2761 
2762  /* Make sure we have a valid memory context and resource owner */
2763  AtAbort_Memory();
2765 
2766  /*
2767  * Release any LW locks we might be holding as quickly as possible.
2768  * (Regular locks, however, must be held till we finish aborting.)
2769  * Releasing LW locks is critical since we might try to grab them again
2770  * while cleaning up!
2771  */
2772  LWLockReleaseAll();
2773 
2774  /* Clear wait information and command progress indicator */
2777 
2778  /* Clean up buffer context locks, too */
2779  UnlockBuffers();
2780 
2781  /* Reset WAL record construction state */
2783 
2784  /* Cancel condition variable sleep */
2786 
2787  /*
2788  * Also clean up any open wait for lock, since the lock manager will choke
2789  * if we try to wait for another lock before doing this.
2790  */
2791  LockErrorCleanup();
2792 
2793  /*
2794  * If any timeout events are still active, make sure the timeout interrupt
2795  * is scheduled. This covers possible loss of a timeout interrupt due to
2796  * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2797  * We delay this till after LockErrorCleanup so that we don't uselessly
2798  * reschedule lock or deadlock check timeouts.
2799  */
2801 
2802  /*
2803  * Re-enable signals, in case we got here by longjmp'ing out of a signal
2804  * handler. We do this fairly early in the sequence so that the timeout
2805  * infrastructure will be functional if needed while aborting.
2806  */
2807  sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
2808 
2809  /*
2810  * check the current transaction state
2811  */
2812  is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2813  if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2814  elog(WARNING, "AbortTransaction while in %s state",
2816  Assert(s->parent == NULL);
2817 
2818  /*
2819  * set the current transaction state information appropriately during the
2820  * abort processing
2821  */
2822  s->state = TRANS_ABORT;
2823 
2824  /*
2825  * Reset user ID which might have been changed transiently. We need this
2826  * to clean up in case control escaped out of a SECURITY DEFINER function
2827  * or other local change of CurrentUserId; therefore, the prior value of
2828  * SecurityRestrictionContext also needs to be restored.
2829  *
2830  * (Note: it is not necessary to restore session authorization or role
2831  * settings here because those can only be changed via GUC, and GUC will
2832  * take care of rolling them back if need be.)
2833  */
2835 
2836  /* Forget about any active REINDEX. */
2838 
2839  /* Reset logical streaming state. */
2841 
2842  /* Reset snapshot export state. */
2844 
2845  /*
2846  * If this xact has started any unfinished parallel operation, clean up
2847  * its workers and exit parallel mode. Don't warn about leaked resources.
2848  */
2849  AtEOXact_Parallel(false);
2850  s->parallelModeLevel = 0;
2851  s->parallelChildXact = false; /* should be false already */
2852 
2853  /*
2854  * do abort processing
2855  */
2856  AfterTriggerEndXact(false); /* 'false' means it's abort */
2857  AtAbort_Portals();
2858  smgrDoPendingSyncs(false, is_parallel_worker);
2859  AtEOXact_LargeObject(false);
2860  AtAbort_Notify();
2861  AtEOXact_RelationMap(false, is_parallel_worker);
2862  AtAbort_Twophase();
2863 
2864  /*
2865  * Advertise the fact that we aborted in pg_xact (assuming that we got as
2866  * far as assigning an XID to advertise). But if we're inside a parallel
2867  * worker, skip this; the user backend must be the one to write the abort
2868  * record.
2869  */
2870  if (!is_parallel_worker)
2871  latestXid = RecordTransactionAbort(false);
2872  else
2873  {
2874  latestXid = InvalidTransactionId;
2875 
2876  /*
2877  * Since the parallel leader won't get our value of XactLastRecEnd in
2878  * this case, we nudge WAL-writer ourselves in this case. See related
2879  * comments in RecordTransactionAbort for why this matters.
2880  */
2882  }
2883 
2884  TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->vxid.lxid);
2885 
2886  /*
2887  * Let others know about no transaction in progress by me. Note that this
2888  * must be done _before_ releasing locks we hold and _after_
2889  * RecordTransactionAbort.
2890  */
2891  ProcArrayEndTransaction(MyProc, latestXid);
2892 
2893  /*
2894  * Post-abort cleanup. See notes in CommitTransaction() concerning
2895  * ordering. We can skip all of it if the transaction failed before
2896  * creating a resource owner.
2897  */
2898  if (TopTransactionResourceOwner != NULL)
2899  {
2900  if (is_parallel_worker)
2902  else
2904 
2907  false, true);
2908  AtEOXact_Buffers(false);
2909  AtEOXact_RelationCache(false);
2910  AtEOXact_Inval(false);
2914  false, true);
2917  false, true);
2918  smgrDoPendingDeletes(false);
2919 
2920  AtEOXact_GUC(false, 1);
2921  AtEOXact_SPI(false);
2922  AtEOXact_Enum();
2924  AtEOXact_Namespace(false, is_parallel_worker);
2925  AtEOXact_SMgr();
2926  AtEOXact_Files(false);
2928  AtEOXact_HashTables(false);
2929  AtEOXact_PgStat(false, is_parallel_worker);
2930  AtEOXact_ApplyLauncher(false);
2933  }
2934 
2935  /*
2936  * State remains TRANS_ABORT until CleanupTransaction().
2937  */
2939 }
2940 
2941 /*
2942  * CleanupTransaction
2943  */
2944 static void
2946 {
2948 
2949  /*
2950  * State should still be TRANS_ABORT from AbortTransaction().
2951  */
2952  if (s->state != TRANS_ABORT)
2953  elog(FATAL, "CleanupTransaction: unexpected state %s",
2955 
2956  /*
2957  * do abort cleanup processing
2958  */
2959  AtCleanup_Portals(); /* now safe to release portal memory */
2960  AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
2961 
2962  CurrentResourceOwner = NULL; /* and resource owner */
2965  s->curTransactionOwner = NULL;
2968 
2969  AtCleanup_Memory(); /* and transaction memory */
2970 
2973  s->nestingLevel = 0;
2974  s->gucNestLevel = 0;
2975  s->childXids = NULL;
2976  s->nChildXids = 0;
2977  s->maxChildXids = 0;
2978  s->parallelModeLevel = 0;
2979  s->parallelChildXact = false;
2980 
2983 
2984  /*
2985  * done with abort processing, set current transaction state back to
2986  * default
2987  */
2988  s->state = TRANS_DEFAULT;
2989 }
2990 
2991 /*
2992  * StartTransactionCommand
2993  */
2994 void
2996 {
2998 
2999  switch (s->blockState)
3000  {
3001  /*
3002  * if we aren't in a transaction block, we just do our usual start
3003  * transaction.
3004  */
3005  case TBLOCK_DEFAULT:
3006  StartTransaction();
3008  break;
3009 
3010  /*
3011  * We are somewhere in a transaction block or subtransaction and
3012  * about to start a new command. For now we do nothing, but
3013  * someday we may do command-local resource initialization. (Note
3014  * that any needed CommandCounterIncrement was done by the
3015  * previous CommitTransactionCommand.)
3016  */
3017  case TBLOCK_INPROGRESS:
3019  case TBLOCK_SUBINPROGRESS:
3020  break;
3021 
3022  /*
3023  * Here we are in a failed transaction block (one of the commands
3024  * caused an abort) so we do nothing but remain in the abort
3025  * state. Eventually we will get a ROLLBACK command which will
3026  * get us out of this state. (It is up to other code to ensure
3027  * that no commands other than ROLLBACK will be processed in these
3028  * states.)
3029  */
3030  case TBLOCK_ABORT:
3031  case TBLOCK_SUBABORT:
3032  break;
3033 
3034  /* These cases are invalid. */
3035  case TBLOCK_STARTED:
3036  case TBLOCK_BEGIN:
3038  case TBLOCK_SUBBEGIN:
3039  case TBLOCK_END:
3040  case TBLOCK_SUBRELEASE:
3041  case TBLOCK_SUBCOMMIT:
3042  case TBLOCK_ABORT_END:
3043  case TBLOCK_SUBABORT_END:
3044  case TBLOCK_ABORT_PENDING:
3046  case TBLOCK_SUBRESTART:
3048  case TBLOCK_PREPARE:
3049  elog(ERROR, "StartTransactionCommand: unexpected state %s",
3051  break;
3052  }
3053 
3054  /*
3055  * We must switch to CurTransactionContext before returning. This is
3056  * already done if we called StartTransaction, otherwise not.
3057  */
3058  Assert(CurTransactionContext != NULL);
3060 }
3061 
3062 
3063 /*
3064  * Simple system for saving and restoring transaction characteristics
3065  * (isolation level, read only, deferrable). We need this for transaction
3066  * chaining, so that we can set the characteristics of the new transaction to
3067  * be the same as the previous one. (We need something like this because the
3068  * GUC system resets the characteristics at transaction end, so for example
3069  * just skipping the reset in StartTransaction() won't work.)
3070  */
3071 void
3073 {
3077 }
3078 
3079 void
3081 {
3085 }
3086 
3087 /*
3088  * CommitTransactionCommand -- a wrapper function handling the
3089  * loop over subtransactions to avoid a potentially dangerous recursion
3090  * in CommitTransactionCommandInternal().
3091  */
3092 void
3094 {
3095  /*
3096  * Repeatedly call CommitTransactionCommandInternal() until all the work
3097  * is done.
3098  */
3100  {
3101  }
3102 }
3103 
3104 /*
3105  * CommitTransactionCommandInternal - a function doing an iteration of work
3106  * regarding handling the commit transaction command. In the case of
3107  * subtransactions more than one iterations could be required. Returns
3108  * true when no more iterations required, false otherwise.
3109  */
3110 static bool
3112 {
3115 
3116  /* Must save in case we need to restore below */
3118 
3119  switch (s->blockState)
3120  {
3121  /*
3122  * These shouldn't happen. TBLOCK_DEFAULT means the previous
3123  * StartTransactionCommand didn't set the STARTED state
3124  * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3125  * by EndParallelWorkerTransaction(), not this function.
3126  */
3127  case TBLOCK_DEFAULT:
3129  elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3131  break;
3132 
3133  /*
3134  * If we aren't in a transaction block, just do our usual
3135  * transaction commit, and return to the idle state.
3136  */
3137  case TBLOCK_STARTED:
3140  break;
3141 
3142  /*
3143  * We are completing a "BEGIN TRANSACTION" command, so we change
3144  * to the "transaction block in progress" state and return. (We
3145  * assume the BEGIN did nothing to the database, so we need no
3146  * CommandCounterIncrement.)
3147  */
3148  case TBLOCK_BEGIN:
3150  break;
3151 
3152  /*
3153  * This is the case when we have finished executing a command
3154  * someplace within a transaction block. We increment the command
3155  * counter and return.
3156  */
3157  case TBLOCK_INPROGRESS:
3159  case TBLOCK_SUBINPROGRESS:
3161  break;
3162 
3163  /*
3164  * We are completing a "COMMIT" command. Do it and return to the
3165  * idle state.
3166  */
3167  case TBLOCK_END:
3170  if (s->chain)
3171  {
3172  StartTransaction();
3174  s->chain = false;
3176  }
3177  break;
3178 
3179  /*
3180  * Here we are in the middle of a transaction block but one of the
3181  * commands caused an abort so we do nothing but remain in the
3182  * abort state. Eventually we will get a ROLLBACK command.
3183  */
3184  case TBLOCK_ABORT:
3185  case TBLOCK_SUBABORT:
3186  break;
3187 
3188  /*
3189  * Here we were in an aborted transaction block and we just got
3190  * the ROLLBACK command from the user, so clean up the
3191  * already-aborted transaction and return to the idle state.
3192  */
3193  case TBLOCK_ABORT_END:
3196  if (s->chain)
3197  {
3198  StartTransaction();
3200  s->chain = false;
3202  }
3203  break;
3204 
3205  /*
3206  * Here we were in a perfectly good transaction block but the user
3207  * told us to ROLLBACK anyway. We have to abort the transaction
3208  * and then clean up.
3209  */
3210  case TBLOCK_ABORT_PENDING:
3211  AbortTransaction();
3214  if (s->chain)
3215  {
3216  StartTransaction();
3218  s->chain = false;
3220  }
3221  break;
3222 
3223  /*
3224  * We are completing a "PREPARE TRANSACTION" command. Do it and
3225  * return to the idle state.
3226  */
3227  case TBLOCK_PREPARE:
3230  break;
3231 
3232  /*
3233  * The user issued a SAVEPOINT inside a transaction block. Start a
3234  * subtransaction. (DefineSavepoint already did PushTransaction,
3235  * so as to have someplace to put the SUBBEGIN state.)
3236  */
3237  case TBLOCK_SUBBEGIN:
3240  break;
3241 
3242  /*
3243  * The user issued a RELEASE command, so we end the current
3244  * subtransaction and return to the parent transaction. The parent
3245  * might be ended too, so repeat till we find an INPROGRESS
3246  * transaction or subtransaction.
3247  */
3248  case TBLOCK_SUBRELEASE:
3249  do
3250  {
3252  s = CurrentTransactionState; /* changed by pop */
3253  } while (s->blockState == TBLOCK_SUBRELEASE);
3254 
3257  break;
3258 
3259  /*
3260  * The user issued a COMMIT, so we end the current subtransaction
3261  * hierarchy and perform final commit. We do this by rolling up
3262  * any subtransactions into their parent, which leads to O(N^2)
3263  * operations with respect to resource owners - this isn't that
3264  * bad until we approach a thousands of savepoints but is
3265  * necessary for correctness should after triggers create new
3266  * resource owners.
3267  */
3268  case TBLOCK_SUBCOMMIT:
3269  do
3270  {
3272  s = CurrentTransactionState; /* changed by pop */
3273  } while (s->blockState == TBLOCK_SUBCOMMIT);
3274  /* If we had a COMMIT command, finish off the main xact too */
3275  if (s->blockState == TBLOCK_END)
3276  {
3277  Assert(s->parent == NULL);
3280  if (s->chain)
3281  {
3282  StartTransaction();
3284  s->chain = false;
3286  }
3287  }
3288  else if (s->blockState == TBLOCK_PREPARE)
3289  {
3290  Assert(s->parent == NULL);
3293  }
3294  else
3295  elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3297  break;
3298 
3299  /*
3300  * The current already-failed subtransaction is ending due to a
3301  * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3302  * examine the parent (which could be in any of several states).
3303  * As we need to examine the parent, return false to request the
3304  * caller to do the next iteration.
3305  */
3306  case TBLOCK_SUBABORT_END:
3308  return false;
3309 
3310  /*
3311  * As above, but it's not dead yet, so abort first.
3312  */
3316  return false;
3317 
3318  /*
3319  * The current subtransaction is the target of a ROLLBACK TO
3320  * command. Abort and pop it, then start a new subtransaction
3321  * with the same name.
3322  */
3323  case TBLOCK_SUBRESTART:
3324  {
3325  char *name;
3326  int savepointLevel;
3327 
3328  /* save name and keep Cleanup from freeing it */
3329  name = s->name;
3330  s->name = NULL;
3331  savepointLevel = s->savepointLevel;
3332 
3335 
3336  DefineSavepoint(NULL);
3337  s = CurrentTransactionState; /* changed by push */
3338  s->name = name;
3339  s->savepointLevel = savepointLevel;
3340 
3341  /* This is the same as TBLOCK_SUBBEGIN case */
3345  }
3346  break;
3347 
3348  /*
3349  * Same as above, but the subtransaction had already failed, so we
3350  * don't need AbortSubTransaction.
3351  */
3353  {
3354  char *name;
3355  int savepointLevel;
3356 
3357  /* save name and keep Cleanup from freeing it */
3358  name = s->name;
3359  s->name = NULL;
3360  savepointLevel = s->savepointLevel;
3361 
3363 
3364  DefineSavepoint(NULL);
3365  s = CurrentTransactionState; /* changed by push */
3366  s->name = name;
3367  s->savepointLevel = savepointLevel;
3368 
3369  /* This is the same as TBLOCK_SUBBEGIN case */
3373  }
3374  break;
3375  }
3376 
3377  /* Done, no more iterations required */
3378  return true;
3379 }
3380 
3381 /*
3382  * AbortCurrentTransaction -- a wrapper function handling the
3383  * loop over subtransactions to avoid potentially dangerous recursion in
3384  * AbortCurrentTransactionInternal().
3385  */
3386 void
3388 {
3389  /*
3390  * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3391  * done.
3392  */
3394  {
3395  }
3396 }
3397 
3398 /*
3399  * AbortCurrentTransactionInternal - a function doing an iteration of work
3400  * regarding handling the current transaction abort. In the case of
3401  * subtransactions more than one iterations could be required. Returns
3402  * true when no more iterations required, false otherwise.
3403  */
3404 static bool
3406 {
3408 
3409  switch (s->blockState)
3410  {
3411  case TBLOCK_DEFAULT:
3412  if (s->state == TRANS_DEFAULT)
3413  {
3414  /* we are idle, so nothing to do */
3415  }
3416  else
3417  {
3418  /*
3419  * We can get here after an error during transaction start
3420  * (state will be TRANS_START). Need to clean up the
3421  * incompletely started transaction. First, adjust the
3422  * low-level state to suppress warning message from
3423  * AbortTransaction.
3424  */
3425  if (s->state == TRANS_START)
3426  s->state = TRANS_INPROGRESS;
3427  AbortTransaction();
3429  }
3430  break;
3431 
3432  /*
3433  * If we aren't in a transaction block, we just do the basic abort
3434  * & cleanup transaction. For this purpose, we treat an implicit
3435  * transaction block as if it were a simple statement.
3436  */
3437  case TBLOCK_STARTED:
3439  AbortTransaction();
3442  break;
3443 
3444  /*
3445  * If we are in TBLOCK_BEGIN it means something screwed up right
3446  * after reading "BEGIN TRANSACTION". We assume that the user
3447  * will interpret the error as meaning the BEGIN failed to get him
3448  * into a transaction block, so we should abort and return to idle
3449  * state.
3450  */
3451  case TBLOCK_BEGIN:
3452  AbortTransaction();
3455  break;
3456 
3457  /*
3458  * We are somewhere in a transaction block and we've gotten a
3459  * failure, so we abort the transaction and set up the persistent
3460  * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3461  */
3462  case TBLOCK_INPROGRESS:
3464  AbortTransaction();
3465  s->blockState = TBLOCK_ABORT;
3466  /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3467  break;
3468 
3469  /*
3470  * Here, we failed while trying to COMMIT. Clean up the
3471  * transaction and return to idle state (we do not want to stay in
3472  * the transaction).
3473  */
3474  case TBLOCK_END:
3475  AbortTransaction();
3478  break;
3479 
3480  /*
3481  * Here, we are already in an aborted transaction state and are
3482  * waiting for a ROLLBACK, but for some reason we failed again! So
3483  * we just remain in the abort state.
3484  */
3485  case TBLOCK_ABORT:
3486  case TBLOCK_SUBABORT:
3487  break;
3488 
3489  /*
3490  * We are in a failed transaction and we got the ROLLBACK command.
3491  * We have already aborted, we just need to cleanup and go to idle
3492  * state.
3493  */
3494  case TBLOCK_ABORT_END:
3497  break;
3498 
3499  /*
3500  * We are in a live transaction and we got a ROLLBACK command.
3501  * Abort, cleanup, go to idle state.
3502  */
3503  case TBLOCK_ABORT_PENDING:
3504  AbortTransaction();
3507  break;
3508 
3509  /*
3510  * Here, we failed while trying to PREPARE. Clean up the
3511  * transaction and return to idle state (we do not want to stay in
3512  * the transaction).
3513  */
3514  case TBLOCK_PREPARE:
3515  AbortTransaction();
3518  break;
3519 
3520  /*
3521  * We got an error inside a subtransaction. Abort just the
3522  * subtransaction, and go to the persistent SUBABORT state until
3523  * we get ROLLBACK.
3524  */
3525  case TBLOCK_SUBINPROGRESS:
3528  break;
3529 
3530  /*
3531  * If we failed while trying to create a subtransaction, clean up
3532  * the broken subtransaction and abort the parent. The same
3533  * applies if we get a failure while ending a subtransaction. As
3534  * we need to abort the parent, return false to request the caller
3535  * to do the next iteration.
3536  */
3537  case TBLOCK_SUBBEGIN:
3538  case TBLOCK_SUBRELEASE:
3539  case TBLOCK_SUBCOMMIT:
3541  case TBLOCK_SUBRESTART:
3544  return false;
3545 
3546  /*
3547  * Same as above, except the Abort() was already done.
3548  */
3549  case TBLOCK_SUBABORT_END:
3552  return false;
3553  }
3554 
3555  /* Done, no more iterations required */
3556  return true;
3557 }
3558 
3559 /*
3560  * PreventInTransactionBlock
3561  *
3562  * This routine is to be called by statements that must not run inside
3563  * a transaction block, typically because they have non-rollback-able
3564  * side effects or do internal commits.
3565  *
3566  * If this routine completes successfully, then the calling statement is
3567  * guaranteed that if it completes without error, its results will be
3568  * committed immediately.
3569  *
3570  * If we have already started a transaction block, issue an error; also issue
3571  * an error if we appear to be running inside a user-defined function (which
3572  * could issue more commands and possibly cause a failure after the statement
3573  * completes). Subtransactions are verboten too.
3574  *
3575  * We must also set XACT_FLAGS_NEEDIMMEDIATECOMMIT in MyXactFlags, to ensure
3576  * that postgres.c follows through by committing after the statement is done.
3577  *
3578  * isTopLevel: passed down from ProcessUtility to determine whether we are
3579  * inside a function. (We will always fail if this is false, but it's
3580  * convenient to centralize the check here instead of making callers do it.)
3581  * stmtType: statement type name, for error messages.
3582  */
3583 void
3584 PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
3585 {
3586  /*
3587  * xact block already started?
3588  */
3589  if (IsTransactionBlock())
3590  ereport(ERROR,
3591  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3592  /* translator: %s represents an SQL statement name */
3593  errmsg("%s cannot run inside a transaction block",
3594  stmtType)));
3595 
3596  /*
3597  * subtransaction?
3598  */
3599  if (IsSubTransaction())
3600  ereport(ERROR,
3601  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3602  /* translator: %s represents an SQL statement name */
3603  errmsg("%s cannot run inside a subtransaction",
3604  stmtType)));
3605 
3606  /*
3607  * inside a pipeline that has started an implicit transaction?
3608  */
3610  ereport(ERROR,
3611  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3612  /* translator: %s represents an SQL statement name */
3613  errmsg("%s cannot be executed within a pipeline",
3614  stmtType)));
3615 
3616  /*
3617  * inside a function call?
3618  */
3619  if (!isTopLevel)
3620  ereport(ERROR,
3621  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3622  /* translator: %s represents an SQL statement name */
3623  errmsg("%s cannot be executed from a function", stmtType)));
3624 
3625  /* If we got past IsTransactionBlock test, should be in default state */
3628  elog(FATAL, "cannot prevent transaction chain");
3629 
3630  /* All okay. Set the flag to make sure the right thing happens later. */
3632 }
3633 
3634 /*
3635  * WarnNoTransactionBlock
3636  * RequireTransactionBlock
3637  *
3638  * These two functions allow for warnings or errors if a command is executed
3639  * outside of a transaction block. This is useful for commands that have no
3640  * effects that persist past transaction end (and so calling them outside a
3641  * transaction block is presumably an error). DECLARE CURSOR is an example.
3642  * While top-level transaction control commands (BEGIN/COMMIT/ABORT) and SET
3643  * that have no effect issue warnings, all other no-effect commands generate
3644  * errors.
3645  *
3646  * If we appear to be running inside a user-defined function, we do not
3647  * issue anything, since the function could issue more commands that make
3648  * use of the current statement's results. Likewise subtransactions.
3649  * Thus these are inverses for PreventInTransactionBlock.
3650  *
3651  * isTopLevel: passed down from ProcessUtility to determine whether we are
3652  * inside a function.
3653  * stmtType: statement type name, for warning or error messages.
3654  */
3655 void
3656 WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
3657 {
3658  CheckTransactionBlock(isTopLevel, false, stmtType);
3659 }
3660 
3661 void
3662 RequireTransactionBlock(bool isTopLevel, const char *stmtType)
3663 {
3664  CheckTransactionBlock(isTopLevel, true, stmtType);
3665 }
3666 
3667 /*
3668  * This is the implementation of the above two.
3669  */
3670 static void
3671 CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
3672 {
3673  /*
3674  * xact block already started?
3675  */
3676  if (IsTransactionBlock())
3677  return;
3678 
3679  /*
3680  * subtransaction?
3681  */
3682  if (IsSubTransaction())
3683  return;
3684 
3685  /*
3686  * inside a function call?
3687  */
3688  if (!isTopLevel)
3689  return;
3690 
3691  ereport(throwError ? ERROR : WARNING,
3692  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3693  /* translator: %s represents an SQL statement name */
3694  errmsg("%s can only be used in transaction blocks",
3695  stmtType)));
3696 }
3697 
3698 /*
3699  * IsInTransactionBlock
3700  *
3701  * This routine is for statements that need to behave differently inside
3702  * a transaction block than when running as single commands. ANALYZE is
3703  * currently the only example.
3704  *
3705  * If this routine returns "false", then the calling statement is allowed
3706  * to perform internal transaction-commit-and-start cycles; there is not a
3707  * risk of messing up any transaction already in progress. (Note that this
3708  * is not the identical guarantee provided by PreventInTransactionBlock,
3709  * since we will not force a post-statement commit.)
3710  *
3711  * isTopLevel: passed down from ProcessUtility to determine whether we are
3712  * inside a function.
3713  */
3714 bool
3715 IsInTransactionBlock(bool isTopLevel)
3716 {
3717  /*
3718  * Return true on same conditions that would make
3719  * PreventInTransactionBlock error out
3720  */
3721  if (IsTransactionBlock())
3722  return true;
3723 
3724  if (IsSubTransaction())
3725  return true;
3726 
3728  return true;
3729 
3730  if (!isTopLevel)
3731  return true;
3732 
3735  return true;
3736 
3737  return false;
3738 }
3739 
3740 
3741 /*
3742  * Register or deregister callback functions for start- and end-of-xact
3743  * operations.
3744  *
3745  * These functions are intended for use by dynamically loaded modules.
3746  * For built-in modules we generally just hardwire the appropriate calls
3747  * (mainly because it's easier to control the order that way, where needed).
3748  *
3749  * At transaction end, the callback occurs post-commit or post-abort, so the
3750  * callback functions can only do noncritical cleanup.
3751  */
3752 void
3754 {
3755  XactCallbackItem *item;
3756 
3757  item = (XactCallbackItem *)
3759  item->callback = callback;
3760  item->arg = arg;
3761  item->next = Xact_callbacks;
3762  Xact_callbacks = item;
3763 }
3764 
3765 void
3767 {
3768  XactCallbackItem *item;
3769  XactCallbackItem *prev;
3770 
3771  prev = NULL;
3772  for (item = Xact_callbacks; item; prev = item, item = item->next)
3773  {
3774  if (item->callback == callback && item->arg == arg)
3775  {
3776  if (prev)
3777  prev->next = item->next;
3778  else
3779  Xact_callbacks = item->next;
3780  pfree(item);
3781  break;
3782  }
3783  }
3784 }
3785 
3786 static void
3788 {
3789  XactCallbackItem *item;
3791 
3792  for (item = Xact_callbacks; item; item = next)
3793  {
3794  /* allow callbacks to unregister themselves when called */
3795  next = item->next;
3796  item->callback(event, item->arg);
3797  }
3798 }
3799 
3800 
3801 /*
3802  * Register or deregister callback functions for start- and end-of-subxact
3803  * operations.
3804  *
3805  * Pretty much same as above, but for subtransaction events.
3806  *
3807  * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3808  * so the callback functions can only do noncritical cleanup. At
3809  * subtransaction start, the callback is called when the subtransaction has
3810  * finished initializing.
3811  */
3812 void
3814 {
3815  SubXactCallbackItem *item;
3816 
3817  item = (SubXactCallbackItem *)
3819  item->callback = callback;
3820  item->arg = arg;
3821  item->next = SubXact_callbacks;
3822  SubXact_callbacks = item;
3823 }
3824 
3825 void
3827 {
3828  SubXactCallbackItem *item;
3829  SubXactCallbackItem *prev;
3830 
3831  prev = NULL;
3832  for (item = SubXact_callbacks; item; prev = item, item = item->next)
3833  {
3834  if (item->callback == callback && item->arg == arg)
3835  {
3836  if (prev)
3837  prev->next = item->next;
3838  else
3839  SubXact_callbacks = item->next;
3840  pfree(item);
3841  break;
3842  }
3843  }
3844 }
3845 
3846 static void
3848  SubTransactionId mySubid,
3849  SubTransactionId parentSubid)
3850 {
3851  SubXactCallbackItem *item;
3853 
3854  for (item = SubXact_callbacks; item; item = next)
3855  {
3856  /* allow callbacks to unregister themselves when called */
3857  next = item->next;
3858  item->callback(event, mySubid, parentSubid, item->arg);
3859  }
3860 }
3861 
3862 
3863 /* ----------------------------------------------------------------
3864  * transaction block support
3865  * ----------------------------------------------------------------
3866  */
3867 
3868 /*
3869  * BeginTransactionBlock
3870  * This executes a BEGIN command.
3871  */
3872 void
3874 {
3876 
3877  switch (s->blockState)
3878  {
3879  /*
3880  * We are not inside a transaction block, so allow one to begin.
3881  */
3882  case TBLOCK_STARTED:
3883  s->blockState = TBLOCK_BEGIN;
3884  break;
3885 
3886  /*
3887  * BEGIN converts an implicit transaction block to a regular one.
3888  * (Note that we allow this even if we've already done some
3889  * commands, which is a bit odd but matches historical practice.)
3890  */
3892  s->blockState = TBLOCK_BEGIN;
3893  break;
3894 
3895  /*
3896  * Already a transaction block in progress.
3897  */
3898  case TBLOCK_INPROGRESS:
3900  case TBLOCK_SUBINPROGRESS:
3901  case TBLOCK_ABORT:
3902  case TBLOCK_SUBABORT:
3903  ereport(WARNING,
3904  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3905  errmsg("there is already a transaction in progress")));
3906  break;
3907 
3908  /* These cases are invalid. */
3909  case TBLOCK_DEFAULT:
3910  case TBLOCK_BEGIN:
3911  case TBLOCK_SUBBEGIN:
3912  case TBLOCK_END:
3913  case TBLOCK_SUBRELEASE:
3914  case TBLOCK_SUBCOMMIT:
3915  case TBLOCK_ABORT_END:
3916  case TBLOCK_SUBABORT_END:
3917  case TBLOCK_ABORT_PENDING:
3919  case TBLOCK_SUBRESTART:
3921  case TBLOCK_PREPARE:
3922  elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3924  break;
3925  }
3926 }
3927 
3928 /*
3929  * PrepareTransactionBlock
3930  * This executes a PREPARE command.
3931  *
3932  * Since PREPARE may actually do a ROLLBACK, the result indicates what
3933  * happened: true for PREPARE, false for ROLLBACK.
3934  *
3935  * Note that we don't actually do anything here except change blockState.
3936  * The real work will be done in the upcoming PrepareTransaction().
3937  * We do it this way because it's not convenient to change memory context,
3938  * resource owner, etc while executing inside a Portal.
3939  */
3940 bool
3941 PrepareTransactionBlock(const char *gid)
3942 {
3943  TransactionState s;
3944  bool result;
3945 
3946  /* Set up to commit the current transaction */
3947  result = EndTransactionBlock(false);
3948 
3949  /* If successful, change outer tblock state to PREPARE */
3950  if (result)
3951  {
3953 
3954  while (s->parent != NULL)
3955  s = s->parent;
3956 
3957  if (s->blockState == TBLOCK_END)
3958  {
3959  /* Save GID where PrepareTransaction can find it again */
3961 
3963  }
3964  else
3965  {
3966  /*
3967  * ignore case where we are not in a transaction;
3968  * EndTransactionBlock already issued a warning.
3969  */
3972  /* Don't send back a PREPARE result tag... */
3973  result = false;
3974  }
3975  }
3976 
3977  return result;
3978 }
3979 
3980 /*
3981  * EndTransactionBlock
3982  * This executes a COMMIT command.
3983  *
3984  * Since COMMIT may actually do a ROLLBACK, the result indicates what
3985  * happened: true for COMMIT, false for ROLLBACK.
3986  *
3987  * Note that we don't actually do anything here except change blockState.
3988  * The real work will be done in the upcoming CommitTransactionCommand().
3989  * We do it this way because it's not convenient to change memory context,
3990  * resource owner, etc while executing inside a Portal.
3991  */
3992 bool
3994 {
3996  bool result = false;
3997 
3998  switch (s->blockState)
3999  {
4000  /*
4001  * We are in a transaction block, so tell CommitTransactionCommand
4002  * to COMMIT.
4003  */
4004  case TBLOCK_INPROGRESS:
4005  s->blockState = TBLOCK_END;
4006  result = true;
4007  break;
4008 
4009  /*
4010  * We are in an implicit transaction block. If AND CHAIN was
4011  * specified, error. Otherwise commit, but issue a warning
4012  * because there was no explicit BEGIN before this.
4013  */
4015  if (chain)
4016  ereport(ERROR,
4017  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4018  /* translator: %s represents an SQL statement name */
4019  errmsg("%s can only be used in transaction blocks",
4020  "COMMIT AND CHAIN")));
4021  else
4022  ereport(WARNING,
4023  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4024  errmsg("there is no transaction in progress")));
4025  s->blockState = TBLOCK_END;
4026  result = true;
4027  break;
4028 
4029  /*
4030  * We are in a failed transaction block. Tell
4031  * CommitTransactionCommand it's time to exit the block.
4032  */
4033  case TBLOCK_ABORT:
4035  break;
4036 
4037  /*
4038  * We are in a live subtransaction block. Set up to subcommit all
4039  * open subtransactions and then commit the main transaction.
4040  */
4041  case TBLOCK_SUBINPROGRESS:
4042  while (s->parent != NULL)
4043  {
4044  if (s->blockState == TBLOCK_SUBINPROGRESS)
4046  else
4047  elog(FATAL, "EndTransactionBlock: unexpected state %s",
4049  s = s->parent;
4050  }
4051  if (s->blockState == TBLOCK_INPROGRESS)
4052  s->blockState = TBLOCK_END;
4053  else
4054  elog(FATAL, "EndTransactionBlock: unexpected state %s",
4056  result = true;
4057  break;
4058 
4059  /*
4060  * Here we are inside an aborted subtransaction. Treat the COMMIT
4061  * as ROLLBACK: set up to abort everything and exit the main
4062  * transaction.
4063  */
4064  case TBLOCK_SUBABORT:
4065  while (s->parent != NULL)
4066  {
4067  if (s->blockState == TBLOCK_SUBINPROGRESS)
4069  else if (s->blockState == TBLOCK_SUBABORT)
4071  else
4072  elog(FATAL, "EndTransactionBlock: unexpected state %s",
4074  s = s->parent;
4075  }
4076  if (s->blockState == TBLOCK_INPROGRESS)
4078  else if (s->blockState == TBLOCK_ABORT)
4080  else
4081  elog(FATAL, "EndTransactionBlock: unexpected state %s",
4083  break;
4084 
4085  /*
4086  * The user issued COMMIT when not inside a transaction. For
4087  * COMMIT without CHAIN, issue a WARNING, staying in
4088  * TBLOCK_STARTED state. The upcoming call to
4089  * CommitTransactionCommand() will then close the transaction and
4090  * put us back into the default state. For COMMIT AND CHAIN,
4091  * error.
4092  */
4093  case TBLOCK_STARTED:
4094  if (chain)
4095  ereport(ERROR,
4096  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4097  /* translator: %s represents an SQL statement name */
4098  errmsg("%s can only be used in transaction blocks",
4099  "COMMIT AND CHAIN")));
4100  else
4101  ereport(WARNING,
4102  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4103  errmsg("there is no transaction in progress")));
4104  result = true;
4105  break;
4106 
4107  /*
4108  * The user issued a COMMIT that somehow ran inside a parallel
4109  * worker. We can't cope with that.
4110  */
4112  ereport(FATAL,
4113  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4114  errmsg("cannot commit during a parallel operation")));
4115  break;
4116 
4117  /* These cases are invalid. */
4118  case TBLOCK_DEFAULT:
4119  case TBLOCK_BEGIN:
4120  case TBLOCK_SUBBEGIN:
4121  case TBLOCK_END:
4122  case TBLOCK_SUBRELEASE:
4123  case TBLOCK_SUBCOMMIT:
4124  case TBLOCK_ABORT_END:
4125  case TBLOCK_SUBABORT_END:
4126  case TBLOCK_ABORT_PENDING:
4128  case TBLOCK_SUBRESTART:
4130  case TBLOCK_PREPARE:
4131  elog(FATAL, "EndTransactionBlock: unexpected state %s",
4133  break;
4134  }
4135 
4137  s->blockState == TBLOCK_END ||
4138  s->blockState == TBLOCK_ABORT_END ||
4140 
4141  s->chain = chain;
4142 
4143  return result;
4144 }
4145 
4146 /*
4147  * UserAbortTransactionBlock
4148  * This executes a ROLLBACK command.
4149  *
4150  * As above, we don't actually do anything here except change blockState.
4151  */
4152 void
4154 {
4156 
4157  switch (s->blockState)
4158  {
4159  /*
4160  * We are inside a transaction block and we got a ROLLBACK command
4161  * from the user, so tell CommitTransactionCommand to abort and
4162  * exit the transaction block.
4163  */
4164  case TBLOCK_INPROGRESS:
4166  break;
4167 
4168  /*
4169  * We are inside a failed transaction block and we got a ROLLBACK
4170  * command from the user. Abort processing is already done, so
4171  * CommitTransactionCommand just has to cleanup and go back to
4172  * idle state.
4173  */
4174  case TBLOCK_ABORT:
4176  break;
4177 
4178  /*
4179  * We are inside a subtransaction. Mark everything up to top
4180  * level as exitable.
4181  */
4182  case TBLOCK_SUBINPROGRESS:
4183  case TBLOCK_SUBABORT:
4184  while (s->parent != NULL)
4185  {
4186  if (s->blockState == TBLOCK_SUBINPROGRESS)
4188  else if (s->blockState == TBLOCK_SUBABORT)
4190  else
4191  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4193  s = s->parent;
4194  }
4195  if (s->blockState == TBLOCK_INPROGRESS)
4197  else if (s->blockState == TBLOCK_ABORT)
4199  else
4200  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4202  break;
4203 
4204  /*
4205  * The user issued ABORT when not inside a transaction. For
4206  * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4207  * The upcoming call to CommitTransactionCommand() will then put
4208  * us back into the default state. For ROLLBACK AND CHAIN, error.
4209  *
4210  * We do the same thing with ABORT inside an implicit transaction,
4211  * although in this case we might be rolling back actual database
4212  * state changes. (It's debatable whether we should issue a
4213  * WARNING in this case, but we have done so historically.)
4214  */
4215  case TBLOCK_STARTED:
4217  if (chain)
4218  ereport(ERROR,
4219  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4220  /* translator: %s represents an SQL statement name */
4221  errmsg("%s can only be used in transaction blocks",
4222  "ROLLBACK AND CHAIN")));
4223  else
4224  ereport(WARNING,
4225  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4226  errmsg("there is no transaction in progress")));
4228  break;
4229 
4230  /*
4231  * The user issued an ABORT that somehow ran inside a parallel
4232  * worker. We can't cope with that.
4233  */
4235  ereport(FATAL,
4236  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4237  errmsg("cannot abort during a parallel operation")));
4238  break;
4239 
4240  /* These cases are invalid. */
4241  case TBLOCK_DEFAULT:
4242  case TBLOCK_BEGIN:
4243  case TBLOCK_SUBBEGIN:
4244  case TBLOCK_END:
4245  case TBLOCK_SUBRELEASE:
4246  case TBLOCK_SUBCOMMIT:
4247  case TBLOCK_ABORT_END:
4248  case TBLOCK_SUBABORT_END:
4249  case TBLOCK_ABORT_PENDING:
4251  case TBLOCK_SUBRESTART:
4253  case TBLOCK_PREPARE:
4254  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4256  break;
4257  }
4258 
4261 
4262  s->chain = chain;
4263 }
4264 
4265 /*
4266  * BeginImplicitTransactionBlock
4267  * Start an implicit transaction block if we're not already in one.
4268  *
4269  * Unlike BeginTransactionBlock, this is called directly from the main loop
4270  * in postgres.c, not within a Portal. So we can just change blockState
4271  * without a lot of ceremony. We do not expect caller to do
4272  * CommitTransactionCommand/StartTransactionCommand.
4273  */
4274 void
4276 {
4278 
4279  /*
4280  * If we are in STARTED state (that is, no transaction block is open),
4281  * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4282  * block.
4283  *
4284  * For caller convenience, we consider all other transaction states as
4285  * legal here; otherwise the caller would need its own state check, which
4286  * seems rather pointless.
4287  */
4288  if (s->blockState == TBLOCK_STARTED)
4290 }
4291 
4292 /*
4293  * EndImplicitTransactionBlock
4294  * End an implicit transaction block, if we're in one.
4295  *
4296  * Like EndTransactionBlock, we just make any needed blockState change here.
4297  * The real work will be done in the upcoming CommitTransactionCommand().
4298  */
4299 void
4301 {
4303 
4304  /*
4305  * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4306  * allowing CommitTransactionCommand to commit whatever happened during
4307  * the implicit transaction block as though it were a single statement.
4308  *
4309  * For caller convenience, we consider all other transaction states as
4310  * legal here; otherwise the caller would need its own state check, which
4311  * seems rather pointless.
4312  */
4315 }
4316 
4317 /*
4318  * DefineSavepoint
4319  * This executes a SAVEPOINT command.
4320  */
4321 void
4322 DefineSavepoint(const char *name)
4323 {
4325 
4326  /*
4327  * Workers synchronize transaction state at the beginning of each parallel
4328  * operation, so we can't account for new subtransactions after that
4329  * point. (Note that this check will certainly error out if s->blockState
4330  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4331  * below.)
4332  */
4334  ereport(ERROR,
4335  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4336  errmsg("cannot define savepoints during a parallel operation")));
4337 
4338  switch (s->blockState)
4339  {
4340  case TBLOCK_INPROGRESS:
4341  case TBLOCK_SUBINPROGRESS:
4342  /* Normal subtransaction start */
4343  PushTransaction();
4344  s = CurrentTransactionState; /* changed by push */
4345 
4346  /*
4347  * Savepoint names, like the TransactionState block itself, live
4348  * in TopTransactionContext.
4349  */
4350  if (name)
4352  break;
4353 
4354  /*
4355  * We disallow savepoint commands in implicit transaction blocks.
4356  * There would be no great difficulty in allowing them so far as
4357  * this module is concerned, but a savepoint seems inconsistent
4358  * with exec_simple_query's behavior of abandoning the whole query
4359  * string upon error. Also, the point of an implicit transaction
4360  * block (as opposed to a regular one) is to automatically close
4361  * after an error, so it's hard to see how a savepoint would fit
4362  * into that.
4363  *
4364  * The error messages for this are phrased as if there were no
4365  * active transaction block at all, which is historical but
4366  * perhaps could be improved.
4367  */
4369  ereport(ERROR,
4370  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4371  /* translator: %s represents an SQL statement name */
4372  errmsg("%s can only be used in transaction blocks",
4373  "SAVEPOINT")));
4374  break;
4375 
4376  /* These cases are invalid. */
4377  case TBLOCK_DEFAULT:
4378  case TBLOCK_STARTED:
4379  case TBLOCK_BEGIN:
4381  case TBLOCK_SUBBEGIN:
4382  case TBLOCK_END:
4383  case TBLOCK_SUBRELEASE:
4384  case TBLOCK_SUBCOMMIT:
4385  case TBLOCK_ABORT:
4386  case TBLOCK_SUBABORT:
4387  case TBLOCK_ABORT_END:
4388  case TBLOCK_SUBABORT_END:
4389  case TBLOCK_ABORT_PENDING:
4391  case TBLOCK_SUBRESTART:
4393  case TBLOCK_PREPARE:
4394  elog(FATAL, "DefineSavepoint: unexpected state %s",
4396  break;
4397  }
4398 }
4399 
4400 /*
4401  * ReleaseSavepoint
4402  * This executes a RELEASE command.
4403  *
4404  * As above, we don't actually do anything here except change blockState.
4405  */
4406 void
4408 {
4410  TransactionState target,
4411  xact;
4412 
4413  /*
4414  * Workers synchronize transaction state at the beginning of each parallel
4415  * operation, so we can't account for transaction state change after that
4416  * point. (Note that this check will certainly error out if s->blockState
4417  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4418  * below.)
4419  */
4421  ereport(ERROR,
4422  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4423  errmsg("cannot release savepoints during a parallel operation")));
4424 
4425  switch (s->blockState)
4426  {
4427  /*
4428  * We can't release a savepoint if there is no savepoint defined.
4429  */
4430  case TBLOCK_INPROGRESS:
4431  ereport(ERROR,
4432  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4433  errmsg("savepoint \"%s\" does not exist", name)));
4434  break;
4435 
4437  /* See comment about implicit transactions in DefineSavepoint */
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  "RELEASE SAVEPOINT")));
4443  break;
4444 
4445  /*
4446  * We are in a non-aborted subtransaction. This is the only valid
4447  * case.
4448  */
4449  case TBLOCK_SUBINPROGRESS:
4450  break;
4451 
4452  /* These cases are invalid. */
4453  case TBLOCK_DEFAULT:
4454  case TBLOCK_STARTED:
4455  case TBLOCK_BEGIN:
4457  case TBLOCK_SUBBEGIN:
4458  case TBLOCK_END:
4459  case TBLOCK_SUBRELEASE:
4460  case TBLOCK_SUBCOMMIT:
4461  case TBLOCK_ABORT:
4462  case TBLOCK_SUBABORT:
4463  case TBLOCK_ABORT_END:
4464  case TBLOCK_SUBABORT_END:
4465  case TBLOCK_ABORT_PENDING:
4467  case TBLOCK_SUBRESTART:
4469  case TBLOCK_PREPARE:
4470  elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4472  break;
4473  }
4474 
4475  for (target = s; PointerIsValid(target); target = target->parent)
4476  {
4477  if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4478  break;
4479  }
4480 
4481  if (!PointerIsValid(target))
4482  ereport(ERROR,
4483  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4484  errmsg("savepoint \"%s\" does not exist", name)));
4485 
4486  /* disallow crossing savepoint level boundaries */
4487  if (target->savepointLevel != s->savepointLevel)
4488  ereport(ERROR,
4489  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4490  errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4491 
4492  /*
4493  * Mark "commit pending" all subtransactions up to the target
4494  * subtransaction. The actual commits will happen when control gets to
4495  * CommitTransactionCommand.
4496  */
4497  xact = CurrentTransactionState;
4498  for (;;)
4499  {
4501  xact->blockState = TBLOCK_SUBRELEASE;
4502  if (xact == target)
4503  break;
4504  xact = xact->parent;
4505  Assert(PointerIsValid(xact));
4506  }
4507 }
4508 
4509 /*
4510  * RollbackToSavepoint
4511  * This executes a ROLLBACK TO <savepoint> command.
4512  *
4513  * As above, we don't actually do anything here except change blockState.
4514  */
4515 void
4517 {
4519  TransactionState target,
4520  xact;
4521 
4522  /*
4523  * Workers synchronize transaction state at the beginning of each parallel
4524  * operation, so we can't account for transaction state change after that
4525  * point. (Note that this check will certainly error out if s->blockState
4526  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4527  * below.)
4528  */
4530  ereport(ERROR,
4531  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4532  errmsg("cannot rollback to savepoints during a parallel operation")));
4533 
4534  switch (s->blockState)
4535  {
4536  /*
4537  * We can't rollback to a savepoint if there is no savepoint
4538  * defined.
4539  */
4540  case TBLOCK_INPROGRESS:
4541  case TBLOCK_ABORT:
4542  ereport(ERROR,
4543  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4544  errmsg("savepoint \"%s\" does not exist", name)));
4545  break;
4546 
4548  /* See comment about implicit transactions in DefineSavepoint */
4549  ereport(ERROR,
4550  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4551  /* translator: %s represents an SQL statement name */
4552  errmsg("%s can only be used in transaction blocks",
4553  "ROLLBACK TO SAVEPOINT")));
4554  break;
4555 
4556  /*
4557  * There is at least one savepoint, so proceed.
4558  */
4559  case TBLOCK_SUBINPROGRESS:
4560  case TBLOCK_SUBABORT:
4561  break;
4562 
4563  /* These cases are invalid. */
4564  case TBLOCK_DEFAULT:
4565  case TBLOCK_STARTED:
4566  case TBLOCK_BEGIN:
4568  case TBLOCK_SUBBEGIN:
4569  case TBLOCK_END:
4570  case TBLOCK_SUBRELEASE:
4571  case TBLOCK_SUBCOMMIT:
4572  case TBLOCK_ABORT_END:
4573  case TBLOCK_SUBABORT_END:
4574  case TBLOCK_ABORT_PENDING:
4576  case TBLOCK_SUBRESTART:
4578  case TBLOCK_PREPARE:
4579  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4581  break;
4582  }
4583 
4584  for (target = s; PointerIsValid(target); target = target->parent)
4585  {
4586  if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4587  break;
4588  }
4589 
4590  if (!PointerIsValid(target))
4591  ereport(ERROR,
4592  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4593  errmsg("savepoint \"%s\" does not exist", name)));
4594 
4595  /* disallow crossing savepoint level boundaries */
4596  if (target->savepointLevel != s->savepointLevel)
4597  ereport(ERROR,
4598  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4599  errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4600 
4601  /*
4602  * Mark "abort pending" all subtransactions up to the target
4603  * subtransaction. The actual aborts will happen when control gets to
4604  * CommitTransactionCommand.
4605  */
4606  xact = CurrentTransactionState;
4607  for (;;)
4608  {
4609  if (xact == target)
4610  break;
4611  if (xact->blockState == TBLOCK_SUBINPROGRESS)
4613  else if (xact->blockState == TBLOCK_SUBABORT)
4615  else
4616  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4618  xact = xact->parent;
4619  Assert(PointerIsValid(xact));
4620  }
4621 
4622  /* And mark the target as "restart pending" */
4623  if (xact->blockState == TBLOCK_SUBINPROGRESS)
4624  xact->blockState = TBLOCK_SUBRESTART;
4625  else if (xact->blockState == TBLOCK_SUBABORT)
4627  else
4628  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4630 }
4631 
4632 /*
4633  * BeginInternalSubTransaction
4634  * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
4635  * TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_END,
4636  * and TBLOCK_PREPARE states, and therefore it can safely be used in
4637  * functions that might be called when not inside a BEGIN block or when
4638  * running deferred triggers at COMMIT/PREPARE time. Also, it
4639  * automatically does CommitTransactionCommand/StartTransactionCommand
4640  * instead of expecting the caller to do it.
4641  */
4642 void
4644 {
4646  bool save_ExitOnAnyError = ExitOnAnyError;
4647 
4648  /*
4649  * Errors within this function are improbable, but if one does happen we
4650  * force a FATAL exit. Callers generally aren't prepared to handle losing
4651  * control, and moreover our transaction state is probably corrupted if we
4652  * fail partway through; so an ordinary ERROR longjmp isn't okay.
4653  */
4654  ExitOnAnyError = true;
4655 
4656  /*
4657  * We do not check for parallel mode here. It's permissible to start and
4658  * end "internal" subtransactions while in parallel mode, so long as no
4659  * new XIDs or command IDs are assigned. Enforcement of that occurs in
4660  * AssignTransactionId() and CommandCounterIncrement().
4661  */
4662 
4663  switch (s->blockState)
4664  {
4665  case TBLOCK_STARTED:
4666  case TBLOCK_INPROGRESS:
4669  case TBLOCK_END:
4670  case TBLOCK_PREPARE:
4671  case TBLOCK_SUBINPROGRESS:
4672  /* Normal subtransaction start */
4673  PushTransaction();
4674  s = CurrentTransactionState; /* changed by push */
4675 
4676  /*
4677  * Savepoint names, like the TransactionState block itself, live
4678  * in TopTransactionContext.
4679  */
4680  if (name)
4682  break;
4683 
4684  /* These cases are invalid. */
4685  case TBLOCK_DEFAULT:
4686  case TBLOCK_BEGIN:
4687  case TBLOCK_SUBBEGIN:
4688  case TBLOCK_SUBRELEASE:
4689  case TBLOCK_SUBCOMMIT:
4690  case TBLOCK_ABORT:
4691  case TBLOCK_SUBABORT:
4692  case TBLOCK_ABORT_END:
4693  case TBLOCK_SUBABORT_END:
4694  case TBLOCK_ABORT_PENDING:
4696  case TBLOCK_SUBRESTART:
4698  elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4700  break;
4701  }
4702 
4705 
4706  ExitOnAnyError = save_ExitOnAnyError;
4707 }
4708 
4709 /*
4710  * ReleaseCurrentSubTransaction
4711  *
4712  * RELEASE (ie, commit) the innermost subtransaction, regardless of its
4713  * savepoint name (if any).
4714  * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4715  */
4716 void
4718 {
4720 
4721  /*
4722  * We do not check for parallel mode here. It's permissible to start and
4723  * end "internal" subtransactions while in parallel mode, so long as no
4724  * new XIDs or command IDs are assigned.
4725  */
4726 
4727  if (s->blockState != TBLOCK_SUBINPROGRESS)
4728  elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4730  Assert(s->state == TRANS_INPROGRESS);
4733  s = CurrentTransactionState; /* changed by pop */
4734  Assert(s->state == TRANS_INPROGRESS);
4735 }
4736 
4737 /*
4738  * RollbackAndReleaseCurrentSubTransaction
4739  *
4740  * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
4741  * of its savepoint name (if any).
4742  * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4743  */
4744 void
4746 {
4748 
4749  /*
4750  * We do not check for parallel mode here. It's permissible to start and
4751  * end "internal" subtransactions while in parallel mode, so long as no
4752  * new XIDs or command IDs are assigned.
4753  */
4754 
4755  switch (s->blockState)
4756  {
4757  /* Must be in a subtransaction */
4758  case TBLOCK_SUBINPROGRESS:
4759  case TBLOCK_SUBABORT:
4760  break;
4761 
4762  /* These cases are invalid. */
4763  case TBLOCK_DEFAULT:
4764  case TBLOCK_STARTED:
4765  case TBLOCK_BEGIN:
4768  case TBLOCK_SUBBEGIN:
4769  case TBLOCK_INPROGRESS:
4770  case TBLOCK_END:
4771  case TBLOCK_SUBRELEASE:
4772  case TBLOCK_SUBCOMMIT:
4773  case TBLOCK_ABORT:
4774  case TBLOCK_ABORT_END:
4775  case TBLOCK_SUBABORT_END:
4776  case TBLOCK_ABORT_PENDING:
4778  case TBLOCK_SUBRESTART:
4780  case TBLOCK_PREPARE:
4781  elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4783  break;
4784  }
4785 
4786  /*
4787  * Abort the current subtransaction, if needed.
4788  */
4789  if (s->blockState == TBLOCK_SUBINPROGRESS)
4791 
4792  /* And clean it up, too */
4794 
4795  s = CurrentTransactionState; /* changed by pop */
4797  s->blockState == TBLOCK_INPROGRESS ||
4800  s->blockState == TBLOCK_STARTED);
4801 }
4802 
4803 /*
4804  * AbortOutOfAnyTransaction
4805  *
4806  * This routine is provided for error recovery purposes. It aborts any
4807  * active transaction or transaction block, leaving the system in a known
4808  * idle state.
4809  */
4810 void
4812 {
4814 
4815  /* Ensure we're not running in a doomed memory context */
4816  AtAbort_Memory();
4817 
4818  /*
4819  * Get out of any transaction or nested transaction
4820  */
4821  do
4822  {
4823  switch (s->blockState)
4824  {
4825  case TBLOCK_DEFAULT:
4826  if (s->state == TRANS_DEFAULT)
4827  {
4828  /* Not in a transaction, do nothing */
4829  }
4830  else
4831  {
4832  /*
4833  * We can get here after an error during transaction start
4834  * (state will be TRANS_START). Need to clean up the
4835  * incompletely started transaction. First, adjust the
4836  * low-level state to suppress warning message from
4837  * AbortTransaction.
4838  */
4839  if (s->state == TRANS_START)
4840  s->state = TRANS_INPROGRESS;
4841  AbortTransaction();
4843  }
4844  break;
4845  case TBLOCK_STARTED:
4846  case TBLOCK_BEGIN:
4847  case TBLOCK_INPROGRESS:
4850  case TBLOCK_END:
4851  case TBLOCK_ABORT_PENDING:
4852  case TBLOCK_PREPARE:
4853  /* In a transaction, so clean up */
4854  AbortTransaction();
4857  break;
4858  case TBLOCK_ABORT:
4859  case TBLOCK_ABORT_END:
4860 
4861  /*
4862  * AbortTransaction is already done, still need Cleanup.
4863  * However, if we failed partway through running ROLLBACK,
4864  * there will be an active portal running that command, which
4865  * we need to shut down before doing CleanupTransaction.
4866  */
4867  AtAbort_Portals();
4870  break;
4871 
4872  /*
4873  * In a subtransaction, so clean it up and abort parent too
4874  */
4875  case TBLOCK_SUBBEGIN:
4876  case TBLOCK_SUBINPROGRESS:
4877  case TBLOCK_SUBRELEASE:
4878  case TBLOCK_SUBCOMMIT:
4880  case TBLOCK_SUBRESTART:
4883  s = CurrentTransactionState; /* changed by pop */
4884  break;
4885 
4886  case TBLOCK_SUBABORT:
4887  case TBLOCK_SUBABORT_END:
4889  /* As above, but AbortSubTransaction already done */
4890  if (s->curTransactionOwner)
4891  {
4892  /* As in TBLOCK_ABORT, might have a live portal to zap */
4897  }
4899  s = CurrentTransactionState; /* changed by pop */
4900  break;
4901  }
4902  } while (s->blockState != TBLOCK_DEFAULT);
4903 
4904  /* Should be out of all subxacts now */
4905  Assert(s->parent == NULL);
4906 
4907  /* If we didn't actually have anything to do, revert to TopMemoryContext */
4908  AtCleanup_Memory();
4909 }
4910 
4911 /*
4912  * IsTransactionBlock --- are we within a transaction block?
4913  */
4914 bool
4916 {
4918 
4920  return false;
4921 
4922  return true;
4923 }
4924 
4925 /*
4926  * IsTransactionOrTransactionBlock --- are we within either a transaction
4927  * or a transaction block? (The backend is only really "idle" when this
4928  * returns false.)
4929  *
4930  * This should match up with IsTransactionBlock and IsTransactionState.
4931  */
4932 bool
4934 {
4936 
4937  if (s->blockState == TBLOCK_DEFAULT)
4938  return false;
4939 
4940  return true;
4941 }
4942 
4943 /*
4944  * TransactionBlockStatusCode - return status code to send in ReadyForQuery
4945  */
4946 char
4948 {
4950 
4951  switch (s->blockState)
4952  {
4953  case TBLOCK_DEFAULT:
4954  case TBLOCK_STARTED:
4955  return 'I'; /* idle --- not in transaction */
4956  case TBLOCK_BEGIN:
4957  case TBLOCK_SUBBEGIN:
4958  case TBLOCK_INPROGRESS:
4961  case TBLOCK_SUBINPROGRESS:
4962  case TBLOCK_END:
4963  case TBLOCK_SUBRELEASE:
4964  case TBLOCK_SUBCOMMIT:
4965  case TBLOCK_PREPARE:
4966  return 'T'; /* in transaction */
4967  case TBLOCK_ABORT:
4968  case TBLOCK_SUBABORT:
4969  case TBLOCK_ABORT_END:
4970  case TBLOCK_SUBABORT_END:
4971  case TBLOCK_ABORT_PENDING:
4973  case TBLOCK_SUBRESTART:
4975  return 'E'; /* in failed transaction */
4976  }
4977 
4978  /* should never get here */
4979  elog(FATAL, "invalid transaction block state: %s",
4981  return 0; /* keep compiler quiet */
4982 }
4983 
4984 /*
4985  * IsSubTransaction
4986  */
4987 bool
4989 {
4991 
4992  if (s->nestingLevel >= 2)
4993  return true;
4994 
4995  return false;
4996 }
4997 
4998 /*
4999  * StartSubTransaction
5000  *
5001  * If you're wondering why this is separate from PushTransaction: it's because
5002  * we can't conveniently do this stuff right inside DefineSavepoint. The
5003  * SAVEPOINT utility command will be executed inside a Portal, and if we
5004  * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
5005  * the Portal will undo those settings. So we make DefineSavepoint just
5006  * push a dummy transaction block, and when control returns to the main
5007  * idle loop, CommitTransactionCommand will be called, and we'll come here
5008  * to finish starting the subtransaction.
5009  */
5010 static void
5012 {
5014 
5015  if (s->state != TRANS_DEFAULT)
5016  elog(WARNING, "StartSubTransaction while in %s state",
5018 
5019  s->state = TRANS_START;
5020 
5021  /*
5022  * Initialize subsystems for new subtransaction
5023  *
5024  * must initialize resource-management stuff first
5025  */
5029 
5030  s->state = TRANS_INPROGRESS;
5031 
5032  /*
5033  * Call start-of-subxact callbacks
5034  */
5036  s->parent->subTransactionId);
5037 
5038  ShowTransactionState("StartSubTransaction");
5039 }
5040 
5041 /*
5042  * CommitSubTransaction
5043  *
5044  * The caller has to make sure to always reassign CurrentTransactionState
5045  * if it has a local pointer to it after calling this function.
5046  */
5047 static void
5049 {
5051 
5052  ShowTransactionState("CommitSubTransaction");
5053 
5054  if (s->state != TRANS_INPROGRESS)
5055  elog(WARNING, "CommitSubTransaction while in %s state",
5057 
5058  /* Pre-commit processing goes here */
5059 
5061  s->parent->subTransactionId);
5062 
5063  /*
5064  * If this subxact has started any unfinished parallel operation, clean up
5065  * its workers and exit parallel mode. Warn about leaked resources.
5066  */
5068  if (s->parallelModeLevel != 0)
5069  {
5070  elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5071  s->parallelModeLevel);
5072  s->parallelModeLevel = 0;
5073  }
5074 
5075  /* Do the actual "commit", such as it is */
5076  s->state = TRANS_COMMIT;
5077 
5078  /* Must CCI to ensure commands of subtransaction are seen as done */
5080 
5081  /*
5082  * Prior to 8.4 we marked subcommit in clog at this point. We now only
5083  * perform that step, if required, as part of the atomic update of the
5084  * whole transaction tree at top level commit or abort.
5085  */
5086 
5087  /* Post-commit cleanup */
5090  AfterTriggerEndSubXact(true);
5093  s->parent->nestingLevel,
5096  s->parent->subTransactionId);
5098 
5100  s->parent->subTransactionId);
5101 
5104  true, false);
5106  s->parent->subTransactionId);
5107  AtEOSubXact_Inval(true);
5108  AtSubCommit_smgr();
5109 
5110  /*
5111  * The only lock we actually release here is the subtransaction XID lock.
5112  */
5116 
5117  /*
5118  * Other locks should get transferred to their parent resource owner.
5119  */
5122  true, false);
5125  true, false);
5126 
5127  AtEOXact_GUC(true, s->gucNestLevel);
5130  s->parent->subTransactionId);
5132  s->parent->subTransactionId);
5134  s->parent->subTransactionId);
5136  AtEOSubXact_PgStat(true, s->nestingLevel);
5138 
5139  /*
5140  * We need to restore the upper transaction's read-only state, in case the
5141  * upper is read-write while the child is read-only; GUC will incorrectly
5142  * think it should leave the child state in place.
5143  */
5145 
5149  s->curTransactionOwner = NULL;
5150 
5152 
5153  s->state = TRANS_DEFAULT;
5154 
5155  PopTransaction();
5156 }
5157 
5158 /*
5159  * AbortSubTransaction
5160  */
5161 static void
5163 {
5165 
5166  /* Prevent cancel/die interrupt while cleaning up */
5167  HOLD_INTERRUPTS();
5168 
5169  /* Make sure we have a valid memory context and resource owner */
5172 
5173  /*
5174  * Release any LW locks we might be holding as quickly as possible.
5175  * (Regular locks, however, must be held till we finish aborting.)
5176  * Releasing LW locks is critical since we might try to grab them again
5177  * while cleaning up!
5178  *
5179  * FIXME This may be incorrect --- Are there some locks we should keep?
5180  * Buffer locks, for example? I don't think so but I'm not sure.
5181  */
5182  LWLockReleaseAll();
5183 
5186  UnlockBuffers();
5187 
5188  /* Reset WAL record construction state */
5190 
5191  /* Cancel condition variable sleep */
5193 
5194  /*
5195  * Also clean up any open wait for lock, since the lock manager will choke
5196  * if we try to wait for another lock before doing this.
5197  */
5198  LockErrorCleanup();
5199 
5200  /*
5201  * If any timeout events are still active, make sure the timeout interrupt
5202  * is scheduled. This covers possible loss of a timeout interrupt due to
5203  * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5204  * We delay this till after LockErrorCleanup so that we don't uselessly
5205  * reschedule lock or deadlock check timeouts.
5206  */
5208 
5209  /*
5210  * Re-enable signals, in case we got here by longjmp'ing out of a signal
5211  * handler. We do this fairly early in the sequence so that the timeout
5212  * infrastructure will be functional if needed while aborting.
5213  */
5214  sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
5215 
5216  /*
5217  * check the current transaction state
5218  */
5219  ShowTransactionState("AbortSubTransaction");
5220 
5221  if (s->state != TRANS_INPROGRESS)
5222  elog(WARNING, "AbortSubTransaction while in %s state",
5224 
5225  s->state = TRANS_ABORT;
5226 
5227  /*
5228  * Reset user ID which might have been changed transiently. (See notes in
5229  * AbortTransaction.)
5230  */
5232 
5233  /* Forget about any active REINDEX. */
5235 
5236  /* Reset logical streaming state. */
5238 
5239  /*
5240  * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5241  * exports are not supported in subtransactions.
5242  */
5243 
5244  /*
5245  * If this subxact has started any unfinished parallel operation, clean up
5246  * its workers and exit parallel mode. Don't warn about leaked resources.
5247  */
5249  s->parallelModeLevel = 0;
5250 
5251  /*
5252  * We can skip all this stuff if the subxact failed before creating a
5253  * ResourceOwner...
5254  */
5255  if (s->curTransactionOwner)
5256  {
5257  AfterTriggerEndSubXact(false);
5263  s->parent->subTransactionId);
5265 
5266  /* Advertise the fact that we aborted in pg_xact. */
5267  (void) RecordTransactionAbort(true);
5268 
5269  /* Post-abort cleanup */
5272 
5274  s->parent->subTransactionId);
5275 
5278  false, false);
5279 
5281  s->parent->subTransactionId);
5282 
5283 
5284  /*
5285  * AtEOSubXact_Inval sometimes needs to temporarily bump the refcount
5286  * on the relcache entries that it processes. We cannot use the
5287  * subtransaction's resource owner anymore, because we've already
5288  * started releasing it. But we can use the parent resource owner.
5289  */
5291 
5292  AtEOSubXact_Inval(false);
5293 
5295 
5298  false, false);
5301  false, false);
5302  AtSubAbort_smgr();
5303 
5304  AtEOXact_GUC(false, s->gucNestLevel);
5305  AtEOSubXact_SPI(false, s->subTransactionId);
5307  s->parent->subTransactionId);
5309  s->parent->subTransactionId);
5311  s->parent->subTransactionId);
5313  AtEOSubXact_PgStat(false, s->nestingLevel);
5315  }
5316 
5317  /*
5318  * Restore the upper transaction's read-only state, too. This should be
5319  * redundant with GUC's cleanup but we may as well do it for consistency
5320  * with the commit case.
5321  */
5323 
5325 }
5326 
5327 /*
5328  * CleanupSubTransaction
5329  *
5330  * The caller has to make sure to always reassign CurrentTransactionState
5331  * if it has a local pointer to it after calling this function.
5332  */
5333 static void
5335 {
5337 
5338  ShowTransactionState("CleanupSubTransaction");
5339 
5340  if (s->state != TRANS_ABORT)
5341  elog(WARNING, "CleanupSubTransaction while in %s state",
5343 
5345 
5348  if (s->curTransactionOwner)
5350  s->curTransactionOwner = NULL;
5351 
5353 
5354  s->state = TRANS_DEFAULT;
5355 
5356  PopTransaction();
5357 }
5358 
5359 /*
5360  * PushTransaction
5361  * Create transaction state stack entry for a subtransaction
5362  *
5363  * The caller has to make sure to always reassign CurrentTransactionState
5364  * if it has a local pointer to it after calling this function.
5365  */
5366 static void
5368 {
5370  TransactionState s;
5371 
5372  /*
5373  * We keep subtransaction state nodes in TopTransactionContext.
5374  */
5375  s = (TransactionState)
5377  sizeof(TransactionStateData));
5378 
5379  /*
5380  * Assign a subtransaction ID, watching out for counter wraparound.
5381  */
5384  {
5386  pfree(s);
5387  ereport(ERROR,
5388  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5389  errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5390  }
5391 
5392  /*
5393  * We can now stack a minimally valid subtransaction without fear of
5394  * failure.
5395  */
5396  s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5398  s->parent = p;
5399  s->nestingLevel = p->nestingLevel + 1;
5402  s->state = TRANS_DEFAULT;
5407  s->parallelModeLevel = 0;
5409  s->topXidLogged = false;
5410 
5412 
5413  /*
5414  * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5415  * with the subtransaction from here on out; in particular they should not
5416  * assume that it necessarily has a transaction context, resource owner,
5417  * or XID.
5418  */
5419 }
5420 
5421 /*
5422  * PopTransaction
5423  * Pop back to parent transaction state
5424  *
5425  * The caller has to make sure to always reassign CurrentTransactionState
5426  * if it has a local pointer to it after calling this function.
5427  */
5428 static void
5430 {
5432 
5433  if (s->state != TRANS_DEFAULT)
5434  elog(WARNING, "PopTransaction while in %s state",
5436 
5437  if (s->parent == NULL)
5438  elog(FATAL, "PopTransaction with no parent");
5439 
5441 
5442  /* Let's just make sure CurTransactionContext is good */
5445 
5446  /* Ditto for ResourceOwner links */
5449 
5450  /* Free the old child structure */
5451  if (s->name)
5452  pfree(s->name);
5453  pfree(s);
5454 }
5455 
5456 /*
5457  * EstimateTransactionStateSpace
5458  * Estimate the amount of space that will be needed by
5459  * SerializeTransactionState. It would be OK to overestimate slightly,
5460  * but it's simple for us to work out the precise value, so we do.
5461  */
5462 Size
5464 {
5465  TransactionState s;
5466  Size nxids = 0;
5468 
5469  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5470  {
5472  nxids = add_size(nxids, 1);
5473  nxids = add_size(nxids, s->nChildXids);
5474  }
5475 
5476  return add_size(size, mul_size(sizeof(TransactionId), nxids));
5477 }
5478 
5479 /*
5480  * SerializeTransactionState
5481  * Write out relevant details of our transaction state that will be
5482  * needed by a parallel worker.
5483  *
5484  * We need to save and restore XactDeferrable, XactIsoLevel, and the XIDs
5485  * associated with this transaction. These are serialized into a
5486  * caller-supplied buffer big enough to hold the number of bytes reported by
5487  * EstimateTransactionStateSpace(). We emit the XIDs in sorted order for the
5488  * convenience of the receiving process.
5489  */
5490 void
5491 SerializeTransactionState(Size maxsize, char *start_address)
5492 {
5493  TransactionState s;
5494  Size nxids = 0;
5495  Size i = 0;
5496  TransactionId *workspace;
5498 
5499  result = (SerializedTransactionState *) start_address;
5500 
5501  result->xactIsoLevel = XactIsoLevel;
5502  result->xactDeferrable = XactDeferrable;
5504  result->currentFullTransactionId =
5507 
5508  /*
5509  * If we're running in a parallel worker and launching a parallel worker
5510  * of our own, we can just pass along the information that was passed to
5511  * us.
5512  */
5513  if (nParallelCurrentXids > 0)
5514  {
5516  memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
5518  return;
5519  }
5520 
5521  /*
5522  * OK, we need to generate a sorted list of XIDs that our workers should
5523  * view as current. First, figure out how many there are.
5524  */
5525  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5526  {
5528  nxids = add_size(nxids, 1);
5529  nxids = add_size(nxids, s->nChildXids);
5530  }
5532  <= maxsize);
5533 
5534  /* Copy them to our scratch space. */
5535  workspace = palloc(nxids * sizeof(TransactionId));
5536  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5537  {
5539  workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5540  if (s->nChildXids > 0)
5541  memcpy(&workspace[i], s->childXids,
5542  s->nChildXids * sizeof(TransactionId));
5543  i += s->nChildXids;
5544  }
5545  Assert(i == nxids);
5546 
5547  /* Sort them. */
5548  qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5549 
5550  /* Copy data into output area. */
5551  result->nParallelCurrentXids = nxids;
5552  memcpy(&result->parallelCurrentXids[0], workspace,
5553  nxids * sizeof(TransactionId));
5554 }
5555 
5556 /*
5557  * StartParallelWorkerTransaction
5558  * Start a parallel worker transaction, restoring the relevant
5559  * transaction state serialized by SerializeTransactionState.
5560  */
5561 void
5563 {
5565 
5567  StartTransaction();
5568 
5569  tstate = (SerializedTransactionState *) tstatespace;
5570  XactIsoLevel = tstate->xactIsoLevel;
5571  XactDeferrable = tstate->xactDeferrable;
5574  tstate->currentFullTransactionId;
5578 
5580 }
5581 
5582 /*
5583  * EndParallelWorkerTransaction
5584  * End a parallel worker transaction.
5585  */
5586 void
5588 {
5592 }
5593 
5594 /*
5595  * ShowTransactionState
5596  * Debug support
5597  */
5598 static void
5600 {
5601  /* skip work if message will definitely not be printed */
5604 }
5605 
5606 /*
5607  * ShowTransactionStateRec
5608  * Recursive subroutine for ShowTransactionState
5609  */
5610 static void
5612 {
5614 
5615  if (s->parent)
5616  {
5617  /*
5618  * Since this function recurses, it could be driven to stack overflow.
5619  * This is just a debugging aid, so we can leave out some details
5620  * instead of erroring out with check_stack_depth().
5621  */
5622  if (stack_is_too_deep())
5623  ereport(DEBUG5,
5624  (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5625  str, s->nestingLevel)));
5626  else
5628  }
5629 
5630  initStringInfo(&buf);
5631  if (s->nChildXids > 0)
5632  {
5633  int i;
5634 
5635  appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5636  for (i = 1; i < s->nChildXids; i++)
5637  appendStringInfo(&buf, " %u", s->childXids[i]);
5638  }
5639  ereport(DEBUG5,
5640  (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5641  str, s->nestingLevel,
5642  PointerIsValid(s->name) ? s->name : "unnamed",
5645  (unsigned int) XidFromFullTransactionId(s->fullTransactionId),
5646  (unsigned int) s->subTransactionId,
5647  (unsigned int) currentCommandId,
5648  currentCommandIdUsed ? " (used)" : "",
5649  buf.data)));
5650  pfree(buf.data);
5651 }
5652 
5653 /*
5654  * BlockStateAsString
5655  * Debug support
5656  */
5657 static const char *
5659 {
5660  switch (blockState)
5661  {
5662  case TBLOCK_DEFAULT:
5663  return "DEFAULT";
5664  case TBLOCK_STARTED:
5665  return "STARTED";
5666  case TBLOCK_BEGIN:
5667  return "BEGIN";
5668  case TBLOCK_INPROGRESS:
5669  return "INPROGRESS";
5671  return "IMPLICIT_INPROGRESS";
5673  return "PARALLEL_INPROGRESS";
5674  case TBLOCK_END:
5675  return "END";
5676  case TBLOCK_ABORT:
5677  return "ABORT";
5678  case TBLOCK_ABORT_END:
5679  return "ABORT_END";
5680  case TBLOCK_ABORT_PENDING:
5681  return "ABORT_PENDING";
5682  case TBLOCK_PREPARE:
5683  return "PREPARE";
5684  case TBLOCK_SUBBEGIN:
5685  return "SUBBEGIN";
5686  case TBLOCK_SUBINPROGRESS:
5687  return "SUBINPROGRESS";
5688  case TBLOCK_SUBRELEASE:
5689  return "SUBRELEASE";
5690  case TBLOCK_SUBCOMMIT:
5691  return "SUBCOMMIT";
5692  case TBLOCK_SUBABORT:
5693  return "SUBABORT";
5694  case TBLOCK_SUBABORT_END:
5695  return "SUBABORT_END";
5697  return "SUBABORT_PENDING";
5698  case TBLOCK_SUBRESTART:
5699  return "SUBRESTART";
5701  return "SUBABORT_RESTART";
5702  }
5703  return "UNRECOGNIZED";
5704 }
5705 
5706 /*
5707  * TransStateAsString
5708  * Debug support
5709  */
5710 static const char *
5712 {
5713  switch (state)
5714  {
5715  case TRANS_DEFAULT:
5716  return "DEFAULT";
5717  case TRANS_START:
5718  return "START";
5719  case TRANS_INPROGRESS:
5720  return "INPROGRESS";
5721  case TRANS_COMMIT:
5722  return "COMMIT";
5723  case TRANS_ABORT:
5724  return "ABORT";
5725  case TRANS_PREPARE:
5726  return "PREPARE";
5727  }
5728  return "UNRECOGNIZED";
5729 }
5730 
5731 /*
5732  * xactGetCommittedChildren
5733  *
5734  * Gets the list of committed children of the current transaction. The return
5735  * value is the number of child transactions. *ptr is set to point to an
5736  * array of TransactionIds. The array is allocated in TopTransactionContext;
5737  * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
5738  * If there are no subxacts, *ptr is set to NULL.
5739  */
5740 int
5742 {
5744 
5745  if (s->nChildXids == 0)
5746  *ptr = NULL;
5747  else
5748  *ptr = s->childXids;
5749 
5750  return s->nChildXids;
5751 }
5752 
5753 /*
5754  * XLOG support routines
5755  */
5756 
5757 
5758 /*
5759  * Log the commit record for a plain or twophase transaction commit.
5760  *
5761  * A 2pc commit will be emitted when twophase_xid is valid, a plain one
5762  * otherwise.
5763  */
5764 XLogRecPtr
5766  int nsubxacts, TransactionId *subxacts,
5767  int nrels, RelFileLocator *rels,
5768  int ndroppedstats, xl_xact_stats_item *droppedstats,
5769  int nmsgs, SharedInvalidationMessage *msgs,
5770  bool relcacheInval,
5771  int xactflags, TransactionId twophase_xid,
5772  const char *twophase_gid)
5773 {
5774  xl_xact_commit xlrec;
5775  xl_xact_xinfo xl_xinfo;
5776  xl_xact_dbinfo xl_dbinfo;
5777  xl_xact_subxacts xl_subxacts;
5778  xl_xact_relfilelocators xl_relfilelocators;
5779  xl_xact_stats_items xl_dropped_stats;
5780  xl_xact_invals xl_invals;
5781  xl_xact_twophase xl_twophase;
5782  xl_xact_origin xl_origin;
5783  uint8 info;
5784 
5785  Assert(CritSectionCount > 0);
5786 
5787  xl_xinfo.xinfo = 0;
5788 
5789  /* decide between a plain and 2pc commit */
5790  if (!TransactionIdIsValid(twophase_xid))
5791  info = XLOG_XACT_COMMIT;
5792  else
5794 
5795  /* First figure out and collect all the information needed */
5796 
5797  xlrec.xact_time = commit_time;
5798 
5799  if (relcacheInval)
5801  if (forceSyncCommit)
5803  if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5804  xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5805 
5806  /*
5807  * Check if the caller would like to ask standbys for immediate feedback
5808  * once this commit is applied.
5809  */
5812 
5813  /*
5814  * Relcache invalidations requires information about the current database
5815  * and so does logical decoding.
5816  */
5817  if (nmsgs > 0 || XLogLogicalInfoActive())
5818  {
5819  xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5820  xl_dbinfo.dbId = MyDatabaseId;
5821  xl_dbinfo.tsId = MyDatabaseTableSpace;
5822  }
5823 
5824  if (nsubxacts > 0)
5825  {
5826  xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5827  xl_subxacts.nsubxacts = nsubxacts;
5828  }
5829 
5830  if (nrels > 0)
5831  {
5833  xl_relfilelocators.nrels = nrels;
5834  info |= XLR_SPECIAL_REL_UPDATE;
5835  }
5836 
5837  if (ndroppedstats > 0)
5838  {
5839  xl_xinfo.xinfo |= XACT_XINFO_HAS_DROPPED_STATS;
5840  xl_dropped_stats.nitems = ndroppedstats;
5841  }
5842 
5843  if (nmsgs > 0)
5844  {
5845  xl_xinfo.xinfo |= XACT_XINFO_HAS_INVALS;
5846  xl_invals.nmsgs = nmsgs;
5847  }
5848 
5849  if (TransactionIdIsValid(twophase_xid))
5850  {
5851  xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5852  xl_twophase.xid = twophase_xid;
5853  Assert(twophase_gid != NULL);
5854 
5855  if (XLogLogicalInfoActive())
5856  xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
5857  }
5858 
5859  /* dump transaction origin information */
5861  {
5862  xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
5863 
5866  }
5867 
5868  if (xl_xinfo.xinfo != 0)
5869  info |= XLOG_XACT_HAS_INFO;
5870 
5871  /* Then include all the collected data into the commit record. */
5872 
5873  XLogBeginInsert();
5874 
5875  XLogRegisterData((char *) (&xlrec), sizeof(xl_xact_commit));
5876 
5877  if (xl_xinfo.xinfo != 0)
5878  XLogRegisterData((char *) (&xl_xinfo.xinfo), sizeof(xl_xinfo.xinfo));
5879 
5880  if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5881  XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
5882 
5883  if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5884  {
5885  XLogRegisterData((char *) (&xl_subxacts),
5887  XLogRegisterData((char *) subxacts,
5888  nsubxacts * sizeof(TransactionId));
5889  }
5890 
5891  if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILELOCATORS)
5892  {
5893  XLogRegisterData((char *) (&xl_relfilelocators),
5895  XLogRegisterData((char *) rels,
5896  nrels * sizeof(RelFileLocator));
5897  }
5898 
5899  if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
5900  {
5901  XLogRegisterData((char *) (&xl_dropped_stats),
5903  XLogRegisterData((char *) droppedstats,
5904  ndroppedstats * sizeof(xl_xact_stats_item));
5905  }
5906 
5907  if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
5908  {
5909  XLogRegisterData((char *) (&xl_invals), MinSizeOfXactInvals);
5910  XLogRegisterData((char *) msgs,
5911  nmsgs * sizeof(SharedInvalidationMessage));
5912  }
5913 
5914  if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5915  {
5916  XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
5917  if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
5918  XLogRegisterData(unconstify(char *, twophase_gid), strlen(twophase_gid) + 1);
5919  }
5920 
5921  if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5922  XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
5923 
5924  /* we allow filtering by xacts */
5926 
5927  return XLogInsert(RM_XACT_ID, info);
5928 }
5929 
5930 /*
5931  * Log the commit record for a plain or twophase transaction abort.
5932  *
5933  * A 2pc abort will be emitted when twophase_xid is valid, a plain one
5934  * otherwise.
5935  */
5936 XLogRecPtr
5938  int nsubxacts, TransactionId *subxacts,
5939  int nrels, RelFileLocator *rels,
5940  int ndroppedstats, xl_xact_stats_item *droppedstats,
5941  int xactflags, TransactionId twophase_xid,
5942  const char *twophase_gid)
5943 {
5944  xl_xact_abort xlrec;
5945  xl_xact_xinfo xl_xinfo;
5946  xl_xact_subxacts xl_subxacts;
5947  xl_xact_relfilelocators xl_relfilelocators;
5948  xl_xact_stats_items xl_dropped_stats;
5949  xl_xact_twophase xl_twophase;
5950  xl_xact_dbinfo xl_dbinfo;
5951  xl_xact_origin xl_origin;
5952 
5953  uint8 info;
5954 
5955  Assert(CritSectionCount > 0);
5956 
5957  xl_xinfo.xinfo = 0;
5958 
5959  /* decide between a plain and 2pc abort */
5960  if (!TransactionIdIsValid(twophase_xid))
5961  info = XLOG_XACT_ABORT;
5962  else
5963  info = XLOG_XACT_ABORT_PREPARED;
5964 
5965 
5966  /* First figure out and collect all the information needed */
5967 
5968  xlrec.xact_time = abort_time;
5969 
5970  if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5971  xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5972 
5973  if (nsubxacts > 0)
5974  {
5975  xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5976  xl_subxacts.nsubxacts = nsubxacts;
5977  }
5978 
5979  if (nrels > 0)
5980  {
5982  xl_relfilelocators.nrels = nrels;
5983  info |= XLR_SPECIAL_REL_UPDATE;
5984  }
5985 
5986  if (ndroppedstats > 0)
5987  {
5988  xl_xinfo.xinfo |= XACT_XINFO_HAS_DROPPED_STATS;
5989  xl_dropped_stats.nitems = ndroppedstats;
5990  }
5991 
5992  if (TransactionIdIsValid(twophase_xid))
5993  {
5994  xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5995  xl_twophase.xid = twophase_xid;
5996  Assert(twophase_gid != NULL);
5997 
5998  if (XLogLogicalInfoActive())
5999  xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
6000  }
6001 
6002  if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6003  {
6004  xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
6005  xl_dbinfo.dbId = MyDatabaseId;
6006  xl_dbinfo.tsId = MyDatabaseTableSpace;
6007  }
6008 
6009  /*
6010  * Dump transaction origin information. We need this during recovery to
6011  * update the replication origin progress.
6012  */
6014  {
6015  xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
6016 
6019  }
6020 
6021  if (xl_xinfo.xinfo != 0)
6022  info |= XLOG_XACT_HAS_INFO;
6023 
6024  /* Then include all the collected data into the abort record. */
6025 
6026  XLogBeginInsert();
6027 
6028  XLogRegisterData((char *) (&xlrec), MinSizeOfXactAbort);
6029 
6030  if (xl_xinfo.xinfo != 0)
6031  XLogRegisterData((char *) (&xl_xinfo), sizeof(xl_xinfo));
6032 
6033  if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6034  XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
6035 
6036  if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
6037  {
6038  XLogRegisterData((char *) (&xl_subxacts),
6040  XLogRegisterData((char *) subxacts,
6041  nsubxacts * sizeof(TransactionId));
6042  }
6043 
6044  if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILELOCATORS)
6045  {
6046  XLogRegisterData((char *) (&xl_relfilelocators),
6048  XLogRegisterData((char *) rels,
6049  nrels * sizeof(RelFileLocator));
6050  }
6051 
6052  if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
6053  {
6054  XLogRegisterData((char *) (&xl_dropped_stats),
6056  XLogRegisterData((char *) droppedstats,
6057  ndroppedstats * sizeof(xl_xact_stats_item));
6058  }
6059 
6060  if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
6061  {
6062  XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
6063  if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6064  XLogRegisterData(unconstify(char *, twophase_gid), strlen(twophase_gid) + 1);
6065  }
6066 
6067  if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6068  XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
6069 
6070  /* Include the replication origin */
6072 
6073  return XLogInsert(RM_XACT_ID, info);
6074 }
6075 
6076 /*
6077  * Before 9.0 this was a fairly short function, but now it performs many
6078  * actions for which the order of execution is critical.
6079  */
6080 static void
6082  TransactionId xid,
6083  XLogRecPtr lsn,
6084  RepOriginId origin_id)
6085 {
6086  TransactionId max_xid;
6087  TimestampTz commit_time;
6088 
6090 
6091  max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
6092 
6093  /* Make sure nextXid is beyond any XID mentioned in the record. */
6095 
6096  Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) ==
6097  (origin_id == InvalidRepOriginId));
6098 
6099  if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6100  commit_time = parsed->origin_timestamp;
6101  else
6102  commit_time = parsed->xact_time;
6103 
6104  /* Set the transaction commit timestamp and metadata */
6105  TransactionTreeSetCommitTsData(xid, parsed->nsubxacts, parsed->subxacts,
6106  commit_time, origin_id);
6107 
6109  {
6110  /*
6111  * Mark the transaction committed in pg_xact.
6112  */
6113  TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
6114  }
6115  else
6116  {
6117  /*
6118  * If a transaction completion record arrives that has as-yet
6119  * unobserved subtransactions then this will not have been fully
6120  * handled by the call to RecordKnownAssignedTransactionIds() in the
6121  * main recovery loop in xlog.c. So we need to do bookkeeping again to
6122  * cover that case. This is confusing and it is easy to think this
6123  * call is irrelevant, which has happened three times in development
6124  * already. Leave it in.
6125  */
6127 
6128  /*
6129  * Mark the transaction committed in pg_xact. We use async commit
6130  * protocol during recovery to provide information on database
6131  * consistency for when users try to set hint bits. It is important
6132  * that we do not set hint bits until the minRecoveryPoint is past
6133  * this commit record. This ensures that if we crash we don't see hint
6134  * bits set on changes made by transactions that haven't yet
6135  * recovered. It's unlikely but it's good to be safe.
6136  */
6137  TransactionIdAsyncCommitTree(xid, parsed->nsubxacts, parsed->subxacts, lsn);
6138 
6139  /*
6140  * We must mark clog before we update the ProcArray.
6141  */
6142  ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6143 
6144  /*
6145  * Send any cache invalidations attached to the commit. We must
6146  * maintain the same order of invalidation then release locks as
6147  * occurs in CommitTransaction().
6148  */
6151  parsed->dbId, parsed->tsId);
6152 
6153  /*
6154  * Release locks, if any. We do this for both two phase and normal one
6155  * phase transactions. In effect we are ignoring the prepare phase and
6156  * just going straight to lock release.
6157  */
6158  if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6159  StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6160  }
6161 
6162  if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6163  {
6164  /* recover apply progress */
6165  replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6166  false /* backward */ , false /* WAL */ );
6167  }
6168 
6169  /* Make sure files supposed to be dropped are dropped */
6170  if (parsed->nrels > 0)
6171  {
6172  /*
6173  * First update minimum recovery point to cover this WAL record. Once
6174  * a relation is deleted, there's no going back. The buffer manager
6175  * enforces the WAL-first rule for normal updates to relation files,
6176  * so that the minimum recovery point is always updated before the
6177  * corresponding change in the data file is flushed to disk, but we
6178  * have to do the same here since we're bypassing the buffer manager.
6179  *
6180  * Doing this before deleting the files means that if a deletion fails
6181  * for some reason, you cannot start up the system even after restart,
6182  * until you fix the underlying situation so that the deletion will
6183  * succeed. Alternatively, we could update the minimum recovery point
6184  * after deletion, but that would leave a small window where the
6185  * WAL-first rule would be violated.
6186  */
6187  XLogFlush(lsn);
6188 
6189  /* Make sure files supposed to be dropped are dropped */
6190  DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6191  }
6192 
6193  if (parsed->nstats > 0)
6194  {
6195  /* see equivalent call for relations above */
6196  XLogFlush(lsn);
6197 
6198  pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6199  }
6200 
6201  /*
6202  * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
6203  * in normal operation. For example, in CREATE DATABASE, we copy all files
6204  * from the template database, and then commit the transaction. If we
6205  * crash after all the files have been copied but before the commit, you
6206  * have files in the data directory without an entry in pg_database. To
6207  * minimize the window for that, we use ForceSyncCommit() to rush the
6208  * commit record to disk as quick as possible. We have the same window
6209  * during recovery, and forcing an XLogFlush() (which updates
6210  * minRecoveryPoint during recovery) helps to reduce that problem window,
6211  * for any user that requested ForceSyncCommit().
6212  */
6213  if (XactCompletionForceSyncCommit(parsed->xinfo))
6214  XLogFlush(lsn);
6215 
6216  /*
6217  * If asked by the primary (because someone is waiting for a synchronous
6218  * commit = remote_apply), we will need to ask walreceiver to send a reply
6219  * immediately.
6220  */
6221  if (XactCompletionApplyFeedback(parsed->xinfo))
6223 }
6224 
6225 /*
6226  * Be careful with the order of execution, as with xact_redo_commit().
6227  * The two functions are similar but differ in key places.
6228  *
6229  * Note also that an abort can be for a subtransaction and its children,
6230  * not just for a top level abort. That means we have to consider
6231  * topxid != xid, whereas in commit we would find topxid == xid always
6232  * because subtransaction commit is never WAL logged.
6233  */
6234 static void
6236  XLogRecPtr lsn, RepOriginId origin_id)
6237 {
6238  TransactionId max_xid;
6239 
6241 
6242  /* Make sure nextXid is beyond any XID mentioned in the record. */
6243  max_xid = TransactionIdLatest(xid,
6244  parsed->nsubxacts,
6245  parsed->subxacts);
6247 
6249  {
6250  /* Mark the transaction aborted in pg_xact, no need for async stuff */
6251  TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6252  }
6253  else
6254  {
6255  /*
6256  * If a transaction completion record arrives that has as-yet
6257  * unobserved subtransactions then this will not have been fully
6258  * handled by the call to RecordKnownAssignedTransactionIds() in the
6259  * main recovery loop in xlog.c. So we need to do bookkeeping again to
6260  * cover that case. This is confusing and it is easy to think this
6261  * call is irrelevant, which has happened three times in development
6262  * already. Leave it in.
6263  */
6265 
6266  /* Mark the transaction aborted in pg_xact, no need for async stuff */
6267  TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6268 
6269  /*
6270  * We must update the ProcArray after we have marked clog.
6271  */
6272  ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6273 
6274  /*
6275  * There are no invalidation messages to send or undo.
6276  */
6277 
6278  /*
6279  * Release locks, if any. There are no invalidations to send.
6280  */
6281  if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6282  StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6283  }
6284 
6285  if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6286  {
6287  /* recover apply progress */
6288  replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6289  false /* backward */ , false /* WAL */ );
6290  }
6291 
6292  /* Make sure files supposed to be dropped are dropped */
6293  if (parsed->nrels > 0)
6294  {
6295  /*
6296  * See comments about update of minimum recovery point on truncation,
6297  * in xact_redo_commit().
6298  */
6299  XLogFlush(lsn);
6300 
6301  DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6302  }
6303 
6304  if (parsed->nstats > 0)
6305  {
6306  /* see equivalent call for relations above */
6307  XLogFlush(lsn);
6308 
6309  pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6310  }
6311 }
6312 
6313 void
6315 {
6316  uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6317 
6318  /* Backup blocks are not used in xact records */
6319  Assert(!XLogRecHasAnyBlockRefs(record));
6320 
6321  if (info == XLOG_XACT_COMMIT)
6322  {
6323  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6324  xl_xact_parsed_commit parsed;
6325 
6326  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6327  xact_redo_commit(&parsed, XLogRecGetXid(record),
6328  record->EndRecPtr, XLogRecGetOrigin(record));
6329  }
6330  else if (info == XLOG_XACT_COMMIT_PREPARED)
6331  {
6332  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6333  xl_xact_parsed_commit parsed;
6334 
6335  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6336  xact_redo_commit(&parsed, parsed.twophase_xid,
6337  record->EndRecPtr, XLogRecGetOrigin(record));
6338 
6339  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6340  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6341  PrepareRedoRemove(parsed.twophase_xid, false);
6342  LWLockRelease(TwoPhaseStateLock);
6343  }
6344  else if (info == XLOG_XACT_ABORT)
6345  {
6346  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6347  xl_xact_parsed_abort parsed;
6348 
6349  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6350  xact_redo_abort(&parsed, XLogRecGetXid(record),
6351  record->EndRecPtr, XLogRecGetOrigin(record));
6352  }
6353  else if (info == XLOG_XACT_ABORT_PREPARED)
6354  {
6355  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6356  xl_xact_parsed_abort parsed;
6357 
6358  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6359  xact_redo_abort(&parsed, parsed.twophase_xid,
6360  record->EndRecPtr, XLogRecGetOrigin(record));
6361 
6362  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6363  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6364  PrepareRedoRemove(parsed.twophase_xid, false);
6365  LWLockRelease(TwoPhaseStateLock);
6366  }
6367  else if (info == XLOG_XACT_PREPARE)
6368  {
6369  /*
6370  * Store xid and start/end pointers of the WAL record in TwoPhaseState
6371  * gxact entry.
6372  */
6373  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6375  record->ReadRecPtr,
6376  record->EndRecPtr,
6377  XLogRecGetOrigin(record));
6378  LWLockRelease(TwoPhaseStateLock);
6379  }
6380  else if (info == XLOG_XACT_ASSIGNMENT)
6381  {
6383 
6386  xlrec->nsubxacts, xlrec->xsub);
6387  }
6388  else if (info == XLOG_XACT_INVALIDATIONS)
6389  {
6390  /*
6391  * XXX we do ignore this for now, what matters are invalidations
6392  * written into the commit record.
6393  */
6394  }
6395  else
6396  elog(PANIC, "xact_redo: unknown op code %u", info);
6397 }
void AtCommit_Notify(void)
Definition: async.c:968
void AtAbort_Notify(void)
Definition: async.c:1671
void PreCommit_Notify(void)
Definition: async.c:861
void AtSubAbort_Notify(void)
Definition: async.c:1761
void AtPrepare_Notify(void)
Definition: async.c:836
void AtSubCommit_Notify(void)
Definition: async.c:1691
void ParallelWorkerReportLastRecEnd(XLogRecPtr last_xlog_end)
Definition: parallel.c:1539
bool ParallelContextActive(void)
Definition: parallel.c:1003
void AtEOSubXact_Parallel(bool isCommit, SubTransactionId mySubId)
Definition: parallel.c:1233
void AtEOXact_Parallel(bool isCommit)
Definition: parallel.c:1254
sigset_t UnBlockSig
Definition: pqsignal.c:22
void AtEOXact_LogicalRepWorkers(bool isCommit)
Definition: worker.c:5003
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1654
void pgstat_progress_end_command(void)
void pgstat_report_xact_timestamp(TimestampTz tstamp)
void AtEOXact_LargeObject(bool isCommit)
Definition: be-fsstubs.c:602
void AtEOSubXact_LargeObject(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: be-fsstubs.c:648
static int32 next
Definition: blutils.c:221
static void cleanup(void)
Definition: bootstrap.c:682
void AtEOXact_Buffers(bool isCommit)
Definition: bufmgr.c:3502
void UnlockBuffers(void)
Definition: bufmgr.c:5057
#define InvalidCommandId
Definition: c.h:669
#define TopSubTransactionId
Definition: c.h:659
#define unconstify(underlying_type, expr)
Definition: c.h:1245
#define Min(x, y)
Definition: c.h:1004
uint32 SubTransactionId
Definition: c.h:656
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:182
#define InvalidSubTransactionId
Definition: c.h:658
#define Assert(condition)
Definition: c.h:858
#define PointerIsValid(pointer)
Definition: c.h:763
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:398
#define FirstCommandId
Definition: c.h:668
uint32 LocalTransactionId
Definition: c.h:654
unsigned char uint8
Definition: c.h:504
uint32 CommandId
Definition: c.h:666
uint32 TransactionId
Definition: c.h:652
size_t Size
Definition: c.h:605
void AtEOXact_ComboCid(void)
Definition: combocid.c:182
void TransactionTreeSetCommitTsData(TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz timestamp, RepOriginId nodeid)
Definition: commit_ts.c:141
bool ConditionVariableCancelSleep(void)
int64 TimestampTz
Definition: timestamp.h:39
void AtEOXact_HashTables(bool isCommit)
Definition: dynahash.c:1869
void AtEOSubXact_HashTables(bool isCommit, int nestDepth)
Definition: dynahash.c:1895
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1159
bool message_level_is_interesting(int elevel)
Definition: elog.c:276
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#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:224
#define ereport(elevel,...)
Definition: elog.h:149
#define DEBUG5
Definition: elog.h:26
void AtEOXact_Files(bool isCommit)
Definition: fd.c:3165
void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: fd.c:3132
ProcNumber MyProcNumber
Definition: globals.c:87
Oid MyDatabaseTableSpace
Definition: globals.c:93
volatile uint32 CritSectionCount
Definition: globals.c:43
bool ExitOnAnyError
Definition: globals.c:120
Oid MyDatabaseId
Definition: globals.c:91
int NewGUCNestLevel(void)
Definition: guc.c:2237
void AtStart_GUC(void)
Definition: guc.c:2217
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:2264
double log_xact_sample_rate
Definition: guc_tables.c:532
const char * str
#define IsParallelWorker()
Definition: parallel.h:60
void ResetReindexState(int nestLevel)
Definition: index.c:4149
void PostPrepare_Inval(void)
Definition: inval.c:863
void LogLogicalInvalidations(void)
Definition: inval.c:1604
void AcceptInvalidationMessages(void)
Definition: inval.c:806
int xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs, bool *RelcacheInitFileInval)
Definition: inval.c:882
void AtEOXact_Inval(bool isCommit)
Definition: inval.c:1025
void AtEOSubXact_Inval(bool isCommit)
Definition: inval.c:1082
void CommandEndInvalidationMessages(void)
Definition: inval.c:1170
void ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs, int nmsgs, bool RelcacheInitFileInval, Oid dbid, Oid tsid)
Definition: inval.c:961
int i
Definition: isn.c:73
void AtEOXact_ApplyLauncher(bool isCommit)
Definition: launcher.c:1086
void XactLockTableDelete(TransactionId xid)
Definition: lmgr.c:643
void XactLockTableInsert(TransactionId xid)
Definition: lmgr.c:626
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
Definition: lock.c:4405
void AtPrepare_Locks(void)
Definition: lock.c:3272
void PostPrepare_Locks(TransactionId xid)
Definition: lock.c:3368
#define InvalidLocalTransactionId
Definition: lock.h:65
void ResetLogicalStreamingState(void)
Definition: logical.c:1921
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1170
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1783
void LWLockReleaseAll(void)
Definition: lwlock.c:1878
@ LW_EXCLUSIVE
Definition: lwlock.h:114
bool MemoryContextIsEmpty(MemoryContext context)
Definition: mcxt.c:743
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:383
MemoryContext TopTransactionContext
Definition: mcxt.c:154
void pfree(void *pointer)
Definition: mcxt.c:1520
MemoryContext TopMemoryContext
Definition: mcxt.c:149
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1214
MemoryContext CurTransactionContext
Definition: mcxt.c:155
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1540
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1180
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1682
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454
void * palloc(Size size)
Definition: mcxt.c:1316
void DropRelationFiles(RelFileLocator *delrels, int ndelrels, bool isRedo)
Definition: md.c:1446
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160
#define MaxAllocSize
Definition: memutils.h:40
#define RESUME_INTERRUPTS()
Definition: miscadmin.h:135
#define START_CRIT_SECTION()
Definition: miscadmin.h:149
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:133
#define END_CRIT_SECTION()
Definition: miscadmin.h:151
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition: miscinit.c:635
Oid GetUserId(void)
Definition: miscinit.c:514
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition: miscinit.c:642
void AtPrepare_MultiXact(void)
Definition: multixact.c:1787
void PostPrepare_MultiXact(TransactionId xid)
Definition: multixact.c:1801
void AtEOXact_MultiXact(void)
Definition: multixact.c:1759
void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: namespace.c:4543
void AtEOXact_Namespace(bool isCommit, bool parallel)
Definition: namespace.c:4497
TimestampTz replorigin_session_origin_timestamp
Definition: origin.c:157
void replorigin_session_advance(XLogRecPtr remote_commit, XLogRecPtr local_commit)
Definition: origin.c:1219
RepOriginId replorigin_session_origin
Definition: origin.c:155
void replorigin_advance(RepOriginId node, XLogRecPtr remote_commit, XLogRecPtr local_commit, bool go_backward, bool wal_log)
Definition: origin.c:888
XLogRecPtr replorigin_session_origin_lsn
Definition: origin.c:156
#define DoNotReplicateId
Definition: origin.h:34
#define InvalidRepOriginId
Definition: origin.h:33
void * arg
void AtEOXact_Enum(void)
Definition: pg_enum.c:726
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:73
void AtPrepare_PgStat(void)
Definition: pgstat_xact.c:189
void pgstat_execute_transactional_drops(int ndrops, struct xl_xact_stats_item *items, bool is_redo)
Definition: pgstat_xact.c:312
void AtEOXact_PgStat(bool isCommit, bool parallel)
Definition: pgstat_xact.c:40
void PostPrepare_PgStat(void)
Definition: pgstat_xact.c:209
int pgstat_get_transactional_drops(bool isCommit, xl_xact_stats_item **items)
Definition: pgstat_xact.c:270
void AtEOSubXact_PgStat(bool isCommit, int nestDepth)
Definition: pgstat_xact.c:112
#define qsort(a, b, c, d)
Definition: port.h:449
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
bool stack_is_too_deep(void)
Definition: postgres.c:3545
unsigned int Oid
Definition: postgres_ext.h:31
void PreCommit_CheckForSerializationFailure(void)
Definition: predicate.c:4688
void AtPrepare_PredicateLocks(void)
Definition: predicate.c:4775
void RegisterPredicateLockingXid(TransactionId xid)
Definition: predicate.c:1944
void PostPrepare_PredicateLocks(TransactionId xid)
Definition: predicate.c:4844
#define PGPROC_MAX_CACHED_SUBXIDS
Definition: proc.h:39
#define DELAY_CHKPT_START
Definition: proc.h:114
void XidCacheRemoveRunningXids(TransactionId xid, int nxids, const TransactionId *xids, TransactionId latestXid)
Definition: procarray.c:3975
void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
Definition: procarray.c:667
void RecordKnownAssignedTransactionIds(TransactionId xid)
Definition: procarray.c:4387
void ProcArrayClearTransaction(PGPROC *proc)
Definition: procarray.c:907
void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)
Definition: procarray.c:1306
void ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids, TransactionId *subxids, TransactionId max_xid)
Definition: procarray.c:4456
MemoryContextSwitchTo(old_ctx)
void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: relcache.c:3346
void AtEOXact_RelationCache(bool isCommit)
Definition: relcache.c:3194
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:167
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition: resowner.c:413
ResourceOwner CurrentResourceOwner
Definition: resowner.c:165
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition: resowner.c:648
void ResourceOwnerDelete(ResourceOwner owner)
Definition: resowner.c:854
ResourceOwner CurTransactionResourceOwner
Definition: resowner.c:166
@ 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:493
Size mul_size(Size s1, Size s2)
Definition: shmem.c:510
LocalTransactionId GetNextLocalTransactionId(void)
Definition: sinvaladt.c:701
static pg_noinline void Size size
Definition: slab.c:607
void AtEOXact_SMgr(void)
Definition: smgr.c:807
void SnapBuildResetExportedSnapshotState(void)
Definition: snapbuild.c:756
void AtSubAbort_Snapshot(int level)
Definition: snapmgr.c:959
void AtEOXact_Snapshot(bool isCommit, bool resetXmin)
Definition: snapmgr.c:995
void AtSubCommit_Snapshot(int level)
Definition: snapmgr.c:938
bool XactHasExportedSnapshots(void)
Definition: snapmgr.c:1554
void SnapshotSetCommandId(CommandId curcid)
Definition: snapmgr.c:456
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:66
int TransactionTimeout
Definition: proc.c:61
void LockErrorCleanup(void)
Definition: proc.c:730
void StandbyReleaseLockTree(TransactionId xid, int nsubxids, TransactionId *subxids)
Definition: standby.c:1091
void LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInitFileInval)
Definition: standby.c:1462
void AtSubCommit_smgr(void)
Definition: storage.c:914
void AtSubAbort_smgr(void)
Definition: storage.c:934
int smgrGetPendingDeletes(bool forCommit, RelFileLocator **ptr)
Definition: storage.c:852
void PostPrepare_smgr(void)
Definition: storage.c:893
void smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
Definition: storage.c:700
void smgrDoPendingDeletes(bool isCommit)
Definition: storage.c:632
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
LocalTransactionId lxid
Definition: proc.h:196
ProcNumber procNumber
Definition: proc.h:191
int delayChkptFlags
Definition: proc.h:236
struct PGPROC::@117 vxid
FullTransactionId currentFullTransactionId
Definition: xact.c:229
FullTransactionId topFullTransactionId
Definition: xact.c:228
CommandId currentCommandId
Definition: xact.c:230
TransactionId parallelCurrentXids[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.c:232
struct SubXactCallbackItem * next
Definition: xact.c:319
SubXactCallback callback
Definition: xact.c:320
TransState state
Definition: xact.c:197
int parallelModeLevel
Definition: xact.c:211
SubTransactionId subTransactionId
Definition: xact.c:194
FullTransactionId fullTransactionId
Definition: xact.c:193
struct TransactionStateData * parent
Definition: xact.c:215
bool parallelChildXact
Definition: xact.c:212
MemoryContext curTransactionContext
Definition: xact.c:201
TBlockState blockState
Definition: xact.c:198
bool prevXactReadOnly
Definition: xact.c:208
TransactionId * childXids
Definition: xact.c:203
bool startedInRecovery
Definition: xact.c:209
ResourceOwner curTransactionOwner
Definition: xact.c:202
LocalTransactionId localTransactionId
Definition: lock.h:62
ProcNumber procNumber
Definition: lock.h:61
XLogRecPtr EndRecPtr
Definition: xlogreader.h:207
XLogRecPtr ReadRecPtr
Definition: xlogreader.h:206
struct XactCallbackItem * next
Definition: xact.c:307
void * arg
Definition: xact.c:309
XactCallback callback
Definition: xact.c:308
Definition: regguts.h:323
TimestampTz xact_time
Definition: xact.h:332
TransactionId xtop
Definition: xact.h:220
TransactionId xsub[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:222
TimestampTz xact_time
Definition: xact.h:316
Oid tsId
Definition: xact.h:258
Oid dbId
Definition: xact.h:257
int nmsgs
Definition: xact.h:298
TimestampTz origin_timestamp
Definition: xact.h:311
XLogRecPtr origin_lsn
Definition: xact.h:310
xl_xact_stats_item * stats
Definition: xact.h:419
RelFileLocator * xlocators
Definition: xact.h:416
TransactionId twophase_xid
Definition: xact.h:421
TransactionId * subxacts
Definition: xact.h:413
XLogRecPtr origin_lsn
Definition: xact.h:424
xl_xact_stats_item * stats
Definition: xact.h:386
TimestampTz xact_time
Definition: xact.h:373
TransactionId twophase_xid
Definition: xact.h:391
RelFileLocator * xlocators
Definition: xact.h:383
TimestampTz origin_timestamp
Definition: xact.h:399
TransactionId * subxacts
Definition: xact.h:380
XLogRecPtr origin_lsn
Definition: xact.h:398
SharedInvalidationMessage * msgs
Definition: xact.h:389
int nsubxacts
Definition: xact.h:263
TransactionId xid
Definition: xact.h:305
uint32 xinfo
Definition: xact.h:252
void SubTransSetParent(TransactionId xid, TransactionId parent)
Definition: subtrans.c:85
void SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
Definition: syncrep.c:148
void AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: tablecmds.c:18379
void PreCommit_on_commit_actions(void)
Definition: tablecmds.c:18240
void AtEOXact_on_commit_actions(bool isCommit)
Definition: tablecmds.c:18347
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:345
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
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:280
static TransactionId ReadNextTransactionId(void)
Definition: transam.h:315
#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
void AfterTriggerBeginXact(void)
Definition: trigger.c:4986
void AfterTriggerEndSubXact(bool isCommit)
Definition: trigger.c:5349
void AfterTriggerFireDeferred(void)
Definition: trigger.c:5197
void AfterTriggerEndXact(bool isCommit)
Definition: trigger.c:5253
void AfterTriggerBeginSubXact(void)
Definition: trigger.c:5301
void AtAbort_Twophase(void)
Definition: twophase.c:304
void PrepareRedoRemove(TransactionId xid, bool giveWarning)
Definition: twophase.c:2582
void EndPrepare(GlobalTransaction gxact)
Definition: twophase.c:1158
void StartPrepare(GlobalTransaction gxact)
Definition: twophase.c:1065
void PrepareRedoAdd(char *buf, XLogRecPtr start_lsn, XLogRecPtr end_lsn, RepOriginId origin_id)
Definition: twophase.c:2480
void PostPrepare_Twophase(void)
Definition: twophase.c:344
GlobalTransaction MarkAsPreparing(TransactionId xid, const char *gid, TimestampTz prepared_at, Oid owner, Oid databaseid)
Definition: twophase.c:359
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:104
const char * name
static bool CommitTransactionCommandInternal(void)
Definition: xact.c:3111
bool IsTransactionOrTransactionBlock(void)
Definition: xact.c:4933
struct SerializedTransactionState SerializedTransactionState
void SerializeTransactionState(Size maxsize, char *start_address)
Definition: xact.c:5491
void ExitParallelMode(void)
Definition: xact.c:1061
static TimestampTz xactStartTimestamp
Definition: xact.c:277
static bool currentCommandIdUsed
Definition: xact.c:265
static void AtSubCommit_Memory(void)
Definition: xact.c:1604
void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
Definition: xact.c:3072
static void CleanupSubTransaction(void)
Definition: xact.c:5334
void BeginInternalSubTransaction(const char *name)
Definition: xact.c:4643
static void AtStart_Memory(void)
Definition: xact.c:1173
FullTransactionId GetCurrentFullTransactionId(void)
Definition: xact.c:509
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition: xact.c:3080
static XactCallbackItem * Xact_callbacks
Definition: xact.c:312
void WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
Definition: xact.c:3656
static TimestampTz stmtStartTimestamp
Definition: xact.c:278
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:788
int synchronous_commit
Definition: xact.c:85
void UserAbortTransactionBlock(bool chain)
Definition: xact.c:4153
bool IsInTransactionBlock(bool isTopLevel)
Definition: xact.c:3715
bool PrepareTransactionBlock(const char *gid)
Definition: xact.c:3941
static void AtSubCleanup_Memory(void)
Definition: xact.c:1979
static void StartTransaction(void)
Definition: xact.c:2014
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:926
void xact_redo(XLogReaderState *record)
Definition: xact.c:6314
TransactionId GetTopTransactionId(void)
Definition: xact.c:423
static void AtSubCommit_childXids(void)
Definition: xact.c:1633
static void CallSubXactCallbacks(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: xact.c:3847
void EnterParallelMode(void)
Definition: xact.c:1048
static void AtAbort_ResourceOwner(void)
Definition: xact.c:1885
TransactionId GetStableLatestTransactionId(void)
Definition: xact.c:604
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3671
void UnregisterSubXactCallback(SubXactCallback callback, void *arg)
Definition: xact.c:3826
bool XactDeferrable
Definition: xact.c:83
static bool forceSyncCommit
Definition: xact.c:290
void BeginImplicitTransactionBlock(void)
Definition: xact.c:4275
static void CallXactCallbacks(XactEvent event)
Definition: xact.c:3787
static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS]
Definition: xact.c:255
static void xact_redo_commit(xl_xact_parsed_commit *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:6081
void RequireTransactionBlock(bool isTopLevel, const char *stmtType)
Definition: xact.c:3662
static void AtSubAbort_Memory(void)
Definition: xact.c:1873
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:324
void DefineSavepoint(const char *name)
Definition: xact.c:4322
bool DefaultXactDeferrable
Definition: xact.c:82
static void CleanupTransaction(void)
Definition: xact.c:2945
static int nUnreportedXids
Definition: xact.c:254
static const char * TransStateAsString(TransState state)
Definition: xact.c:5711
static TimestampTz xactStopTimestamp
Definition: xact.c:279
bool TransactionStartedDuringRecovery(void)
Definition: xact.c:1039
static void CommitSubTransaction(void)
Definition: xact.c:5048
bool XactReadOnly
Definition: xact.c:80
static void PushTransaction(void)
Definition: xact.c:5367
bool bsysscan
Definition: xact.c:98
TransactionId CheckXidAlive
Definition: xact.c:97
static TransactionId RecordTransactionCommit(void)
Definition: xact.c:1304
static char * prepareGID
Definition: xact.c:285
void UnregisterXactCallback(XactCallback callback, void *arg)
Definition: xact.c:3766
bool IsTransactionState(void)
Definition: xact.c:384
struct SubXactCallbackItem SubXactCallbackItem
static MemoryContext TransactionAbortContext
Definition: xact.c:300
void CommandCounterIncrement(void)
Definition: xact.c:1097
TransState
Definition: xact.c:140
@ TRANS_INPROGRESS
Definition: xact.c:143
@ TRANS_START
Definition: xact.c:142
@ TRANS_COMMIT
Definition: xact.c:144
@ TRANS_ABORT
Definition: xact.c:145
@ TRANS_DEFAULT
Definition: xact.c:141
@ TRANS_PREPARE
Definition: xact.c:146
void PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
Definition: xact.c:3584
static void AtCleanup_Memory(void)
Definition: xact.c:1943
Size EstimateTransactionStateSpace(void)
Definition: xact.c:5463
TransactionStateData * TransactionState
Definition: xact.c:218
static void AtSubAbort_childXids(void)
Definition: xact.c:1911
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:438
static bool AbortCurrentTransactionInternal(void)
Definition: xact.c:3405
struct XactCallbackItem XactCallbackItem
static SubTransactionId currentSubTransactionId
Definition: xact.c:263
static void AssignTransactionId(TransactionState s)
Definition: xact.c:632
static void xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:6235
char TransactionBlockStatusCode(void)
Definition: xact.c:4947
void RollbackAndReleaseCurrentSubTransaction(void)
Definition: xact.c:4745
static int nParallelCurrentXids
Definition: xact.c:124
FullTransactionId GetCurrentFullTransactionIdIfAny(void)
Definition: xact.c:527
static void CommitTransaction(void)
Definition: xact.c:2178
void StartTransactionCommand(void)
Definition: xact.c:2995
static void PopTransaction(void)
Definition: xact.c:5429
bool IsAbortedTransactionBlockState(void)
Definition: xact.c:404
void ReleaseCurrentSubTransaction(void)
Definition: xact.c:4717
void EndImplicitTransactionBlock(void)
Definition: xact.c:4300
void StartParallelWorkerTransaction(char *tstatespace)
Definition: xact.c:5562
void SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts)
Definition: xact.c:856
static void AtSubAbort_ResourceOwner(void)
Definition: xact.c:1898
void ReleaseSavepoint(const char *name)
Definition: xact.c:4407
static TransactionStateData TopTransactionStateData
Definition: xact.c:244
static FullTransactionId XactTopFullTransactionId
Definition: xact.c:123
static void ShowTransactionState(const char *str)
Definition: xact.c:5599
int XactIsoLevel
Definition: xact.c:77
static void PrepareTransaction(void)
Definition: xact.c:2460
FullTransactionId GetTopFullTransactionId(void)
Definition: xact.c:480
static CommandId currentCommandId
Definition: xact.c:264
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:5765
void ForceSyncCommit(void)
Definition: xact.c:1149
static TransactionId RecordTransactionAbort(bool isSubXact)
Definition: xact.c:1723
static void AtCommit_Memory(void)
Definition: xact.c:1577
static void AbortSubTransaction(void)
Definition: xact.c:5162
bool IsSubTransaction(void)
Definition: xact.c:4988
void MarkSubxactTopXidLogged(void)
Definition: xact.c:588
void SetCurrentStatementStartTimestamp(void)
Definition: xact.c:911
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:938
bool IsTransactionBlock(void)
Definition: xact.c:4915
bool IsInParallelMode(void)
Definition: xact.c:1086
int xactGetCommittedChildren(TransactionId **ptr)
Definition: xact.c:5741
struct TransactionStateData TransactionStateData
TransactionId GetCurrentTransactionIdIfAny(void)
Definition: xact.c:468
void BeginTransactionBlock(void)
Definition: xact.c:3873
static void AtStart_ResourceOwner(void)
Definition: xact.c:1220
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition: xact.c:876
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition: xact.c:867
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5658
void EndParallelWorkerTransaction(void)
Definition: xact.c:5587
static void AtAbort_Memory(void)
Definition: xact.c:1853
void RegisterXactCallback(XactCallback callback, void *arg)
Definition: xact.c:3753
void CommitTransactionCommand(void)
Definition: xact.c:3093
void RollbackToSavepoint(const char *name)
Definition: xact.c:4516
bool SubTransactionIsActive(SubTransactionId subxid)
Definition: xact.c:802
TBlockState
Definition: xact.c:156
@ TBLOCK_DEFAULT
Definition: xact.c:158
@ TBLOCK_SUBABORT_END
Definition: xact.c:178
@ TBLOCK_STARTED
Definition: xact.c:159
@ TBLOCK_SUBCOMMIT
Definition: xact.c:176
@ TBLOCK_IMPLICIT_INPROGRESS
Definition: xact.c:164
@ TBLOCK_ABORT_END
Definition: xact.c:168
@ TBLOCK_PREPARE
Definition: xact.c:170
@ TBLOCK_ABORT_PENDING
Definition: xact.c:169
@ TBLOCK_ABORT
Definition: xact.c:167
@ TBLOCK_SUBRELEASE
Definition: xact.c:175
@ TBLOCK_SUBBEGIN
Definition: xact.c:173
@ TBLOCK_SUBABORT
Definition: xact.c:177
@ TBLOCK_SUBRESTART
Definition: xact.c:180
@ TBLOCK_INPROGRESS
Definition: xact.c:163
@ TBLOCK_END
Definition: xact.c:166
@ TBLOCK_PARALLEL_INPROGRESS
Definition: xact.c:165
@ TBLOCK_SUBABORT_RESTART
Definition: xact.c:181
@ TBLOCK_SUBABORT_PENDING
Definition: xact.c:179
@ TBLOCK_BEGIN
Definition: xact.c:162
@ TBLOCK_SUBINPROGRESS
Definition: xact.c:174
void RegisterSubXactCallback(SubXactCallback callback, void *arg)
Definition: xact.c:3813
FullTransactionId GetTopFullTransactionIdIfAny(void)
Definition: xact.c:496
TransactionId GetCurrentTransactionId(void)
Definition: xact.c:451
static void AbortTransaction(void)
Definition: xact.c:2749
static void AtStart_Cache(void)
Definition: xact.c:1164
static void AtSubStart_ResourceOwner(void)
Definition: xact.c:1272
int DefaultXactIsoLevel
Definition: xact.c:76
static void AtSubStart_Memory(void)
Definition: xact.c:1248
bool xact_is_sampled
Definition: xact.c:293
bool EndTransactionBlock(bool chain)
Definition: xact.c:3993
bool IsSubxactTopXidLogPending(void)
Definition: xact.c:556
#define SerializedTransactionStateHeaderSize
Definition: xact.c:236
void AbortOutOfAnyTransaction(void)
Definition: xact.c:4811
int MyXactFlags
Definition: xact.c:134
static void ShowTransactionStateRec(const char *str, TransactionState s)
Definition: xact.c:5611
static TransactionState CurrentTransactionState
Definition: xact.c:257
void AbortCurrentTransaction(void)
Definition: xact.c:3387
static void StartSubTransaction(void)
Definition: xact.c:5011
static TransactionId * ParallelCurrentXids
Definition: xact.c:125
bool DefaultXactReadOnly
Definition: xact.c:79
TimestampTz GetCurrentTransactionStopTimestamp(void)
Definition: xact.c:888
static void AtCCI_LocalCache(void)
Definition: xact.c:1558
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:5937
void MarkCurrentTransactionIdLoggedIfAny(void)
Definition: xact.c:538
CommandId GetCurrentCommandId(bool used)
Definition: xact.c:826
#define XactCompletionForceSyncCommit(xinfo)
Definition: xact.h:215
#define MinSizeOfXactInvals
Definition: xact.h:301
void(* SubXactCallback)(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg)
Definition: xact.h:148
#define MinSizeOfXactSubxacts
Definition: xact.h:266
#define XLOG_XACT_COMMIT_PREPARED
Definition: xact.h:172
#define XLOG_XACT_INVALIDATIONS
Definition: xact.h:175
#define XACT_COMPLETION_UPDATE_RELCACHE_FILE
Definition: xact.h:207
SubXactEvent
Definition: xact.h:141
@ SUBXACT_EVENT_PRE_COMMIT_SUB
Definition: xact.h:145
@ SUBXACT_EVENT_START_SUB
Definition: xact.h:142
@ SUBXACT_EVENT_ABORT_SUB
Definition: xact.h:144
@ SUBXACT_EVENT_COMMIT_SUB
Definition: xact.h:143
void(* XactCallback)(XactEvent event, void *arg)
Definition: xact.h:138
#define XACT_XINFO_HAS_GID
Definition: xact.h:195
#define XACT_COMPLETION_FORCE_SYNC_COMMIT
Definition: xact.h:208
#define XACT_XINFO_HAS_ORIGIN
Definition: xact.h:193
@ SYNCHRONOUS_COMMIT_REMOTE_APPLY
Definition: xact.h:75
@ SYNCHRONOUS_COMMIT_OFF
Definition: xact.h:70
#define XLOG_XACT_PREPARE
Definition: xact.h:170
XactEvent
Definition: xact.h:127
@ XACT_EVENT_PRE_PREPARE
Definition: xact.h:135
@ XACT_EVENT_COMMIT
Definition: xact.h:128
@ XACT_EVENT_PARALLEL_PRE_COMMIT
Definition: xact.h:134
@ XACT_EVENT_PARALLEL_COMMIT
Definition: xact.h:129
@ XACT_EVENT_ABORT
Definition: xact.h:130
@ XACT_EVENT_PRE_COMMIT
Definition: xact.h:133
@ XACT_EVENT_PARALLEL_ABORT
Definition: xact.h:131
@ XACT_EVENT_PREPARE
Definition: xact.h:132
#define SYNCHRONOUS_COMMIT_ON
Definition: xact.h:80
#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK
Definition: xact.h:108
#define XACT_XINFO_HAS_TWOPHASE
Definition: xact.h:192
#define XLOG_XACT_COMMIT
Definition: xact.h:169
#define XLOG_XACT_OPMASK
Definition: xact.h:179
#define XACT_FLAGS_PIPELINING
Definition: xact.h:121
#define MinSizeOfXactRelfileLocators
Definition: xact.h:273
#define XLOG_XACT_ABORT
Definition: xact.h:171
#define MinSizeOfXactStatsItems
Definition: xact.h:294
#define XACT_XINFO_HAS_RELFILELOCATORS
Definition: xact.h:190
#define MinSizeOfXactAbort
Definition: xact.h:344
#define XACT_COMPLETION_APPLY_FEEDBACK
Definition: xact.h:206
#define MinSizeOfXactAssignment
Definition: xact.h:225
#define XACT_XINFO_HAS_DBINFO
Definition: xact.h:188
#define XACT_FLAGS_NEEDIMMEDIATECOMMIT
Definition: xact.h:114
#define XactCompletionApplyFeedback(xinfo)
Definition: xact.h:211
#define XLOG_XACT_ASSIGNMENT
Definition: xact.h:174
#define XACT_XINFO_HAS_INVALS
Definition: xact.h:191
#define XLOG_XACT_ABORT_PREPARED
Definition: xact.h:173
#define XACT_XINFO_HAS_AE_LOCKS
Definition: xact.h:194
#define XLOG_XACT_HAS_INFO
Definition: xact.h:182
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE
Definition: xact.h:102
#define XactCompletionRelcacheInitFileInval(xinfo)
Definition: xact.h:213
#define XACT_READ_COMMITTED
Definition: xact.h:37
#define XACT_XINFO_HAS_SUBXACTS
Definition: xact.h:189
#define XACT_XINFO_HAS_DROPPED_STATS
Definition: xact.h:196
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:139
bool RecoveryInProgress(void)
Definition: xlog.c:6290
XLogRecPtr XactLastRecEnd
Definition: xlog.c:254
XLogRecPtr XactLastCommitEnd
Definition: xlog.c:255
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2791
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition: xlog.c:2626
#define XLogLogicalInfoActive()
Definition: xlog.h:124
#define XLOG_INCLUDE_ORIGIN
Definition: xlog.h:152
#define XLogStandbyInfoActive()
Definition: xlog.h:121
uint16 RepOriginId
Definition: xlogdefs.h:65
uint64 XLogRecPtr
Definition: xlogdefs.h:21
void XLogRegisterData(char *data, uint32 len)
Definition: xloginsert.c:364
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:474
void XLogSetRecordFlags(uint8 flags)
Definition: xloginsert.c:456
void XLogResetInsertion(void)
Definition: xloginsert.c:222
void XLogBeginInsert(void)
Definition: xloginsert.c:149
#define XLogRecGetOrigin(decoder)
Definition: xlogreader.h:413
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:410
#define XLogRecGetData(decoder)
Definition: xlogreader.h:415
#define XLogRecGetXid(decoder)
Definition: xlogreader.h:412
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:417
#define XLR_SPECIAL_REL_UPDATE
Definition: xlogrecord.h:82
void XLogRequestWalReceiverReply(void)
HotStandbyState standbyState
Definition: xlogutils.c:53
@ STANDBY_DISABLED
Definition: xlogutils.h:49
@ STANDBY_INITIALIZED
Definition: xlogutils.h:50