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)
 
int GetTopReadOnlyTransactionNestLevel (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 * GetTopReadOnlyTransactionNestLevel
1050 *
1051 * Note: this will return zero when not inside any transaction or when neither
1052 * a top-level transaction nor subtransactions are read-only, one when the
1053 * top-level transaction is read-only, two when one level of subtransaction is
1054 * read-only, etc.
1055 *
1056 * Note: subtransactions of the topmost read-only transaction are also
1057 * read-only, because they inherit read-only mode from the transaction, and
1058 * thus can't change to read-write mode (see check_transaction_read_only).
1059 */
1060int
1062{
1064
1065 if (!XactReadOnly)
1066 return 0;
1067 while (s->nestingLevel > 1)
1068 {
1069 if (!s->prevXactReadOnly)
1070 return s->nestingLevel;
1071 s = s->parent;
1072 }
1073 return s->nestingLevel;
1074}
1075
1076/*
1077 * EnterParallelMode
1078 */
1079void
1081{
1083
1084 Assert(s->parallelModeLevel >= 0);
1085
1086 ++s->parallelModeLevel;
1087}
1088
1089/*
1090 * ExitParallelMode
1091 */
1092void
1093ExitParallelMode(void)
1094{
1096
1097 Assert(s->parallelModeLevel > 0);
1100
1101 --s->parallelModeLevel;
1102}
1103
1104/*
1105 * IsInParallelMode
1106 *
1107 * Are we in a parallel operation, as either the leader or a worker? Check
1108 * this to prohibit operations that change backend-local state expected to
1109 * match across all workers. Mere caches usually don't require such a
1110 * restriction. State modified in a strict push/pop fashion, such as the
1111 * active snapshot stack, is often fine.
1112 *
1113 * We say we are in parallel mode if we are in a subxact of a transaction
1114 * that's initiated a parallel operation; for most purposes that context
1115 * has all the same restrictions.
1116 */
1117bool
1118IsInParallelMode(void)
1119{
1121
1122 return s->parallelModeLevel != 0 || s->parallelChildXact;
1123}
1124
1125/*
1126 * CommandCounterIncrement
1127 */
1128void
1130{
1131 /*
1132 * If the current value of the command counter hasn't been "used" to mark
1133 * tuples, we need not increment it, since there's no need to distinguish
1134 * a read-only command from others. This helps postpone command counter
1135 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
1136 */
1138 {
1139 /*
1140 * Workers synchronize transaction state at the beginning of each
1141 * parallel operation, so we can't account for new commands after that
1142 * point.
1143 */
1145 ereport(ERROR,
1147 errmsg("cannot start commands during a parallel operation")));
1148
1149 currentCommandId += 1;
1151 {
1152 currentCommandId -= 1;
1153 ereport(ERROR,
1155 errmsg("cannot have more than 2^32-2 commands in a transaction")));
1156 }
1157 currentCommandIdUsed = false;
1158
1159 /* Propagate new command ID into static snapshots */
1161
1162 /*
1163 * Make any catalog changes done by the just-completed command visible
1164 * in the local syscache. We obviously don't need to do this after a
1165 * read-only command. (But see hacks in inval.c to make real sure we
1166 * don't think a command that queued inval messages was read-only.)
1167 */
1169 }
1170}
1171
1172/*
1173 * ForceSyncCommit
1174 *
1175 * Interface routine to allow commands to force a synchronous commit of the
1176 * current top-level transaction. Currently, two-phase commit does not
1177 * persist and restore this variable. So long as all callers use
1178 * PreventInTransactionBlock(), that omission has no consequences.
1179 */
1180void
1181ForceSyncCommit(void)
1182{
1183 forceSyncCommit = true;
1184}
1185
1186
1187/* ----------------------------------------------------------------
1188 * StartTransaction stuff
1189 * ----------------------------------------------------------------
1190 */
1191
1192/*
1193 * AtStart_Cache
1194 */
1195static void
1196AtStart_Cache(void)
1197{
1199}
1200
1201/*
1202 * AtStart_Memory
1203 */
1204static void
1205AtStart_Memory(void)
1206{
1208
1209 /*
1210 * Remember the memory context that was active prior to transaction start.
1211 */
1213
1214 /*
1215 * If this is the first time through, create a private context for
1216 * AbortTransaction to work in. By reserving some space now, we can
1217 * insulate AbortTransaction from out-of-memory scenarios. Like
1218 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1219 * size, so that space will be reserved immediately.
1220 */
1224 "TransactionAbortContext",
1225 32 * 1024,
1226 32 * 1024,
1227 32 * 1024);
1228
1229 /*
1230 * Likewise, if this is the first time through, create a top-level context
1231 * for transaction-local data. This context will be reset at transaction
1232 * end, and then re-used in later transactions.
1233 */
1237 "TopTransactionContext",
1239
1240 /*
1241 * In a top-level transaction, CurTransactionContext is the same as
1242 * TopTransactionContext.
1243 */
1246
1247 /* Make the CurTransactionContext active. */
1249}
1250
1251/*
1252 * AtStart_ResourceOwner
1253 */
1254static void
1256{
1258
1259 /*
1260 * We shouldn't have a transaction resource owner already.
1261 */
1263
1264 /*
1265 * Create a toplevel resource owner for the transaction.
1266 */
1267 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1268
1272}
1273
1274/* ----------------------------------------------------------------
1275 * StartSubTransaction stuff
1276 * ----------------------------------------------------------------
1277 */
1278
1279/*
1280 * AtSubStart_Memory
1281 */
1282static void
1284{
1286
1288
1289 /*
1290 * Remember the context that was active prior to subtransaction start.
1291 */
1293
1294 /*
1295 * Create a CurTransactionContext, which will be used to hold data that
1296 * survives subtransaction commit but disappears on subtransaction abort.
1297 * We make it a child of the immediate parent's CurTransactionContext.
1298 */
1300 "CurTransactionContext",
1303
1304 /* Make the CurTransactionContext active. */
1306}
1307
1308/*
1309 * AtSubStart_ResourceOwner
1310 */
1311static void
1313{
1315
1316 Assert(s->parent != NULL);
1317
1318 /*
1319 * Create a resource owner for the subtransaction. We make it a child of
1320 * the immediate parent's resource owner.
1321 */
1324 "SubTransaction");
1325
1328}
1329
1330/* ----------------------------------------------------------------
1331 * CommitTransaction stuff
1332 * ----------------------------------------------------------------
1333 */
1334
1335/*
1336 * RecordTransactionCommit
1337 *
1338 * Returns latest XID among xact and its children, or InvalidTransactionId
1339 * if the xact has no XID. (We compute that here just because it's easier.)
1340 *
1341 * If you change this function, see RecordTransactionCommitPrepared also.
1342 */
1343static TransactionId
1345{
1349 int nrels;
1350 RelFileLocator *rels;
1351 int nchildren;
1352 TransactionId *children;
1353 int ndroppedstats = 0;
1355 int nmsgs = 0;
1357 bool RelcacheInitFileInval = false;
1358 bool wrote_xlog;
1359
1360 /*
1361 * Log pending invalidations for logical decoding of in-progress
1362 * transactions. Normally for DDLs, we log this at each command end,
1363 * however, for certain cases where we directly update the system table
1364 * without a transaction block, the invalidations are not logged till this
1365 * time.
1366 */
1369
1370 /* Get data needed for commit record */
1371 nrels = smgrGetPendingDeletes(true, &rels);
1376 &RelcacheInitFileInval);
1377 wrote_xlog = (XactLastRecEnd != 0);
1378
1379 /*
1380 * If we haven't been assigned an XID yet, we neither can, nor do we want
1381 * to write a COMMIT record.
1382 */
1383 if (!markXidCommitted)
1384 {
1385 /*
1386 * We expect that every RelationDropStorage is followed by a catalog
1387 * update, and hence XID assignment, so we shouldn't get here with any
1388 * pending deletes. Same is true for dropping stats.
1389 *
1390 * Use a real test not just an Assert to check this, since it's a bit
1391 * fragile.
1392 */
1393 if (nrels != 0 || ndroppedstats != 0)
1394 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
1395
1396 /* Can't have child XIDs either; AssignTransactionId enforces this */
1397 Assert(nchildren == 0);
1398
1399 /*
1400 * Transactions without an assigned xid can contain invalidation
1401 * messages. While inplace updates do this, this is not known to be
1402 * necessary; see comment at inplace CacheInvalidateHeapTuple().
1403 * Extensions might still rely on this capability, and standbys may
1404 * need to process those invals. We can't emit a commit record
1405 * without an xid, and we don't want to force assigning an xid,
1406 * because that'd be problematic for e.g. vacuum. Hence we emit a
1407 * bespoke record for the invalidations. We don't want to use that in
1408 * case a commit record is emitted, so they happen synchronously with
1409 * commits (besides not wanting to emit more WAL records).
1410 *
1411 * XXX Every known use of this capability is a defect. Since an XID
1412 * isn't controlling visibility of the change that prompted invals,
1413 * other sessions need the inval even if this transactions aborts.
1414 *
1415 * ON COMMIT DELETE ROWS does a nontransactional index_build(), which
1416 * queues a relcache inval, including in transactions without an xid
1417 * that had read the (empty) table. Standbys don't need any ON COMMIT
1418 * DELETE ROWS invals, but we've not done the work to withhold them.
1419 */
1420 if (nmsgs != 0)
1421 {
1423 RelcacheInitFileInval);
1424 wrote_xlog = true; /* not strictly necessary */
1425 }
1426
1427 /*
1428 * If we didn't create XLOG entries, we're done here; otherwise we
1429 * should trigger flushing those entries the same as a commit record
1430 * would. This will primarily happen for HOT pruning and the like; we
1431 * want these to be flushed to disk in due time.
1432 */
1433 if (!wrote_xlog)
1434 goto cleanup;
1435 }
1436 else
1437 {
1438 bool replorigin;
1439
1440 /*
1441 * Are we using the replication origins feature? Or, in other words,
1442 * are we replaying remote actions?
1443 */
1446
1447 /*
1448 * Mark ourselves as within our "commit critical section". This
1449 * forces any concurrent checkpoint to wait until we've updated
1450 * pg_xact. Without this, it is possible for the checkpoint to set
1451 * REDO after the XLOG record but fail to flush the pg_xact update to
1452 * disk, leading to loss of the transaction commit if the system
1453 * crashes a little later.
1454 *
1455 * Note: we could, but don't bother to, set this flag in
1456 * RecordTransactionAbort. That's because loss of a transaction abort
1457 * is noncritical; the presumption would be that it aborted, anyway.
1458 *
1459 * It's safe to change the delayChkptFlags flag of our own backend
1460 * without holding the ProcArrayLock, since we're the only one
1461 * modifying it. This makes checkpoint's determination of which xacts
1462 * are delaying the checkpoint a bit fuzzy, but it doesn't matter.
1463 *
1464 * Note, it is important to get the commit timestamp after marking the
1465 * transaction in the commit critical section. See
1466 * RecordTransactionCommitPrepared.
1467 */
1471
1473
1474 /*
1475 * Ensures the DELAY_CHKPT_IN_COMMIT flag write is globally visible
1476 * before commit time is written.
1477 */
1479
1480 /*
1481 * Insert the commit XLOG record.
1482 */
1484 nchildren, children, nrels, rels,
1486 nmsgs, invalMessages,
1487 RelcacheInitFileInval,
1489 InvalidTransactionId, NULL /* plain commit */ );
1490
1491 if (replorigin)
1492 /* Move LSNs forward for this replication origin */
1495
1496 /*
1497 * Record commit timestamp. The value comes from plain commit
1498 * timestamp if there's no replication origin; otherwise, the
1499 * timestamp was already set in replorigin_xact_state.origin_timestamp
1500 * by replication.
1501 *
1502 * We don't need to WAL-log anything here, as the commit record
1503 * written above already contains the data.
1504 */
1505
1508
1512 }
1513
1514 /*
1515 * Check if we want to commit asynchronously. We can allow the XLOG flush
1516 * to happen asynchronously if synchronous_commit=off, or if the current
1517 * transaction has not performed any WAL-logged operation or didn't assign
1518 * an xid. The transaction can end up not writing any WAL, even if it has
1519 * an xid, if it only wrote to temporary and/or unlogged tables. It can
1520 * end up having written WAL without an xid if it did HOT pruning. In
1521 * case of a crash, the loss of such a transaction will be irrelevant;
1522 * temp tables will be lost anyway, unlogged tables will be truncated and
1523 * HOT pruning will be done again later. (Given the foregoing, you might
1524 * think that it would be unnecessary to emit the XLOG record at all in
1525 * this case, but we don't currently try to do that. It would certainly
1526 * cause problems at least in Hot Standby mode, where the
1527 * KnownAssignedXids machinery requires tracking every XID assignment. It
1528 * might be OK to skip it only when wal_level < replica, but for now we
1529 * don't.)
1530 *
1531 * However, if we're doing cleanup of any non-temp rels or committing any
1532 * command that wanted to force sync commit, then we must flush XLOG
1533 * immediately. (We must not allow asynchronous commit if there are any
1534 * non-temp tables to be deleted, because we might delete the files before
1535 * the COMMIT record is flushed to disk. We do allow asynchronous commit
1536 * if all to-be-deleted tables are temporary though, since they are lost
1537 * anyway if we crash.)
1538 */
1539 if ((wrote_xlog && markXidCommitted &&
1541 forceSyncCommit || nrels > 0)
1542 {
1544
1545 /*
1546 * Now we may update the CLOG, if we wrote a COMMIT record above
1547 */
1548 if (markXidCommitted)
1549 TransactionIdCommitTree(xid, nchildren, children);
1550 }
1551 else
1552 {
1553 /*
1554 * Asynchronous commit case:
1555 *
1556 * This enables possible committed transaction loss in the case of a
1557 * postmaster crash because WAL buffers are left unwritten. Ideally we
1558 * could issue the WAL write without the fsync, but some
1559 * wal_sync_methods do not allow separate write/fsync.
1560 *
1561 * Report the latest async commit LSN, so that the WAL writer knows to
1562 * flush this commit.
1563 */
1565
1566 /*
1567 * We must not immediately update the CLOG, since we didn't flush the
1568 * XLOG. Instead, we store the LSN up to which the XLOG must be
1569 * flushed before the CLOG may be updated.
1570 */
1571 if (markXidCommitted)
1573 }
1574
1575 /*
1576 * If we entered a commit critical section, leave it now, and let
1577 * checkpoints proceed.
1578 */
1579 if (markXidCommitted)
1580 {
1583 }
1584
1585 /* Compute latestXid while we have the child XIDs handy */
1586 latestXid = TransactionIdLatest(xid, nchildren, children);
1587
1588 /*
1589 * Wait for synchronous replication, if required. Similar to the decision
1590 * above about using committing asynchronously we only want to wait if
1591 * this backend assigned an xid and wrote WAL. No need to wait if an xid
1592 * was assigned due to temporary/unlogged tables or due to HOT pruning.
1593 *
1594 * Note that at this stage we have marked clog, but still show as running
1595 * in the procarray and continue to hold locks.
1596 */
1599
1600 /* remember end of last commit record */
1602
1603 /* Reset XactLastRecEnd until the next transaction writes something */
1604 XactLastRecEnd = 0;
1605cleanup:
1606 /* Clean up local data */
1607 if (rels)
1608 pfree(rels);
1609 if (ndroppedstats)
1611
1612 return latestXid;
1613}
1614
1615
1616/*
1617 * AtCCI_LocalCache
1618 */
1619static void
1620AtCCI_LocalCache(void)
1621{
1622 /*
1623 * Make any pending relation map changes visible. We must do this before
1624 * processing local sinval messages, so that the map changes will get
1625 * reflected into the relcache when relcache invals are processed.
1626 */
1628
1629 /*
1630 * Make catalog changes visible to me for the next command.
1631 */
1633}
1634
1635/*
1636 * AtCommit_Memory
1637 */
1638static void
1639AtCommit_Memory(void)
1640{
1642
1643 /*
1644 * Return to the memory context that was current before we started the
1645 * transaction. (In principle, this could not be any of the contexts we
1646 * are about to delete. If it somehow is, assertions in mcxt.c will
1647 * complain.)
1648 */
1650
1651 /*
1652 * Release all transaction-local memory. TopTransactionContext survives
1653 * but becomes empty; any sub-contexts go away.
1654 */
1657
1658 /*
1659 * Clear these pointers as a pro-forma matter. (Notionally, while
1660 * TopTransactionContext still exists, it's currently not associated with
1661 * this TransactionState struct.)
1662 */
1665}
1666
1667/* ----------------------------------------------------------------
1668 * CommitSubTransaction stuff
1669 * ----------------------------------------------------------------
1670 */
1671
1672/*
1673 * AtSubCommit_Memory
1674 */
1675static void
1677{
1679
1680 Assert(s->parent != NULL);
1681
1682 /* Return to parent transaction level's memory context. */
1685
1686 /*
1687 * Ordinarily we cannot throw away the child's CurTransactionContext,
1688 * since the data it contains will be needed at upper commit. However, if
1689 * there isn't actually anything in it, we can throw it away. This avoids
1690 * a small memory leak in the common case of "trivial" subxacts.
1691 */
1693 {
1696 }
1697}
1698
1699/*
1700 * AtSubCommit_childXids
1701 *
1702 * Pass my own XID and my child XIDs up to my parent as committed children.
1703 */
1704static void
1706{
1708 int new_nChildXids;
1709
1710 Assert(s->parent != NULL);
1711
1712 /*
1713 * The parent childXids array will need to hold my XID and all my
1714 * childXids, in addition to the XIDs already there.
1715 */
1717
1718 /* Allocate or enlarge the parent array if necessary */
1720 {
1721 int new_maxChildXids;
1723
1724 /*
1725 * Make it 2x what's needed right now, to avoid having to enlarge it
1726 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1727 * is what ensures that we don't need to worry about integer overflow
1728 * here or in the calculation of new_nChildXids.)
1729 */
1731 (int) (MaxAllocSize / sizeof(TransactionId)));
1732
1734 ereport(ERROR,
1736 errmsg("maximum number of committed subtransactions (%d) exceeded",
1737 (int) (MaxAllocSize / sizeof(TransactionId)))));
1738
1739 /*
1740 * We keep the child-XID arrays in TopTransactionContext; this avoids
1741 * setting up child-transaction contexts for what might be just a few
1742 * bytes of grandchild XIDs.
1743 */
1744 if (s->parent->childXids == NULL)
1748 else
1751
1754 }
1755
1756 /*
1757 * Copy all my XIDs to parent's array.
1758 *
1759 * Note: We rely on the fact that the XID of a child always follows that
1760 * of its parent. By copying the XID of this subtransaction before the
1761 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1762 * all XIDs already in the array belong to subtransactions started and
1763 * subcommitted before us, so their XIDs must precede ours.
1764 */
1766
1767 if (s->nChildXids > 0)
1768 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1769 s->childXids,
1770 s->nChildXids * sizeof(TransactionId));
1771
1773
1774 /* Release child's array to avoid leakage */
1775 if (s->childXids != NULL)
1776 pfree(s->childXids);
1777 /* We must reset these to avoid double-free if fail later in commit */
1778 s->childXids = NULL;
1779 s->nChildXids = 0;
1780 s->maxChildXids = 0;
1781}
1782
1783/* ----------------------------------------------------------------
1784 * AbortTransaction stuff
1785 * ----------------------------------------------------------------
1786 */
1787
1788/*
1789 * RecordTransactionAbort
1790 *
1791 * Returns latest XID among xact and its children, or InvalidTransactionId
1792 * if the xact has no XID. (We compute that here just because it's easier.)
1793 */
1794static TransactionId
1796{
1799 int nrels;
1800 RelFileLocator *rels;
1801 int ndroppedstats = 0;
1803 int nchildren;
1804 TransactionId *children;
1805 TimestampTz xact_time;
1806 bool replorigin;
1807
1808 /*
1809 * If we haven't been assigned an XID, nobody will care whether we aborted
1810 * or not. Hence, we're done in that case. It does not matter if we have
1811 * rels to delete (note that this routine is not responsible for actually
1812 * deleting 'em). We cannot have any child XIDs, either.
1813 */
1814 if (!TransactionIdIsValid(xid))
1815 {
1816 /* Reset XactLastRecEnd until the next transaction writes something */
1817 if (!isSubXact)
1818 XactLastRecEnd = 0;
1819 return InvalidTransactionId;
1820 }
1821
1822 /*
1823 * We have a valid XID, so we should write an ABORT record for it.
1824 *
1825 * We do not flush XLOG to disk here, since the default assumption after a
1826 * crash would be that we aborted, anyway. For the same reason, we don't
1827 * need to worry about interlocking against checkpoint start.
1828 */
1829
1830 /*
1831 * Check that we haven't aborted halfway through RecordTransactionCommit.
1832 */
1833 if (TransactionIdDidCommit(xid))
1834 elog(PANIC, "cannot abort transaction %u, it was already committed",
1835 xid);
1836
1837 /*
1838 * Are we using the replication origins feature? Or, in other words, are
1839 * we replaying remote actions?
1840 */
1843
1844 /* Fetch the data we need for the abort record */
1845 nrels = smgrGetPendingDeletes(false, &rels);
1848
1849 /* XXX do we really need a critical section here? */
1851
1852 /* Write the ABORT record */
1853 if (isSubXact)
1854 xact_time = GetCurrentTimestamp();
1855 else
1856 {
1858 }
1859
1860 XactLogAbortRecord(xact_time,
1861 nchildren, children,
1862 nrels, rels,
1865 NULL);
1866
1867 if (replorigin)
1868 /* Move LSNs forward for this replication origin */
1871
1872 /*
1873 * Report the latest async abort LSN, so that the WAL writer knows to
1874 * flush this abort. There's nothing to be gained by delaying this, since
1875 * WALWriter may as well do this when it can. This is important with
1876 * streaming replication because if we don't flush WAL regularly we will
1877 * find that large aborts leave us with a long backlog for when commits
1878 * occur after the abort, increasing our window of data loss should
1879 * problems occur at that point.
1880 */
1881 if (!isSubXact)
1883
1884 /*
1885 * Mark the transaction aborted in clog. This is not absolutely necessary
1886 * but we may as well do it while we are here; also, in the subxact case
1887 * it is helpful because XactLockTableWait makes use of it to avoid
1888 * waiting for already-aborted subtransactions. It is OK to do it without
1889 * having flushed the ABORT record to disk, because in event of a crash
1890 * we'd be assumed to have aborted anyway.
1891 */
1892 TransactionIdAbortTree(xid, nchildren, children);
1893
1895
1896 /* Compute latestXid while we have the child XIDs handy */
1897 latestXid = TransactionIdLatest(xid, nchildren, children);
1898
1899 /*
1900 * If we're aborting a subtransaction, we can immediately remove failed
1901 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1902 * subxacts, because we already have the child XID array at hand. For
1903 * main xacts, the equivalent happens just after this function returns.
1904 */
1905 if (isSubXact)
1907
1908 /* Reset XactLastRecEnd until the next transaction writes something */
1909 if (!isSubXact)
1910 XactLastRecEnd = 0;
1911
1912 /* And clean up local data */
1913 if (rels)
1914 pfree(rels);
1915 if (ndroppedstats)
1917
1918 return latestXid;
1919}
1920
1921/*
1922 * AtAbort_Memory
1923 */
1924static void
1925AtAbort_Memory(void)
1926{
1927 /*
1928 * Switch into TransactionAbortContext, which should have some free space
1929 * even if nothing else does. We'll work in this context until we've
1930 * finished cleaning up.
1931 *
1932 * It is barely possible to get here when we've not been able to create
1933 * TransactionAbortContext yet; if so use TopMemoryContext.
1934 */
1937 else
1939}
1940
1941/*
1942 * AtSubAbort_Memory
1943 */
1944static void
1946{
1948
1950}
1951
1952
1953/*
1954 * AtAbort_ResourceOwner
1955 */
1956static void
1958{
1959 /*
1960 * Make sure we have a valid ResourceOwner, if possible (else it will be
1961 * NULL, which is OK)
1962 */
1964}
1965
1966/*
1967 * AtSubAbort_ResourceOwner
1968 */
1969static void
1971{
1973
1974 /* Make sure we have a valid ResourceOwner */
1976}
1977
1978
1979/*
1980 * AtSubAbort_childXids
1981 */
1982static void
1984{
1986
1987 /*
1988 * We keep the child-XID arrays in TopTransactionContext (see
1989 * AtSubCommit_childXids). This means we'd better free the array
1990 * explicitly at abort to avoid leakage.
1991 */
1992 if (s->childXids != NULL)
1993 pfree(s->childXids);
1994 s->childXids = NULL;
1995 s->nChildXids = 0;
1996 s->maxChildXids = 0;
1997
1998 /*
1999 * We could prune the unreportedXids array here. But we don't bother. That
2000 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
2001 * would likely introduce more CPU time into the more common paths, so we
2002 * choose not to do that.
2003 */
2004}
2005
2006/* ----------------------------------------------------------------
2007 * CleanupTransaction stuff
2008 * ----------------------------------------------------------------
2009 */
2010
2011/*
2012 * AtCleanup_Memory
2013 */
2014static void
2015AtCleanup_Memory(void)
2016{
2018
2019 /* Should be at top level */
2020 Assert(s->parent == NULL);
2021
2022 /*
2023 * Return to the memory context that was current before we started the
2024 * transaction. (In principle, this could not be any of the contexts we
2025 * are about to delete. If it somehow is, assertions in mcxt.c will
2026 * complain.)
2027 */
2029
2030 /*
2031 * Clear the special abort context for next time.
2032 */
2035
2036 /*
2037 * Release all transaction-local memory, the same as in AtCommit_Memory,
2038 * except we must cope with the possibility that we didn't get as far as
2039 * creating TopTransactionContext.
2040 */
2043
2044 /*
2045 * Clear these pointers as a pro-forma matter. (Notionally, while
2046 * TopTransactionContext still exists, it's currently not associated with
2047 * this TransactionState struct.)
2048 */
2051}
2052
2053
2054/* ----------------------------------------------------------------
2055 * CleanupSubTransaction stuff
2056 * ----------------------------------------------------------------
2057 */
2058
2059/*
2060 * AtSubCleanup_Memory
2061 */
2062static void
2064{
2066
2067 Assert(s->parent != NULL);
2068
2069 /*
2070 * Return to the memory context that was current before we started the
2071 * subtransaction. (In principle, this could not be any of the contexts
2072 * we are about to delete. If it somehow is, assertions in mcxt.c will
2073 * complain.)
2074 */
2076
2077 /* Update CurTransactionContext (might not be same as priorContext) */
2079
2080 /*
2081 * Clear the special abort context for next time.
2082 */
2085
2086 /*
2087 * Delete the subxact local memory contexts. Its CurTransactionContext can
2088 * go too (note this also kills CurTransactionContexts from any children
2089 * of the subxact).
2090 */
2091 if (s->curTransactionContext)
2094}
2095
2096/* ----------------------------------------------------------------
2097 * interface routines
2098 * ----------------------------------------------------------------
2099 */
2100
2101/*
2102 * StartTransaction
2103 */
2104static void
2105StartTransaction(void)
2106{
2109
2110 /*
2111 * Let's just make sure the state stack is empty
2112 */
2115
2117
2118 /* check the current transaction state */
2119 Assert(s->state == TRANS_DEFAULT);
2120
2121 /*
2122 * Set the current transaction state information appropriately during
2123 * start processing. Note that once the transaction status is switched
2124 * this process cannot fail until the user ID and the security context
2125 * flags are fetched below.
2126 */
2127 s->state = TRANS_START;
2128 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
2129
2130 /* Determine if statements are logged in this transaction */
2132 (log_xact_sample_rate == 1 ||
2134
2135 /*
2136 * initialize current transaction state fields
2137 *
2138 * note: prevXactReadOnly is not used at the outermost level
2139 */
2140 s->nestingLevel = 1;
2141 s->gucNestLevel = 1;
2142 s->childXids = NULL;
2143 s->nChildXids = 0;
2144 s->maxChildXids = 0;
2145
2146 /*
2147 * Once the current user ID and the security context flags are fetched,
2148 * both will be properly reset even if transaction startup fails.
2149 */
2151
2152 /* SecurityRestrictionContext should never be set outside a transaction */
2153 Assert(s->prevSecContext == 0);
2154
2155 /*
2156 * Make sure we've reset xact state variables
2157 *
2158 * If recovery is still in progress, mark this transaction as read-only.
2159 * We have lower level defences in XLogInsert and elsewhere to stop us
2160 * from modifying data during recovery, but this gives the normal
2161 * indication to the user that the transaction is read-only.
2162 */
2163 if (RecoveryInProgress())
2164 {
2165 s->startedInRecovery = true;
2166 XactReadOnly = true;
2167 }
2168 else
2169 {
2170 s->startedInRecovery = false;
2172 }
2175 forceSyncCommit = false;
2176 MyXactFlags = 0;
2177
2178 /*
2179 * reinitialize within-transaction counters
2180 */
2184 currentCommandIdUsed = false;
2185
2186 /*
2187 * initialize reported xid accounting
2188 */
2189 nUnreportedXids = 0;
2190 s->didLogXid = false;
2191
2192 /*
2193 * must initialize resource-management stuff first
2194 */
2197
2198 /*
2199 * Assign a new LocalTransactionId, and combine it with the proc number to
2200 * form a virtual transaction id.
2201 */
2202 vxid.procNumber = MyProcNumber;
2204
2205 /*
2206 * Lock the virtual transaction id before we announce it in the proc array
2207 */
2209
2210 /*
2211 * Advertise it in the proc array. We assume assignment of
2212 * localTransactionId is atomic, and the proc number should be set
2213 * already.
2214 */
2217
2219
2220 /*
2221 * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2222 * be the same as the first command's statement_timestamp(), so don't do a
2223 * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2224 * for transactions started inside procedures (i.e., nonatomic SPI
2225 * contexts), we do need to advance the timestamp. Also, in a parallel
2226 * worker, the timestamp should already have been provided by a call to
2227 * SetParallelStartTimestamps().
2228 */
2229 if (!IsParallelWorker())
2230 {
2233 else
2235 }
2236 else
2239 /* Mark xactStopTimestamp as unset. */
2241
2242 /*
2243 * initialize other subsystems for new transaction
2244 */
2245 AtStart_GUC();
2246 AtStart_Cache();
2248
2249 /*
2250 * done with start processing, set current transaction state to "in
2251 * progress"
2252 */
2254
2255 /* Schedule transaction timeout */
2256 if (TransactionTimeout > 0)
2258
2259 ShowTransactionState("StartTransaction");
2260}
2261
2262
2263/*
2264 * CommitTransaction
2265 *
2266 * NB: if you change this routine, better look at PrepareTransaction too!
2267 */
2268static void
2270{
2273 bool is_parallel_worker;
2274
2276
2277 /* Enforce parallel mode restrictions during parallel worker commit. */
2280
2281 ShowTransactionState("CommitTransaction");
2282
2283 /*
2284 * check the current transaction state
2285 */
2286 if (s->state != TRANS_INPROGRESS)
2287 elog(WARNING, "CommitTransaction while in %s state",
2289 Assert(s->parent == NULL);
2290
2291 /*
2292 * Do pre-commit processing that involves calling user-defined code, such
2293 * as triggers. SECURITY_RESTRICTED_OPERATION contexts must not queue an
2294 * action that would run here, because that would bypass the sandbox.
2295 * Since closing cursors could queue trigger actions, triggers could open
2296 * cursors, etc, we have to keep looping until there's nothing left to do.
2297 */
2298 for (;;)
2299 {
2300 /*
2301 * Fire all currently pending deferred triggers.
2302 */
2304
2305 /*
2306 * Close open portals (converting holdable ones into static portals).
2307 * If there weren't any, we are done ... otherwise loop back to check
2308 * if they queued deferred triggers. Lather, rinse, repeat.
2309 */
2310 if (!PreCommit_Portals(false))
2311 break;
2312 }
2313
2314 /*
2315 * The remaining actions cannot call any user-defined code, so it's safe
2316 * to start shutting down within-transaction services. But note that most
2317 * of this stuff could still throw an error, which would switch us into
2318 * the transaction-abort path.
2319 */
2320
2323
2324 /*
2325 * If this xact has started any unfinished parallel operation, clean up
2326 * its workers, warning about leaked resources. (But we don't actually
2327 * reset parallelModeLevel till entering TRANS_COMMIT, a bit below. This
2328 * keeps parallel mode restrictions active as long as possible in a
2329 * parallel worker.)
2330 */
2331 AtEOXact_Parallel(true);
2333 {
2334 if (s->parallelModeLevel != 1)
2335 elog(WARNING, "parallelModeLevel is %d not 1 at end of parallel worker transaction",
2337 }
2338 else
2339 {
2340 if (s->parallelModeLevel != 0)
2341 elog(WARNING, "parallelModeLevel is %d not 0 at end of transaction",
2343 }
2344
2345 /* Shut down the deferred-trigger manager */
2346 AfterTriggerEndXact(true);
2347
2348 /*
2349 * Let ON COMMIT management do its thing (must happen after closing
2350 * cursors, to avoid dangling-reference problems)
2351 */
2353
2354 /*
2355 * Synchronize files that are created and not WAL-logged during this
2356 * transaction. This must happen before AtEOXact_RelationMap(), so that we
2357 * don't see committed-but-broken files after a crash.
2358 */
2360
2361 /* close large objects before lower-level cleanup */
2363
2364 /*
2365 * Insert notifications sent by NOTIFY commands into the queue. This
2366 * should be late in the pre-commit sequence to minimize time spent
2367 * holding the notify-insertion lock. However, this could result in
2368 * creating a snapshot, so we must do it before serializable cleanup.
2369 */
2371
2372 /*
2373 * Mark serializable transaction as complete for predicate locking
2374 * purposes. This should be done as late as we can put it and still allow
2375 * errors to be raised for failure patterns found at commit. This is not
2376 * appropriate in a parallel worker however, because we aren't committing
2377 * the leader's transaction and its serializable state will live on.
2378 */
2379 if (!is_parallel_worker)
2381
2382 /* Prevent cancel/die interrupt while cleaning up */
2384
2385 /* Commit updates to the relation map --- do this as late as possible */
2387
2388 /*
2389 * set the current transaction state information appropriately during
2390 * commit processing
2391 */
2392 s->state = TRANS_COMMIT;
2393 s->parallelModeLevel = 0;
2394 s->parallelChildXact = false; /* should be false already */
2395
2396 /* Disable transaction timeout */
2397 if (TransactionTimeout > 0)
2399
2400 if (!is_parallel_worker)
2401 {
2402 /*
2403 * We need to mark our XIDs as committed in pg_xact. This is where we
2404 * durably commit.
2405 */
2407 }
2408 else
2409 {
2410 /*
2411 * We must not mark our XID committed; the parallel leader is
2412 * responsible for that.
2413 */
2415
2416 /*
2417 * Make sure the leader will know about any WAL we wrote before it
2418 * commits.
2419 */
2421 }
2422
2424
2425 /*
2426 * Let others know about no transaction in progress by me. Note that this
2427 * must be done _before_ releasing locks we hold and _after_
2428 * RecordTransactionCommit.
2429 */
2431
2432 /*
2433 * This is all post-commit cleanup. Note that if an error is raised here,
2434 * it's too late to abort the transaction. This should be just
2435 * noncritical resource releasing.
2436 *
2437 * The ordering of operations is not entirely random. The idea is:
2438 * release resources visible to other backends (eg, files, buffer pins);
2439 * then release locks; then release backend-local resources. We want to
2440 * release locks at the point where any backend waiting for us will see
2441 * our transaction as being fully cleaned up.
2442 *
2443 * Resources that can be associated with individual queries are handled by
2444 * the ResourceOwner mechanism. The other calls here are for backend-wide
2445 * state.
2446 */
2447
2450
2454 true, true);
2455
2456 AtEOXact_Aio(true);
2457
2458 /* Check we've released all buffer pins */
2459 AtEOXact_Buffers(true);
2460
2461 /* Clean up the relation cache */
2463
2464 /* Clean up the type cache */
2466
2467 /*
2468 * Make catalog changes visible to all backends. This has to happen after
2469 * relcache references are dropped (see comments for
2470 * AtEOXact_RelationCache), but before locks are released (if anyone is
2471 * waiting for lock on a relation we've modified, we want them to know
2472 * about the catalog change before they start using the relation).
2473 */
2474 AtEOXact_Inval(true);
2475
2477
2480 true, true);
2483 true, true);
2484
2485 /*
2486 * Likewise, dropping of files deleted during the transaction is best done
2487 * after releasing relcache and buffer pins. (This is not strictly
2488 * necessary during commit, since such pins should have been released
2489 * already, but this ordering is definitely critical during abort.) Since
2490 * this may take many seconds, also delay until after releasing locks.
2491 * Other backends will observe the attendant catalog changes and not
2492 * attempt to access affected files.
2493 */
2495
2496 /*
2497 * Send out notification signals to other backends (and do other
2498 * post-commit NOTIFY cleanup). This must not happen until after our
2499 * transaction is fully done from the viewpoint of other backends.
2500 */
2502
2503 /*
2504 * Everything after this should be purely internal-to-this-backend
2505 * cleanup.
2506 */
2507 AtEOXact_GUC(true, 1);
2508 AtEOXact_SPI(true);
2509 AtEOXact_Enum();
2512 AtEOXact_SMgr();
2513 AtEOXact_Files(true);
2515 AtEOXact_HashTables(true);
2517 AtEOXact_Snapshot(true, false);
2522
2527
2529
2532 s->nestingLevel = 0;
2533 s->gucNestLevel = 0;
2534 s->childXids = NULL;
2535 s->nChildXids = 0;
2536 s->maxChildXids = 0;
2537
2540
2541 /*
2542 * done with commit processing, set current transaction state back to
2543 * default
2544 */
2545 s->state = TRANS_DEFAULT;
2546
2548}
2549
2550
2551/*
2552 * PrepareTransaction
2553 *
2554 * NB: if you change this routine, better look at CommitTransaction too!
2555 */
2556static void
2558{
2562 TimestampTz prepared_at;
2563
2565
2566 ShowTransactionState("PrepareTransaction");
2567
2568 /*
2569 * check the current transaction state
2570 */
2571 if (s->state != TRANS_INPROGRESS)
2572 elog(WARNING, "PrepareTransaction while in %s state",
2574 Assert(s->parent == NULL);
2575
2576 /*
2577 * Do pre-commit processing that involves calling user-defined code, such
2578 * as triggers. Since closing cursors could queue trigger actions,
2579 * triggers could open cursors, etc, we have to keep looping until there's
2580 * nothing left to do.
2581 */
2582 for (;;)
2583 {
2584 /*
2585 * Fire all currently pending deferred triggers.
2586 */
2588
2589 /*
2590 * Close open portals (converting holdable ones into static portals).
2591 * If there weren't any, we are done ... otherwise loop back to check
2592 * if they queued deferred triggers. Lather, rinse, repeat.
2593 */
2594 if (!PreCommit_Portals(true))
2595 break;
2596 }
2597
2599
2600 /*
2601 * The remaining actions cannot call any user-defined code, so it's safe
2602 * to start shutting down within-transaction services. But note that most
2603 * of this stuff could still throw an error, which would switch us into
2604 * the transaction-abort path.
2605 */
2606
2607 /* Shut down the deferred-trigger manager */
2608 AfterTriggerEndXact(true);
2609
2610 /*
2611 * Let ON COMMIT management do its thing (must happen after closing
2612 * cursors, to avoid dangling-reference problems)
2613 */
2615
2616 /*
2617 * Synchronize files that are created and not WAL-logged during this
2618 * transaction. This must happen before EndPrepare(), so that we don't see
2619 * committed-but-broken files after a crash and COMMIT PREPARED.
2620 */
2621 smgrDoPendingSyncs(true, false);
2622
2623 /* close large objects before lower-level cleanup */
2625
2626 /* NOTIFY requires no work at this point */
2627
2628 /*
2629 * Mark serializable transaction as complete for predicate locking
2630 * purposes. This should be done as late as we can put it and still allow
2631 * errors to be raised for failure patterns found at commit.
2632 */
2634
2635 /*
2636 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2637 * this transaction. Having the prepared xact hold locks on another
2638 * backend's temp table seems a bad idea --- for instance it would prevent
2639 * the backend from exiting. There are other problems too, such as how to
2640 * clean up the source backend's local buffers and ON COMMIT state if the
2641 * prepared xact includes a DROP of a temp table.
2642 *
2643 * Other objects types, like functions, operators or extensions, share the
2644 * same restriction as they should not be created, locked or dropped as
2645 * this can mess up with this session or even a follow-up session trying
2646 * to use the same temporary namespace.
2647 *
2648 * We must check this after executing any ON COMMIT actions, because they
2649 * might still access a temp relation.
2650 *
2651 * XXX In principle this could be relaxed to allow some useful special
2652 * cases, such as a temp table created and dropped all within the
2653 * transaction. That seems to require much more bookkeeping though.
2654 */
2656 ereport(ERROR,
2658 errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2659
2660 /*
2661 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2662 * supported if we added cleanup logic to twophase.c, but for now it
2663 * doesn't seem worth the trouble.
2664 */
2666 ereport(ERROR,
2668 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2669
2670 /* Prevent cancel/die interrupt while cleaning up */
2672
2673 /*
2674 * set the current transaction state information appropriately during
2675 * prepare processing
2676 */
2677 s->state = TRANS_PREPARE;
2678
2679 /* Disable transaction timeout */
2680 if (TransactionTimeout > 0)
2682
2683 prepared_at = GetCurrentTimestamp();
2684
2685 /*
2686 * Reserve the GID for this transaction. This could fail if the requested
2687 * GID is invalid or already in use.
2688 */
2689 gxact = MarkAsPreparing(fxid, prepareGID, prepared_at,
2691 prepareGID = NULL;
2692
2693 /*
2694 * Collect data for the 2PC state file. Note that in general, no actual
2695 * state change should happen in the called modules during this step,
2696 * since it's still possible to fail before commit, and in that case we
2697 * want transaction abort to be able to clean up. (In particular, the
2698 * AtPrepare routines may error out if they find cases they cannot
2699 * handle.) State cleanup should happen in the PostPrepare routines
2700 * below. However, some modules can go ahead and clear state here because
2701 * they wouldn't do anything with it during abort anyway.
2702 *
2703 * Note: because the 2PC state file records will be replayed in the same
2704 * order they are made, the order of these calls has to match the order in
2705 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2706 * PREPARED; in particular, pay attention to whether things should happen
2707 * before or after releasing the transaction's locks.
2708 */
2710
2717
2718 /*
2719 * Here is where we really truly prepare.
2720 *
2721 * We have to record transaction prepares even if we didn't make any
2722 * updates, because the transaction manager might get confused if we lose
2723 * a global transaction.
2724 */
2726
2727 /*
2728 * Now we clean up backend-internal state and release internal resources.
2729 */
2730
2731 /* Reset XactLastRecEnd until the next transaction writes something */
2732 XactLastRecEnd = 0;
2733
2734 /*
2735 * Transfer our locks to a dummy PGPROC. This has to be done before
2736 * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2737 * conclude "xact already committed or aborted" for our locks.
2738 */
2739 PostPrepare_Locks(fxid);
2740
2741 /*
2742 * Let others know about no transaction in progress by me. This has to be
2743 * done *after* the prepared transaction has been marked valid, else
2744 * someone may think it is unlocked and recyclable.
2745 */
2747
2748 /*
2749 * In normal commit-processing, this is all non-critical post-transaction
2750 * cleanup. When the transaction is prepared, however, it's important
2751 * that the locks and other per-backend resources are transferred to the
2752 * prepared transaction's PGPROC entry. Note that if an error is raised
2753 * here, it's too late to abort the transaction. XXX: This probably should
2754 * be in a critical section, to force a PANIC if any of this fails, but
2755 * that cure could be worse than the disease.
2756 */
2757
2759
2762 true, true);
2763
2764 AtEOXact_Aio(true);
2765
2766 /* Check we've released all buffer pins */
2767 AtEOXact_Buffers(true);
2768
2769 /* Clean up the relation cache */
2771
2772 /* Clean up the type cache */
2774
2775 /* notify doesn't need a postprepare call */
2776
2778
2780
2782
2784
2786
2789 true, true);
2792 true, true);
2793
2794 /*
2795 * Allow another backend to finish the transaction. After
2796 * PostPrepare_Twophase(), the transaction is completely detached from our
2797 * backend. The rest is just non-critical cleanup of backend-local state.
2798 */
2800
2801 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2802 AtEOXact_GUC(true, 1);
2803 AtEOXact_SPI(true);
2804 AtEOXact_Enum();
2806 AtEOXact_Namespace(true, false);
2807 AtEOXact_SMgr();
2808 AtEOXact_Files(true);
2810 AtEOXact_HashTables(true);
2811 /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2812 AtEOXact_Snapshot(true, true);
2813 /* we treat PREPARE as ROLLBACK so far as waking workers goes */
2818
2824
2826
2829 s->nestingLevel = 0;
2830 s->gucNestLevel = 0;
2831 s->childXids = NULL;
2832 s->nChildXids = 0;
2833 s->maxChildXids = 0;
2834
2837
2838 /*
2839 * done with 1st phase commit processing, set current transaction state
2840 * back to default
2841 */
2842 s->state = TRANS_DEFAULT;
2843
2845}
2846
2847
2848/*
2849 * AbortTransaction
2850 */
2851static void
2852AbortTransaction(void)
2853{
2856 bool is_parallel_worker;
2857
2858 /* Prevent cancel/die interrupt while cleaning up */
2860
2861 /* Disable transaction timeout */
2862 if (TransactionTimeout > 0)
2864
2865 /* Make sure we have a valid memory context and resource owner */
2868
2869 /*
2870 * Release any LW locks we might be holding as quickly as possible.
2871 * (Regular locks, however, must be held till we finish aborting.)
2872 * Releasing LW locks is critical since we might try to grab them again
2873 * while cleaning up!
2874 */
2876
2877 /*
2878 * Cleanup waiting for LSN if any.
2879 */
2881
2882 /* Clear wait information and command progress indicator */
2885
2887
2888 /* Clean up buffer content locks, too */
2889 UnlockBuffers();
2890
2891 /* Reset WAL record construction state */
2893
2894 /* Cancel condition variable sleep */
2896
2897 /*
2898 * Also clean up any open wait for lock, since the lock manager will choke
2899 * if we try to wait for another lock before doing this.
2900 */
2902
2903 /*
2904 * If any timeout events are still active, make sure the timeout interrupt
2905 * is scheduled. This covers possible loss of a timeout interrupt due to
2906 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2907 * We delay this till after LockErrorCleanup so that we don't uselessly
2908 * reschedule lock or deadlock check timeouts.
2909 */
2911
2912 /*
2913 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2914 * handler. We do this fairly early in the sequence so that the timeout
2915 * infrastructure will be functional if needed while aborting.
2916 */
2918
2919 /*
2920 * check the current transaction state
2921 */
2923 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2924 elog(WARNING, "AbortTransaction while in %s state",
2926 Assert(s->parent == NULL);
2927
2928 /*
2929 * set the current transaction state information appropriately during the
2930 * abort processing
2931 */
2932 s->state = TRANS_ABORT;
2933
2934 /*
2935 * Reset user ID which might have been changed transiently. We need this
2936 * to clean up in case control escaped out of a SECURITY DEFINER function
2937 * or other local change of CurrentUserId; therefore, the prior value of
2938 * SecurityRestrictionContext also needs to be restored.
2939 *
2940 * (Note: it is not necessary to restore session authorization or role
2941 * settings here because those can only be changed via GUC, and GUC will
2942 * take care of rolling them back if need be.)
2943 */
2945
2946 /* Forget about any active REINDEX. */
2948
2949 /* Reset logical streaming state. */
2951
2952 /* Reset snapshot export state. */
2954
2955 /*
2956 * If this xact has started any unfinished parallel operation, clean up
2957 * its workers and exit parallel mode. Don't warn about leaked resources.
2958 */
2959 AtEOXact_Parallel(false);
2960 s->parallelModeLevel = 0;
2961 s->parallelChildXact = false; /* should be false already */
2962
2963 /*
2964 * do abort processing
2965 */
2966 AfterTriggerEndXact(false); /* 'false' means it's abort */
2969 AtEOXact_LargeObject(false);
2973
2974 /*
2975 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2976 * far as assigning an XID to advertise). But if we're inside a parallel
2977 * worker, skip this; the user backend must be the one to write the abort
2978 * record.
2979 */
2980 if (!is_parallel_worker)
2982 else
2983 {
2985
2986 /*
2987 * Since the parallel leader won't get our value of XactLastRecEnd in
2988 * this case, we nudge WAL-writer ourselves in this case. See related
2989 * comments in RecordTransactionAbort for why this matters.
2990 */
2992 }
2993
2995
2996 /*
2997 * Let others know about no transaction in progress by me. Note that this
2998 * must be done _before_ releasing locks we hold and _after_
2999 * RecordTransactionAbort.
3000 */
3002
3003 /*
3004 * Post-abort cleanup. See notes in CommitTransaction() concerning
3005 * ordering. We can skip all of it if the transaction failed before
3006 * creating a resource owner.
3007 */
3009 {
3012 else
3014
3017 false, true);
3018 AtEOXact_Aio(false);
3019 AtEOXact_Buffers(false);
3022 AtEOXact_Inval(false);
3026 false, true);
3029 false, true);
3030 smgrDoPendingDeletes(false);
3031
3032 AtEOXact_GUC(false, 1);
3033 AtEOXact_SPI(false);
3034 AtEOXact_Enum();
3037 AtEOXact_SMgr();
3038 AtEOXact_Files(false);
3040 AtEOXact_HashTables(false);
3046 }
3047
3048 /*
3049 * State remains TRANS_ABORT until CleanupTransaction().
3050 */
3052}
3053
3054/*
3055 * CleanupTransaction
3056 */
3057static void
3059{
3061
3062 /*
3063 * State should still be TRANS_ABORT from AbortTransaction().
3064 */
3065 if (s->state != TRANS_ABORT)
3066 elog(FATAL, "CleanupTransaction: unexpected state %s",
3068
3069 /*
3070 * do abort cleanup processing
3071 */
3072 AtCleanup_Portals(); /* now safe to release portal memory */
3073 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
3074
3075 CurrentResourceOwner = NULL; /* and resource owner */
3081
3082 AtCleanup_Memory(); /* and transaction memory */
3083
3086 s->nestingLevel = 0;
3087 s->gucNestLevel = 0;
3088 s->childXids = NULL;
3089 s->nChildXids = 0;
3090 s->maxChildXids = 0;
3091 s->parallelModeLevel = 0;
3092 s->parallelChildXact = false;
3093
3096
3097 /*
3098 * done with abort processing, set current transaction state back to
3099 * default
3100 */
3101 s->state = TRANS_DEFAULT;
3102}
3103
3104/*
3105 * StartTransactionCommand
3106 */
3107void
3109{
3111
3112 switch (s->blockState)
3113 {
3114 /*
3115 * if we aren't in a transaction block, we just do our usual start
3116 * transaction.
3117 */
3118 case TBLOCK_DEFAULT:
3121 break;
3122
3123 /*
3124 * We are somewhere in a transaction block or subtransaction and
3125 * about to start a new command. For now we do nothing, but
3126 * someday we may do command-local resource initialization. (Note
3127 * that any needed CommandCounterIncrement was done by the
3128 * previous CommitTransactionCommand.)
3129 */
3130 case TBLOCK_INPROGRESS:
3133 break;
3134
3135 /*
3136 * Here we are in a failed transaction block (one of the commands
3137 * caused an abort) so we do nothing but remain in the abort
3138 * state. Eventually we will get a ROLLBACK command which will
3139 * get us out of this state. (It is up to other code to ensure
3140 * that no commands other than ROLLBACK will be processed in these
3141 * states.)
3142 */
3143 case TBLOCK_ABORT:
3144 case TBLOCK_SUBABORT:
3145 break;
3146
3147 /* These cases are invalid. */
3148 case TBLOCK_STARTED:
3149 case TBLOCK_BEGIN:
3151 case TBLOCK_SUBBEGIN:
3152 case TBLOCK_END:
3153 case TBLOCK_SUBRELEASE:
3154 case TBLOCK_SUBCOMMIT:
3155 case TBLOCK_ABORT_END:
3159 case TBLOCK_SUBRESTART:
3161 case TBLOCK_PREPARE:
3162 elog(ERROR, "StartTransactionCommand: unexpected state %s",
3164 break;
3165 }
3166
3167 /*
3168 * We must switch to CurTransactionContext before returning. This is
3169 * already done if we called StartTransaction, otherwise not.
3170 */
3173}
3174
3175
3176/*
3177 * Simple system for saving and restoring transaction characteristics
3178 * (isolation level, read only, deferrable). We need this for transaction
3179 * chaining, so that we can set the characteristics of the new transaction to
3180 * be the same as the previous one. (We need something like this because the
3181 * GUC system resets the characteristics at transaction end, so for example
3182 * just skipping the reset in StartTransaction() won't work.)
3183 */
3184void
3186{
3190}
3191
3192void
3194{
3198}
3199
3200/*
3201 * CommitTransactionCommand -- a wrapper function handling the
3202 * loop over subtransactions to avoid a potentially dangerous recursion
3203 * in CommitTransactionCommandInternal().
3204 */
3205void
3207{
3208 /*
3209 * Repeatedly call CommitTransactionCommandInternal() until all the work
3210 * is done.
3211 */
3213 {
3214 }
3215}
3216
3217/*
3218 * CommitTransactionCommandInternal - a function doing an iteration of work
3219 * regarding handling the commit transaction command. In the case of
3220 * subtransactions more than one iterations could be required. Returns
3221 * true when no more iterations required, false otherwise.
3222 */
3223static bool
3225{
3228
3229 /* Must save in case we need to restore below */
3231
3232 switch (s->blockState)
3233 {
3234 /*
3235 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3236 * StartTransactionCommand didn't set the STARTED state
3237 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3238 * by EndParallelWorkerTransaction(), not this function.
3239 */
3240 case TBLOCK_DEFAULT:
3242 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3244 break;
3245
3246 /*
3247 * If we aren't in a transaction block, just do our usual
3248 * transaction commit, and return to the idle state.
3249 */
3250 case TBLOCK_STARTED:
3253 break;
3254
3255 /*
3256 * We are completing a "BEGIN TRANSACTION" command, so we change
3257 * to the "transaction block in progress" state and return. (We
3258 * assume the BEGIN did nothing to the database, so we need no
3259 * CommandCounterIncrement.)
3260 */
3261 case TBLOCK_BEGIN:
3263 break;
3264
3265 /*
3266 * This is the case when we have finished executing a command
3267 * someplace within a transaction block. We increment the command
3268 * counter and return.
3269 */
3270 case TBLOCK_INPROGRESS:
3274 break;
3275
3276 /*
3277 * We are completing a "COMMIT" command. Do it and return to the
3278 * idle state.
3279 */
3280 case TBLOCK_END:
3283 if (s->chain)
3284 {
3287 s->chain = false;
3289 }
3290 break;
3291
3292 /*
3293 * Here we are in the middle of a transaction block but one of the
3294 * commands caused an abort so we do nothing but remain in the
3295 * abort state. Eventually we will get a ROLLBACK command.
3296 */
3297 case TBLOCK_ABORT:
3298 case TBLOCK_SUBABORT:
3299 break;
3300
3301 /*
3302 * Here we were in an aborted transaction block and we just got
3303 * the ROLLBACK command from the user, so clean up the
3304 * already-aborted transaction and return to the idle state.
3305 */
3306 case TBLOCK_ABORT_END:
3309 if (s->chain)
3310 {
3313 s->chain = false;
3315 }
3316 break;
3317
3318 /*
3319 * Here we were in a perfectly good transaction block but the user
3320 * told us to ROLLBACK anyway. We have to abort the transaction
3321 * and then clean up.
3322 */
3327 if (s->chain)
3328 {
3331 s->chain = false;
3333 }
3334 break;
3335
3336 /*
3337 * We are completing a "PREPARE TRANSACTION" command. Do it and
3338 * return to the idle state.
3339 */
3340 case TBLOCK_PREPARE:
3343 break;
3344
3345 /*
3346 * The user issued a SAVEPOINT inside a transaction block. Start a
3347 * subtransaction. (DefineSavepoint already did PushTransaction,
3348 * so as to have someplace to put the SUBBEGIN state.)
3349 */
3350 case TBLOCK_SUBBEGIN:
3353 break;
3354
3355 /*
3356 * The user issued a RELEASE command, so we end the current
3357 * subtransaction and return to the parent transaction. The parent
3358 * might be ended too, so repeat till we find an INPROGRESS
3359 * transaction or subtransaction.
3360 */
3361 case TBLOCK_SUBRELEASE:
3362 do
3363 {
3365 s = CurrentTransactionState; /* changed by pop */
3366 } while (s->blockState == TBLOCK_SUBRELEASE);
3367
3370 break;
3371
3372 /*
3373 * The user issued a COMMIT, so we end the current subtransaction
3374 * hierarchy and perform final commit. We do this by rolling up
3375 * any subtransactions into their parent, which leads to O(N^2)
3376 * operations with respect to resource owners - this isn't that
3377 * bad until we approach a thousands of savepoints but is
3378 * necessary for correctness should after triggers create new
3379 * resource owners.
3380 */
3381 case TBLOCK_SUBCOMMIT:
3382 do
3383 {
3385 s = CurrentTransactionState; /* changed by pop */
3386 } while (s->blockState == TBLOCK_SUBCOMMIT);
3387 /* If we had a COMMIT command, finish off the main xact too */
3388 if (s->blockState == TBLOCK_END)
3389 {
3390 Assert(s->parent == NULL);
3393 if (s->chain)
3394 {
3397 s->chain = false;
3399 }
3400 }
3401 else if (s->blockState == TBLOCK_PREPARE)
3402 {
3403 Assert(s->parent == NULL);
3406 }
3407 else
3408 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3410 break;
3411
3412 /*
3413 * The current already-failed subtransaction is ending due to a
3414 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3415 * examine the parent (which could be in any of several states).
3416 * As we need to examine the parent, return false to request the
3417 * caller to do the next iteration.
3418 */
3421 return false;
3422
3423 /*
3424 * As above, but it's not dead yet, so abort first.
3425 */
3429 return false;
3430
3431 /*
3432 * The current subtransaction is the target of a ROLLBACK TO
3433 * command. Abort and pop it, then start a new subtransaction
3434 * with the same name.
3435 */
3436 case TBLOCK_SUBRESTART:
3437 {
3438 char *name;
3439 int savepointLevel;
3440
3441 /* save name and keep Cleanup from freeing it */
3442 name = s->name;
3443 s->name = NULL;
3444 savepointLevel = s->savepointLevel;
3445
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 * Same as above, but the subtransaction had already failed, so we
3463 * don't need AbortSubTransaction.
3464 */
3466 {
3467 char *name;
3468 int savepointLevel;
3469
3470 /* save name and keep Cleanup from freeing it */
3471 name = s->name;
3472 s->name = NULL;
3473 savepointLevel = s->savepointLevel;
3474
3476
3478 s = CurrentTransactionState; /* changed by push */
3479 s->name = name;
3480 s->savepointLevel = savepointLevel;
3481
3482 /* This is the same as TBLOCK_SUBBEGIN case */
3486 }
3487 break;
3488 }
3489
3490 /* Done, no more iterations required */
3491 return true;
3492}
3493
3494/*
3495 * AbortCurrentTransaction -- a wrapper function handling the
3496 * loop over subtransactions to avoid potentially dangerous recursion in
3497 * AbortCurrentTransactionInternal().
3498 */
3499void
3501{
3502 /*
3503 * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3504 * done.
3505 */
3507 {
3508 }
3509}
3510
3511/*
3512 * AbortCurrentTransactionInternal - a function doing an iteration of work
3513 * regarding handling the current transaction abort. In the case of
3514 * subtransactions more than one iterations could be required. Returns
3515 * true when no more iterations required, false otherwise.
3516 */
3517static bool
3519{
3521
3522 switch (s->blockState)
3523 {
3524 case TBLOCK_DEFAULT:
3525 if (s->state == TRANS_DEFAULT)
3526 {
3527 /* we are idle, so nothing to do */
3528 }
3529 else
3530 {
3531 /*
3532 * We can get here after an error during transaction start
3533 * (state will be TRANS_START). Need to clean up the
3534 * incompletely started transaction. First, adjust the
3535 * low-level state to suppress warning message from
3536 * AbortTransaction.
3537 */
3538 if (s->state == TRANS_START)
3542 }
3543 break;
3544
3545 /*
3546 * If we aren't in a transaction block, we just do the basic abort
3547 * & cleanup transaction. For this purpose, we treat an implicit
3548 * transaction block as if it were a simple statement.
3549 */
3550 case TBLOCK_STARTED:
3555 break;
3556
3557 /*
3558 * If we are in TBLOCK_BEGIN it means something screwed up right
3559 * after reading "BEGIN TRANSACTION". We assume that the user
3560 * will interpret the error as meaning the BEGIN failed to get him
3561 * into a transaction block, so we should abort and return to idle
3562 * state.
3563 */
3564 case TBLOCK_BEGIN:
3568 break;
3569
3570 /*
3571 * We are somewhere in a transaction block and we've gotten a
3572 * failure, so we abort the transaction and set up the persistent
3573 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3574 */
3575 case TBLOCK_INPROGRESS:
3579 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3580 break;
3581
3582 /*
3583 * Here, we failed while trying to COMMIT. Clean up the
3584 * transaction and return to idle state (we do not want to stay in
3585 * the transaction).
3586 */
3587 case TBLOCK_END:
3591 break;
3592
3593 /*
3594 * Here, we are already in an aborted transaction state and are
3595 * waiting for a ROLLBACK, but for some reason we failed again! So
3596 * we just remain in the abort state.
3597 */
3598 case TBLOCK_ABORT:
3599 case TBLOCK_SUBABORT:
3600 break;
3601
3602 /*
3603 * We are in a failed transaction and we got the ROLLBACK command.
3604 * We have already aborted, we just need to cleanup and go to idle
3605 * state.
3606 */
3607 case TBLOCK_ABORT_END:
3610 break;
3611
3612 /*
3613 * We are in a live transaction and we got a ROLLBACK command.
3614 * Abort, cleanup, go to idle state.
3615 */
3620 break;
3621
3622 /*
3623 * Here, we failed while trying to PREPARE. Clean up the
3624 * transaction and return to idle state (we do not want to stay in
3625 * the transaction).
3626 */
3627 case TBLOCK_PREPARE:
3631 break;
3632
3633 /*
3634 * We got an error inside a subtransaction. Abort just the
3635 * subtransaction, and go to the persistent SUBABORT state until
3636 * we get ROLLBACK.
3637 */
3641 break;
3642
3643 /*
3644 * If we failed while trying to create a subtransaction, clean up
3645 * the broken subtransaction and abort the parent. The same
3646 * applies if we get a failure while ending a subtransaction. As
3647 * we need to abort the parent, return false to request the caller
3648 * to do the next iteration.
3649 */
3650 case TBLOCK_SUBBEGIN:
3651 case TBLOCK_SUBRELEASE:
3652 case TBLOCK_SUBCOMMIT:
3654 case TBLOCK_SUBRESTART:
3657 return false;
3658
3659 /*
3660 * Same as above, except the Abort() was already done.
3661 */
3665 return false;
3666 }
3667
3668 /* Done, no more iterations required */
3669 return true;
3670}
3671
3672/*
3673 * PreventInTransactionBlock
3674 *
3675 * This routine is to be called by statements that must not run inside
3676 * a transaction block, typically because they have non-rollback-able
3677 * side effects or do internal commits.
3678 *
3679 * If this routine completes successfully, then the calling statement is
3680 * guaranteed that if it completes without error, its results will be
3681 * committed immediately.
3682 *
3683 * If we have already started a transaction block, issue an error; also issue
3684 * an error if we appear to be running inside a user-defined function (which
3685 * could issue more commands and possibly cause a failure after the statement
3686 * completes). Subtransactions are verboten too.
3687 *
3688 * We must also set XACT_FLAGS_NEEDIMMEDIATECOMMIT in MyXactFlags, to ensure
3689 * that postgres.c follows through by committing after the statement is done.
3690 *
3691 * isTopLevel: passed down from ProcessUtility to determine whether we are
3692 * inside a function. (We will always fail if this is false, but it's
3693 * convenient to centralize the check here instead of making callers do it.)
3694 * stmtType: statement type name, for error messages.
3695 */
3696void
3697PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
3698{
3699 /*
3700 * xact block already started?
3701 */
3702 if (IsTransactionBlock())
3703 ereport(ERROR,
3705 /* translator: %s represents an SQL statement name */
3706 errmsg("%s cannot run inside a transaction block",
3707 stmtType)));
3708
3709 /*
3710 * subtransaction?
3711 */
3712 if (IsSubTransaction())
3713 ereport(ERROR,
3715 /* translator: %s represents an SQL statement name */
3716 errmsg("%s cannot run inside a subtransaction",
3717 stmtType)));
3718
3719 /*
3720 * inside a function call?
3721 */
3722 if (!isTopLevel)
3723 ereport(ERROR,
3725 /* translator: %s represents an SQL statement name */
3726 errmsg("%s cannot be executed from a function or procedure",
3727 stmtType)));
3728
3729 /* If we got past IsTransactionBlock test, should be in default state */
3732 elog(FATAL, "cannot prevent transaction chain");
3733
3734 /* All okay. Set the flag to make sure the right thing happens later. */
3736}
3737
3738/*
3739 * WarnNoTransactionBlock
3740 * RequireTransactionBlock
3741 *
3742 * These two functions allow for warnings or errors if a command is executed
3743 * outside of a transaction block. This is useful for commands that have no
3744 * effects that persist past transaction end (and so calling them outside a
3745 * transaction block is presumably an error). DECLARE CURSOR is an example.
3746 * While top-level transaction control commands (BEGIN/COMMIT/ABORT) and SET
3747 * that have no effect issue warnings, all other no-effect commands generate
3748 * errors.
3749 *
3750 * If we appear to be running inside a user-defined function, we do not
3751 * issue anything, since the function could issue more commands that make
3752 * use of the current statement's results. Likewise subtransactions.
3753 * Thus these are inverses for PreventInTransactionBlock.
3754 *
3755 * isTopLevel: passed down from ProcessUtility to determine whether we are
3756 * inside a function.
3757 * stmtType: statement type name, for warning or error messages.
3758 */
3759void
3760WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
3761{
3762 CheckTransactionBlock(isTopLevel, false, stmtType);
3763}
3764
3765void
3766RequireTransactionBlock(bool isTopLevel, const char *stmtType)
3767{
3768 CheckTransactionBlock(isTopLevel, true, stmtType);
3769}
3770
3771/*
3772 * This is the implementation of the above two.
3773 */
3774static void
3775CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
3776{
3777 /*
3778 * xact block already started?
3779 */
3780 if (IsTransactionBlock())
3781 return;
3782
3783 /*
3784 * subtransaction?
3785 */
3786 if (IsSubTransaction())
3787 return;
3788
3789 /*
3790 * inside a function call?
3791 */
3792 if (!isTopLevel)
3793 return;
3794
3797 /* translator: %s represents an SQL statement name */
3798 errmsg("%s can only be used in transaction blocks",
3799 stmtType)));
3800}
3801
3802/*
3803 * IsInTransactionBlock
3804 *
3805 * This routine is for statements that need to behave differently inside
3806 * a transaction block than when running as single commands. ANALYZE is
3807 * currently the only example.
3808 *
3809 * If this routine returns "false", then the calling statement is allowed
3810 * to perform internal transaction-commit-and-start cycles; there is not a
3811 * risk of messing up any transaction already in progress. (Note that this
3812 * is not the identical guarantee provided by PreventInTransactionBlock,
3813 * since we will not force a post-statement commit.)
3814 *
3815 * isTopLevel: passed down from ProcessUtility to determine whether we are
3816 * inside a function.
3817 */
3818bool
3820{
3821 /*
3822 * Return true on same conditions that would make
3823 * PreventInTransactionBlock error out
3824 */
3825 if (IsTransactionBlock())
3826 return true;
3827
3828 if (IsSubTransaction())
3829 return true;
3830
3831 if (!isTopLevel)
3832 return true;
3833
3836 return true;
3837
3838 return false;
3839}
3840
3841
3842/*
3843 * Register or deregister callback functions for start- and end-of-xact
3844 * operations.
3845 *
3846 * These functions are intended for use by dynamically loaded modules.
3847 * For built-in modules we generally just hardwire the appropriate calls
3848 * (mainly because it's easier to control the order that way, where needed).
3849 *
3850 * At transaction end, the callback occurs post-commit or post-abort, so the
3851 * callback functions can only do noncritical cleanup.
3852 */
3853void
3855{
3856 XactCallbackItem *item;
3857
3858 item = (XactCallbackItem *)
3860 item->callback = callback;
3861 item->arg = arg;
3862 item->next = Xact_callbacks;
3863 Xact_callbacks = item;
3864}
3865
3866void
3868{
3869 XactCallbackItem *item;
3870 XactCallbackItem *prev;
3871
3872 prev = NULL;
3873 for (item = Xact_callbacks; item; prev = item, item = item->next)
3874 {
3875 if (item->callback == callback && item->arg == arg)
3876 {
3877 if (prev)
3878 prev->next = item->next;
3879 else
3880 Xact_callbacks = item->next;
3881 pfree(item);
3882 break;
3883 }
3884 }
3885}
3886
3887static void
3889{
3890 XactCallbackItem *item;
3892
3893 for (item = Xact_callbacks; item; item = next)
3894 {
3895 /* allow callbacks to unregister themselves when called */
3896 next = item->next;
3897 item->callback(event, item->arg);
3898 }
3899}
3900
3901
3902/*
3903 * Register or deregister callback functions for start- and end-of-subxact
3904 * operations.
3905 *
3906 * Pretty much same as above, but for subtransaction events.
3907 *
3908 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3909 * so the callback functions can only do noncritical cleanup. At
3910 * subtransaction start, the callback is called when the subtransaction has
3911 * finished initializing.
3912 */
3913void
3915{
3916 SubXactCallbackItem *item;
3917
3918 item = (SubXactCallbackItem *)
3920 item->callback = callback;
3921 item->arg = arg;
3922 item->next = SubXact_callbacks;
3923 SubXact_callbacks = item;
3924}
3925
3926void
3928{
3929 SubXactCallbackItem *item;
3930 SubXactCallbackItem *prev;
3931
3932 prev = NULL;
3933 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3934 {
3935 if (item->callback == callback && item->arg == arg)
3936 {
3937 if (prev)
3938 prev->next = item->next;
3939 else
3940 SubXact_callbacks = item->next;
3941 pfree(item);
3942 break;
3943 }
3944 }
3945}
3946
3947static void
3951{
3952 SubXactCallbackItem *item;
3954
3955 for (item = SubXact_callbacks; item; item = next)
3956 {
3957 /* allow callbacks to unregister themselves when called */
3958 next = item->next;
3959 item->callback(event, mySubid, parentSubid, item->arg);
3960 }
3961}
3962
3963
3964/* ----------------------------------------------------------------
3965 * transaction block support
3966 * ----------------------------------------------------------------
3967 */
3968
3969/*
3970 * BeginTransactionBlock
3971 * This executes a BEGIN command.
3972 */
3973void
3975{
3977
3978 switch (s->blockState)
3979 {
3980 /*
3981 * We are not inside a transaction block, so allow one to begin.
3982 */
3983 case TBLOCK_STARTED:
3985 break;
3986
3987 /*
3988 * BEGIN converts an implicit transaction block to a regular one.
3989 * (Note that we allow this even if we've already done some
3990 * commands, which is a bit odd but matches historical practice.)
3991 */
3994 break;
3995
3996 /*
3997 * Already a transaction block in progress.
3998 */
3999 case TBLOCK_INPROGRESS:
4002 case TBLOCK_ABORT:
4003 case TBLOCK_SUBABORT:
4006 errmsg("there is already a transaction in progress")));
4007 break;
4008
4009 /* These cases are invalid. */
4010 case TBLOCK_DEFAULT:
4011 case TBLOCK_BEGIN:
4012 case TBLOCK_SUBBEGIN:
4013 case TBLOCK_END:
4014 case TBLOCK_SUBRELEASE:
4015 case TBLOCK_SUBCOMMIT:
4016 case TBLOCK_ABORT_END:
4020 case TBLOCK_SUBRESTART:
4022 case TBLOCK_PREPARE:
4023 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
4025 break;
4026 }
4027}
4028
4029/*
4030 * PrepareTransactionBlock
4031 * This executes a PREPARE command.
4032 *
4033 * Since PREPARE may actually do a ROLLBACK, the result indicates what
4034 * happened: true for PREPARE, false for ROLLBACK.
4035 *
4036 * Note that we don't actually do anything here except change blockState.
4037 * The real work will be done in the upcoming PrepareTransaction().
4038 * We do it this way because it's not convenient to change memory context,
4039 * resource owner, etc while executing inside a Portal.
4040 */
4041bool
4042PrepareTransactionBlock(const char *gid)
4043{
4045 bool result;
4046
4047 /* Set up to commit the current transaction */
4048 result = EndTransactionBlock(false);
4049
4050 /* If successful, change outer tblock state to PREPARE */
4051 if (result)
4052 {
4054
4055 while (s->parent != NULL)
4056 s = s->parent;
4057
4058 if (s->blockState == TBLOCK_END)
4059 {
4060 /* Save GID where PrepareTransaction can find it again */
4062
4064 }
4065 else
4066 {
4067 /*
4068 * ignore case where we are not in a transaction;
4069 * EndTransactionBlock already issued a warning.
4070 */
4073 /* Don't send back a PREPARE result tag... */
4074 result = false;
4075 }
4076 }
4077
4078 return result;
4079}
4080
4081/*
4082 * EndTransactionBlock
4083 * This executes a COMMIT command.
4084 *
4085 * Since COMMIT may actually do a ROLLBACK, the result indicates what
4086 * happened: true for COMMIT, false for ROLLBACK.
4087 *
4088 * Note that we don't actually do anything here except change blockState.
4089 * The real work will be done in the upcoming CommitTransactionCommand().
4090 * We do it this way because it's not convenient to change memory context,
4091 * resource owner, etc while executing inside a Portal.
4092 */
4093bool
4094EndTransactionBlock(bool chain)
4095{
4097 bool result = false;
4098
4099 switch (s->blockState)
4100 {
4101 /*
4102 * We are in a transaction block, so tell CommitTransactionCommand
4103 * to COMMIT.
4104 */
4105 case TBLOCK_INPROGRESS:
4107 result = true;
4108 break;
4109
4110 /*
4111 * We are in an implicit transaction block. If AND CHAIN was
4112 * specified, error. Otherwise commit, but issue a warning
4113 * because there was no explicit BEGIN before this.
4114 */
4116 if (chain)
4117 ereport(ERROR,
4119 /* translator: %s represents an SQL statement name */
4120 errmsg("%s can only be used in transaction blocks",
4121 "COMMIT AND CHAIN")));
4122 else
4125 errmsg("there is no transaction in progress")));
4127 result = true;
4128 break;
4129
4130 /*
4131 * We are in a failed transaction block. Tell
4132 * CommitTransactionCommand it's time to exit the block.
4133 */
4134 case TBLOCK_ABORT:
4136 break;
4137
4138 /*
4139 * We are in a live subtransaction block. Set up to subcommit all
4140 * open subtransactions and then commit the main transaction.
4141 */
4143 while (s->parent != NULL)
4144 {
4147 else
4148 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4150 s = s->parent;
4151 }
4152 if (s->blockState == TBLOCK_INPROGRESS)
4154 else
4155 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4157 result = true;
4158 break;
4159
4160 /*
4161 * Here we are inside an aborted subtransaction. Treat the COMMIT
4162 * as ROLLBACK: set up to abort everything and exit the main
4163 * transaction.
4164 */
4165 case TBLOCK_SUBABORT:
4166 while (s->parent != NULL)
4167 {
4170 else if (s->blockState == TBLOCK_SUBABORT)
4172 else
4173 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4175 s = s->parent;
4176 }
4177 if (s->blockState == TBLOCK_INPROGRESS)
4179 else if (s->blockState == TBLOCK_ABORT)
4181 else
4182 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4184 break;
4185
4186 /*
4187 * The user issued COMMIT when not inside a transaction. For
4188 * COMMIT without CHAIN, issue a WARNING, staying in
4189 * TBLOCK_STARTED state. The upcoming call to
4190 * CommitTransactionCommand() will then close the transaction and
4191 * put us back into the default state. For COMMIT AND CHAIN,
4192 * error.
4193 */
4194 case TBLOCK_STARTED:
4195 if (chain)
4196 ereport(ERROR,
4198 /* translator: %s represents an SQL statement name */
4199 errmsg("%s can only be used in transaction blocks",
4200 "COMMIT AND CHAIN")));
4201 else
4204 errmsg("there is no transaction in progress")));
4205 result = true;
4206 break;
4207
4208 /*
4209 * The user issued a COMMIT that somehow ran inside a parallel
4210 * worker. We can't cope with that.
4211 */
4213 ereport(FATAL,
4215 errmsg("cannot commit during a parallel operation")));
4216 break;
4217
4218 /* These cases are invalid. */
4219 case TBLOCK_DEFAULT:
4220 case TBLOCK_BEGIN:
4221 case TBLOCK_SUBBEGIN:
4222 case TBLOCK_END:
4223 case TBLOCK_SUBRELEASE:
4224 case TBLOCK_SUBCOMMIT:
4225 case TBLOCK_ABORT_END:
4229 case TBLOCK_SUBRESTART:
4231 case TBLOCK_PREPARE:
4232 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4234 break;
4235 }
4236
4238 s->blockState == TBLOCK_END ||
4241
4242 s->chain = chain;
4243
4244 return result;
4245}
4246
4247/*
4248 * UserAbortTransactionBlock
4249 * This executes a ROLLBACK command.
4250 *
4251 * As above, we don't actually do anything here except change blockState.
4252 */
4253void
4254UserAbortTransactionBlock(bool chain)
4255{
4257
4258 switch (s->blockState)
4259 {
4260 /*
4261 * We are inside a transaction block and we got a ROLLBACK command
4262 * from the user, so tell CommitTransactionCommand to abort and
4263 * exit the transaction block.
4264 */
4265 case TBLOCK_INPROGRESS:
4267 break;
4268
4269 /*
4270 * We are inside a failed transaction block and we got a ROLLBACK
4271 * command from the user. Abort processing is already done, so
4272 * CommitTransactionCommand just has to cleanup and go back to
4273 * idle state.
4274 */
4275 case TBLOCK_ABORT:
4277 break;
4278
4279 /*
4280 * We are inside a subtransaction. Mark everything up to top
4281 * level as exitable.
4282 */
4284 case TBLOCK_SUBABORT:
4285 while (s->parent != NULL)
4286 {
4289 else if (s->blockState == TBLOCK_SUBABORT)
4291 else
4292 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4294 s = s->parent;
4295 }
4296 if (s->blockState == TBLOCK_INPROGRESS)
4298 else if (s->blockState == TBLOCK_ABORT)
4300 else
4301 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4303 break;
4304
4305 /*
4306 * The user issued ABORT when not inside a transaction. For
4307 * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4308 * The upcoming call to CommitTransactionCommand() will then put
4309 * us back into the default state. For ROLLBACK AND CHAIN, error.
4310 *
4311 * We do the same thing with ABORT inside an implicit transaction,
4312 * although in this case we might be rolling back actual database
4313 * state changes. (It's debatable whether we should issue a
4314 * WARNING in this case, but we have done so historically.)
4315 */
4316 case TBLOCK_STARTED:
4318 if (chain)
4319 ereport(ERROR,
4321 /* translator: %s represents an SQL statement name */
4322 errmsg("%s can only be used in transaction blocks",
4323 "ROLLBACK AND CHAIN")));
4324 else
4327 errmsg("there is no transaction in progress")));
4329 break;
4330
4331 /*
4332 * The user issued an ABORT that somehow ran inside a parallel
4333 * worker. We can't cope with that.
4334 */
4336 ereport(FATAL,
4338 errmsg("cannot abort during a parallel operation")));
4339 break;
4340
4341 /* These cases are invalid. */
4342 case TBLOCK_DEFAULT:
4343 case TBLOCK_BEGIN:
4344 case TBLOCK_SUBBEGIN:
4345 case TBLOCK_END:
4346 case TBLOCK_SUBRELEASE:
4347 case TBLOCK_SUBCOMMIT:
4348 case TBLOCK_ABORT_END:
4352 case TBLOCK_SUBRESTART:
4354 case TBLOCK_PREPARE:
4355 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4357 break;
4358 }
4359
4362
4363 s->chain = chain;
4364}
4365
4366/*
4367 * BeginImplicitTransactionBlock
4368 * Start an implicit transaction block if we're not already in one.
4369 *
4370 * Unlike BeginTransactionBlock, this is called directly from the main loop
4371 * in postgres.c, not within a Portal. So we can just change blockState
4372 * without a lot of ceremony. We do not expect caller to do
4373 * CommitTransactionCommand/StartTransactionCommand.
4374 */
4375void
4377{
4379
4380 /*
4381 * If we are in STARTED state (that is, no transaction block is open),
4382 * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4383 * block.
4384 *
4385 * For caller convenience, we consider all other transaction states as
4386 * legal here; otherwise the caller would need its own state check, which
4387 * seems rather pointless.
4388 */
4389 if (s->blockState == TBLOCK_STARTED)
4391}
4392
4393/*
4394 * EndImplicitTransactionBlock
4395 * End an implicit transaction block, if we're in one.
4396 *
4397 * Like EndTransactionBlock, we just make any needed blockState change here.
4398 * The real work will be done in the upcoming CommitTransactionCommand().
4399 */
4400void
4402{
4404
4405 /*
4406 * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4407 * allowing CommitTransactionCommand to commit whatever happened during
4408 * the implicit transaction block as though it were a single statement.
4409 *
4410 * For caller convenience, we consider all other transaction states as
4411 * legal here; otherwise the caller would need its own state check, which
4412 * seems rather pointless.
4413 */
4416}
4417
4418/*
4419 * DefineSavepoint
4420 * This executes a SAVEPOINT command.
4421 */
4422void
4423DefineSavepoint(const char *name)
4424{
4426
4427 /*
4428 * Workers synchronize transaction state at the beginning of each parallel
4429 * operation, so we can't account for new subtransactions after that
4430 * point. (Note that this check will certainly error out if s->blockState
4431 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4432 * below.)
4433 */
4435 ereport(ERROR,
4437 errmsg("cannot define savepoints during a parallel operation")));
4438
4439 switch (s->blockState)
4440 {
4441 case TBLOCK_INPROGRESS:
4443 /* Normal subtransaction start */
4445 s = CurrentTransactionState; /* changed by push */
4446
4447 /*
4448 * Savepoint names, like the TransactionState block itself, live
4449 * in TopTransactionContext.
4450 */
4451 if (name)
4453 break;
4454
4455 /*
4456 * We disallow savepoint commands in implicit transaction blocks.
4457 * There would be no great difficulty in allowing them so far as
4458 * this module is concerned, but a savepoint seems inconsistent
4459 * with exec_simple_query's behavior of abandoning the whole query
4460 * string upon error. Also, the point of an implicit transaction
4461 * block (as opposed to a regular one) is to automatically close
4462 * after an error, so it's hard to see how a savepoint would fit
4463 * into that.
4464 *
4465 * The error messages for this are phrased as if there were no
4466 * active transaction block at all, which is historical but
4467 * perhaps could be improved.
4468 */
4470 ereport(ERROR,
4472 /* translator: %s represents an SQL statement name */
4473 errmsg("%s can only be used in transaction blocks",
4474 "SAVEPOINT")));
4475 break;
4476
4477 /* These cases are invalid. */
4478 case TBLOCK_DEFAULT:
4479 case TBLOCK_STARTED:
4480 case TBLOCK_BEGIN:
4482 case TBLOCK_SUBBEGIN:
4483 case TBLOCK_END:
4484 case TBLOCK_SUBRELEASE:
4485 case TBLOCK_SUBCOMMIT:
4486 case TBLOCK_ABORT:
4487 case TBLOCK_SUBABORT:
4488 case TBLOCK_ABORT_END:
4492 case TBLOCK_SUBRESTART:
4494 case TBLOCK_PREPARE:
4495 elog(FATAL, "DefineSavepoint: unexpected state %s",
4497 break;
4498 }
4499}
4500
4501/*
4502 * ReleaseSavepoint
4503 * This executes a RELEASE command.
4504 *
4505 * As above, we don't actually do anything here except change blockState.
4506 */
4507void
4508ReleaseSavepoint(const char *name)
4509{
4511 TransactionState target,
4512 xact;
4513
4514 /*
4515 * Workers synchronize transaction state at the beginning of each parallel
4516 * operation, so we can't account for transaction state change after that
4517 * point. (Note that this check will certainly error out if s->blockState
4518 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4519 * below.)
4520 */
4522 ereport(ERROR,
4524 errmsg("cannot release savepoints during a parallel operation")));
4525
4526 switch (s->blockState)
4527 {
4528 /*
4529 * We can't release a savepoint if there is no savepoint defined.
4530 */
4531 case TBLOCK_INPROGRESS:
4532 ereport(ERROR,
4534 errmsg("savepoint \"%s\" does not exist", name)));
4535 break;
4536
4538 /* See comment about implicit transactions in DefineSavepoint */
4539 ereport(ERROR,
4541 /* translator: %s represents an SQL statement name */
4542 errmsg("%s can only be used in transaction blocks",
4543 "RELEASE SAVEPOINT")));
4544 break;
4545
4546 /*
4547 * We are in a non-aborted subtransaction. This is the only valid
4548 * case.
4549 */
4551 break;
4552
4553 /* These cases are invalid. */
4554 case TBLOCK_DEFAULT:
4555 case TBLOCK_STARTED:
4556 case TBLOCK_BEGIN:
4558 case TBLOCK_SUBBEGIN:
4559 case TBLOCK_END:
4560 case TBLOCK_SUBRELEASE:
4561 case TBLOCK_SUBCOMMIT:
4562 case TBLOCK_ABORT:
4563 case TBLOCK_SUBABORT:
4564 case TBLOCK_ABORT_END:
4568 case TBLOCK_SUBRESTART:
4570 case TBLOCK_PREPARE:
4571 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4573 break;
4574 }
4575
4576 for (target = s; target; target = target->parent)
4577 {
4578 if (target->name && strcmp(target->name, name) == 0)
4579 break;
4580 }
4581
4582 if (!target)
4583 ereport(ERROR,
4585 errmsg("savepoint \"%s\" does not exist", name)));
4586
4587 /* disallow crossing savepoint level boundaries */
4588 if (target->savepointLevel != s->savepointLevel)
4589 ereport(ERROR,
4591 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4592
4593 /*
4594 * Mark "commit pending" all subtransactions up to the target
4595 * subtransaction. The actual commits will happen when control gets to
4596 * CommitTransactionCommand.
4597 */
4599 for (;;)
4600 {
4601 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
4602 xact->blockState = TBLOCK_SUBRELEASE;
4603 if (xact == target)
4604 break;
4605 xact = xact->parent;
4606 Assert(xact);
4607 }
4608}
4609
4610/*
4611 * RollbackToSavepoint
4612 * This executes a ROLLBACK TO <savepoint> command.
4613 *
4614 * As above, we don't actually do anything here except change blockState.
4615 */
4616void
4617RollbackToSavepoint(const char *name)
4618{
4620 TransactionState target,
4621 xact;
4622
4623 /*
4624 * Workers synchronize transaction state at the beginning of each parallel
4625 * operation, so we can't account for transaction state change after that
4626 * point. (Note that this check will certainly error out if s->blockState
4627 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4628 * below.)
4629 */
4631 ereport(ERROR,
4633 errmsg("cannot rollback to savepoints during a parallel operation")));
4634
4635 switch (s->blockState)
4636 {
4637 /*
4638 * We can't rollback to a savepoint if there is no savepoint
4639 * defined.
4640 */
4641 case TBLOCK_INPROGRESS:
4642 case TBLOCK_ABORT:
4643 ereport(ERROR,
4645 errmsg("savepoint \"%s\" does not exist", name)));
4646 break;
4647
4649 /* See comment about implicit transactions in DefineSavepoint */
4650 ereport(ERROR,
4652 /* translator: %s represents an SQL statement name */
4653 errmsg("%s can only be used in transaction blocks",
4654 "ROLLBACK TO SAVEPOINT")));
4655 break;
4656
4657 /*
4658 * There is at least one savepoint, so proceed.
4659 */
4661 case TBLOCK_SUBABORT:
4662 break;
4663
4664 /* These cases are invalid. */
4665 case TBLOCK_DEFAULT:
4666 case TBLOCK_STARTED:
4667 case TBLOCK_BEGIN:
4669 case TBLOCK_SUBBEGIN:
4670 case TBLOCK_END:
4671 case TBLOCK_SUBRELEASE:
4672 case TBLOCK_SUBCOMMIT:
4673 case TBLOCK_ABORT_END:
4677 case TBLOCK_SUBRESTART:
4679 case TBLOCK_PREPARE:
4680 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4682 break;
4683 }
4684
4685 for (target = s; target; target = target->parent)
4686 {
4687 if (target->name && strcmp(target->name, name) == 0)
4688 break;
4689 }
4690
4691 if (!target)
4692 ereport(ERROR,
4694 errmsg("savepoint \"%s\" does not exist", name)));
4695
4696 /* disallow crossing savepoint level boundaries */
4697 if (target->savepointLevel != s->savepointLevel)
4698 ereport(ERROR,
4700 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4701
4702 /*
4703 * Mark "abort pending" all subtransactions up to the target
4704 * subtransaction. The actual aborts will happen when control gets to
4705 * CommitTransactionCommand.
4706 */
4708 for (;;)
4709 {
4710 if (xact == target)
4711 break;
4712 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4714 else if (xact->blockState == TBLOCK_SUBABORT)
4715 xact->blockState = TBLOCK_SUBABORT_END;
4716 else
4717 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4718 BlockStateAsString(xact->blockState));
4719 xact = xact->parent;
4720 Assert(xact);
4721 }
4722
4723 /* And mark the target as "restart pending" */
4724 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4725 xact->blockState = TBLOCK_SUBRESTART;
4726 else if (xact->blockState == TBLOCK_SUBABORT)
4727 xact->blockState = TBLOCK_SUBABORT_RESTART;
4728 else
4729 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4730 BlockStateAsString(xact->blockState));
4731}
4732
4733/*
4734 * BeginInternalSubTransaction
4735 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
4736 * TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_END,
4737 * and TBLOCK_PREPARE states, and therefore it can safely be used in
4738 * functions that might be called when not inside a BEGIN block or when
4739 * running deferred triggers at COMMIT/PREPARE time. Also, it
4740 * automatically does CommitTransactionCommand/StartTransactionCommand
4741 * instead of expecting the caller to do it.
4742 */
4743void
4745{
4748
4749 /*
4750 * Errors within this function are improbable, but if one does happen we
4751 * force a FATAL exit. Callers generally aren't prepared to handle losing
4752 * control, and moreover our transaction state is probably corrupted if we
4753 * fail partway through; so an ordinary ERROR longjmp isn't okay.
4754 */
4755 ExitOnAnyError = true;
4756
4757 /*
4758 * We do not check for parallel mode here. It's permissible to start and
4759 * end "internal" subtransactions while in parallel mode, so long as no
4760 * new XIDs or command IDs are assigned. Enforcement of that occurs in
4761 * AssignTransactionId() and CommandCounterIncrement().
4762 */
4763
4764 switch (s->blockState)
4765 {
4766 case TBLOCK_STARTED:
4767 case TBLOCK_INPROGRESS:
4770 case TBLOCK_END:
4771 case TBLOCK_PREPARE:
4773 /* Normal subtransaction start */
4775 s = CurrentTransactionState; /* changed by push */
4776
4777 /*
4778 * Savepoint names, like the TransactionState block itself, live
4779 * in TopTransactionContext.
4780 */
4781 if (name)
4783 break;
4784
4785 /* These cases are invalid. */
4786 case TBLOCK_DEFAULT:
4787 case TBLOCK_BEGIN:
4788 case TBLOCK_SUBBEGIN:
4789 case TBLOCK_SUBRELEASE:
4790 case TBLOCK_SUBCOMMIT:
4791 case TBLOCK_ABORT:
4792 case TBLOCK_SUBABORT:
4793 case TBLOCK_ABORT_END:
4797 case TBLOCK_SUBRESTART:
4799 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4801 break;
4802 }
4803
4806
4808}
4809
4810/*
4811 * ReleaseCurrentSubTransaction
4812 *
4813 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
4814 * 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
4829 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4834 s = CurrentTransactionState; /* changed by pop */
4836}
4837
4838/*
4839 * RollbackAndReleaseCurrentSubTransaction
4840 *
4841 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
4842 * of its savepoint name (if any).
4843 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4844 */
4845void
4847{
4849
4850 /*
4851 * We do not check for parallel mode here. It's permissible to start and
4852 * end "internal" subtransactions while in parallel mode, so long as no
4853 * new XIDs or command IDs are assigned.
4854 */
4855
4856 switch (s->blockState)
4857 {
4858 /* Must be in a subtransaction */
4860 case TBLOCK_SUBABORT:
4861 break;
4862
4863 /* These cases are invalid. */
4864 case TBLOCK_DEFAULT:
4865 case TBLOCK_STARTED:
4866 case TBLOCK_BEGIN:
4869 case TBLOCK_SUBBEGIN:
4870 case TBLOCK_INPROGRESS:
4871 case TBLOCK_END:
4872 case TBLOCK_SUBRELEASE:
4873 case TBLOCK_SUBCOMMIT:
4874 case TBLOCK_ABORT:
4875 case TBLOCK_ABORT_END:
4879 case TBLOCK_SUBRESTART:
4881 case TBLOCK_PREPARE:
4882 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4884 break;
4885 }
4886
4887 /*
4888 * Abort the current subtransaction, if needed.
4889 */
4892
4893 /* And clean it up, too */
4895
4896 s = CurrentTransactionState; /* changed by pop */
4902}
4903
4904/*
4905 * AbortOutOfAnyTransaction
4906 *
4907 * This routine is provided for error recovery purposes. It aborts any
4908 * active transaction or transaction block, leaving the system in a known
4909 * idle state.
4910 */
4911void
4913{
4915
4916 /* Ensure we're not running in a doomed memory context */
4918
4919 /*
4920 * Get out of any transaction or nested transaction
4921 */
4922 do
4923 {
4924 switch (s->blockState)
4925 {
4926 case TBLOCK_DEFAULT:
4927 if (s->state == TRANS_DEFAULT)
4928 {
4929 /* Not in a transaction, do nothing */
4930 }
4931 else
4932 {
4933 /*
4934 * We can get here after an error during transaction start
4935 * (state will be TRANS_START). Need to clean up the
4936 * incompletely started transaction. First, adjust the
4937 * low-level state to suppress warning message from
4938 * AbortTransaction.
4939 */
4940 if (s->state == TRANS_START)
4944 }
4945 break;
4946 case TBLOCK_STARTED:
4947 case TBLOCK_BEGIN:
4948 case TBLOCK_INPROGRESS:
4951 case TBLOCK_END:
4953 case TBLOCK_PREPARE:
4954 /* In a transaction, so clean up */
4958 break;
4959 case TBLOCK_ABORT:
4960 case TBLOCK_ABORT_END:
4961
4962 /*
4963 * AbortTransaction is already done, still need Cleanup.
4964 * However, if we failed partway through running ROLLBACK,
4965 * there will be an active portal running that command, which
4966 * we need to shut down before doing CleanupTransaction.
4967 */
4971 break;
4972
4973 /*
4974 * In a subtransaction, so clean it up and abort parent too
4975 */
4976 case TBLOCK_SUBBEGIN:
4978 case TBLOCK_SUBRELEASE:
4979 case TBLOCK_SUBCOMMIT:
4981 case TBLOCK_SUBRESTART:
4984 s = CurrentTransactionState; /* changed by pop */
4985 break;
4986
4987 case TBLOCK_SUBABORT:
4990 /* As above, but AbortSubTransaction already done */
4991 if (s->curTransactionOwner)
4992 {
4993 /* As in TBLOCK_ABORT, might have a live portal to zap */
4998 }
5000 s = CurrentTransactionState; /* changed by pop */
5001 break;
5002 }
5003 } while (s->blockState != TBLOCK_DEFAULT);
5004
5005 /* Should be out of all subxacts now */
5006 Assert(s->parent == NULL);
5007
5008 /*
5009 * Revert to TopMemoryContext, to ensure we exit in a well-defined state
5010 * whether there were any transactions to close or not. (Callers that
5011 * don't intend to exit soon should switch to some other context to avoid
5012 * long-term memory leaks.)
5013 */
5015}
5016
5017/*
5018 * IsTransactionBlock --- are we within a transaction block?
5019 */
5020bool
5022{
5024
5026 return false;
5027
5028 return true;
5029}
5030
5031/*
5032 * IsTransactionOrTransactionBlock --- are we within either a transaction
5033 * or a transaction block? (The backend is only really "idle" when this
5034 * returns false.)
5035 *
5036 * This should match up with IsTransactionBlock and IsTransactionState.
5037 */
5038bool
5040{
5042
5043 if (s->blockState == TBLOCK_DEFAULT)
5044 return false;
5045
5046 return true;
5047}
5048
5049/*
5050 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
5051 */
5052char
5054{
5056
5057 switch (s->blockState)
5058 {
5059 case TBLOCK_DEFAULT:
5060 case TBLOCK_STARTED:
5061 return 'I'; /* idle --- not in transaction */
5062 case TBLOCK_BEGIN:
5063 case TBLOCK_SUBBEGIN:
5064 case TBLOCK_INPROGRESS:
5068 case TBLOCK_END:
5069 case TBLOCK_SUBRELEASE:
5070 case TBLOCK_SUBCOMMIT:
5071 case TBLOCK_PREPARE:
5072 return 'T'; /* in transaction */
5073 case TBLOCK_ABORT:
5074 case TBLOCK_SUBABORT:
5075 case TBLOCK_ABORT_END:
5079 case TBLOCK_SUBRESTART:
5081 return 'E'; /* in failed transaction */
5082 }
5083
5084 /* should never get here */
5085 elog(FATAL, "invalid transaction block state: %s",
5087 return 0; /* keep compiler quiet */
5088}
5089
5090/*
5091 * IsSubTransaction
5092 */
5093bool
5094IsSubTransaction(void)
5095{
5097
5098 if (s->nestingLevel >= 2)
5099 return true;
5100
5101 return false;
5102}
5103
5104/*
5105 * StartSubTransaction
5106 *
5107 * If you're wondering why this is separate from PushTransaction: it's because
5108 * we can't conveniently do this stuff right inside DefineSavepoint. The
5109 * SAVEPOINT utility command will be executed inside a Portal, and if we
5110 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
5111 * the Portal will undo those settings. So we make DefineSavepoint just
5112 * push a dummy transaction block, and when control returns to the main
5113 * idle loop, CommitTransactionCommand will be called, and we'll come here
5114 * to finish starting the subtransaction.
5115 */
5116static void
5118{
5120
5121 if (s->state != TRANS_DEFAULT)
5122 elog(WARNING, "StartSubTransaction while in %s state",
5124
5125 s->state = TRANS_START;
5126
5127 /*
5128 * Initialize subsystems for new subtransaction
5129 *
5130 * must initialize resource-management stuff first
5131 */
5135
5137
5138 /*
5139 * Call start-of-subxact callbacks
5140 */
5143
5144 ShowTransactionState("StartSubTransaction");
5145}
5146
5147/*
5148 * CommitSubTransaction
5149 *
5150 * The caller has to make sure to always reassign CurrentTransactionState
5151 * if it has a local pointer to it after calling this function.
5152 */
5153static void
5155{
5157
5158 ShowTransactionState("CommitSubTransaction");
5159
5160 if (s->state != TRANS_INPROGRESS)
5161 elog(WARNING, "CommitSubTransaction while in %s state",
5163
5164 /* Pre-commit processing goes here */
5165
5168
5169 /*
5170 * If this subxact has started any unfinished parallel operation, clean up
5171 * its workers and exit parallel mode. Warn about leaked resources.
5172 */
5174 if (s->parallelModeLevel != 0)
5175 {
5176 elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5178 s->parallelModeLevel = 0;
5179 }
5180
5181 /* Do the actual "commit", such as it is */
5182 s->state = TRANS_COMMIT;
5183
5184 /* Must CCI to ensure commands of subtransaction are seen as done */
5186
5187 /*
5188 * Prior to 8.4 we marked subcommit in clog at this point. We now only
5189 * perform that step, if required, as part of the atomic update of the
5190 * whole transaction tree at top level commit or abort.
5191 */
5192
5193 /* Post-commit cleanup */
5199 s->parent->nestingLevel,
5204
5207
5210 true, false);
5214 AtEOSubXact_Inval(true);
5216
5217 /*
5218 * The only lock we actually release here is the subtransaction XID lock.
5219 */
5223
5224 /*
5225 * Other locks should get transferred to their parent resource owner.
5226 */
5229 true, false);
5232 true, false);
5233
5234 AtEOXact_GUC(true, s->gucNestLevel);
5245
5246 /*
5247 * We need to restore the upper transaction's read-only state, in case the
5248 * upper is read-write while the child is read-only; GUC will incorrectly
5249 * think it should leave the child state in place.
5250 */
5252
5257
5259
5260 s->state = TRANS_DEFAULT;
5261
5263}
5264
5265/*
5266 * AbortSubTransaction
5267 */
5268static void
5270{
5272
5273 /* Prevent cancel/die interrupt while cleaning up */
5275
5276 /* Make sure we have a valid memory context and resource owner */
5279
5280 /*
5281 * Release any LW locks we might be holding as quickly as possible.
5282 * (Regular locks, however, must be held till we finish aborting.)
5283 * Releasing LW locks is critical since we might try to grab them again
5284 * while cleaning up!
5285 *
5286 * FIXME This may be incorrect --- Are there some locks we should keep?
5287 * Buffer locks, for example? I don't think so but I'm not sure.
5288 */
5290
5293
5295
5296 UnlockBuffers();
5297
5298 /* Reset WAL record construction state */
5300
5301 /* Cancel condition variable sleep */
5303
5304 /*
5305 * Also clean up any open wait for lock, since the lock manager will choke
5306 * if we try to wait for another lock before doing this.
5307 */
5309
5310 /*
5311 * If any timeout events are still active, make sure the timeout interrupt
5312 * is scheduled. This covers possible loss of a timeout interrupt due to
5313 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5314 * We delay this till after LockErrorCleanup so that we don't uselessly
5315 * reschedule lock or deadlock check timeouts.
5316 */
5318
5319 /*
5320 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5321 * handler. We do this fairly early in the sequence so that the timeout
5322 * infrastructure will be functional if needed while aborting.
5323 */
5325
5326 /*
5327 * check the current transaction state
5328 */
5329 ShowTransactionState("AbortSubTransaction");
5330
5331 if (s->state != TRANS_INPROGRESS)
5332 elog(WARNING, "AbortSubTransaction while in %s state",
5334
5335 s->state = TRANS_ABORT;
5336
5337 /*
5338 * Reset user ID which might have been changed transiently. (See notes in
5339 * AbortTransaction.)
5340 */
5342
5343 /* Forget about any active REINDEX. */
5345
5346 /* Reset logical streaming state. */
5348
5349 /*
5350 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5351 * exports are not supported in subtransactions.
5352 */
5353
5354 /*
5355 * If this subxact has started any unfinished parallel operation, clean up
5356 * its workers and exit parallel mode. Don't warn about leaked resources.
5357 */
5359 s->parallelModeLevel = 0;
5360
5361 /*
5362 * We can skip all this stuff if the subxact failed before creating a
5363 * ResourceOwner...
5364 */
5365 if (s->curTransactionOwner)
5366 {
5375
5376 /* Advertise the fact that we aborted in pg_xact. */
5378
5379 /* Post-abort cleanup */
5382
5385
5388 false, false);
5389
5390 AtEOXact_Aio(false);
5394 AtEOSubXact_Inval(false);
5397 false, false);
5400 false, false);
5402
5403 AtEOXact_GUC(false, s->gucNestLevel);
5414 }
5415
5416 /*
5417 * Restore the upper transaction's read-only state, too. This should be
5418 * redundant with GUC's cleanup but we may as well do it for consistency
5419 * with the commit case.
5420 */
5422
5424}
5425
5426/*
5427 * CleanupSubTransaction
5428 *
5429 * The caller has to make sure to always reassign CurrentTransactionState
5430 * if it has a local pointer to it after calling this function.
5431 */
5432static void
5434{
5436
5437 ShowTransactionState("CleanupSubTransaction");
5438
5439 if (s->state != TRANS_ABORT)
5440 elog(WARNING, "CleanupSubTransaction while in %s state",
5442
5444
5447 if (s->curTransactionOwner)
5450
5452
5453 s->state = TRANS_DEFAULT;
5454
5456}
5457
5458/*
5459 * PushTransaction
5460 * Create transaction state stack entry for a subtransaction
5461 *
5462 * The caller has to make sure to always reassign CurrentTransactionState
5463 * if it has a local pointer to it after calling this function.
5464 */
5465static void
5466PushTransaction(void)
5467{
5470
5471 /*
5472 * We keep subtransaction state nodes in TopTransactionContext.
5473 */
5474 s = (TransactionState)
5476 sizeof(TransactionStateData));
5477
5478 /*
5479 * Assign a subtransaction ID, watching out for counter wraparound.
5480 */
5483 {
5485 pfree(s);
5486 ereport(ERROR,
5488 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5489 }
5490
5491 /*
5492 * We can now stack a minimally valid subtransaction without fear of
5493 * failure.
5494 */
5495 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5497 s->parent = p;
5498 s->nestingLevel = p->nestingLevel + 1;
5501 s->state = TRANS_DEFAULT;
5506 s->parallelModeLevel = 0;
5508 s->topXidLogged = false;
5509
5511
5512 /*
5513 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5514 * with the subtransaction from here on out; in particular they should not
5515 * assume that it necessarily has a transaction context, resource owner,
5516 * or XID.
5517 */
5518}
5519
5520/*
5521 * PopTransaction
5522 * Pop back to parent transaction state
5523 *
5524 * The caller has to make sure to always reassign CurrentTransactionState
5525 * if it has a local pointer to it after calling this function.
5526 */
5527static void
5528PopTransaction(void)
5529{
5531
5532 if (s->state != TRANS_DEFAULT)
5533 elog(WARNING, "PopTransaction while in %s state",
5535
5536 if (s->parent == NULL)
5537 elog(FATAL, "PopTransaction with no parent");
5538
5540
5541 /* Let's just make sure CurTransactionContext is good */
5544
5545 /* Ditto for ResourceOwner links */
5548
5549 /* Free the old child structure */
5550 if (s->name)
5551 pfree(s->name);
5552 pfree(s);
5553}
5554
5555/*
5556 * EstimateTransactionStateSpace
5557 * Estimate the amount of space that will be needed by
5558 * SerializeTransactionState. It would be OK to overestimate slightly,
5559 * but it's simple for us to work out the precise value, so we do.
5560 */
5561Size
5563{
5565 Size nxids = 0;
5567
5568 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5569 {
5571 nxids = add_size(nxids, 1);
5573 }
5574
5575 return add_size(size, mul_size(sizeof(TransactionId), nxids));
5576}
5577
5578/*
5579 * SerializeTransactionState
5580 * Write out relevant details of our transaction state that will be
5581 * needed by a parallel worker.
5582 *
5583 * We need to save and restore XactDeferrable, XactIsoLevel, and the XIDs
5584 * associated with this transaction. These are serialized into a
5585 * caller-supplied buffer big enough to hold the number of bytes reported by
5586 * EstimateTransactionStateSpace(). We emit the XIDs in sorted order for the
5587 * convenience of the receiving process.
5588 */
5589void
5591{
5593 Size nxids = 0;
5594 Size i = 0;
5595 TransactionId *workspace;
5597
5599
5601 result->xactDeferrable = XactDeferrable;
5602 result->topFullTransactionId = XactTopFullTransactionId;
5603 result->currentFullTransactionId =
5605 result->currentCommandId = currentCommandId;
5606
5607 /*
5608 * If we're running in a parallel worker and launching a parallel worker
5609 * of our own, we can just pass along the information that was passed to
5610 * us.
5611 */
5612 if (nParallelCurrentXids > 0)
5613 {
5614 result->nParallelCurrentXids = nParallelCurrentXids;
5615 memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
5617 return;
5618 }
5619
5620 /*
5621 * OK, we need to generate a sorted list of XIDs that our workers should
5622 * view as current. First, figure out how many there are.
5623 */
5624 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5625 {
5627 nxids = add_size(nxids, 1);
5629 }
5631 <= maxsize);
5632
5633 /* Copy them to our scratch space. */
5634 workspace = palloc(nxids * sizeof(TransactionId));
5635 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5636 {
5638 workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5639 if (s->nChildXids > 0)
5640 memcpy(&workspace[i], s->childXids,
5641 s->nChildXids * sizeof(TransactionId));
5642 i += s->nChildXids;
5643 }
5644 Assert(i == nxids);
5645
5646 /* Sort them. */
5647 qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5648
5649 /* Copy data into output area. */
5650 result->nParallelCurrentXids = nxids;
5651 memcpy(&result->parallelCurrentXids[0], workspace,
5652 nxids * sizeof(TransactionId));
5653}
5654
5655/*
5656 * StartParallelWorkerTransaction
5657 * Start a parallel worker transaction, restoring the relevant
5658 * transaction state serialized by SerializeTransactionState.
5659 */
5660void
5662{
5664
5667
5669 XactIsoLevel = tstate->xactIsoLevel;
5670 XactDeferrable = tstate->xactDeferrable;
5671 XactTopFullTransactionId = tstate->topFullTransactionId;
5673 tstate->currentFullTransactionId;
5674 currentCommandId = tstate->currentCommandId;
5675 nParallelCurrentXids = tstate->nParallelCurrentXids;
5676 ParallelCurrentXids = &tstate->parallelCurrentXids[0];
5677
5679}
5680
5681/*
5682 * EndParallelWorkerTransaction
5683 * End a parallel worker transaction.
5684 */
5685void
5687{
5691}
5692
5693/*
5694 * ShowTransactionState
5695 * Debug support
5696 */
5697static void
5698ShowTransactionState(const char *str)
5699{
5700 /* skip work if message will definitely not be printed */
5703}
5704
5705/*
5706 * ShowTransactionStateRec
5707 * Recursive subroutine for ShowTransactionState
5708 */
5709static void
5711{
5713
5714 if (s->parent)
5715 {
5716 /*
5717 * Since this function recurses, it could be driven to stack overflow.
5718 * This is just a debugging aid, so we can leave out some details
5719 * instead of erroring out with check_stack_depth().
5720 */
5721 if (stack_is_too_deep())
5723 (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5724 str, s->nestingLevel)));
5725 else
5727 }
5728
5730 if (s->nChildXids > 0)
5731 {
5732 int i;
5733
5734 appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5735 for (i = 1; i < s->nChildXids; i++)
5736 appendStringInfo(&buf, " %u", s->childXids[i]);
5737 }
5739 (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5740 str, s->nestingLevel,
5741 s->name ? s->name : "unnamed",
5742 BlockStateAsString(s->blockState),
5744 XidFromFullTransactionId(s->fullTransactionId),
5745 s->subTransactionId,
5747 currentCommandIdUsed ? " (used)" : "",
5748 buf.data)));
5749 pfree(buf.data);
5750}
5751
5752/*
5753 * BlockStateAsString
5754 * Debug support
5755 */
5756static const char *
5758{
5759 switch (blockState)
5760 {
5761 case TBLOCK_DEFAULT:
5762 return "DEFAULT";
5763 case TBLOCK_STARTED:
5764 return "STARTED";
5765 case TBLOCK_BEGIN:
5766 return "BEGIN";
5767 case TBLOCK_INPROGRESS:
5768 return "INPROGRESS";
5770 return "IMPLICIT_INPROGRESS";
5772 return "PARALLEL_INPROGRESS";
5773 case TBLOCK_END:
5774 return "END";
5775 case TBLOCK_ABORT:
5776 return "ABORT";
5777 case TBLOCK_ABORT_END:
5778 return "ABORT_END";
5780 return "ABORT_PENDING";
5781 case TBLOCK_PREPARE:
5782 return "PREPARE";
5783 case TBLOCK_SUBBEGIN:
5784 return "SUBBEGIN";
5786 return "SUBINPROGRESS";
5787 case TBLOCK_SUBRELEASE:
5788 return "SUBRELEASE";
5789 case TBLOCK_SUBCOMMIT:
5790 return "SUBCOMMIT";
5791 case TBLOCK_SUBABORT:
5792 return "SUBABORT";
5794 return "SUBABORT_END";
5796 return "SUBABORT_PENDING";
5797 case TBLOCK_SUBRESTART:
5798 return "SUBRESTART";
5800 return "SUBABORT_RESTART";
5801 }
5802 return "UNRECOGNIZED";
5803}
5804
5805/*
5806 * TransStateAsString
5807 * Debug support
5808 */
5809static const char *
5811{
5812 switch (state)
5813 {
5814 case TRANS_DEFAULT:
5815 return "DEFAULT";
5816 case TRANS_START:
5817 return "START";
5818 case TRANS_INPROGRESS:
5819 return "INPROGRESS";
5820 case TRANS_COMMIT:
5821 return "COMMIT";
5822 case TRANS_ABORT:
5823 return "ABORT";
5824 case TRANS_PREPARE:
5825 return "PREPARE";
5826 }
5827 return "UNRECOGNIZED";
5828}
5829
5830/*
5831 * xactGetCommittedChildren
5832 *
5833 * Gets the list of committed children of the current transaction. The return
5834 * value is the number of child transactions. *ptr is set to point to an
5835 * array of TransactionIds. The array is allocated in TopTransactionContext;
5836 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
5837 * If there are no subxacts, *ptr is set to NULL.
5838 */
5839int
5841{
5843
5844 if (s->nChildXids == 0)
5845 *ptr = NULL;
5846 else
5847 *ptr = s->childXids;
5848
5849 return s->nChildXids;
5850}
5851
5852/*
5853 * XLOG support routines
5854 */
5855
5856
5857/*
5858 * Log the commit record for a plain or twophase transaction commit.
5859 *
5860 * A 2pc commit will be emitted when twophase_xid is valid, a plain one
5861 * otherwise.
5862 */
5865 int nsubxacts, TransactionId *subxacts,
5866 int nrels, RelFileLocator *rels,
5868 int nmsgs, SharedInvalidationMessage *msgs,
5869 bool relcacheInval,
5870 int xactflags, TransactionId twophase_xid,
5871 const char *twophase_gid)
5872{
5882 uint8 info;
5883
5885
5886 xl_xinfo.xinfo = 0;
5887
5888 /* decide between a plain and 2pc commit */
5889 if (!TransactionIdIsValid(twophase_xid))
5890 info = XLOG_XACT_COMMIT;
5891 else
5893
5894 /* First figure out and collect all the information needed */
5895
5896 xlrec.xact_time = commit_time;
5897
5898 if (relcacheInval)
5900 if (forceSyncCommit)
5904
5905 /*
5906 * Check if the caller would like to ask standbys for immediate feedback
5907 * once this commit is applied.
5908 */
5911
5912 /*
5913 * Relcache invalidations requires information about the current database
5914 * and so does logical decoding.
5915 */
5916 if (nmsgs > 0 || XLogLogicalInfoActive())
5917 {
5919 xl_dbinfo.dbId = MyDatabaseId;
5921 }
5922
5923 if (nsubxacts > 0)
5924 {
5926 xl_subxacts.nsubxacts = nsubxacts;
5927 }
5928
5929 if (nrels > 0)
5930 {
5932 xl_relfilelocators.nrels = nrels;
5933 info |= XLR_SPECIAL_REL_UPDATE;
5934 }
5935
5936 if (ndroppedstats > 0)
5937 {
5940 }
5941
5942 if (nmsgs > 0)
5943 {
5945 xl_invals.nmsgs = nmsgs;
5946 }
5947
5948 if (TransactionIdIsValid(twophase_xid))
5949 {
5951 xl_twophase.xid = twophase_xid;
5952 Assert(twophase_gid != NULL);
5953
5956 }
5957
5958 /* dump transaction origin information */
5960 {
5962
5965 }
5966
5967 if (xl_xinfo.xinfo != 0)
5968 info |= XLOG_XACT_HAS_INFO;
5969
5970 /* Then include all the collected data into the commit record. */
5971
5973
5975
5976 if (xl_xinfo.xinfo != 0)
5977 XLogRegisterData(&xl_xinfo.xinfo, sizeof(xl_xinfo.xinfo));
5978
5979 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5981
5983 {
5986 XLogRegisterData(subxacts,
5987 nsubxacts * sizeof(TransactionId));
5988 }
5989
5991 {
5994 XLogRegisterData(rels,
5995 nrels * sizeof(RelFileLocator));
5996 }
5997
5999 {
6004 }
6005
6006 if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
6007 {
6009 XLogRegisterData(msgs,
6010 nmsgs * sizeof(SharedInvalidationMessage));
6011 }
6012
6014 {
6016 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6017 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6018 }
6019
6020 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6022
6023 /* we allow filtering by xacts */
6025
6026 return XLogInsert(RM_XACT_ID, info);
6027}
6028
6029/*
6030 * Log the commit record for a plain or twophase transaction abort.
6031 *
6032 * A 2pc abort will be emitted when twophase_xid is valid, a plain one
6033 * otherwise.
6034 */
6037 int nsubxacts, TransactionId *subxacts,
6038 int nrels, RelFileLocator *rels,
6040 int xactflags, TransactionId twophase_xid,
6041 const char *twophase_gid)
6042{
6051
6052 uint8 info;
6053
6055
6056 xl_xinfo.xinfo = 0;
6057
6058 /* decide between a plain and 2pc abort */
6059 if (!TransactionIdIsValid(twophase_xid))
6060 info = XLOG_XACT_ABORT;
6061 else
6063
6064
6065 /* First figure out and collect all the information needed */
6066
6067 xlrec.xact_time = abort_time;
6068
6071
6072 if (nsubxacts > 0)
6073 {
6075 xl_subxacts.nsubxacts = nsubxacts;
6076 }
6077
6078 if (nrels > 0)
6079 {
6081 xl_relfilelocators.nrels = nrels;
6082 info |= XLR_SPECIAL_REL_UPDATE;
6083 }
6084
6085 if (ndroppedstats > 0)
6086 {
6089 }
6090
6091 if (TransactionIdIsValid(twophase_xid))
6092 {
6094 xl_twophase.xid = twophase_xid;
6095 Assert(twophase_gid != NULL);
6096
6099 }
6100
6101 if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6102 {
6104 xl_dbinfo.dbId = MyDatabaseId;
6106 }
6107
6108 /*
6109 * Dump transaction origin information. We need this during recovery to
6110 * update the replication origin progress.
6111 */
6113 {
6115
6118 }
6119
6120 if (xl_xinfo.xinfo != 0)
6121 info |= XLOG_XACT_HAS_INFO;
6122
6123 /* Then include all the collected data into the abort record. */
6124
6126
6128
6129 if (xl_xinfo.xinfo != 0)
6131
6132 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6134
6136 {
6139 XLogRegisterData(subxacts,
6140 nsubxacts * sizeof(TransactionId));
6141 }
6142
6144 {
6147 XLogRegisterData(rels,
6148 nrels * sizeof(RelFileLocator));
6149 }
6150
6152 {
6157 }
6158
6160 {
6162 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6163 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6164 }
6165
6166 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6168
6169 /* Include the replication origin */
6171
6172 return XLogInsert(RM_XACT_ID, info);
6173}
6174
6175/*
6176 * Before 9.0 this was a fairly short function, but now it performs many
6177 * actions for which the order of execution is critical.
6178 */
6179static void
6181 TransactionId xid,
6182 XLogRecPtr lsn,
6183 ReplOriginId origin_id)
6184{
6186 TimestampTz commit_time;
6187
6189
6190 max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
6191
6192 /* Make sure nextXid is beyond any XID mentioned in the record. */
6194
6195 Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) ==
6196 (origin_id == InvalidReplOriginId));
6197
6198 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6199 commit_time = parsed->origin_timestamp;
6200 else
6201 commit_time = parsed->xact_time;
6202
6203 /* Set the transaction commit timestamp and metadata */
6204 TransactionTreeSetCommitTsData(xid, parsed->nsubxacts, parsed->subxacts,
6205 commit_time, origin_id);
6206
6208 {
6209 /*
6210 * Mark the transaction committed in pg_xact.
6211 */
6212 TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
6213 }
6214 else
6215 {
6216 /*
6217 * If a transaction completion record arrives that has as-yet
6218 * unobserved subtransactions then this will not have been fully
6219 * handled by the call to RecordKnownAssignedTransactionIds() in the
6220 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6221 * cover that case. This is confusing and it is easy to think this
6222 * call is irrelevant, which has happened three times in development
6223 * already. Leave it in.
6224 */
6226
6227 /*
6228 * Mark the transaction committed in pg_xact. We use async commit
6229 * protocol during recovery to provide information on database
6230 * consistency for when users try to set hint bits. It is important
6231 * that we do not set hint bits until the minRecoveryPoint is past
6232 * this commit record. This ensures that if we crash we don't see hint
6233 * bits set on changes made by transactions that haven't yet
6234 * recovered. It's unlikely but it's good to be safe.
6235 */
6236 TransactionIdAsyncCommitTree(xid, parsed->nsubxacts, parsed->subxacts, lsn);
6237
6238 /*
6239 * We must mark clog before we update the ProcArray.
6240 */
6241 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6242
6243 /*
6244 * Send any cache invalidations attached to the commit. We must
6245 * maintain the same order of invalidation then release locks as
6246 * occurs in CommitTransaction().
6247 */
6250 parsed->dbId, parsed->tsId);
6251
6252 /*
6253 * Release locks, if any. We do this for both two phase and normal one
6254 * phase transactions. In effect we are ignoring the prepare phase and
6255 * just going straight to lock release.
6256 */
6257 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6258 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6259 }
6260
6261 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6262 {
6263 /* recover apply progress */
6264 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6265 false /* backward */ , false /* WAL */ );
6266 }
6267
6268 /* Make sure files supposed to be dropped are dropped */
6269 if (parsed->nrels > 0)
6270 {
6271 /*
6272 * First update minimum recovery point to cover this WAL record. Once
6273 * a relation is deleted, there's no going back. The buffer manager
6274 * enforces the WAL-first rule for normal updates to relation files,
6275 * so that the minimum recovery point is always updated before the
6276 * corresponding change in the data file is flushed to disk, but we
6277 * have to do the same here since we're bypassing the buffer manager.
6278 *
6279 * Doing this before deleting the files means that if a deletion fails
6280 * for some reason, you cannot start up the system even after restart,
6281 * until you fix the underlying situation so that the deletion will
6282 * succeed. Alternatively, we could update the minimum recovery point
6283 * after deletion, but that would leave a small window where the
6284 * WAL-first rule would be violated.
6285 */
6286 XLogFlush(lsn);
6287
6288 /* Make sure files supposed to be dropped are dropped */
6289 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6290 }
6291
6292 if (parsed->nstats > 0)
6293 {
6294 /* see equivalent call for relations above */
6295 XLogFlush(lsn);
6296
6297 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6298 }
6299
6300 /*
6301 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
6302 * in normal operation. For example, in CREATE DATABASE, we copy all files
6303 * from the template database, and then commit the transaction. If we
6304 * crash after all the files have been copied but before the commit, you
6305 * have files in the data directory without an entry in pg_database. To
6306 * minimize the window for that, we use ForceSyncCommit() to rush the
6307 * commit record to disk as quick as possible. We have the same window
6308 * during recovery, and forcing an XLogFlush() (which updates
6309 * minRecoveryPoint during recovery) helps to reduce that problem window,
6310 * for any user that requested ForceSyncCommit().
6311 */
6313 XLogFlush(lsn);
6314
6315 /*
6316 * If asked by the primary (because someone is waiting for a synchronous
6317 * commit = remote_apply), we will need to ask walreceiver to send a reply
6318 * immediately.
6319 */
6322}
6323
6324/*
6325 * Be careful with the order of execution, as with xact_redo_commit().
6326 * The two functions are similar but differ in key places.
6327 *
6328 * Note also that an abort can be for a subtransaction and its children,
6329 * not just for a top level abort. That means we have to consider
6330 * topxid != xid, whereas in commit we would find topxid == xid always
6331 * because subtransaction commit is never WAL logged.
6332 */
6333static void
6335 XLogRecPtr lsn, ReplOriginId origin_id)
6336{
6338
6340
6341 /* Make sure nextXid is beyond any XID mentioned in the record. */
6343 parsed->nsubxacts,
6344 parsed->subxacts);
6346
6348 {
6349 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6350 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6351 }
6352 else
6353 {
6354 /*
6355 * If a transaction completion record arrives that has as-yet
6356 * unobserved subtransactions then this will not have been fully
6357 * handled by the call to RecordKnownAssignedTransactionIds() in the
6358 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6359 * cover that case. This is confusing and it is easy to think this
6360 * call is irrelevant, which has happened three times in development
6361 * already. Leave it in.
6362 */
6364
6365 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6366 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6367
6368 /*
6369 * We must update the ProcArray after we have marked clog.
6370 */
6371 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6372
6373 /*
6374 * There are no invalidation messages to send or undo.
6375 */
6376
6377 /*
6378 * Release locks, if any. There are no invalidations to send.
6379 */
6380 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6381 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6382 }
6383
6384 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6385 {
6386 /* recover apply progress */
6387 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6388 false /* backward */ , false /* WAL */ );
6389 }
6390
6391 /* Make sure files supposed to be dropped are dropped */
6392 if (parsed->nrels > 0)
6393 {
6394 /*
6395 * See comments about update of minimum recovery point on truncation,
6396 * in xact_redo_commit().
6397 */
6398 XLogFlush(lsn);
6399
6400 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6401 }
6402
6403 if (parsed->nstats > 0)
6404 {
6405 /* see equivalent call for relations above */
6406 XLogFlush(lsn);
6407
6408 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6409 }
6410}
6411
6412void
6414{
6415 uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6416
6417 /* Backup blocks are not used in xact records */
6419
6420 if (info == XLOG_XACT_COMMIT)
6421 {
6424
6427 record->EndRecPtr, XLogRecGetOrigin(record));
6428 }
6429 else if (info == XLOG_XACT_COMMIT_PREPARED)
6430 {
6433
6435 xact_redo_commit(&parsed, parsed.twophase_xid,
6436 record->EndRecPtr, XLogRecGetOrigin(record));
6437
6438 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6440 PrepareRedoRemove(parsed.twophase_xid, false);
6442 }
6443 else if (info == XLOG_XACT_ABORT)
6444 {
6447
6450 record->EndRecPtr, XLogRecGetOrigin(record));
6451 }
6452 else if (info == XLOG_XACT_ABORT_PREPARED)
6453 {
6456
6458 xact_redo_abort(&parsed, parsed.twophase_xid,
6459 record->EndRecPtr, XLogRecGetOrigin(record));
6460
6461 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6463 PrepareRedoRemove(parsed.twophase_xid, false);
6465 }
6466 else if (info == XLOG_XACT_PREPARE)
6467 {
6468 /*
6469 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6470 * gxact entry.
6471 */
6474 XLogRecGetData(record),
6475 record->ReadRecPtr,
6476 record->EndRecPtr,
6477 XLogRecGetOrigin(record));
6479 }
6480 else if (info == XLOG_XACT_ASSIGNMENT)
6481 {
6483
6486 xlrec->nsubxacts, xlrec->xsub);
6487 }
6488 else if (info == XLOG_XACT_INVALIDATIONS)
6489 {
6490 /*
6491 * XXX we do ignore this for now, what matters are invalidations
6492 * written into the commit record.
6493 */
6494 }
6495 else
6496 elog(PANIC, "xact_redo: unknown op code %u", info);
6497}
void pgaio_error_cleanup(void)
Definition aio.c:1175
void AtEOXact_Aio(bool is_commit)
Definition aio.c:1203
void AtCommit_Notify(void)
Definition async.c:1378
void AtAbort_Notify(void)
Definition async.c:2418
void PreCommit_Notify(void)
Definition async.c:1185
void AtSubAbort_Notify(void)
Definition async.c:2507
void AtPrepare_Notify(void)
Definition async.c:1160
void AtSubCommit_Notify(void)
Definition async.c:2437
#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:6332
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1639
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:886
void AtEOXact_Buffers(bool isCommit)
Definition bufmgr.c:4199
void UnlockBuffers(void)
Definition bufmgr.c:5852
#define InvalidCommandId
Definition c.h:753
#define TopSubTransactionId
Definition c.h:743
#define Min(x, y)
Definition c.h:1091
uint8_t uint8
Definition c.h:622
uint32 SubTransactionId
Definition c.h:740
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:249
#define InvalidSubTransactionId
Definition c.h:742
#define Assert(condition)
Definition c.h:943
#define FirstCommandId
Definition c.h:752
uint32 LocalTransactionId
Definition c.h:738
uint32 CommandId
Definition c.h:750
uint32 TransactionId
Definition c.h:736
size_t Size
Definition c.h:689
uint32 result
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
void AtEOXact_ComboCid(void)
Definition combocid.c:182
void TransactionTreeSetCommitTsData(TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz timestamp, ReplOriginId nodeid)
Definition commit_ts.c:150
bool ConditionVariableCancelSleep(void)
int64 TimestampTz
Definition timestamp.h:39
void AtEOXact_HashTables(bool isCommit)
Definition dynahash.c:1864
void AtEOSubXact_HashTables(bool isCommit, int nestDepth)
Definition dynahash.c:1890
Datum arg
Definition elog.c:1323
bool message_level_is_interesting(int elevel)
Definition elog.c:285
int errcode(int sqlerrcode)
Definition elog.c:875
#define FATAL
Definition elog.h:42
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define WARNING
Definition elog.h:37
#define PANIC
Definition elog.h:44
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
#define DEBUG5
Definition elog.h:27
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:92
Oid MyDatabaseTableSpace
Definition globals.c:98
volatile uint32 CritSectionCount
Definition globals.c:45
bool ExitOnAnyError
Definition globals.c:125
Oid MyDatabaseId
Definition globals.c:96
int NewGUCNestLevel(void)
Definition guc.c:2142
void AtStart_GUC(void)
Definition guc.c:2122
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition guc.c:2169
double log_xact_sample_rate
Definition guc_tables.c:575
const char * str
#define IsParallelWorker()
Definition parallel.h:62
void ResetReindexState(int nestLevel)
Definition index.c:4234
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:3580
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
Definition lock.c:4602
void AtPrepare_Locks(void)
Definition lock.c:3484
#define InvalidLocalTransactionId
Definition lock.h:68
void ResetLogicalStreamingState(void)
Definition logical.c:1938
void AtEOXact_LogicalCtl(void)
Definition logicalctl.c:233
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1150
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1767
void LWLockReleaseAll(void)
Definition lwlock.c:1866
@ LW_EXCLUSIVE
Definition lwlock.h:104
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:138
#define START_CRIT_SECTION()
Definition miscadmin.h:152
#define HOLD_INTERRUPTS()
Definition miscadmin.h:136
#define END_CRIT_SECTION()
Definition miscadmin.h:154
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:1670
void AtPrepare_MultiXact(void)
Definition multixact.c:1656
void AtEOXact_MultiXact(void)
Definition multixact.c:1628
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:168
void replorigin_advance(ReplOriginId node, XLogRecPtr remote_commit, XLogRecPtr local_commit, bool go_backward, bool wal_log)
Definition origin.c:928
void replorigin_session_advance(XLogRecPtr remote_commit, XLogRecPtr local_commit)
Definition origin.c:1335
#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:782
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition portalmem.c:981
bool PreCommit_Portals(bool isPrepare)
Definition portalmem.c:678
void AtSubCommit_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, int parentLevel, ResourceOwner parentXactOwner)
Definition portalmem.c:945
void AtCleanup_Portals(void)
Definition portalmem.c:860
void AtSubCleanup_Portals(SubTransactionId mySubid)
Definition portalmem.c:1094
void PreCommit_CheckForSerializationFailure(void)
Definition predicate.c:4632
void PostPrepare_PredicateLocks(FullTransactionId fxid)
Definition predicate.c:4788
void AtPrepare_PredicateLocks(void)
Definition predicate.c:4719
void RegisterPredicateLockingXid(TransactionId xid)
Definition predicate.c:1888
static int fb(int x)
#define DELAY_CHKPT_IN_COMMIT
Definition proc.h:141
#define PGPROC_MAX_CACHED_SUBXIDS
Definition proc.h:43
void XidCacheRemoveRunningXids(TransactionId xid, int nxids, const TransactionId *xids, TransactionId latestXid)
Definition procarray.c:4011
void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
Definition procarray.c:663
void RecordKnownAssignedTransactionIds(TransactionId xid)
Definition procarray.c:4456
void ProcArrayClearTransaction(PGPROC *proc)
Definition procarray.c:899
void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)
Definition procarray.c:1309
void ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids, TransactionId *subxids, TransactionId max_xid)
Definition procarray.c:4525
void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition relcache.c:3368
void AtEOXact_RelationCache(bool isCommit)
Definition relcache.c:3216
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:1048
Size mul_size(Size s1, Size s2)
Definition shmem.c:1063
LocalTransactionId GetNextLocalTransactionId(void)
Definition sinvaladt.c:703
void AtEOXact_SMgr(void)
Definition smgr.c:1017
void SnapBuildResetExportedSnapshotState(void)
Definition snapbuild.c:644
void AtSubAbort_Snapshot(int level)
Definition snapmgr.c:982
void AtEOXact_Snapshot(bool isCommit, bool resetXmin)
Definition snapmgr.c:1016
void AtSubCommit_Snapshot(int level)
Definition snapmgr.c:961
bool XactHasExportedSnapshots(void)
Definition snapmgr.c:1574
void SnapshotSetCommandId(CommandId curcid)
Definition snapmgr.c:490
void AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid)
Definition spi.c:483
bool SPI_inside_nonatomic_context(void)
Definition spi.c:582
void AtEOXact_SPI(bool isCommit)
Definition spi.c:429
PGPROC * MyProc
Definition proc.c:71
int TransactionTimeout
Definition proc.c:66
void LockErrorCleanup(void)
Definition proc.c:818
bool stack_is_too_deep(void)
void StandbyReleaseLockTree(TransactionId xid, int nsubxids, TransactionId *subxids)
Definition standby.c:1094
void LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInitFileInval)
Definition standby.c:1493
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:231
ProcNumber procNumber
Definition proc.h:226
struct PGPROC::@136 vxid
int delayChkptFlags
Definition proc.h:260
ReplOriginId origin
Definition origin.h:45
XLogRecPtr origin_lsn
Definition origin.h:46
TimestampTz origin_timestamp
Definition origin.h:47
struct SubXactCallbackItem * next
Definition xact.c:324
SubXactCallback callback
Definition xact.c:325
TransState state
Definition xact.c:201
SubTransactionId subTransactionId
Definition xact.c:198
FullTransactionId fullTransactionId
Definition xact.c:197
struct TransactionStateData * parent
Definition xact.c:220
MemoryContext priorContext
Definition xact.c:207
bool parallelChildXact
Definition xact.c:217
MemoryContext curTransactionContext
Definition xact.c:205
TBlockState blockState
Definition xact.c:202
bool prevXactReadOnly
Definition xact.c:213
TransactionId * childXids
Definition xact.c:208
bool startedInRecovery
Definition xact.c:214
ResourceOwner curTransactionOwner
Definition xact.c:206
LocalTransactionId localTransactionId
Definition lock.h:65
ProcNumber procNumber
Definition lock.h:64
XLogRecPtr EndRecPtr
Definition xlogreader.h:206
XLogRecPtr ReadRecPtr
Definition xlogreader.h:205
struct XactCallbackItem * next
Definition xact.c:312
void * arg
Definition xact.c:314
XactCallback callback
Definition xact.c:313
TransactionId xtop
Definition xact.h:221
void SubTransSetParent(TransactionId xid, TransactionId parent)
Definition subtrans.c:92
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:375
#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:5106
void AfterTriggerEndSubXact(bool isCommit)
Definition trigger.c:5489
void AfterTriggerFireDeferred(void)
Definition trigger.c:5324
void AfterTriggerEndXact(bool isCommit)
Definition trigger.c:5387
void AfterTriggerBeginSubXact(void)
Definition trigger.c:5441
GlobalTransaction MarkAsPreparing(FullTransactionId fxid, const char *gid, TimestampTz prepared_at, Oid owner, Oid databaseid)
Definition twophase.c:365
void PrepareRedoAdd(FullTransactionId fxid, char *buf, XLogRecPtr start_lsn, XLogRecPtr end_lsn, ReplOriginId origin_id)
Definition twophase.c:2513
void AtAbort_Twophase(void)
Definition twophase.c:310
void PrepareRedoRemove(TransactionId xid, bool giveWarning)
Definition twophase.c:2670
void EndPrepare(GlobalTransaction gxact)
Definition twophase.c:1151
void StartPrepare(GlobalTransaction gxact)
Definition twophase.c:1058
void PostPrepare_Twophase(void)
Definition twophase.c:350
void AtEOXact_TypeCache(void)
Definition typcache.c:3217
void AtEOSubXact_TypeCache(void)
Definition typcache.c:3223
void AdvanceNextFullTransactionIdPastXid(TransactionId xid)
Definition varsup.c:299
FullTransactionId GetNewTransactionId(bool isSubXact)
Definition varsup.c:68
static void pgstat_report_wait_end(void)
Definition wait_event.h:83
const char * name
static bool CommitTransactionCommandInternal(void)
Definition xact.c:3225
bool IsTransactionOrTransactionBlock(void)
Definition xact.c:5040
void SerializeTransactionState(Size maxsize, char *start_address)
Definition xact.c:5591
void ExitParallelMode(void)
Definition xact.c:1094
static TimestampTz xactStartTimestamp
Definition xact.c:282
static bool currentCommandIdUsed
Definition xact.c:270
static void AtSubCommit_Memory(void)
Definition xact.c:1677
void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
Definition xact.c:3186
static void CleanupSubTransaction(void)
Definition xact.c:5434
void BeginInternalSubTransaction(const char *name)
Definition xact.c:4745
static void AtStart_Memory(void)
Definition xact.c:1206
FullTransactionId GetCurrentFullTransactionId(void)
Definition xact.c:514
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition xact.c:3194
static XactCallbackItem * Xact_callbacks
Definition xact.c:317
void WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
Definition xact.c:3761
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:4255
bool IsInTransactionBlock(bool isTopLevel)
Definition xact.c:3820
bool PrepareTransactionBlock(const char *gid)
Definition xact.c:4043
static void AtSubCleanup_Memory(void)
Definition xact.c:2064
static void StartTransaction(void)
Definition xact.c:2106
int GetCurrentTransactionNestLevel(void)
Definition xact.c:931
void xact_redo(XLogReaderState *record)
Definition xact.c:6414
TransactionId GetTopTransactionId(void)
Definition xact.c:428
static void AtSubCommit_childXids(void)
Definition xact.c:1706
static void CallSubXactCallbacks(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition xact.c:3949
void EnterParallelMode(void)
Definition xact.c:1081
static void AtAbort_ResourceOwner(void)
Definition xact.c:1958
TransactionId GetStableLatestTransactionId(void)
Definition xact.c:609
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition xact.c:3776
void UnregisterSubXactCallback(SubXactCallback callback, void *arg)
Definition xact.c:3928
bool XactDeferrable
Definition xact.c:87
static bool forceSyncCommit
Definition xact.c:295
void BeginImplicitTransactionBlock(void)
Definition xact.c:4377
static void CallXactCallbacks(XactEvent event)
Definition xact.c:3889
static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS]
Definition xact.c:260
void RequireTransactionBlock(bool isTopLevel, const char *stmtType)
Definition xact.c:3767
static void AtSubAbort_Memory(void)
Definition xact.c:1946
static SubXactCallbackItem * SubXact_callbacks
Definition xact.c:329
void DefineSavepoint(const char *name)
Definition xact.c:4424
bool DefaultXactDeferrable
Definition xact.c:86
static void CleanupTransaction(void)
Definition xact.c:3059
static int nUnreportedXids
Definition xact.c:259
static const char * TransStateAsString(TransState state)
Definition xact.c:5811
static TimestampTz xactStopTimestamp
Definition xact.c:284
bool TransactionStartedDuringRecovery(void)
Definition xact.c:1044
static void CommitSubTransaction(void)
Definition xact.c:5155
bool XactReadOnly
Definition xact.c:84
static void PushTransaction(void)
Definition xact.c:5467
static TransactionId RecordTransactionCommit(void)
Definition xact.c:1345
static char * prepareGID
Definition xact.c:290
void UnregisterXactCallback(XactCallback callback, void *arg)
Definition xact.c:3868
bool IsTransactionState(void)
Definition xact.c:389
static MemoryContext TransactionAbortContext
Definition xact.c:305
void CommandCounterIncrement(void)
Definition xact.c:1130
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:3698
static void AtCleanup_Memory(void)
Definition xact.c:2016
Size EstimateTransactionStateSpace(void)
Definition xact.c:5563
TransactionStateData * TransactionState
Definition xact.c:223
static void AtSubAbort_childXids(void)
Definition xact.c:1984
TransactionId GetTopTransactionIdIfAny(void)
Definition xact.c:443
static bool AbortCurrentTransactionInternal(void)
Definition xact.c:3519
static SubTransactionId currentSubTransactionId
Definition xact.c:268
static void AssignTransactionId(TransactionState s)
Definition xact.c:637
char TransactionBlockStatusCode(void)
Definition xact.c:5054
void RollbackAndReleaseCurrentSubTransaction(void)
Definition xact.c:4847
static int nParallelCurrentXids
Definition xact.c:128
FullTransactionId GetCurrentFullTransactionIdIfAny(void)
Definition xact.c:532
static void CommitTransaction(void)
Definition xact.c:2270
void StartTransactionCommand(void)
Definition xact.c:3109
static void PopTransaction(void)
Definition xact.c:5529
bool IsAbortedTransactionBlockState(void)
Definition xact.c:409
void ReleaseCurrentSubTransaction(void)
Definition xact.c:4819
void EndImplicitTransactionBlock(void)
Definition xact.c:4402
void StartParallelWorkerTransaction(char *tstatespace)
Definition xact.c:5662
void SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts)
Definition xact.c:861
static void AtSubAbort_ResourceOwner(void)
Definition xact.c:1971
void ReleaseSavepoint(const char *name)
Definition xact.c:4509
static TransactionStateData TopTransactionStateData
Definition xact.c:249
static FullTransactionId XactTopFullTransactionId
Definition xact.c:127
static void ShowTransactionState(const char *str)
Definition xact.c:5699
int XactIsoLevel
Definition xact.c:81
static void PrepareTransaction(void)
Definition xact.c:2558
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:5865
void ForceSyncCommit(void)
Definition xact.c:1182
int GetTopReadOnlyTransactionNestLevel(void)
Definition xact.c:1062
static TransactionId RecordTransactionAbort(bool isSubXact)
Definition xact.c:1796
static void AtCommit_Memory(void)
Definition xact.c:1640
static void AbortSubTransaction(void)
Definition xact.c:5270
bool IsSubTransaction(void)
Definition xact.c:5095
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:6335
bool IsTransactionBlock(void)
Definition xact.c:5022
bool IsInParallelMode(void)
Definition xact.c:1119
int xactGetCommittedChildren(TransactionId **ptr)
Definition xact.c:5841
TransactionId GetCurrentTransactionIdIfAny(void)
Definition xact.c:473
void BeginTransactionBlock(void)
Definition xact.c:3975
static void AtStart_ResourceOwner(void)
Definition xact.c:1256
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition xact.c:881
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition xact.c:872
static const char * BlockStateAsString(TBlockState blockState)
Definition xact.c:5758
void EndParallelWorkerTransaction(void)
Definition xact.c:5687
static void AtAbort_Memory(void)
Definition xact.c:1926
void RegisterXactCallback(XactCallback callback, void *arg)
Definition xact.c:3855
void CommitTransactionCommand(void)
Definition xact.c:3207
void RollbackToSavepoint(const char *name)
Definition xact.c:4618
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:3915
FullTransactionId GetTopFullTransactionIdIfAny(void)
Definition xact.c:501
TransactionId GetCurrentTransactionId(void)
Definition xact.c:456
static void AbortTransaction(void)
Definition xact.c:2853
static void AtStart_Cache(void)
Definition xact.c:1197
static void AtSubStart_ResourceOwner(void)
Definition xact.c:1313
int DefaultXactIsoLevel
Definition xact.c:80
static void AtSubStart_Memory(void)
Definition xact.c:1284
bool xact_is_sampled
Definition xact.c:298
bool EndTransactionBlock(bool chain)
Definition xact.c:4095
bool IsSubxactTopXidLogPending(void)
Definition xact.c:561
#define SerializedTransactionStateHeaderSize
Definition xact.c:241
void AbortOutOfAnyTransaction(void)
Definition xact.c:4913
int MyXactFlags
Definition xact.c:138
static void ShowTransactionStateRec(const char *str, TransactionState s)
Definition xact.c:5711
static TransactionState CurrentTransactionState
Definition xact.c:262
void AbortCurrentTransaction(void)
Definition xact.c:3501
static void StartSubTransaction(void)
Definition xact.c:5118
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:1621
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:6037
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:6181
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:6830
XLogRecPtr XactLastRecEnd
Definition xlog.c:261
XLogRecPtr XactLastCommitEnd
Definition xlog.c:262
void XLogFlush(XLogRecPtr record)
Definition xlog.c:2801
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition xlog.c:2630
#define XLogLogicalInfoActive()
Definition xlog.h:137
#define XLOG_INCLUDE_ORIGIN
Definition xlog.h:166
#define XLogStandbyInfoActive()
Definition xlog.h:126
uint16 ReplOriginId
Definition xlogdefs.h:69
uint64 XLogRecPtr
Definition xlogdefs.h:21
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition xloginsert.c:482
void XLogRegisterData(const void *data, uint32 len)
Definition xloginsert.c:372
void XLogSetRecordFlags(uint8 flags)
Definition xloginsert.c:464
void XLogResetInsertion(void)
Definition xloginsert.c:226
void XLogBeginInsert(void)
Definition xloginsert.c:153
#define XLogRecGetOrigin(decoder)
Definition xlogreader.h:413
#define XLogRecGetInfo(decoder)
Definition xlogreader.h:410
#define XLogRecGetData(decoder)
Definition xlogreader.h:415
#define XLogRecGetXid(decoder)
Definition xlogreader.h:412
#define XLogRecHasAnyBlockRefs(decoder)
Definition xlogreader.h:417
#define XLR_SPECIAL_REL_UPDATE
Definition xlogrecord.h:82
void XLogRequestWalReceiverReply(void)
HotStandbyState standbyState
Definition xlogutils.c:53
@ STANDBY_DISABLED
Definition xlogutils.h:52
@ STANDBY_INITIALIZED
Definition xlogutils.h:53
void WaitLSNCleanup(void)
Definition xlogwait.c:341

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 3501 of file xact.c.

3502{
3503 /*
3504 * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3505 * done.
3506 */
3508 {
3509 }
3510}

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 3519 of file xact.c.

3520{
3522
3523 switch (s->blockState)
3524 {
3525 case TBLOCK_DEFAULT:
3526 if (s->state == TRANS_DEFAULT)
3527 {
3528 /* we are idle, so nothing to do */
3529 }
3530 else
3531 {
3532 /*
3533 * We can get here after an error during transaction start
3534 * (state will be TRANS_START). Need to clean up the
3535 * incompletely started transaction. First, adjust the
3536 * low-level state to suppress warning message from
3537 * AbortTransaction.
3538 */
3539 if (s->state == TRANS_START)
3543 }
3544 break;
3545
3546 /*
3547 * If we aren't in a transaction block, we just do the basic abort
3548 * & cleanup transaction. For this purpose, we treat an implicit
3549 * transaction block as if it were a simple statement.
3550 */
3551 case TBLOCK_STARTED:
3556 break;
3557
3558 /*
3559 * If we are in TBLOCK_BEGIN it means something screwed up right
3560 * after reading "BEGIN TRANSACTION". We assume that the user
3561 * will interpret the error as meaning the BEGIN failed to get him
3562 * into a transaction block, so we should abort and return to idle
3563 * state.
3564 */
3565 case TBLOCK_BEGIN:
3569 break;
3570
3571 /*
3572 * We are somewhere in a transaction block and we've gotten a
3573 * failure, so we abort the transaction and set up the persistent
3574 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3575 */
3576 case TBLOCK_INPROGRESS:
3580 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3581 break;
3582
3583 /*
3584 * Here, we failed while trying to COMMIT. Clean up the
3585 * transaction and return to idle state (we do not want to stay in
3586 * the transaction).
3587 */
3588 case TBLOCK_END:
3592 break;
3593
3594 /*
3595 * Here, we are already in an aborted transaction state and are
3596 * waiting for a ROLLBACK, but for some reason we failed again! So
3597 * we just remain in the abort state.
3598 */
3599 case TBLOCK_ABORT:
3600 case TBLOCK_SUBABORT:
3601 break;
3602
3603 /*
3604 * We are in a failed transaction and we got the ROLLBACK command.
3605 * We have already aborted, we just need to cleanup and go to idle
3606 * state.
3607 */
3608 case TBLOCK_ABORT_END:
3611 break;
3612
3613 /*
3614 * We are in a live transaction and we got a ROLLBACK command.
3615 * Abort, cleanup, go to idle state.
3616 */
3621 break;
3622
3623 /*
3624 * Here, we failed while trying to PREPARE. Clean up the
3625 * transaction and return to idle state (we do not want to stay in
3626 * the transaction).
3627 */
3628 case TBLOCK_PREPARE:
3632 break;
3633
3634 /*
3635 * We got an error inside a subtransaction. Abort just the
3636 * subtransaction, and go to the persistent SUBABORT state until
3637 * we get ROLLBACK.
3638 */
3642 break;
3643
3644 /*
3645 * If we failed while trying to create a subtransaction, clean up
3646 * the broken subtransaction and abort the parent. The same
3647 * applies if we get a failure while ending a subtransaction. As
3648 * we need to abort the parent, return false to request the caller
3649 * to do the next iteration.
3650 */
3651 case TBLOCK_SUBBEGIN:
3652 case TBLOCK_SUBRELEASE:
3653 case TBLOCK_SUBCOMMIT:
3655 case TBLOCK_SUBRESTART:
3658 return false;
3659
3660 /*
3661 * Same as above, except the Abort() was already done.
3662 */
3666 return false;
3667 }
3668
3669 /* Done, no more iterations required */
3670 return true;
3671}

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 4913 of file xact.c.

4914{
4916
4917 /* Ensure we're not running in a doomed memory context */
4919
4920 /*
4921 * Get out of any transaction or nested transaction
4922 */
4923 do
4924 {
4925 switch (s->blockState)
4926 {
4927 case TBLOCK_DEFAULT:
4928 if (s->state == TRANS_DEFAULT)
4929 {
4930 /* Not in a transaction, do nothing */
4931 }
4932 else
4933 {
4934 /*
4935 * We can get here after an error during transaction start
4936 * (state will be TRANS_START). Need to clean up the
4937 * incompletely started transaction. First, adjust the
4938 * low-level state to suppress warning message from
4939 * AbortTransaction.
4940 */
4941 if (s->state == TRANS_START)
4945 }
4946 break;
4947 case TBLOCK_STARTED:
4948 case TBLOCK_BEGIN:
4949 case TBLOCK_INPROGRESS:
4952 case TBLOCK_END:
4954 case TBLOCK_PREPARE:
4955 /* In a transaction, so clean up */
4959 break;
4960 case TBLOCK_ABORT:
4961 case TBLOCK_ABORT_END:
4962
4963 /*
4964 * AbortTransaction is already done, still need Cleanup.
4965 * However, if we failed partway through running ROLLBACK,
4966 * there will be an active portal running that command, which
4967 * we need to shut down before doing CleanupTransaction.
4968 */
4972 break;
4973
4974 /*
4975 * In a subtransaction, so clean it up and abort parent too
4976 */
4977 case TBLOCK_SUBBEGIN:
4979 case TBLOCK_SUBRELEASE:
4980 case TBLOCK_SUBCOMMIT:
4982 case TBLOCK_SUBRESTART:
4985 s = CurrentTransactionState; /* changed by pop */
4986 break;
4987
4988 case TBLOCK_SUBABORT:
4991 /* As above, but AbortSubTransaction already done */
4992 if (s->curTransactionOwner)
4993 {
4994 /* As in TBLOCK_ABORT, might have a live portal to zap */
4999 }
5001 s = CurrentTransactionState; /* changed by pop */
5002 break;
5003 }
5004 } while (s->blockState != TBLOCK_DEFAULT);
5005
5006 /* Should be out of all subxacts now */
5007 Assert(s->parent == NULL);
5008
5009 /*
5010 * Revert to TopMemoryContext, to ensure we exit in a well-defined state
5011 * whether there were any transactions to close or not. (Callers that
5012 * don't intend to exit soon should switch to some other context to avoid
5013 * long-term memory leaks.)
5014 */
5016}

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 5270 of file xact.c.

5271{
5273
5274 /* Prevent cancel/die interrupt while cleaning up */
5276
5277 /* Make sure we have a valid memory context and resource owner */
5280
5281 /*
5282 * Release any LW locks we might be holding as quickly as possible.
5283 * (Regular locks, however, must be held till we finish aborting.)
5284 * Releasing LW locks is critical since we might try to grab them again
5285 * while cleaning up!
5286 *
5287 * FIXME This may be incorrect --- Are there some locks we should keep?
5288 * Buffer locks, for example? I don't think so but I'm not sure.
5289 */
5291
5294
5296
5297 UnlockBuffers();
5298
5299 /* Reset WAL record construction state */
5301
5302 /* Cancel condition variable sleep */
5304
5305 /*
5306 * Also clean up any open wait for lock, since the lock manager will choke
5307 * if we try to wait for another lock before doing this.
5308 */
5310
5311 /*
5312 * If any timeout events are still active, make sure the timeout interrupt
5313 * is scheduled. This covers possible loss of a timeout interrupt due to
5314 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5315 * We delay this till after LockErrorCleanup so that we don't uselessly
5316 * reschedule lock or deadlock check timeouts.
5317 */
5319
5320 /*
5321 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5322 * handler. We do this fairly early in the sequence so that the timeout
5323 * infrastructure will be functional if needed while aborting.
5324 */
5326
5327 /*
5328 * check the current transaction state
5329 */
5330 ShowTransactionState("AbortSubTransaction");
5331
5332 if (s->state != TRANS_INPROGRESS)
5333 elog(WARNING, "AbortSubTransaction while in %s state",
5335
5336 s->state = TRANS_ABORT;
5337
5338 /*
5339 * Reset user ID which might have been changed transiently. (See notes in
5340 * AbortTransaction.)
5341 */
5343
5344 /* Forget about any active REINDEX. */
5346
5347 /* Reset logical streaming state. */
5349
5350 /*
5351 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5352 * exports are not supported in subtransactions.
5353 */
5354
5355 /*
5356 * If this subxact has started any unfinished parallel operation, clean up
5357 * its workers and exit parallel mode. Don't warn about leaked resources.
5358 */
5360 s->parallelModeLevel = 0;
5361
5362 /*
5363 * We can skip all this stuff if the subxact failed before creating a
5364 * ResourceOwner...
5365 */
5366 if (s->curTransactionOwner)
5367 {
5376
5377 /* Advertise the fact that we aborted in pg_xact. */
5379
5380 /* Post-abort cleanup */
5383
5386
5389 false, false);
5390
5391 AtEOXact_Aio(false);
5395 AtEOSubXact_Inval(false);
5398 false, false);
5401 false, false);
5403
5404 AtEOXact_GUC(false, s->gucNestLevel);
5415 }
5416
5417 /*
5418 * Restore the upper transaction's read-only state, too. This should be
5419 * redundant with GUC's cleanup but we may as well do it for consistency
5420 * with the commit case.
5421 */
5423
5425}

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 2853 of file xact.c.

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

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 1926 of file xact.c.

1927{
1928 /*
1929 * Switch into TransactionAbortContext, which should have some free space
1930 * even if nothing else does. We'll work in this context until we've
1931 * finished cleaning up.
1932 *
1933 * It is barely possible to get here when we've not been able to create
1934 * TransactionAbortContext yet; if so use TopMemoryContext.
1935 */
1938 else
1940}

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

Referenced by AbortOutOfAnyTransaction(), and AbortTransaction().

◆ AtAbort_ResourceOwner()

static void AtAbort_ResourceOwner ( void  )
static

Definition at line 1958 of file xact.c.

1959{
1960 /*
1961 * Make sure we have a valid ResourceOwner, if possible (else it will be
1962 * NULL, which is OK)
1963 */
1965}

References CurrentResourceOwner, and TopTransactionResourceOwner.

Referenced by AbortTransaction().

◆ AtCCI_LocalCache()

static void AtCCI_LocalCache ( void  )
static

Definition at line 1621 of file xact.c.

1622{
1623 /*
1624 * Make any pending relation map changes visible. We must do this before
1625 * processing local sinval messages, so that the map changes will get
1626 * reflected into the relcache when relcache invals are processed.
1627 */
1629
1630 /*
1631 * Make catalog changes visible to me for the next command.
1632 */
1634}

References AtCCI_RelationMap(), and CommandEndInvalidationMessages().

Referenced by CommandCounterIncrement().

◆ AtCleanup_Memory()

static void AtCleanup_Memory ( void  )
static

Definition at line 2016 of file xact.c.

2017{
2019
2020 /* Should be at top level */
2021 Assert(s->parent == NULL);
2022
2023 /*
2024 * Return to the memory context that was current before we started the
2025 * transaction. (In principle, this could not be any of the contexts we
2026 * are about to delete. If it somehow is, assertions in mcxt.c will
2027 * complain.)
2028 */
2030
2031 /*
2032 * Clear the special abort context for next time.
2033 */
2036
2037 /*
2038 * Release all transaction-local memory, the same as in AtCommit_Memory,
2039 * except we must cope with the possibility that we didn't get as far as
2040 * creating TopTransactionContext.
2041 */
2044
2045 /*
2046 * Clear these pointers as a pro-forma matter. (Notionally, while
2047 * TopTransactionContext still exists, it's currently not associated with
2048 * this TransactionState struct.)
2049 */
2052}

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 1640 of file xact.c.

1641{
1643
1644 /*
1645 * Return to the memory context that was current before we started the
1646 * transaction. (In principle, this could not be any of the contexts we
1647 * are about to delete. If it somehow is, assertions in mcxt.c will
1648 * complain.)
1649 */
1651
1652 /*
1653 * Release all transaction-local memory. TopTransactionContext survives
1654 * but becomes empty; any sub-contexts go away.
1655 */
1658
1659 /*
1660 * Clear these pointers as a pro-forma matter. (Notionally, while
1661 * TopTransactionContext still exists, it's currently not associated with
1662 * this TransactionState struct.)
1663 */
1666}

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 1197 of file xact.c.

1198{
1200}

References AcceptInvalidationMessages().

Referenced by StartTransaction().

◆ AtStart_Memory()

static void AtStart_Memory ( void  )
static

Definition at line 1206 of file xact.c.

1207{
1209
1210 /*
1211 * Remember the memory context that was active prior to transaction start.
1212 */
1214
1215 /*
1216 * If this is the first time through, create a private context for
1217 * AbortTransaction to work in. By reserving some space now, we can
1218 * insulate AbortTransaction from out-of-memory scenarios. Like
1219 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1220 * size, so that space will be reserved immediately.
1221 */
1225 "TransactionAbortContext",
1226 32 * 1024,
1227 32 * 1024,
1228 32 * 1024);
1229
1230 /*
1231 * Likewise, if this is the first time through, create a top-level context
1232 * for transaction-local data. This context will be reset at transaction
1233 * end, and then re-used in later transactions.
1234 */
1238 "TopTransactionContext",
1240
1241 /*
1242 * In a top-level transaction, CurTransactionContext is the same as
1243 * TopTransactionContext.
1244 */
1247
1248 /* Make the CurTransactionContext active. */
1250}

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 1256 of file xact.c.

1257{
1259
1260 /*
1261 * We shouldn't have a transaction resource owner already.
1262 */
1264
1265 /*
1266 * Create a toplevel resource owner for the transaction.
1267 */
1268 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1269
1273}

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 1984 of file xact.c.

1985{
1987
1988 /*
1989 * We keep the child-XID arrays in TopTransactionContext (see
1990 * AtSubCommit_childXids). This means we'd better free the array
1991 * explicitly at abort to avoid leakage.
1992 */
1993 if (s->childXids != NULL)
1994 pfree(s->childXids);
1995 s->childXids = NULL;
1996 s->nChildXids = 0;
1997 s->maxChildXids = 0;
1998
1999 /*
2000 * We could prune the unreportedXids array here. But we don't bother. That
2001 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
2002 * would likely introduce more CPU time into the more common paths, so we
2003 * choose not to do that.
2004 */
2005}

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 1971 of file xact.c.

1972{
1974
1975 /* Make sure we have a valid ResourceOwner */
1977}

References CurrentResourceOwner, CurrentTransactionState, and TransactionStateData::curTransactionOwner.

Referenced by AbortSubTransaction().

◆ AtSubCleanup_Memory()

static void AtSubCleanup_Memory ( void  )
static

Definition at line 2064 of file xact.c.

2065{
2067
2068 Assert(s->parent != NULL);
2069
2070 /*
2071 * Return to the memory context that was current before we started the
2072 * subtransaction. (In principle, this could not be any of the contexts
2073 * we are about to delete. If it somehow is, assertions in mcxt.c will
2074 * complain.)
2075 */
2077
2078 /* Update CurTransactionContext (might not be same as priorContext) */
2080
2081 /*
2082 * Clear the special abort context for next time.
2083 */
2086
2087 /*
2088 * Delete the subxact local memory contexts. Its CurTransactionContext can
2089 * go too (note this also kills CurTransactionContexts from any children
2090 * of the subxact).
2091 */
2092 if (s->curTransactionContext)
2095}

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 1706 of file xact.c.

1707{
1709 int new_nChildXids;
1710
1711 Assert(s->parent != NULL);
1712
1713 /*
1714 * The parent childXids array will need to hold my XID and all my
1715 * childXids, in addition to the XIDs already there.
1716 */
1718
1719 /* Allocate or enlarge the parent array if necessary */
1721 {
1722 int new_maxChildXids;
1724
1725 /*
1726 * Make it 2x what's needed right now, to avoid having to enlarge it
1727 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1728 * is what ensures that we don't need to worry about integer overflow
1729 * here or in the calculation of new_nChildXids.)
1730 */
1732 (int) (MaxAllocSize / sizeof(TransactionId)));
1733
1735 ereport(ERROR,
1737 errmsg("maximum number of committed subtransactions (%d) exceeded",
1738 (int) (MaxAllocSize / sizeof(TransactionId)))));
1739
1740 /*
1741 * We keep the child-XID arrays in TopTransactionContext; this avoids
1742 * setting up child-transaction contexts for what might be just a few
1743 * bytes of grandchild XIDs.
1744 */
1745 if (s->parent->childXids == NULL)
1749 else
1752
1755 }
1756
1757 /*
1758 * Copy all my XIDs to parent's array.
1759 *
1760 * Note: We rely on the fact that the XID of a child always follows that
1761 * of its parent. By copying the XID of this subtransaction before the
1762 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1763 * all XIDs already in the array belong to subtransactions started and
1764 * subcommitted before us, so their XIDs must precede ours.
1765 */
1767
1768 if (s->nChildXids > 0)
1769 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1770 s->childXids,
1771 s->nChildXids * sizeof(TransactionId));
1772
1774
1775 /* Release child's array to avoid leakage */
1776 if (s->childXids != NULL)
1777 pfree(s->childXids);
1778 /* We must reset these to avoid double-free if fail later in commit */
1779 s->childXids = NULL;
1780 s->nChildXids = 0;
1781 s->maxChildXids = 0;
1782}

References Assert, TransactionStateData::childXids, CurrentTransactionState, ereport, errcode(), errmsg, ERROR, fb(), TransactionStateData::fullTransactionId, MaxAllocSize, TransactionStateData::maxChildXids, memcpy(), 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 1677 of file xact.c.

1678{
1680
1681 Assert(s->parent != NULL);
1682
1683 /* Return to parent transaction level's memory context. */
1686
1687 /*
1688 * Ordinarily we cannot throw away the child's CurTransactionContext,
1689 * since the data it contains will be needed at upper commit. However, if
1690 * there isn't actually anything in it, we can throw it away. This avoids
1691 * a small memory leak in the common case of "trivial" subxacts.
1692 */
1694 {
1697 }
1698}

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 1284 of file xact.c.

1285{
1287
1289
1290 /*
1291 * Remember the context that was active prior to subtransaction start.
1292 */
1294
1295 /*
1296 * Create a CurTransactionContext, which will be used to hold data that
1297 * survives subtransaction commit but disappears on subtransaction abort.
1298 * We make it a child of the immediate parent's CurTransactionContext.
1299 */
1301 "CurTransactionContext",
1304
1305 /* Make the CurTransactionContext active. */
1307}

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 1313 of file xact.c.

1314{
1316
1317 Assert(s->parent != NULL);
1318
1319 /*
1320 * Create a resource owner for the subtransaction. We make it a child of
1321 * the immediate parent's resource owner.
1322 */
1325 "SubTransaction");
1326
1329}

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

Referenced by StartSubTransaction().

◆ BeginImplicitTransactionBlock()

void BeginImplicitTransactionBlock ( void  )

Definition at line 4377 of file xact.c.

4378{
4380
4381 /*
4382 * If we are in STARTED state (that is, no transaction block is open),
4383 * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4384 * block.
4385 *
4386 * For caller convenience, we consider all other transaction states as
4387 * legal here; otherwise the caller would need its own state check, which
4388 * seems rather pointless.
4389 */
4390 if (s->blockState == TBLOCK_STARTED)
4392}

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 4745 of file xact.c.

4746{
4749
4750 /*
4751 * Errors within this function are improbable, but if one does happen we
4752 * force a FATAL exit. Callers generally aren't prepared to handle losing
4753 * control, and moreover our transaction state is probably corrupted if we
4754 * fail partway through; so an ordinary ERROR longjmp isn't okay.
4755 */
4756 ExitOnAnyError = true;
4757
4758 /*
4759 * We do not check for parallel mode here. It's permissible to start and
4760 * end "internal" subtransactions while in parallel mode, so long as no
4761 * new XIDs or command IDs are assigned. Enforcement of that occurs in
4762 * AssignTransactionId() and CommandCounterIncrement().
4763 */
4764
4765 switch (s->blockState)
4766 {
4767 case TBLOCK_STARTED:
4768 case TBLOCK_INPROGRESS:
4771 case TBLOCK_END:
4772 case TBLOCK_PREPARE:
4774 /* Normal subtransaction start */
4776 s = CurrentTransactionState; /* changed by push */
4777
4778 /*
4779 * Savepoint names, like the TransactionState block itself, live
4780 * in TopTransactionContext.
4781 */
4782 if (name)
4784 break;
4785
4786 /* These cases are invalid. */
4787 case TBLOCK_DEFAULT:
4788 case TBLOCK_BEGIN:
4789 case TBLOCK_SUBBEGIN:
4790 case TBLOCK_SUBRELEASE:
4791 case TBLOCK_SUBCOMMIT:
4792 case TBLOCK_ABORT:
4793 case TBLOCK_SUBABORT:
4794 case TBLOCK_ABORT_END:
4798 case TBLOCK_SUBRESTART:
4800 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4802 break;
4803 }
4804
4807
4809}

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 3975 of file xact.c.

3976{
3978
3979 switch (s->blockState)
3980 {
3981 /*
3982 * We are not inside a transaction block, so allow one to begin.
3983 */
3984 case TBLOCK_STARTED:
3986 break;
3987
3988 /*
3989 * BEGIN converts an implicit transaction block to a regular one.
3990 * (Note that we allow this even if we've already done some
3991 * commands, which is a bit odd but matches historical practice.)
3992 */
3995 break;
3996
3997 /*
3998 * Already a transaction block in progress.
3999 */
4000 case TBLOCK_INPROGRESS:
4003 case TBLOCK_ABORT:
4004 case TBLOCK_SUBABORT:
4007 errmsg("there is already a transaction in progress")));
4008 break;
4009
4010 /* These cases are invalid. */
4011 case TBLOCK_DEFAULT:
4012 case TBLOCK_BEGIN:
4013 case TBLOCK_SUBBEGIN:
4014 case TBLOCK_END:
4015 case TBLOCK_SUBRELEASE:
4016 case TBLOCK_SUBCOMMIT:
4017 case TBLOCK_ABORT_END:
4021 case TBLOCK_SUBRESTART:
4023 case TBLOCK_PREPARE:
4024 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
4026 break;
4027 }
4028}

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 5758 of file xact.c.

5759{
5760 switch (blockState)
5761 {
5762 case TBLOCK_DEFAULT:
5763 return "DEFAULT";
5764 case TBLOCK_STARTED:
5765 return "STARTED";
5766 case TBLOCK_BEGIN:
5767 return "BEGIN";
5768 case TBLOCK_INPROGRESS:
5769 return "INPROGRESS";
5771 return "IMPLICIT_INPROGRESS";
5773 return "PARALLEL_INPROGRESS";
5774 case TBLOCK_END:
5775 return "END";
5776 case TBLOCK_ABORT:
5777 return "ABORT";
5778 case TBLOCK_ABORT_END:
5779 return "ABORT_END";
5781 return "ABORT_PENDING";
5782 case TBLOCK_PREPARE:
5783 return "PREPARE";
5784 case TBLOCK_SUBBEGIN:
5785 return "SUBBEGIN";
5787 return "SUBINPROGRESS";
5788 case TBLOCK_SUBRELEASE:
5789 return "SUBRELEASE";
5790 case TBLOCK_SUBCOMMIT:
5791 return "SUBCOMMIT";
5792 case TBLOCK_SUBABORT:
5793 return "SUBABORT";
5795 return "SUBABORT_END";
5797 return "SUBABORT_PENDING";
5798 case TBLOCK_SUBRESTART:
5799 return "SUBRESTART";
5801 return "SUBABORT_RESTART";
5802 }
5803 return "UNRECOGNIZED";
5804}

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 3949 of file xact.c.

3952{
3953 SubXactCallbackItem *item;
3955
3956 for (item = SubXact_callbacks; item; item = next)
3957 {
3958 /* allow callbacks to unregister themselves when called */
3959 next = item->next;
3960 item->callback(event, mySubid, parentSubid, item->arg);
3961 }
3962}

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 3889 of file xact.c.

3890{
3891 XactCallbackItem *item;
3893
3894 for (item = Xact_callbacks; item; item = next)
3895 {
3896 /* allow callbacks to unregister themselves when called */
3897 next = item->next;
3898 item->callback(event, item->arg);
3899 }
3900}

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 3776 of file xact.c.

3777{
3778 /*
3779 * xact block already started?
3780 */
3781 if (IsTransactionBlock())
3782 return;
3783
3784 /*
3785 * subtransaction?
3786 */
3787 if (IsSubTransaction())
3788 return;
3789
3790 /*
3791 * inside a function call?
3792 */
3793 if (!isTopLevel)
3794 return;
3795
3798 /* translator: %s represents an SQL statement name */
3799 errmsg("%s can only be used in transaction blocks",
3800 stmtType)));
3801}

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 3059 of file xact.c.

3060{
3062
3063 /*
3064 * State should still be TRANS_ABORT from AbortTransaction().
3065 */
3066 if (s->state != TRANS_ABORT)
3067 elog(FATAL, "CleanupTransaction: unexpected state %s",
3069
3070 /*
3071 * do abort cleanup processing
3072 */
3073 AtCleanup_Portals(); /* now safe to release portal memory */
3074 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
3075
3076 CurrentResourceOwner = NULL; /* and resource owner */
3082
3083 AtCleanup_Memory(); /* and transaction memory */
3084
3087 s->nestingLevel = 0;
3088 s->gucNestLevel = 0;
3089 s->childXids = NULL;
3090 s->nChildXids = 0;
3091 s->maxChildXids = 0;
3092 s->parallelModeLevel = 0;
3093 s->parallelChildXact = false;
3094
3097
3098 /*
3099 * done with abort processing, set current transaction state back to
3100 * default
3101 */
3102 s->state = TRANS_DEFAULT;
3103}

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 1130 of file xact.c.

1131{
1132 /*
1133 * If the current value of the command counter hasn't been "used" to mark
1134 * tuples, we need not increment it, since there's no need to distinguish
1135 * a read-only command from others. This helps postpone command counter
1136 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
1137 */
1139 {
1140 /*
1141 * Workers synchronize transaction state at the beginning of each
1142 * parallel operation, so we can't account for new commands after that
1143 * point.
1144 */
1146 ereport(ERROR,
1148 errmsg("cannot start commands during a parallel operation")));
1149
1150 currentCommandId += 1;
1152 {
1153 currentCommandId -= 1;
1154 ereport(ERROR,
1156 errmsg("cannot have more than 2^32-2 commands in a transaction")));
1157 }
1158 currentCommandIdUsed = false;
1159
1160 /* Propagate new command ID into static snapshots */
1162
1163 /*
1164 * Make any catalog changes done by the just-completed command visible
1165 * in the local syscache. We obviously don't need to do this after a
1166 * read-only command. (But see hacks in inval.c to make real sure we
1167 * don't think a command that queued inval messages was read-only.)
1168 */
1170 }
1171}

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(), AlterPropGraph(), AlterPublicationAllFlags(), AlterPublicationOptions(), AlterRole(), apply_concurrent_changes(), 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_index_constraints(), copy_table_data(), create_ctas_internal(), create_toast_table(), CreateFKCheckTrigger(), createForeignKeyActionTriggers(), CreateForeignTable(), createPartitionTable(), CreatePropGraph(), 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(), insert_element_record(), 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(), rebuild_relation_finish_concurrent(), recordExtensionInitPrivWorker(), reindex_index(), reindex_relation(), ReindexRelationConcurrently(), relation_statistics_update(), RelationSetNewRelfilenumber(), RemoveInheritedConstraint(), RemoveRoleFromInitPriv(), RemoveRoleFromObjectPolicy(), RenumberEnumType(), ReplaceRoleInInitPriv(), replorigin_create(), replorigin_drop_by_name(), ri_FastPathBatchFlush(), ri_FastPathCheck(), 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 5155 of file xact.c.

5156{
5158
5159 ShowTransactionState("CommitSubTransaction");
5160
5161 if (s->state != TRANS_INPROGRESS)
5162 elog(WARNING, "CommitSubTransaction while in %s state",
5164
5165 /* Pre-commit processing goes here */
5166
5169
5170 /*
5171 * If this subxact has started any unfinished parallel operation, clean up
5172 * its workers and exit parallel mode. Warn about leaked resources.
5173 */
5175 if (s->parallelModeLevel != 0)
5176 {
5177 elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5179 s->parallelModeLevel = 0;
5180 }
5181
5182 /* Do the actual "commit", such as it is */
5183 s->state = TRANS_COMMIT;
5184
5185 /* Must CCI to ensure commands of subtransaction are seen as done */
5187
5188 /*
5189 * Prior to 8.4 we marked subcommit in clog at this point. We now only
5190 * perform that step, if required, as part of the atomic update of the
5191 * whole transaction tree at top level commit or abort.
5192 */
5193
5194 /* Post-commit cleanup */
5200 s->parent->nestingLevel,
5205
5208
5211 true, false);
5215 AtEOSubXact_Inval(true);
5217
5218 /*
5219 * The only lock we actually release here is the subtransaction XID lock.
5220 */
5224
5225 /*
5226 * Other locks should get transferred to their parent resource owner.
5227 */
5230 true, false);
5233 true, false);
5234
5235 AtEOXact_GUC(true, s->gucNestLevel);
5246
5247 /*
5248 * We need to restore the upper transaction's read-only state, in case the
5249 * upper is read-write while the child is read-only; GUC will incorrectly
5250 * think it should leave the child state in place.
5251 */
5253
5258
5260
5261 s->state = TRANS_DEFAULT;
5262
5264}

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 2270 of file xact.c.

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

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 3207 of file xact.c.

3208{
3209 /*
3210 * Repeatedly call CommitTransactionCommandInternal() until all the work
3211 * is done.
3212 */
3214 {
3215 }
3216}

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(), BuildDatabaseList(), BuildRelationList(), clear_subscription_skip_lsn(), copy_sequences(), DatabaseExists(), 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(), ProcessSingleRelationByOid(), ProcessSyncingTablesForApply(), ProcessSyncingTablesForSync(), ReindexMultipleInternal(), ReindexRelationConcurrently(), RemoveTempRelationsCallback(), RepackWorkerMain(), 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 3225 of file xact.c.

3226{
3229
3230 /* Must save in case we need to restore below */
3232
3233 switch (s->blockState)
3234 {
3235 /*
3236 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3237 * StartTransactionCommand didn't set the STARTED state
3238 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3239 * by EndParallelWorkerTransaction(), not this function.
3240 */
3241 case TBLOCK_DEFAULT:
3243 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3245 break;
3246
3247 /*
3248 * If we aren't in a transaction block, just do our usual
3249 * transaction commit, and return to the idle state.
3250 */
3251 case TBLOCK_STARTED:
3254 break;
3255
3256 /*
3257 * We are completing a "BEGIN TRANSACTION" command, so we change
3258 * to the "transaction block in progress" state and return. (We
3259 * assume the BEGIN did nothing to the database, so we need no
3260 * CommandCounterIncrement.)
3261 */
3262 case TBLOCK_BEGIN:
3264 break;
3265
3266 /*
3267 * This is the case when we have finished executing a command
3268 * someplace within a transaction block. We increment the command
3269 * counter and return.
3270 */
3271 case TBLOCK_INPROGRESS:
3275 break;
3276
3277 /*
3278 * We are completing a "COMMIT" command. Do it and return to the
3279 * idle state.
3280 */
3281 case TBLOCK_END:
3284 if (s->chain)
3285 {
3288 s->chain = false;
3290 }
3291 break;
3292
3293 /*
3294 * Here we are in the middle of a transaction block but one of the
3295 * commands caused an abort so we do nothing but remain in the
3296 * abort state. Eventually we will get a ROLLBACK command.
3297 */
3298 case TBLOCK_ABORT:
3299 case TBLOCK_SUBABORT:
3300 break;
3301
3302 /*
3303 * Here we were in an aborted transaction block and we just got
3304 * the ROLLBACK command from the user, so clean up the
3305 * already-aborted transaction and return to the idle state.
3306 */
3307 case TBLOCK_ABORT_END:
3310 if (s->chain)
3311 {
3314 s->chain = false;
3316 }
3317 break;
3318
3319 /*
3320 * Here we were in a perfectly good transaction block but the user
3321 * told us to ROLLBACK anyway. We have to abort the transaction
3322 * and then clean up.
3323 */
3328 if (s->chain)
3329 {
3332 s->chain = false;
3334 }
3335 break;
3336
3337 /*
3338 * We are completing a "PREPARE TRANSACTION" command. Do it and
3339 * return to the idle state.
3340 */
3341 case TBLOCK_PREPARE:
3344 break;
3345
3346 /*
3347 * The user issued a SAVEPOINT inside a transaction block. Start a
3348 * subtransaction. (DefineSavepoint already did PushTransaction,
3349 * so as to have someplace to put the SUBBEGIN state.)
3350 */
3351 case TBLOCK_SUBBEGIN:
3354 break;
3355
3356 /*
3357 * The user issued a RELEASE command, so we end the current
3358 * subtransaction and return to the parent transaction. The parent
3359 * might be ended too, so repeat till we find an INPROGRESS
3360 * transaction or subtransaction.
3361 */
3362 case TBLOCK_SUBRELEASE:
3363 do
3364 {
3366 s = CurrentTransactionState; /* changed by pop */
3367 } while (s->blockState == TBLOCK_SUBRELEASE);
3368
3371 break;
3372
3373 /*
3374 * The user issued a COMMIT, so we end the current subtransaction
3375 * hierarchy and perform final commit. We do this by rolling up
3376 * any subtransactions into their parent, which leads to O(N^2)
3377 * operations with respect to resource owners - this isn't that
3378 * bad until we approach a thousands of savepoints but is
3379 * necessary for correctness should after triggers create new
3380 * resource owners.
3381 */
3382 case TBLOCK_SUBCOMMIT:
3383 do
3384 {
3386 s = CurrentTransactionState; /* changed by pop */
3387 } while (s->blockState == TBLOCK_SUBCOMMIT);
3388 /* If we had a COMMIT command, finish off the main xact too */
3389 if (s->blockState == TBLOCK_END)
3390 {
3391 Assert(s->parent == NULL);
3394 if (s->chain)
3395 {
3398 s->chain = false;
3400 }
3401 }
3402 else if (s->blockState == TBLOCK_PREPARE)
3403 {
3404 Assert(s->parent == NULL);
3407 }
3408 else
3409 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3411 break;
3412
3413 /*
3414 * The current already-failed subtransaction is ending due to a
3415 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3416 * examine the parent (which could be in any of several states).
3417 * As we need to examine the parent, return false to request the
3418 * caller to do the next iteration.
3419 */
3422 return false;
3423
3424 /*
3425 * As above, but it's not dead yet, so abort first.
3426 */
3430 return false;
3431
3432 /*
3433 * The current subtransaction is the target of a ROLLBACK TO
3434 * command. Abort and pop it, then start a new subtransaction
3435 * with the same name.
3436 */
3437 case TBLOCK_SUBRESTART:
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
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 * Same as above, but the subtransaction had already failed, so we
3464 * don't need AbortSubTransaction.
3465 */
3467 {
3468 char *name;
3469 int savepointLevel;
3470
3471 /* save name and keep Cleanup from freeing it */
3472 name = s->name;
3473 s->name = NULL;
3474 savepointLevel = s->savepointLevel;
3475
3477
3479 s = CurrentTransactionState; /* changed by push */
3480 s->name = name;
3481 s->savepointLevel = savepointLevel;
3482
3483 /* This is the same as TBLOCK_SUBBEGIN case */
3487 }
3488 break;
3489 }
3490
3491 /* Done, no more iterations required */
3492 return true;
3493}

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 4424 of file xact.c.

4425{
4427
4428 /*
4429 * Workers synchronize transaction state at the beginning of each parallel
4430 * operation, so we can't account for new subtransactions after that
4431 * point. (Note that this check will certainly error out if s->blockState
4432 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4433 * below.)
4434 */
4436 ereport(ERROR,
4438 errmsg("cannot define savepoints during a parallel operation")));
4439
4440 switch (s->blockState)
4441 {
4442 case TBLOCK_INPROGRESS:
4444 /* Normal subtransaction start */
4446 s = CurrentTransactionState; /* changed by push */
4447
4448 /*
4449 * Savepoint names, like the TransactionState block itself, live
4450 * in TopTransactionContext.
4451 */
4452 if (name)
4454 break;
4455
4456 /*
4457 * We disallow savepoint commands in implicit transaction blocks.
4458 * There would be no great difficulty in allowing them so far as
4459 * this module is concerned, but a savepoint seems inconsistent
4460 * with exec_simple_query's behavior of abandoning the whole query
4461 * string upon error. Also, the point of an implicit transaction
4462 * block (as opposed to a regular one) is to automatically close
4463 * after an error, so it's hard to see how a savepoint would fit
4464 * into that.
4465 *
4466 * The error messages for this are phrased as if there were no
4467 * active transaction block at all, which is historical but
4468 * perhaps could be improved.
4469 */
4471 ereport(ERROR,
4473 /* translator: %s represents an SQL statement name */
4474 errmsg("%s can only be used in transaction blocks",
4475 "SAVEPOINT")));
4476 break;
4477
4478 /* These cases are invalid. */
4479 case TBLOCK_DEFAULT:
4480 case TBLOCK_STARTED:
4481 case TBLOCK_BEGIN:
4483 case TBLOCK_SUBBEGIN:
4484 case TBLOCK_END:
4485 case TBLOCK_SUBRELEASE:
4486 case TBLOCK_SUBCOMMIT:
4487 case TBLOCK_ABORT:
4488 case TBLOCK_SUBABORT:
4489 case TBLOCK_ABORT_END:
4493 case TBLOCK_SUBRESTART:
4495 case TBLOCK_PREPARE:
4496 elog(FATAL, "DefineSavepoint: unexpected state %s",
4498 break;
4499 }
4500}

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 4402 of file xact.c.

4403{
4405
4406 /*
4407 * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4408 * allowing CommitTransactionCommand to commit whatever happened during
4409 * the implicit transaction block as though it were a single statement.
4410 *
4411 * For caller convenience, we consider all other transaction states as
4412 * legal here; otherwise the caller would need its own state check, which
4413 * seems rather pointless.
4414 */
4417}

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 4095 of file xact.c.

4096{
4098 bool result = false;
4099
4100 switch (s->blockState)
4101 {
4102 /*
4103 * We are in a transaction block, so tell CommitTransactionCommand
4104 * to COMMIT.
4105 */
4106 case TBLOCK_INPROGRESS:
4108 result = true;
4109 break;
4110
4111 /*
4112 * We are in an implicit transaction block. If AND CHAIN was
4113 * specified, error. Otherwise commit, but issue a warning
4114 * because there was no explicit BEGIN before this.
4115 */
4117 if (chain)
4118 ereport(ERROR,
4120 /* translator: %s represents an SQL statement name */
4121 errmsg("%s can only be used in transaction blocks",
4122 "COMMIT AND CHAIN")));
4123 else
4126 errmsg("there is no transaction in progress")));
4128 result = true;
4129 break;
4130
4131 /*
4132 * We are in a failed transaction block. Tell
4133 * CommitTransactionCommand it's time to exit the block.
4134 */
4135 case TBLOCK_ABORT:
4137 break;
4138
4139 /*
4140 * We are in a live subtransaction block. Set up to subcommit all
4141 * open subtransactions and then commit the main transaction.
4142 */
4144 while (s->parent != NULL)
4145 {
4148 else
4149 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4151 s = s->parent;
4152 }
4153 if (s->blockState == TBLOCK_INPROGRESS)
4155 else
4156 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4158 result = true;
4159 break;
4160
4161 /*
4162 * Here we are inside an aborted subtransaction. Treat the COMMIT
4163 * as ROLLBACK: set up to abort everything and exit the main
4164 * transaction.
4165 */
4166 case TBLOCK_SUBABORT:
4167 while (s->parent != NULL)
4168 {
4171 else if (s->blockState == TBLOCK_SUBABORT)
4173 else
4174 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4176 s = s->parent;
4177 }
4178 if (s->blockState == TBLOCK_INPROGRESS)
4180 else if (s->blockState == TBLOCK_ABORT)
4182 else
4183 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4185 break;
4186
4187 /*
4188 * The user issued COMMIT when not inside a transaction. For
4189 * COMMIT without CHAIN, issue a WARNING, staying in
4190 * TBLOCK_STARTED state. The upcoming call to
4191 * CommitTransactionCommand() will then close the transaction and
4192 * put us back into the default state. For COMMIT AND CHAIN,
4193 * error.
4194 */
4195 case TBLOCK_STARTED:
4196 if (chain)
4197 ereport(ERROR,
4199 /* translator: %s represents an SQL statement name */
4200 errmsg("%s can only be used in transaction blocks",
4201 "COMMIT AND CHAIN")));
4202 else
4205 errmsg("there is no transaction in progress")));
4206 result = true;
4207 break;
4208
4209 /*
4210 * The user issued a COMMIT that somehow ran inside a parallel
4211 * worker. We can't cope with that.
4212 */
4214 ereport(FATAL,
4216 errmsg("cannot commit during a parallel operation")));
4217 break;
4218
4219 /* These cases are invalid. */
4220 case TBLOCK_DEFAULT:
4221 case TBLOCK_BEGIN:
4222 case TBLOCK_SUBBEGIN:
4223 case TBLOCK_END:
4224 case TBLOCK_SUBRELEASE:
4225 case TBLOCK_SUBCOMMIT:
4226 case TBLOCK_ABORT_END:
4230 case TBLOCK_SUBRESTART:
4232 case TBLOCK_PREPARE:
4233 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4235 break;
4236 }
4237
4239 s->blockState == TBLOCK_END ||
4242
4243 s->chain = chain;
4244
4245 return result;
4246}

References Assert, TransactionStateData::blockState, BlockStateAsString(), TransactionStateData::chain, CurrentTransactionState, elog, ereport, errcode(), errmsg, ERROR, FATAL, fb(), TransactionStateData::parent, result, 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 1182 of file xact.c.

1183{
1184 forceSyncCommit = true;
1185}

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 apply_concurrent_delete(), apply_concurrent_insert(), apply_concurrent_update(), ATRewriteTable(), CatalogTuplesMultiInsertWithInfo(), CopyFrom(), create_edata_for_relation(), create_estate_for_relation(), FindConflictTuple(), GetSnapshotData(), GetSnapshotDataReuse(), heap_inplace_lock(), heap_insert_for_repack(), intorel_startup(), MergePartitionsMoveRows(), pgrowlocks(), RegisterRelcacheInvalidation(), RelationFindReplTupleByIndex(), RelationFindReplTupleSeq(), ri_LockPKTuple(), 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().

◆ GetTopReadOnlyTransactionNestLevel()

int GetTopReadOnlyTransactionNestLevel ( void  )

Definition at line 1062 of file xact.c.

1063{
1065
1066 if (!XactReadOnly)
1067 return 0;
1068 while (s->nestingLevel > 1)
1069 {
1070 if (!s->prevXactReadOnly)
1071 return s->nestingLevel;
1072 s = s->parent;
1073 }
1074 return s->nestingLevel;
1075}

References CurrentTransactionState, TransactionStateData::nestingLevel, TransactionStateData::parent, TransactionStateData::prevXactReadOnly, and XactReadOnly.

Referenced by begin_remote_xact().

◆ GetTopTransactionId()

◆ GetTopTransactionIdIfAny()

◆ IsAbortedTransactionBlockState()

◆ IsInParallelMode()

◆ IsInTransactionBlock()

bool IsInTransactionBlock ( bool  isTopLevel)

Definition at line 3820 of file xact.c.

3821{
3822 /*
3823 * Return true on same conditions that would make
3824 * PreventInTransactionBlock error out
3825 */
3826 if (IsTransactionBlock())
3827 return true;
3828
3829 if (IsSubTransaction())
3830 return true;
3831
3832 if (!isTopLevel)
3833 return true;
3834
3837 return true;
3838
3839 return false;
3840}

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(), LogicalParallelApplyLoop(), 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 5529 of file xact.c.

5530{
5532
5533 if (s->state != TRANS_DEFAULT)
5534 elog(WARNING, "PopTransaction while in %s state",
5536
5537 if (s->parent == NULL)
5538 elog(FATAL, "PopTransaction with no parent");
5539
5541
5542 /* Let's just make sure CurTransactionContext is good */
5545
5546 /* Ditto for ResourceOwner links */
5549
5550 /* Free the old child structure */
5551 if (s->name)
5552 pfree(s->name);
5553 pfree(s);
5554}

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 2558 of file xact.c.

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

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 4043 of file xact.c.

4044{
4046 bool result;
4047
4048 /* Set up to commit the current transaction */
4049 result = EndTransactionBlock(false);
4050
4051 /* If successful, change outer tblock state to PREPARE */
4052 if (result)
4053 {
4055
4056 while (s->parent != NULL)
4057 s = s->parent;
4058
4059 if (s->blockState == TBLOCK_END)
4060 {
4061 /* Save GID where PrepareTransaction can find it again */
4063
4065 }
4066 else
4067 {
4068 /*
4069 * ignore case where we are not in a transaction;
4070 * EndTransactionBlock already issued a warning.
4071 */
4074 /* Don't send back a PREPARE result tag... */
4075 result = false;
4076 }
4077 }
4078
4079 return result;
4080}

References Assert, TransactionStateData::blockState, CurrentTransactionState, EndTransactionBlock(), fb(), MemoryContextStrdup(), TransactionStateData::parent, prepareGID, result, 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 3698 of file xact.c.

3699{
3700 /*
3701 * xact block already started?
3702 */
3703 if (IsTransactionBlock())
3704 ereport(ERROR,
3706 /* translator: %s represents an SQL statement name */
3707 errmsg("%s cannot run inside a transaction block",
3708 stmtType)));
3709
3710 /*
3711 * subtransaction?
3712 */
3713 if (IsSubTransaction())
3714 ereport(ERROR,
3716 /* translator: %s represents an SQL statement name */
3717 errmsg("%s cannot run inside a subtransaction",
3718 stmtType)));
3719
3720 /*
3721 * inside a function call?
3722 */
3723 if (!isTopLevel)
3724 ereport(ERROR,
3726 /* translator: %s represents an SQL statement name */
3727 errmsg("%s cannot be executed from a function or procedure",
3728 stmtType)));
3729
3730 /* If we got past IsTransactionBlock test, should be in default state */
3733 elog(FATAL, "cannot prevent transaction chain");
3734
3735 /* All okay. Set the flag to make sure the right thing happens later. */
3737}

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 5467 of file xact.c.

5468{
5471
5472 /*
5473 * We keep subtransaction state nodes in TopTransactionContext.
5474 */
5475 s = (TransactionState)
5477 sizeof(TransactionStateData));
5478
5479 /*
5480 * Assign a subtransaction ID, watching out for counter wraparound.
5481 */
5484 {
5486 pfree(s);
5487 ereport(ERROR,
5489 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5490 }
5491
5492 /*
5493 * We can now stack a minimally valid subtransaction without fear of
5494 * failure.
5495 */
5496 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5498 s->parent = p;
5499 s->nestingLevel = p->nestingLevel + 1;
5502 s->state = TRANS_DEFAULT;
5507 s->parallelModeLevel = 0;
5509 s->topXidLogged = false;
5510
5512
5513 /*
5514 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5515 * with the subtransaction from here on out; in particular they should not
5516 * assume that it necessarily has a transaction context, resource owner,
5517 * or XID.
5518 */
5519}

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 1796 of file xact.c.

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

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 1345 of file xact.c.

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

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 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
4830 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4835 s = CurrentTransactionState; /* changed by pop */
4837}

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 4509 of file xact.c.

4510{
4512 TransactionState target,
4513 xact;
4514
4515 /*
4516 * Workers synchronize transaction state at the beginning of each parallel
4517 * operation, so we can't account for transaction state change after that
4518 * point. (Note that this check will certainly error out if s->blockState
4519 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4520 * below.)
4521 */
4523 ereport(ERROR,
4525 errmsg("cannot release savepoints during a parallel operation")));
4526
4527 switch (s->blockState)
4528 {
4529 /*
4530 * We can't release a savepoint if there is no savepoint defined.
4531 */
4532 case TBLOCK_INPROGRESS:
4533 ereport(ERROR,
4535 errmsg("savepoint \"%s\" does not exist", name)));
4536 break;
4537
4539 /* See comment about implicit transactions in DefineSavepoint */
4540 ereport(ERROR,
4542 /* translator: %s represents an SQL statement name */
4543 errmsg("%s can only be used in transaction blocks",
4544 "RELEASE SAVEPOINT")));
4545 break;
4546
4547 /*
4548 * We are in a non-aborted subtransaction. This is the only valid
4549 * case.
4550 */
4552 break;
4553
4554 /* These cases are invalid. */
4555 case TBLOCK_DEFAULT:
4556 case TBLOCK_STARTED:
4557 case TBLOCK_BEGIN:
4559 case TBLOCK_SUBBEGIN:
4560 case TBLOCK_END:
4561 case TBLOCK_SUBRELEASE:
4562 case TBLOCK_SUBCOMMIT:
4563 case TBLOCK_ABORT:
4564 case TBLOCK_SUBABORT:
4565 case TBLOCK_ABORT_END:
4569 case TBLOCK_SUBRESTART:
4571 case TBLOCK_PREPARE:
4572 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4574 break;
4575 }
4576
4577 for (target = s; target; target = target->parent)
4578 {
4579 if (target->name && strcmp(target->name, name) == 0)
4580 break;
4581 }
4582
4583 if (!target)
4584 ereport(ERROR,
4586 errmsg("savepoint \"%s\" does not exist", name)));
4587
4588 /* disallow crossing savepoint level boundaries */
4589 if (target->savepointLevel != s->savepointLevel)
4590 ereport(ERROR,
4592 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4593
4594 /*
4595 * Mark "commit pending" all subtransactions up to the target
4596 * subtransaction. The actual commits will happen when control gets to
4597 * CommitTransactionCommand.
4598 */
4600 for (;;)
4601 {
4602 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
4603 xact->blockState = TBLOCK_SUBRELEASE;
4604 if (xact == target)
4605 break;
4606 xact = xact->parent;
4607 Assert(xact);
4608 }
4609}

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 3767 of file xact.c.

3768{
3769 CheckTransactionBlock(isTopLevel, true, stmtType);
3770}

References CheckTransactionBlock(), and fb().

Referenced by PerformCursorOpen(), and standard_ProcessUtility().

◆ RestoreTransactionCharacteristics()

◆ RollbackAndReleaseCurrentSubTransaction()

void RollbackAndReleaseCurrentSubTransaction ( void  )

Definition at line 4847 of file xact.c.

4848{
4850
4851 /*
4852 * We do not check for parallel mode here. It's permissible to start and
4853 * end "internal" subtransactions while in parallel mode, so long as no
4854 * new XIDs or command IDs are assigned.
4855 */
4856
4857 switch (s->blockState)
4858 {
4859 /* Must be in a subtransaction */
4861 case TBLOCK_SUBABORT:
4862 break;
4863
4864 /* These cases are invalid. */
4865 case TBLOCK_DEFAULT:
4866 case TBLOCK_STARTED:
4867 case TBLOCK_BEGIN:
4870 case TBLOCK_SUBBEGIN:
4871 case TBLOCK_INPROGRESS:
4872 case TBLOCK_END:
4873 case TBLOCK_SUBRELEASE:
4874 case TBLOCK_SUBCOMMIT:
4875 case TBLOCK_ABORT:
4876 case TBLOCK_ABORT_END:
4880 case TBLOCK_SUBRESTART:
4882 case TBLOCK_PREPARE:
4883 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4885 break;
4886 }
4887
4888 /*
4889 * Abort the current subtransaction, if needed.
4890 */
4893
4894 /* And clean it up, too */
4896
4897 s = CurrentTransactionState; /* changed by pop */
4903}

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 4618 of file xact.c.

4619{
4621 TransactionState target,
4622 xact;
4623
4624 /*
4625 * Workers synchronize transaction state at the beginning of each parallel
4626 * operation, so we can't account for transaction state change after that
4627 * point. (Note that this check will certainly error out if s->blockState
4628 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4629 * below.)
4630 */
4632 ereport(ERROR,
4634 errmsg("cannot rollback to savepoints during a parallel operation")));
4635
4636 switch (s->blockState)
4637 {
4638 /*
4639 * We can't rollback to a savepoint if there is no savepoint
4640 * defined.
4641 */
4642 case TBLOCK_INPROGRESS:
4643 case TBLOCK_ABORT:
4644 ereport(ERROR,
4646 errmsg("savepoint \"%s\" does not exist", name)));
4647 break;
4648
4650 /* See comment about implicit transactions in DefineSavepoint */
4651 ereport(ERROR,
4653 /* translator: %s represents an SQL statement name */
4654 errmsg("%s can only be used in transaction blocks",
4655 "ROLLBACK TO SAVEPOINT")));
4656 break;
4657
4658 /*
4659 * There is at least one savepoint, so proceed.
4660 */
4662 case TBLOCK_SUBABORT:
4663 break;
4664
4665 /* These cases are invalid. */
4666 case TBLOCK_DEFAULT:
4667 case TBLOCK_STARTED:
4668 case TBLOCK_BEGIN:
4670 case TBLOCK_SUBBEGIN:
4671 case TBLOCK_END:
4672 case TBLOCK_SUBRELEASE:
4673 case TBLOCK_SUBCOMMIT:
4674 case TBLOCK_ABORT_END:
4678 case TBLOCK_SUBRESTART:
4680 case TBLOCK_PREPARE:
4681 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4683 break;
4684 }
4685
4686 for (target = s; target; target = target->parent)
4687 {
4688 if (target->name && strcmp(target->name, name) == 0)
4689 break;
4690 }
4691
4692 if (!target)
4693 ereport(ERROR,
4695 errmsg("savepoint \"%s\" does not exist", name)));
4696
4697 /* disallow crossing savepoint level boundaries */
4698 if (target->savepointLevel != s->savepointLevel)
4699 ereport(ERROR,
4701 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4702
4703 /*
4704 * Mark "abort pending" all subtransactions up to the target
4705 * subtransaction. The actual aborts will happen when control gets to
4706 * CommitTransactionCommand.
4707 */
4709 for (;;)
4710 {
4711 if (xact == target)
4712 break;
4713 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4715 else if (xact->blockState == TBLOCK_SUBABORT)
4716 xact->blockState = TBLOCK_SUBABORT_END;
4717 else
4718 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4719 BlockStateAsString(xact->blockState));
4720 xact = xact->parent;
4721 Assert(xact);
4722 }
4723
4724 /* And mark the target as "restart pending" */
4725 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4726 xact->blockState = TBLOCK_SUBRESTART;
4727 else if (xact->blockState == TBLOCK_SUBABORT)
4728 xact->blockState = TBLOCK_SUBABORT_RESTART;
4729 else
4730 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4731 BlockStateAsString(xact->blockState));
4732}

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 5591 of file xact.c.

5592{
5594 Size nxids = 0;
5595 Size i = 0;
5596 TransactionId *workspace;
5598
5600
5602 result->xactDeferrable = XactDeferrable;
5603 result->topFullTransactionId = XactTopFullTransactionId;
5604 result->currentFullTransactionId =
5606 result->currentCommandId = currentCommandId;
5607
5608 /*
5609 * If we're running in a parallel worker and launching a parallel worker
5610 * of our own, we can just pass along the information that was passed to
5611 * us.
5612 */
5613 if (nParallelCurrentXids > 0)
5614 {
5615 result->nParallelCurrentXids = nParallelCurrentXids;
5616 memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
5618 return;
5619 }
5620
5621 /*
5622 * OK, we need to generate a sorted list of XIDs that our workers should
5623 * view as current. First, figure out how many there are.
5624 */
5625 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5626 {
5628 nxids = add_size(nxids, 1);
5630 }
5632 <= maxsize);
5633
5634 /* Copy them to our scratch space. */
5635 workspace = palloc(nxids * sizeof(TransactionId));
5636 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5637 {
5639 workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5640 if (s->nChildXids > 0)
5641 memcpy(&workspace[i], s->childXids,
5642 s->nChildXids * sizeof(TransactionId));
5643 i += s->nChildXids;
5644 }
5645 Assert(i == nxids);
5646
5647 /* Sort them. */
5648 qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5649
5650 /* Copy data into output area. */
5651 result->nParallelCurrentXids = nxids;
5652 memcpy(&result->parallelCurrentXids[0], workspace,
5653 nxids * sizeof(TransactionId));
5654}

References add_size(), Assert, TransactionStateData::childXids, currentCommandId, CurrentTransactionState, fb(), TransactionStateData::fullTransactionId, FullTransactionIdIsValid, i, memcpy(), TransactionStateData::nChildXids, nParallelCurrentXids, palloc(), ParallelCurrentXids, TransactionStateData::parent, qsort, result, SerializedTransactionStateHeaderSize, 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 5711 of file xact.c.

5712{
5714
5715 if (s->parent)
5716 {
5717 /*
5718 * Since this function recurses, it could be driven to stack overflow.
5719 * This is just a debugging aid, so we can leave out some details
5720 * instead of erroring out with check_stack_depth().
5721 */
5722 if (stack_is_too_deep())
5724 (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5725 str, s->nestingLevel)));
5726 else
5728 }
5729
5731 if (s->nChildXids > 0)
5732 {
5733 int i;
5734
5735 appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5736 for (i = 1; i < s->nChildXids; i++)
5737 appendStringInfo(&buf, " %u", s->childXids[i]);
5738 }
5740 (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5741 str, s->nestingLevel,
5742 s->name ? s->name : "unnamed",
5743 BlockStateAsString(s->blockState),
5745 XidFromFullTransactionId(s->fullTransactionId),
5746 s->subTransactionId,
5748 currentCommandIdUsed ? " (used)" : "",
5749 buf.data)));
5750 pfree(buf.data);
5751}

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 5118 of file xact.c.

5119{
5121
5122 if (s->state != TRANS_DEFAULT)
5123 elog(WARNING, "StartSubTransaction while in %s state",
5125
5126 s->state = TRANS_START;
5127
5128 /*
5129 * Initialize subsystems for new subtransaction
5130 *
5131 * must initialize resource-management stuff first
5132 */
5136
5138
5139 /*
5140 * Call start-of-subxact callbacks
5141 */
5144
5145 ShowTransactionState("StartSubTransaction");
5146}

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 2106 of file xact.c.

2107{
2110
2111 /*
2112 * Let's just make sure the state stack is empty
2113 */
2116
2118
2119 /* check the current transaction state */
2120 Assert(s->state == TRANS_DEFAULT);
2121
2122 /*
2123 * Set the current transaction state information appropriately during
2124 * start processing. Note that once the transaction status is switched
2125 * this process cannot fail until the user ID and the security context
2126 * flags are fetched below.
2127 */
2128 s->state = TRANS_START;
2129 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
2130
2131 /* Determine if statements are logged in this transaction */
2133 (log_xact_sample_rate == 1 ||
2135
2136 /*
2137 * initialize current transaction state fields
2138 *
2139 * note: prevXactReadOnly is not used at the outermost level
2140 */
2141 s->nestingLevel = 1;
2142 s->gucNestLevel = 1;
2143 s->childXids = NULL;
2144 s->nChildXids = 0;
2145 s->maxChildXids = 0;
2146
2147 /*
2148 * Once the current user ID and the security context flags are fetched,
2149 * both will be properly reset even if transaction startup fails.
2150 */
2152
2153 /* SecurityRestrictionContext should never be set outside a transaction */
2154 Assert(s->prevSecContext == 0);
2155
2156 /*
2157 * Make sure we've reset xact state variables
2158 *
2159 * If recovery is still in progress, mark this transaction as read-only.
2160 * We have lower level defences in XLogInsert and elsewhere to stop us
2161 * from modifying data during recovery, but this gives the normal
2162 * indication to the user that the transaction is read-only.
2163 */
2164 if (RecoveryInProgress())
2165 {
2166 s->startedInRecovery = true;
2167 XactReadOnly = true;
2168 }
2169 else
2170 {
2171 s->startedInRecovery = false;
2173 }
2176 forceSyncCommit = false;
2177 MyXactFlags = 0;
2178
2179 /*
2180 * reinitialize within-transaction counters
2181 */
2185 currentCommandIdUsed = false;
2186
2187 /*
2188 * initialize reported xid accounting
2189 */
2190 nUnreportedXids = 0;
2191 s->didLogXid = false;
2192
2193 /*
2194 * must initialize resource-management stuff first
2195 */
2198
2199 /*
2200 * Assign a new LocalTransactionId, and combine it with the proc number to
2201 * form a virtual transaction id.
2202 */
2203 vxid.procNumber = MyProcNumber;
2205
2206 /*
2207 * Lock the virtual transaction id before we announce it in the proc array
2208 */
2210
2211 /*
2212 * Advertise it in the proc array. We assume assignment of
2213 * localTransactionId is atomic, and the proc number should be set
2214 * already.
2215 */
2218
2220
2221 /*
2222 * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2223 * be the same as the first command's statement_timestamp(), so don't do a
2224 * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2225 * for transactions started inside procedures (i.e., nonatomic SPI
2226 * contexts), we do need to advance the timestamp. Also, in a parallel
2227 * worker, the timestamp should already have been provided by a call to
2228 * SetParallelStartTimestamps().
2229 */
2230 if (!IsParallelWorker())
2231 {
2234 else
2236 }
2237 else
2240 /* Mark xactStopTimestamp as unset. */
2242
2243 /*
2244 * initialize other subsystems for new transaction
2245 */
2246 AtStart_GUC();
2247 AtStart_Cache();
2249
2250 /*
2251 * done with start processing, set current transaction state to "in
2252 * progress"
2253 */
2255
2256 /* Schedule transaction timeout */
2257 if (TransactionTimeout > 0)
2259
2260 ShowTransactionState("StartTransaction");
2261}

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 3109 of file xact.c.

3110{
3112
3113 switch (s->blockState)
3114 {
3115 /*
3116 * if we aren't in a transaction block, we just do our usual start
3117 * transaction.
3118 */
3119 case TBLOCK_DEFAULT:
3122 break;
3123
3124 /*
3125 * We are somewhere in a transaction block or subtransaction and
3126 * about to start a new command. For now we do nothing, but
3127 * someday we may do command-local resource initialization. (Note
3128 * that any needed CommandCounterIncrement was done by the
3129 * previous CommitTransactionCommand.)
3130 */
3131 case TBLOCK_INPROGRESS:
3134 break;
3135
3136 /*
3137 * Here we are in a failed transaction block (one of the commands
3138 * caused an abort) so we do nothing but remain in the abort
3139 * state. Eventually we will get a ROLLBACK command which will
3140 * get us out of this state. (It is up to other code to ensure
3141 * that no commands other than ROLLBACK will be processed in these
3142 * states.)
3143 */
3144 case TBLOCK_ABORT:
3145 case TBLOCK_SUBABORT:
3146 break;
3147
3148 /* These cases are invalid. */
3149 case TBLOCK_STARTED:
3150 case TBLOCK_BEGIN:
3152 case TBLOCK_SUBBEGIN:
3153 case TBLOCK_END:
3154 case TBLOCK_SUBRELEASE:
3155 case TBLOCK_SUBCOMMIT:
3156 case TBLOCK_ABORT_END:
3160 case TBLOCK_SUBRESTART:
3162 case TBLOCK_PREPARE:
3163 elog(ERROR, "StartTransactionCommand: unexpected state %s",
3165 break;
3166 }
3167
3168 /*
3169 * We must switch to CurTransactionContext before returning. This is
3170 * already done if we called StartTransaction, otherwise not.
3171 */
3174}

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(), BuildDatabaseList(), BuildRelationList(), clear_subscription_skip_lsn(), copy_sequences(), DatabaseExists(), 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(), ProcessSingleRelationByOid(), ProcessSyncingTablesForApply(), ProcessSyncingTablesForSync(), ReindexMultipleInternal(), ReindexRelationConcurrently(), RemoveTempRelationsCallback(), ReorderBufferProcessTXN(), RepackWorkerMain(), 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 5054 of file xact.c.

5055{
5057
5058 switch (s->blockState)
5059 {
5060 case TBLOCK_DEFAULT:
5061 case TBLOCK_STARTED:
5062 return 'I'; /* idle --- not in transaction */
5063 case TBLOCK_BEGIN:
5064 case TBLOCK_SUBBEGIN:
5065 case TBLOCK_INPROGRESS:
5069 case TBLOCK_END:
5070 case TBLOCK_SUBRELEASE:
5071 case TBLOCK_SUBCOMMIT:
5072 case TBLOCK_PREPARE:
5073 return 'T'; /* in transaction */
5074 case TBLOCK_ABORT:
5075 case TBLOCK_SUBABORT:
5076 case TBLOCK_ABORT_END:
5080 case TBLOCK_SUBRESTART:
5082 return 'E'; /* in failed transaction */
5083 }
5084
5085 /* should never get here */
5086 elog(FATAL, "invalid transaction block state: %s",
5088 return 0; /* keep compiler quiet */
5089}

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 5811 of file xact.c.

5812{
5813 switch (state)
5814 {
5815 case TRANS_DEFAULT:
5816 return "DEFAULT";
5817 case TRANS_START:
5818 return "START";
5819 case TRANS_INPROGRESS:
5820 return "INPROGRESS";
5821 case TRANS_COMMIT:
5822 return "COMMIT";
5823 case TRANS_ABORT:
5824 return "ABORT";
5825 case TRANS_PREPARE:
5826 return "PREPARE";
5827 }
5828 return "UNRECOGNIZED";
5829}

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 3928 of file xact.c.

3929{
3930 SubXactCallbackItem *item;
3931 SubXactCallbackItem *prev;
3932
3933 prev = NULL;
3934 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3935 {
3936 if (item->callback == callback && item->arg == arg)
3937 {
3938 if (prev)
3939 prev->next = item->next;
3940 else
3941 SubXact_callbacks = item->next;
3942 pfree(item);
3943 break;
3944 }
3945 }
3946}

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

◆ UnregisterXactCallback()

void UnregisterXactCallback ( XactCallback  callback,
void arg 
)

Definition at line 3868 of file xact.c.

3869{
3870 XactCallbackItem *item;
3871 XactCallbackItem *prev;
3872
3873 prev = NULL;
3874 for (item = Xact_callbacks; item; prev = item, item = item->next)
3875 {
3876 if (item->callback == callback && item->arg == arg)
3877 {
3878 if (prev)
3879 prev->next = item->next;
3880 else
3881 Xact_callbacks = item->next;
3882 pfree(item);
3883 break;
3884 }
3885 }
3886}

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

◆ UserAbortTransactionBlock()

void UserAbortTransactionBlock ( bool  chain)

Definition at line 4255 of file xact.c.

4256{
4258
4259 switch (s->blockState)
4260 {
4261 /*
4262 * We are inside a transaction block and we got a ROLLBACK command
4263 * from the user, so tell CommitTransactionCommand to abort and
4264 * exit the transaction block.
4265 */
4266 case TBLOCK_INPROGRESS:
4268 break;
4269
4270 /*
4271 * We are inside a failed transaction block and we got a ROLLBACK
4272 * command from the user. Abort processing is already done, so
4273 * CommitTransactionCommand just has to cleanup and go back to
4274 * idle state.
4275 */
4276 case TBLOCK_ABORT:
4278 break;
4279
4280 /*
4281 * We are inside a subtransaction. Mark everything up to top
4282 * level as exitable.
4283 */
4285 case TBLOCK_SUBABORT:
4286 while (s->parent != NULL)
4287 {
4290 else if (s->blockState == TBLOCK_SUBABORT)
4292 else
4293 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4295 s = s->parent;
4296 }
4297 if (s->blockState == TBLOCK_INPROGRESS)
4299 else if (s->blockState == TBLOCK_ABORT)
4301 else
4302 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4304 break;
4305
4306 /*
4307 * The user issued ABORT when not inside a transaction. For
4308 * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4309 * The upcoming call to CommitTransactionCommand() will then put
4310 * us back into the default state. For ROLLBACK AND CHAIN, error.
4311 *
4312 * We do the same thing with ABORT inside an implicit transaction,
4313 * although in this case we might be rolling back actual database
4314 * state changes. (It's debatable whether we should issue a
4315 * WARNING in this case, but we have done so historically.)
4316 */
4317 case TBLOCK_STARTED:
4319 if (chain)
4320 ereport(ERROR,
4322 /* translator: %s represents an SQL statement name */
4323 errmsg("%s can only be used in transaction blocks",
4324 "ROLLBACK AND CHAIN")));
4325 else
4328 errmsg("there is no transaction in progress")));
4330 break;
4331
4332 /*
4333 * The user issued an ABORT that somehow ran inside a parallel
4334 * worker. We can't cope with that.
4335 */
4337 ereport(FATAL,
4339 errmsg("cannot abort during a parallel operation")));
4340 break;
4341
4342 /* These cases are invalid. */
4343 case TBLOCK_DEFAULT:
4344 case TBLOCK_BEGIN:
4345 case TBLOCK_SUBBEGIN:
4346 case TBLOCK_END:
4347 case TBLOCK_SUBRELEASE:
4348 case TBLOCK_SUBCOMMIT:
4349 case TBLOCK_ABORT_END:
4353 case TBLOCK_SUBRESTART:
4355 case TBLOCK_PREPARE:
4356 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4358 break;
4359 }
4360
4363
4364 s->chain = chain;
4365}

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 3761 of file xact.c.

3762{
3763 CheckTransactionBlock(isTopLevel, false, stmtType);
3764}

References CheckTransactionBlock(), and fb().

Referenced by ExecSetVariableStmt(), and standard_ProcessUtility().

◆ xact_redo()

void xact_redo ( XLogReaderState record)

Definition at line 6414 of file xact.c.

6415{
6416 uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6417
6418 /* Backup blocks are not used in xact records */
6420
6421 if (info == XLOG_XACT_COMMIT)
6422 {
6425
6428 record->EndRecPtr, XLogRecGetOrigin(record));
6429 }
6430 else if (info == XLOG_XACT_COMMIT_PREPARED)
6431 {
6434
6436 xact_redo_commit(&parsed, parsed.twophase_xid,
6437 record->EndRecPtr, XLogRecGetOrigin(record));
6438
6439 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6441 PrepareRedoRemove(parsed.twophase_xid, false);
6443 }
6444 else if (info == XLOG_XACT_ABORT)
6445 {
6448
6451 record->EndRecPtr, XLogRecGetOrigin(record));
6452 }
6453 else if (info == XLOG_XACT_ABORT_PREPARED)
6454 {
6457
6459 xact_redo_abort(&parsed, parsed.twophase_xid,
6460 record->EndRecPtr, XLogRecGetOrigin(record));
6461
6462 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6464 PrepareRedoRemove(parsed.twophase_xid, false);
6466 }
6467 else if (info == XLOG_XACT_PREPARE)
6468 {
6469 /*
6470 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6471 * gxact entry.
6472 */
6475 XLogRecGetData(record),
6476 record->ReadRecPtr,
6477 record->EndRecPtr,
6478 XLogRecGetOrigin(record));
6480 }
6481 else if (info == XLOG_XACT_ASSIGNMENT)
6482 {
6484
6487 xlrec->nsubxacts, xlrec->xsub);
6488 }
6489 else if (info == XLOG_XACT_INVALIDATIONS)
6490 {
6491 /*
6492 * XXX we do ignore this for now, what matters are invalidations
6493 * written into the commit record.
6494 */
6495 }
6496 else
6497 elog(PANIC, "xact_redo: unknown op code %u", info);
6498}

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 6335 of file xact.c.

6337{
6339
6341
6342 /* Make sure nextXid is beyond any XID mentioned in the record. */
6344 parsed->nsubxacts,
6345 parsed->subxacts);
6347
6349 {
6350 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6351 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6352 }
6353 else
6354 {
6355 /*
6356 * If a transaction completion record arrives that has as-yet
6357 * unobserved subtransactions then this will not have been fully
6358 * handled by the call to RecordKnownAssignedTransactionIds() in the
6359 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6360 * cover that case. This is confusing and it is easy to think this
6361 * call is irrelevant, which has happened three times in development
6362 * already. Leave it in.
6363 */
6365
6366 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6367 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6368
6369 /*
6370 * We must update the ProcArray after we have marked clog.
6371 */
6372 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6373
6374 /*
6375 * There are no invalidation messages to send or undo.
6376 */
6377
6378 /*
6379 * Release locks, if any. There are no invalidations to send.
6380 */
6381 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6382 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6383 }
6384
6385 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6386 {
6387 /* recover apply progress */
6388 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6389 false /* backward */ , false /* WAL */ );
6390 }
6391
6392 /* Make sure files supposed to be dropped are dropped */
6393 if (parsed->nrels > 0)
6394 {
6395 /*
6396 * See comments about update of minimum recovery point on truncation,
6397 * in xact_redo_commit().
6398 */
6399 XLogFlush(lsn);
6400
6401 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6402 }
6403
6404 if (parsed->nstats > 0)
6405 {
6406 /* see equivalent call for relations above */
6407 XLogFlush(lsn);
6408
6409 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6410 }
6411}

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 6181 of file xact.c.

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

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 5841 of file xact.c.

5842{
5844
5845 if (s->nChildXids == 0)
5846 *ptr = NULL;
5847 else
5848 *ptr = s->childXids;
5849
5850 return s->nChildXids;
5851}

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 6037 of file xact.c.

6043{
6052
6053 uint8 info;
6054
6056
6057 xl_xinfo.xinfo = 0;
6058
6059 /* decide between a plain and 2pc abort */
6060 if (!TransactionIdIsValid(twophase_xid))
6061 info = XLOG_XACT_ABORT;
6062 else
6064
6065
6066 /* First figure out and collect all the information needed */
6067
6068 xlrec.xact_time = abort_time;
6069
6072
6073 if (nsubxacts > 0)
6074 {
6076 xl_subxacts.nsubxacts = nsubxacts;
6077 }
6078
6079 if (nrels > 0)
6080 {
6082 xl_relfilelocators.nrels = nrels;
6083 info |= XLR_SPECIAL_REL_UPDATE;
6084 }
6085
6086 if (ndroppedstats > 0)
6087 {
6090 }
6091
6092 if (TransactionIdIsValid(twophase_xid))
6093 {
6095 xl_twophase.xid = twophase_xid;
6096 Assert(twophase_gid != NULL);
6097
6100 }
6101
6102 if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6103 {
6105 xl_dbinfo.dbId = MyDatabaseId;
6107 }
6108
6109 /*
6110 * Dump transaction origin information. We need this during recovery to
6111 * update the replication origin progress.
6112 */
6114 {
6116
6119 }
6120
6121 if (xl_xinfo.xinfo != 0)
6122 info |= XLOG_XACT_HAS_INFO;
6123
6124 /* Then include all the collected data into the abort record. */
6125
6127
6129
6130 if (xl_xinfo.xinfo != 0)
6132
6133 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6135
6137 {
6140 XLogRegisterData(subxacts,
6141 nsubxacts * sizeof(TransactionId));
6142 }
6143
6145 {
6148 XLogRegisterData(rels,
6149 nrels * sizeof(RelFileLocator));
6150 }
6151
6153 {
6158 }
6159
6161 {
6163 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6164 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6165 }
6166
6167 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6169
6170 /* Include the replication origin */
6172
6173 return XLogInsert(RM_XACT_ID, info);
6174}

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 5865 of file xact.c.

5873{
5883 uint8 info;
5884
5886
5887 xl_xinfo.xinfo = 0;
5888
5889 /* decide between a plain and 2pc commit */
5890 if (!TransactionIdIsValid(twophase_xid))
5891 info = XLOG_XACT_COMMIT;
5892 else
5894
5895 /* First figure out and collect all the information needed */
5896
5897 xlrec.xact_time = commit_time;
5898
5899 if (relcacheInval)
5901 if (forceSyncCommit)
5905
5906 /*
5907 * Check if the caller would like to ask standbys for immediate feedback
5908 * once this commit is applied.
5909 */
5912
5913 /*
5914 * Relcache invalidations requires information about the current database
5915 * and so does logical decoding.
5916 */
5917 if (nmsgs > 0 || XLogLogicalInfoActive())
5918 {
5920 xl_dbinfo.dbId = MyDatabaseId;
5922 }
5923
5924 if (nsubxacts > 0)
5925 {
5927 xl_subxacts.nsubxacts = nsubxacts;
5928 }
5929
5930 if (nrels > 0)
5931 {
5933 xl_relfilelocators.nrels = nrels;
5934 info |= XLR_SPECIAL_REL_UPDATE;
5935 }
5936
5937 if (ndroppedstats > 0)
5938 {
5941 }
5942
5943 if (nmsgs > 0)
5944 {
5946 xl_invals.nmsgs = nmsgs;
5947 }
5948
5949 if (TransactionIdIsValid(twophase_xid))
5950 {
5952 xl_twophase.xid = twophase_xid;
5953 Assert(twophase_gid != NULL);
5954
5957 }
5958
5959 /* dump transaction origin information */
5961 {
5963
5966 }
5967
5968 if (xl_xinfo.xinfo != 0)
5969 info |= XLOG_XACT_HAS_INFO;
5970
5971 /* Then include all the collected data into the commit record. */
5972
5974
5976
5977 if (xl_xinfo.xinfo != 0)
5978 XLogRegisterData(&xl_xinfo.xinfo, sizeof(xl_xinfo.xinfo));
5979
5980 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5982
5984 {
5987 XLogRegisterData(subxacts,
5988 nsubxacts * sizeof(TransactionId));
5989 }
5990
5992 {
5995 XLogRegisterData(rels,
5996 nrels * sizeof(RelFileLocator));
5997 }
5998
6000 {
6005 }
6006
6007 if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
6008 {
6010 XLogRegisterData(msgs,
6011 nmsgs * sizeof(SharedInvalidationMessage));
6012 }
6013
6015 {
6017 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6018 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6019 }
6020
6021 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6023
6024 /* we allow filtering by xacts */
6026
6027 return XLogInsert(RM_XACT_ID, info);
6028}

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(), GetTopReadOnlyTransactionNestLevel(), 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