PostgreSQL Source Code git master
Loading...
Searching...
No Matches
xact.c File Reference
#include "postgres.h"
#include <time.h>
#include <unistd.h>
#include "access/commit_ts.h"
#include "access/multixact.h"
#include "access/parallel.h"
#include "access/subtrans.h"
#include "access/transam.h"
#include "access/twophase.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "access/xlogrecovery.h"
#include "access/xlogutils.h"
#include "access/xlogwait.h"
#include "catalog/index.h"
#include "catalog/namespace.h"
#include "catalog/pg_enum.h"
#include "catalog/storage.h"
#include "commands/async.h"
#include "commands/tablecmds.h"
#include "commands/trigger.h"
#include "common/pg_prng.h"
#include "executor/spi.h"
#include "libpq/be-fsstubs.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pg_trace.h"
#include "pgstat.h"
#include "replication/logical.h"
#include "replication/logicallauncher.h"
#include "replication/logicalworker.h"
#include "replication/origin.h"
#include "replication/snapbuild.h"
#include "replication/syncrep.h"
#include "storage/aio_subsys.h"
#include "storage/condition_variable.h"
#include "storage/fd.h"
#include "storage/lmgr.h"
#include "storage/md.h"
#include "storage/predicate.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/sinvaladt.h"
#include "storage/smgr.h"
#include "utils/builtins.h"
#include "utils/combocid.h"
#include "utils/guc.h"
#include "utils/inval.h"
#include "utils/memutils.h"
#include "utils/relmapper.h"
#include "utils/snapmgr.h"
#include "utils/timeout.h"
#include "utils/timestamp.h"
#include "utils/typcache.h"
#include "utils/wait_event.h"
Include dependency graph for xact.c:

Go to the source code of this file.

Data Structures

struct  TransactionStateData
 
struct  SerializedTransactionState
 
struct  XactCallbackItem
 
struct  SubXactCallbackItem
 

Macros

#define SerializedTransactionStateHeaderSize    offsetof(SerializedTransactionState, parallelCurrentXids)
 

Typedefs

typedef enum TransState TransState
 
typedef enum TBlockState TBlockState
 
typedef struct TransactionStateData TransactionStateData
 
typedef TransactionStateDataTransactionState
 
typedef struct SerializedTransactionState SerializedTransactionState
 
typedef struct XactCallbackItem XactCallbackItem
 
typedef struct SubXactCallbackItem SubXactCallbackItem
 

Enumerations

enum  TransState {
  TRANS_DEFAULT , TRANS_START , TRANS_INPROGRESS , TRANS_COMMIT ,
  TRANS_ABORT , TRANS_PREPARE
}
 
enum  TBlockState {
  TBLOCK_DEFAULT , TBLOCK_STARTED , TBLOCK_BEGIN , TBLOCK_INPROGRESS ,
  TBLOCK_IMPLICIT_INPROGRESS , TBLOCK_PARALLEL_INPROGRESS , TBLOCK_END , TBLOCK_ABORT ,
  TBLOCK_ABORT_END , TBLOCK_ABORT_PENDING , TBLOCK_PREPARE , TBLOCK_SUBBEGIN ,
  TBLOCK_SUBINPROGRESS , TBLOCK_SUBRELEASE , TBLOCK_SUBCOMMIT , TBLOCK_SUBABORT ,
  TBLOCK_SUBABORT_END , TBLOCK_SUBABORT_PENDING , TBLOCK_SUBRESTART , TBLOCK_SUBABORT_RESTART
}
 

Functions

static void AssignTransactionId (TransactionState s)
 
static void AbortTransaction (void)
 
static void AtAbort_Memory (void)
 
static void AtCleanup_Memory (void)
 
static void AtAbort_ResourceOwner (void)
 
static void AtCCI_LocalCache (void)
 
static void AtCommit_Memory (void)
 
static void AtStart_Cache (void)
 
static void AtStart_Memory (void)
 
static void AtStart_ResourceOwner (void)
 
static void CallXactCallbacks (XactEvent event)
 
static void CallSubXactCallbacks (SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
 
static void CleanupTransaction (void)
 
static void CheckTransactionBlock (bool isTopLevel, bool throwError, const char *stmtType)
 
static void CommitTransaction (void)
 
static TransactionId RecordTransactionAbort (bool isSubXact)
 
static void StartTransaction (void)
 
static bool CommitTransactionCommandInternal (void)
 
static bool AbortCurrentTransactionInternal (void)
 
static void StartSubTransaction (void)
 
static void CommitSubTransaction (void)
 
static void AbortSubTransaction (void)
 
static void CleanupSubTransaction (void)
 
static void PushTransaction (void)
 
static void PopTransaction (void)
 
static void AtSubAbort_Memory (void)
 
static void AtSubCleanup_Memory (void)
 
static void AtSubAbort_ResourceOwner (void)
 
static void AtSubCommit_Memory (void)
 
static void AtSubStart_Memory (void)
 
static void AtSubStart_ResourceOwner (void)
 
static void ShowTransactionState (const char *str)
 
static void ShowTransactionStateRec (const char *str, TransactionState s)
 
static const charBlockStateAsString (TBlockState blockState)
 
static const charTransStateAsString (TransState state)
 
bool IsTransactionState (void)
 
bool IsAbortedTransactionBlockState (void)
 
TransactionId GetTopTransactionId (void)
 
TransactionId GetTopTransactionIdIfAny (void)
 
TransactionId GetCurrentTransactionId (void)
 
TransactionId GetCurrentTransactionIdIfAny (void)
 
FullTransactionId GetTopFullTransactionId (void)
 
FullTransactionId GetTopFullTransactionIdIfAny (void)
 
FullTransactionId GetCurrentFullTransactionId (void)
 
FullTransactionId GetCurrentFullTransactionIdIfAny (void)
 
void MarkCurrentTransactionIdLoggedIfAny (void)
 
bool IsSubxactTopXidLogPending (void)
 
void MarkSubxactTopXidLogged (void)
 
TransactionId GetStableLatestTransactionId (void)
 
SubTransactionId GetCurrentSubTransactionId (void)
 
bool SubTransactionIsActive (SubTransactionId subxid)
 
CommandId GetCurrentCommandId (bool used)
 
void SetParallelStartTimestamps (TimestampTz xact_ts, TimestampTz stmt_ts)
 
TimestampTz GetCurrentTransactionStartTimestamp (void)
 
TimestampTz GetCurrentStatementStartTimestamp (void)
 
TimestampTz GetCurrentTransactionStopTimestamp (void)
 
void SetCurrentStatementStartTimestamp (void)
 
int GetCurrentTransactionNestLevel (void)
 
bool TransactionIdIsCurrentTransactionId (TransactionId xid)
 
bool TransactionStartedDuringRecovery (void)
 
void EnterParallelMode (void)
 
void ExitParallelMode (void)
 
bool IsInParallelMode (void)
 
void CommandCounterIncrement (void)
 
void ForceSyncCommit (void)
 
static TransactionId RecordTransactionCommit (void)
 
static void AtSubCommit_childXids (void)
 
static void AtSubAbort_childXids (void)
 
static void PrepareTransaction (void)
 
void StartTransactionCommand (void)
 
void SaveTransactionCharacteristics (SavedTransactionCharacteristics *s)
 
void RestoreTransactionCharacteristics (const SavedTransactionCharacteristics *s)
 
void CommitTransactionCommand (void)
 
void AbortCurrentTransaction (void)
 
void PreventInTransactionBlock (bool isTopLevel, const char *stmtType)
 
void WarnNoTransactionBlock (bool isTopLevel, const char *stmtType)
 
void RequireTransactionBlock (bool isTopLevel, const char *stmtType)
 
bool IsInTransactionBlock (bool isTopLevel)
 
void RegisterXactCallback (XactCallback callback, void *arg)
 
void UnregisterXactCallback (XactCallback callback, void *arg)
 
void RegisterSubXactCallback (SubXactCallback callback, void *arg)
 
void UnregisterSubXactCallback (SubXactCallback callback, void *arg)
 
void BeginTransactionBlock (void)
 
bool PrepareTransactionBlock (const char *gid)
 
bool EndTransactionBlock (bool chain)
 
void UserAbortTransactionBlock (bool chain)
 
void BeginImplicitTransactionBlock (void)
 
void EndImplicitTransactionBlock (void)
 
void DefineSavepoint (const char *name)
 
void ReleaseSavepoint (const char *name)
 
void RollbackToSavepoint (const char *name)
 
void BeginInternalSubTransaction (const char *name)
 
void ReleaseCurrentSubTransaction (void)
 
void RollbackAndReleaseCurrentSubTransaction (void)
 
void AbortOutOfAnyTransaction (void)
 
bool IsTransactionBlock (void)
 
bool IsTransactionOrTransactionBlock (void)
 
char TransactionBlockStatusCode (void)
 
bool IsSubTransaction (void)
 
Size EstimateTransactionStateSpace (void)
 
void SerializeTransactionState (Size maxsize, char *start_address)
 
void StartParallelWorkerTransaction (char *tstatespace)
 
void EndParallelWorkerTransaction (void)
 
int xactGetCommittedChildren (TransactionId **ptr)
 
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)
 
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)
 
static void xact_redo_commit (xl_xact_parsed_commit *parsed, TransactionId xid, XLogRecPtr lsn, ReplOriginId origin_id)
 
static void xact_redo_abort (xl_xact_parsed_abort *parsed, TransactionId xid, XLogRecPtr lsn, ReplOriginId origin_id)
 
void xact_redo (XLogReaderState *record)
 

Variables

int DefaultXactIsoLevel = XACT_READ_COMMITTED
 
int XactIsoLevel = XACT_READ_COMMITTED
 
bool DefaultXactReadOnly = false
 
bool XactReadOnly
 
bool DefaultXactDeferrable = false
 
bool XactDeferrable
 
int synchronous_commit = SYNCHRONOUS_COMMIT_ON
 
TransactionId CheckXidAlive = InvalidTransactionId
 
bool bsysscan = false
 
static FullTransactionId XactTopFullTransactionId = {InvalidTransactionId}
 
static int nParallelCurrentXids = 0
 
static TransactionIdParallelCurrentXids
 
int MyXactFlags
 
static TransactionStateData TopTransactionStateData
 
static int nUnreportedXids
 
static TransactionId unreportedXids [PGPROC_MAX_CACHED_SUBXIDS]
 
static TransactionState CurrentTransactionState = &TopTransactionStateData
 
static SubTransactionId currentSubTransactionId
 
static CommandId currentCommandId
 
static bool currentCommandIdUsed
 
static TimestampTz xactStartTimestamp
 
static TimestampTz stmtStartTimestamp
 
static TimestampTz xactStopTimestamp
 
static charprepareGID
 
static bool forceSyncCommit = false
 
bool xact_is_sampled = false
 
static MemoryContext TransactionAbortContext = NULL
 
static XactCallbackItemXact_callbacks = NULL
 
static SubXactCallbackItemSubXact_callbacks = NULL
 

Macro Definition Documentation

◆ SerializedTransactionStateHeaderSize

#define SerializedTransactionStateHeaderSize    offsetof(SerializedTransactionState, parallelCurrentXids)

Definition at line 241 of file xact.c.

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

Typedef Documentation

◆ SerializedTransactionState

◆ SubXactCallbackItem

◆ TBlockState

◆ TransactionState

Definition at line 223 of file xact.c.

◆ TransactionStateData

◆ TransState

◆ XactCallbackItem

Enumeration Type Documentation

◆ TBlockState

Enumerator
TBLOCK_DEFAULT 
TBLOCK_STARTED 
TBLOCK_BEGIN 
TBLOCK_INPROGRESS 
TBLOCK_IMPLICIT_INPROGRESS 
TBLOCK_PARALLEL_INPROGRESS 
TBLOCK_END 
TBLOCK_ABORT 
TBLOCK_ABORT_END 
TBLOCK_ABORT_PENDING 
TBLOCK_PREPARE 
TBLOCK_SUBBEGIN 
TBLOCK_SUBINPROGRESS 
TBLOCK_SUBRELEASE 
TBLOCK_SUBCOMMIT 
TBLOCK_SUBABORT 
TBLOCK_SUBABORT_END 
TBLOCK_SUBABORT_PENDING 
TBLOCK_SUBRESTART 
TBLOCK_SUBABORT_RESTART 

Definition at line 159 of file xact.c.

160{
161 /* not-in-transaction-block states */
162 TBLOCK_DEFAULT, /* idle */
163 TBLOCK_STARTED, /* running single-query transaction */
164
165 /* transaction block states */
166 TBLOCK_BEGIN, /* starting transaction block */
167 TBLOCK_INPROGRESS, /* live transaction */
168 TBLOCK_IMPLICIT_INPROGRESS, /* live transaction after implicit BEGIN */
169 TBLOCK_PARALLEL_INPROGRESS, /* live transaction inside parallel worker */
170 TBLOCK_END, /* COMMIT received */
171 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
172 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
173 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
174 TBLOCK_PREPARE, /* live xact, PREPARE received */
175
176 /* subtransaction states */
177 TBLOCK_SUBBEGIN, /* starting a subtransaction */
178 TBLOCK_SUBINPROGRESS, /* live subtransaction */
179 TBLOCK_SUBRELEASE, /* RELEASE received */
180 TBLOCK_SUBCOMMIT, /* COMMIT received while TBLOCK_SUBINPROGRESS */
181 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
182 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
183 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
184 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
185 TBLOCK_SUBABORT_RESTART, /* failed subxact, ROLLBACK TO received */

◆ TransState

Enumerator
TRANS_DEFAULT 
TRANS_START 
TRANS_INPROGRESS 
TRANS_COMMIT 
TRANS_ABORT 
TRANS_PREPARE 

Definition at line 143 of file xact.c.

144{
145 TRANS_DEFAULT, /* idle */
146 TRANS_START, /* transaction starting */
147 TRANS_INPROGRESS, /* inside a valid transaction */
148 TRANS_COMMIT, /* commit in progress */
149 TRANS_ABORT, /* abort in progress */
150 TRANS_PREPARE, /* prepare in progress */
151} TransState;

Function Documentation

◆ AbortCurrentTransaction()

void AbortCurrentTransaction ( void  )

Definition at line 3473 of file xact.c.

3474{
3475 /*
3476 * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3477 * done.
3478 */
3480 {
3481 }
3482}

References AbortCurrentTransactionInternal().

Referenced by _SPI_commit(), _SPI_rollback(), AutoVacLauncherMain(), pa_stream_abort(), PostgresMain(), ReorderBufferImmediateInvalidation(), ReorderBufferProcessTXN(), and SnapBuildClearExportedSnapshot().

◆ AbortCurrentTransactionInternal()

static bool AbortCurrentTransactionInternal ( void  )
static

Definition at line 3491 of file xact.c.

3492{
3494
3495 switch (s->blockState)
3496 {
3497 case TBLOCK_DEFAULT:
3498 if (s->state == TRANS_DEFAULT)
3499 {
3500 /* we are idle, so nothing to do */
3501 }
3502 else
3503 {
3504 /*
3505 * We can get here after an error during transaction start
3506 * (state will be TRANS_START). Need to clean up the
3507 * incompletely started transaction. First, adjust the
3508 * low-level state to suppress warning message from
3509 * AbortTransaction.
3510 */
3511 if (s->state == TRANS_START)
3515 }
3516 break;
3517
3518 /*
3519 * If we aren't in a transaction block, we just do the basic abort
3520 * & cleanup transaction. For this purpose, we treat an implicit
3521 * transaction block as if it were a simple statement.
3522 */
3523 case TBLOCK_STARTED:
3528 break;
3529
3530 /*
3531 * If we are in TBLOCK_BEGIN it means something screwed up right
3532 * after reading "BEGIN TRANSACTION". We assume that the user
3533 * will interpret the error as meaning the BEGIN failed to get him
3534 * into a transaction block, so we should abort and return to idle
3535 * state.
3536 */
3537 case TBLOCK_BEGIN:
3541 break;
3542
3543 /*
3544 * We are somewhere in a transaction block and we've gotten a
3545 * failure, so we abort the transaction and set up the persistent
3546 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3547 */
3548 case TBLOCK_INPROGRESS:
3552 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3553 break;
3554
3555 /*
3556 * Here, we failed while trying to COMMIT. Clean up the
3557 * transaction and return to idle state (we do not want to stay in
3558 * the transaction).
3559 */
3560 case TBLOCK_END:
3564 break;
3565
3566 /*
3567 * Here, we are already in an aborted transaction state and are
3568 * waiting for a ROLLBACK, but for some reason we failed again! So
3569 * we just remain in the abort state.
3570 */
3571 case TBLOCK_ABORT:
3572 case TBLOCK_SUBABORT:
3573 break;
3574
3575 /*
3576 * We are in a failed transaction and we got the ROLLBACK command.
3577 * We have already aborted, we just need to cleanup and go to idle
3578 * state.
3579 */
3580 case TBLOCK_ABORT_END:
3583 break;
3584
3585 /*
3586 * We are in a live transaction and we got a ROLLBACK command.
3587 * Abort, cleanup, go to idle state.
3588 */
3593 break;
3594
3595 /*
3596 * Here, we failed while trying to PREPARE. Clean up the
3597 * transaction and return to idle state (we do not want to stay in
3598 * the transaction).
3599 */
3600 case TBLOCK_PREPARE:
3604 break;
3605
3606 /*
3607 * We got an error inside a subtransaction. Abort just the
3608 * subtransaction, and go to the persistent SUBABORT state until
3609 * we get ROLLBACK.
3610 */
3614 break;
3615
3616 /*
3617 * If we failed while trying to create a subtransaction, clean up
3618 * the broken subtransaction and abort the parent. The same
3619 * applies if we get a failure while ending a subtransaction. As
3620 * we need to abort the parent, return false to request the caller
3621 * to do the next iteration.
3622 */
3623 case TBLOCK_SUBBEGIN:
3624 case TBLOCK_SUBRELEASE:
3625 case TBLOCK_SUBCOMMIT:
3627 case TBLOCK_SUBRESTART:
3630 return false;
3631
3632 /*
3633 * Same as above, except the Abort() was already done.
3634 */
3638 return false;
3639 }
3640
3641 /* Done, no more iterations required */
3642 return true;
3643}

References AbortSubTransaction(), AbortTransaction(), TransactionStateData::blockState, CleanupSubTransaction(), CleanupTransaction(), CurrentTransactionState, TransactionStateData::state, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, TBLOCK_SUBRESTART, TRANS_DEFAULT, TRANS_INPROGRESS, and TRANS_START.

Referenced by AbortCurrentTransaction().

◆ AbortOutOfAnyTransaction()

void AbortOutOfAnyTransaction ( void  )

Definition at line 4885 of file xact.c.

4886{
4888
4889 /* Ensure we're not running in a doomed memory context */
4891
4892 /*
4893 * Get out of any transaction or nested transaction
4894 */
4895 do
4896 {
4897 switch (s->blockState)
4898 {
4899 case TBLOCK_DEFAULT:
4900 if (s->state == TRANS_DEFAULT)
4901 {
4902 /* Not in a transaction, do nothing */
4903 }
4904 else
4905 {
4906 /*
4907 * We can get here after an error during transaction start
4908 * (state will be TRANS_START). Need to clean up the
4909 * incompletely started transaction. First, adjust the
4910 * low-level state to suppress warning message from
4911 * AbortTransaction.
4912 */
4913 if (s->state == TRANS_START)
4917 }
4918 break;
4919 case TBLOCK_STARTED:
4920 case TBLOCK_BEGIN:
4921 case TBLOCK_INPROGRESS:
4924 case TBLOCK_END:
4926 case TBLOCK_PREPARE:
4927 /* In a transaction, so clean up */
4931 break;
4932 case TBLOCK_ABORT:
4933 case TBLOCK_ABORT_END:
4934
4935 /*
4936 * AbortTransaction is already done, still need Cleanup.
4937 * However, if we failed partway through running ROLLBACK,
4938 * there will be an active portal running that command, which
4939 * we need to shut down before doing CleanupTransaction.
4940 */
4944 break;
4945
4946 /*
4947 * In a subtransaction, so clean it up and abort parent too
4948 */
4949 case TBLOCK_SUBBEGIN:
4951 case TBLOCK_SUBRELEASE:
4952 case TBLOCK_SUBCOMMIT:
4954 case TBLOCK_SUBRESTART:
4957 s = CurrentTransactionState; /* changed by pop */
4958 break;
4959
4960 case TBLOCK_SUBABORT:
4963 /* As above, but AbortSubTransaction already done */
4964 if (s->curTransactionOwner)
4965 {
4966 /* As in TBLOCK_ABORT, might have a live portal to zap */
4971 }
4973 s = CurrentTransactionState; /* changed by pop */
4974 break;
4975 }
4976 } while (s->blockState != TBLOCK_DEFAULT);
4977
4978 /* Should be out of all subxacts now */
4979 Assert(s->parent == NULL);
4980
4981 /*
4982 * Revert to TopMemoryContext, to ensure we exit in a well-defined state
4983 * whether there were any transactions to close or not. (Callers that
4984 * don't intend to exit soon should switch to some other context to avoid
4985 * long-term memory leaks.)
4986 */
4988}

References AbortSubTransaction(), AbortTransaction(), Assert, AtAbort_Memory(), AtAbort_Portals(), AtSubAbort_Portals(), TransactionStateData::blockState, CleanupSubTransaction(), CleanupTransaction(), CurrentTransactionState, TransactionStateData::curTransactionOwner, fb(), MemoryContextSwitchTo(), TransactionStateData::parent, TransactionStateData::state, TransactionStateData::subTransactionId, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, TBLOCK_SUBRESTART, TopMemoryContext, TRANS_DEFAULT, TRANS_INPROGRESS, and TRANS_START.

Referenced by DisableSubscriptionAndExit(), do_autovacuum(), perform_work_item(), RemoveTempRelationsCallback(), ShutdownPostgres(), start_apply(), start_sequence_sync(), and start_table_sync().

◆ AbortSubTransaction()

static void AbortSubTransaction ( void  )
static

Definition at line 5242 of file xact.c.

5243{
5245
5246 /* Prevent cancel/die interrupt while cleaning up */
5248
5249 /* Make sure we have a valid memory context and resource owner */
5252
5253 /*
5254 * Release any LW locks we might be holding as quickly as possible.
5255 * (Regular locks, however, must be held till we finish aborting.)
5256 * Releasing LW locks is critical since we might try to grab them again
5257 * while cleaning up!
5258 *
5259 * FIXME This may be incorrect --- Are there some locks we should keep?
5260 * Buffer locks, for example? I don't think so but I'm not sure.
5261 */
5263
5266
5268
5269 UnlockBuffers();
5270
5271 /* Reset WAL record construction state */
5273
5274 /* Cancel condition variable sleep */
5276
5277 /*
5278 * Also clean up any open wait for lock, since the lock manager will choke
5279 * if we try to wait for another lock before doing this.
5280 */
5282
5283 /*
5284 * If any timeout events are still active, make sure the timeout interrupt
5285 * is scheduled. This covers possible loss of a timeout interrupt due to
5286 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5287 * We delay this till after LockErrorCleanup so that we don't uselessly
5288 * reschedule lock or deadlock check timeouts.
5289 */
5291
5292 /*
5293 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5294 * handler. We do this fairly early in the sequence so that the timeout
5295 * infrastructure will be functional if needed while aborting.
5296 */
5298
5299 /*
5300 * check the current transaction state
5301 */
5302 ShowTransactionState("AbortSubTransaction");
5303
5304 if (s->state != TRANS_INPROGRESS)
5305 elog(WARNING, "AbortSubTransaction while in %s state",
5307
5308 s->state = TRANS_ABORT;
5309
5310 /*
5311 * Reset user ID which might have been changed transiently. (See notes in
5312 * AbortTransaction.)
5313 */
5315
5316 /* Forget about any active REINDEX. */
5318
5319 /* Reset logical streaming state. */
5321
5322 /*
5323 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5324 * exports are not supported in subtransactions.
5325 */
5326
5327 /*
5328 * If this subxact has started any unfinished parallel operation, clean up
5329 * its workers and exit parallel mode. Don't warn about leaked resources.
5330 */
5332 s->parallelModeLevel = 0;
5333
5334 /*
5335 * We can skip all this stuff if the subxact failed before creating a
5336 * ResourceOwner...
5337 */
5338 if (s->curTransactionOwner)
5339 {
5348
5349 /* Advertise the fact that we aborted in pg_xact. */
5351
5352 /* Post-abort cleanup */
5355
5358
5361 false, false);
5362
5363 AtEOXact_Aio(false);
5367 AtEOSubXact_Inval(false);
5370 false, false);
5373 false, false);
5375
5376 AtEOXact_GUC(false, s->gucNestLevel);
5387 }
5388
5389 /*
5390 * Restore the upper transaction's read-only state, too. This should be
5391 * redundant with GUC's cleanup but we may as well do it for consistency
5392 * with the commit case.
5393 */
5395
5397}

References AfterTriggerEndSubXact(), AtEOSubXact_Files(), AtEOSubXact_HashTables(), AtEOSubXact_Inval(), AtEOSubXact_LargeObject(), AtEOSubXact_Namespace(), AtEOSubXact_on_commit_actions(), AtEOSubXact_Parallel(), AtEOSubXact_PgStat(), AtEOSubXact_RelationCache(), AtEOSubXact_SPI(), AtEOSubXact_TypeCache(), AtEOXact_Aio(), AtEOXact_GUC(), AtSubAbort_childXids(), AtSubAbort_Memory(), AtSubAbort_Notify(), AtSubAbort_Portals(), AtSubAbort_ResourceOwner(), AtSubAbort_smgr(), AtSubAbort_Snapshot(), CallSubXactCallbacks(), ConditionVariableCancelSleep(), CurrentTransactionState, TransactionStateData::curTransactionOwner, elog, fb(), TransactionStateData::fullTransactionId, FullTransactionIdIsValid, TransactionStateData::gucNestLevel, HOLD_INTERRUPTS, LockErrorCleanup(), LWLockReleaseAll(), TransactionStateData::nestingLevel, TransactionStateData::parallelModeLevel, TransactionStateData::parent, pgaio_error_cleanup(), pgstat_progress_end_command(), pgstat_report_wait_end(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, TransactionStateData::prevXactReadOnly, RecordTransactionAbort(), reschedule_timeouts(), ResetLogicalStreamingState(), ResetReindexState(), RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerRelease(), RESUME_INTERRUPTS, SetUserIdAndSecContext(), ShowTransactionState(), TransactionStateData::state, TransactionStateData::subTransactionId, SUBXACT_EVENT_ABORT_SUB, TRANS_ABORT, TRANS_INPROGRESS, TransStateAsString(), UnBlockSig, UnlockBuffers(), WARNING, XactReadOnly, and XLogResetInsertion().

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), CommitTransactionCommandInternal(), and RollbackAndReleaseCurrentSubTransaction().

◆ AbortTransaction()

static void AbortTransaction ( void  )
static

Definition at line 2825 of file xact.c.

2826{
2829 bool is_parallel_worker;
2830
2831 /* Prevent cancel/die interrupt while cleaning up */
2833
2834 /* Disable transaction timeout */
2835 if (TransactionTimeout > 0)
2837
2838 /* Make sure we have a valid memory context and resource owner */
2841
2842 /*
2843 * Release any LW locks we might be holding as quickly as possible.
2844 * (Regular locks, however, must be held till we finish aborting.)
2845 * Releasing LW locks is critical since we might try to grab them again
2846 * while cleaning up!
2847 */
2849
2850 /*
2851 * Cleanup waiting for LSN if any.
2852 */
2854
2855 /* Clear wait information and command progress indicator */
2858
2860
2861 /* Clean up buffer content locks, too */
2862 UnlockBuffers();
2863
2864 /* Reset WAL record construction state */
2866
2867 /* Cancel condition variable sleep */
2869
2870 /*
2871 * Also clean up any open wait for lock, since the lock manager will choke
2872 * if we try to wait for another lock before doing this.
2873 */
2875
2876 /*
2877 * If any timeout events are still active, make sure the timeout interrupt
2878 * is scheduled. This covers possible loss of a timeout interrupt due to
2879 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2880 * We delay this till after LockErrorCleanup so that we don't uselessly
2881 * reschedule lock or deadlock check timeouts.
2882 */
2884
2885 /*
2886 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2887 * handler. We do this fairly early in the sequence so that the timeout
2888 * infrastructure will be functional if needed while aborting.
2889 */
2891
2892 /*
2893 * check the current transaction state
2894 */
2896 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2897 elog(WARNING, "AbortTransaction while in %s state",
2899 Assert(s->parent == NULL);
2900
2901 /*
2902 * set the current transaction state information appropriately during the
2903 * abort processing
2904 */
2905 s->state = TRANS_ABORT;
2906
2907 /*
2908 * Reset user ID which might have been changed transiently. We need this
2909 * to clean up in case control escaped out of a SECURITY DEFINER function
2910 * or other local change of CurrentUserId; therefore, the prior value of
2911 * SecurityRestrictionContext also needs to be restored.
2912 *
2913 * (Note: it is not necessary to restore session authorization or role
2914 * settings here because those can only be changed via GUC, and GUC will
2915 * take care of rolling them back if need be.)
2916 */
2918
2919 /* Forget about any active REINDEX. */
2921
2922 /* Reset logical streaming state. */
2924
2925 /* Reset snapshot export state. */
2927
2928 /*
2929 * If this xact has started any unfinished parallel operation, clean up
2930 * its workers and exit parallel mode. Don't warn about leaked resources.
2931 */
2932 AtEOXact_Parallel(false);
2933 s->parallelModeLevel = 0;
2934 s->parallelChildXact = false; /* should be false already */
2935
2936 /*
2937 * do abort processing
2938 */
2939 AfterTriggerEndXact(false); /* 'false' means it's abort */
2942 AtEOXact_LargeObject(false);
2946
2947 /*
2948 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2949 * far as assigning an XID to advertise). But if we're inside a parallel
2950 * worker, skip this; the user backend must be the one to write the abort
2951 * record.
2952 */
2953 if (!is_parallel_worker)
2955 else
2956 {
2958
2959 /*
2960 * Since the parallel leader won't get our value of XactLastRecEnd in
2961 * this case, we nudge WAL-writer ourselves in this case. See related
2962 * comments in RecordTransactionAbort for why this matters.
2963 */
2965 }
2966
2968
2969 /*
2970 * Let others know about no transaction in progress by me. Note that this
2971 * must be done _before_ releasing locks we hold and _after_
2972 * RecordTransactionAbort.
2973 */
2975
2976 /*
2977 * Post-abort cleanup. See notes in CommitTransaction() concerning
2978 * ordering. We can skip all of it if the transaction failed before
2979 * creating a resource owner.
2980 */
2982 {
2985 else
2987
2990 false, true);
2991 AtEOXact_Aio(false);
2992 AtEOXact_Buffers(false);
2995 AtEOXact_Inval(false);
2999 false, true);
3002 false, true);
3003 smgrDoPendingDeletes(false);
3004
3005 AtEOXact_GUC(false, 1);
3006 AtEOXact_SPI(false);
3007 AtEOXact_Enum();
3010 AtEOXact_SMgr();
3011 AtEOXact_Files(false);
3013 AtEOXact_HashTables(false);
3019 }
3020
3021 /*
3022 * State remains TRANS_ABORT until CleanupTransaction().
3023 */
3025}

References AfterTriggerEndXact(), Assert, AtAbort_Memory(), AtAbort_Notify(), AtAbort_Portals(), AtAbort_ResourceOwner(), AtAbort_Twophase(), AtEOXact_Aio(), AtEOXact_ApplyLauncher(), AtEOXact_Buffers(), AtEOXact_ComboCid(), AtEOXact_Enum(), AtEOXact_Files(), AtEOXact_GUC(), AtEOXact_HashTables(), AtEOXact_Inval(), AtEOXact_LargeObject(), AtEOXact_LogicalCtl(), AtEOXact_LogicalRepWorkers(), AtEOXact_MultiXact(), AtEOXact_Namespace(), AtEOXact_on_commit_actions(), AtEOXact_Parallel(), AtEOXact_PgStat(), AtEOXact_RelationCache(), AtEOXact_RelationMap(), AtEOXact_SMgr(), AtEOXact_SPI(), AtEOXact_TypeCache(), TransactionStateData::blockState, CallXactCallbacks(), ConditionVariableCancelSleep(), CurrentTransactionState, disable_timeout(), elog, fb(), HOLD_INTERRUPTS, InvalidTransactionId, LockErrorCleanup(), LWLockReleaseAll(), PGPROC::lxid, MyProc, TransactionStateData::nestingLevel, TransactionStateData::parallelChildXact, TransactionStateData::parallelModeLevel, TransactionStateData::parent, pgaio_error_cleanup(), pgstat_progress_end_command(), pgstat_report_wait_end(), pgstat_report_xact_timestamp(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, ProcArrayEndTransaction(), RecordTransactionAbort(), reschedule_timeouts(), ResetLogicalStreamingState(), ResetReindexState(), RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerRelease(), RESUME_INTERRUPTS, SetUserIdAndSecContext(), smgrDoPendingDeletes(), smgrDoPendingSyncs(), SnapBuildResetExportedSnapshotState(), TransactionStateData::state, TBLOCK_PARALLEL_INPROGRESS, TopTransactionResourceOwner, TRANS_ABORT, TRANS_INPROGRESS, TRANS_PREPARE, TRANSACTION_TIMEOUT, TransactionTimeout, TransStateAsString(), UnBlockSig, UnlockBuffers(), PGPROC::vxid, WaitLSNCleanup(), WARNING, XACT_EVENT_ABORT, XACT_EVENT_PARALLEL_ABORT, XactLastRecEnd, XLogResetInsertion(), and XLogSetAsyncXactLSN().

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), and CommitTransactionCommandInternal().

◆ AssignTransactionId()

static void AssignTransactionId ( TransactionState  s)
static

Definition at line 637 of file xact.c.

638{
639 bool isSubXact = (s->parent != NULL);
641 bool log_unknown_top = false;
642
643 /* Assert that caller didn't screw up */
646
647 /*
648 * Workers synchronize transaction state at the beginning of each parallel
649 * operation, so we can't account for new XIDs at this point.
650 */
654 errmsg("cannot assign transaction IDs during a parallel operation")));
655
656 /*
657 * Ensure parent(s) have XIDs, so that a child always has an XID later
658 * than its parent. Mustn't recurse here, or we might get a stack
659 * overflow if we're at the bottom of a huge stack of subtransactions none
660 * of which have XIDs yet.
661 */
663 {
665 TransactionState *parents;
666 size_t parentOffset = 0;
667
670 {
671 parents[parentOffset++] = p;
672 p = p->parent;
673 }
674
675 /*
676 * This is technically a recursive call, but the recursion will never
677 * be more than one layer deep.
678 */
679 while (parentOffset != 0)
680 AssignTransactionId(parents[--parentOffset]);
681
682 pfree(parents);
683 }
684
685 /*
686 * When effective_wal_level is logical, guarantee that a subtransaction's
687 * xid can only be seen in the WAL stream if its toplevel xid has been
688 * logged before. If necessary we log an xact_assignment record with fewer
689 * than PGPROC_MAX_CACHED_SUBXIDS. Note that it is fine if didLogXid isn't
690 * set for a transaction even though it appears in a WAL record, we just
691 * might superfluously log something. That can happen when an xid is
692 * included somewhere inside a wal record, but not in XLogRecord->xl_xid,
693 * like in xl_standby_locks.
694 */
697 log_unknown_top = true;
698
699 /*
700 * Generate a new FullTransactionId and record its xid in PGPROC and
701 * pg_subtrans.
702 *
703 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
704 * shared storage other than PGPROC; because if there's no room for it in
705 * PGPROC, the subtrans entry is needed to ensure that other backends see
706 * the Xid as "running". See GetNewTransactionId.
707 */
709 if (!isSubXact)
711
712 if (isSubXact)
715
716 /*
717 * If it's a top-level transaction, the predicate locking system needs to
718 * be told about it too.
719 */
720 if (!isSubXact)
722
723 /*
724 * Acquire lock on the transaction XID. (We assume this cannot block.) We
725 * have to ensure that the lock is assigned to the transaction's own
726 * ResourceOwner.
727 */
730
732
734
735 /*
736 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
737 * top-level transaction we issue a WAL record for the assignment. We
738 * include the top-level xid and all the subxids that have not yet been
739 * reported using XLOG_XACT_ASSIGNMENT records.
740 *
741 * This is required to limit the amount of shared memory required in a hot
742 * standby server to keep track of in-progress XIDs. See notes for
743 * RecordKnownAssignedTransactionIds().
744 *
745 * We don't keep track of the immediate parent of each subxid, only the
746 * top-level transaction that each subxact belongs to. This is correct in
747 * recovery only because aborted subtransactions are separately WAL
748 * logged.
749 *
750 * This is correct even for the case where several levels above us didn't
751 * have an xid assigned as we recursed up to them beforehand.
752 */
754 {
757
758 /*
759 * ensure this test matches similar one in
760 * RecoverPreparedTransactions()
761 */
764 {
766
767 /*
768 * xtop is always set by now because we recurse up transaction
769 * stack to the highest unassigned xid and then come back down
770 */
773 xlrec.nsubxacts = nUnreportedXids;
774
779
781
782 nUnreportedXids = 0;
783 /* mark top, not current xact as having been logged */
785 }
786 }
787}

References Assert, AssignTransactionId(), CurrentResourceOwner, TransactionStateData::curTransactionOwner, TransactionStateData::didLogXid, ereport, errcode(), errmsg, ERROR, fb(), TransactionStateData::fullTransactionId, FullTransactionIdIsValid, GetNewTransactionId(), GetTopTransactionId(), IsInParallelMode(), IsParallelWorker, MinSizeOfXactAssignment, TransactionStateData::nestingLevel, nUnreportedXids, palloc_array, TransactionStateData::parent, pfree(), PGPROC_MAX_CACHED_SUBXIDS, RegisterPredicateLockingXid(), TransactionStateData::state, SubTransSetParent(), TopTransactionStateData, TRANS_INPROGRESS, TransactionIdIsValid, unreportedXids, XactLockTableInsert(), XactTopFullTransactionId, XidFromFullTransactionId, XLOG_XACT_ASSIGNMENT, XLogBeginInsert(), XLogInsert(), XLogLogicalInfoActive, XLogRegisterData(), XLogStandbyInfoActive, and xl_xact_assignment::xtop.

Referenced by AssignTransactionId(), GetCurrentFullTransactionId(), GetCurrentTransactionId(), GetTopFullTransactionId(), and GetTopTransactionId().

◆ AtAbort_Memory()

static void AtAbort_Memory ( void  )
static

Definition at line 1898 of file xact.c.

1899{
1900 /*
1901 * Switch into TransactionAbortContext, which should have some free space
1902 * even if nothing else does. We'll work in this context until we've
1903 * finished cleaning up.
1904 *
1905 * It is barely possible to get here when we've not been able to create
1906 * TransactionAbortContext yet; if so use TopMemoryContext.
1907 */
1910 else
1912}

References fb(), MemoryContextSwitchTo(), TopMemoryContext, and TransactionAbortContext.

Referenced by AbortOutOfAnyTransaction(), and AbortTransaction().

◆ AtAbort_ResourceOwner()

static void AtAbort_ResourceOwner ( void  )
static

Definition at line 1930 of file xact.c.

1931{
1932 /*
1933 * Make sure we have a valid ResourceOwner, if possible (else it will be
1934 * NULL, which is OK)
1935 */
1937}

References CurrentResourceOwner, and TopTransactionResourceOwner.

Referenced by AbortTransaction().

◆ AtCCI_LocalCache()

static void AtCCI_LocalCache ( void  )
static

Definition at line 1593 of file xact.c.

1594{
1595 /*
1596 * Make any pending relation map changes visible. We must do this before
1597 * processing local sinval messages, so that the map changes will get
1598 * reflected into the relcache when relcache invals are processed.
1599 */
1601
1602 /*
1603 * Make catalog changes visible to me for the next command.
1604 */
1606}

References AtCCI_RelationMap(), and CommandEndInvalidationMessages().

Referenced by CommandCounterIncrement().

◆ AtCleanup_Memory()

static void AtCleanup_Memory ( void  )
static

Definition at line 1988 of file xact.c.

1989{
1991
1992 /* Should be at top level */
1993 Assert(s->parent == NULL);
1994
1995 /*
1996 * Return to the memory context that was current before we started the
1997 * transaction. (In principle, this could not be any of the contexts we
1998 * are about to delete. If it somehow is, assertions in mcxt.c will
1999 * complain.)
2000 */
2002
2003 /*
2004 * Clear the special abort context for next time.
2005 */
2008
2009 /*
2010 * Release all transaction-local memory, the same as in AtCommit_Memory,
2011 * except we must cope with the possibility that we didn't get as far as
2012 * creating TopTransactionContext.
2013 */
2016
2017 /*
2018 * Clear these pointers as a pro-forma matter. (Notionally, while
2019 * TopTransactionContext still exists, it's currently not associated with
2020 * this TransactionState struct.)
2021 */
2024}

References Assert, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, fb(), MemoryContextReset(), MemoryContextSwitchTo(), TransactionStateData::parent, TransactionStateData::priorContext, TopTransactionContext, and TransactionAbortContext.

Referenced by CleanupTransaction().

◆ AtCommit_Memory()

static void AtCommit_Memory ( void  )
static

Definition at line 1612 of file xact.c.

1613{
1615
1616 /*
1617 * Return to the memory context that was current before we started the
1618 * transaction. (In principle, this could not be any of the contexts we
1619 * are about to delete. If it somehow is, assertions in mcxt.c will
1620 * complain.)
1621 */
1623
1624 /*
1625 * Release all transaction-local memory. TopTransactionContext survives
1626 * but becomes empty; any sub-contexts go away.
1627 */
1630
1631 /*
1632 * Clear these pointers as a pro-forma matter. (Notionally, while
1633 * TopTransactionContext still exists, it's currently not associated with
1634 * this TransactionState struct.)
1635 */
1638}

References Assert, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, fb(), MemoryContextReset(), MemoryContextSwitchTo(), TransactionStateData::priorContext, and TopTransactionContext.

Referenced by CommitTransaction(), and PrepareTransaction().

◆ AtStart_Cache()

static void AtStart_Cache ( void  )
static

Definition at line 1169 of file xact.c.

1170{
1172}

References AcceptInvalidationMessages().

Referenced by StartTransaction().

◆ AtStart_Memory()

static void AtStart_Memory ( void  )
static

Definition at line 1178 of file xact.c.

1179{
1181
1182 /*
1183 * Remember the memory context that was active prior to transaction start.
1184 */
1186
1187 /*
1188 * If this is the first time through, create a private context for
1189 * AbortTransaction to work in. By reserving some space now, we can
1190 * insulate AbortTransaction from out-of-memory scenarios. Like
1191 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1192 * size, so that space will be reserved immediately.
1193 */
1197 "TransactionAbortContext",
1198 32 * 1024,
1199 32 * 1024,
1200 32 * 1024);
1201
1202 /*
1203 * Likewise, if this is the first time through, create a top-level context
1204 * for transaction-local data. This context will be reset at transaction
1205 * end, and then re-used in later transactions.
1206 */
1210 "TopTransactionContext",
1212
1213 /*
1214 * In a top-level transaction, CurTransactionContext is the same as
1215 * TopTransactionContext.
1216 */
1219
1220 /* Make the CurTransactionContext active. */
1222}

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, CurrentMemoryContext, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, fb(), MemoryContextSwitchTo(), TransactionStateData::priorContext, TopMemoryContext, TopTransactionContext, and TransactionAbortContext.

Referenced by StartTransaction().

◆ AtStart_ResourceOwner()

static void AtStart_ResourceOwner ( void  )
static

Definition at line 1228 of file xact.c.

1229{
1231
1232 /*
1233 * We shouldn't have a transaction resource owner already.
1234 */
1236
1237 /*
1238 * Create a toplevel resource owner for the transaction.
1239 */
1240 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1241
1245}

References Assert, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, fb(), ResourceOwnerCreate(), and TopTransactionResourceOwner.

Referenced by StartTransaction().

◆ AtSubAbort_childXids()

static void AtSubAbort_childXids ( void  )
static

Definition at line 1956 of file xact.c.

1957{
1959
1960 /*
1961 * We keep the child-XID arrays in TopTransactionContext (see
1962 * AtSubCommit_childXids). This means we'd better free the array
1963 * explicitly at abort to avoid leakage.
1964 */
1965 if (s->childXids != NULL)
1966 pfree(s->childXids);
1967 s->childXids = NULL;
1968 s->nChildXids = 0;
1969 s->maxChildXids = 0;
1970
1971 /*
1972 * We could prune the unreportedXids array here. But we don't bother. That
1973 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1974 * would likely introduce more CPU time into the more common paths, so we
1975 * choose not to do that.
1976 */
1977}

References TransactionStateData::childXids, CurrentTransactionState, fb(), TransactionStateData::maxChildXids, TransactionStateData::nChildXids, and pfree().

Referenced by AbortSubTransaction().

◆ AtSubAbort_Memory()

static void AtSubAbort_Memory ( void  )
static

◆ AtSubAbort_ResourceOwner()

static void AtSubAbort_ResourceOwner ( void  )
static

Definition at line 1943 of file xact.c.

1944{
1946
1947 /* Make sure we have a valid ResourceOwner */
1949}

References CurrentResourceOwner, CurrentTransactionState, and TransactionStateData::curTransactionOwner.

Referenced by AbortSubTransaction().

◆ AtSubCleanup_Memory()

static void AtSubCleanup_Memory ( void  )
static

Definition at line 2036 of file xact.c.

2037{
2039
2040 Assert(s->parent != NULL);
2041
2042 /*
2043 * Return to the memory context that was current before we started the
2044 * subtransaction. (In principle, this could not be any of the contexts
2045 * we are about to delete. If it somehow is, assertions in mcxt.c will
2046 * complain.)
2047 */
2049
2050 /* Update CurTransactionContext (might not be same as priorContext) */
2052
2053 /*
2054 * Clear the special abort context for next time.
2055 */
2058
2059 /*
2060 * Delete the subxact local memory contexts. Its CurTransactionContext can
2061 * go too (note this also kills CurTransactionContexts from any children
2062 * of the subxact).
2063 */
2064 if (s->curTransactionContext)
2067}

References Assert, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, fb(), MemoryContextDelete(), MemoryContextReset(), MemoryContextSwitchTo(), TransactionStateData::parent, TransactionStateData::priorContext, and TransactionAbortContext.

Referenced by CleanupSubTransaction().

◆ AtSubCommit_childXids()

static void AtSubCommit_childXids ( void  )
static

Definition at line 1678 of file xact.c.

1679{
1681 int new_nChildXids;
1682
1683 Assert(s->parent != NULL);
1684
1685 /*
1686 * The parent childXids array will need to hold my XID and all my
1687 * childXids, in addition to the XIDs already there.
1688 */
1690
1691 /* Allocate or enlarge the parent array if necessary */
1693 {
1694 int new_maxChildXids;
1696
1697 /*
1698 * Make it 2x what's needed right now, to avoid having to enlarge it
1699 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1700 * is what ensures that we don't need to worry about integer overflow
1701 * here or in the calculation of new_nChildXids.)
1702 */
1704 (int) (MaxAllocSize / sizeof(TransactionId)));
1705
1707 ereport(ERROR,
1709 errmsg("maximum number of committed subtransactions (%d) exceeded",
1710 (int) (MaxAllocSize / sizeof(TransactionId)))));
1711
1712 /*
1713 * We keep the child-XID arrays in TopTransactionContext; this avoids
1714 * setting up child-transaction contexts for what might be just a few
1715 * bytes of grandchild XIDs.
1716 */
1717 if (s->parent->childXids == NULL)
1721 else
1724
1727 }
1728
1729 /*
1730 * Copy all my XIDs to parent's array.
1731 *
1732 * Note: We rely on the fact that the XID of a child always follows that
1733 * of its parent. By copying the XID of this subtransaction before the
1734 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1735 * all XIDs already in the array belong to subtransactions started and
1736 * subcommitted before us, so their XIDs must precede ours.
1737 */
1739
1740 if (s->nChildXids > 0)
1741 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1742 s->childXids,
1743 s->nChildXids * sizeof(TransactionId));
1744
1746
1747 /* Release child's array to avoid leakage */
1748 if (s->childXids != NULL)
1749 pfree(s->childXids);
1750 /* We must reset these to avoid double-free if fail later in commit */
1751 s->childXids = NULL;
1752 s->nChildXids = 0;
1753 s->maxChildXids = 0;
1754}

References Assert, TransactionStateData::childXids, CurrentTransactionState, ereport, errcode(), errmsg, ERROR, fb(), TransactionStateData::fullTransactionId, MaxAllocSize, TransactionStateData::maxChildXids, MemoryContextAlloc(), Min, TransactionStateData::nChildXids, TransactionStateData::parent, pfree(), repalloc(), TopTransactionContext, and XidFromFullTransactionId.

Referenced by CommitSubTransaction().

◆ AtSubCommit_Memory()

static void AtSubCommit_Memory ( void  )
static

Definition at line 1649 of file xact.c.

1650{
1652
1653 Assert(s->parent != NULL);
1654
1655 /* Return to parent transaction level's memory context. */
1658
1659 /*
1660 * Ordinarily we cannot throw away the child's CurTransactionContext,
1661 * since the data it contains will be needed at upper commit. However, if
1662 * there isn't actually anything in it, we can throw it away. This avoids
1663 * a small memory leak in the common case of "trivial" subxacts.
1664 */
1666 {
1669 }
1670}

References Assert, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, fb(), MemoryContextDelete(), MemoryContextIsEmpty(), MemoryContextSwitchTo(), and TransactionStateData::parent.

Referenced by CommitSubTransaction().

◆ AtSubStart_Memory()

static void AtSubStart_Memory ( void  )
static

Definition at line 1256 of file xact.c.

1257{
1259
1261
1262 /*
1263 * Remember the context that was active prior to subtransaction start.
1264 */
1266
1267 /*
1268 * Create a CurTransactionContext, which will be used to hold data that
1269 * survives subtransaction commit but disappears on subtransaction abort.
1270 * We make it a child of the immediate parent's CurTransactionContext.
1271 */
1273 "CurTransactionContext",
1276
1277 /* Make the CurTransactionContext active. */
1279}

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, CurrentMemoryContext, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, fb(), MemoryContextSwitchTo(), and TransactionStateData::priorContext.

Referenced by StartSubTransaction().

◆ AtSubStart_ResourceOwner()

static void AtSubStart_ResourceOwner ( void  )
static

Definition at line 1285 of file xact.c.

1286{
1288
1289 Assert(s->parent != NULL);
1290
1291 /*
1292 * Create a resource owner for the subtransaction. We make it a child of
1293 * the immediate parent's resource owner.
1294 */
1297 "SubTransaction");
1298
1301}

References Assert, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, fb(), TransactionStateData::parent, and ResourceOwnerCreate().

Referenced by StartSubTransaction().

◆ BeginImplicitTransactionBlock()

void BeginImplicitTransactionBlock ( void  )

Definition at line 4349 of file xact.c.

4350{
4352
4353 /*
4354 * If we are in STARTED state (that is, no transaction block is open),
4355 * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4356 * block.
4357 *
4358 * For caller convenience, we consider all other transaction states as
4359 * legal here; otherwise the caller would need its own state check, which
4360 * seems rather pointless.
4361 */
4362 if (s->blockState == TBLOCK_STARTED)
4364}

References TransactionStateData::blockState, CurrentTransactionState, TBLOCK_IMPLICIT_INPROGRESS, and TBLOCK_STARTED.

Referenced by exec_simple_query(), and start_xact_command().

◆ BeginInternalSubTransaction()

void BeginInternalSubTransaction ( const char name)

Definition at line 4717 of file xact.c.

4718{
4721
4722 /*
4723 * Errors within this function are improbable, but if one does happen we
4724 * force a FATAL exit. Callers generally aren't prepared to handle losing
4725 * control, and moreover our transaction state is probably corrupted if we
4726 * fail partway through; so an ordinary ERROR longjmp isn't okay.
4727 */
4728 ExitOnAnyError = true;
4729
4730 /*
4731 * We do not check for parallel mode here. It's permissible to start and
4732 * end "internal" subtransactions while in parallel mode, so long as no
4733 * new XIDs or command IDs are assigned. Enforcement of that occurs in
4734 * AssignTransactionId() and CommandCounterIncrement().
4735 */
4736
4737 switch (s->blockState)
4738 {
4739 case TBLOCK_STARTED:
4740 case TBLOCK_INPROGRESS:
4743 case TBLOCK_END:
4744 case TBLOCK_PREPARE:
4746 /* Normal subtransaction start */
4748 s = CurrentTransactionState; /* changed by push */
4749
4750 /*
4751 * Savepoint names, like the TransactionState block itself, live
4752 * in TopTransactionContext.
4753 */
4754 if (name)
4756 break;
4757
4758 /* These cases are invalid. */
4759 case TBLOCK_DEFAULT:
4760 case TBLOCK_BEGIN:
4761 case TBLOCK_SUBBEGIN:
4762 case TBLOCK_SUBRELEASE:
4763 case TBLOCK_SUBCOMMIT:
4764 case TBLOCK_ABORT:
4765 case TBLOCK_SUBABORT:
4766 case TBLOCK_ABORT_END:
4770 case TBLOCK_SUBRESTART:
4772 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4774 break;
4775 }
4776
4779
4781}

References TransactionStateData::blockState, BlockStateAsString(), CommitTransactionCommand(), CurrentTransactionState, elog, ExitOnAnyError, FATAL, fb(), MemoryContextStrdup(), TransactionStateData::name, name, PushTransaction(), StartTransactionCommand(), TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, TBLOCK_SUBRESTART, and TopTransactionContext.

Referenced by exec_stmt_block(), plperl_spi_exec(), plperl_spi_exec_prepared(), plperl_spi_fetchrow(), plperl_spi_prepare(), plperl_spi_query(), plperl_spi_query_prepared(), pltcl_returnnext(), pltcl_subtrans_begin(), pltcl_subtransaction(), PLy_spi_subtransaction_begin(), PLy_subtransaction_enter(), ReorderBufferImmediateInvalidation(), and ReorderBufferProcessTXN().

◆ BeginTransactionBlock()

void BeginTransactionBlock ( void  )

Definition at line 3947 of file xact.c.

3948{
3950
3951 switch (s->blockState)
3952 {
3953 /*
3954 * We are not inside a transaction block, so allow one to begin.
3955 */
3956 case TBLOCK_STARTED:
3958 break;
3959
3960 /*
3961 * BEGIN converts an implicit transaction block to a regular one.
3962 * (Note that we allow this even if we've already done some
3963 * commands, which is a bit odd but matches historical practice.)
3964 */
3967 break;
3968
3969 /*
3970 * Already a transaction block in progress.
3971 */
3972 case TBLOCK_INPROGRESS:
3975 case TBLOCK_ABORT:
3976 case TBLOCK_SUBABORT:
3979 errmsg("there is already a transaction in progress")));
3980 break;
3981
3982 /* These cases are invalid. */
3983 case TBLOCK_DEFAULT:
3984 case TBLOCK_BEGIN:
3985 case TBLOCK_SUBBEGIN:
3986 case TBLOCK_END:
3987 case TBLOCK_SUBRELEASE:
3988 case TBLOCK_SUBCOMMIT:
3989 case TBLOCK_ABORT_END:
3993 case TBLOCK_SUBRESTART:
3995 case TBLOCK_PREPARE:
3996 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3998 break;
3999 }
4000}

References TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg, FATAL, fb(), TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, TBLOCK_SUBRESTART, and WARNING.

Referenced by apply_handle_prepare_internal(), pa_start_subtrans(), and standard_ProcessUtility().

◆ BlockStateAsString()

static const char * BlockStateAsString ( TBlockState  blockState)
static

Definition at line 5730 of file xact.c.

5731{
5732 switch (blockState)
5733 {
5734 case TBLOCK_DEFAULT:
5735 return "DEFAULT";
5736 case TBLOCK_STARTED:
5737 return "STARTED";
5738 case TBLOCK_BEGIN:
5739 return "BEGIN";
5740 case TBLOCK_INPROGRESS:
5741 return "INPROGRESS";
5743 return "IMPLICIT_INPROGRESS";
5745 return "PARALLEL_INPROGRESS";
5746 case TBLOCK_END:
5747 return "END";
5748 case TBLOCK_ABORT:
5749 return "ABORT";
5750 case TBLOCK_ABORT_END:
5751 return "ABORT_END";
5753 return "ABORT_PENDING";
5754 case TBLOCK_PREPARE:
5755 return "PREPARE";
5756 case TBLOCK_SUBBEGIN:
5757 return "SUBBEGIN";
5759 return "SUBINPROGRESS";
5760 case TBLOCK_SUBRELEASE:
5761 return "SUBRELEASE";
5762 case TBLOCK_SUBCOMMIT:
5763 return "SUBCOMMIT";
5764 case TBLOCK_SUBABORT:
5765 return "SUBABORT";
5767 return "SUBABORT_END";
5769 return "SUBABORT_PENDING";
5770 case TBLOCK_SUBRESTART:
5771 return "SUBRESTART";
5773 return "SUBABORT_RESTART";
5774 }
5775 return "UNRECOGNIZED";
5776}

References TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by BeginInternalSubTransaction(), BeginTransactionBlock(), CommitTransactionCommandInternal(), DefineSavepoint(), EndTransactionBlock(), ReleaseCurrentSubTransaction(), ReleaseSavepoint(), RollbackAndReleaseCurrentSubTransaction(), RollbackToSavepoint(), ShowTransactionStateRec(), StartTransactionCommand(), TransactionBlockStatusCode(), and UserAbortTransactionBlock().

◆ CallSubXactCallbacks()

static void CallSubXactCallbacks ( SubXactEvent  event,
SubTransactionId  mySubid,
SubTransactionId  parentSubid 
)
static

Definition at line 3921 of file xact.c.

3924{
3925 SubXactCallbackItem *item;
3927
3928 for (item = SubXact_callbacks; item; item = next)
3929 {
3930 /* allow callbacks to unregister themselves when called */
3931 next = item->next;
3932 item->callback(event, mySubid, parentSubid, item->arg);
3933 }
3934}

References SubXactCallbackItem::arg, SubXactCallbackItem::callback, fb(), next, SubXactCallbackItem::next, and SubXact_callbacks.

Referenced by AbortSubTransaction(), CommitSubTransaction(), and StartSubTransaction().

◆ CallXactCallbacks()

static void CallXactCallbacks ( XactEvent  event)
static

Definition at line 3861 of file xact.c.

3862{
3863 XactCallbackItem *item;
3865
3866 for (item = Xact_callbacks; item; item = next)
3867 {
3868 /* allow callbacks to unregister themselves when called */
3869 next = item->next;
3870 item->callback(event, item->arg);
3871 }
3872}

References XactCallbackItem::arg, XactCallbackItem::callback, next, XactCallbackItem::next, and Xact_callbacks.

Referenced by AbortTransaction(), CommitTransaction(), and PrepareTransaction().

◆ CheckTransactionBlock()

static void CheckTransactionBlock ( bool  isTopLevel,
bool  throwError,
const char stmtType 
)
static

Definition at line 3748 of file xact.c.

3749{
3750 /*
3751 * xact block already started?
3752 */
3753 if (IsTransactionBlock())
3754 return;
3755
3756 /*
3757 * subtransaction?
3758 */
3759 if (IsSubTransaction())
3760 return;
3761
3762 /*
3763 * inside a function call?
3764 */
3765 if (!isTopLevel)
3766 return;
3767
3770 /* translator: %s represents an SQL statement name */
3771 errmsg("%s can only be used in transaction blocks",
3772 stmtType)));
3773}

References ereport, errcode(), errmsg, ERROR, fb(), IsSubTransaction(), IsTransactionBlock(), and WARNING.

Referenced by RequireTransactionBlock(), and WarnNoTransactionBlock().

◆ CleanupSubTransaction()

◆ CleanupTransaction()

static void CleanupTransaction ( void  )
static

Definition at line 3031 of file xact.c.

3032{
3034
3035 /*
3036 * State should still be TRANS_ABORT from AbortTransaction().
3037 */
3038 if (s->state != TRANS_ABORT)
3039 elog(FATAL, "CleanupTransaction: unexpected state %s",
3041
3042 /*
3043 * do abort cleanup processing
3044 */
3045 AtCleanup_Portals(); /* now safe to release portal memory */
3046 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
3047
3048 CurrentResourceOwner = NULL; /* and resource owner */
3054
3055 AtCleanup_Memory(); /* and transaction memory */
3056
3059 s->nestingLevel = 0;
3060 s->gucNestLevel = 0;
3061 s->childXids = NULL;
3062 s->nChildXids = 0;
3063 s->maxChildXids = 0;
3064 s->parallelModeLevel = 0;
3065 s->parallelChildXact = false;
3066
3069
3070 /*
3071 * done with abort processing, set current transaction state back to
3072 * default
3073 */
3074 s->state = TRANS_DEFAULT;
3075}

References AtCleanup_Memory(), AtCleanup_Portals(), AtEOXact_Snapshot(), TransactionStateData::childXids, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, elog, FATAL, fb(), TransactionStateData::fullTransactionId, TransactionStateData::gucNestLevel, InvalidFullTransactionId, InvalidSubTransactionId, TransactionStateData::maxChildXids, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, nParallelCurrentXids, TransactionStateData::parallelChildXact, TransactionStateData::parallelModeLevel, ResourceOwnerDelete(), TransactionStateData::state, TransactionStateData::subTransactionId, TopTransactionResourceOwner, TRANS_ABORT, TRANS_DEFAULT, TransStateAsString(), and XactTopFullTransactionId.

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), and CommitTransactionCommandInternal().

◆ CommandCounterIncrement()

void CommandCounterIncrement ( void  )

Definition at line 1102 of file xact.c.

1103{
1104 /*
1105 * If the current value of the command counter hasn't been "used" to mark
1106 * tuples, we need not increment it, since there's no need to distinguish
1107 * a read-only command from others. This helps postpone command counter
1108 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
1109 */
1111 {
1112 /*
1113 * Workers synchronize transaction state at the beginning of each
1114 * parallel operation, so we can't account for new commands after that
1115 * point.
1116 */
1118 ereport(ERROR,
1120 errmsg("cannot start commands during a parallel operation")));
1121
1122 currentCommandId += 1;
1124 {
1125 currentCommandId -= 1;
1126 ereport(ERROR,
1128 errmsg("cannot have more than 2^32-2 commands in a transaction")));
1129 }
1130 currentCommandIdUsed = false;
1131
1132 /* Propagate new command ID into static snapshots */
1134
1135 /*
1136 * Make any catalog changes done by the just-completed command visible
1137 * in the local syscache. We obviously don't need to do this after a
1138 * read-only command. (But see hacks in inval.c to make real sure we
1139 * don't think a command that queued inval messages was read-only.)
1140 */
1142 }
1143}

References AtCCI_LocalCache(), currentCommandId, currentCommandIdUsed, ereport, errcode(), errmsg, ERROR, fb(), InvalidCommandId, IsInParallelMode(), IsParallelWorker, and SnapshotSetCommandId().

Referenced by _SPI_execute_plan(), acquire_inherited_sample_rows(), addFkConstraint(), AddRoleMems(), AlterPublicationOptions(), AlterRole(), ATAddCheckNNConstraint(), ATExecAddColumn(), ATExecAlterColumnType(), ATExecAlterConstrInheritability(), ATExecCmd(), ATExecDropColumn(), ATExecDropExpression(), ATExecDropIdentity(), ATExecMergePartitions(), ATExecSetAccessMethodNoStorage(), ATExecSetCompression(), ATExecSetExpression(), ATExecSetNotNull(), ATExecSetTableSpace(), ATExecSetTableSpaceNoStorage(), ATExecSplitPartition(), ATParseTransformCmd(), ATRewriteTables(), AttachPartitionEnsureIndexes(), AttachPartitionForeignKey(), btadjustmembers(), CommitSubTransaction(), CommitTransactionCommandInternal(), compute_return_type(), copy_table_data(), create_ctas_internal(), create_toast_table(), CreateFKCheckTrigger(), createForeignKeyActionTriggers(), CreateForeignTable(), createPartitionTable(), CreatePublication(), CreateRole(), CreateSchemaCommand(), createTableConstraints(), CreateTriggerFiringOn(), DefineCollation(), DefineDomain(), DefineIndex(), DefineRange(), DefineRelation(), DefineVirtualRelation(), delete_pg_statistic(), delete_pg_statistic_ext_data(), deleteOneObject(), DetachPartitionFinalize(), do_analyze_rel(), DropClonedTriggersFromPartition(), dropconstraint_internal(), DropForeignKeyConstraintTriggers(), DropRole(), end_replication_step(), EventTriggerDDLCommandEnd(), EventTriggerDDLCommandStart(), EventTriggerInvoke(), EventTriggerSQLDrop(), EventTriggerTableRewrite(), exec_eval_simple_expr(), exec_execute_message(), exec_parse_message(), exec_simple_query(), ExecGrant_common(), ExecGrant_Largeobject(), ExecGrant_Parameter(), ExecGrant_Relation(), execute_sql_string(), ExplainOnePlan(), finish_heap_swap(), fmgr_sql(), hashadjustmembers(), ImportForeignSchema(), index_build(), index_create(), IndexSetParentIndex(), InitTempTableNamespace(), inv_create(), inv_drop(), inv_truncate(), inv_write(), LogicalRepSyncTableStart(), make_new_heap(), makeConfigurationDependencies(), moveArrayTypeName(), objectNamesToOids(), OperatorShellMake(), OperatorUpd(), pg_import_system_collations(), PortalRunMulti(), ProcedureCreate(), process_single_relation(), ProcessSyncingTablesForApply(), ProcessUtilitySlow(), recordExtensionInitPrivWorker(), reindex_index(), reindex_relation(), ReindexRelationConcurrently(), relation_statistics_update(), RelationSetNewRelfilenumber(), RemoveInheritedConstraint(), RemoveRoleFromInitPriv(), RemoveRoleFromObjectPolicy(), RenumberEnumType(), ReplaceRoleInInitPriv(), replorigin_create(), replorigin_drop_by_name(), ri_PerformCheck(), set_attnotnull(), SetDatabaseHasLoginEventTriggers(), SetDefaultACL(), SetMatViewPopulatedState(), shdepReassignOwned(), SPI_cursor_open_internal(), standard_ProcessUtility(), StoreConstraints(), StorePartitionBound(), upsert_pg_statistic(), upsert_pg_statistic_ext_data(), vacuum(), and validatePartitionedIndex().

◆ CommitSubTransaction()

static void CommitSubTransaction ( void  )
static

Definition at line 5127 of file xact.c.

5128{
5130
5131 ShowTransactionState("CommitSubTransaction");
5132
5133 if (s->state != TRANS_INPROGRESS)
5134 elog(WARNING, "CommitSubTransaction while in %s state",
5136
5137 /* Pre-commit processing goes here */
5138
5141
5142 /*
5143 * If this subxact has started any unfinished parallel operation, clean up
5144 * its workers and exit parallel mode. Warn about leaked resources.
5145 */
5147 if (s->parallelModeLevel != 0)
5148 {
5149 elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5151 s->parallelModeLevel = 0;
5152 }
5153
5154 /* Do the actual "commit", such as it is */
5155 s->state = TRANS_COMMIT;
5156
5157 /* Must CCI to ensure commands of subtransaction are seen as done */
5159
5160 /*
5161 * Prior to 8.4 we marked subcommit in clog at this point. We now only
5162 * perform that step, if required, as part of the atomic update of the
5163 * whole transaction tree at top level commit or abort.
5164 */
5165
5166 /* Post-commit cleanup */
5172 s->parent->nestingLevel,
5177
5180
5183 true, false);
5187 AtEOSubXact_Inval(true);
5189
5190 /*
5191 * The only lock we actually release here is the subtransaction XID lock.
5192 */
5196
5197 /*
5198 * Other locks should get transferred to their parent resource owner.
5199 */
5202 true, false);
5205 true, false);
5206
5207 AtEOXact_GUC(true, s->gucNestLevel);
5218
5219 /*
5220 * We need to restore the upper transaction's read-only state, in case the
5221 * upper is read-write while the child is read-only; GUC will incorrectly
5222 * think it should leave the child state in place.
5223 */
5225
5230
5232
5233 s->state = TRANS_DEFAULT;
5234
5236}

References AfterTriggerEndSubXact(), AtEOSubXact_Files(), AtEOSubXact_HashTables(), AtEOSubXact_Inval(), AtEOSubXact_LargeObject(), AtEOSubXact_Namespace(), AtEOSubXact_on_commit_actions(), AtEOSubXact_Parallel(), AtEOSubXact_PgStat(), AtEOSubXact_RelationCache(), AtEOSubXact_SPI(), AtEOSubXact_TypeCache(), AtEOXact_GUC(), AtSubCommit_childXids(), AtSubCommit_Memory(), AtSubCommit_Notify(), AtSubCommit_Portals(), AtSubCommit_smgr(), AtSubCommit_Snapshot(), CallSubXactCallbacks(), CommandCounterIncrement(), CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, elog, fb(), TransactionStateData::fullTransactionId, FullTransactionIdIsValid, TransactionStateData::gucNestLevel, TransactionStateData::nestingLevel, TransactionStateData::parallelModeLevel, TransactionStateData::parent, PopTransaction(), TransactionStateData::prevXactReadOnly, RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerDelete(), ResourceOwnerRelease(), ShowTransactionState(), TransactionStateData::state, TransactionStateData::subTransactionId, SUBXACT_EVENT_COMMIT_SUB, SUBXACT_EVENT_PRE_COMMIT_SUB, TRANS_COMMIT, TRANS_DEFAULT, TRANS_INPROGRESS, TransStateAsString(), WARNING, XactLockTableDelete(), XactReadOnly, and XidFromFullTransactionId.

Referenced by CommitTransactionCommandInternal(), and ReleaseCurrentSubTransaction().

◆ CommitTransaction()

static void CommitTransaction ( void  )
static

Definition at line 2242 of file xact.c.

2243{
2246 bool is_parallel_worker;
2247
2249
2250 /* Enforce parallel mode restrictions during parallel worker commit. */
2253
2254 ShowTransactionState("CommitTransaction");
2255
2256 /*
2257 * check the current transaction state
2258 */
2259 if (s->state != TRANS_INPROGRESS)
2260 elog(WARNING, "CommitTransaction while in %s state",
2262 Assert(s->parent == NULL);
2263
2264 /*
2265 * Do pre-commit processing that involves calling user-defined code, such
2266 * as triggers. SECURITY_RESTRICTED_OPERATION contexts must not queue an
2267 * action that would run here, because that would bypass the sandbox.
2268 * Since closing cursors could queue trigger actions, triggers could open
2269 * cursors, etc, we have to keep looping until there's nothing left to do.
2270 */
2271 for (;;)
2272 {
2273 /*
2274 * Fire all currently pending deferred triggers.
2275 */
2277
2278 /*
2279 * Close open portals (converting holdable ones into static portals).
2280 * If there weren't any, we are done ... otherwise loop back to check
2281 * if they queued deferred triggers. Lather, rinse, repeat.
2282 */
2283 if (!PreCommit_Portals(false))
2284 break;
2285 }
2286
2287 /*
2288 * The remaining actions cannot call any user-defined code, so it's safe
2289 * to start shutting down within-transaction services. But note that most
2290 * of this stuff could still throw an error, which would switch us into
2291 * the transaction-abort path.
2292 */
2293
2296
2297 /*
2298 * If this xact has started any unfinished parallel operation, clean up
2299 * its workers, warning about leaked resources. (But we don't actually
2300 * reset parallelModeLevel till entering TRANS_COMMIT, a bit below. This
2301 * keeps parallel mode restrictions active as long as possible in a
2302 * parallel worker.)
2303 */
2304 AtEOXact_Parallel(true);
2306 {
2307 if (s->parallelModeLevel != 1)
2308 elog(WARNING, "parallelModeLevel is %d not 1 at end of parallel worker transaction",
2310 }
2311 else
2312 {
2313 if (s->parallelModeLevel != 0)
2314 elog(WARNING, "parallelModeLevel is %d not 0 at end of transaction",
2316 }
2317
2318 /* Shut down the deferred-trigger manager */
2319 AfterTriggerEndXact(true);
2320
2321 /*
2322 * Let ON COMMIT management do its thing (must happen after closing
2323 * cursors, to avoid dangling-reference problems)
2324 */
2326
2327 /*
2328 * Synchronize files that are created and not WAL-logged during this
2329 * transaction. This must happen before AtEOXact_RelationMap(), so that we
2330 * don't see committed-but-broken files after a crash.
2331 */
2333
2334 /* close large objects before lower-level cleanup */
2336
2337 /*
2338 * Insert notifications sent by NOTIFY commands into the queue. This
2339 * should be late in the pre-commit sequence to minimize time spent
2340 * holding the notify-insertion lock. However, this could result in
2341 * creating a snapshot, so we must do it before serializable cleanup.
2342 */
2344
2345 /*
2346 * Mark serializable transaction as complete for predicate locking
2347 * purposes. This should be done as late as we can put it and still allow
2348 * errors to be raised for failure patterns found at commit. This is not
2349 * appropriate in a parallel worker however, because we aren't committing
2350 * the leader's transaction and its serializable state will live on.
2351 */
2352 if (!is_parallel_worker)
2354
2355 /* Prevent cancel/die interrupt while cleaning up */
2357
2358 /* Commit updates to the relation map --- do this as late as possible */
2360
2361 /*
2362 * set the current transaction state information appropriately during
2363 * commit processing
2364 */
2365 s->state = TRANS_COMMIT;
2366 s->parallelModeLevel = 0;
2367 s->parallelChildXact = false; /* should be false already */
2368
2369 /* Disable transaction timeout */
2370 if (TransactionTimeout > 0)
2372
2373 if (!is_parallel_worker)
2374 {
2375 /*
2376 * We need to mark our XIDs as committed in pg_xact. This is where we
2377 * durably commit.
2378 */
2380 }
2381 else
2382 {
2383 /*
2384 * We must not mark our XID committed; the parallel leader is
2385 * responsible for that.
2386 */
2388
2389 /*
2390 * Make sure the leader will know about any WAL we wrote before it
2391 * commits.
2392 */
2394 }
2395
2397
2398 /*
2399 * Let others know about no transaction in progress by me. Note that this
2400 * must be done _before_ releasing locks we hold and _after_
2401 * RecordTransactionCommit.
2402 */
2404
2405 /*
2406 * This is all post-commit cleanup. Note that if an error is raised here,
2407 * it's too late to abort the transaction. This should be just
2408 * noncritical resource releasing.
2409 *
2410 * The ordering of operations is not entirely random. The idea is:
2411 * release resources visible to other backends (eg, files, buffer pins);
2412 * then release locks; then release backend-local resources. We want to
2413 * release locks at the point where any backend waiting for us will see
2414 * our transaction as being fully cleaned up.
2415 *
2416 * Resources that can be associated with individual queries are handled by
2417 * the ResourceOwner mechanism. The other calls here are for backend-wide
2418 * state.
2419 */
2420
2423
2427 true, true);
2428
2429 AtEOXact_Aio(true);
2430
2431 /* Check we've released all buffer pins */
2432 AtEOXact_Buffers(true);
2433
2434 /* Clean up the relation cache */
2436
2437 /* Clean up the type cache */
2439
2440 /*
2441 * Make catalog changes visible to all backends. This has to happen after
2442 * relcache references are dropped (see comments for
2443 * AtEOXact_RelationCache), but before locks are released (if anyone is
2444 * waiting for lock on a relation we've modified, we want them to know
2445 * about the catalog change before they start using the relation).
2446 */
2447 AtEOXact_Inval(true);
2448
2450
2453 true, true);
2456 true, true);
2457
2458 /*
2459 * Likewise, dropping of files deleted during the transaction is best done
2460 * after releasing relcache and buffer pins. (This is not strictly
2461 * necessary during commit, since such pins should have been released
2462 * already, but this ordering is definitely critical during abort.) Since
2463 * this may take many seconds, also delay until after releasing locks.
2464 * Other backends will observe the attendant catalog changes and not
2465 * attempt to access affected files.
2466 */
2468
2469 /*
2470 * Send out notification signals to other backends (and do other
2471 * post-commit NOTIFY cleanup). This must not happen until after our
2472 * transaction is fully done from the viewpoint of other backends.
2473 */
2475
2476 /*
2477 * Everything after this should be purely internal-to-this-backend
2478 * cleanup.
2479 */
2480 AtEOXact_GUC(true, 1);
2481 AtEOXact_SPI(true);
2482 AtEOXact_Enum();
2485 AtEOXact_SMgr();
2486 AtEOXact_Files(true);
2488 AtEOXact_HashTables(true);
2490 AtEOXact_Snapshot(true, false);
2495
2500
2502
2505 s->nestingLevel = 0;
2506 s->gucNestLevel = 0;
2507 s->childXids = NULL;
2508 s->nChildXids = 0;
2509 s->maxChildXids = 0;
2510
2513
2514 /*
2515 * done with commit processing, set current transaction state back to
2516 * default
2517 */
2518 s->state = TRANS_DEFAULT;
2519
2521}

References AfterTriggerEndXact(), AfterTriggerFireDeferred(), Assert, AtCommit_Memory(), AtCommit_Notify(), AtEOXact_Aio(), AtEOXact_ApplyLauncher(), AtEOXact_Buffers(), AtEOXact_ComboCid(), AtEOXact_Enum(), AtEOXact_Files(), AtEOXact_GUC(), AtEOXact_HashTables(), AtEOXact_Inval(), AtEOXact_LargeObject(), AtEOXact_LogicalCtl(), AtEOXact_LogicalRepWorkers(), AtEOXact_MultiXact(), AtEOXact_Namespace(), AtEOXact_on_commit_actions(), AtEOXact_Parallel(), AtEOXact_PgStat(), AtEOXact_RelationCache(), AtEOXact_RelationMap(), AtEOXact_SMgr(), AtEOXact_Snapshot(), AtEOXact_SPI(), AtEOXact_TypeCache(), TransactionStateData::blockState, CallXactCallbacks(), TransactionStateData::childXids, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, disable_timeout(), elog, EnterParallelMode(), fb(), TransactionStateData::fullTransactionId, TransactionStateData::gucNestLevel, HOLD_INTERRUPTS, InvalidFullTransactionId, InvalidSubTransactionId, InvalidTransactionId, PGPROC::lxid, TransactionStateData::maxChildXids, MyProc, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, nParallelCurrentXids, TransactionStateData::parallelChildXact, TransactionStateData::parallelModeLevel, ParallelWorkerReportLastRecEnd(), TransactionStateData::parent, pgstat_report_xact_timestamp(), PreCommit_CheckForSerializationFailure(), PreCommit_Notify(), PreCommit_on_commit_actions(), PreCommit_Portals(), ProcArrayEndTransaction(), RecordTransactionCommit(), RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerDelete(), ResourceOwnerRelease(), RESUME_INTERRUPTS, ShowTransactionState(), smgrDoPendingDeletes(), smgrDoPendingSyncs(), TransactionStateData::state, TransactionStateData::subTransactionId, TBLOCK_PARALLEL_INPROGRESS, TopTransactionResourceOwner, TRANS_COMMIT, TRANS_DEFAULT, TRANS_INPROGRESS, TRANSACTION_TIMEOUT, TransactionTimeout, TransStateAsString(), PGPROC::vxid, WARNING, XACT_EVENT_COMMIT, XACT_EVENT_PARALLEL_COMMIT, XACT_EVENT_PARALLEL_PRE_COMMIT, XACT_EVENT_PRE_COMMIT, XactLastRecEnd, and XactTopFullTransactionId.

Referenced by CommitTransactionCommandInternal(), EndParallelWorkerTransaction(), EndRestoreLOs(), IssueCommandPerBlob(), restore_toc_entries_prefork(), restore_toc_entry(), and RestoreArchive().

◆ CommitTransactionCommand()

void CommitTransactionCommand ( void  )

Definition at line 3179 of file xact.c.

3180{
3181 /*
3182 * Repeatedly call CommitTransactionCommandInternal() until all the work
3183 * is done.
3184 */
3186 {
3187 }
3188}

References CommitTransactionCommandInternal().

Referenced by _SPI_commit(), AllTablesyncsReady(), apply_handle_commit_internal(), apply_handle_commit_prepared(), apply_handle_prepare(), apply_handle_prepare_internal(), apply_handle_rollback_prepared(), apply_handle_stream_prepare(), ATExecDetachPartition(), autoprewarm_database_main(), bbsink_server_new(), BeginInternalSubTransaction(), BootstrapModeMain(), clear_subscription_skip_lsn(), copy_sequences(), DefineIndex(), DisableSubscriptionAndExit(), do_autovacuum(), EventTriggerOnLogin(), exec_replication_command(), ExecRepack(), finish_xact_command(), FinishSyncWorker(), get_database_list(), get_subscription_list(), HasSubscriptionTablesCached(), IdentifySystem(), index_drop(), initialize_worker_spi(), InitializeLogRepWorker(), InitPostgres(), LogicalRepSyncSequences(), LogicalRepSyncTableStart(), maybe_reread_subscription(), movedb(), pa_start_subtrans(), pa_stream_abort(), ParallelApplyWorkerMain(), ParallelWorkerMain(), process_single_relation(), ProcessCatchupInterrupt(), ProcessIncomingNotify(), ProcessSequencesForSync(), ProcessSyncingTablesForApply(), ProcessSyncingTablesForSync(), ReindexMultipleInternal(), ReindexRelationConcurrently(), RemoveTempRelationsCallback(), ReplSlotSyncWorkerMain(), run_apply_worker(), shell_check_detail(), stream_abort_internal(), stream_stop_internal(), update_retention_status(), vacuum(), vacuum_rel(), validate_remote_info(), and worker_spi_main().

◆ CommitTransactionCommandInternal()

static bool CommitTransactionCommandInternal ( void  )
static

Definition at line 3197 of file xact.c.

3198{
3201
3202 /* Must save in case we need to restore below */
3204
3205 switch (s->blockState)
3206 {
3207 /*
3208 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3209 * StartTransactionCommand didn't set the STARTED state
3210 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3211 * by EndParallelWorkerTransaction(), not this function.
3212 */
3213 case TBLOCK_DEFAULT:
3215 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3217 break;
3218
3219 /*
3220 * If we aren't in a transaction block, just do our usual
3221 * transaction commit, and return to the idle state.
3222 */
3223 case TBLOCK_STARTED:
3226 break;
3227
3228 /*
3229 * We are completing a "BEGIN TRANSACTION" command, so we change
3230 * to the "transaction block in progress" state and return. (We
3231 * assume the BEGIN did nothing to the database, so we need no
3232 * CommandCounterIncrement.)
3233 */
3234 case TBLOCK_BEGIN:
3236 break;
3237
3238 /*
3239 * This is the case when we have finished executing a command
3240 * someplace within a transaction block. We increment the command
3241 * counter and return.
3242 */
3243 case TBLOCK_INPROGRESS:
3247 break;
3248
3249 /*
3250 * We are completing a "COMMIT" command. Do it and return to the
3251 * idle state.
3252 */
3253 case TBLOCK_END:
3256 if (s->chain)
3257 {
3260 s->chain = false;
3262 }
3263 break;
3264
3265 /*
3266 * Here we are in the middle of a transaction block but one of the
3267 * commands caused an abort so we do nothing but remain in the
3268 * abort state. Eventually we will get a ROLLBACK command.
3269 */
3270 case TBLOCK_ABORT:
3271 case TBLOCK_SUBABORT:
3272 break;
3273
3274 /*
3275 * Here we were in an aborted transaction block and we just got
3276 * the ROLLBACK command from the user, so clean up the
3277 * already-aborted transaction and return to the idle state.
3278 */
3279 case TBLOCK_ABORT_END:
3282 if (s->chain)
3283 {
3286 s->chain = false;
3288 }
3289 break;
3290
3291 /*
3292 * Here we were in a perfectly good transaction block but the user
3293 * told us to ROLLBACK anyway. We have to abort the transaction
3294 * and then clean up.
3295 */
3300 if (s->chain)
3301 {
3304 s->chain = false;
3306 }
3307 break;
3308
3309 /*
3310 * We are completing a "PREPARE TRANSACTION" command. Do it and
3311 * return to the idle state.
3312 */
3313 case TBLOCK_PREPARE:
3316 break;
3317
3318 /*
3319 * The user issued a SAVEPOINT inside a transaction block. Start a
3320 * subtransaction. (DefineSavepoint already did PushTransaction,
3321 * so as to have someplace to put the SUBBEGIN state.)
3322 */
3323 case TBLOCK_SUBBEGIN:
3326 break;
3327
3328 /*
3329 * The user issued a RELEASE command, so we end the current
3330 * subtransaction and return to the parent transaction. The parent
3331 * might be ended too, so repeat till we find an INPROGRESS
3332 * transaction or subtransaction.
3333 */
3334 case TBLOCK_SUBRELEASE:
3335 do
3336 {
3338 s = CurrentTransactionState; /* changed by pop */
3339 } while (s->blockState == TBLOCK_SUBRELEASE);
3340
3343 break;
3344
3345 /*
3346 * The user issued a COMMIT, so we end the current subtransaction
3347 * hierarchy and perform final commit. We do this by rolling up
3348 * any subtransactions into their parent, which leads to O(N^2)
3349 * operations with respect to resource owners - this isn't that
3350 * bad until we approach a thousands of savepoints but is
3351 * necessary for correctness should after triggers create new
3352 * resource owners.
3353 */
3354 case TBLOCK_SUBCOMMIT:
3355 do
3356 {
3358 s = CurrentTransactionState; /* changed by pop */
3359 } while (s->blockState == TBLOCK_SUBCOMMIT);
3360 /* If we had a COMMIT command, finish off the main xact too */
3361 if (s->blockState == TBLOCK_END)
3362 {
3363 Assert(s->parent == NULL);
3366 if (s->chain)
3367 {
3370 s->chain = false;
3372 }
3373 }
3374 else if (s->blockState == TBLOCK_PREPARE)
3375 {
3376 Assert(s->parent == NULL);
3379 }
3380 else
3381 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3383 break;
3384
3385 /*
3386 * The current already-failed subtransaction is ending due to a
3387 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3388 * examine the parent (which could be in any of several states).
3389 * As we need to examine the parent, return false to request the
3390 * caller to do the next iteration.
3391 */
3394 return false;
3395
3396 /*
3397 * As above, but it's not dead yet, so abort first.
3398 */
3402 return false;
3403
3404 /*
3405 * The current subtransaction is the target of a ROLLBACK TO
3406 * command. Abort and pop it, then start a new subtransaction
3407 * with the same name.
3408 */
3409 case TBLOCK_SUBRESTART:
3410 {
3411 char *name;
3412 int savepointLevel;
3413
3414 /* save name and keep Cleanup from freeing it */
3415 name = s->name;
3416 s->name = NULL;
3417 savepointLevel = s->savepointLevel;
3418
3421
3423 s = CurrentTransactionState; /* changed by push */
3424 s->name = name;
3425 s->savepointLevel = savepointLevel;
3426
3427 /* This is the same as TBLOCK_SUBBEGIN case */
3431 }
3432 break;
3433
3434 /*
3435 * Same as above, but the subtransaction had already failed, so we
3436 * don't need AbortSubTransaction.
3437 */
3439 {
3440 char *name;
3441 int savepointLevel;
3442
3443 /* save name and keep Cleanup from freeing it */
3444 name = s->name;
3445 s->name = NULL;
3446 savepointLevel = s->savepointLevel;
3447
3449
3451 s = CurrentTransactionState; /* changed by push */
3452 s->name = name;
3453 s->savepointLevel = savepointLevel;
3454
3455 /* This is the same as TBLOCK_SUBBEGIN case */
3459 }
3460 break;
3461 }
3462
3463 /* Done, no more iterations required */
3464 return true;
3465}

References AbortSubTransaction(), AbortTransaction(), Assert, TransactionStateData::blockState, BlockStateAsString(), TransactionStateData::chain, CleanupSubTransaction(), CleanupTransaction(), CommandCounterIncrement(), CommitSubTransaction(), CommitTransaction(), CurrentTransactionState, DefineSavepoint(), elog, ERROR, FATAL, fb(), TransactionStateData::name, name, TransactionStateData::parent, PrepareTransaction(), RestoreTransactionCharacteristics(), TransactionStateData::savepointLevel, SaveTransactionCharacteristics(), StartSubTransaction(), StartTransaction(), TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by CommitTransactionCommand().

◆ DefineSavepoint()

void DefineSavepoint ( const char name)

Definition at line 4396 of file xact.c.

4397{
4399
4400 /*
4401 * Workers synchronize transaction state at the beginning of each parallel
4402 * operation, so we can't account for new subtransactions after that
4403 * point. (Note that this check will certainly error out if s->blockState
4404 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4405 * below.)
4406 */
4408 ereport(ERROR,
4410 errmsg("cannot define savepoints during a parallel operation")));
4411
4412 switch (s->blockState)
4413 {
4414 case TBLOCK_INPROGRESS:
4416 /* Normal subtransaction start */
4418 s = CurrentTransactionState; /* changed by push */
4419
4420 /*
4421 * Savepoint names, like the TransactionState block itself, live
4422 * in TopTransactionContext.
4423 */
4424 if (name)
4426 break;
4427
4428 /*
4429 * We disallow savepoint commands in implicit transaction blocks.
4430 * There would be no great difficulty in allowing them so far as
4431 * this module is concerned, but a savepoint seems inconsistent
4432 * with exec_simple_query's behavior of abandoning the whole query
4433 * string upon error. Also, the point of an implicit transaction
4434 * block (as opposed to a regular one) is to automatically close
4435 * after an error, so it's hard to see how a savepoint would fit
4436 * into that.
4437 *
4438 * The error messages for this are phrased as if there were no
4439 * active transaction block at all, which is historical but
4440 * perhaps could be improved.
4441 */
4443 ereport(ERROR,
4445 /* translator: %s represents an SQL statement name */
4446 errmsg("%s can only be used in transaction blocks",
4447 "SAVEPOINT")));
4448 break;
4449
4450 /* These cases are invalid. */
4451 case TBLOCK_DEFAULT:
4452 case TBLOCK_STARTED:
4453 case TBLOCK_BEGIN:
4455 case TBLOCK_SUBBEGIN:
4456 case TBLOCK_END:
4457 case TBLOCK_SUBRELEASE:
4458 case TBLOCK_SUBCOMMIT:
4459 case TBLOCK_ABORT:
4460 case TBLOCK_SUBABORT:
4461 case TBLOCK_ABORT_END:
4465 case TBLOCK_SUBRESTART:
4467 case TBLOCK_PREPARE:
4468 elog(FATAL, "DefineSavepoint: unexpected state %s",
4470 break;
4471 }
4472}

References TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg, ERROR, FATAL, fb(), IsInParallelMode(), IsParallelWorker, MemoryContextStrdup(), TransactionStateData::name, name, PushTransaction(), TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, TBLOCK_SUBRESTART, and TopTransactionContext.

Referenced by CommitTransactionCommandInternal(), pa_start_subtrans(), and standard_ProcessUtility().

◆ EndImplicitTransactionBlock()

void EndImplicitTransactionBlock ( void  )

Definition at line 4374 of file xact.c.

4375{
4377
4378 /*
4379 * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4380 * allowing CommitTransactionCommand to commit whatever happened during
4381 * the implicit transaction block as though it were a single statement.
4382 *
4383 * For caller convenience, we consider all other transaction states as
4384 * legal here; otherwise the caller would need its own state check, which
4385 * seems rather pointless.
4386 */
4389}

References TransactionStateData::blockState, CurrentTransactionState, TBLOCK_IMPLICIT_INPROGRESS, and TBLOCK_STARTED.

Referenced by exec_simple_query(), and PostgresMain().

◆ EndParallelWorkerTransaction()

◆ EndTransactionBlock()

bool EndTransactionBlock ( bool  chain)

Definition at line 4067 of file xact.c.

4068{
4070 bool result = false;
4071
4072 switch (s->blockState)
4073 {
4074 /*
4075 * We are in a transaction block, so tell CommitTransactionCommand
4076 * to COMMIT.
4077 */
4078 case TBLOCK_INPROGRESS:
4080 result = true;
4081 break;
4082
4083 /*
4084 * We are in an implicit transaction block. If AND CHAIN was
4085 * specified, error. Otherwise commit, but issue a warning
4086 * because there was no explicit BEGIN before this.
4087 */
4089 if (chain)
4090 ereport(ERROR,
4092 /* translator: %s represents an SQL statement name */
4093 errmsg("%s can only be used in transaction blocks",
4094 "COMMIT AND CHAIN")));
4095 else
4098 errmsg("there is no transaction in progress")));
4100 result = true;
4101 break;
4102
4103 /*
4104 * We are in a failed transaction block. Tell
4105 * CommitTransactionCommand it's time to exit the block.
4106 */
4107 case TBLOCK_ABORT:
4109 break;
4110
4111 /*
4112 * We are in a live subtransaction block. Set up to subcommit all
4113 * open subtransactions and then commit the main transaction.
4114 */
4116 while (s->parent != NULL)
4117 {
4120 else
4121 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4123 s = s->parent;
4124 }
4125 if (s->blockState == TBLOCK_INPROGRESS)
4127 else
4128 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4130 result = true;
4131 break;
4132
4133 /*
4134 * Here we are inside an aborted subtransaction. Treat the COMMIT
4135 * as ROLLBACK: set up to abort everything and exit the main
4136 * transaction.
4137 */
4138 case TBLOCK_SUBABORT:
4139 while (s->parent != NULL)
4140 {
4143 else if (s->blockState == TBLOCK_SUBABORT)
4145 else
4146 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4148 s = s->parent;
4149 }
4150 if (s->blockState == TBLOCK_INPROGRESS)
4152 else if (s->blockState == TBLOCK_ABORT)
4154 else
4155 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4157 break;
4158
4159 /*
4160 * The user issued COMMIT when not inside a transaction. For
4161 * COMMIT without CHAIN, issue a WARNING, staying in
4162 * TBLOCK_STARTED state. The upcoming call to
4163 * CommitTransactionCommand() will then close the transaction and
4164 * put us back into the default state. For COMMIT AND CHAIN,
4165 * error.
4166 */
4167 case TBLOCK_STARTED:
4168 if (chain)
4169 ereport(ERROR,
4171 /* translator: %s represents an SQL statement name */
4172 errmsg("%s can only be used in transaction blocks",
4173 "COMMIT AND CHAIN")));
4174 else
4177 errmsg("there is no transaction in progress")));
4178 result = true;
4179 break;
4180
4181 /*
4182 * The user issued a COMMIT that somehow ran inside a parallel
4183 * worker. We can't cope with that.
4184 */
4186 ereport(FATAL,
4188 errmsg("cannot commit during a parallel operation")));
4189 break;
4190
4191 /* These cases are invalid. */
4192 case TBLOCK_DEFAULT:
4193 case TBLOCK_BEGIN:
4194 case TBLOCK_SUBBEGIN:
4195 case TBLOCK_END:
4196 case TBLOCK_SUBRELEASE:
4197 case TBLOCK_SUBCOMMIT:
4198 case TBLOCK_ABORT_END:
4202 case TBLOCK_SUBRESTART:
4204 case TBLOCK_PREPARE:
4205 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4207 break;
4208 }
4209
4211 s->blockState == TBLOCK_END ||
4214
4215 s->chain = chain;
4216
4217 return result;
4218}

References Assert, TransactionStateData::blockState, BlockStateAsString(), TransactionStateData::chain, CurrentTransactionState, elog, ereport, errcode(), errmsg, ERROR, FATAL, fb(), TransactionStateData::parent, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, TBLOCK_SUBRESTART, and WARNING.

Referenced by apply_handle_commit_internal(), pa_stream_abort(), PrepareTransactionBlock(), and standard_ProcessUtility().

◆ EnterParallelMode()

◆ EstimateTransactionStateSpace()

◆ ExitParallelMode()

◆ ForceSyncCommit()

void ForceSyncCommit ( void  )

Definition at line 1154 of file xact.c.

1155{
1156 forceSyncCommit = true;
1157}

References forceSyncCommit.

Referenced by createdb(), CreateTableSpace(), dropdb(), DropTableSpace(), and movedb().

◆ GetCurrentCommandId()

CommandId GetCurrentCommandId ( bool  used)

Definition at line 831 of file xact.c.

832{
833 /* this is global to a transaction, not subtransaction-local */
834 if (used)
835 {
836 /*
837 * Forbid setting currentCommandIdUsed in a parallel worker, because
838 * we have no provision for communicating this back to the leader. We
839 * could relax this restriction when currentCommandIdUsed was already
840 * true at the start of the parallel operation.
841 */
842 if (IsParallelWorker())
845 errmsg("cannot modify data in a parallel worker")));
846
848 }
849 return currentCommandId;
850}

References currentCommandId, currentCommandIdUsed, ereport, errcode(), errmsg, ERROR, fb(), and IsParallelWorker.

Referenced by ATRewriteTable(), CatalogTuplesMultiInsertWithInfo(), CopyFrom(), create_edata_for_relation(), create_estate_for_relation(), FindConflictTuple(), GetSnapshotData(), GetSnapshotDataReuse(), heap_inplace_lock(), intorel_startup(), MergePartitionsMoveRows(), pgrowlocks(), RegisterRelcacheInvalidation(), RelationFindReplTupleByIndex(), RelationFindReplTupleSeq(), simple_heap_delete(), simple_heap_insert(), simple_heap_update(), simple_table_tuple_delete(), simple_table_tuple_insert(), simple_table_tuple_update(), SplitPartitionMoveRows(), standard_ExecutorStart(), toast_save_datum(), transientrel_startup(), and UpdateActiveSnapshotCommandId().

◆ GetCurrentFullTransactionId()

◆ GetCurrentFullTransactionIdIfAny()

FullTransactionId GetCurrentFullTransactionIdIfAny ( void  )

Definition at line 532 of file xact.c.

References CurrentTransactionState, and TransactionStateData::fullTransactionId.

◆ GetCurrentStatementStartTimestamp()

TimestampTz GetCurrentStatementStartTimestamp ( void  )

◆ GetCurrentSubTransactionId()

◆ GetCurrentTransactionId()

◆ GetCurrentTransactionIdIfAny()

◆ GetCurrentTransactionNestLevel()

◆ GetCurrentTransactionStartTimestamp()

◆ GetCurrentTransactionStopTimestamp()

TimestampTz GetCurrentTransactionStopTimestamp ( void  )

Definition at line 893 of file xact.c.

894{
896
897 /* should only be called after commit / abort processing */
898 Assert(s->state == TRANS_DEFAULT ||
899 s->state == TRANS_COMMIT ||
900 s->state == TRANS_ABORT ||
901 s->state == TRANS_PREPARE);
902
903 if (xactStopTimestamp == 0)
905
906 return xactStopTimestamp;
907}

References Assert, CurrentTransactionState, GetCurrentTimestamp(), PG_USED_FOR_ASSERTS_ONLY, TRANS_ABORT, TRANS_COMMIT, TRANS_DEFAULT, TRANS_PREPARE, and xactStopTimestamp.

Referenced by pgstat_relation_flush_cb(), pgstat_report_stat(), RecordTransactionAbort(), and RecordTransactionCommit().

◆ GetStableLatestTransactionId()

◆ GetTopFullTransactionId()

◆ GetTopFullTransactionIdIfAny()

FullTransactionId GetTopFullTransactionIdIfAny ( void  )

Definition at line 501 of file xact.c.

502{
504}

References XactTopFullTransactionId.

Referenced by pg_current_xact_id_if_assigned().

◆ GetTopTransactionId()

◆ GetTopTransactionIdIfAny()

◆ IsAbortedTransactionBlockState()

◆ IsInParallelMode()

◆ IsInTransactionBlock()

bool IsInTransactionBlock ( bool  isTopLevel)

Definition at line 3792 of file xact.c.

3793{
3794 /*
3795 * Return true on same conditions that would make
3796 * PreventInTransactionBlock error out
3797 */
3798 if (IsTransactionBlock())
3799 return true;
3800
3801 if (IsSubTransaction())
3802 return true;
3803
3804 if (!isTopLevel)
3805 return true;
3806
3809 return true;
3810
3811 return false;
3812}

References TransactionStateData::blockState, CurrentTransactionState, fb(), IsSubTransaction(), IsTransactionBlock(), TBLOCK_DEFAULT, and TBLOCK_STARTED.

Referenced by vacuum().

◆ IsSubTransaction()

◆ IsSubxactTopXidLogPending()

bool IsSubxactTopXidLogPending ( void  )

Definition at line 561 of file xact.c.

562{
563 /* check whether it is already logged */
565 return false;
566
567 /* effective_wal_level has to be logical */
569 return false;
570
571 /* we need to be in a transaction state */
572 if (!IsTransactionState())
573 return false;
574
575 /* it has to be a subtransaction */
576 if (!IsSubTransaction())
577 return false;
578
579 /* the subtransaction has to have a XID assigned */
581 return false;
582
583 return true;
584}

References CurrentTransactionState, GetCurrentTransactionIdIfAny(), IsSubTransaction(), IsTransactionState(), TransactionStateData::topXidLogged, TransactionIdIsValid, and XLogLogicalInfoActive.

Referenced by MarkSubxactTopXidLogged(), and XLogRecordAssemble().

◆ IsTransactionBlock()

◆ IsTransactionOrTransactionBlock()

◆ IsTransactionState()

bool IsTransactionState ( void  )

Definition at line 389 of file xact.c.

390{
392
393 /*
394 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
395 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
396 * TRANS_PREPARE since it might be too soon or too late within those
397 * transition states to do anything interesting. Hence, the only "valid"
398 * state is TRANS_INPROGRESS.
399 */
400 return (s->state == TRANS_INPROGRESS);
401}

References CurrentTransactionState, TransactionStateData::state, and TRANS_INPROGRESS.

Referenced by AcceptInvalidationMessages(), apply_handle_commit_internal(), apply_handle_origin(), assign_transaction_timeout(), begin_replication_step(), check_client_encoding(), check_default_table_access_method(), check_default_tablespace(), check_default_text_search_config(), check_role(), check_session_authorization(), check_temp_tablespaces(), check_transaction_isolation(), check_transaction_read_only(), clear_subscription_skip_lsn(), ConditionalCatalogCacheInitializeCache(), CreateInitDecodingContext(), ensure_last_message(), FetchRelationStates(), FinishSyncWorker(), IsSubxactTopXidLogPending(), LogicalRepApplyLoop(), LogLogicalMessage(), maybe_reread_subscription(), pa_send_data(), pa_start_subtrans(), pg_do_encoding_conversion(), PrepareClientEncoding(), PrepareTempTablespaces(), ProcessSyncingTablesForApply(), ProcessSyncingTablesForSync(), RelationCacheInvalidate(), RelationFlushRelation(), RelationInitPhysicalAddr(), replorigin_create(), replorigin_drop_by_name(), ReplSlotSyncWorkerMain(), SetMultiXactIdLimit(), SetTransactionIdLimit(), SnapBuildClearExportedSnapshot(), SocketBackend(), stream_stop_internal(), SyncReplicationSlots(), update_retention_status(), and validate_remote_info().

◆ MarkCurrentTransactionIdLoggedIfAny()

◆ MarkSubxactTopXidLogged()

void MarkSubxactTopXidLogged ( void  )

◆ PopTransaction()

static void PopTransaction ( void  )
static

Definition at line 5501 of file xact.c.

5502{
5504
5505 if (s->state != TRANS_DEFAULT)
5506 elog(WARNING, "PopTransaction while in %s state",
5508
5509 if (s->parent == NULL)
5510 elog(FATAL, "PopTransaction with no parent");
5511
5513
5514 /* Let's just make sure CurTransactionContext is good */
5517
5518 /* Ditto for ResourceOwner links */
5521
5522 /* Free the old child structure */
5523 if (s->name)
5524 pfree(s->name);
5525 pfree(s);
5526}

References CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, elog, FATAL, fb(), MemoryContextSwitchTo(), TransactionStateData::name, TransactionStateData::parent, pfree(), TransactionStateData::state, TRANS_DEFAULT, TransStateAsString(), and WARNING.

Referenced by CleanupSubTransaction(), and CommitSubTransaction().

◆ PrepareTransaction()

static void PrepareTransaction ( void  )
static

Definition at line 2530 of file xact.c.

2531{
2535 TimestampTz prepared_at;
2536
2538
2539 ShowTransactionState("PrepareTransaction");
2540
2541 /*
2542 * check the current transaction state
2543 */
2544 if (s->state != TRANS_INPROGRESS)
2545 elog(WARNING, "PrepareTransaction while in %s state",
2547 Assert(s->parent == NULL);
2548
2549 /*
2550 * Do pre-commit processing that involves calling user-defined code, such
2551 * as triggers. Since closing cursors could queue trigger actions,
2552 * triggers could open cursors, etc, we have to keep looping until there's
2553 * nothing left to do.
2554 */
2555 for (;;)
2556 {
2557 /*
2558 * Fire all currently pending deferred triggers.
2559 */
2561
2562 /*
2563 * Close open portals (converting holdable ones into static portals).
2564 * If there weren't any, we are done ... otherwise loop back to check
2565 * if they queued deferred triggers. Lather, rinse, repeat.
2566 */
2567 if (!PreCommit_Portals(true))
2568 break;
2569 }
2570
2572
2573 /*
2574 * The remaining actions cannot call any user-defined code, so it's safe
2575 * to start shutting down within-transaction services. But note that most
2576 * of this stuff could still throw an error, which would switch us into
2577 * the transaction-abort path.
2578 */
2579
2580 /* Shut down the deferred-trigger manager */
2581 AfterTriggerEndXact(true);
2582
2583 /*
2584 * Let ON COMMIT management do its thing (must happen after closing
2585 * cursors, to avoid dangling-reference problems)
2586 */
2588
2589 /*
2590 * Synchronize files that are created and not WAL-logged during this
2591 * transaction. This must happen before EndPrepare(), so that we don't see
2592 * committed-but-broken files after a crash and COMMIT PREPARED.
2593 */
2594 smgrDoPendingSyncs(true, false);
2595
2596 /* close large objects before lower-level cleanup */
2598
2599 /* NOTIFY requires no work at this point */
2600
2601 /*
2602 * Mark serializable transaction as complete for predicate locking
2603 * purposes. This should be done as late as we can put it and still allow
2604 * errors to be raised for failure patterns found at commit.
2605 */
2607
2608 /*
2609 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2610 * this transaction. Having the prepared xact hold locks on another
2611 * backend's temp table seems a bad idea --- for instance it would prevent
2612 * the backend from exiting. There are other problems too, such as how to
2613 * clean up the source backend's local buffers and ON COMMIT state if the
2614 * prepared xact includes a DROP of a temp table.
2615 *
2616 * Other objects types, like functions, operators or extensions, share the
2617 * same restriction as they should not be created, locked or dropped as
2618 * this can mess up with this session or even a follow-up session trying
2619 * to use the same temporary namespace.
2620 *
2621 * We must check this after executing any ON COMMIT actions, because they
2622 * might still access a temp relation.
2623 *
2624 * XXX In principle this could be relaxed to allow some useful special
2625 * cases, such as a temp table created and dropped all within the
2626 * transaction. That seems to require much more bookkeeping though.
2627 */
2629 ereport(ERROR,
2631 errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2632
2633 /*
2634 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2635 * supported if we added cleanup logic to twophase.c, but for now it
2636 * doesn't seem worth the trouble.
2637 */
2639 ereport(ERROR,
2641 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2642
2643 /* Prevent cancel/die interrupt while cleaning up */
2645
2646 /*
2647 * set the current transaction state information appropriately during
2648 * prepare processing
2649 */
2650 s->state = TRANS_PREPARE;
2651
2652 /* Disable transaction timeout */
2653 if (TransactionTimeout > 0)
2655
2656 prepared_at = GetCurrentTimestamp();
2657
2658 /*
2659 * Reserve the GID for this transaction. This could fail if the requested
2660 * GID is invalid or already in use.
2661 */
2662 gxact = MarkAsPreparing(fxid, prepareGID, prepared_at,
2664 prepareGID = NULL;
2665
2666 /*
2667 * Collect data for the 2PC state file. Note that in general, no actual
2668 * state change should happen in the called modules during this step,
2669 * since it's still possible to fail before commit, and in that case we
2670 * want transaction abort to be able to clean up. (In particular, the
2671 * AtPrepare routines may error out if they find cases they cannot
2672 * handle.) State cleanup should happen in the PostPrepare routines
2673 * below. However, some modules can go ahead and clear state here because
2674 * they wouldn't do anything with it during abort anyway.
2675 *
2676 * Note: because the 2PC state file records will be replayed in the same
2677 * order they are made, the order of these calls has to match the order in
2678 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2679 * PREPARED; in particular, pay attention to whether things should happen
2680 * before or after releasing the transaction's locks.
2681 */
2683
2690
2691 /*
2692 * Here is where we really truly prepare.
2693 *
2694 * We have to record transaction prepares even if we didn't make any
2695 * updates, because the transaction manager might get confused if we lose
2696 * a global transaction.
2697 */
2699
2700 /*
2701 * Now we clean up backend-internal state and release internal resources.
2702 */
2703
2704 /* Reset XactLastRecEnd until the next transaction writes something */
2705 XactLastRecEnd = 0;
2706
2707 /*
2708 * Transfer our locks to a dummy PGPROC. This has to be done before
2709 * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2710 * conclude "xact already committed or aborted" for our locks.
2711 */
2712 PostPrepare_Locks(fxid);
2713
2714 /*
2715 * Let others know about no transaction in progress by me. This has to be
2716 * done *after* the prepared transaction has been marked valid, else
2717 * someone may think it is unlocked and recyclable.
2718 */
2720
2721 /*
2722 * In normal commit-processing, this is all non-critical post-transaction
2723 * cleanup. When the transaction is prepared, however, it's important
2724 * that the locks and other per-backend resources are transferred to the
2725 * prepared transaction's PGPROC entry. Note that if an error is raised
2726 * here, it's too late to abort the transaction. XXX: This probably should
2727 * be in a critical section, to force a PANIC if any of this fails, but
2728 * that cure could be worse than the disease.
2729 */
2730
2732
2735 true, true);
2736
2737 AtEOXact_Aio(true);
2738
2739 /* Check we've released all buffer pins */
2740 AtEOXact_Buffers(true);
2741
2742 /* Clean up the relation cache */
2744
2745 /* Clean up the type cache */
2747
2748 /* notify doesn't need a postprepare call */
2749
2751
2753
2755
2757
2759
2762 true, true);
2765 true, true);
2766
2767 /*
2768 * Allow another backend to finish the transaction. After
2769 * PostPrepare_Twophase(), the transaction is completely detached from our
2770 * backend. The rest is just non-critical cleanup of backend-local state.
2771 */
2773
2774 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2775 AtEOXact_GUC(true, 1);
2776 AtEOXact_SPI(true);
2777 AtEOXact_Enum();
2779 AtEOXact_Namespace(true, false);
2780 AtEOXact_SMgr();
2781 AtEOXact_Files(true);
2783 AtEOXact_HashTables(true);
2784 /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2785 AtEOXact_Snapshot(true, true);
2786 /* we treat PREPARE as ROLLBACK so far as waking workers goes */
2791
2797
2799
2802 s->nestingLevel = 0;
2803 s->gucNestLevel = 0;
2804 s->childXids = NULL;
2805 s->nChildXids = 0;
2806 s->maxChildXids = 0;
2807
2810
2811 /*
2812 * done with 1st phase commit processing, set current transaction state
2813 * back to default
2814 */
2815 s->state = TRANS_DEFAULT;
2816
2818}

References AfterTriggerEndXact(), AfterTriggerFireDeferred(), Assert, AtCommit_Memory(), AtEOXact_Aio(), AtEOXact_ApplyLauncher(), AtEOXact_Buffers(), AtEOXact_ComboCid(), AtEOXact_Enum(), AtEOXact_Files(), AtEOXact_GUC(), AtEOXact_HashTables(), AtEOXact_LargeObject(), AtEOXact_LogicalCtl(), AtEOXact_LogicalRepWorkers(), AtEOXact_Namespace(), AtEOXact_on_commit_actions(), AtEOXact_RelationCache(), AtEOXact_SMgr(), AtEOXact_Snapshot(), AtEOXact_SPI(), AtEOXact_TypeCache(), AtPrepare_Locks(), AtPrepare_MultiXact(), AtPrepare_Notify(), AtPrepare_PgStat(), AtPrepare_PredicateLocks(), AtPrepare_RelationMap(), CallXactCallbacks(), TransactionStateData::childXids, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, disable_timeout(), elog, EndPrepare(), ereport, errcode(), errmsg, ERROR, fb(), TransactionStateData::fullTransactionId, GetCurrentFullTransactionId(), GetCurrentTimestamp(), GetUserId(), TransactionStateData::gucNestLevel, HOLD_INTERRUPTS, InvalidFullTransactionId, InvalidSubTransactionId, IsInParallelMode(), MarkAsPreparing(), TransactionStateData::maxChildXids, MyDatabaseId, MyProc, MyXactFlags, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, nParallelCurrentXids, TransactionStateData::parent, pgstat_report_xact_timestamp(), PostPrepare_Inval(), PostPrepare_Locks(), PostPrepare_MultiXact(), PostPrepare_PgStat(), PostPrepare_PredicateLocks(), PostPrepare_smgr(), PostPrepare_Twophase(), PreCommit_CheckForSerializationFailure(), PreCommit_on_commit_actions(), PreCommit_Portals(), prepareGID, ProcArrayClearTransaction(), RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerDelete(), ResourceOwnerRelease(), RESUME_INTERRUPTS, ShowTransactionState(), smgrDoPendingSyncs(), StartPrepare(), TransactionStateData::state, TransactionStateData::subTransactionId, TopTransactionResourceOwner, TRANS_DEFAULT, TRANS_INPROGRESS, TRANS_PREPARE, TRANSACTION_TIMEOUT, TransactionTimeout, TransStateAsString(), WARNING, XACT_EVENT_PRE_PREPARE, XACT_EVENT_PREPARE, XACT_FLAGS_ACCESSEDTEMPNAMESPACE, XactHasExportedSnapshots(), XactLastRecEnd, and XactTopFullTransactionId.

Referenced by CommitTransactionCommandInternal().

◆ PrepareTransactionBlock()

bool PrepareTransactionBlock ( const char gid)

Definition at line 4015 of file xact.c.

4016{
4018 bool result;
4019
4020 /* Set up to commit the current transaction */
4021 result = EndTransactionBlock(false);
4022
4023 /* If successful, change outer tblock state to PREPARE */
4024 if (result)
4025 {
4027
4028 while (s->parent != NULL)
4029 s = s->parent;
4030
4031 if (s->blockState == TBLOCK_END)
4032 {
4033 /* Save GID where PrepareTransaction can find it again */
4035
4037 }
4038 else
4039 {
4040 /*
4041 * ignore case where we are not in a transaction;
4042 * EndTransactionBlock already issued a warning.
4043 */
4046 /* Don't send back a PREPARE result tag... */
4047 result = false;
4048 }
4049 }
4050
4051 return result;
4052}

References Assert, TransactionStateData::blockState, CurrentTransactionState, EndTransactionBlock(), fb(), MemoryContextStrdup(), TransactionStateData::parent, prepareGID, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, and TopTransactionContext.

Referenced by apply_handle_prepare_internal(), and standard_ProcessUtility().

◆ PreventInTransactionBlock()

void PreventInTransactionBlock ( bool  isTopLevel,
const char stmtType 
)

Definition at line 3670 of file xact.c.

3671{
3672 /*
3673 * xact block already started?
3674 */
3675 if (IsTransactionBlock())
3676 ereport(ERROR,
3678 /* translator: %s represents an SQL statement name */
3679 errmsg("%s cannot run inside a transaction block",
3680 stmtType)));
3681
3682 /*
3683 * subtransaction?
3684 */
3685 if (IsSubTransaction())
3686 ereport(ERROR,
3688 /* translator: %s represents an SQL statement name */
3689 errmsg("%s cannot run inside a subtransaction",
3690 stmtType)));
3691
3692 /*
3693 * inside a function call?
3694 */
3695 if (!isTopLevel)
3696 ereport(ERROR,
3698 /* translator: %s represents an SQL statement name */
3699 errmsg("%s cannot be executed from a function or procedure",
3700 stmtType)));
3701
3702 /* If we got past IsTransactionBlock test, should be in default state */
3705 elog(FATAL, "cannot prevent transaction chain");
3706
3707 /* All okay. Set the flag to make sure the right thing happens later. */
3709}

References TransactionStateData::blockState, CurrentTransactionState, elog, ereport, errcode(), errmsg, ERROR, FATAL, fb(), IsSubTransaction(), IsTransactionBlock(), MyXactFlags, TBLOCK_DEFAULT, TBLOCK_STARTED, and XACT_FLAGS_NEEDIMMEDIATECOMMIT.

Referenced by AlterDatabase(), AlterSubscription(), CheckAlterSubOption(), CreateSubscription(), DiscardAll(), DropSubscription(), exec_replication_command(), ExecDropStmt(), ExecReindex(), ExecRepack(), ProcessUtilitySlow(), ReindexPartitions(), standard_ProcessUtility(), and vacuum().

◆ PushTransaction()

static void PushTransaction ( void  )
static

Definition at line 5439 of file xact.c.

5440{
5443
5444 /*
5445 * We keep subtransaction state nodes in TopTransactionContext.
5446 */
5447 s = (TransactionState)
5449 sizeof(TransactionStateData));
5450
5451 /*
5452 * Assign a subtransaction ID, watching out for counter wraparound.
5453 */
5456 {
5458 pfree(s);
5459 ereport(ERROR,
5461 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5462 }
5463
5464 /*
5465 * We can now stack a minimally valid subtransaction without fear of
5466 * failure.
5467 */
5468 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5470 s->parent = p;
5471 s->nestingLevel = p->nestingLevel + 1;
5474 s->state = TRANS_DEFAULT;
5479 s->parallelModeLevel = 0;
5481 s->topXidLogged = false;
5482
5484
5485 /*
5486 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5487 * with the subtransaction from here on out; in particular they should not
5488 * assume that it necessarily has a transaction context, resource owner,
5489 * or XID.
5490 */
5491}

References TransactionStateData::blockState, currentSubTransactionId, CurrentTransactionState, ereport, errcode(), errmsg, ERROR, fb(), TransactionStateData::fullTransactionId, GetUserIdAndSecContext(), TransactionStateData::gucNestLevel, InvalidFullTransactionId, InvalidSubTransactionId, MemoryContextAllocZero(), TransactionStateData::nestingLevel, NewGUCNestLevel(), TransactionStateData::parallelChildXact, TransactionStateData::parallelModeLevel, TransactionStateData::parent, pfree(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, TransactionStateData::prevXactReadOnly, TransactionStateData::savepointLevel, TransactionStateData::startedInRecovery, TransactionStateData::state, TransactionStateData::subTransactionId, TBLOCK_SUBBEGIN, TopTransactionContext, TransactionStateData::topXidLogged, TRANS_DEFAULT, and XactReadOnly.

Referenced by BeginInternalSubTransaction(), and DefineSavepoint().

◆ RecordTransactionAbort()

static TransactionId RecordTransactionAbort ( bool  isSubXact)
static

Definition at line 1768 of file xact.c.

1769{
1772 int nrels;
1773 RelFileLocator *rels;
1774 int ndroppedstats = 0;
1776 int nchildren;
1777 TransactionId *children;
1778 TimestampTz xact_time;
1779 bool replorigin;
1780
1781 /*
1782 * If we haven't been assigned an XID, nobody will care whether we aborted
1783 * or not. Hence, we're done in that case. It does not matter if we have
1784 * rels to delete (note that this routine is not responsible for actually
1785 * deleting 'em). We cannot have any child XIDs, either.
1786 */
1787 if (!TransactionIdIsValid(xid))
1788 {
1789 /* Reset XactLastRecEnd until the next transaction writes something */
1790 if (!isSubXact)
1791 XactLastRecEnd = 0;
1792 return InvalidTransactionId;
1793 }
1794
1795 /*
1796 * We have a valid XID, so we should write an ABORT record for it.
1797 *
1798 * We do not flush XLOG to disk here, since the default assumption after a
1799 * crash would be that we aborted, anyway. For the same reason, we don't
1800 * need to worry about interlocking against checkpoint start.
1801 */
1802
1803 /*
1804 * Check that we haven't aborted halfway through RecordTransactionCommit.
1805 */
1806 if (TransactionIdDidCommit(xid))
1807 elog(PANIC, "cannot abort transaction %u, it was already committed",
1808 xid);
1809
1810 /*
1811 * Are we using the replication origins feature? Or, in other words, are
1812 * we replaying remote actions?
1813 */
1816
1817 /* Fetch the data we need for the abort record */
1818 nrels = smgrGetPendingDeletes(false, &rels);
1821
1822 /* XXX do we really need a critical section here? */
1824
1825 /* Write the ABORT record */
1826 if (isSubXact)
1827 xact_time = GetCurrentTimestamp();
1828 else
1829 {
1831 }
1832
1833 XactLogAbortRecord(xact_time,
1834 nchildren, children,
1835 nrels, rels,
1838 NULL);
1839
1840 if (replorigin)
1841 /* Move LSNs forward for this replication origin */
1844
1845 /*
1846 * Report the latest async abort LSN, so that the WAL writer knows to
1847 * flush this abort. There's nothing to be gained by delaying this, since
1848 * WALWriter may as well do this when it can. This is important with
1849 * streaming replication because if we don't flush WAL regularly we will
1850 * find that large aborts leave us with a long backlog for when commits
1851 * occur after the abort, increasing our window of data loss should
1852 * problems occur at that point.
1853 */
1854 if (!isSubXact)
1856
1857 /*
1858 * Mark the transaction aborted in clog. This is not absolutely necessary
1859 * but we may as well do it while we are here; also, in the subxact case
1860 * it is helpful because XactLockTableWait makes use of it to avoid
1861 * waiting for already-aborted subtransactions. It is OK to do it without
1862 * having flushed the ABORT record to disk, because in event of a crash
1863 * we'd be assumed to have aborted anyway.
1864 */
1865 TransactionIdAbortTree(xid, nchildren, children);
1866
1868
1869 /* Compute latestXid while we have the child XIDs handy */
1870 latestXid = TransactionIdLatest(xid, nchildren, children);
1871
1872 /*
1873 * If we're aborting a subtransaction, we can immediately remove failed
1874 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1875 * subxacts, because we already have the child XID array at hand. For
1876 * main xacts, the equivalent happens just after this function returns.
1877 */
1878 if (isSubXact)
1880
1881 /* Reset XactLastRecEnd until the next transaction writes something */
1882 if (!isSubXact)
1883 XactLastRecEnd = 0;
1884
1885 /* And clean up local data */
1886 if (rels)
1887 pfree(rels);
1888 if (ndroppedstats)
1890
1891 return latestXid;
1892}

References DoNotReplicateId, elog, END_CRIT_SECTION, fb(), GetCurrentTimestamp(), GetCurrentTransactionIdIfAny(), GetCurrentTransactionStopTimestamp(), InvalidReplOriginId, InvalidTransactionId, MyXactFlags, ReplOriginXactState::origin, ReplOriginXactState::origin_lsn, PANIC, pfree(), pgstat_get_transactional_drops(), replorigin_session_advance(), replorigin_xact_state, smgrGetPendingDeletes(), START_CRIT_SECTION, TransactionIdAbortTree(), TransactionIdDidCommit(), TransactionIdIsValid, TransactionIdLatest(), xactGetCommittedChildren(), XactLastRecEnd, XactLogAbortRecord(), XidCacheRemoveRunningXids(), and XLogSetAsyncXactLSN().

Referenced by AbortSubTransaction(), and AbortTransaction().

◆ RecordTransactionCommit()

static TransactionId RecordTransactionCommit ( void  )
static

Definition at line 1317 of file xact.c.

1318{
1322 int nrels;
1323 RelFileLocator *rels;
1324 int nchildren;
1325 TransactionId *children;
1326 int ndroppedstats = 0;
1328 int nmsgs = 0;
1330 bool RelcacheInitFileInval = false;
1331 bool wrote_xlog;
1332
1333 /*
1334 * Log pending invalidations for logical decoding of in-progress
1335 * transactions. Normally for DDLs, we log this at each command end,
1336 * however, for certain cases where we directly update the system table
1337 * without a transaction block, the invalidations are not logged till this
1338 * time.
1339 */
1342
1343 /* Get data needed for commit record */
1344 nrels = smgrGetPendingDeletes(true, &rels);
1349 &RelcacheInitFileInval);
1350 wrote_xlog = (XactLastRecEnd != 0);
1351
1352 /*
1353 * If we haven't been assigned an XID yet, we neither can, nor do we want
1354 * to write a COMMIT record.
1355 */
1356 if (!markXidCommitted)
1357 {
1358 /*
1359 * We expect that every RelationDropStorage is followed by a catalog
1360 * update, and hence XID assignment, so we shouldn't get here with any
1361 * pending deletes. Same is true for dropping stats.
1362 *
1363 * Use a real test not just an Assert to check this, since it's a bit
1364 * fragile.
1365 */
1366 if (nrels != 0 || ndroppedstats != 0)
1367 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
1368
1369 /* Can't have child XIDs either; AssignTransactionId enforces this */
1370 Assert(nchildren == 0);
1371
1372 /*
1373 * Transactions without an assigned xid can contain invalidation
1374 * messages. While inplace updates do this, this is not known to be
1375 * necessary; see comment at inplace CacheInvalidateHeapTuple().
1376 * Extensions might still rely on this capability, and standbys may
1377 * need to process those invals. We can't emit a commit record
1378 * without an xid, and we don't want to force assigning an xid,
1379 * because that'd be problematic for e.g. vacuum. Hence we emit a
1380 * bespoke record for the invalidations. We don't want to use that in
1381 * case a commit record is emitted, so they happen synchronously with
1382 * commits (besides not wanting to emit more WAL records).
1383 *
1384 * XXX Every known use of this capability is a defect. Since an XID
1385 * isn't controlling visibility of the change that prompted invals,
1386 * other sessions need the inval even if this transactions aborts.
1387 *
1388 * ON COMMIT DELETE ROWS does a nontransactional index_build(), which
1389 * queues a relcache inval, including in transactions without an xid
1390 * that had read the (empty) table. Standbys don't need any ON COMMIT
1391 * DELETE ROWS invals, but we've not done the work to withhold them.
1392 */
1393 if (nmsgs != 0)
1394 {
1396 RelcacheInitFileInval);
1397 wrote_xlog = true; /* not strictly necessary */
1398 }
1399
1400 /*
1401 * If we didn't create XLOG entries, we're done here; otherwise we
1402 * should trigger flushing those entries the same as a commit record
1403 * would. This will primarily happen for HOT pruning and the like; we
1404 * want these to be flushed to disk in due time.
1405 */
1406 if (!wrote_xlog)
1407 goto cleanup;
1408 }
1409 else
1410 {
1411 bool replorigin;
1412
1413 /*
1414 * Are we using the replication origins feature? Or, in other words,
1415 * are we replaying remote actions?
1416 */
1419
1420 /*
1421 * Mark ourselves as within our "commit critical section". This
1422 * forces any concurrent checkpoint to wait until we've updated
1423 * pg_xact. Without this, it is possible for the checkpoint to set
1424 * REDO after the XLOG record but fail to flush the pg_xact update to
1425 * disk, leading to loss of the transaction commit if the system
1426 * crashes a little later.
1427 *
1428 * Note: we could, but don't bother to, set this flag in
1429 * RecordTransactionAbort. That's because loss of a transaction abort
1430 * is noncritical; the presumption would be that it aborted, anyway.
1431 *
1432 * It's safe to change the delayChkptFlags flag of our own backend
1433 * without holding the ProcArrayLock, since we're the only one
1434 * modifying it. This makes checkpoint's determination of which xacts
1435 * are delaying the checkpoint a bit fuzzy, but it doesn't matter.
1436 *
1437 * Note, it is important to get the commit timestamp after marking the
1438 * transaction in the commit critical section. See
1439 * RecordTransactionCommitPrepared.
1440 */
1444
1446
1447 /*
1448 * Ensures the DELAY_CHKPT_IN_COMMIT flag write is globally visible
1449 * before commit time is written.
1450 */
1452
1453 /*
1454 * Insert the commit XLOG record.
1455 */
1457 nchildren, children, nrels, rels,
1459 nmsgs, invalMessages,
1460 RelcacheInitFileInval,
1462 InvalidTransactionId, NULL /* plain commit */ );
1463
1464 if (replorigin)
1465 /* Move LSNs forward for this replication origin */
1468
1469 /*
1470 * Record commit timestamp. The value comes from plain commit
1471 * timestamp if there's no replication origin; otherwise, the
1472 * timestamp was already set in replorigin_xact_state.origin_timestamp
1473 * by replication.
1474 *
1475 * We don't need to WAL-log anything here, as the commit record
1476 * written above already contains the data.
1477 */
1478
1481
1485 }
1486
1487 /*
1488 * Check if we want to commit asynchronously. We can allow the XLOG flush
1489 * to happen asynchronously if synchronous_commit=off, or if the current
1490 * transaction has not performed any WAL-logged operation or didn't assign
1491 * an xid. The transaction can end up not writing any WAL, even if it has
1492 * an xid, if it only wrote to temporary and/or unlogged tables. It can
1493 * end up having written WAL without an xid if it did HOT pruning. In
1494 * case of a crash, the loss of such a transaction will be irrelevant;
1495 * temp tables will be lost anyway, unlogged tables will be truncated and
1496 * HOT pruning will be done again later. (Given the foregoing, you might
1497 * think that it would be unnecessary to emit the XLOG record at all in
1498 * this case, but we don't currently try to do that. It would certainly
1499 * cause problems at least in Hot Standby mode, where the
1500 * KnownAssignedXids machinery requires tracking every XID assignment. It
1501 * might be OK to skip it only when wal_level < replica, but for now we
1502 * don't.)
1503 *
1504 * However, if we're doing cleanup of any non-temp rels or committing any
1505 * command that wanted to force sync commit, then we must flush XLOG
1506 * immediately. (We must not allow asynchronous commit if there are any
1507 * non-temp tables to be deleted, because we might delete the files before
1508 * the COMMIT record is flushed to disk. We do allow asynchronous commit
1509 * if all to-be-deleted tables are temporary though, since they are lost
1510 * anyway if we crash.)
1511 */
1512 if ((wrote_xlog && markXidCommitted &&
1514 forceSyncCommit || nrels > 0)
1515 {
1517
1518 /*
1519 * Now we may update the CLOG, if we wrote a COMMIT record above
1520 */
1521 if (markXidCommitted)
1522 TransactionIdCommitTree(xid, nchildren, children);
1523 }
1524 else
1525 {
1526 /*
1527 * Asynchronous commit case:
1528 *
1529 * This enables possible committed transaction loss in the case of a
1530 * postmaster crash because WAL buffers are left unwritten. Ideally we
1531 * could issue the WAL write without the fsync, but some
1532 * wal_sync_methods do not allow separate write/fsync.
1533 *
1534 * Report the latest async commit LSN, so that the WAL writer knows to
1535 * flush this commit.
1536 */
1538
1539 /*
1540 * We must not immediately update the CLOG, since we didn't flush the
1541 * XLOG. Instead, we store the LSN up to which the XLOG must be
1542 * flushed before the CLOG may be updated.
1543 */
1544 if (markXidCommitted)
1546 }
1547
1548 /*
1549 * If we entered a commit critical section, leave it now, and let
1550 * checkpoints proceed.
1551 */
1552 if (markXidCommitted)
1553 {
1556 }
1557
1558 /* Compute latestXid while we have the child XIDs handy */
1559 latestXid = TransactionIdLatest(xid, nchildren, children);
1560
1561 /*
1562 * Wait for synchronous replication, if required. Similar to the decision
1563 * above about using committing asynchronously we only want to wait if
1564 * this backend assigned an xid and wrote WAL. No need to wait if an xid
1565 * was assigned due to temporary/unlogged tables or due to HOT pruning.
1566 *
1567 * Note that at this stage we have marked clog, but still show as running
1568 * in the procarray and continue to hold locks.
1569 */
1572
1573 /* remember end of last commit record */
1575
1576 /* Reset XactLastRecEnd until the next transaction writes something */
1577 XactLastRecEnd = 0;
1578cleanup:
1579 /* Clean up local data */
1580 if (rels)
1581 pfree(rels);
1582 if (ndroppedstats)
1584
1585 return latestXid;
1586}

References Assert, cleanup(), DELAY_CHKPT_IN_COMMIT, PGPROC::delayChkptFlags, DoNotReplicateId, elog, END_CRIT_SECTION, ERROR, fb(), forceSyncCommit, GetCurrentTransactionStopTimestamp(), GetTopTransactionIdIfAny(), InvalidReplOriginId, InvalidTransactionId, LogLogicalInvalidations(), LogStandbyInvalidations(), MyProc, MyXactFlags, ReplOriginXactState::origin, ReplOriginXactState::origin_lsn, ReplOriginXactState::origin_timestamp, pfree(), pg_write_barrier, pgstat_get_transactional_drops(), replorigin_session_advance(), replorigin_xact_state, smgrGetPendingDeletes(), START_CRIT_SECTION, synchronous_commit, SYNCHRONOUS_COMMIT_OFF, SyncRepWaitForLSN(), TransactionIdAsyncCommitTree(), TransactionIdCommitTree(), TransactionIdIsValid, TransactionIdLatest(), TransactionTreeSetCommitTsData(), xactGetCommittedChildren(), xactGetCommittedInvalidationMessages(), XactLastCommitEnd, XactLastRecEnd, XactLogCommitRecord(), xactStopTimestamp, XLogFlush(), XLogLogicalInfoActive, XLogSetAsyncXactLSN(), and XLogStandbyInfoActive.

Referenced by CommitTransaction().

◆ RegisterSubXactCallback()

void RegisterSubXactCallback ( SubXactCallback  callback,
void arg 
)

◆ RegisterXactCallback()

void RegisterXactCallback ( XactCallback  callback,
void arg 
)

◆ ReleaseCurrentSubTransaction()

void ReleaseCurrentSubTransaction ( void  )

Definition at line 4791 of file xact.c.

4792{
4794
4795 /*
4796 * We do not check for parallel mode here. It's permissible to start and
4797 * end "internal" subtransactions while in parallel mode, so long as no
4798 * new XIDs or command IDs are assigned.
4799 */
4800
4802 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4807 s = CurrentTransactionState; /* changed by pop */
4809}

References Assert, TransactionStateData::blockState, BlockStateAsString(), CommitSubTransaction(), CurrentTransactionState, CurTransactionContext, elog, ERROR, MemoryContextSwitchTo(), TransactionStateData::state, TBLOCK_SUBINPROGRESS, and TRANS_INPROGRESS.

Referenced by exec_stmt_block(), plperl_spi_exec(), plperl_spi_exec_prepared(), plperl_spi_fetchrow(), plperl_spi_prepare(), plperl_spi_query(), plperl_spi_query_prepared(), pltcl_subtrans_commit(), pltcl_subtransaction(), PLy_spi_subtransaction_commit(), and PLy_subtransaction_exit().

◆ ReleaseSavepoint()

void ReleaseSavepoint ( const char name)

Definition at line 4481 of file xact.c.

4482{
4484 TransactionState target,
4485 xact;
4486
4487 /*
4488 * Workers synchronize transaction state at the beginning of each parallel
4489 * operation, so we can't account for transaction state change after that
4490 * point. (Note that this check will certainly error out if s->blockState
4491 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4492 * below.)
4493 */
4495 ereport(ERROR,
4497 errmsg("cannot release savepoints during a parallel operation")));
4498
4499 switch (s->blockState)
4500 {
4501 /*
4502 * We can't release a savepoint if there is no savepoint defined.
4503 */
4504 case TBLOCK_INPROGRESS:
4505 ereport(ERROR,
4507 errmsg("savepoint \"%s\" does not exist", name)));
4508 break;
4509
4511 /* See comment about implicit transactions in DefineSavepoint */
4512 ereport(ERROR,
4514 /* translator: %s represents an SQL statement name */
4515 errmsg("%s can only be used in transaction blocks",
4516 "RELEASE SAVEPOINT")));
4517 break;
4518
4519 /*
4520 * We are in a non-aborted subtransaction. This is the only valid
4521 * case.
4522 */
4524 break;
4525
4526 /* These cases are invalid. */
4527 case TBLOCK_DEFAULT:
4528 case TBLOCK_STARTED:
4529 case TBLOCK_BEGIN:
4531 case TBLOCK_SUBBEGIN:
4532 case TBLOCK_END:
4533 case TBLOCK_SUBRELEASE:
4534 case TBLOCK_SUBCOMMIT:
4535 case TBLOCK_ABORT:
4536 case TBLOCK_SUBABORT:
4537 case TBLOCK_ABORT_END:
4541 case TBLOCK_SUBRESTART:
4543 case TBLOCK_PREPARE:
4544 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4546 break;
4547 }
4548
4549 for (target = s; target; target = target->parent)
4550 {
4551 if (target->name && strcmp(target->name, name) == 0)
4552 break;
4553 }
4554
4555 if (!target)
4556 ereport(ERROR,
4558 errmsg("savepoint \"%s\" does not exist", name)));
4559
4560 /* disallow crossing savepoint level boundaries */
4561 if (target->savepointLevel != s->savepointLevel)
4562 ereport(ERROR,
4564 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4565
4566 /*
4567 * Mark "commit pending" all subtransactions up to the target
4568 * subtransaction. The actual commits will happen when control gets to
4569 * CommitTransactionCommand.
4570 */
4572 for (;;)
4573 {
4574 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
4575 xact->blockState = TBLOCK_SUBRELEASE;
4576 if (xact == target)
4577 break;
4578 xact = xact->parent;
4579 Assert(xact);
4580 }
4581}

References Assert, TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg, ERROR, FATAL, fb(), IsInParallelMode(), IsParallelWorker, TransactionStateData::name, name, TransactionStateData::parent, TransactionStateData::savepointLevel, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by standard_ProcessUtility().

◆ RequireTransactionBlock()

void RequireTransactionBlock ( bool  isTopLevel,
const char stmtType 
)

Definition at line 3739 of file xact.c.

3740{
3741 CheckTransactionBlock(isTopLevel, true, stmtType);
3742}

References CheckTransactionBlock(), and fb().

Referenced by PerformCursorOpen(), and standard_ProcessUtility().

◆ RestoreTransactionCharacteristics()

◆ RollbackAndReleaseCurrentSubTransaction()

void RollbackAndReleaseCurrentSubTransaction ( void  )

Definition at line 4819 of file xact.c.

4820{
4822
4823 /*
4824 * We do not check for parallel mode here. It's permissible to start and
4825 * end "internal" subtransactions while in parallel mode, so long as no
4826 * new XIDs or command IDs are assigned.
4827 */
4828
4829 switch (s->blockState)
4830 {
4831 /* Must be in a subtransaction */
4833 case TBLOCK_SUBABORT:
4834 break;
4835
4836 /* These cases are invalid. */
4837 case TBLOCK_DEFAULT:
4838 case TBLOCK_STARTED:
4839 case TBLOCK_BEGIN:
4842 case TBLOCK_SUBBEGIN:
4843 case TBLOCK_INPROGRESS:
4844 case TBLOCK_END:
4845 case TBLOCK_SUBRELEASE:
4846 case TBLOCK_SUBCOMMIT:
4847 case TBLOCK_ABORT:
4848 case TBLOCK_ABORT_END:
4852 case TBLOCK_SUBRESTART:
4854 case TBLOCK_PREPARE:
4855 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4857 break;
4858 }
4859
4860 /*
4861 * Abort the current subtransaction, if needed.
4862 */
4865
4866 /* And clean it up, too */
4868
4869 s = CurrentTransactionState; /* changed by pop */
4875}

References AbortSubTransaction(), Assert, TransactionStateData::blockState, BlockStateAsString(), CleanupSubTransaction(), CurrentTransactionState, elog, FATAL, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by exec_stmt_block(), plperl_spi_exec(), plperl_spi_exec_prepared(), plperl_spi_fetchrow(), plperl_spi_prepare(), plperl_spi_query(), plperl_spi_query_prepared(), pltcl_subtrans_abort(), pltcl_subtransaction(), PLy_abort_open_subtransactions(), PLy_spi_subtransaction_abort(), PLy_subtransaction_exit(), ReorderBufferImmediateInvalidation(), and ReorderBufferProcessTXN().

◆ RollbackToSavepoint()

void RollbackToSavepoint ( const char name)

Definition at line 4590 of file xact.c.

4591{
4593 TransactionState target,
4594 xact;
4595
4596 /*
4597 * Workers synchronize transaction state at the beginning of each parallel
4598 * operation, so we can't account for transaction state change after that
4599 * point. (Note that this check will certainly error out if s->blockState
4600 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4601 * below.)
4602 */
4604 ereport(ERROR,
4606 errmsg("cannot rollback to savepoints during a parallel operation")));
4607
4608 switch (s->blockState)
4609 {
4610 /*
4611 * We can't rollback to a savepoint if there is no savepoint
4612 * defined.
4613 */
4614 case TBLOCK_INPROGRESS:
4615 case TBLOCK_ABORT:
4616 ereport(ERROR,
4618 errmsg("savepoint \"%s\" does not exist", name)));
4619 break;
4620
4622 /* See comment about implicit transactions in DefineSavepoint */
4623 ereport(ERROR,
4625 /* translator: %s represents an SQL statement name */
4626 errmsg("%s can only be used in transaction blocks",
4627 "ROLLBACK TO SAVEPOINT")));
4628 break;
4629
4630 /*
4631 * There is at least one savepoint, so proceed.
4632 */
4634 case TBLOCK_SUBABORT:
4635 break;
4636
4637 /* These cases are invalid. */
4638 case TBLOCK_DEFAULT:
4639 case TBLOCK_STARTED:
4640 case TBLOCK_BEGIN:
4642 case TBLOCK_SUBBEGIN:
4643 case TBLOCK_END:
4644 case TBLOCK_SUBRELEASE:
4645 case TBLOCK_SUBCOMMIT:
4646 case TBLOCK_ABORT_END:
4650 case TBLOCK_SUBRESTART:
4652 case TBLOCK_PREPARE:
4653 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4655 break;
4656 }
4657
4658 for (target = s; target; target = target->parent)
4659 {
4660 if (target->name && strcmp(target->name, name) == 0)
4661 break;
4662 }
4663
4664 if (!target)
4665 ereport(ERROR,
4667 errmsg("savepoint \"%s\" does not exist", name)));
4668
4669 /* disallow crossing savepoint level boundaries */
4670 if (target->savepointLevel != s->savepointLevel)
4671 ereport(ERROR,
4673 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4674
4675 /*
4676 * Mark "abort pending" all subtransactions up to the target
4677 * subtransaction. The actual aborts will happen when control gets to
4678 * CommitTransactionCommand.
4679 */
4681 for (;;)
4682 {
4683 if (xact == target)
4684 break;
4685 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4687 else if (xact->blockState == TBLOCK_SUBABORT)
4688 xact->blockState = TBLOCK_SUBABORT_END;
4689 else
4690 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4691 BlockStateAsString(xact->blockState));
4692 xact = xact->parent;
4693 Assert(xact);
4694 }
4695
4696 /* And mark the target as "restart pending" */
4697 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4698 xact->blockState = TBLOCK_SUBRESTART;
4699 else if (xact->blockState == TBLOCK_SUBABORT)
4700 xact->blockState = TBLOCK_SUBABORT_RESTART;
4701 else
4702 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4703 BlockStateAsString(xact->blockState));
4704}

References Assert, TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg, ERROR, FATAL, fb(), IsInParallelMode(), IsParallelWorker, TransactionStateData::name, name, TransactionStateData::parent, TransactionStateData::savepointLevel, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by pa_stream_abort(), and standard_ProcessUtility().

◆ SaveTransactionCharacteristics()

◆ SerializeTransactionState()

void SerializeTransactionState ( Size  maxsize,
char start_address 
)

Definition at line 5563 of file xact.c.

5564{
5566 Size nxids = 0;
5567 Size i = 0;
5568 TransactionId *workspace;
5570
5572
5573 result->xactIsoLevel = XactIsoLevel;
5576 result->currentFullTransactionId =
5579
5580 /*
5581 * If we're running in a parallel worker and launching a parallel worker
5582 * of our own, we can just pass along the information that was passed to
5583 * us.
5584 */
5585 if (nParallelCurrentXids > 0)
5586 {
5590 return;
5591 }
5592
5593 /*
5594 * OK, we need to generate a sorted list of XIDs that our workers should
5595 * view as current. First, figure out how many there are.
5596 */
5597 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5598 {
5600 nxids = add_size(nxids, 1);
5602 }
5604 <= maxsize);
5605
5606 /* Copy them to our scratch space. */
5607 workspace = palloc(nxids * sizeof(TransactionId));
5608 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5609 {
5611 workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5612 if (s->nChildXids > 0)
5613 memcpy(&workspace[i], s->childXids,
5614 s->nChildXids * sizeof(TransactionId));
5615 i += s->nChildXids;
5616 }
5617 Assert(i == nxids);
5618
5619 /* Sort them. */
5620 qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5621
5622 /* Copy data into output area. */
5623 result->nParallelCurrentXids = nxids;
5624 memcpy(&result->parallelCurrentXids[0], workspace,
5625 nxids * sizeof(TransactionId));
5626}

References add_size(), Assert, TransactionStateData::childXids, SerializedTransactionState::currentCommandId, currentCommandId, SerializedTransactionState::currentFullTransactionId, CurrentTransactionState, fb(), TransactionStateData::fullTransactionId, FullTransactionIdIsValid, i, TransactionStateData::nChildXids, nParallelCurrentXids, SerializedTransactionState::nParallelCurrentXids, palloc(), ParallelCurrentXids, SerializedTransactionState::parallelCurrentXids, TransactionStateData::parent, qsort, SerializedTransactionStateHeaderSize, SerializedTransactionState::topFullTransactionId, XactDeferrable, SerializedTransactionState::xactDeferrable, XactIsoLevel, SerializedTransactionState::xactIsoLevel, XactTopFullTransactionId, xidComparator(), and XidFromFullTransactionId.

Referenced by InitializeParallelDSM().

◆ SetCurrentStatementStartTimestamp()

◆ SetParallelStartTimestamps()

void SetParallelStartTimestamps ( TimestampTz  xact_ts,
TimestampTz  stmt_ts 
)

Definition at line 861 of file xact.c.

862{
864 xactStartTimestamp = xact_ts;
865 stmtStartTimestamp = stmt_ts;
866}

References Assert, IsParallelWorker, stmtStartTimestamp, and xactStartTimestamp.

Referenced by ParallelWorkerMain().

◆ ShowTransactionState()

static void ShowTransactionState ( const char str)
static

◆ ShowTransactionStateRec()

static void ShowTransactionStateRec ( const char str,
TransactionState  s 
)
static

Definition at line 5683 of file xact.c.

5684{
5686
5687 if (s->parent)
5688 {
5689 /*
5690 * Since this function recurses, it could be driven to stack overflow.
5691 * This is just a debugging aid, so we can leave out some details
5692 * instead of erroring out with check_stack_depth().
5693 */
5694 if (stack_is_too_deep())
5696 (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5697 str, s->nestingLevel)));
5698 else
5700 }
5701
5703 if (s->nChildXids > 0)
5704 {
5705 int i;
5706
5707 appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5708 for (i = 1; i < s->nChildXids; i++)
5709 appendStringInfo(&buf, " %u", s->childXids[i]);
5710 }
5712 (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5713 str, s->nestingLevel,
5714 s->name ? s->name : "unnamed",
5715 BlockStateAsString(s->blockState),
5717 XidFromFullTransactionId(s->fullTransactionId),
5718 s->subTransactionId,
5720 currentCommandIdUsed ? " (used)" : "",
5721 buf.data)));
5722 pfree(buf.data);
5723}

References appendStringInfo(), TransactionStateData::blockState, BlockStateAsString(), buf, TransactionStateData::childXids, currentCommandId, currentCommandIdUsed, DEBUG5, ereport, errmsg_internal(), TransactionStateData::fullTransactionId, i, initStringInfo(), TransactionStateData::name, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, TransactionStateData::parent, pfree(), ShowTransactionStateRec(), stack_is_too_deep(), TransactionStateData::state, str, TransactionStateData::subTransactionId, TransStateAsString(), and XidFromFullTransactionId.

Referenced by ShowTransactionState(), and ShowTransactionStateRec().

◆ StartParallelWorkerTransaction()

◆ StartSubTransaction()

static void StartSubTransaction ( void  )
static

Definition at line 5090 of file xact.c.

5091{
5093
5094 if (s->state != TRANS_DEFAULT)
5095 elog(WARNING, "StartSubTransaction while in %s state",
5097
5098 s->state = TRANS_START;
5099
5100 /*
5101 * Initialize subsystems for new subtransaction
5102 *
5103 * must initialize resource-management stuff first
5104 */
5108
5110
5111 /*
5112 * Call start-of-subxact callbacks
5113 */
5116
5117 ShowTransactionState("StartSubTransaction");
5118}

References AfterTriggerBeginSubXact(), AtSubStart_Memory(), AtSubStart_ResourceOwner(), CallSubXactCallbacks(), CurrentTransactionState, elog, TransactionStateData::parent, ShowTransactionState(), TransactionStateData::state, TransactionStateData::subTransactionId, SUBXACT_EVENT_START_SUB, TRANS_DEFAULT, TRANS_INPROGRESS, TRANS_START, TransStateAsString(), and WARNING.

Referenced by CommitTransactionCommandInternal().

◆ StartTransaction()

static void StartTransaction ( void  )
static

Definition at line 2078 of file xact.c.

2079{
2082
2083 /*
2084 * Let's just make sure the state stack is empty
2085 */
2088
2090
2091 /* check the current transaction state */
2092 Assert(s->state == TRANS_DEFAULT);
2093
2094 /*
2095 * Set the current transaction state information appropriately during
2096 * start processing. Note that once the transaction status is switched
2097 * this process cannot fail until the user ID and the security context
2098 * flags are fetched below.
2099 */
2100 s->state = TRANS_START;
2101 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
2102
2103 /* Determine if statements are logged in this transaction */
2105 (log_xact_sample_rate == 1 ||
2107
2108 /*
2109 * initialize current transaction state fields
2110 *
2111 * note: prevXactReadOnly is not used at the outermost level
2112 */
2113 s->nestingLevel = 1;
2114 s->gucNestLevel = 1;
2115 s->childXids = NULL;
2116 s->nChildXids = 0;
2117 s->maxChildXids = 0;
2118
2119 /*
2120 * Once the current user ID and the security context flags are fetched,
2121 * both will be properly reset even if transaction startup fails.
2122 */
2124
2125 /* SecurityRestrictionContext should never be set outside a transaction */
2126 Assert(s->prevSecContext == 0);
2127
2128 /*
2129 * Make sure we've reset xact state variables
2130 *
2131 * If recovery is still in progress, mark this transaction as read-only.
2132 * We have lower level defences in XLogInsert and elsewhere to stop us
2133 * from modifying data during recovery, but this gives the normal
2134 * indication to the user that the transaction is read-only.
2135 */
2136 if (RecoveryInProgress())
2137 {
2138 s->startedInRecovery = true;
2139 XactReadOnly = true;
2140 }
2141 else
2142 {
2143 s->startedInRecovery = false;
2145 }
2148 forceSyncCommit = false;
2149 MyXactFlags = 0;
2150
2151 /*
2152 * reinitialize within-transaction counters
2153 */
2157 currentCommandIdUsed = false;
2158
2159 /*
2160 * initialize reported xid accounting
2161 */
2162 nUnreportedXids = 0;
2163 s->didLogXid = false;
2164
2165 /*
2166 * must initialize resource-management stuff first
2167 */
2170
2171 /*
2172 * Assign a new LocalTransactionId, and combine it with the proc number to
2173 * form a virtual transaction id.
2174 */
2175 vxid.procNumber = MyProcNumber;
2177
2178 /*
2179 * Lock the virtual transaction id before we announce it in the proc array
2180 */
2182
2183 /*
2184 * Advertise it in the proc array. We assume assignment of
2185 * localTransactionId is atomic, and the proc number should be set
2186 * already.
2187 */
2190
2192
2193 /*
2194 * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2195 * be the same as the first command's statement_timestamp(), so don't do a
2196 * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2197 * for transactions started inside procedures (i.e., nonatomic SPI
2198 * contexts), we do need to advance the timestamp. Also, in a parallel
2199 * worker, the timestamp should already have been provided by a call to
2200 * SetParallelStartTimestamps().
2201 */
2202 if (!IsParallelWorker())
2203 {
2206 else
2208 }
2209 else
2212 /* Mark xactStopTimestamp as unset. */
2214
2215 /*
2216 * initialize other subsystems for new transaction
2217 */
2218 AtStart_GUC();
2219 AtStart_Cache();
2221
2222 /*
2223 * done with start processing, set current transaction state to "in
2224 * progress"
2225 */
2227
2228 /* Schedule transaction timeout */
2229 if (TransactionTimeout > 0)
2231
2232 ShowTransactionState("StartTransaction");
2233}

References AfterTriggerBeginXact(), Assert, AtStart_Cache(), AtStart_GUC(), AtStart_Memory(), AtStart_ResourceOwner(), TransactionStateData::childXids, currentCommandId, currentCommandIdUsed, currentSubTransactionId, CurrentTransactionState, DefaultXactDeferrable, DefaultXactIsoLevel, DefaultXactReadOnly, TransactionStateData::didLogXid, enable_timeout_after(), fb(), FirstCommandId, forceSyncCommit, TransactionStateData::fullTransactionId, FullTransactionIdIsValid, GetCurrentTimestamp(), GetNextLocalTransactionId(), GetUserIdAndSecContext(), TransactionStateData::gucNestLevel, InvalidFullTransactionId, IsParallelWorker, VirtualTransactionId::localTransactionId, log_xact_sample_rate, PGPROC::lxid, TransactionStateData::maxChildXids, MyProc, MyProcNumber, MyXactFlags, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, nUnreportedXids, pg_global_prng_state, pg_prng_double(), pgstat_report_xact_timestamp(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, VirtualTransactionId::procNumber, PGPROC::procNumber, RecoveryInProgress(), ShowTransactionState(), SPI_inside_nonatomic_context(), TransactionStateData::startedInRecovery, TransactionStateData::state, stmtStartTimestamp, TransactionStateData::subTransactionId, TopSubTransactionId, TopTransactionStateData, TRANS_DEFAULT, TRANS_INPROGRESS, TRANS_START, TRANSACTION_TIMEOUT, TransactionTimeout, VirtualXactLockTableInsert(), PGPROC::vxid, xact_is_sampled, XactDeferrable, XactIsoLevel, XactReadOnly, xactStartTimestamp, xactStopTimestamp, and XactTopFullTransactionId.

Referenced by _doSetFixedOutputState(), CommitTransactionCommandInternal(), IssueCommandPerBlob(), restore_toc_entry(), RestoreArchive(), StartParallelWorkerTransaction(), StartRestoreLOs(), and StartTransactionCommand().

◆ StartTransactionCommand()

void StartTransactionCommand ( void  )

Definition at line 3081 of file xact.c.

3082{
3084
3085 switch (s->blockState)
3086 {
3087 /*
3088 * if we aren't in a transaction block, we just do our usual start
3089 * transaction.
3090 */
3091 case TBLOCK_DEFAULT:
3094 break;
3095
3096 /*
3097 * We are somewhere in a transaction block or subtransaction and
3098 * about to start a new command. For now we do nothing, but
3099 * someday we may do command-local resource initialization. (Note
3100 * that any needed CommandCounterIncrement was done by the
3101 * previous CommitTransactionCommand.)
3102 */
3103 case TBLOCK_INPROGRESS:
3106 break;
3107
3108 /*
3109 * Here we are in a failed transaction block (one of the commands
3110 * caused an abort) so we do nothing but remain in the abort
3111 * state. Eventually we will get a ROLLBACK command which will
3112 * get us out of this state. (It is up to other code to ensure
3113 * that no commands other than ROLLBACK will be processed in these
3114 * states.)
3115 */
3116 case TBLOCK_ABORT:
3117 case TBLOCK_SUBABORT:
3118 break;
3119
3120 /* These cases are invalid. */
3121 case TBLOCK_STARTED:
3122 case TBLOCK_BEGIN:
3124 case TBLOCK_SUBBEGIN:
3125 case TBLOCK_END:
3126 case TBLOCK_SUBRELEASE:
3127 case TBLOCK_SUBCOMMIT:
3128 case TBLOCK_ABORT_END:
3132 case TBLOCK_SUBRESTART:
3134 case TBLOCK_PREPARE:
3135 elog(ERROR, "StartTransactionCommand: unexpected state %s",
3137 break;
3138 }
3139
3140 /*
3141 * We must switch to CurTransactionContext before returning. This is
3142 * already done if we called StartTransaction, otherwise not.
3143 */
3146}

References Assert, TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, CurTransactionContext, elog, ERROR, fb(), MemoryContextSwitchTo(), StartTransaction(), TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by _SPI_commit(), _SPI_rollback(), apply_handle_commit_internal(), ATExecDetachPartition(), autoprewarm_database_main(), bbsink_server_new(), begin_replication_step(), BeginInternalSubTransaction(), BootstrapModeMain(), clear_subscription_skip_lsn(), copy_sequences(), DefineIndex(), DisableSubscriptionAndExit(), do_autovacuum(), EventTriggerOnLogin(), exec_replication_command(), ExecRepack(), FetchRelationStates(), FinishSyncWorker(), get_database_list(), get_subscription_list(), IdentifySystem(), index_drop(), initialize_worker_spi(), InitializeLogRepWorker(), InitPostgres(), LogicalRepSyncSequences(), LogicalRepSyncTableStart(), maybe_reread_subscription(), movedb(), pa_start_subtrans(), ParallelApplyWorkerMain(), ParallelWorkerMain(), perform_work_item(), process_single_relation(), ProcessCatchupInterrupt(), ProcessIncomingNotify(), ProcessSyncingTablesForApply(), ProcessSyncingTablesForSync(), ReindexMultipleInternal(), ReindexRelationConcurrently(), RemoveTempRelationsCallback(), ReorderBufferProcessTXN(), ReplSlotSyncWorkerMain(), run_apply_worker(), shell_check_detail(), SnapBuildExportSnapshot(), start_xact_command(), update_retention_status(), vacuum(), vacuum_rel(), validate_remote_info(), and worker_spi_main().

◆ SubTransactionIsActive()

bool SubTransactionIsActive ( SubTransactionId  subxid)

Definition at line 807 of file xact.c.

808{
810
811 for (s = CurrentTransactionState; s != NULL; s = s->parent)
812 {
813 if (s->state == TRANS_ABORT)
814 continue;
815 if (s->subTransactionId == subxid)
816 return true;
817 }
818 return false;
819}

References CurrentTransactionState, fb(), TransactionStateData::parent, TransactionStateData::state, TransactionStateData::subTransactionId, and TRANS_ABORT.

◆ TransactionBlockStatusCode()

char TransactionBlockStatusCode ( void  )

Definition at line 5026 of file xact.c.

5027{
5029
5030 switch (s->blockState)
5031 {
5032 case TBLOCK_DEFAULT:
5033 case TBLOCK_STARTED:
5034 return 'I'; /* idle --- not in transaction */
5035 case TBLOCK_BEGIN:
5036 case TBLOCK_SUBBEGIN:
5037 case TBLOCK_INPROGRESS:
5041 case TBLOCK_END:
5042 case TBLOCK_SUBRELEASE:
5043 case TBLOCK_SUBCOMMIT:
5044 case TBLOCK_PREPARE:
5045 return 'T'; /* in transaction */
5046 case TBLOCK_ABORT:
5047 case TBLOCK_SUBABORT:
5048 case TBLOCK_ABORT_END:
5052 case TBLOCK_SUBRESTART:
5054 return 'E'; /* in failed transaction */
5055 }
5056
5057 /* should never get here */
5058 elog(FATAL, "invalid transaction block state: %s",
5060 return 0; /* keep compiler quiet */
5061}

References TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, FATAL, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by ReadyForQuery().

◆ TransactionIdIsCurrentTransactionId()

bool TransactionIdIsCurrentTransactionId ( TransactionId  xid)

Definition at line 943 of file xact.c.

944{
946
947 /*
948 * We always say that BootstrapTransactionId is "not my transaction ID"
949 * even when it is (ie, during bootstrap). Along with the fact that
950 * transam.c always treats BootstrapTransactionId as already committed,
951 * this causes the heapam_visibility.c routines to see all tuples as
952 * committed, which is what we need during bootstrap. (Bootstrap mode
953 * only inserts tuples, it never updates or deletes them, so all tuples
954 * can be presumed good immediately.)
955 *
956 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
957 * not my transaction ID, so we can just return "false" immediately for
958 * any non-normal XID.
959 */
960 if (!TransactionIdIsNormal(xid))
961 return false;
962
964 return true;
965
966 /*
967 * In parallel workers, the XIDs we must consider as current are stored in
968 * ParallelCurrentXids rather than the transaction-state stack. Note that
969 * the XIDs in this array are sorted numerically rather than according to
970 * transactionIdPrecedes order.
971 */
972 if (nParallelCurrentXids > 0)
973 {
974 int low,
975 high;
976
977 low = 0;
978 high = nParallelCurrentXids - 1;
979 while (low <= high)
980 {
981 int middle;
983
984 middle = low + (high - low) / 2;
986 if (probe == xid)
987 return true;
988 else if (probe < xid)
989 low = middle + 1;
990 else
991 high = middle - 1;
992 }
993 return false;
994 }
995
996 /*
997 * We will return true for the Xid of the current subtransaction, any of
998 * its subcommitted children, any of its parents, or any of their
999 * previously subcommitted children. However, a transaction being aborted
1000 * is no longer "current", even though it may still have an entry on the
1001 * state stack.
1002 */
1003 for (s = CurrentTransactionState; s != NULL; s = s->parent)
1004 {
1005 int low,
1006 high;
1007
1008 if (s->state == TRANS_ABORT)
1009 continue;
1011 continue; /* it can't have any child XIDs either */
1013 return true;
1014 /* As the childXids array is ordered, we can use binary search */
1015 low = 0;
1016 high = s->nChildXids - 1;
1017 while (low <= high)
1018 {
1019 int middle;
1021
1022 middle = low + (high - low) / 2;
1023 probe = s->childXids[middle];
1024 if (TransactionIdEquals(probe, xid))
1025 return true;
1026 else if (TransactionIdPrecedes(probe, xid))
1027 low = middle + 1;
1028 else
1029 high = middle - 1;
1030 }
1031 }
1032
1033 return false;
1034}

References TransactionStateData::childXids, CurrentTransactionState, fb(), TransactionStateData::fullTransactionId, FullTransactionIdIsValid, GetTopTransactionIdIfAny(), TransactionStateData::nChildXids, nParallelCurrentXids, ParallelCurrentXids, TransactionStateData::parent, TransactionStateData::state, TRANS_ABORT, TransactionIdEquals, TransactionIdIsNormal, TransactionIdPrecedes(), and XidFromFullTransactionId.

Referenced by compute_new_xmax_infomask(), Do_MultiXactIdWait(), DoesMultiXactIdConflict(), ExecCheckTupleVisible(), ExecMergeMatched(), ExecOnConflictLockRow(), FreezeMultiXactId(), get_xid_status(), heap_delete(), heap_inplace_lock(), heap_lock_tuple(), heap_update(), heapam_index_build_range_scan(), heapam_relation_copy_for_cluster(), heapam_scan_analyze_next_tuple(), heapam_tuple_lock(), HeapTupleCleanMoved(), HeapTupleHeaderAdjustCmax(), HeapTupleHeaderGetCmax(), HeapTupleHeaderGetCmin(), HeapTupleHeaderIsOnlyLocked(), HeapTupleSatisfiesDirty(), HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesSelf(), HeapTupleSatisfiesUpdate(), HeapTupleSatisfiesVacuumHorizon(), MultiXactIdIsRunning(), PredicateLockTID(), SnapBuildWaitSnapshot(), test_lockmode_for_conflict(), TransactionIdIsInProgress(), tts_buffer_is_current_xact_tuple(), and tts_heap_is_current_xact_tuple().

◆ TransactionStartedDuringRecovery()

bool TransactionStartedDuringRecovery ( void  )

Definition at line 1044 of file xact.c.

1045{
1047}

References CurrentTransactionState, and TransactionStateData::startedInRecovery.

Referenced by RelationGetIndexScan().

◆ TransStateAsString()

static const char * TransStateAsString ( TransState  state)
static

Definition at line 5783 of file xact.c.

5784{
5785 switch (state)
5786 {
5787 case TRANS_DEFAULT:
5788 return "DEFAULT";
5789 case TRANS_START:
5790 return "START";
5791 case TRANS_INPROGRESS:
5792 return "INPROGRESS";
5793 case TRANS_COMMIT:
5794 return "COMMIT";
5795 case TRANS_ABORT:
5796 return "ABORT";
5797 case TRANS_PREPARE:
5798 return "PREPARE";
5799 }
5800 return "UNRECOGNIZED";
5801}

References TRANS_ABORT, TRANS_COMMIT, TRANS_DEFAULT, TRANS_INPROGRESS, TRANS_PREPARE, and TRANS_START.

Referenced by AbortSubTransaction(), AbortTransaction(), CleanupSubTransaction(), CleanupTransaction(), CommitSubTransaction(), CommitTransaction(), PopTransaction(), PrepareTransaction(), ShowTransactionStateRec(), and StartSubTransaction().

◆ UnregisterSubXactCallback()

void UnregisterSubXactCallback ( SubXactCallback  callback,
void arg 
)

Definition at line 3900 of file xact.c.

3901{
3902 SubXactCallbackItem *item;
3903 SubXactCallbackItem *prev;
3904
3905 prev = NULL;
3906 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3907 {
3908 if (item->callback == callback && item->arg == arg)
3909 {
3910 if (prev)
3911 prev->next = item->next;
3912 else
3913 SubXact_callbacks = item->next;
3914 pfree(item);
3915 break;
3916 }
3917 }
3918}

References SubXactCallbackItem::arg, arg, SubXactCallbackItem::callback, callback(), fb(), SubXactCallbackItem::next, pfree(), and SubXact_callbacks.

◆ UnregisterXactCallback()

void UnregisterXactCallback ( XactCallback  callback,
void arg 
)

Definition at line 3840 of file xact.c.

3841{
3842 XactCallbackItem *item;
3843 XactCallbackItem *prev;
3844
3845 prev = NULL;
3846 for (item = Xact_callbacks; item; prev = item, item = item->next)
3847 {
3848 if (item->callback == callback && item->arg == arg)
3849 {
3850 if (prev)
3851 prev->next = item->next;
3852 else
3853 Xact_callbacks = item->next;
3854 pfree(item);
3855 break;
3856 }
3857 }
3858}

References XactCallbackItem::arg, arg, XactCallbackItem::callback, callback(), fb(), XactCallbackItem::next, pfree(), and Xact_callbacks.

◆ UserAbortTransactionBlock()

void UserAbortTransactionBlock ( bool  chain)

Definition at line 4227 of file xact.c.

4228{
4230
4231 switch (s->blockState)
4232 {
4233 /*
4234 * We are inside a transaction block and we got a ROLLBACK command
4235 * from the user, so tell CommitTransactionCommand to abort and
4236 * exit the transaction block.
4237 */
4238 case TBLOCK_INPROGRESS:
4240 break;
4241
4242 /*
4243 * We are inside a failed transaction block and we got a ROLLBACK
4244 * command from the user. Abort processing is already done, so
4245 * CommitTransactionCommand just has to cleanup and go back to
4246 * idle state.
4247 */
4248 case TBLOCK_ABORT:
4250 break;
4251
4252 /*
4253 * We are inside a subtransaction. Mark everything up to top
4254 * level as exitable.
4255 */
4257 case TBLOCK_SUBABORT:
4258 while (s->parent != NULL)
4259 {
4262 else if (s->blockState == TBLOCK_SUBABORT)
4264 else
4265 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4267 s = s->parent;
4268 }
4269 if (s->blockState == TBLOCK_INPROGRESS)
4271 else if (s->blockState == TBLOCK_ABORT)
4273 else
4274 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4276 break;
4277
4278 /*
4279 * The user issued ABORT when not inside a transaction. For
4280 * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4281 * The upcoming call to CommitTransactionCommand() will then put
4282 * us back into the default state. For ROLLBACK AND CHAIN, error.
4283 *
4284 * We do the same thing with ABORT inside an implicit transaction,
4285 * although in this case we might be rolling back actual database
4286 * state changes. (It's debatable whether we should issue a
4287 * WARNING in this case, but we have done so historically.)
4288 */
4289 case TBLOCK_STARTED:
4291 if (chain)
4292 ereport(ERROR,
4294 /* translator: %s represents an SQL statement name */
4295 errmsg("%s can only be used in transaction blocks",
4296 "ROLLBACK AND CHAIN")));
4297 else
4300 errmsg("there is no transaction in progress")));
4302 break;
4303
4304 /*
4305 * The user issued an ABORT that somehow ran inside a parallel
4306 * worker. We can't cope with that.
4307 */
4309 ereport(FATAL,
4311 errmsg("cannot abort during a parallel operation")));
4312 break;
4313
4314 /* These cases are invalid. */
4315 case TBLOCK_DEFAULT:
4316 case TBLOCK_BEGIN:
4317 case TBLOCK_SUBBEGIN:
4318 case TBLOCK_END:
4319 case TBLOCK_SUBRELEASE:
4320 case TBLOCK_SUBCOMMIT:
4321 case TBLOCK_ABORT_END:
4325 case TBLOCK_SUBRESTART:
4327 case TBLOCK_PREPARE:
4328 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4330 break;
4331 }
4332
4335
4336 s->chain = chain;
4337}

References Assert, TransactionStateData::blockState, BlockStateAsString(), TransactionStateData::chain, CurrentTransactionState, elog, ereport, errcode(), errmsg, ERROR, FATAL, fb(), TransactionStateData::parent, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, TBLOCK_SUBRESTART, and WARNING.

Referenced by standard_ProcessUtility().

◆ WarnNoTransactionBlock()

void WarnNoTransactionBlock ( bool  isTopLevel,
const char stmtType 
)

Definition at line 3733 of file xact.c.

3734{
3735 CheckTransactionBlock(isTopLevel, false, stmtType);
3736}

References CheckTransactionBlock(), and fb().

Referenced by ExecSetVariableStmt(), and standard_ProcessUtility().

◆ xact_redo()

void xact_redo ( XLogReaderState record)

Definition at line 6386 of file xact.c.

6387{
6388 uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6389
6390 /* Backup blocks are not used in xact records */
6392
6393 if (info == XLOG_XACT_COMMIT)
6394 {
6397
6400 record->EndRecPtr, XLogRecGetOrigin(record));
6401 }
6402 else if (info == XLOG_XACT_COMMIT_PREPARED)
6403 {
6406
6408 xact_redo_commit(&parsed, parsed.twophase_xid,
6409 record->EndRecPtr, XLogRecGetOrigin(record));
6410
6411 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6413 PrepareRedoRemove(parsed.twophase_xid, false);
6415 }
6416 else if (info == XLOG_XACT_ABORT)
6417 {
6420
6423 record->EndRecPtr, XLogRecGetOrigin(record));
6424 }
6425 else if (info == XLOG_XACT_ABORT_PREPARED)
6426 {
6429
6431 xact_redo_abort(&parsed, parsed.twophase_xid,
6432 record->EndRecPtr, XLogRecGetOrigin(record));
6433
6434 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6436 PrepareRedoRemove(parsed.twophase_xid, false);
6438 }
6439 else if (info == XLOG_XACT_PREPARE)
6440 {
6441 /*
6442 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6443 * gxact entry.
6444 */
6447 XLogRecGetData(record),
6448 record->ReadRecPtr,
6449 record->EndRecPtr,
6450 XLogRecGetOrigin(record));
6452 }
6453 else if (info == XLOG_XACT_ASSIGNMENT)
6454 {
6456
6459 xlrec->nsubxacts, xlrec->xsub);
6460 }
6461 else if (info == XLOG_XACT_INVALIDATIONS)
6462 {
6463 /*
6464 * XXX we do ignore this for now, what matters are invalidations
6465 * written into the commit record.
6466 */
6467 }
6468 else
6469 elog(PANIC, "xact_redo: unknown op code %u", info);
6470}

References Assert, elog, XLogReaderState::EndRecPtr, fb(), InvalidFullTransactionId, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), PANIC, ParseAbortRecord(), ParseCommitRecord(), PrepareRedoAdd(), PrepareRedoRemove(), ProcArrayApplyXidAssignment(), XLogReaderState::ReadRecPtr, STANDBY_INITIALIZED, standbyState, xact_redo_abort(), xact_redo_commit(), XLOG_XACT_ABORT, XLOG_XACT_ABORT_PREPARED, XLOG_XACT_ASSIGNMENT, XLOG_XACT_COMMIT, XLOG_XACT_COMMIT_PREPARED, XLOG_XACT_INVALIDATIONS, XLOG_XACT_OPMASK, XLOG_XACT_PREPARE, XLogRecGetData, XLogRecGetInfo, XLogRecGetOrigin, XLogRecGetXid, and XLogRecHasAnyBlockRefs.

◆ xact_redo_abort()

static void xact_redo_abort ( xl_xact_parsed_abort parsed,
TransactionId  xid,
XLogRecPtr  lsn,
ReplOriginId  origin_id 
)
static

Definition at line 6307 of file xact.c.

6309{
6311
6313
6314 /* Make sure nextXid is beyond any XID mentioned in the record. */
6316 parsed->nsubxacts,
6317 parsed->subxacts);
6319
6321 {
6322 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6323 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6324 }
6325 else
6326 {
6327 /*
6328 * If a transaction completion record arrives that has as-yet
6329 * unobserved subtransactions then this will not have been fully
6330 * handled by the call to RecordKnownAssignedTransactionIds() in the
6331 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6332 * cover that case. This is confusing and it is easy to think this
6333 * call is irrelevant, which has happened three times in development
6334 * already. Leave it in.
6335 */
6337
6338 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6339 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6340
6341 /*
6342 * We must update the ProcArray after we have marked clog.
6343 */
6344 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6345
6346 /*
6347 * There are no invalidation messages to send or undo.
6348 */
6349
6350 /*
6351 * Release locks, if any. There are no invalidations to send.
6352 */
6353 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6354 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6355 }
6356
6357 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6358 {
6359 /* recover apply progress */
6360 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6361 false /* backward */ , false /* WAL */ );
6362 }
6363
6364 /* Make sure files supposed to be dropped are dropped */
6365 if (parsed->nrels > 0)
6366 {
6367 /*
6368 * See comments about update of minimum recovery point on truncation,
6369 * in xact_redo_commit().
6370 */
6371 XLogFlush(lsn);
6372
6373 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6374 }
6375
6376 if (parsed->nstats > 0)
6377 {
6378 /* see equivalent call for relations above */
6379 XLogFlush(lsn);
6380
6381 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6382 }
6383}

References AdvanceNextFullTransactionIdPastXid(), Assert, DropRelationFiles(), ExpireTreeKnownAssignedTransactionIds(), fb(), pgstat_execute_transactional_drops(), RecordKnownAssignedTransactionIds(), replorigin_advance(), STANDBY_DISABLED, StandbyReleaseLockTree(), standbyState, TransactionIdAbortTree(), TransactionIdIsValid, TransactionIdLatest(), XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_ORIGIN, and XLogFlush().

Referenced by xact_redo().

◆ xact_redo_commit()

static void xact_redo_commit ( xl_xact_parsed_commit parsed,
TransactionId  xid,
XLogRecPtr  lsn,
ReplOriginId  origin_id 
)
static

Definition at line 6153 of file xact.c.

6157{
6159 TimestampTz commit_time;
6160
6162
6163 max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
6164
6165 /* Make sure nextXid is beyond any XID mentioned in the record. */
6167
6168 Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) ==
6169 (origin_id == InvalidReplOriginId));
6170
6171 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6172 commit_time = parsed->origin_timestamp;
6173 else
6174 commit_time = parsed->xact_time;
6175
6176 /* Set the transaction commit timestamp and metadata */
6177 TransactionTreeSetCommitTsData(xid, parsed->nsubxacts, parsed->subxacts,
6178 commit_time, origin_id);
6179
6181 {
6182 /*
6183 * Mark the transaction committed in pg_xact.
6184 */
6185 TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
6186 }
6187 else
6188 {
6189 /*
6190 * If a transaction completion record arrives that has as-yet
6191 * unobserved subtransactions then this will not have been fully
6192 * handled by the call to RecordKnownAssignedTransactionIds() in the
6193 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6194 * cover that case. This is confusing and it is easy to think this
6195 * call is irrelevant, which has happened three times in development
6196 * already. Leave it in.
6197 */
6199
6200 /*
6201 * Mark the transaction committed in pg_xact. We use async commit
6202 * protocol during recovery to provide information on database
6203 * consistency for when users try to set hint bits. It is important
6204 * that we do not set hint bits until the minRecoveryPoint is past
6205 * this commit record. This ensures that if we crash we don't see hint
6206 * bits set on changes made by transactions that haven't yet
6207 * recovered. It's unlikely but it's good to be safe.
6208 */
6209 TransactionIdAsyncCommitTree(xid, parsed->nsubxacts, parsed->subxacts, lsn);
6210
6211 /*
6212 * We must mark clog before we update the ProcArray.
6213 */
6214 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6215
6216 /*
6217 * Send any cache invalidations attached to the commit. We must
6218 * maintain the same order of invalidation then release locks as
6219 * occurs in CommitTransaction().
6220 */
6223 parsed->dbId, parsed->tsId);
6224
6225 /*
6226 * Release locks, if any. We do this for both two phase and normal one
6227 * phase transactions. In effect we are ignoring the prepare phase and
6228 * just going straight to lock release.
6229 */
6230 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6231 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6232 }
6233
6234 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6235 {
6236 /* recover apply progress */
6237 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6238 false /* backward */ , false /* WAL */ );
6239 }
6240
6241 /* Make sure files supposed to be dropped are dropped */
6242 if (parsed->nrels > 0)
6243 {
6244 /*
6245 * First update minimum recovery point to cover this WAL record. Once
6246 * a relation is deleted, there's no going back. The buffer manager
6247 * enforces the WAL-first rule for normal updates to relation files,
6248 * so that the minimum recovery point is always updated before the
6249 * corresponding change in the data file is flushed to disk, but we
6250 * have to do the same here since we're bypassing the buffer manager.
6251 *
6252 * Doing this before deleting the files means that if a deletion fails
6253 * for some reason, you cannot start up the system even after restart,
6254 * until you fix the underlying situation so that the deletion will
6255 * succeed. Alternatively, we could update the minimum recovery point
6256 * after deletion, but that would leave a small window where the
6257 * WAL-first rule would be violated.
6258 */
6259 XLogFlush(lsn);
6260
6261 /* Make sure files supposed to be dropped are dropped */
6262 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6263 }
6264
6265 if (parsed->nstats > 0)
6266 {
6267 /* see equivalent call for relations above */
6268 XLogFlush(lsn);
6269
6270 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6271 }
6272
6273 /*
6274 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
6275 * in normal operation. For example, in CREATE DATABASE, we copy all files
6276 * from the template database, and then commit the transaction. If we
6277 * crash after all the files have been copied but before the commit, you
6278 * have files in the data directory without an entry in pg_database. To
6279 * minimize the window for that, we use ForceSyncCommit() to rush the
6280 * commit record to disk as quick as possible. We have the same window
6281 * during recovery, and forcing an XLogFlush() (which updates
6282 * minRecoveryPoint during recovery) helps to reduce that problem window,
6283 * for any user that requested ForceSyncCommit().
6284 */
6286 XLogFlush(lsn);
6287
6288 /*
6289 * If asked by the primary (because someone is waiting for a synchronous
6290 * commit = remote_apply), we will need to ask walreceiver to send a reply
6291 * immediately.
6292 */
6295}

References AdvanceNextFullTransactionIdPastXid(), Assert, DropRelationFiles(), ExpireTreeKnownAssignedTransactionIds(), fb(), InvalidReplOriginId, pgstat_execute_transactional_drops(), ProcessCommittedInvalidationMessages(), RecordKnownAssignedTransactionIds(), replorigin_advance(), STANDBY_DISABLED, StandbyReleaseLockTree(), standbyState, TransactionIdAsyncCommitTree(), TransactionIdCommitTree(), TransactionIdIsValid, TransactionIdLatest(), TransactionTreeSetCommitTsData(), XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_ORIGIN, XactCompletionApplyFeedback, XactCompletionForceSyncCommit, XactCompletionRelcacheInitFileInval, XLogFlush(), and XLogRequestWalReceiverReply().

Referenced by xact_redo().

◆ xactGetCommittedChildren()

int xactGetCommittedChildren ( TransactionId **  ptr)

Definition at line 5813 of file xact.c.

5814{
5816
5817 if (s->nChildXids == 0)
5818 *ptr = NULL;
5819 else
5820 *ptr = s->childXids;
5821
5822 return s->nChildXids;
5823}

References TransactionStateData::childXids, CurrentTransactionState, fb(), and TransactionStateData::nChildXids.

Referenced by ExportSnapshot(), RecordTransactionAbort(), RecordTransactionCommit(), and StartPrepare().

◆ XactLogAbortRecord()

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 at line 6009 of file xact.c.

6015{
6024
6025 uint8 info;
6026
6028
6029 xl_xinfo.xinfo = 0;
6030
6031 /* decide between a plain and 2pc abort */
6032 if (!TransactionIdIsValid(twophase_xid))
6033 info = XLOG_XACT_ABORT;
6034 else
6036
6037
6038 /* First figure out and collect all the information needed */
6039
6040 xlrec.xact_time = abort_time;
6041
6044
6045 if (nsubxacts > 0)
6046 {
6048 xl_subxacts.nsubxacts = nsubxacts;
6049 }
6050
6051 if (nrels > 0)
6052 {
6054 xl_relfilelocators.nrels = nrels;
6055 info |= XLR_SPECIAL_REL_UPDATE;
6056 }
6057
6058 if (ndroppedstats > 0)
6059 {
6062 }
6063
6064 if (TransactionIdIsValid(twophase_xid))
6065 {
6067 xl_twophase.xid = twophase_xid;
6068 Assert(twophase_gid != NULL);
6069
6072 }
6073
6074 if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6075 {
6077 xl_dbinfo.dbId = MyDatabaseId;
6079 }
6080
6081 /*
6082 * Dump transaction origin information. We need this during recovery to
6083 * update the replication origin progress.
6084 */
6086 {
6088
6091 }
6092
6093 if (xl_xinfo.xinfo != 0)
6094 info |= XLOG_XACT_HAS_INFO;
6095
6096 /* Then include all the collected data into the abort record. */
6097
6099
6101
6102 if (xl_xinfo.xinfo != 0)
6104
6105 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6107
6109 {
6112 XLogRegisterData(subxacts,
6113 nsubxacts * sizeof(TransactionId));
6114 }
6115
6117 {
6120 XLogRegisterData(rels,
6121 nrels * sizeof(RelFileLocator));
6122 }
6123
6125 {
6130 }
6131
6133 {
6135 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6136 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6137 }
6138
6139 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6141
6142 /* Include the replication origin */
6144
6145 return XLogInsert(RM_XACT_ID, info);
6146}

References Assert, CritSectionCount, fb(), InvalidReplOriginId, MinSizeOfXactAbort, MinSizeOfXactRelfileLocators, MinSizeOfXactStatsItems, MinSizeOfXactSubxacts, MyDatabaseId, MyDatabaseTableSpace, ReplOriginXactState::origin, ReplOriginXactState::origin_lsn, ReplOriginXactState::origin_timestamp, replorigin_xact_state, TransactionIdIsValid, XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK, XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_DBINFO, XACT_XINFO_HAS_DROPPED_STATS, XACT_XINFO_HAS_GID, XACT_XINFO_HAS_ORIGIN, XACT_XINFO_HAS_RELFILELOCATORS, XACT_XINFO_HAS_SUBXACTS, XACT_XINFO_HAS_TWOPHASE, XLOG_INCLUDE_ORIGIN, XLOG_XACT_ABORT, XLOG_XACT_ABORT_PREPARED, XLOG_XACT_HAS_INFO, XLogBeginInsert(), XLogInsert(), XLogLogicalInfoActive, XLogRegisterData(), XLogSetRecordFlags(), and XLR_SPECIAL_REL_UPDATE.

Referenced by RecordTransactionAbort(), and RecordTransactionAbortPrepared().

◆ XactLogCommitRecord()

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 at line 5837 of file xact.c.

5845{
5855 uint8 info;
5856
5858
5859 xl_xinfo.xinfo = 0;
5860
5861 /* decide between a plain and 2pc commit */
5862 if (!TransactionIdIsValid(twophase_xid))
5863 info = XLOG_XACT_COMMIT;
5864 else
5866
5867 /* First figure out and collect all the information needed */
5868
5869 xlrec.xact_time = commit_time;
5870
5871 if (relcacheInval)
5873 if (forceSyncCommit)
5877
5878 /*
5879 * Check if the caller would like to ask standbys for immediate feedback
5880 * once this commit is applied.
5881 */
5884
5885 /*
5886 * Relcache invalidations requires information about the current database
5887 * and so does logical decoding.
5888 */
5889 if (nmsgs > 0 || XLogLogicalInfoActive())
5890 {
5892 xl_dbinfo.dbId = MyDatabaseId;
5894 }
5895
5896 if (nsubxacts > 0)
5897 {
5899 xl_subxacts.nsubxacts = nsubxacts;
5900 }
5901
5902 if (nrels > 0)
5903 {
5905 xl_relfilelocators.nrels = nrels;
5906 info |= XLR_SPECIAL_REL_UPDATE;
5907 }
5908
5909 if (ndroppedstats > 0)
5910 {
5913 }
5914
5915 if (nmsgs > 0)
5916 {
5918 xl_invals.nmsgs = nmsgs;
5919 }
5920
5921 if (TransactionIdIsValid(twophase_xid))
5922 {
5924 xl_twophase.xid = twophase_xid;
5925 Assert(twophase_gid != NULL);
5926
5929 }
5930
5931 /* dump transaction origin information */
5933 {
5935
5938 }
5939
5940 if (xl_xinfo.xinfo != 0)
5941 info |= XLOG_XACT_HAS_INFO;
5942
5943 /* Then include all the collected data into the commit record. */
5944
5946
5948
5949 if (xl_xinfo.xinfo != 0)
5950 XLogRegisterData(&xl_xinfo.xinfo, sizeof(xl_xinfo.xinfo));
5951
5952 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5954
5956 {
5959 XLogRegisterData(subxacts,
5960 nsubxacts * sizeof(TransactionId));
5961 }
5962
5964 {
5967 XLogRegisterData(rels,
5968 nrels * sizeof(RelFileLocator));
5969 }
5970
5972 {
5977 }
5978
5979 if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
5980 {
5982 XLogRegisterData(msgs,
5983 nmsgs * sizeof(SharedInvalidationMessage));
5984 }
5985
5987 {
5989 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
5990 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
5991 }
5992
5993 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5995
5996 /* we allow filtering by xacts */
5998
5999 return XLogInsert(RM_XACT_ID, info);
6000}

References Assert, CritSectionCount, fb(), forceSyncCommit, InvalidReplOriginId, MinSizeOfXactInvals, MinSizeOfXactRelfileLocators, MinSizeOfXactStatsItems, MinSizeOfXactSubxacts, MyDatabaseId, MyDatabaseTableSpace, ReplOriginXactState::origin, ReplOriginXactState::origin_lsn, ReplOriginXactState::origin_timestamp, replorigin_xact_state, synchronous_commit, SYNCHRONOUS_COMMIT_REMOTE_APPLY, TransactionIdIsValid, XACT_COMPLETION_APPLY_FEEDBACK, XACT_COMPLETION_FORCE_SYNC_COMMIT, XACT_COMPLETION_UPDATE_RELCACHE_FILE, XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK, XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_DBINFO, XACT_XINFO_HAS_DROPPED_STATS, XACT_XINFO_HAS_GID, XACT_XINFO_HAS_INVALS, XACT_XINFO_HAS_ORIGIN, XACT_XINFO_HAS_RELFILELOCATORS, XACT_XINFO_HAS_SUBXACTS, XACT_XINFO_HAS_TWOPHASE, XLOG_INCLUDE_ORIGIN, XLOG_XACT_COMMIT, XLOG_XACT_COMMIT_PREPARED, XLOG_XACT_HAS_INFO, XLogBeginInsert(), XLogInsert(), XLogLogicalInfoActive, XLogRegisterData(), XLogSetRecordFlags(), and XLR_SPECIAL_REL_UPDATE.

Referenced by RecordTransactionCommit(), and RecordTransactionCommitPrepared().

Variable Documentation

◆ bsysscan

◆ CheckXidAlive

◆ currentCommandId

◆ currentCommandIdUsed

bool currentCommandIdUsed
static

◆ currentSubTransactionId

SubTransactionId currentSubTransactionId
static

Definition at line 268 of file xact.c.

Referenced by PushTransaction(), and StartTransaction().

◆ CurrentTransactionState

TransactionState CurrentTransactionState = &TopTransactionStateData
static

Definition at line 262 of file xact.c.

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), AbortSubTransaction(), AbortTransaction(), AtCleanup_Memory(), AtCommit_Memory(), AtStart_Memory(), AtStart_ResourceOwner(), AtSubAbort_childXids(), AtSubAbort_ResourceOwner(), AtSubCleanup_Memory(), AtSubCommit_childXids(), AtSubCommit_Memory(), AtSubStart_Memory(), AtSubStart_ResourceOwner(), BeginImplicitTransactionBlock(), BeginInternalSubTransaction(), BeginTransactionBlock(), CleanupSubTransaction(), CleanupTransaction(), CommitSubTransaction(), CommitTransaction(), CommitTransactionCommandInternal(), DefineSavepoint(), EndImplicitTransactionBlock(), EndParallelWorkerTransaction(), EndTransactionBlock(), EnterParallelMode(), EstimateTransactionStateSpace(), ExitParallelMode(), GetCurrentFullTransactionId(), GetCurrentFullTransactionIdIfAny(), GetCurrentSubTransactionId(), GetCurrentTransactionId(), GetCurrentTransactionIdIfAny(), GetCurrentTransactionNestLevel(), GetCurrentTransactionStopTimestamp(), IsAbortedTransactionBlockState(), IsInParallelMode(), IsInTransactionBlock(), IsSubTransaction(), IsSubxactTopXidLogPending(), IsTransactionBlock(), IsTransactionOrTransactionBlock(), IsTransactionState(), MarkCurrentTransactionIdLoggedIfAny(), MarkSubxactTopXidLogged(), PopTransaction(), PrepareTransaction(), PrepareTransactionBlock(), PreventInTransactionBlock(), PushTransaction(), ReleaseCurrentSubTransaction(), ReleaseSavepoint(), RollbackAndReleaseCurrentSubTransaction(), RollbackToSavepoint(), SerializeTransactionState(), ShowTransactionState(), StartParallelWorkerTransaction(), StartSubTransaction(), StartTransaction(), StartTransactionCommand(), SubTransactionIsActive(), TransactionBlockStatusCode(), TransactionIdIsCurrentTransactionId(), TransactionStartedDuringRecovery(), UserAbortTransactionBlock(), and xactGetCommittedChildren().

◆ DefaultXactDeferrable

bool DefaultXactDeferrable = false

Definition at line 86 of file xact.c.

Referenced by StartTransaction().

◆ DefaultXactIsoLevel

int DefaultXactIsoLevel = XACT_READ_COMMITTED

Definition at line 80 of file xact.c.

Referenced by StartTransaction().

◆ DefaultXactReadOnly

bool DefaultXactReadOnly = false

Definition at line 83 of file xact.c.

Referenced by StartTransaction().

◆ forceSyncCommit

bool forceSyncCommit = false
static

◆ MyXactFlags

◆ nParallelCurrentXids

◆ nUnreportedXids

int nUnreportedXids
static

Definition at line 259 of file xact.c.

Referenced by AssignTransactionId(), and StartTransaction().

◆ ParallelCurrentXids

TransactionId* ParallelCurrentXids
static

◆ prepareGID

char* prepareGID
static

Definition at line 290 of file xact.c.

Referenced by PrepareTransaction(), and PrepareTransactionBlock().

◆ stmtStartTimestamp

◆ SubXact_callbacks

SubXactCallbackItem* SubXact_callbacks = NULL
static

◆ synchronous_commit

int synchronous_commit = SYNCHRONOUS_COMMIT_ON

Definition at line 89 of file xact.c.

Referenced by AutoVacWorkerMain(), RecordTransactionCommit(), and XactLogCommitRecord().

◆ TopTransactionStateData

TransactionStateData TopTransactionStateData
static
Initial value:
= {
.state = TRANS_DEFAULT,
.blockState = TBLOCK_DEFAULT,
.topXidLogged = false,
}

Definition at line 249 of file xact.c.

249 {
250 .state = TRANS_DEFAULT,
251 .blockState = TBLOCK_DEFAULT,
252 .topXidLogged = false,
253};

Referenced by AssignTransactionId(), GetTopFullTransactionId(), GetTopTransactionId(), and StartTransaction().

◆ TransactionAbortContext

MemoryContext TransactionAbortContext = NULL
static

◆ unreportedXids

TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS]
static

Definition at line 260 of file xact.c.

Referenced by AssignTransactionId().

◆ Xact_callbacks

XactCallbackItem* Xact_callbacks = NULL
static

Definition at line 317 of file xact.c.

Referenced by CallXactCallbacks(), RegisterXactCallback(), and UnregisterXactCallback().

◆ xact_is_sampled

bool xact_is_sampled = false

Definition at line 298 of file xact.c.

Referenced by check_log_duration(), and StartTransaction().

◆ XactDeferrable

◆ XactIsoLevel

◆ XactReadOnly

◆ xactStartTimestamp

TimestampTz xactStartTimestamp
static

◆ xactStopTimestamp

TimestampTz xactStopTimestamp
static

◆ XactTopFullTransactionId