PostgreSQL Source Code  git master
xact.h File Reference
#include "access/xlogreader.h"
#include "lib/stringinfo.h"
#include "nodes/pg_list.h"
#include "storage/relfilenode.h"
#include "storage/sinval.h"
#include "utils/datetime.h"
Include dependency graph for xact.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  xl_xact_assignment
 
struct  xl_xact_xinfo
 
struct  xl_xact_dbinfo
 
struct  xl_xact_subxacts
 
struct  xl_xact_relfilenodes
 
struct  xl_xact_invals
 
struct  xl_xact_twophase
 
struct  xl_xact_origin
 
struct  xl_xact_commit
 
struct  xl_xact_abort
 
struct  xl_xact_parsed_commit
 
struct  xl_xact_parsed_abort
 

Macros

#define GIDSIZE   200
 
#define XACT_READ_UNCOMMITTED   0
 
#define XACT_READ_COMMITTED   1
 
#define XACT_REPEATABLE_READ   2
 
#define XACT_SERIALIZABLE   3
 
#define IsolationUsesXactSnapshot()   (XactIsoLevel >= XACT_REPEATABLE_READ)
 
#define IsolationIsSerializable()   (XactIsoLevel == XACT_SERIALIZABLE)
 
#define SYNCHRONOUS_COMMIT_ON   SYNCHRONOUS_COMMIT_REMOTE_FLUSH
 
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE   (1U << 0)
 
#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK   (1U << 1)
 
#define XLOG_XACT_COMMIT   0x00
 
#define XLOG_XACT_PREPARE   0x10
 
#define XLOG_XACT_ABORT   0x20
 
#define XLOG_XACT_COMMIT_PREPARED   0x30
 
#define XLOG_XACT_ABORT_PREPARED   0x40
 
#define XLOG_XACT_ASSIGNMENT   0x50
 
#define XLOG_XACT_OPMASK   0x70
 
#define XLOG_XACT_HAS_INFO   0x80
 
#define XACT_XINFO_HAS_DBINFO   (1U << 0)
 
#define XACT_XINFO_HAS_SUBXACTS   (1U << 1)
 
#define XACT_XINFO_HAS_RELFILENODES   (1U << 2)
 
#define XACT_XINFO_HAS_INVALS   (1U << 3)
 
#define XACT_XINFO_HAS_TWOPHASE   (1U << 4)
 
#define XACT_XINFO_HAS_ORIGIN   (1U << 5)
 
#define XACT_XINFO_HAS_AE_LOCKS   (1U << 6)
 
#define XACT_XINFO_HAS_GID   (1U << 7)
 
#define XACT_COMPLETION_APPLY_FEEDBACK   (1U << 29)
 
#define XACT_COMPLETION_UPDATE_RELCACHE_FILE   (1U << 30)
 
#define XACT_COMPLETION_FORCE_SYNC_COMMIT   (1U << 31)
 
#define XactCompletionApplyFeedback(xinfo)   ((xinfo & XACT_COMPLETION_APPLY_FEEDBACK) != 0)
 
#define XactCompletionRelcacheInitFileInval(xinfo)   ((xinfo & XACT_COMPLETION_UPDATE_RELCACHE_FILE) != 0)
 
#define XactCompletionForceSyncCommit(xinfo)   ((xinfo & XACT_COMPLETION_FORCE_SYNC_COMMIT) != 0)
 
#define MinSizeOfXactAssignment   offsetof(xl_xact_assignment, xsub)
 
#define MinSizeOfXactSubxacts   offsetof(xl_xact_subxacts, subxacts)
 
#define MinSizeOfXactRelfilenodes   offsetof(xl_xact_relfilenodes, xnodes)
 
#define MinSizeOfXactInvals   offsetof(xl_xact_invals, msgs)
 
#define MinSizeOfXactCommit   (offsetof(xl_xact_commit, xact_time) + sizeof(TimestampTz))
 
#define MinSizeOfXactAbort   sizeof(xl_xact_abort)
 

Typedefs

typedef void(* XactCallback) (XactEvent event, void *arg)
 
typedef void(* SubXactCallback) (SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg)
 
typedef struct xl_xact_assignment xl_xact_assignment
 
typedef struct xl_xact_xinfo xl_xact_xinfo
 
typedef struct xl_xact_dbinfo xl_xact_dbinfo
 
typedef struct xl_xact_subxacts xl_xact_subxacts
 
typedef struct xl_xact_relfilenodes xl_xact_relfilenodes
 
typedef struct xl_xact_invals xl_xact_invals
 
typedef struct xl_xact_twophase xl_xact_twophase
 
typedef struct xl_xact_origin xl_xact_origin
 
typedef struct xl_xact_commit xl_xact_commit
 
typedef struct xl_xact_abort xl_xact_abort
 
typedef struct xl_xact_parsed_commit xl_xact_parsed_commit
 
typedef xl_xact_parsed_commit xl_xact_parsed_prepare
 
typedef struct xl_xact_parsed_abort xl_xact_parsed_abort
 

Enumerations

enum  SyncCommitLevel {
  SYNCHRONOUS_COMMIT_OFF, SYNCHRONOUS_COMMIT_LOCAL_FLUSH, SYNCHRONOUS_COMMIT_REMOTE_WRITE, SYNCHRONOUS_COMMIT_REMOTE_FLUSH,
  SYNCHRONOUS_COMMIT_REMOTE_APPLY
}
 
enum  XactEvent {
  XACT_EVENT_COMMIT, XACT_EVENT_PARALLEL_COMMIT, XACT_EVENT_ABORT, XACT_EVENT_PARALLEL_ABORT,
  XACT_EVENT_PREPARE, XACT_EVENT_PRE_COMMIT, XACT_EVENT_PARALLEL_PRE_COMMIT, XACT_EVENT_PRE_PREPARE
}
 
enum  SubXactEvent { SUBXACT_EVENT_START_SUB, SUBXACT_EVENT_COMMIT_SUB, SUBXACT_EVENT_ABORT_SUB, SUBXACT_EVENT_PRE_COMMIT_SUB }
 

Functions

bool IsTransactionState (void)
 
bool IsAbortedTransactionBlockState (void)
 
TransactionId GetTopTransactionId (void)
 
TransactionId GetTopTransactionIdIfAny (void)
 
TransactionId GetCurrentTransactionId (void)
 
TransactionId GetCurrentTransactionIdIfAny (void)
 
TransactionId GetStableLatestTransactionId (void)
 
SubTransactionId GetCurrentSubTransactionId (void)
 
void MarkCurrentTransactionIdLoggedIfAny (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)
 
void CommandCounterIncrement (void)
 
void ForceSyncCommit (void)
 
void StartTransactionCommand (void)
 
void CommitTransactionCommand (void)
 
void AbortCurrentTransaction (void)
 
void BeginTransactionBlock (void)
 
bool EndTransactionBlock (void)
 
bool PrepareTransactionBlock (const char *gid)
 
void UserAbortTransactionBlock (void)
 
void BeginImplicitTransactionBlock (void)
 
void EndImplicitTransactionBlock (void)
 
void ReleaseSavepoint (const char *name)
 
void DefineSavepoint (const char *name)
 
void RollbackToSavepoint (const char *name)
 
void BeginInternalSubTransaction (const char *name)
 
void ReleaseCurrentSubTransaction (void)
 
void RollbackAndReleaseCurrentSubTransaction (void)
 
bool IsSubTransaction (void)
 
Size EstimateTransactionStateSpace (void)
 
void SerializeTransactionState (Size maxsize, char *start_address)
 
void StartParallelWorkerTransaction (char *tstatespace)
 
void EndParallelWorkerTransaction (void)
 
bool IsTransactionBlock (void)
 
bool IsTransactionOrTransactionBlock (void)
 
char TransactionBlockStatusCode (void)
 
void AbortOutOfAnyTransaction (void)
 
void PreventInTransactionBlock (bool isTopLevel, const char *stmtType)
 
void RequireTransactionBlock (bool isTopLevel, const char *stmtType)
 
void WarnNoTransactionBlock (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)
 
int xactGetCommittedChildren (TransactionId **ptr)
 
XLogRecPtr XactLogCommitRecord (TimestampTz commit_time, int nsubxacts, TransactionId *subxacts, int nrels, RelFileNode *rels, int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInval, bool forceSync, int xactflags, TransactionId twophase_xid, const char *twophase_gid)
 
XLogRecPtr XactLogAbortRecord (TimestampTz abort_time, int nsubxacts, TransactionId *subxacts, int nrels, RelFileNode *rels, int xactflags, TransactionId twophase_xid, const char *twophase_gid)
 
void xact_redo (XLogReaderState *record)
 
void xact_desc (StringInfo buf, XLogReaderState *record)
 
const char * xact_identify (uint8 info)
 
void ParseCommitRecord (uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *parsed)
 
void ParseAbortRecord (uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed)
 
void EnterParallelMode (void)
 
void ExitParallelMode (void)
 
bool IsInParallelMode (void)
 

Variables

int DefaultXactIsoLevel
 
PGDLLIMPORT int XactIsoLevel
 
bool DefaultXactReadOnly
 
bool XactReadOnly
 
bool DefaultXactDeferrable
 
bool XactDeferrable
 
int synchronous_commit
 
int MyXactFlags
 

Macro Definition Documentation

◆ GIDSIZE

#define GIDSIZE   200

Definition at line 30 of file xact.h.

Referenced by MarkAsPreparing().

◆ IsolationIsSerializable

◆ IsolationUsesXactSnapshot

◆ MinSizeOfXactAbort

#define MinSizeOfXactAbort   sizeof(xl_xact_abort)

Definition at line 289 of file xact.h.

Referenced by ParseAbortRecord(), and XactLogAbortRecord().

◆ MinSizeOfXactAssignment

#define MinSizeOfXactAssignment   offsetof(xl_xact_assignment, xsub)

Definition at line 194 of file xact.h.

Referenced by AssignTransactionId().

◆ MinSizeOfXactCommit

#define MinSizeOfXactCommit   (offsetof(xl_xact_commit, xact_time) + sizeof(TimestampTz))

Definition at line 274 of file xact.h.

Referenced by ParseCommitRecord().

◆ MinSizeOfXactInvals

#define MinSizeOfXactInvals   offsetof(xl_xact_invals, msgs)

Definition at line 248 of file xact.h.

Referenced by ParseCommitRecord(), and XactLogCommitRecord().

◆ MinSizeOfXactRelfilenodes

#define MinSizeOfXactRelfilenodes   offsetof(xl_xact_relfilenodes, xnodes)

◆ MinSizeOfXactSubxacts

#define MinSizeOfXactSubxacts   offsetof(xl_xact_subxacts, subxacts)

◆ SYNCHRONOUS_COMMIT_ON

#define SYNCHRONOUS_COMMIT_ON   SYNCHRONOUS_COMMIT_REMOTE_FLUSH

Definition at line 75 of file xact.h.

◆ XACT_COMPLETION_APPLY_FEEDBACK

#define XACT_COMPLETION_APPLY_FEEDBACK   (1U << 29)

Definition at line 175 of file xact.h.

Referenced by XactLogCommitRecord().

◆ XACT_COMPLETION_FORCE_SYNC_COMMIT

#define XACT_COMPLETION_FORCE_SYNC_COMMIT   (1U << 31)

Definition at line 177 of file xact.h.

Referenced by XactLogCommitRecord().

◆ XACT_COMPLETION_UPDATE_RELCACHE_FILE

#define XACT_COMPLETION_UPDATE_RELCACHE_FILE   (1U << 30)

Definition at line 176 of file xact.h.

Referenced by XactLogCommitRecord().

◆ XACT_FLAGS_ACCESSEDTEMPNAMESPACE

◆ XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK

#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK   (1U << 1)

◆ XACT_READ_COMMITTED

#define XACT_READ_COMMITTED   1

Definition at line 36 of file xact.h.

Referenced by InitPostgres().

◆ XACT_READ_UNCOMMITTED

#define XACT_READ_UNCOMMITTED   0

Definition at line 35 of file xact.h.

◆ XACT_REPEATABLE_READ

#define XACT_REPEATABLE_READ   2

Definition at line 37 of file xact.h.

Referenced by CreateReplicationSlot(), SnapBuildExportSnapshot(), and SnapBuildInitialSnapshot().

◆ XACT_SERIALIZABLE

#define XACT_SERIALIZABLE   3

Definition at line 38 of file xact.h.

Referenced by check_XactIsoLevel(), and ImportSnapshot().

◆ XACT_XINFO_HAS_AE_LOCKS

#define XACT_XINFO_HAS_AE_LOCKS   (1U << 6)

Definition at line 164 of file xact.h.

Referenced by xact_redo_abort(), xact_redo_commit(), XactLogAbortRecord(), and XactLogCommitRecord().

◆ XACT_XINFO_HAS_DBINFO

#define XACT_XINFO_HAS_DBINFO   (1U << 0)

◆ XACT_XINFO_HAS_GID

#define XACT_XINFO_HAS_GID   (1U << 7)

◆ XACT_XINFO_HAS_INVALS

#define XACT_XINFO_HAS_INVALS   (1U << 3)

Definition at line 161 of file xact.h.

Referenced by ParseCommitRecord(), and XactLogCommitRecord().

◆ XACT_XINFO_HAS_ORIGIN

#define XACT_XINFO_HAS_ORIGIN   (1U << 5)

◆ XACT_XINFO_HAS_RELFILENODES

#define XACT_XINFO_HAS_RELFILENODES   (1U << 2)

◆ XACT_XINFO_HAS_SUBXACTS

#define XACT_XINFO_HAS_SUBXACTS   (1U << 1)

◆ XACT_XINFO_HAS_TWOPHASE

#define XACT_XINFO_HAS_TWOPHASE   (1U << 4)

◆ XactCompletionApplyFeedback

#define XactCompletionApplyFeedback (   xinfo)    ((xinfo & XACT_COMPLETION_APPLY_FEEDBACK) != 0)

Definition at line 180 of file xact.h.

Referenced by xact_redo_commit().

◆ XactCompletionForceSyncCommit

#define XactCompletionForceSyncCommit (   xinfo)    ((xinfo & XACT_COMPLETION_FORCE_SYNC_COMMIT) != 0)

Definition at line 184 of file xact.h.

Referenced by xact_desc_commit(), and xact_redo_commit().

◆ XactCompletionRelcacheInitFileInval

#define XactCompletionRelcacheInitFileInval (   xinfo)    ((xinfo & XACT_COMPLETION_UPDATE_RELCACHE_FILE) != 0)

Definition at line 182 of file xact.h.

Referenced by xact_desc_commit(), and xact_redo_commit().

◆ XLOG_XACT_ABORT

#define XLOG_XACT_ABORT   0x20

◆ XLOG_XACT_ABORT_PREPARED

#define XLOG_XACT_ABORT_PREPARED   0x40

◆ XLOG_XACT_ASSIGNMENT

#define XLOG_XACT_ASSIGNMENT   0x50

Definition at line 144 of file xact.h.

Referenced by AssignTransactionId(), DecodeXactOp(), xact_desc(), xact_identify(), and xact_redo().

◆ XLOG_XACT_COMMIT

◆ XLOG_XACT_COMMIT_PREPARED

#define XLOG_XACT_COMMIT_PREPARED   0x30

◆ XLOG_XACT_HAS_INFO

#define XLOG_XACT_HAS_INFO   0x80

◆ XLOG_XACT_OPMASK

◆ XLOG_XACT_PREPARE

#define XLOG_XACT_PREPARE   0x10

Definition at line 140 of file xact.h.

Referenced by DecodeXactOp(), EndPrepare(), xact_identify(), xact_redo(), and XlogReadTwoPhaseData().

Typedef Documentation

◆ SubXactCallback

typedef void(* SubXactCallback) (SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg)

Definition at line 126 of file xact.h.

◆ XactCallback

typedef void(* XactCallback) (XactEvent event, void *arg)

Definition at line 116 of file xact.h.

◆ xl_xact_abort

◆ xl_xact_assignment

◆ xl_xact_commit

◆ xl_xact_dbinfo

◆ xl_xact_invals

◆ xl_xact_origin

◆ xl_xact_parsed_abort

◆ xl_xact_parsed_commit

◆ xl_xact_parsed_prepare

◆ xl_xact_relfilenodes

◆ xl_xact_subxacts

◆ xl_xact_twophase

◆ xl_xact_xinfo

Enumeration Type Documentation

◆ SubXactEvent

Enumerator
SUBXACT_EVENT_START_SUB 
SUBXACT_EVENT_COMMIT_SUB 
SUBXACT_EVENT_ABORT_SUB 
SUBXACT_EVENT_PRE_COMMIT_SUB 

Definition at line 118 of file xact.h.

◆ SyncCommitLevel

Enumerator
SYNCHRONOUS_COMMIT_OFF 
SYNCHRONOUS_COMMIT_LOCAL_FLUSH 
SYNCHRONOUS_COMMIT_REMOTE_WRITE 
SYNCHRONOUS_COMMIT_REMOTE_FLUSH 
SYNCHRONOUS_COMMIT_REMOTE_APPLY 

Definition at line 64 of file xact.h.

65 {
66  SYNCHRONOUS_COMMIT_OFF, /* asynchronous commit */
67  SYNCHRONOUS_COMMIT_LOCAL_FLUSH, /* wait for local flush only */
68  SYNCHRONOUS_COMMIT_REMOTE_WRITE, /* wait for local flush and remote
69  * write */
70  SYNCHRONOUS_COMMIT_REMOTE_FLUSH, /* wait for local and remote flush */
71  SYNCHRONOUS_COMMIT_REMOTE_APPLY /* wait for local flush and remote apply */
SyncCommitLevel
Definition: xact.h:64

◆ XactEvent

enum XactEvent
Enumerator
XACT_EVENT_COMMIT 
XACT_EVENT_PARALLEL_COMMIT 
XACT_EVENT_ABORT 
XACT_EVENT_PARALLEL_ABORT 
XACT_EVENT_PREPARE 
XACT_EVENT_PRE_COMMIT 
XACT_EVENT_PARALLEL_PRE_COMMIT 
XACT_EVENT_PRE_PREPARE 

Definition at line 104 of file xact.h.

Function Documentation

◆ AbortCurrentTransaction()

void AbortCurrentTransaction ( void  )

Definition at line 3019 of file xact.c.

References AbortCurrentTransaction(), 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(), AutoVacLauncherMain(), PostgresMain(), ReorderBufferCommit(), ReorderBufferImmediateInvalidation(), SnapBuildClearExportedSnapshot(), and SPI_rollback().

3020 {
3022 
3023  switch (s->blockState)
3024  {
3025  case TBLOCK_DEFAULT:
3026  if (s->state == TRANS_DEFAULT)
3027  {
3028  /* we are idle, so nothing to do */
3029  }
3030  else
3031  {
3032  /*
3033  * We can get here after an error during transaction start
3034  * (state will be TRANS_START). Need to clean up the
3035  * incompletely started transaction. First, adjust the
3036  * low-level state to suppress warning message from
3037  * AbortTransaction.
3038  */
3039  if (s->state == TRANS_START)
3040  s->state = TRANS_INPROGRESS;
3041  AbortTransaction();
3043  }
3044  break;
3045 
3046  /*
3047  * If we aren't in a transaction block, we just do the basic abort
3048  * & cleanup transaction. For this purpose, we treat an implicit
3049  * transaction block as if it were a simple statement.
3050  */
3051  case TBLOCK_STARTED:
3053  AbortTransaction();
3056  break;
3057 
3058  /*
3059  * If we are in TBLOCK_BEGIN it means something screwed up right
3060  * after reading "BEGIN TRANSACTION". We assume that the user
3061  * will interpret the error as meaning the BEGIN failed to get him
3062  * into a transaction block, so we should abort and return to idle
3063  * state.
3064  */
3065  case TBLOCK_BEGIN:
3066  AbortTransaction();
3069  break;
3070 
3071  /*
3072  * We are somewhere in a transaction block and we've gotten a
3073  * failure, so we abort the transaction and set up the persistent
3074  * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3075  */
3076  case TBLOCK_INPROGRESS:
3078  AbortTransaction();
3079  s->blockState = TBLOCK_ABORT;
3080  /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3081  break;
3082 
3083  /*
3084  * Here, we failed while trying to COMMIT. Clean up the
3085  * transaction and return to idle state (we do not want to stay in
3086  * the transaction).
3087  */
3088  case TBLOCK_END:
3089  AbortTransaction();
3092  break;
3093 
3094  /*
3095  * Here, we are already in an aborted transaction state and are
3096  * waiting for a ROLLBACK, but for some reason we failed again! So
3097  * we just remain in the abort state.
3098  */
3099  case TBLOCK_ABORT:
3100  case TBLOCK_SUBABORT:
3101  break;
3102 
3103  /*
3104  * We are in a failed transaction and we got the ROLLBACK command.
3105  * We have already aborted, we just need to cleanup and go to idle
3106  * state.
3107  */
3108  case TBLOCK_ABORT_END:
3111  break;
3112 
3113  /*
3114  * We are in a live transaction and we got a ROLLBACK command.
3115  * Abort, cleanup, go to idle state.
3116  */
3117  case TBLOCK_ABORT_PENDING:
3118  AbortTransaction();
3121  break;
3122 
3123  /*
3124  * Here, we failed while trying to PREPARE. Clean up the
3125  * transaction and return to idle state (we do not want to stay in
3126  * the transaction).
3127  */
3128  case TBLOCK_PREPARE:
3129  AbortTransaction();
3132  break;
3133 
3134  /*
3135  * We got an error inside a subtransaction. Abort just the
3136  * subtransaction, and go to the persistent SUBABORT state until
3137  * we get ROLLBACK.
3138  */
3139  case TBLOCK_SUBINPROGRESS:
3142  break;
3143 
3144  /*
3145  * If we failed while trying to create a subtransaction, clean up
3146  * the broken subtransaction and abort the parent. The same
3147  * applies if we get a failure while ending a subtransaction.
3148  */
3149  case TBLOCK_SUBBEGIN:
3150  case TBLOCK_SUBRELEASE:
3151  case TBLOCK_SUBCOMMIT:
3153  case TBLOCK_SUBRESTART:
3157  break;
3158 
3159  /*
3160  * Same as above, except the Abort() was already done.
3161  */
3162  case TBLOCK_SUBABORT_END:
3166  break;
3167  }
3168 }
void AbortCurrentTransaction(void)
Definition: xact.c:3019
static TransactionState CurrentTransactionState
Definition: xact.c:215
TBlockState blockState
Definition: xact.c:179
TransState state
Definition: xact.c:178
static void CleanupTransaction(void)
Definition: xact.c:2659
static void AbortSubTransaction(void)
Definition: xact.c:4700
static void AbortTransaction(void)
Definition: xact.c:2472
static void CleanupSubTransaction(void)
Definition: xact.c:4856

◆ AbortOutOfAnyTransaction()

void AbortOutOfAnyTransaction ( void  )

Definition at line 4353 of file xact.c.

References AbortSubTransaction(), AbortTransaction(), Assert, AtAbort_Memory(), AtAbort_Portals(), AtCleanup_Memory(), AtSubAbort_Portals(), TransactionStateData::blockState, CleanupSubTransaction(), CleanupTransaction(), CurrentTransactionState, TransactionStateData::curTransactionOwner, 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, TRANS_DEFAULT, TRANS_INPROGRESS, and TRANS_START.

Referenced by do_autovacuum(), perform_work_item(), RemoveTempRelationsCallback(), and ShutdownPostgres().

4354 {
4356 
4357  /* Ensure we're not running in a doomed memory context */
4358  AtAbort_Memory();
4359 
4360  /*
4361  * Get out of any transaction or nested transaction
4362  */
4363  do
4364  {
4365  switch (s->blockState)
4366  {
4367  case TBLOCK_DEFAULT:
4368  if (s->state == TRANS_DEFAULT)
4369  {
4370  /* Not in a transaction, do nothing */
4371  }
4372  else
4373  {
4374  /*
4375  * We can get here after an error during transaction start
4376  * (state will be TRANS_START). Need to clean up the
4377  * incompletely started transaction. First, adjust the
4378  * low-level state to suppress warning message from
4379  * AbortTransaction.
4380  */
4381  if (s->state == TRANS_START)
4382  s->state = TRANS_INPROGRESS;
4383  AbortTransaction();
4385  }
4386  break;
4387  case TBLOCK_STARTED:
4388  case TBLOCK_BEGIN:
4389  case TBLOCK_INPROGRESS:
4392  case TBLOCK_END:
4393  case TBLOCK_ABORT_PENDING:
4394  case TBLOCK_PREPARE:
4395  /* In a transaction, so clean up */
4396  AbortTransaction();
4399  break;
4400  case TBLOCK_ABORT:
4401  case TBLOCK_ABORT_END:
4402 
4403  /*
4404  * AbortTransaction is already done, still need Cleanup.
4405  * However, if we failed partway through running ROLLBACK,
4406  * there will be an active portal running that command, which
4407  * we need to shut down before doing CleanupTransaction.
4408  */
4409  AtAbort_Portals();
4412  break;
4413 
4414  /*
4415  * In a subtransaction, so clean it up and abort parent too
4416  */
4417  case TBLOCK_SUBBEGIN:
4418  case TBLOCK_SUBINPROGRESS:
4419  case TBLOCK_SUBRELEASE:
4420  case TBLOCK_SUBCOMMIT:
4422  case TBLOCK_SUBRESTART:
4425  s = CurrentTransactionState; /* changed by pop */
4426  break;
4427 
4428  case TBLOCK_SUBABORT:
4429  case TBLOCK_SUBABORT_END:
4431  /* As above, but AbortSubTransaction already done */
4432  if (s->curTransactionOwner)
4433  {
4434  /* As in TBLOCK_ABORT, might have a live portal to zap */
4439  }
4441  s = CurrentTransactionState; /* changed by pop */
4442  break;
4443  }
4444  } while (s->blockState != TBLOCK_DEFAULT);
4445 
4446  /* Should be out of all subxacts now */
4447  Assert(s->parent == NULL);
4448 
4449  /* If we didn't actually have anything to do, revert to TopMemoryContext */
4450  AtCleanup_Memory();
4451 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
static void AtCleanup_Memory(void)
Definition: xact.c:1729
void AtAbort_Portals(void)
Definition: portalmem.c:772
TBlockState blockState
Definition: xact.c:179
TransState state
Definition: xact.c:178
ResourceOwner curTransactionOwner
Definition: xact.c:183
static void CleanupTransaction(void)
Definition: xact.c:2659
struct TransactionStateData * parent
Definition: xact.c:193
SubTransactionId subTransactionId
Definition: xact.c:175
static void AbortSubTransaction(void)
Definition: xact.c:4700
static void AtAbort_Memory(void)
Definition: xact.c:1639
static void AbortTransaction(void)
Definition: xact.c:2472
#define Assert(condition)
Definition: c.h:732
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition: portalmem.c:968
static void CleanupSubTransaction(void)
Definition: xact.c:4856

◆ BeginImplicitTransactionBlock()

void BeginImplicitTransactionBlock ( void  )

Definition at line 3813 of file xact.c.

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

Referenced by exec_simple_query().

3814 {
3816 
3817  /*
3818  * If we are in STARTED state (that is, no transaction block is open),
3819  * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
3820  * block.
3821  *
3822  * For caller convenience, we consider all other transaction states as
3823  * legal here; otherwise the caller would need its own state check, which
3824  * seems rather pointless.
3825  */
3826  if (s->blockState == TBLOCK_STARTED)
3828 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
TBlockState blockState
Definition: xact.c:179

◆ BeginInternalSubTransaction()

void BeginInternalSubTransaction ( const char *  name)

Definition at line 4181 of file xact.c.

References TransactionStateData::blockState, BlockStateAsString(), CommitTransactionCommand(), CurrentTransactionState, elog, ereport, errcode(), errmsg(), ERROR, FATAL, IsInParallelMode(), MemoryContextStrdup(), TransactionStateData::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(), ReorderBufferCommit(), and ReorderBufferImmediateInvalidation().

4182 {
4184 
4185  /*
4186  * Workers synchronize transaction state at the beginning of each parallel
4187  * operation, so we can't account for new subtransactions after that
4188  * point. We might be able to make an exception for the type of
4189  * subtransaction established by this function, which is typically used in
4190  * contexts where we're going to release or roll back the subtransaction
4191  * before proceeding further, so that no enduring change to the
4192  * transaction state occurs. For now, however, we prohibit this case along
4193  * with all the others.
4194  */
4195  if (IsInParallelMode())
4196  ereport(ERROR,
4197  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4198  errmsg("cannot start subtransactions during a parallel operation")));
4199 
4200  switch (s->blockState)
4201  {
4202  case TBLOCK_STARTED:
4203  case TBLOCK_INPROGRESS:
4205  case TBLOCK_END:
4206  case TBLOCK_PREPARE:
4207  case TBLOCK_SUBINPROGRESS:
4208  /* Normal subtransaction start */
4209  PushTransaction();
4210  s = CurrentTransactionState; /* changed by push */
4211 
4212  /*
4213  * Savepoint names, like the TransactionState block itself, live
4214  * in TopTransactionContext.
4215  */
4216  if (name)
4218  break;
4219 
4220  /* These cases are invalid. */
4221  case TBLOCK_DEFAULT:
4222  case TBLOCK_BEGIN:
4224  case TBLOCK_SUBBEGIN:
4225  case TBLOCK_SUBRELEASE:
4226  case TBLOCK_SUBCOMMIT:
4227  case TBLOCK_ABORT:
4228  case TBLOCK_SUBABORT:
4229  case TBLOCK_ABORT_END:
4230  case TBLOCK_SUBABORT_END:
4231  case TBLOCK_ABORT_PENDING:
4233  case TBLOCK_SUBRESTART:
4235  elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4237  break;
4238  }
4239 
4242 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
MemoryContext TopTransactionContext
Definition: mcxt.c:49
void CommitTransactionCommand(void)
Definition: xact.c:2779
int errcode(int sqlerrcode)
Definition: elog.c:570
TBlockState blockState
Definition: xact.c:179
bool IsInParallelMode(void)
Definition: xact.c:910
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5169
#define ereport(elevel, rest)
Definition: elog.h:141
static void PushTransaction(void)
Definition: xact.c:4889
void StartTransactionCommand(void)
Definition: xact.c:2708
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:784
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1148
#define elog(elevel,...)
Definition: elog.h:226

◆ BeginTransactionBlock()

void BeginTransactionBlock ( void  )

Definition at line 3447 of file xact.c.

References TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg(), 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, TBLOCK_SUBRESTART, and WARNING.

Referenced by standard_ProcessUtility().

3448 {
3450 
3451  switch (s->blockState)
3452  {
3453  /*
3454  * We are not inside a transaction block, so allow one to begin.
3455  */
3456  case TBLOCK_STARTED:
3457  s->blockState = TBLOCK_BEGIN;
3458  break;
3459 
3460  /*
3461  * BEGIN converts an implicit transaction block to a regular one.
3462  * (Note that we allow this even if we've already done some
3463  * commands, which is a bit odd but matches historical practice.)
3464  */
3466  s->blockState = TBLOCK_BEGIN;
3467  break;
3468 
3469  /*
3470  * Already a transaction block in progress.
3471  */
3472  case TBLOCK_INPROGRESS:
3474  case TBLOCK_SUBINPROGRESS:
3475  case TBLOCK_ABORT:
3476  case TBLOCK_SUBABORT:
3477  ereport(WARNING,
3478  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3479  errmsg("there is already a transaction in progress")));
3480  break;
3481 
3482  /* These cases are invalid. */
3483  case TBLOCK_DEFAULT:
3484  case TBLOCK_BEGIN:
3485  case TBLOCK_SUBBEGIN:
3486  case TBLOCK_END:
3487  case TBLOCK_SUBRELEASE:
3488  case TBLOCK_SUBCOMMIT:
3489  case TBLOCK_ABORT_END:
3490  case TBLOCK_SUBABORT_END:
3491  case TBLOCK_ABORT_PENDING:
3493  case TBLOCK_SUBRESTART:
3495  case TBLOCK_PREPARE:
3496  elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3498  break;
3499  }
3500 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
int errcode(int sqlerrcode)
Definition: elog.c:570
TBlockState blockState
Definition: xact.c:179
#define FATAL
Definition: elog.h:52
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5169
#define ereport(elevel, rest)
Definition: elog.h:141
#define WARNING
Definition: elog.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226

◆ CommandCounterIncrement()

void CommandCounterIncrement ( void  )

Definition at line 919 of file xact.c.

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

Referenced by _SPI_execute_plan(), acquire_inherited_sample_rows(), AddRoleMems(), AlterPublicationOptions(), AlterRole(), apply_handle_delete(), apply_handle_insert(), apply_handle_truncate(), apply_handle_update(), ATAddCheckConstraint(), ATExecAddColumn(), ATExecAlterColumnType(), ATExecCmd(), ATExecDropColumn(), ATExecDropConstraint(), ATExecDropIdentity(), ATExecSetTableSpace(), ATExecSetTableSpaceNoStorage(), CloneFkReferencing(), CommitSubTransaction(), CommitTransactionCommand(), copy_heap_data(), create_ctas_internal(), create_toast_table(), CreateFKCheckTrigger(), createForeignKeyActionTriggers(), createForeignKeyTriggers(), CreateForeignTable(), CreatePublication(), CreateRole(), CreateSchemaCommand(), CreateTrigger(), DefineCollation(), DefineDomain(), DefineQueryRewrite(), DefineRange(), DefineRelation(), DefineType(), DefineVirtualRelation(), deleteOneObject(), DelRoleMems(), DropRole(), EventTriggerDDLCommandEnd(), EventTriggerDDLCommandStart(), EventTriggerInvoke(), EventTriggerSQLDrop(), EventTriggerTableRewrite(), exec_eval_simple_expr(), exec_execute_message(), exec_parse_message(), exec_simple_query(), ExecGrant_Database(), ExecGrant_Fdw(), ExecGrant_ForeignServer(), ExecGrant_Function(), ExecGrant_Language(), ExecGrant_Largeobject(), ExecGrant_Namespace(), ExecGrant_Relation(), ExecGrant_Tablespace(), ExecGrant_Type(), execute_sql_string(), ExplainOnePlan(), findTypeInputFunction(), findTypeOutputFunction(), fmgr_sql(), ImportForeignSchema(), index_build(), index_create(), IndexSetParentIndex(), InitTempTableNamespace(), inv_create(), inv_drop(), inv_truncate(), inv_write(), LogicalRepSyncTableStart(), make_new_heap(), makeConfigurationDependencies(), moveArrayTypeName(), OperatorShellMake(), OperatorUpd(), pg_import_system_collations(), PortalRunMulti(), ProcedureCreate(), ProcessUtilitySlow(), recordExtensionInitPrivWorker(), reindex_relation(), RelationSetNewRelfilenode(), RenumberEnumType(), replorigin_create(), replorigin_drop(), ri_PerformCheck(), SetMatViewPopulatedState(), shdepReassignOwned(), SPI_cursor_open_internal(), StoreConstraints(), StorePartitionBound(), and validatePartitionedIndex().

920 {
921  /*
922  * If the current value of the command counter hasn't been "used" to mark
923  * tuples, we need not increment it, since there's no need to distinguish
924  * a read-only command from others. This helps postpone command counter
925  * overflow, and keeps no-op CommandCounterIncrement operations cheap.
926  */
928  {
929  /*
930  * Workers synchronize transaction state at the beginning of each
931  * parallel operation, so we can't account for new commands after that
932  * point.
933  */
935  elog(ERROR, "cannot start commands during a parallel operation");
936 
937  currentCommandId += 1;
939  {
940  currentCommandId -= 1;
941  ereport(ERROR,
942  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
943  errmsg("cannot have more than 2^32-2 commands in a transaction")));
944  }
945  currentCommandIdUsed = false;
946 
947  /* Propagate new command ID into static snapshots */
949 
950  /*
951  * Make any catalog changes done by the just-completed command visible
952  * in the local syscache. We obviously don't need to do this after a
953  * read-only command. (But see hacks in inval.c to make real sure we
954  * don't think a command that queued inval messages was read-only.)
955  */
957  }
958 }
int errcode(int sqlerrcode)
Definition: elog.c:570
bool IsInParallelMode(void)
Definition: xact.c:910
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
#define IsParallelWorker()
Definition: parallel.h:60
#define InvalidCommandId
Definition: c.h:524
static void AtCCI_LocalCache(void)
Definition: xact.c:1362
void SnapshotSetCommandId(CommandId curcid)
Definition: snapmgr.c:546
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
static CommandId currentCommandId
Definition: xact.c:222
static bool currentCommandIdUsed
Definition: xact.c:223

◆ CommitTransactionCommand()

void CommitTransactionCommand ( void  )

Definition at line 2779 of file xact.c.

References AbortSubTransaction(), AbortTransaction(), Assert, AssertState, TransactionStateData::blockState, BlockStateAsString(), CleanupSubTransaction(), CleanupTransaction(), CommandCounterIncrement(), CommitSubTransaction(), CommitTransaction(), CommitTransactionCommand(), CurrentTransactionState, DefineSavepoint(), elog, ERROR, FATAL, TransactionStateData::name, TransactionStateData::parent, PrepareTransaction(), TransactionStateData::savepointLevel, StartSubTransaction(), 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 apply_handle_commit(), ApplyWorkerMain(), autoprewarm_database_main(), BeginInternalSubTransaction(), BootstrapModeMain(), cluster(), CommitTransactionCommand(), DefineIndex(), do_autovacuum(), finish_xact_command(), get_database_list(), get_subscription_list(), IdentifySystem(), index_drop(), initialize_worker_spi(), InitPostgres(), LogicalRepSyncTableStart(), maybe_reread_subscription(), movedb(), ParallelWorkerMain(), pg_attribute_noreturn(), process_syncing_tables_for_apply(), ProcessCatchupInterrupt(), ProcessCompletedNotifies(), ProcessIncomingNotify(), ReindexMultipleTables(), RemoveTempRelationsCallback(), SPI_commit(), vacuum(), and vacuum_rel().

2780 {
2782 
2783  switch (s->blockState)
2784  {
2785  /*
2786  * These shouldn't happen. TBLOCK_DEFAULT means the previous
2787  * StartTransactionCommand didn't set the STARTED state
2788  * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
2789  * by EndParallelWorkerTransaction(), not this function.
2790  */
2791  case TBLOCK_DEFAULT:
2793  elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2795  break;
2796 
2797  /*
2798  * If we aren't in a transaction block, just do our usual
2799  * transaction commit, and return to the idle state.
2800  */
2801  case TBLOCK_STARTED:
2804  break;
2805 
2806  /*
2807  * We are completing a "BEGIN TRANSACTION" command, so we change
2808  * to the "transaction block in progress" state and return. (We
2809  * assume the BEGIN did nothing to the database, so we need no
2810  * CommandCounterIncrement.)
2811  */
2812  case TBLOCK_BEGIN:
2814  break;
2815 
2816  /*
2817  * This is the case when we have finished executing a command
2818  * someplace within a transaction block. We increment the command
2819  * counter and return.
2820  */
2821  case TBLOCK_INPROGRESS:
2823  case TBLOCK_SUBINPROGRESS:
2825  break;
2826 
2827  /*
2828  * We are completing a "COMMIT" command. Do it and return to the
2829  * idle state.
2830  */
2831  case TBLOCK_END:
2834  break;
2835 
2836  /*
2837  * Here we are in the middle of a transaction block but one of the
2838  * commands caused an abort so we do nothing but remain in the
2839  * abort state. Eventually we will get a ROLLBACK command.
2840  */
2841  case TBLOCK_ABORT:
2842  case TBLOCK_SUBABORT:
2843  break;
2844 
2845  /*
2846  * Here we were in an aborted transaction block and we just got
2847  * the ROLLBACK command from the user, so clean up the
2848  * already-aborted transaction and return to the idle state.
2849  */
2850  case TBLOCK_ABORT_END:
2853  break;
2854 
2855  /*
2856  * Here we were in a perfectly good transaction block but the user
2857  * told us to ROLLBACK anyway. We have to abort the transaction
2858  * and then clean up.
2859  */
2860  case TBLOCK_ABORT_PENDING:
2861  AbortTransaction();
2864  break;
2865 
2866  /*
2867  * We are completing a "PREPARE TRANSACTION" command. Do it and
2868  * return to the idle state.
2869  */
2870  case TBLOCK_PREPARE:
2873  break;
2874 
2875  /*
2876  * We were just issued a SAVEPOINT inside a transaction block.
2877  * Start a subtransaction. (DefineSavepoint already did
2878  * PushTransaction, so as to have someplace to put the SUBBEGIN
2879  * state.)
2880  */
2881  case TBLOCK_SUBBEGIN:
2884  break;
2885 
2886  /*
2887  * We were issued a RELEASE command, so we end the current
2888  * subtransaction and return to the parent transaction. The parent
2889  * might be ended too, so repeat till we find an INPROGRESS
2890  * transaction or subtransaction.
2891  */
2892  case TBLOCK_SUBRELEASE:
2893  do
2894  {
2896  s = CurrentTransactionState; /* changed by pop */
2897  } while (s->blockState == TBLOCK_SUBRELEASE);
2898 
2901  break;
2902 
2903  /*
2904  * We were issued a COMMIT, so we end the current subtransaction
2905  * hierarchy and perform final commit. We do this by rolling up
2906  * any subtransactions into their parent, which leads to O(N^2)
2907  * operations with respect to resource owners - this isn't that
2908  * bad until we approach a thousands of savepoints but is
2909  * necessary for correctness should after triggers create new
2910  * resource owners.
2911  */
2912  case TBLOCK_SUBCOMMIT:
2913  do
2914  {
2916  s = CurrentTransactionState; /* changed by pop */
2917  } while (s->blockState == TBLOCK_SUBCOMMIT);
2918  /* If we had a COMMIT command, finish off the main xact too */
2919  if (s->blockState == TBLOCK_END)
2920  {
2921  Assert(s->parent == NULL);
2924  }
2925  else if (s->blockState == TBLOCK_PREPARE)
2926  {
2927  Assert(s->parent == NULL);
2930  }
2931  else
2932  elog(ERROR, "CommitTransactionCommand: unexpected state %s",
2934  break;
2935 
2936  /*
2937  * The current already-failed subtransaction is ending due to a
2938  * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2939  * examine the parent (which could be in any of several states).
2940  */
2941  case TBLOCK_SUBABORT_END:
2944  break;
2945 
2946  /*
2947  * As above, but it's not dead yet, so abort first.
2948  */
2953  break;
2954 
2955  /*
2956  * The current subtransaction is the target of a ROLLBACK TO
2957  * command. Abort and pop it, then start a new subtransaction
2958  * with the same name.
2959  */
2960  case TBLOCK_SUBRESTART:
2961  {
2962  char *name;
2963  int savepointLevel;
2964 
2965  /* save name and keep Cleanup from freeing it */
2966  name = s->name;
2967  s->name = NULL;
2968  savepointLevel = s->savepointLevel;
2969 
2972 
2973  DefineSavepoint(NULL);
2974  s = CurrentTransactionState; /* changed by push */
2975  s->name = name;
2976  s->savepointLevel = savepointLevel;
2977 
2978  /* This is the same as TBLOCK_SUBBEGIN case */
2982  }
2983  break;
2984 
2985  /*
2986  * Same as above, but the subtransaction had already failed, so we
2987  * don't need AbortSubTransaction.
2988  */
2990  {
2991  char *name;
2992  int savepointLevel;
2993 
2994  /* save name and keep Cleanup from freeing it */
2995  name = s->name;
2996  s->name = NULL;
2997  savepointLevel = s->savepointLevel;
2998 
3000 
3001  DefineSavepoint(NULL);
3002  s = CurrentTransactionState; /* changed by push */
3003  s->name = name;
3004  s->savepointLevel = savepointLevel;
3005 
3006  /* This is the same as TBLOCK_SUBBEGIN case */
3010  }
3011  break;
3012  }
3013 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
#define AssertState(condition)
Definition: c.h:735
void CommitTransactionCommand(void)
Definition: xact.c:2779
void DefineSavepoint(const char *name)
Definition: xact.c:3860
TBlockState blockState
Definition: xact.c:179
static void PrepareTransaction(void)
Definition: xact.c:2191
#define ERROR
Definition: elog.h:43
static void CommitSubTransaction(void)
Definition: xact.c:4591
#define FATAL
Definition: elog.h:52
static void CleanupTransaction(void)
Definition: xact.c:2659
struct TransactionStateData * parent
Definition: xact.c:193
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5169
static void AbortSubTransaction(void)
Definition: xact.c:4700
void CommandCounterIncrement(void)
Definition: xact.c:919
static void AbortTransaction(void)
Definition: xact.c:2472
#define Assert(condition)
Definition: c.h:732
static void CleanupSubTransaction(void)
Definition: xact.c:4856
const char * name
Definition: encode.c:521
#define elog(elevel,...)
Definition: elog.h:226
static void CommitTransaction(void)
Definition: xact.c:1954
static void StartSubTransaction(void)
Definition: xact.c:4553

◆ DefineSavepoint()

void DefineSavepoint ( const char *  name)

Definition at line 3860 of file xact.c.

References TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg(), ERROR, FATAL, IsInParallelMode(), MemoryContextStrdup(), TransactionStateData::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 CommitTransactionCommand(), and standard_ProcessUtility().

3861 {
3863 
3864  /*
3865  * Workers synchronize transaction state at the beginning of each parallel
3866  * operation, so we can't account for new subtransactions after that
3867  * point. (Note that this check will certainly error out if s->blockState
3868  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
3869  * below.)
3870  */
3871  if (IsInParallelMode())
3872  ereport(ERROR,
3873  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3874  errmsg("cannot define savepoints during a parallel operation")));
3875 
3876  switch (s->blockState)
3877  {
3878  case TBLOCK_INPROGRESS:
3879  case TBLOCK_SUBINPROGRESS:
3880  /* Normal subtransaction start */
3881  PushTransaction();
3882  s = CurrentTransactionState; /* changed by push */
3883 
3884  /*
3885  * Savepoint names, like the TransactionState block itself, live
3886  * in TopTransactionContext.
3887  */
3888  if (name)
3890  break;
3891 
3892  /*
3893  * We disallow savepoint commands in implicit transaction blocks.
3894  * There would be no great difficulty in allowing them so far as
3895  * this module is concerned, but a savepoint seems inconsistent
3896  * with exec_simple_query's behavior of abandoning the whole query
3897  * string upon error. Also, the point of an implicit transaction
3898  * block (as opposed to a regular one) is to automatically close
3899  * after an error, so it's hard to see how a savepoint would fit
3900  * into that.
3901  *
3902  * The error messages for this are phrased as if there were no
3903  * active transaction block at all, which is historical but
3904  * perhaps could be improved.
3905  */
3907  ereport(ERROR,
3908  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3909  /* translator: %s represents an SQL statement name */
3910  errmsg("%s can only be used in transaction blocks",
3911  "SAVEPOINT")));
3912  break;
3913 
3914  /* These cases are invalid. */
3915  case TBLOCK_DEFAULT:
3916  case TBLOCK_STARTED:
3917  case TBLOCK_BEGIN:
3919  case TBLOCK_SUBBEGIN:
3920  case TBLOCK_END:
3921  case TBLOCK_SUBRELEASE:
3922  case TBLOCK_SUBCOMMIT:
3923  case TBLOCK_ABORT:
3924  case TBLOCK_SUBABORT:
3925  case TBLOCK_ABORT_END:
3926  case TBLOCK_SUBABORT_END:
3927  case TBLOCK_ABORT_PENDING:
3929  case TBLOCK_SUBRESTART:
3931  case TBLOCK_PREPARE:
3932  elog(FATAL, "DefineSavepoint: unexpected state %s",
3934  break;
3935  }
3936 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
MemoryContext TopTransactionContext
Definition: mcxt.c:49
int errcode(int sqlerrcode)
Definition: elog.c:570
TBlockState blockState
Definition: xact.c:179
bool IsInParallelMode(void)
Definition: xact.c:910
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5169
#define ereport(elevel, rest)
Definition: elog.h:141
static void PushTransaction(void)
Definition: xact.c:4889
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:784
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1148
#define elog(elevel,...)
Definition: elog.h:226

◆ EndImplicitTransactionBlock()

void EndImplicitTransactionBlock ( void  )

Definition at line 3838 of file xact.c.

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

Referenced by exec_simple_query().

3839 {
3841 
3842  /*
3843  * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
3844  * allowing CommitTransactionCommand to commit whatever happened during
3845  * the implicit transaction block as though it were a single statement.
3846  *
3847  * For caller convenience, we consider all other transaction states as
3848  * legal here; otherwise the caller would need its own state check, which
3849  * seems rather pointless.
3850  */
3853 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
TBlockState blockState
Definition: xact.c:179

◆ EndParallelWorkerTransaction()

void EndParallelWorkerTransaction ( void  )

Definition at line 5106 of file xact.c.

References Assert, TransactionStateData::blockState, CommitTransaction(), TBLOCK_DEFAULT, and TBLOCK_PARALLEL_INPROGRESS.

Referenced by ParallelWorkerMain().

5107 {
5111 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
TBlockState blockState
Definition: xact.c:179
#define Assert(condition)
Definition: c.h:732
static void CommitTransaction(void)
Definition: xact.c:1954

◆ EndTransactionBlock()

bool EndTransactionBlock ( void  )

Definition at line 3567 of file xact.c.

References TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg(), FATAL, 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 PrepareTransactionBlock(), and standard_ProcessUtility().

3568 {
3570  bool result = false;
3571 
3572  switch (s->blockState)
3573  {
3574  /*
3575  * We are in a transaction block, so tell CommitTransactionCommand
3576  * to COMMIT.
3577  */
3578  case TBLOCK_INPROGRESS:
3579  s->blockState = TBLOCK_END;
3580  result = true;
3581  break;
3582 
3583  /*
3584  * In an implicit transaction block, commit, but issue a warning
3585  * because there was no explicit BEGIN before this.
3586  */
3588  ereport(WARNING,
3589  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3590  errmsg("there is no transaction in progress")));
3591  s->blockState = TBLOCK_END;
3592  result = true;
3593  break;
3594 
3595  /*
3596  * We are in a failed transaction block. Tell
3597  * CommitTransactionCommand it's time to exit the block.
3598  */
3599  case TBLOCK_ABORT:
3601  break;
3602 
3603  /*
3604  * We are in a live subtransaction block. Set up to subcommit all
3605  * open subtransactions and then commit the main transaction.
3606  */
3607  case TBLOCK_SUBINPROGRESS:
3608  while (s->parent != NULL)
3609  {
3610  if (s->blockState == TBLOCK_SUBINPROGRESS)
3612  else
3613  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3615  s = s->parent;
3616  }
3617  if (s->blockState == TBLOCK_INPROGRESS)
3618  s->blockState = TBLOCK_END;
3619  else
3620  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3622  result = true;
3623  break;
3624 
3625  /*
3626  * Here we are inside an aborted subtransaction. Treat the COMMIT
3627  * as ROLLBACK: set up to abort everything and exit the main
3628  * transaction.
3629  */
3630  case TBLOCK_SUBABORT:
3631  while (s->parent != NULL)
3632  {
3633  if (s->blockState == TBLOCK_SUBINPROGRESS)
3635  else if (s->blockState == TBLOCK_SUBABORT)
3637  else
3638  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3640  s = s->parent;
3641  }
3642  if (s->blockState == TBLOCK_INPROGRESS)
3644  else if (s->blockState == TBLOCK_ABORT)
3646  else
3647  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3649  break;
3650 
3651  /*
3652  * The user issued COMMIT when not inside a transaction. Issue a
3653  * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
3654  * CommitTransactionCommand() will then close the transaction and
3655  * put us back into the default state.
3656  */
3657  case TBLOCK_STARTED:
3658  ereport(WARNING,
3659  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3660  errmsg("there is no transaction in progress")));
3661  result = true;
3662  break;
3663 
3664  /*
3665  * The user issued a COMMIT that somehow ran inside a parallel
3666  * worker. We can't cope with that.
3667  */
3669  ereport(FATAL,
3670  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3671  errmsg("cannot commit during a parallel operation")));
3672  break;
3673 
3674  /* These cases are invalid. */
3675  case TBLOCK_DEFAULT:
3676  case TBLOCK_BEGIN:
3677  case TBLOCK_SUBBEGIN:
3678  case TBLOCK_END:
3679  case TBLOCK_SUBRELEASE:
3680  case TBLOCK_SUBCOMMIT:
3681  case TBLOCK_ABORT_END:
3682  case TBLOCK_SUBABORT_END:
3683  case TBLOCK_ABORT_PENDING:
3685  case TBLOCK_SUBRESTART:
3687  case TBLOCK_PREPARE:
3688  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3690  break;
3691  }
3692 
3693  return result;
3694 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
int errcode(int sqlerrcode)
Definition: elog.c:570
TBlockState blockState
Definition: xact.c:179
#define FATAL
Definition: elog.h:52
struct TransactionStateData * parent
Definition: xact.c:193
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5169
#define ereport(elevel, rest)
Definition: elog.h:141
#define WARNING
Definition: elog.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226

◆ EnterParallelMode()

void EnterParallelMode ( void  )

Definition at line 877 of file xact.c.

References Assert, CurrentTransactionState, and TransactionStateData::parallelModeLevel.

Referenced by _bt_begin_parallel(), CommitTransaction(), ExecutePlan(), and ParallelWorkerMain().

878 {
880 
881  Assert(s->parallelModeLevel >= 0);
882 
883  ++s->parallelModeLevel;
884 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
int parallelModeLevel
Definition: xact.c:192
#define Assert(condition)
Definition: c.h:732

◆ EstimateTransactionStateSpace()

Size EstimateTransactionStateSpace ( void  )

Definition at line 4982 of file xact.c.

References add_size(), mul_size(), TransactionStateData::nChildXids, nParallelCurrentXids, TransactionStateData::parent, TransactionStateData::transactionId, and TransactionIdIsValid.

Referenced by InitializeParallelDSM().

4983 {
4984  TransactionState s;
4985  Size nxids = 6; /* iso level, deferrable, top & current XID,
4986  * command counter, XID count */
4987 
4988  for (s = CurrentTransactionState; s != NULL; s = s->parent)
4989  {
4991  nxids = add_size(nxids, 1);
4992  nxids = add_size(nxids, s->nChildXids);
4993  }
4994 
4995  nxids = add_size(nxids, nParallelCurrentXids);
4996  return mul_size(nxids, sizeof(TransactionId));
4997 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
uint32 TransactionId
Definition: c.h:507
int nParallelCurrentXids
Definition: xact.c:109
struct TransactionStateData * parent
Definition: xact.c:193
Size mul_size(Size s1, Size s2)
Definition: shmem.c:492
Size add_size(Size s1, Size s2)
Definition: shmem.c:475
TransactionId transactionId
Definition: xact.c:174
size_t Size
Definition: c.h:466
#define TransactionIdIsValid(xid)
Definition: transam.h:41

◆ ExitParallelMode()

void ExitParallelMode ( void  )

Definition at line 890 of file xact.c.

References Assert, CurrentTransactionState, ParallelContextActive(), and TransactionStateData::parallelModeLevel.

Referenced by _bt_end_parallel(), ExecutePlan(), and ParallelWorkerMain().

891 {
893 
894  Assert(s->parallelModeLevel > 0);
896 
897  --s->parallelModeLevel;
898 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
bool ParallelContextActive(void)
Definition: parallel.c:952
int parallelModeLevel
Definition: xact.c:192
#define Assert(condition)
Definition: c.h:732

◆ ForceSyncCommit()

void ForceSyncCommit ( void  )

Definition at line 967 of file xact.c.

References forceSyncCommit.

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

968 {
969  forceSyncCommit = true;
970 }
static bool forceSyncCommit
Definition: xact.c:245

◆ GetCurrentCommandId()

CommandId GetCurrentCommandId ( bool  used)

Definition at line 662 of file xact.c.

References Assert, currentCommandId, currentCommandIdUsed, and IsParallelWorker.

Referenced by ATRewriteTable(), CopyFrom(), create_estate_for_relation(), GetSnapshotData(), intorel_startup(), pgrowlocks(), RegisterRelcacheInvalidation(), RelationFindReplTupleByIndex(), RelationFindReplTupleSeq(), simple_heap_delete(), simple_heap_insert(), simple_heap_update(), standard_ExecutorStart(), toast_save_datum(), transientrel_startup(), and UpdateActiveSnapshotCommandId().

663 {
664  /* this is global to a transaction, not subtransaction-local */
665  if (used)
666  {
667  /*
668  * Forbid setting currentCommandIdUsed in a parallel worker, because
669  * we have no provision for communicating this back to the master. We
670  * could relax this restriction when currentCommandIdUsed was already
671  * true at the start of the parallel operation.
672  */
674  currentCommandIdUsed = true;
675  }
676  return currentCommandId;
677 }
#define IsParallelWorker()
Definition: parallel.h:60
#define Assert(condition)
Definition: c.h:732
static CommandId currentCommandId
Definition: xact.c:222
static bool currentCommandIdUsed
Definition: xact.c:223

◆ GetCurrentStatementStartTimestamp()

TimestampTz GetCurrentStatementStartTimestamp ( void  )

Definition at line 708 of file xact.c.

References stmtStartTimestamp.

Referenced by check_log_duration(), CreatePortal(), InitializeParallelDSM(), pgstat_report_activity(), statement_timestamp(), and StorePreparedStatement().

709 {
710  return stmtStartTimestamp;
711 }
static TimestampTz stmtStartTimestamp
Definition: xact.c:233

◆ GetCurrentSubTransactionId()

◆ GetCurrentTransactionId()

◆ GetCurrentTransactionIdIfAny()

TransactionId GetCurrentTransactionIdIfAny ( void  )

Definition at line 417 of file xact.c.

References TransactionStateData::transactionId.

Referenced by RecordTransactionAbort(), ReorderBufferCommit(), and XLogRecordAssemble().

418 {
420 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
TransactionId transactionId
Definition: xact.c:174

◆ GetCurrentTransactionNestLevel()

◆ GetCurrentTransactionStartTimestamp()

TimestampTz GetCurrentTransactionStartTimestamp ( void  )

◆ GetCurrentTransactionStopTimestamp()

TimestampTz GetCurrentTransactionStopTimestamp ( void  )

Definition at line 720 of file xact.c.

References GetCurrentTimestamp(), and xactStopTimestamp.

Referenced by pgstat_report_stat().

721 {
722  if (xactStopTimestamp != 0)
723  return xactStopTimestamp;
724  return GetCurrentTimestamp();
725 }
static TimestampTz xactStopTimestamp
Definition: xact.c:234
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1592

◆ GetStableLatestTransactionId()

TransactionId GetStableLatestTransactionId ( void  )

Definition at line 444 of file xact.c.

References Assert, GetTopTransactionIdIfAny(), InvalidLocalTransactionId, InvalidTransactionId, PGPROC::lxid, MyProc, ReadNewTransactionId(), and TransactionIdIsValid.

Referenced by xid_age().

445 {
447  static TransactionId stablexid = InvalidTransactionId;
448 
449  if (lxid != MyProc->lxid)
450  {
451  lxid = MyProc->lxid;
452  stablexid = GetTopTransactionIdIfAny();
453  if (!TransactionIdIsValid(stablexid))
454  stablexid = ReadNewTransactionId();
455  }
456 
457  Assert(TransactionIdIsValid(stablexid));
458 
459  return stablexid;
460 }
uint32 TransactionId
Definition: c.h:507
PGPROC * MyProc
Definition: proc.c:68
#define InvalidTransactionId
Definition: transam.h:31
TransactionId ReadNewTransactionId(void)
Definition: varsup.c:242
uint32 LocalTransactionId
Definition: c.h:509
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:387
#define Assert(condition)
Definition: c.h:732
#define InvalidLocalTransactionId
Definition: lock.h:69
#define TransactionIdIsValid(xid)
Definition: transam.h:41
LocalTransactionId lxid
Definition: proc.h:106

◆ GetTopTransactionId()

TransactionId GetTopTransactionId ( void  )

Definition at line 372 of file xact.c.

References AssignTransactionId(), TransactionIdIsValid, and XactTopTransactionId.

Referenced by AlterSequence(), AssignTransactionId(), do_setval(), fill_seq_with_data(), log_heap_new_cid(), nextval_internal(), and txid_current().

373 {
376  return XactTopTransactionId;
377 }
TransactionId XactTopTransactionId
Definition: xact.c:108
static TransactionStateData TopTransactionStateData
Definition: xact.c:203
#define TransactionIdIsValid(xid)
Definition: transam.h:41
static void AssignTransactionId(TransactionState s)
Definition: xact.c:472

◆ GetTopTransactionIdIfAny()

◆ IsAbortedTransactionBlockState()

◆ IsInParallelMode()

◆ IsInTransactionBlock()

bool IsInTransactionBlock ( bool  isTopLevel)

Definition at line 3302 of file xact.c.

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

Referenced by vacuum().

3303 {
3304  /*
3305  * Return true on same conditions that would make
3306  * PreventInTransactionBlock error out
3307  */
3308  if (IsTransactionBlock())
3309  return true;
3310 
3311  if (IsSubTransaction())
3312  return true;
3313 
3314  if (!isTopLevel)
3315  return true;
3316 
3319  return true;
3320 
3321  return false;
3322 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
TBlockState blockState
Definition: xact.c:179
bool IsTransactionBlock(void)
Definition: xact.c:4457
bool IsSubTransaction(void)
Definition: xact.c:4530

◆ IsSubTransaction()

◆ IsTransactionBlock()

bool IsTransactionBlock ( void  )

Definition at line 4457 of file xact.c.

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

Referenced by CheckTransactionBlock(), CreateReplicationSlot(), exec_replication_command(), IsInTransactionBlock(), PreventInTransactionBlock(), and standard_ProcessUtility().

4458 {
4460 
4462  return false;
4463 
4464  return true;
4465 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
TBlockState blockState
Definition: xact.c:179

◆ IsTransactionOrTransactionBlock()

bool IsTransactionOrTransactionBlock ( void  )

◆ IsTransactionState()

bool IsTransactionState ( void  )

Definition at line 333 of file xact.c.

References CurrentTransactionState, TransactionStateData::state, and TRANS_INPROGRESS.

Referenced by apply_handle_commit(), apply_handle_origin(), check_client_encoding(), check_default_tablespace(), check_role(), check_session_authorization(), check_temp_tablespaces(), check_transaction_read_only(), check_TSCurrentConfig(), check_XactIsoLevel(), CreateInitDecodingContext(), ensure_transaction(), GetMessageEncoding(), LogLogicalMessage(), maybe_reread_subscription(), pg_attribute_noreturn(), pg_do_encoding_conversion(), PrepareClientEncoding(), PrepareTempTablespaces(), process_syncing_tables_for_apply(), process_syncing_tables_for_sync(), RelationClearRelation(), RelationIdGetRelation(), RelationInitPhysicalAddr(), RelationReloadNailed(), replorigin_create(), replorigin_drop(), SearchCatCacheInternal(), SetMultiXactIdLimit(), SetTransactionIdLimit(), SnapBuildClearExportedSnapshot(), and SocketBackend().

334 {
336 
337  /*
338  * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
339  * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
340  * TRANS_PREPARE since it might be too soon or too late within those
341  * transition states to do anything interesting. Hence, the only "valid"
342  * state is TRANS_INPROGRESS.
343  */
344  return (s->state == TRANS_INPROGRESS);
345 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
TransState state
Definition: xact.c:178

◆ MarkCurrentTransactionIdLoggedIfAny()

void MarkCurrentTransactionIdLoggedIfAny ( void  )

Definition at line 428 of file xact.c.

References TransactionStateData::didLogXid, TransactionStateData::transactionId, and TransactionIdIsValid.

Referenced by XLogInsertRecord().

429 {
432 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
TransactionId transactionId
Definition: xact.c:174
#define TransactionIdIsValid(xid)
Definition: transam.h:41

◆ ParseAbortRecord()

void ParseAbortRecord ( uint8  info,
xl_xact_abort xlrec,
xl_xact_parsed_abort parsed 
)

Definition at line 129 of file xactdesc.c.

References xl_xact_dbinfo::dbId, xl_xact_parsed_abort::dbId, MinSizeOfXactAbort, MinSizeOfXactRelfilenodes, MinSizeOfXactSubxacts, xl_xact_relfilenodes::nrels, xl_xact_parsed_abort::nrels, xl_xact_subxacts::nsubxacts, xl_xact_parsed_abort::nsubxacts, xl_xact_origin::origin_lsn, xl_xact_parsed_abort::origin_lsn, xl_xact_origin::origin_timestamp, xl_xact_parsed_abort::origin_timestamp, strlcpy(), xl_xact_subxacts::subxacts, xl_xact_parsed_abort::subxacts, xl_xact_dbinfo::tsId, xl_xact_parsed_abort::tsId, xl_xact_parsed_abort::twophase_gid, xl_xact_parsed_abort::twophase_xid, xl_xact_abort::xact_time, xl_xact_parsed_abort::xact_time, XACT_XINFO_HAS_DBINFO, XACT_XINFO_HAS_GID, XACT_XINFO_HAS_ORIGIN, XACT_XINFO_HAS_RELFILENODES, XACT_XINFO_HAS_SUBXACTS, XACT_XINFO_HAS_TWOPHASE, xl_xact_twophase::xid, xl_xact_xinfo::xinfo, xl_xact_parsed_abort::xinfo, XLOG_XACT_HAS_INFO, xl_xact_relfilenodes::xnodes, and xl_xact_parsed_abort::xnodes.

Referenced by DecodeXactOp(), recoveryStopsAfter(), recoveryStopsBefore(), xact_desc_abort(), and xact_redo().

130 {
131  char *data = ((char *) xlrec) + MinSizeOfXactAbort;
132 
133  memset(parsed, 0, sizeof(*parsed));
134 
135  parsed->xinfo = 0; /* default, if no XLOG_XACT_HAS_INFO is
136  * present */
137 
138  parsed->xact_time = xlrec->xact_time;
139 
140  if (info & XLOG_XACT_HAS_INFO)
141  {
142  xl_xact_xinfo *xl_xinfo = (xl_xact_xinfo *) data;
143 
144  parsed->xinfo = xl_xinfo->xinfo;
145 
146  data += sizeof(xl_xact_xinfo);
147  }
148 
149  if (parsed->xinfo & XACT_XINFO_HAS_DBINFO)
150  {
151  xl_xact_dbinfo *xl_dbinfo = (xl_xact_dbinfo *) data;
152 
153  parsed->dbId = xl_dbinfo->dbId;
154  parsed->tsId = xl_dbinfo->tsId;
155 
156  data += sizeof(xl_xact_dbinfo);
157  }
158 
159  if (parsed->xinfo & XACT_XINFO_HAS_SUBXACTS)
160  {
161  xl_xact_subxacts *xl_subxacts = (xl_xact_subxacts *) data;
162 
163  parsed->nsubxacts = xl_subxacts->nsubxacts;
164  parsed->subxacts = xl_subxacts->subxacts;
165 
166  data += MinSizeOfXactSubxacts;
167  data += parsed->nsubxacts * sizeof(TransactionId);
168  }
169 
170  if (parsed->xinfo & XACT_XINFO_HAS_RELFILENODES)
171  {
172  xl_xact_relfilenodes *xl_relfilenodes = (xl_xact_relfilenodes *) data;
173 
174  parsed->nrels = xl_relfilenodes->nrels;
175  parsed->xnodes = xl_relfilenodes->xnodes;
176 
178  data += xl_relfilenodes->nrels * sizeof(RelFileNode);
179  }
180 
181  if (parsed->xinfo & XACT_XINFO_HAS_TWOPHASE)
182  {
183  xl_xact_twophase *xl_twophase = (xl_xact_twophase *) data;
184 
185  parsed->twophase_xid = xl_twophase->xid;
186 
187  data += sizeof(xl_xact_twophase);
188 
189  if (parsed->xinfo & XACT_XINFO_HAS_GID)
190  {
191  strlcpy(parsed->twophase_gid, data, sizeof(parsed->twophase_gid));
192  data += strlen(data) + 1;
193  }
194  }
195 
196  /* Note: no alignment is guaranteed after this point */
197 
198  if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
199  {
200  xl_xact_origin xl_origin;
201 
202  /* no alignment is guaranteed, so copy onto stack */
203  memcpy(&xl_origin, data, sizeof(xl_origin));
204 
205  parsed->origin_lsn = xl_origin.origin_lsn;
206  parsed->origin_timestamp = xl_origin.origin_timestamp;
207 
208  data += sizeof(xl_xact_origin);
209  }
210 }
#define XACT_XINFO_HAS_ORIGIN
Definition: xact.h:163
struct xl_xact_xinfo xl_xact_xinfo
uint32 TransactionId
Definition: c.h:507
TransactionId xid
Definition: xact.h:252
#define MinSizeOfXactAbort
Definition: xact.h:289
#define XLOG_XACT_HAS_INFO
Definition: xact.h:152
#define XACT_XINFO_HAS_SUBXACTS
Definition: xact.h:159
struct xl_xact_dbinfo xl_xact_dbinfo
#define MinSizeOfXactRelfilenodes
Definition: xact.h:241
TimestampTz xact_time
Definition: xact.h:278
Oid tsId
Definition: xact.h:226
struct xl_xact_origin xl_xact_origin
RelFileNode xnodes[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:239
#define MinSizeOfXactSubxacts
Definition: xact.h:234
struct RelFileNode RelFileNode
struct xl_xact_twophase xl_xact_twophase
#define XACT_XINFO_HAS_DBINFO
Definition: xact.h:158
XLogRecPtr origin_lsn
Definition: xact.h:257
TransactionId * subxacts
Definition: xact.h:333
uint32 xinfo
Definition: xact.h:220
XLogRecPtr origin_lsn
Definition: xact.h:341
RelFileNode * xnodes
Definition: xact.h:336
int nsubxacts
Definition: xact.h:231
#define XACT_XINFO_HAS_TWOPHASE
Definition: xact.h:162
Oid dbId
Definition: xact.h:225
TransactionId twophase_xid
Definition: xact.h:338
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
TimestampTz xact_time
Definition: xact.h:326
TimestampTz origin_timestamp
Definition: xact.h:258
#define XACT_XINFO_HAS_RELFILENODES
Definition: xact.h:160
TimestampTz origin_timestamp
Definition: xact.h:342
#define XACT_XINFO_HAS_GID
Definition: xact.h:165
char twophase_gid[GIDSIZE]
Definition: xact.h:339
TransactionId subxacts[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:232

◆ ParseCommitRecord()

void ParseCommitRecord ( uint8  info,
xl_xact_commit xlrec,
xl_xact_parsed_commit parsed 
)

Definition at line 34 of file xactdesc.c.

References xl_xact_dbinfo::dbId, xl_xact_parsed_commit::dbId, MinSizeOfXactCommit, MinSizeOfXactInvals, MinSizeOfXactRelfilenodes, MinSizeOfXactSubxacts, xl_xact_invals::msgs, xl_xact_parsed_commit::msgs, xl_xact_invals::nmsgs, xl_xact_parsed_commit::nmsgs, xl_xact_relfilenodes::nrels, xl_xact_parsed_commit::nrels, xl_xact_subxacts::nsubxacts, xl_xact_parsed_commit::nsubxacts, xl_xact_origin::origin_lsn, xl_xact_parsed_commit::origin_lsn, xl_xact_origin::origin_timestamp, xl_xact_parsed_commit::origin_timestamp, strlcpy(), xl_xact_subxacts::subxacts, xl_xact_parsed_commit::subxacts, xl_xact_dbinfo::tsId, xl_xact_parsed_commit::tsId, xl_xact_parsed_commit::twophase_gid, xl_xact_parsed_commit::twophase_xid, xl_xact_commit::xact_time, xl_xact_parsed_commit::xact_time, XACT_XINFO_HAS_DBINFO, XACT_XINFO_HAS_GID, XACT_XINFO_HAS_INVALS, XACT_XINFO_HAS_ORIGIN, XACT_XINFO_HAS_RELFILENODES, XACT_XINFO_HAS_SUBXACTS, XACT_XINFO_HAS_TWOPHASE, xl_xact_twophase::xid, xl_xact_xinfo::xinfo, xl_xact_parsed_commit::xinfo, XLOG_XACT_HAS_INFO, xl_xact_relfilenodes::xnodes, and xl_xact_parsed_commit::xnodes.

Referenced by DecodeXactOp(), recoveryStopsAfter(), recoveryStopsBefore(), xact_desc_commit(), and xact_redo().

35 {
36  char *data = ((char *) xlrec) + MinSizeOfXactCommit;
37 
38  memset(parsed, 0, sizeof(*parsed));
39 
40  parsed->xinfo = 0; /* default, if no XLOG_XACT_HAS_INFO is
41  * present */
42 
43  parsed->xact_time = xlrec->xact_time;
44 
45  if (info & XLOG_XACT_HAS_INFO)
46  {
47  xl_xact_xinfo *xl_xinfo = (xl_xact_xinfo *) data;
48 
49  parsed->xinfo = xl_xinfo->xinfo;
50 
51  data += sizeof(xl_xact_xinfo);
52  }
53 
54  if (parsed->xinfo & XACT_XINFO_HAS_DBINFO)
55  {
56  xl_xact_dbinfo *xl_dbinfo = (xl_xact_dbinfo *) data;
57 
58  parsed->dbId = xl_dbinfo->dbId;
59  parsed->tsId = xl_dbinfo->tsId;
60 
61  data += sizeof(xl_xact_dbinfo);
62  }
63 
64  if (parsed->xinfo & XACT_XINFO_HAS_SUBXACTS)
65  {
66  xl_xact_subxacts *xl_subxacts = (xl_xact_subxacts *) data;
67 
68  parsed->nsubxacts = xl_subxacts->nsubxacts;
69  parsed->subxacts = xl_subxacts->subxacts;
70 
71  data += MinSizeOfXactSubxacts;
72  data += parsed->nsubxacts * sizeof(TransactionId);
73  }
74 
75  if (parsed->xinfo & XACT_XINFO_HAS_RELFILENODES)
76  {
77  xl_xact_relfilenodes *xl_relfilenodes = (xl_xact_relfilenodes *) data;
78 
79  parsed->nrels = xl_relfilenodes->nrels;
80  parsed->xnodes = xl_relfilenodes->xnodes;
81 
83  data += xl_relfilenodes->nrels * sizeof(RelFileNode);
84  }
85 
86  if (parsed->xinfo & XACT_XINFO_HAS_INVALS)
87  {
88  xl_xact_invals *xl_invals = (xl_xact_invals *) data;
89 
90  parsed->nmsgs = xl_invals->nmsgs;
91  parsed->msgs = xl_invals->msgs;
92 
93  data += MinSizeOfXactInvals;
94  data += xl_invals->nmsgs * sizeof(SharedInvalidationMessage);
95  }
96 
97  if (parsed->xinfo & XACT_XINFO_HAS_TWOPHASE)
98  {
99  xl_xact_twophase *xl_twophase = (xl_xact_twophase *) data;
100 
101  parsed->twophase_xid = xl_twophase->xid;
102 
103  data += sizeof(xl_xact_twophase);
104 
105  if (parsed->xinfo & XACT_XINFO_HAS_GID)
106  {
107  strlcpy(parsed->twophase_gid, data, sizeof(parsed->twophase_gid));
108  data += strlen(data) + 1;
109  }
110  }
111 
112  /* Note: no alignment is guaranteed after this point */
113 
114  if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
115  {
116  xl_xact_origin xl_origin;
117 
118  /* no alignment is guaranteed, so copy onto stack */
119  memcpy(&xl_origin, data, sizeof(xl_origin));
120 
121  parsed->origin_lsn = xl_origin.origin_lsn;
122  parsed->origin_timestamp = xl_origin.origin_timestamp;
123 
124  data += sizeof(xl_xact_origin);
125  }
126 }
RelFileNode * xnodes
Definition: xact.h:308
#define XACT_XINFO_HAS_ORIGIN
Definition: xact.h:163
struct xl_xact_xinfo xl_xact_xinfo
uint32 TransactionId
Definition: c.h:507
TimestampTz origin_timestamp
Definition: xact.h:319
TransactionId xid
Definition: xact.h:252
TransactionId twophase_xid
Definition: xact.h:313
TransactionId * subxacts
Definition: xact.h:305
#define XLOG_XACT_HAS_INFO
Definition: xact.h:152
SharedInvalidationMessage * msgs
Definition: xact.h:311
XLogRecPtr origin_lsn
Definition: xact.h:318
#define XACT_XINFO_HAS_SUBXACTS
Definition: xact.h:159
struct xl_xact_dbinfo xl_xact_dbinfo
#define MinSizeOfXactRelfilenodes
Definition: xact.h:241
Oid tsId
Definition: xact.h:226
struct xl_xact_origin xl_xact_origin
RelFileNode xnodes[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:239
#define MinSizeOfXactSubxacts
Definition: xact.h:234
#define MinSizeOfXactCommit
Definition: xact.h:274
SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:246
struct RelFileNode RelFileNode
TimestampTz xact_time
Definition: xact.h:263
struct xl_xact_twophase xl_xact_twophase
#define MinSizeOfXactInvals
Definition: xact.h:248
#define XACT_XINFO_HAS_DBINFO
Definition: xact.h:158
XLogRecPtr origin_lsn
Definition: xact.h:257
uint32 xinfo
Definition: xact.h:220
int nsubxacts
Definition: xact.h:231
#define XACT_XINFO_HAS_TWOPHASE
Definition: xact.h:162
Oid dbId
Definition: xact.h:225
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
TimestampTz origin_timestamp
Definition: xact.h:258
#define XACT_XINFO_HAS_INVALS
Definition: xact.h:161
#define XACT_XINFO_HAS_RELFILENODES
Definition: xact.h:160
int nmsgs
Definition: xact.h:245
#define XACT_XINFO_HAS_GID
Definition: xact.h:165
char twophase_gid[GIDSIZE]
Definition: xact.h:314
TransactionId subxacts[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:232
TimestampTz xact_time
Definition: xact.h:298

◆ PrepareTransactionBlock()

bool PrepareTransactionBlock ( const char *  gid)

Definition at line 3515 of file xact.c.

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

Referenced by standard_ProcessUtility().

3516 {
3517  TransactionState s;
3518  bool result;
3519 
3520  /* Set up to commit the current transaction */
3521  result = EndTransactionBlock();
3522 
3523  /* If successful, change outer tblock state to PREPARE */
3524  if (result)
3525  {
3527 
3528  while (s->parent != NULL)
3529  s = s->parent;
3530 
3531  if (s->blockState == TBLOCK_END)
3532  {
3533  /* Save GID where PrepareTransaction can find it again */
3535 
3537  }
3538  else
3539  {
3540  /*
3541  * ignore case where we are not in a transaction;
3542  * EndTransactionBlock already issued a warning.
3543  */
3546  /* Don't send back a PREPARE result tag... */
3547  result = false;
3548  }
3549  }
3550 
3551  return result;
3552 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
MemoryContext TopTransactionContext
Definition: mcxt.c:49
bool EndTransactionBlock(void)
Definition: xact.c:3567
TBlockState blockState
Definition: xact.c:179
struct TransactionStateData * parent
Definition: xact.c:193
#define Assert(condition)
Definition: c.h:732
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1148
static char * prepareGID
Definition: xact.c:240

◆ PreventInTransactionBlock()

void PreventInTransactionBlock ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3188 of file xact.c.

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

Referenced by AlterDatabase(), cluster(), CreateSubscription(), DiscardAll(), DropSubscription(), exec_replication_command(), ExecDropStmt(), ProcessUtilitySlow(), standard_ProcessUtility(), and vacuum().

3189 {
3190  /*
3191  * xact block already started?
3192  */
3193  if (IsTransactionBlock())
3194  ereport(ERROR,
3195  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3196  /* translator: %s represents an SQL statement name */
3197  errmsg("%s cannot run inside a transaction block",
3198  stmtType)));
3199 
3200  /*
3201  * subtransaction?
3202  */
3203  if (IsSubTransaction())
3204  ereport(ERROR,
3205  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3206  /* translator: %s represents an SQL statement name */
3207  errmsg("%s cannot run inside a subtransaction",
3208  stmtType)));
3209 
3210  /*
3211  * inside a function call?
3212  */
3213  if (!isTopLevel)
3214  ereport(ERROR,
3215  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3216  /* translator: %s represents an SQL statement name */
3217  errmsg("%s cannot be executed from a function", stmtType)));
3218 
3219  /* If we got past IsTransactionBlock test, should be in default state */
3222  elog(FATAL, "cannot prevent transaction chain");
3223  /* all okay */
3224 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
int errcode(int sqlerrcode)
Definition: elog.c:570
TBlockState blockState
Definition: xact.c:179
bool IsTransactionBlock(void)
Definition: xact.c:4457
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
#define ereport(elevel, rest)
Definition: elog.h:141
bool IsSubTransaction(void)
Definition: xact.c:4530
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226

◆ RegisterSubXactCallback()

void RegisterSubXactCallback ( SubXactCallback  callback,
void *  arg 
)

Definition at line 3392 of file xact.c.

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

Referenced by _PG_init(), GetConnection(), and sepgsql_init_client_label().

3393 {
3394  SubXactCallbackItem *item;
3395 
3396  item = (SubXactCallbackItem *)
3398  item->callback = callback;
3399  item->arg = arg;
3400  item->next = SubXact_callbacks;
3401  SubXact_callbacks = item;
3402 }
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:276
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
struct SubXactCallbackItem * next
Definition: xact.c:271
SubXactCallback callback
Definition: xact.c:272
MemoryContext TopMemoryContext
Definition: mcxt.c:44
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:771
void * arg

◆ RegisterXactCallback()

void RegisterXactCallback ( XactCallback  callback,
void *  arg 
)

Definition at line 3337 of file xact.c.

References arg, XactCallbackItem::arg, callback(), XactCallbackItem::callback, MemoryContextAlloc(), XactCallbackItem::next, TopMemoryContext, and Xact_callbacks.

Referenced by _PG_init(), GetConnection(), and sepgsql_init_client_label().

3338 {
3339  XactCallbackItem *item;
3340 
3341  item = (XactCallbackItem *)
3343  item->callback = callback;
3344  item->arg = arg;
3345  item->next = Xact_callbacks;
3346  Xact_callbacks = item;
3347 }
struct XactCallbackItem * next
Definition: xact.c:259
void * arg
Definition: xact.c:261
XactCallback callback
Definition: xact.c:260
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
MemoryContext TopMemoryContext
Definition: mcxt.c:44
static XactCallbackItem * Xact_callbacks
Definition: xact.c:264
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:771
void * arg

◆ ReleaseCurrentSubTransaction()

void ReleaseCurrentSubTransaction ( void  )

Definition at line 4252 of file xact.c.

References Assert, TransactionStateData::blockState, BlockStateAsString(), CommitSubTransaction(), CurrentTransactionState, CurTransactionContext, elog, ereport, errcode(), errmsg(), ERROR, IsInParallelMode(), 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().

4253 {
4255 
4256  /*
4257  * Workers synchronize transaction state at the beginning of each parallel
4258  * operation, so we can't account for commit of subtransactions after that
4259  * point. This should not happen anyway. Code calling this would
4260  * typically have called BeginInternalSubTransaction() first, failing
4261  * there.
4262  */
4263  if (IsInParallelMode())
4264  ereport(ERROR,
4265  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4266  errmsg("cannot commit subtransactions during a parallel operation")));
4267 
4268  if (s->blockState != TBLOCK_SUBINPROGRESS)
4269  elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4271  Assert(s->state == TRANS_INPROGRESS);
4274  s = CurrentTransactionState; /* changed by pop */
4275  Assert(s->state == TRANS_INPROGRESS);
4276 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext CurTransactionContext
Definition: mcxt.c:50
int errcode(int sqlerrcode)
Definition: elog.c:570
TBlockState blockState
Definition: xact.c:179
TransState state
Definition: xact.c:178
bool IsInParallelMode(void)
Definition: xact.c:910
#define ERROR
Definition: elog.h:43
static void CommitSubTransaction(void)
Definition: xact.c:4591
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5169
#define ereport(elevel, rest)
Definition: elog.h:141
#define Assert(condition)
Definition: c.h:732
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226

◆ ReleaseSavepoint()

void ReleaseSavepoint ( const char *  name)

Definition at line 3945 of file xact.c.

References Assert, TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg(), ERROR, FATAL, IsInParallelMode(), TransactionStateData::name, TransactionStateData::parent, PointerIsValid, 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().

3946 {
3948  TransactionState target,
3949  xact;
3950 
3951  /*
3952  * Workers synchronize transaction state at the beginning of each parallel
3953  * operation, so we can't account for transaction state change after that
3954  * point. (Note that this check will certainly error out if s->blockState
3955  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
3956  * below.)
3957  */
3958  if (IsInParallelMode())
3959  ereport(ERROR,
3960  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3961  errmsg("cannot release savepoints during a parallel operation")));
3962 
3963  switch (s->blockState)
3964  {
3965  /*
3966  * We can't release a savepoint if there is no savepoint defined.
3967  */
3968  case TBLOCK_INPROGRESS:
3969  ereport(ERROR,
3970  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3971  errmsg("savepoint \"%s\" does not exist", name)));
3972  break;
3973 
3975  /* See comment about implicit transactions in DefineSavepoint */
3976  ereport(ERROR,
3977  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3978  /* translator: %s represents an SQL statement name */
3979  errmsg("%s can only be used in transaction blocks",
3980  "RELEASE SAVEPOINT")));
3981  break;
3982 
3983  /*
3984  * We are in a non-aborted subtransaction. This is the only valid
3985  * case.
3986  */
3987  case TBLOCK_SUBINPROGRESS:
3988  break;
3989 
3990  /* These cases are invalid. */
3991  case TBLOCK_DEFAULT:
3992  case TBLOCK_STARTED:
3993  case TBLOCK_BEGIN:
3995  case TBLOCK_SUBBEGIN:
3996  case TBLOCK_END:
3997  case TBLOCK_SUBRELEASE:
3998  case TBLOCK_SUBCOMMIT:
3999  case TBLOCK_ABORT:
4000  case TBLOCK_SUBABORT:
4001  case TBLOCK_ABORT_END:
4002  case TBLOCK_SUBABORT_END:
4003  case TBLOCK_ABORT_PENDING:
4005  case TBLOCK_SUBRESTART:
4007  case TBLOCK_PREPARE:
4008  elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4010  break;
4011  }
4012 
4013  for (target = s; PointerIsValid(target); target = target->parent)
4014  {
4015  if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4016  break;
4017  }
4018 
4019  if (!PointerIsValid(target))
4020  ereport(ERROR,
4021  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4022  errmsg("savepoint \"%s\" does not exist", name)));
4023 
4024  /* disallow crossing savepoint level boundaries */
4025  if (target->savepointLevel != s->savepointLevel)
4026  ereport(ERROR,
4027  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4028  errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4029 
4030  /*
4031  * Mark "commit pending" all subtransactions up to the target
4032  * subtransaction. The actual commits will happen when control gets to
4033  * CommitTransactionCommand.
4034  */
4035  xact = CurrentTransactionState;
4036  for (;;)
4037  {
4039  xact->blockState = TBLOCK_SUBRELEASE;
4040  if (xact == target)
4041  break;
4042  xact = xact->parent;
4043  Assert(PointerIsValid(xact));
4044  }
4045 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
int errcode(int sqlerrcode)
Definition: elog.c:570
TBlockState blockState
Definition: xact.c:179
bool IsInParallelMode(void)
Definition: xact.c:910
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
struct TransactionStateData * parent
Definition: xact.c:193
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5169
#define ereport(elevel, rest)
Definition: elog.h:141
#define Assert(condition)
Definition: c.h:732
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
#define PointerIsValid(pointer)
Definition: c.h:626

◆ RequireTransactionBlock()

void RequireTransactionBlock ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3254 of file xact.c.

References CheckTransactionBlock().

Referenced by PerformCursorOpen(), and standard_ProcessUtility().

3255 {
3256  CheckTransactionBlock(isTopLevel, true, stmtType);
3257 }
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3263

◆ RollbackAndReleaseCurrentSubTransaction()

void RollbackAndReleaseCurrentSubTransaction ( void  )

Definition at line 4286 of file xact.c.

References AbortSubTransaction(), AssertState, 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(), ReorderBufferCommit(), and ReorderBufferImmediateInvalidation().

4287 {
4289 
4290  /*
4291  * Unlike ReleaseCurrentSubTransaction(), this is nominally permitted
4292  * during parallel operations. That's because we may be in the master,
4293  * recovering from an error thrown while we were in parallel mode. We
4294  * won't reach here in a worker, because BeginInternalSubTransaction()
4295  * will have failed.
4296  */
4297 
4298  switch (s->blockState)
4299  {
4300  /* Must be in a subtransaction */
4301  case TBLOCK_SUBINPROGRESS:
4302  case TBLOCK_SUBABORT:
4303  break;
4304 
4305  /* These cases are invalid. */
4306  case TBLOCK_DEFAULT:
4307  case TBLOCK_STARTED:
4308  case TBLOCK_BEGIN:
4311  case TBLOCK_SUBBEGIN:
4312  case TBLOCK_INPROGRESS:
4313  case TBLOCK_END:
4314  case TBLOCK_SUBRELEASE:
4315  case TBLOCK_SUBCOMMIT:
4316  case TBLOCK_ABORT:
4317  case TBLOCK_ABORT_END:
4318  case TBLOCK_SUBABORT_END:
4319  case TBLOCK_ABORT_PENDING:
4321  case TBLOCK_SUBRESTART:
4323  case TBLOCK_PREPARE:
4324  elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4326  break;
4327  }
4328 
4329  /*
4330  * Abort the current subtransaction, if needed.
4331  */
4332  if (s->blockState == TBLOCK_SUBINPROGRESS)
4334 
4335  /* And clean it up, too */
4337 
4338  s = CurrentTransactionState; /* changed by pop */
4340  s->blockState == TBLOCK_INPROGRESS ||
4342  s->blockState == TBLOCK_STARTED);
4343 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
#define AssertState(condition)
Definition: c.h:735
TBlockState blockState
Definition: xact.c:179
#define FATAL
Definition: elog.h:52
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5169
static void AbortSubTransaction(void)
Definition: xact.c:4700
static void CleanupSubTransaction(void)
Definition: xact.c:4856
#define elog(elevel,...)
Definition: elog.h:226

◆ RollbackToSavepoint()

void RollbackToSavepoint ( const char *  name)

Definition at line 4054 of file xact.c.

References Assert, TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg(), ERROR, FATAL, IsInParallelMode(), TransactionStateData::name, TransactionStateData::parent, PointerIsValid, 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().

4055 {
4057  TransactionState target,
4058  xact;
4059 
4060  /*
4061  * Workers synchronize transaction state at the beginning of each parallel
4062  * operation, so we can't account for transaction state change after that
4063  * point. (Note that this check will certainly error out if s->blockState
4064  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4065  * below.)
4066  */
4067  if (IsInParallelMode())
4068  ereport(ERROR,
4069  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4070  errmsg("cannot rollback to savepoints during a parallel operation")));
4071 
4072  switch (s->blockState)
4073  {
4074  /*
4075  * We can't rollback to a savepoint if there is no savepoint
4076  * defined.
4077  */
4078  case TBLOCK_INPROGRESS:
4079  case TBLOCK_ABORT:
4080  ereport(ERROR,
4081  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4082  errmsg("savepoint \"%s\" does not exist", name)));
4083  break;
4084 
4086  /* See comment about implicit transactions in DefineSavepoint */
4087  ereport(ERROR,
4088  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4089  /* translator: %s represents an SQL statement name */
4090  errmsg("%s can only be used in transaction blocks",
4091  "ROLLBACK TO SAVEPOINT")));
4092  break;
4093 
4094  /*
4095  * There is at least one savepoint, so proceed.
4096  */
4097  case TBLOCK_SUBINPROGRESS:
4098  case TBLOCK_SUBABORT:
4099  break;
4100 
4101  /* These cases are invalid. */
4102  case TBLOCK_DEFAULT:
4103  case TBLOCK_STARTED:
4104  case TBLOCK_BEGIN:
4106  case TBLOCK_SUBBEGIN:
4107  case TBLOCK_END:
4108  case TBLOCK_SUBRELEASE:
4109  case TBLOCK_SUBCOMMIT:
4110  case TBLOCK_ABORT_END:
4111  case TBLOCK_SUBABORT_END:
4112  case TBLOCK_ABORT_PENDING:
4114  case TBLOCK_SUBRESTART:
4116  case TBLOCK_PREPARE:
4117  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4119  break;
4120  }
4121 
4122  for (target = s; PointerIsValid(target); target = target->parent)
4123  {
4124  if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4125  break;
4126  }
4127 
4128  if (!PointerIsValid(target))
4129  ereport(ERROR,
4130  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4131  errmsg("savepoint \"%s\" does not exist", name)));
4132 
4133  /* disallow crossing savepoint level boundaries */
4134  if (target->savepointLevel != s->savepointLevel)
4135  ereport(ERROR,
4136  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4137  errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4138 
4139  /*
4140  * Mark "abort pending" all subtransactions up to the target
4141  * subtransaction. The actual aborts will happen when control gets to
4142  * CommitTransactionCommand.
4143  */
4144  xact = CurrentTransactionState;
4145  for (;;)
4146  {
4147  if (xact == target)
4148  break;
4149  if (xact->blockState == TBLOCK_SUBINPROGRESS)
4151  else if (xact->blockState == TBLOCK_SUBABORT)
4153  else
4154  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4156  xact = xact->parent;
4157  Assert(PointerIsValid(xact));
4158  }
4159 
4160  /* And mark the target as "restart pending" */
4161  if (xact->blockState == TBLOCK_SUBINPROGRESS)
4162  xact->blockState = TBLOCK_SUBRESTART;
4163  else if (xact->blockState == TBLOCK_SUBABORT)
4165  else
4166  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4168 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
int errcode(int sqlerrcode)
Definition: elog.c:570
TBlockState blockState
Definition: xact.c:179
bool IsInParallelMode(void)
Definition: xact.c:910
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
struct TransactionStateData * parent
Definition: xact.c:193
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5169
#define ereport(elevel, rest)
Definition: elog.h:141
#define Assert(condition)
Definition: c.h:732
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
#define PointerIsValid(pointer)
Definition: c.h:626

◆ SerializeTransactionState()

void SerializeTransactionState ( Size  maxsize,
char *  start_address 
)

Definition at line 5015 of file xact.c.

References add_size(), Assert, TransactionStateData::childXids, currentCommandId, i, TransactionStateData::nChildXids, nParallelCurrentXids, palloc(), ParallelCurrentXids, TransactionStateData::parent, qsort, TransactionStateData::transactionId, TransactionIdIsValid, XactDeferrable, XactIsoLevel, XactTopTransactionId, and xidComparator().

Referenced by InitializeParallelDSM().

5016 {
5017  TransactionState s;
5018  Size nxids = 0;
5019  Size i = 0;
5020  Size c = 0;
5021  TransactionId *workspace;
5022  TransactionId *result = (TransactionId *) start_address;
5023 
5024  result[c++] = (TransactionId) XactIsoLevel;
5025  result[c++] = (TransactionId) XactDeferrable;
5026  result[c++] = XactTopTransactionId;
5027  result[c++] = CurrentTransactionState->transactionId;
5028  result[c++] = (TransactionId) currentCommandId;
5029  Assert(maxsize >= c * sizeof(TransactionId));
5030 
5031  /*
5032  * If we're running in a parallel worker and launching a parallel worker
5033  * of our own, we can just pass along the information that was passed to
5034  * us.
5035  */
5036  if (nParallelCurrentXids > 0)
5037  {
5038  result[c++] = nParallelCurrentXids;
5039  Assert(maxsize >= (nParallelCurrentXids + c) * sizeof(TransactionId));
5040  memcpy(&result[c], ParallelCurrentXids,
5042  return;
5043  }
5044 
5045  /*
5046  * OK, we need to generate a sorted list of XIDs that our workers should
5047  * view as current. First, figure out how many there are.
5048  */
5049  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5050  {
5052  nxids = add_size(nxids, 1);
5053  nxids = add_size(nxids, s->nChildXids);
5054  }
5055  Assert((c + 1 + nxids) * sizeof(TransactionId) <= maxsize);
5056 
5057  /* Copy them to our scratch space. */
5058  workspace = palloc(nxids * sizeof(TransactionId));
5059  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5060  {
5062  workspace[i++] = s->transactionId;
5063  memcpy(&workspace[i], s->childXids,
5064  s->nChildXids * sizeof(TransactionId));
5065  i += s->nChildXids;
5066  }
5067  Assert(i == nxids);
5068 
5069  /* Sort them. */
5070  qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5071 
5072  /* Copy data into output area. */
5073  result[c++] = (TransactionId) nxids;
5074  memcpy(&result[c], workspace, nxids * sizeof(TransactionId));
5075 }
TransactionId XactTopTransactionId
Definition: xact.c:108
bool XactDeferrable
Definition: xact.c:81
static TransactionState CurrentTransactionState
Definition: xact.c:215
uint32 TransactionId
Definition: c.h:507
int nParallelCurrentXids
Definition: xact.c:109
TransactionId * childXids
Definition: xact.c:184
struct TransactionStateData * parent
Definition: xact.c:193
char * c
Size add_size(Size s1, Size s2)
Definition: shmem.c:475
TransactionId transactionId
Definition: xact.c:174
TransactionId * ParallelCurrentXids
Definition: xact.c:110
#define Assert(condition)
Definition: c.h:732
size_t Size
Definition: c.h:466
int XactIsoLevel
Definition: xact.c:75
void * palloc(Size size)
Definition: mcxt.c:924
int i
#define qsort(a, b, c, d)
Definition: port.h:491
static CommandId currentCommandId
Definition: xact.c:222
#define TransactionIdIsValid(xid)
Definition: transam.h:41
int xidComparator(const void *arg1, const void *arg2)
Definition: xid.c:138

◆ SetCurrentStatementStartTimestamp()

void SetCurrentStatementStartTimestamp ( void  )

Definition at line 734 of file xact.c.

References Assert, GetCurrentTimestamp(), IsParallelWorker, and stmtStartTimestamp.

Referenced by autovac_report_activity(), autovac_report_workitem(), ensure_transaction(), initialize_worker_spi(), InitPostgres(), and PostgresMain().

735 {
736  if (!IsParallelWorker())
738  else
740 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1592
static TimestampTz stmtStartTimestamp
Definition: xact.c:233
#define IsParallelWorker()
Definition: parallel.h:60
#define Assert(condition)
Definition: c.h:732

◆ SetParallelStartTimestamps()

void SetParallelStartTimestamps ( TimestampTz  xact_ts,
TimestampTz  stmt_ts 
)

Definition at line 688 of file xact.c.

References Assert, IsParallelWorker, stmtStartTimestamp, and xactStartTimestamp.

Referenced by ParallelWorkerMain().

689 {
691  xactStartTimestamp = xact_ts;
692  stmtStartTimestamp = stmt_ts;
693 }
static TimestampTz stmtStartTimestamp
Definition: xact.c:233
#define IsParallelWorker()
Definition: parallel.h:60
#define Assert(condition)
Definition: c.h:732
static TimestampTz xactStartTimestamp
Definition: xact.c:232

◆ StartParallelWorkerTransaction()

void StartParallelWorkerTransaction ( char *  tstatespace)

Definition at line 5083 of file xact.c.

References Assert, TransactionStateData::blockState, currentCommandId, nParallelCurrentXids, ParallelCurrentXids, StartTransaction(), TBLOCK_DEFAULT, TBLOCK_PARALLEL_INPROGRESS, TransactionStateData::transactionId, XactDeferrable, XactIsoLevel, and XactTopTransactionId.

Referenced by ParallelWorkerMain().

5084 {
5085  TransactionId *tstate = (TransactionId *) tstatespace;
5086 
5088  StartTransaction();
5089 
5090  XactIsoLevel = (int) tstate[0];
5091  XactDeferrable = (bool) tstate[1];
5092  XactTopTransactionId = tstate[2];
5094  currentCommandId = tstate[4];
5095  nParallelCurrentXids = (int) tstate[5];
5096  ParallelCurrentXids = &tstate[6];
5097 
5099 }
TransactionId XactTopTransactionId
Definition: xact.c:108
bool XactDeferrable
Definition: xact.c:81
static TransactionState CurrentTransactionState
Definition: xact.c:215
uint32 TransactionId
Definition: c.h:507
int nParallelCurrentXids
Definition: xact.c:109
TBlockState blockState
Definition: xact.c:179
TransactionId transactionId
Definition: xact.c:174
static void StartTransaction(void)
Definition: xact.c:1800
TransactionId * ParallelCurrentXids
Definition: xact.c:110
#define Assert(condition)
Definition: c.h:732
int XactIsoLevel
Definition: xact.c:75
static CommandId currentCommandId
Definition: xact.c:222
unsigned char bool
Definition: c.h:308

◆ StartTransactionCommand()

void StartTransactionCommand ( void  )

Definition at line 2708 of file xact.c.

References Assert, TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, CurTransactionContext, elog, ERROR, 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 ApplyWorkerMain(), autoprewarm_database_main(), BeginInternalSubTransaction(), BootstrapModeMain(), cluster(), DefineIndex(), do_autovacuum(), ensure_transaction(), get_database_list(), get_subscription_list(), IdentifySystem(), index_drop(), initialize_worker_spi(), InitPostgres(), LogicalRepSyncTableStart(), maybe_reread_subscription(), movedb(), ParallelWorkerMain(), perform_work_item(), pg_attribute_noreturn(), process_syncing_tables_for_apply(), ProcessCatchupInterrupt(), ProcessCompletedNotifies(), ProcessIncomingNotify(), ReindexMultipleTables(), RemoveTempRelationsCallback(), ReorderBufferCommit(), SnapBuildExportSnapshot(), SPI_start_transaction(), start_xact_command(), vacuum(), and vacuum_rel().

2709 {
2711 
2712  switch (s->blockState)
2713  {
2714  /*
2715  * if we aren't in a transaction block, we just do our usual start
2716  * transaction.
2717  */
2718  case TBLOCK_DEFAULT:
2719  StartTransaction();
2721  break;
2722 
2723  /*
2724  * We are somewhere in a transaction block or subtransaction and
2725  * about to start a new command. For now we do nothing, but
2726  * someday we may do command-local resource initialization. (Note
2727  * that any needed CommandCounterIncrement was done by the
2728  * previous CommitTransactionCommand.)
2729  */
2730  case TBLOCK_INPROGRESS:
2732  case TBLOCK_SUBINPROGRESS:
2733  break;
2734 
2735  /*
2736  * Here we are in a failed transaction block (one of the commands
2737  * caused an abort) so we do nothing but remain in the abort
2738  * state. Eventually we will get a ROLLBACK command which will
2739  * get us out of this state. (It is up to other code to ensure
2740  * that no commands other than ROLLBACK will be processed in these
2741  * states.)
2742  */
2743  case TBLOCK_ABORT:
2744  case TBLOCK_SUBABORT:
2745  break;
2746 
2747  /* These cases are invalid. */
2748  case TBLOCK_STARTED:
2749  case TBLOCK_BEGIN:
2751  case TBLOCK_SUBBEGIN:
2752  case TBLOCK_END:
2753  case TBLOCK_SUBRELEASE:
2754  case TBLOCK_SUBCOMMIT:
2755  case TBLOCK_ABORT_END:
2756  case TBLOCK_SUBABORT_END:
2757  case TBLOCK_ABORT_PENDING:
2759  case TBLOCK_SUBRESTART:
2761  case TBLOCK_PREPARE:
2762  elog(ERROR, "StartTransactionCommand: unexpected state %s",
2764  break;
2765  }
2766 
2767  /*
2768  * We must switch to CurTransactionContext before returning. This is
2769  * already done if we called StartTransaction, otherwise not.
2770  */
2771  Assert(CurTransactionContext != NULL);
2773 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext CurTransactionContext
Definition: mcxt.c:50
TBlockState blockState
Definition: xact.c:179
#define ERROR
Definition: elog.h:43
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5169
static void StartTransaction(void)
Definition: xact.c:1800
#define Assert(condition)
Definition: c.h:732
#define elog(elevel,...)
Definition: elog.h:226

◆ SubTransactionIsActive()

bool SubTransactionIsActive ( SubTransactionId  subxid)

Definition at line 638 of file xact.c.

References TransactionStateData::parent, TransactionStateData::state, TransactionStateData::subTransactionId, and TRANS_ABORT.

Referenced by fmgr_sql().

639 {
641 
642  for (s = CurrentTransactionState; s != NULL; s = s->parent)
643  {
644  if (s->state == TRANS_ABORT)
645  continue;
646  if (s->subTransactionId == subxid)
647  return true;
648  }
649  return false;
650 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
TransState state
Definition: xact.c:178
struct TransactionStateData * parent
Definition: xact.c:193
SubTransactionId subTransactionId
Definition: xact.c:175

◆ TransactionBlockStatusCode()

char TransactionBlockStatusCode ( void  )

Definition at line 4489 of file xact.c.

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().

4490 {
4492 
4493  switch (s->blockState)
4494  {
4495  case TBLOCK_DEFAULT:
4496  case TBLOCK_STARTED:
4497  return 'I'; /* idle --- not in transaction */
4498  case TBLOCK_BEGIN:
4499  case TBLOCK_SUBBEGIN:
4500  case TBLOCK_INPROGRESS:
4503  case TBLOCK_SUBINPROGRESS:
4504  case TBLOCK_END:
4505  case TBLOCK_SUBRELEASE:
4506  case TBLOCK_SUBCOMMIT:
4507  case TBLOCK_PREPARE:
4508  return 'T'; /* in transaction */
4509  case TBLOCK_ABORT:
4510  case TBLOCK_SUBABORT:
4511  case TBLOCK_ABORT_END:
4512  case TBLOCK_SUBABORT_END:
4513  case TBLOCK_ABORT_PENDING:
4515  case TBLOCK_SUBRESTART:
4517  return 'E'; /* in failed transaction */
4518  }
4519 
4520  /* should never get here */
4521  elog(FATAL, "invalid transaction block state: %s",
4523  return 0; /* keep compiler quiet */
4524 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
TBlockState blockState
Definition: xact.c:179
#define FATAL
Definition: elog.h:52
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5169
#define elog(elevel,...)
Definition: elog.h:226

◆ TransactionIdIsCurrentTransactionId()

bool TransactionIdIsCurrentTransactionId ( TransactionId  xid)

Definition at line 770 of file xact.c.

References TransactionStateData::childXids, TransactionStateData::nChildXids, nParallelCurrentXids, ParallelCurrentXids, TransactionStateData::parent, TransactionStateData::state, TRANS_ABORT, TransactionStateData::transactionId, TransactionIdEquals, TransactionIdIsNormal, TransactionIdIsValid, and TransactionIdPrecedes().

Referenced by acquire_sample_rows(), compute_new_xmax_infomask(), copy_heap_data(), Do_MultiXactIdWait(), DoesMultiXactIdConflict(), EvalPlanQualFetch(), ExecCheckHeapTupleVisible(), ExecOnConflictUpdate(), FreezeMultiXactId(), heap_delete(), heap_lock_tuple(), heap_update(), HeapTupleHeaderAdjustCmax(), HeapTupleHeaderGetCmax(), HeapTupleHeaderGetCmin(), HeapTupleHeaderIsOnlyLocked(), HeapTupleSatisfiesDirty(), HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesSelf(), HeapTupleSatisfiesToast(), HeapTupleSatisfiesUpdate(), HeapTupleSatisfiesVacuum(), IndexBuildHeapRangeScan(), MultiXactIdIsRunning(), RI_FKey_fk_upd_check_required(), SnapBuildWaitSnapshot(), test_lockmode_for_conflict(), TransactionIdIsInProgress(), and txid_status().

771 {
773 
774  /*
775  * We always say that BootstrapTransactionId is "not my transaction ID"
776  * even when it is (ie, during bootstrap). Along with the fact that
777  * transam.c always treats BootstrapTransactionId as already committed,
778  * this causes the heapam_visibility.c routines to see all tuples as
779  * committed, which is what we need during bootstrap. (Bootstrap mode
780  * only inserts tuples, it never updates or deletes them, so all tuples
781  * can be presumed good immediately.)
782  *
783  * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
784  * not my transaction ID, so we can just return "false" immediately for
785  * any non-normal XID.
786  */
787  if (!TransactionIdIsNormal(xid))
788  return false;
789 
790  /*
791  * In parallel workers, the XIDs we must consider as current are stored in
792  * ParallelCurrentXids rather than the transaction-state stack. Note that
793  * the XIDs in this array are sorted numerically rather than according to
794  * transactionIdPrecedes order.
795  */
796  if (nParallelCurrentXids > 0)
797  {
798  int low,
799  high;
800 
801  low = 0;
802  high = nParallelCurrentXids - 1;
803  while (low <= high)
804  {
805  int middle;
806  TransactionId probe;
807 
808  middle = low + (high - low) / 2;
809  probe = ParallelCurrentXids[middle];
810  if (probe == xid)
811  return true;
812  else if (probe < xid)
813  low = middle + 1;
814  else
815  high = middle - 1;
816  }
817  return false;
818  }
819 
820  /*
821  * We will return true for the Xid of the current subtransaction, any of
822  * its subcommitted children, any of its parents, or any of their
823  * previously subcommitted children. However, a transaction being aborted
824  * is no longer "current", even though it may still have an entry on the
825  * state stack.
826  */
827  for (s = CurrentTransactionState; s != NULL; s = s->parent)
828  {
829  int low,
830  high;
831 
832  if (s->state == TRANS_ABORT)
833  continue;
835  continue; /* it can't have any child XIDs either */
836  if (TransactionIdEquals(xid, s->transactionId))
837  return true;
838  /* As the childXids array is ordered, we can use binary search */
839  low = 0;
840  high = s->nChildXids - 1;
841  while (low <= high)
842  {
843  int middle;
844  TransactionId probe;
845 
846  middle = low + (high - low) / 2;
847  probe = s->childXids[middle];
848  if (TransactionIdEquals(probe, xid))
849  return true;
850  else if (TransactionIdPrecedes(probe, xid))
851  low = middle + 1;
852  else
853  high = middle - 1;
854  }
855  }
856 
857  return false;
858 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
uint32 TransactionId
Definition: c.h:507
int nParallelCurrentXids
Definition: xact.c:109
TransactionId * childXids
Definition: xact.c:184
TransState state
Definition: xact.c:178
struct TransactionStateData * parent
Definition: xact.c:193
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
TransactionId transactionId
Definition: xact.c:174
TransactionId * ParallelCurrentXids
Definition: xact.c:110
#define TransactionIdIsValid(xid)
Definition: transam.h:41
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

◆ UnregisterSubXactCallback()

void UnregisterSubXactCallback ( SubXactCallback  callback,
void *  arg 
)

Definition at line 3405 of file xact.c.

References SubXactCallbackItem::next, and pfree().

3406 {
3407  SubXactCallbackItem *item;
3408  SubXactCallbackItem *prev;
3409 
3410  prev = NULL;
3411  for (item = SubXact_callbacks; item; prev = item, item = item->next)
3412  {
3413  if (item->callback == callback && item->arg == arg)
3414  {
3415  if (prev)
3416  prev->next = item->next;
3417  else
3418  SubXact_callbacks = item->next;
3419  pfree(item);
3420  break;
3421  }
3422  }
3423 }
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:276
void pfree(void *pointer)
Definition: mcxt.c:1031
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
struct SubXactCallbackItem * next
Definition: xact.c:271
void * arg

◆ UnregisterXactCallback()

void UnregisterXactCallback ( XactCallback  callback,
void *  arg 
)

Definition at line 3350 of file xact.c.

References XactCallbackItem::next, and pfree().

3351 {
3352  XactCallbackItem *item;
3353  XactCallbackItem *prev;
3354 
3355  prev = NULL;
3356  for (item = Xact_callbacks; item; prev = item, item = item->next)
3357  {
3358  if (item->callback == callback && item->arg == arg)
3359  {
3360  if (prev)
3361  prev->next = item->next;
3362  else
3363  Xact_callbacks = item->next;
3364  pfree(item);
3365  break;
3366  }
3367  }
3368 }
struct XactCallbackItem * next
Definition: xact.c:259
void pfree(void *pointer)
Definition: mcxt.c:1031
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
static XactCallbackItem * Xact_callbacks
Definition: xact.c:264
void * arg

◆ UserAbortTransactionBlock()

void UserAbortTransactionBlock ( void  )

Definition at line 3703 of file xact.c.

References TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg(), FATAL, 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().

3704 {
3706 
3707  switch (s->blockState)
3708  {
3709  /*
3710  * We are inside a transaction block and we got a ROLLBACK command
3711  * from the user, so tell CommitTransactionCommand to abort and
3712  * exit the transaction block.
3713  */
3714  case TBLOCK_INPROGRESS:
3716  break;
3717 
3718  /*
3719  * We are inside a failed transaction block and we got a ROLLBACK
3720  * command from the user. Abort processing is already done, so
3721  * CommitTransactionCommand just has to cleanup and go back to
3722  * idle state.
3723  */
3724  case TBLOCK_ABORT:
3726  break;
3727 
3728  /*
3729  * We are inside a subtransaction. Mark everything up to top
3730  * level as exitable.
3731  */
3732  case TBLOCK_SUBINPROGRESS:
3733  case TBLOCK_SUBABORT:
3734  while (s->parent != NULL)
3735  {
3736  if (s->blockState == TBLOCK_SUBINPROGRESS)
3738  else if (s->blockState == TBLOCK_SUBABORT)
3740  else
3741  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3743  s = s->parent;
3744  }
3745  if (s->blockState == TBLOCK_INPROGRESS)
3747  else if (s->blockState == TBLOCK_ABORT)
3749  else
3750  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3752  break;
3753 
3754  /*
3755  * The user issued ABORT when not inside a transaction. Issue a
3756  * WARNING and go to abort state. The upcoming call to
3757  * CommitTransactionCommand() will then put us back into the
3758  * default state.
3759  *
3760  * We do the same thing with ABORT inside an implicit transaction,
3761  * although in this case we might be rolling back actual database
3762  * state changes. (It's debatable whether we should issue a
3763  * WARNING in this case, but we have done so historically.)
3764  */
3765  case TBLOCK_STARTED:
3767  ereport(WARNING,
3768  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3769  errmsg("there is no transaction in progress")));
3771  break;
3772 
3773  /*
3774  * The user issued an ABORT that somehow ran inside a parallel
3775  * worker. We can't cope with that.
3776  */
3778  ereport(FATAL,
3779  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3780  errmsg("cannot abort during a parallel operation")));
3781  break;
3782 
3783  /* These cases are invalid. */
3784  case TBLOCK_DEFAULT:
3785  case TBLOCK_BEGIN:
3786  case TBLOCK_SUBBEGIN:
3787  case TBLOCK_END:
3788  case TBLOCK_SUBRELEASE:
3789  case TBLOCK_SUBCOMMIT:
3790  case TBLOCK_ABORT_END:
3791  case TBLOCK_SUBABORT_END:
3792  case TBLOCK_ABORT_PENDING:
3794  case TBLOCK_SUBRESTART:
3796  case TBLOCK_PREPARE:
3797  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3799  break;
3800  }
3801 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
int errcode(int sqlerrcode)
Definition: elog.c:570
TBlockState blockState
Definition: xact.c:179
#define FATAL
Definition: elog.h:52
struct TransactionStateData * parent
Definition: xact.c:193
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5169
#define ereport(elevel, rest)
Definition: elog.h:141
#define WARNING
Definition: elog.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226

◆ WarnNoTransactionBlock()

void WarnNoTransactionBlock ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3248 of file xact.c.

References CheckTransactionBlock().

Referenced by ExecSetVariableStmt(), and standard_ProcessUtility().

3249 {
3250  CheckTransactionBlock(isTopLevel, false, stmtType);
3251 }
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3263

◆ xact_desc()

void xact_desc ( StringInfo  buf,
XLogReaderState record 
)

Definition at line 308 of file xactdesc.c.

References appendStringInfo(), xact_desc_abort(), xact_desc_assignment(), xact_desc_commit(), XLOG_XACT_ABORT, XLOG_XACT_ABORT_PREPARED, XLOG_XACT_ASSIGNMENT, XLOG_XACT_COMMIT, XLOG_XACT_COMMIT_PREPARED, XLOG_XACT_OPMASK, XLogRecGetData, XLogRecGetInfo, XLogRecGetOrigin, and xl_xact_assignment::xtop.

309 {
310  char *rec = XLogRecGetData(record);
311  uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
312 
313  if (info == XLOG_XACT_COMMIT || info == XLOG_XACT_COMMIT_PREPARED)
314  {
315  xl_xact_commit *xlrec = (xl_xact_commit *) rec;
316 
317  xact_desc_commit(buf, XLogRecGetInfo(record), xlrec,
318  XLogRecGetOrigin(record));
319  }
320  else if (info == XLOG_XACT_ABORT || info == XLOG_XACT_ABORT_PREPARED)
321  {
322  xl_xact_abort *xlrec = (xl_xact_abort *) rec;
323 
324  xact_desc_abort(buf, XLogRecGetInfo(record), xlrec);
325  }
326  else if (info == XLOG_XACT_ASSIGNMENT)
327  {
328  xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
329 
330  /*
331  * Note that we ignore the WAL record's xid, since we're more
332  * interested in the top-level xid that issued the record and which
333  * xids are being reported here.
334  */
335  appendStringInfo(buf, "xtop %u: ", xlrec->xtop);
336  xact_desc_assignment(buf, xlrec);
337  }
338 }
#define XLOG_XACT_COMMIT
Definition: xact.h:139
unsigned char uint8
Definition: c.h:356
TransactionId xtop
Definition: xact.h:189
#define XLogRecGetOrigin(decoder)
Definition: xlogreader.h:232
#define XLogRecGetData(decoder)
Definition: xlogreader.h:233
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define XLOG_XACT_ABORT_PREPARED
Definition: xact.h:143
static void xact_desc_abort(StringInfo buf, uint8 info, xl_xact_abort *xlrec)
Definition: xactdesc.c:264
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:229
#define XLOG_XACT_ASSIGNMENT
Definition: xact.h:144
#define XLOG_XACT_ABORT
Definition: xact.h:141
#define XLOG_XACT_OPMASK
Definition: xact.h:149
static void xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
Definition: xactdesc.c:297
#define XLOG_XACT_COMMIT_PREPARED
Definition: xact.h:142
static void xact_desc_commit(StringInfo buf, uint8 info, xl_xact_commit *xlrec, RepOriginId origin_id)
Definition: xactdesc.c:213

◆ xact_identify()

const char* xact_identify ( uint8  info)

Definition at line 341 of file xactdesc.c.

References XLOG_XACT_ABORT, XLOG_XACT_ABORT_PREPARED, XLOG_XACT_ASSIGNMENT, XLOG_XACT_COMMIT, XLOG_XACT_COMMIT_PREPARED, XLOG_XACT_OPMASK, and XLOG_XACT_PREPARE.

342 {
343  const char *id = NULL;
344 
345  switch (info & XLOG_XACT_OPMASK)
346  {
347  case XLOG_XACT_COMMIT:
348  id = "COMMIT";
349  break;
350  case XLOG_XACT_PREPARE:
351  id = "PREPARE";
352  break;
353  case XLOG_XACT_ABORT:
354  id = "ABORT";
355  break;
357  id = "COMMIT_PREPARED";
358  break;
360  id = "ABORT_PREPARED";
361  break;
363  id = "ASSIGNMENT";
364  break;
365  }
366 
367  return id;
368 }
#define XLOG_XACT_COMMIT
Definition: xact.h:139
#define XLOG_XACT_PREPARE
Definition: xact.h:140
#define XLOG_XACT_ABORT_PREPARED
Definition: xact.h:143
#define XLOG_XACT_ASSIGNMENT
Definition: xact.h:144
#define XLOG_XACT_ABORT
Definition: xact.h:141
#define XLOG_XACT_OPMASK
Definition: xact.h:149
#define XLOG_XACT_COMMIT_PREPARED
Definition: xact.h:142

◆ xact_redo()

void xact_redo ( XLogReaderState record)

Definition at line 5789 of file xact.c.

References Assert, elog, XLogReaderState::EndRecPtr, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), xl_xact_assignment::nsubxacts, PANIC, ParseAbortRecord(), ParseCommitRecord(), PrepareRedoAdd(), PrepareRedoRemove(), ProcArrayApplyXidAssignment(), XLogReaderState::ReadRecPtr, STANDBY_INITIALIZED, standbyState, xl_xact_parsed_commit::twophase_xid, xl_xact_parsed_abort::twophase_xid, 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_OPMASK, XLOG_XACT_PREPARE, XLogRecGetData, XLogRecGetInfo, XLogRecGetOrigin, XLogRecGetXid, XLogRecHasAnyBlockRefs, xl_xact_assignment::xsub, and xl_xact_assignment::xtop.

5790 {
5791  uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
5792 
5793  /* Backup blocks are not used in xact records */
5794  Assert(!XLogRecHasAnyBlockRefs(record));
5795 
5796  if (info == XLOG_XACT_COMMIT)
5797  {
5798  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
5799  xl_xact_parsed_commit parsed;
5800 
5801  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
5802  xact_redo_commit(&parsed, XLogRecGetXid(record),
5803  record->EndRecPtr, XLogRecGetOrigin(record));
5804  }
5805  else if (info == XLOG_XACT_COMMIT_PREPARED)
5806  {
5807  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
5808  xl_xact_parsed_commit parsed;
5809 
5810  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
5811  xact_redo_commit(&parsed, parsed.twophase_xid,
5812  record->EndRecPtr, XLogRecGetOrigin(record));
5813 
5814  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
5815  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5816  PrepareRedoRemove(parsed.twophase_xid, false);
5817  LWLockRelease(TwoPhaseStateLock);
5818  }
5819  else if (info == XLOG_XACT_ABORT)
5820  {
5821  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
5822  xl_xact_parsed_abort parsed;
5823 
5824  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
5825  xact_redo_abort(&parsed, XLogRecGetXid(record));
5826  }
5827  else if (info == XLOG_XACT_ABORT_PREPARED)
5828  {
5829  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
5830  xl_xact_parsed_abort parsed;
5831 
5832  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
5833  xact_redo_abort(&parsed, parsed.twophase_xid);
5834 
5835  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
5836  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5837  PrepareRedoRemove(parsed.twophase_xid, false);
5838  LWLockRelease(TwoPhaseStateLock);
5839  }
5840  else if (info == XLOG_XACT_PREPARE)
5841  {
5842  /*
5843  * Store xid and start/end pointers of the WAL record in TwoPhaseState
5844  * gxact entry.
5845  */
5846  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5848  record->ReadRecPtr,
5849  record->EndRecPtr,
5850  XLogRecGetOrigin(record));
5851  LWLockRelease(TwoPhaseStateLock);
5852  }
5853  else if (info == XLOG_XACT_ASSIGNMENT)
5854  {
5856 
5859  xlrec->nsubxacts, xlrec->xsub);
5860  }
5861  else
5862  elog(PANIC, "xact_redo: unknown op code %u", info);
5863 }
#define XLOG_XACT_COMMIT
Definition: xact.h:139
void PrepareRedoRemove(TransactionId xid, bool giveWarning)
Definition: twophase.c:2459
#define XLOG_XACT_PREPARE
Definition: xact.h:140
static void xact_redo_commit(xl_xact_parsed_commit *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:5557
TransactionId twophase_xid
Definition: xact.h:313
unsigned char uint8
Definition: c.h:356
TransactionId xtop
Definition: xact.h:189
TransactionId xsub[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:191
#define PANIC
Definition: elog.h:53
#define XLogRecGetOrigin(decoder)
Definition: xlogreader.h:232
XLogRecPtr EndRecPtr
Definition: xlogreader.h:120
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
#define XLogRecGetData(decoder)
Definition: xlogreader.h:233
void ParseCommitRecord(uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *parsed)
Definition: xactdesc.c:34
#define XLOG_XACT_ABORT_PREPARED
Definition: xact.h:143
XLogRecPtr ReadRecPtr
Definition: xlogreader.h:119
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:229
#define XLogRecGetXid(decoder)
Definition: xlogreader.h:231
#define XLOG_XACT_ASSIGNMENT
Definition: xact.h:144
static void xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid)
Definition: xact.c:5719
void PrepareRedoAdd(char *buf, XLogRecPtr start_lsn, XLogRecPtr end_lsn, RepOriginId origin_id)
Definition: twophase.c:2389
TransactionId twophase_xid
Definition: xact.h:338
#define Assert(condition)
Definition: c.h:732
#define XLOG_XACT_ABORT
Definition: xact.h:141
#define XLOG_XACT_OPMASK
Definition: xact.h:149
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1121
void ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed)
Definition: xactdesc.c:129
#define elog(elevel,...)
Definition: elog.h:226
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:235
void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)
Definition: procarray.c:918
#define XLOG_XACT_COMMIT_PREPARED
Definition: xact.h:142
HotStandbyState standbyState
Definition: xlog.c:199

◆ xactGetCommittedChildren()

int xactGetCommittedChildren ( TransactionId **  ptr)

Definition at line 5252 of file xact.c.

References TransactionStateData::childXids, CurrentTransactionState, and TransactionStateData::nChildXids.

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

5253 {
5255 
5256  if (s->nChildXids == 0)
5257  *ptr = NULL;
5258  else
5259  *ptr = s->childXids;
5260 
5261  return s->nChildXids;
5262 }
static TransactionState CurrentTransactionState
Definition: xact.c:215
TransactionId * childXids
Definition: xact.c:184

◆ XactLogAbortRecord()

XLogRecPtr XactLogAbortRecord ( TimestampTz  abort_time,
int  nsubxacts,
TransactionId subxacts,
int  nrels,
RelFileNode rels,
int  xactflags,
TransactionId  twophase_xid,
const char *  twophase_gid 
)

Definition at line 5431 of file xact.c.

References Assert, CritSectionCount, xl_xact_dbinfo::dbId, InvalidRepOriginId, MinSizeOfXactAbort, MinSizeOfXactRelfilenodes, MinSizeOfXactSubxacts, MyDatabaseId, MyDatabaseTableSpace, xl_xact_relfilenodes::nrels, xl_xact_subxacts::nsubxacts, xl_xact_origin::origin_lsn, xl_xact_origin::origin_timestamp, replorigin_session_origin, replorigin_session_origin_lsn, replorigin_session_origin_timestamp, TransactionIdIsValid, xl_xact_dbinfo::tsId, unconstify, XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK, xl_xact_abort::xact_time, XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_DBINFO, XACT_XINFO_HAS_GID, XACT_XINFO_HAS_ORIGIN, XACT_XINFO_HAS_RELFILENODES, XACT_XINFO_HAS_SUBXACTS, XACT_XINFO_HAS_TWOPHASE, xl_xact_twophase::xid, xl_xact_xinfo::xinfo, XLOG_INCLUDE_ORIGIN, XLOG_XACT_ABORT, XLOG_XACT_ABORT_PREPARED, XLOG_XACT_HAS_INFO, XLogBeginInsert(), XLogInsert(), XLogLogicalInfoActive, XLogRegisterData(), and XLogSetRecordFlags().

Referenced by RecordTransactionAbort(), and RecordTransactionAbortPrepared().

5436 {
5437  xl_xact_abort xlrec;
5438  xl_xact_xinfo xl_xinfo;
5439  xl_xact_subxacts xl_subxacts;
5440  xl_xact_relfilenodes xl_relfilenodes;
5441  xl_xact_twophase xl_twophase;
5442  xl_xact_dbinfo xl_dbinfo;
5443  xl_xact_origin xl_origin;
5444 
5445  uint8 info;
5446 
5447  Assert(CritSectionCount > 0);
5448 
5449  xl_xinfo.xinfo = 0;
5450 
5451  /* decide between a plain and 2pc abort */
5452  if (!TransactionIdIsValid(twophase_xid))
5453  info = XLOG_XACT_ABORT;
5454  else
5455  info = XLOG_XACT_ABORT_PREPARED;
5456 
5457 
5458  /* First figure out and collect all the information needed */
5459 
5460  xlrec.xact_time = abort_time;
5461 
5462  if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5463  xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5464 
5465  if (nsubxacts > 0)
5466  {
5467  xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5468  xl_subxacts.nsubxacts = nsubxacts;
5469  }
5470 
5471  if (nrels > 0)
5472  {
5473  xl_xinfo.xinfo |= XACT_XINFO_HAS_RELFILENODES;
5474  xl_relfilenodes.nrels = nrels;
5475  }
5476 
5477  if (TransactionIdIsValid(twophase_xid))
5478  {
5479  xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5480  xl_twophase.xid = twophase_xid;
5481  Assert(twophase_gid != NULL);
5482 
5483  if (XLogLogicalInfoActive())
5484  xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
5485  }
5486 
5487  if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
5488  {
5489  xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5490  xl_dbinfo.dbId = MyDatabaseId;
5491  xl_dbinfo.tsId = MyDatabaseTableSpace;
5492  }
5493 
5494  /* dump transaction origin information only for abort prepared */
5496  TransactionIdIsValid(twophase_xid) &&
5498  {
5499  xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
5500 
5503  }
5504 
5505  if (xl_xinfo.xinfo != 0)
5506  info |= XLOG_XACT_HAS_INFO;
5507 
5508  /* Then include all the collected data into the abort record. */
5509 
5510  XLogBeginInsert();
5511 
5512  XLogRegisterData((char *) (&xlrec), MinSizeOfXactAbort);
5513 
5514  if (xl_xinfo.xinfo != 0)
5515  XLogRegisterData((char *) (&xl_xinfo), sizeof(xl_xinfo));
5516 
5517  if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5518  XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
5519 
5520  if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5521  {
5522  XLogRegisterData((char *) (&xl_subxacts),
5524  XLogRegisterData((char *) subxacts,
5525  nsubxacts * sizeof(TransactionId));
5526  }
5527 
5528  if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILENODES)
5529  {
5530  XLogRegisterData((char *) (&xl_relfilenodes),
5532  XLogRegisterData((char *) rels,
5533  nrels * sizeof(RelFileNode));
5534  }
5535 
5536