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_ACCESSEDTEMPREL   (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 290 of file xact.h.

Referenced by ParseAbortRecord(), and XactLogAbortRecord().

◆ MinSizeOfXactAssignment

#define MinSizeOfXactAssignment   offsetof(xl_xact_assignment, xsub)

Definition at line 195 of file xact.h.

Referenced by AssignTransactionId().

◆ MinSizeOfXactCommit

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

Definition at line 275 of file xact.h.

Referenced by ParseCommitRecord().

◆ MinSizeOfXactInvals

#define MinSizeOfXactInvals   offsetof(xl_xact_invals, msgs)

Definition at line 249 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 176 of file xact.h.

Referenced by XactLogCommitRecord().

◆ XACT_COMPLETION_FORCE_SYNC_COMMIT

#define XACT_COMPLETION_FORCE_SYNC_COMMIT   (1U << 31)

Definition at line 178 of file xact.h.

Referenced by XactLogCommitRecord().

◆ XACT_COMPLETION_UPDATE_RELCACHE_FILE

#define XACT_COMPLETION_UPDATE_RELCACHE_FILE   (1U << 30)

Definition at line 177 of file xact.h.

Referenced by XactLogCommitRecord().

◆ XACT_FLAGS_ACCESSEDTEMPREL

#define XACT_FLAGS_ACCESSEDTEMPREL   (1U << 0)

◆ 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 165 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 162 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 181 of file xact.h.

Referenced by xact_redo_commit().

◆ XactCompletionForceSyncCommit

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

Definition at line 185 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 183 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 145 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 141 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 127 of file xact.h.

◆ XactCallback

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

Definition at line 117 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 119 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 105 of file xact.h.

Function Documentation

◆ AbortCurrentTransaction()

void AbortCurrentTransaction ( void  )

Definition at line 3003 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().

3004 {
3006 
3007  switch (s->blockState)
3008  {
3009  case TBLOCK_DEFAULT:
3010  if (s->state == TRANS_DEFAULT)
3011  {
3012  /* we are idle, so nothing to do */
3013  }
3014  else
3015  {
3016  /*
3017  * We can get here after an error during transaction start
3018  * (state will be TRANS_START). Need to clean up the
3019  * incompletely started transaction. First, adjust the
3020  * low-level state to suppress warning message from
3021  * AbortTransaction.
3022  */
3023  if (s->state == TRANS_START)
3024  s->state = TRANS_INPROGRESS;
3025  AbortTransaction();
3027  }
3028  break;
3029 
3030  /*
3031  * If we aren't in a transaction block, we just do the basic abort
3032  * & cleanup transaction. For this purpose, we treat an implicit
3033  * transaction block as if it were a simple statement.
3034  */
3035  case TBLOCK_STARTED:
3037  AbortTransaction();
3040  break;
3041 
3042  /*
3043  * If we are in TBLOCK_BEGIN it means something screwed up right
3044  * after reading "BEGIN TRANSACTION". We assume that the user
3045  * will interpret the error as meaning the BEGIN failed to get him
3046  * into a transaction block, so we should abort and return to idle
3047  * state.
3048  */
3049  case TBLOCK_BEGIN:
3050  AbortTransaction();
3053  break;
3054 
3055  /*
3056  * We are somewhere in a transaction block and we've gotten a
3057  * failure, so we abort the transaction and set up the persistent
3058  * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3059  */
3060  case TBLOCK_INPROGRESS:
3062  AbortTransaction();
3063  s->blockState = TBLOCK_ABORT;
3064  /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3065  break;
3066 
3067  /*
3068  * Here, we failed while trying to COMMIT. Clean up the
3069  * transaction and return to idle state (we do not want to stay in
3070  * the transaction).
3071  */
3072  case TBLOCK_END:
3073  AbortTransaction();
3076  break;
3077 
3078  /*
3079  * Here, we are already in an aborted transaction state and are
3080  * waiting for a ROLLBACK, but for some reason we failed again! So
3081  * we just remain in the abort state.
3082  */
3083  case TBLOCK_ABORT:
3084  case TBLOCK_SUBABORT:
3085  break;
3086 
3087  /*
3088  * We are in a failed transaction and we got the ROLLBACK command.
3089  * We have already aborted, we just need to cleanup and go to idle
3090  * state.
3091  */
3092  case TBLOCK_ABORT_END:
3095  break;
3096 
3097  /*
3098  * We are in a live transaction and we got a ROLLBACK command.
3099  * Abort, cleanup, go to idle state.
3100  */
3101  case TBLOCK_ABORT_PENDING:
3102  AbortTransaction();
3105  break;
3106 
3107  /*
3108  * Here, we failed while trying to PREPARE. Clean up the
3109  * transaction and return to idle state (we do not want to stay in
3110  * the transaction).
3111  */
3112  case TBLOCK_PREPARE:
3113  AbortTransaction();
3116  break;
3117 
3118  /*
3119  * We got an error inside a subtransaction. Abort just the
3120  * subtransaction, and go to the persistent SUBABORT state until
3121  * we get ROLLBACK.
3122  */
3123  case TBLOCK_SUBINPROGRESS:
3126  break;
3127 
3128  /*
3129  * If we failed while trying to create a subtransaction, clean up
3130  * the broken subtransaction and abort the parent. The same
3131  * applies if we get a failure while ending a subtransaction.
3132  */
3133  case TBLOCK_SUBBEGIN:
3134  case TBLOCK_SUBRELEASE:
3135  case TBLOCK_SUBCOMMIT:
3137  case TBLOCK_SUBRESTART:
3141  break;
3142 
3143  /*
3144  * Same as above, except the Abort() was already done.
3145  */
3146  case TBLOCK_SUBABORT_END:
3150  break;
3151  }
3152 }
void AbortCurrentTransaction(void)
Definition: xact.c:3003
static TransactionState CurrentTransactionState
Definition: xact.c:214
TBlockState blockState
Definition: xact.c:178
TransState state
Definition: xact.c:177
static void CleanupTransaction(void)
Definition: xact.c:2643
static void AbortSubTransaction(void)
Definition: xact.c:4684
static void AbortTransaction(void)
Definition: xact.c:2462
static void CleanupSubTransaction(void)
Definition: xact.c:4833

◆ AbortOutOfAnyTransaction()

void AbortOutOfAnyTransaction ( void  )

Definition at line 4337 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().

4338 {
4340 
4341  /* Ensure we're not running in a doomed memory context */
4342  AtAbort_Memory();
4343 
4344  /*
4345  * Get out of any transaction or nested transaction
4346  */
4347  do
4348  {
4349  switch (s->blockState)
4350  {
4351  case TBLOCK_DEFAULT:
4352  if (s->state == TRANS_DEFAULT)
4353  {
4354  /* Not in a transaction, do nothing */
4355  }
4356  else
4357  {
4358  /*
4359  * We can get here after an error during transaction start
4360  * (state will be TRANS_START). Need to clean up the
4361  * incompletely started transaction. First, adjust the
4362  * low-level state to suppress warning message from
4363  * AbortTransaction.
4364  */
4365  if (s->state == TRANS_START)
4366  s->state = TRANS_INPROGRESS;
4367  AbortTransaction();
4369  }
4370  break;
4371  case TBLOCK_STARTED:
4372  case TBLOCK_BEGIN:
4373  case TBLOCK_INPROGRESS:
4376  case TBLOCK_END:
4377  case TBLOCK_ABORT_PENDING:
4378  case TBLOCK_PREPARE:
4379  /* In a transaction, so clean up */
4380  AbortTransaction();
4383  break;
4384  case TBLOCK_ABORT:
4385  case TBLOCK_ABORT_END:
4386 
4387  /*
4388  * AbortTransaction is already done, still need Cleanup.
4389  * However, if we failed partway through running ROLLBACK,
4390  * there will be an active portal running that command, which
4391  * we need to shut down before doing CleanupTransaction.
4392  */
4393  AtAbort_Portals();
4396  break;
4397 
4398  /*
4399  * In a subtransaction, so clean it up and abort parent too
4400  */
4401  case TBLOCK_SUBBEGIN:
4402  case TBLOCK_SUBINPROGRESS:
4403  case TBLOCK_SUBRELEASE:
4404  case TBLOCK_SUBCOMMIT:
4406  case TBLOCK_SUBRESTART:
4409  s = CurrentTransactionState; /* changed by pop */
4410  break;
4411 
4412  case TBLOCK_SUBABORT:
4413  case TBLOCK_SUBABORT_END:
4415  /* As above, but AbortSubTransaction already done */
4416  if (s->curTransactionOwner)
4417  {
4418  /* As in TBLOCK_ABORT, might have a live portal to zap */
4423  }
4425  s = CurrentTransactionState; /* changed by pop */
4426  break;
4427  }
4428  } while (s->blockState != TBLOCK_DEFAULT);
4429 
4430  /* Should be out of all subxacts now */
4431  Assert(s->parent == NULL);
4432 
4433  /* If we didn't actually have anything to do, revert to TopMemoryContext */
4434  AtCleanup_Memory();
4435 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
static void AtCleanup_Memory(void)
Definition: xact.c:1728
void AtAbort_Portals(void)
Definition: portalmem.c:772
TBlockState blockState
Definition: xact.c:178
TransState state
Definition: xact.c:177
ResourceOwner curTransactionOwner
Definition: xact.c:182
static void CleanupTransaction(void)
Definition: xact.c:2643
struct TransactionStateData * parent
Definition: xact.c:192
SubTransactionId subTransactionId
Definition: xact.c:174
static void AbortSubTransaction(void)
Definition: xact.c:4684
static void AtAbort_Memory(void)
Definition: xact.c:1638
static void AbortTransaction(void)
Definition: xact.c:2462
#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:4833

◆ BeginImplicitTransactionBlock()

void BeginImplicitTransactionBlock ( void  )

Definition at line 3797 of file xact.c.

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

Referenced by exec_simple_query().

3798 {
3800 
3801  /*
3802  * If we are in STARTED state (that is, no transaction block is open),
3803  * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
3804  * block.
3805  *
3806  * For caller convenience, we consider all other transaction states as
3807  * legal here; otherwise the caller would need its own state check, which
3808  * seems rather pointless.
3809  */
3810  if (s->blockState == TBLOCK_STARTED)
3812 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
TBlockState blockState
Definition: xact.c:178

◆ BeginInternalSubTransaction()

void BeginInternalSubTransaction ( const char *  name)

Definition at line 4165 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().

4166 {
4168 
4169  /*
4170  * Workers synchronize transaction state at the beginning of each parallel
4171  * operation, so we can't account for new subtransactions after that
4172  * point. We might be able to make an exception for the type of
4173  * subtransaction established by this function, which is typically used in
4174  * contexts where we're going to release or roll back the subtransaction
4175  * before proceeding further, so that no enduring change to the
4176  * transaction state occurs. For now, however, we prohibit this case along
4177  * with all the others.
4178  */
4179  if (IsInParallelMode())
4180  ereport(ERROR,
4181  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4182  errmsg("cannot start subtransactions during a parallel operation")));
4183 
4184  switch (s->blockState)
4185  {
4186  case TBLOCK_STARTED:
4187  case TBLOCK_INPROGRESS:
4189  case TBLOCK_END:
4190  case TBLOCK_PREPARE:
4191  case TBLOCK_SUBINPROGRESS:
4192  /* Normal subtransaction start */
4193  PushTransaction();
4194  s = CurrentTransactionState; /* changed by push */
4195 
4196  /*
4197  * Savepoint names, like the TransactionState block itself, live
4198  * in TopTransactionContext.
4199  */
4200  if (name)
4202  break;
4203 
4204  /* These cases are invalid. */
4205  case TBLOCK_DEFAULT:
4206  case TBLOCK_BEGIN:
4208  case TBLOCK_SUBBEGIN:
4209  case TBLOCK_SUBRELEASE:
4210  case TBLOCK_SUBCOMMIT:
4211  case TBLOCK_ABORT:
4212  case TBLOCK_SUBABORT:
4213  case TBLOCK_ABORT_END:
4214  case TBLOCK_SUBABORT_END:
4215  case TBLOCK_ABORT_PENDING:
4217  case TBLOCK_SUBRESTART:
4219  elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4221  break;
4222  }
4223 
4226 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
MemoryContext TopTransactionContext
Definition: mcxt.c:49
void CommitTransactionCommand(void)
Definition: xact.c:2763
int errcode(int sqlerrcode)
Definition: elog.c:572
TBlockState blockState
Definition: xact.c:178
bool IsInParallelMode(void)
Definition: xact.c:909
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5146
#define ereport(elevel, rest)
Definition: elog.h:141
static void PushTransaction(void)
Definition: xact.c:4866
void StartTransactionCommand(void)
Definition: xact.c:2692
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:786
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 3431 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().

3432 {
3434 
3435  switch (s->blockState)
3436  {
3437  /*
3438  * We are not inside a transaction block, so allow one to begin.
3439  */
3440  case TBLOCK_STARTED:
3441  s->blockState = TBLOCK_BEGIN;
3442  break;
3443 
3444  /*
3445  * BEGIN converts an implicit transaction block to a regular one.
3446  * (Note that we allow this even if we've already done some
3447  * commands, which is a bit odd but matches historical practice.)
3448  */
3450  s->blockState = TBLOCK_BEGIN;
3451  break;
3452 
3453  /*
3454  * Already a transaction block in progress.
3455  */
3456  case TBLOCK_INPROGRESS:
3458  case TBLOCK_SUBINPROGRESS:
3459  case TBLOCK_ABORT:
3460  case TBLOCK_SUBABORT:
3461  ereport(WARNING,
3462  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3463  errmsg("there is already a transaction in progress")));
3464  break;
3465 
3466  /* These cases are invalid. */
3467  case TBLOCK_DEFAULT:
3468  case TBLOCK_BEGIN:
3469  case TBLOCK_SUBBEGIN:
3470  case TBLOCK_END:
3471  case TBLOCK_SUBRELEASE:
3472  case TBLOCK_SUBCOMMIT:
3473  case TBLOCK_ABORT_END:
3474  case TBLOCK_SUBABORT_END:
3475  case TBLOCK_ABORT_PENDING:
3477  case TBLOCK_SUBRESTART:
3479  case TBLOCK_PREPARE:
3480  elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3482  break;
3483  }
3484 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
int errcode(int sqlerrcode)
Definition: elog.c:572
TBlockState blockState
Definition: xact.c:178
#define FATAL
Definition: elog.h:52
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5146
#define ereport(elevel, rest)
Definition: elog.h:141
#define WARNING
Definition: elog.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:786
#define elog(elevel,...)
Definition: elog.h:226

◆ CommandCounterIncrement()

void CommandCounterIncrement ( void  )

Definition at line 918 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(), clone_fk_constraints(), 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(), PreCommit_on_commit_actions(), ProcedureCreate(), ProcessUtilitySlow(), recordExtensionInitPrivWorker(), reindex_relation(), RelationSetNewRelfilenode(), RenumberEnumType(), replorigin_create(), replorigin_drop(), ri_PerformCheck(), SetMatViewPopulatedState(), shdepReassignOwned(), SPI_cursor_open_internal(), StoreConstraints(), StorePartitionBound(), and validatePartitionedIndex().

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

◆ CommitTransactionCommand()

void CommitTransactionCommand ( void  )

Definition at line 2763 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().

2764 {
2766 
2767  switch (s->blockState)
2768  {
2769  /*
2770  * These shouldn't happen. TBLOCK_DEFAULT means the previous
2771  * StartTransactionCommand didn't set the STARTED state
2772  * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
2773  * by EndParallelWorkerTransaction(), not this function.
2774  */
2775  case TBLOCK_DEFAULT:
2777  elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2779  break;
2780 
2781  /*
2782  * If we aren't in a transaction block, just do our usual
2783  * transaction commit, and return to the idle state.
2784  */
2785  case TBLOCK_STARTED:
2788  break;
2789 
2790  /*
2791  * We are completing a "BEGIN TRANSACTION" command, so we change
2792  * to the "transaction block in progress" state and return. (We
2793  * assume the BEGIN did nothing to the database, so we need no
2794  * CommandCounterIncrement.)
2795  */
2796  case TBLOCK_BEGIN:
2798  break;
2799 
2800  /*
2801  * This is the case when we have finished executing a command
2802  * someplace within a transaction block. We increment the command
2803  * counter and return.
2804  */
2805  case TBLOCK_INPROGRESS:
2807  case TBLOCK_SUBINPROGRESS:
2809  break;
2810 
2811  /*
2812  * We are completing a "COMMIT" command. Do it and return to the
2813  * idle state.
2814  */
2815  case TBLOCK_END:
2818  break;
2819 
2820  /*
2821  * Here we are in the middle of a transaction block but one of the
2822  * commands caused an abort so we do nothing but remain in the
2823  * abort state. Eventually we will get a ROLLBACK command.
2824  */
2825  case TBLOCK_ABORT:
2826  case TBLOCK_SUBABORT:
2827  break;
2828 
2829  /*
2830  * Here we were in an aborted transaction block and we just got
2831  * the ROLLBACK command from the user, so clean up the
2832  * already-aborted transaction and return to the idle state.
2833  */
2834  case TBLOCK_ABORT_END:
2837  break;
2838 
2839  /*
2840  * Here we were in a perfectly good transaction block but the user
2841  * told us to ROLLBACK anyway. We have to abort the transaction
2842  * and then clean up.
2843  */
2844  case TBLOCK_ABORT_PENDING:
2845  AbortTransaction();
2848  break;
2849 
2850  /*
2851  * We are completing a "PREPARE TRANSACTION" command. Do it and
2852  * return to the idle state.
2853  */
2854  case TBLOCK_PREPARE:
2857  break;
2858 
2859  /*
2860  * We were just issued a SAVEPOINT inside a transaction block.
2861  * Start a subtransaction. (DefineSavepoint already did
2862  * PushTransaction, so as to have someplace to put the SUBBEGIN
2863  * state.)
2864  */
2865  case TBLOCK_SUBBEGIN:
2868  break;
2869 
2870  /*
2871  * We were issued a RELEASE command, so we end the current
2872  * subtransaction and return to the parent transaction. The parent
2873  * might be ended too, so repeat till we find an INPROGRESS
2874  * transaction or subtransaction.
2875  */
2876  case TBLOCK_SUBRELEASE:
2877  do
2878  {
2880  s = CurrentTransactionState; /* changed by pop */
2881  } while (s->blockState == TBLOCK_SUBRELEASE);
2882 
2885  break;
2886 
2887  /*
2888  * We were issued a COMMIT, so we end the current subtransaction
2889  * hierarchy and perform final commit. We do this by rolling up
2890  * any subtransactions into their parent, which leads to O(N^2)
2891  * operations with respect to resource owners - this isn't that
2892  * bad until we approach a thousands of savepoints but is
2893  * necessary for correctness should after triggers create new
2894  * resource owners.
2895  */
2896  case TBLOCK_SUBCOMMIT:
2897  do
2898  {
2900  s = CurrentTransactionState; /* changed by pop */
2901  } while (s->blockState == TBLOCK_SUBCOMMIT);
2902  /* If we had a COMMIT command, finish off the main xact too */
2903  if (s->blockState == TBLOCK_END)
2904  {
2905  Assert(s->parent == NULL);
2908  }
2909  else if (s->blockState == TBLOCK_PREPARE)
2910  {
2911  Assert(s->parent == NULL);
2914  }
2915  else
2916  elog(ERROR, "CommitTransactionCommand: unexpected state %s",
2918  break;
2919 
2920  /*
2921  * The current already-failed subtransaction is ending due to a
2922  * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2923  * examine the parent (which could be in any of several states).
2924  */
2925  case TBLOCK_SUBABORT_END:
2928  break;
2929 
2930  /*
2931  * As above, but it's not dead yet, so abort first.
2932  */
2937  break;
2938 
2939  /*
2940  * The current subtransaction is the target of a ROLLBACK TO
2941  * command. Abort and pop it, then start a new subtransaction
2942  * with the same name.
2943  */
2944  case TBLOCK_SUBRESTART:
2945  {
2946  char *name;
2947  int savepointLevel;
2948 
2949  /* save name and keep Cleanup from freeing it */
2950  name = s->name;
2951  s->name = NULL;
2952  savepointLevel = s->savepointLevel;
2953 
2956 
2957  DefineSavepoint(NULL);
2958  s = CurrentTransactionState; /* changed by push */
2959  s->name = name;
2960  s->savepointLevel = savepointLevel;
2961 
2962  /* This is the same as TBLOCK_SUBBEGIN case */
2966  }
2967  break;
2968 
2969  /*
2970  * Same as above, but the subtransaction had already failed, so we
2971  * don't need AbortSubTransaction.
2972  */
2974  {
2975  char *name;
2976  int savepointLevel;
2977 
2978  /* save name and keep Cleanup from freeing it */
2979  name = s->name;
2980  s->name = NULL;
2981  savepointLevel = s->savepointLevel;
2982 
2984 
2985  DefineSavepoint(NULL);
2986  s = CurrentTransactionState; /* changed by push */
2987  s->name = name;
2988  s->savepointLevel = savepointLevel;
2989 
2990  /* This is the same as TBLOCK_SUBBEGIN case */
2994  }
2995  break;
2996  }
2997 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
#define AssertState(condition)
Definition: c.h:735
void CommitTransactionCommand(void)
Definition: xact.c:2763
void DefineSavepoint(const char *name)
Definition: xact.c:3844
TBlockState blockState
Definition: xact.c:178
static void PrepareTransaction(void)
Definition: xact.c:2186
#define ERROR
Definition: elog.h:43
static void CommitSubTransaction(void)
Definition: xact.c:4575
#define FATAL
Definition: elog.h:52
static void CleanupTransaction(void)
Definition: xact.c:2643
struct TransactionStateData * parent
Definition: xact.c:192
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5146
static void AbortSubTransaction(void)
Definition: xact.c:4684
void CommandCounterIncrement(void)
Definition: xact.c:918
static void AbortTransaction(void)
Definition: xact.c:2462
#define Assert(condition)
Definition: c.h:732
static void CleanupSubTransaction(void)
Definition: xact.c:4833
const char * name
Definition: encode.c:521
#define elog(elevel,...)
Definition: elog.h:226
static void CommitTransaction(void)
Definition: xact.c:1949
static void StartSubTransaction(void)
Definition: xact.c:4537

◆ DefineSavepoint()

void DefineSavepoint ( const char *  name)

Definition at line 3844 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().

3845 {
3847 
3848  /*
3849  * Workers synchronize transaction state at the beginning of each parallel
3850  * operation, so we can't account for new subtransactions after that
3851  * point. (Note that this check will certainly error out if s->blockState
3852  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
3853  * below.)
3854  */
3855  if (IsInParallelMode())
3856  ereport(ERROR,
3857  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3858  errmsg("cannot define savepoints during a parallel operation")));
3859 
3860  switch (s->blockState)
3861  {
3862  case TBLOCK_INPROGRESS:
3863  case TBLOCK_SUBINPROGRESS:
3864  /* Normal subtransaction start */
3865  PushTransaction();
3866  s = CurrentTransactionState; /* changed by push */
3867 
3868  /*
3869  * Savepoint names, like the TransactionState block itself, live
3870  * in TopTransactionContext.
3871  */
3872  if (name)
3874  break;
3875 
3876  /*
3877  * We disallow savepoint commands in implicit transaction blocks.
3878  * There would be no great difficulty in allowing them so far as
3879  * this module is concerned, but a savepoint seems inconsistent
3880  * with exec_simple_query's behavior of abandoning the whole query
3881  * string upon error. Also, the point of an implicit transaction
3882  * block (as opposed to a regular one) is to automatically close
3883  * after an error, so it's hard to see how a savepoint would fit
3884  * into that.
3885  *
3886  * The error messages for this are phrased as if there were no
3887  * active transaction block at all, which is historical but
3888  * perhaps could be improved.
3889  */
3891  ereport(ERROR,
3892  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3893  /* translator: %s represents an SQL statement name */
3894  errmsg("%s can only be used in transaction blocks",
3895  "SAVEPOINT")));
3896  break;
3897 
3898  /* These cases are invalid. */
3899  case TBLOCK_DEFAULT:
3900  case TBLOCK_STARTED:
3901  case TBLOCK_BEGIN:
3903  case TBLOCK_SUBBEGIN:
3904  case TBLOCK_END:
3905  case TBLOCK_SUBRELEASE:
3906  case TBLOCK_SUBCOMMIT:
3907  case TBLOCK_ABORT:
3908  case TBLOCK_SUBABORT:
3909  case TBLOCK_ABORT_END:
3910  case TBLOCK_SUBABORT_END:
3911  case TBLOCK_ABORT_PENDING:
3913  case TBLOCK_SUBRESTART:
3915  case TBLOCK_PREPARE:
3916  elog(FATAL, "DefineSavepoint: unexpected state %s",
3918  break;
3919  }
3920 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
MemoryContext TopTransactionContext
Definition: mcxt.c:49
int errcode(int sqlerrcode)
Definition: elog.c:572
TBlockState blockState
Definition: xact.c:178
bool IsInParallelMode(void)
Definition: xact.c:909
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5146
#define ereport(elevel, rest)
Definition: elog.h:141
static void PushTransaction(void)
Definition: xact.c:4866
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:786
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 3822 of file xact.c.

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

Referenced by exec_simple_query().

3823 {
3825 
3826  /*
3827  * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
3828  * allowing CommitTransactionCommand to commit whatever happened during
3829  * the implicit transaction block as though it were a single statement.
3830  *
3831  * For caller convenience, we consider all other transaction states as
3832  * legal here; otherwise the caller would need its own state check, which
3833  * seems rather pointless.
3834  */
3837 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
TBlockState blockState
Definition: xact.c:178

◆ EndParallelWorkerTransaction()

void EndParallelWorkerTransaction ( void  )

Definition at line 5083 of file xact.c.

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

Referenced by ParallelWorkerMain().

5084 {
5088 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
TBlockState blockState
Definition: xact.c:178
#define Assert(condition)
Definition: c.h:732
static void CommitTransaction(void)
Definition: xact.c:1949

◆ EndTransactionBlock()

bool EndTransactionBlock ( void  )

Definition at line 3551 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().

3552 {
3554  bool result = false;
3555 
3556  switch (s->blockState)
3557  {
3558  /*
3559  * We are in a transaction block, so tell CommitTransactionCommand
3560  * to COMMIT.
3561  */
3562  case TBLOCK_INPROGRESS:
3563  s->blockState = TBLOCK_END;
3564  result = true;
3565  break;
3566 
3567  /*
3568  * In an implicit transaction block, commit, but issue a warning
3569  * because there was no explicit BEGIN before this.
3570  */
3572  ereport(WARNING,
3573  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3574  errmsg("there is no transaction in progress")));
3575  s->blockState = TBLOCK_END;
3576  result = true;
3577  break;
3578 
3579  /*
3580  * We are in a failed transaction block. Tell
3581  * CommitTransactionCommand it's time to exit the block.
3582  */
3583  case TBLOCK_ABORT:
3585  break;
3586 
3587  /*
3588  * We are in a live subtransaction block. Set up to subcommit all
3589  * open subtransactions and then commit the main transaction.
3590  */
3591  case TBLOCK_SUBINPROGRESS:
3592  while (s->parent != NULL)
3593  {
3594  if (s->blockState == TBLOCK_SUBINPROGRESS)
3596  else
3597  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3599  s = s->parent;
3600  }
3601  if (s->blockState == TBLOCK_INPROGRESS)
3602  s->blockState = TBLOCK_END;
3603  else
3604  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3606  result = true;
3607  break;
3608 
3609  /*
3610  * Here we are inside an aborted subtransaction. Treat the COMMIT
3611  * as ROLLBACK: set up to abort everything and exit the main
3612  * transaction.
3613  */
3614  case TBLOCK_SUBABORT:
3615  while (s->parent != NULL)
3616  {
3617  if (s->blockState == TBLOCK_SUBINPROGRESS)
3619  else if (s->blockState == TBLOCK_SUBABORT)
3621  else
3622  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3624  s = s->parent;
3625  }
3626  if (s->blockState == TBLOCK_INPROGRESS)
3628  else if (s->blockState == TBLOCK_ABORT)
3630  else
3631  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3633  break;
3634 
3635  /*
3636  * The user issued COMMIT when not inside a transaction. Issue a
3637  * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
3638  * CommitTransactionCommand() will then close the transaction and
3639  * put us back into the default state.
3640  */
3641  case TBLOCK_STARTED:
3642  ereport(WARNING,
3643  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3644  errmsg("there is no transaction in progress")));
3645  result = true;
3646  break;
3647 
3648  /*
3649  * The user issued a COMMIT that somehow ran inside a parallel
3650  * worker. We can't cope with that.
3651  */
3653  ereport(FATAL,
3654  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3655  errmsg("cannot commit during a parallel operation")));
3656  break;
3657 
3658  /* These cases are invalid. */
3659  case TBLOCK_DEFAULT:
3660  case TBLOCK_BEGIN:
3661  case TBLOCK_SUBBEGIN:
3662  case TBLOCK_END:
3663  case TBLOCK_SUBRELEASE:
3664  case TBLOCK_SUBCOMMIT:
3665  case TBLOCK_ABORT_END:
3666  case TBLOCK_SUBABORT_END:
3667  case TBLOCK_ABORT_PENDING:
3669  case TBLOCK_SUBRESTART:
3671  case TBLOCK_PREPARE:
3672  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3674  break;
3675  }
3676 
3677  return result;
3678 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
int errcode(int sqlerrcode)
Definition: elog.c:572
TBlockState blockState
Definition: xact.c:178
#define FATAL
Definition: elog.h:52
struct TransactionStateData * parent
Definition: xact.c:192
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5146
#define ereport(elevel, rest)
Definition: elog.h:141
#define WARNING
Definition: elog.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:786
#define elog(elevel,...)
Definition: elog.h:226

◆ EnterParallelMode()

void EnterParallelMode ( void  )

Definition at line 876 of file xact.c.

References Assert, CurrentTransactionState, and TransactionStateData::parallelModeLevel.

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

877 {
879 
880  Assert(s->parallelModeLevel >= 0);
881 
882  ++s->parallelModeLevel;
883 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
int parallelModeLevel
Definition: xact.c:191
#define Assert(condition)
Definition: c.h:732

◆ EstimateTransactionStateSpace()

Size EstimateTransactionStateSpace ( void  )

Definition at line 4959 of file xact.c.

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

Referenced by InitializeParallelDSM().

4960 {
4961  TransactionState s;
4962  Size nxids = 6; /* iso level, deferrable, top & current XID,
4963  * command counter, XID count */
4964 
4965  for (s = CurrentTransactionState; s != NULL; s = s->parent)
4966  {
4968  nxids = add_size(nxids, 1);
4969  nxids = add_size(nxids, s->nChildXids);
4970  }
4971 
4972  nxids = add_size(nxids, nParallelCurrentXids);
4973  return mul_size(nxids, sizeof(TransactionId));
4974 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
uint32 TransactionId
Definition: c.h:507
int nParallelCurrentXids
Definition: xact.c:108
struct TransactionStateData * parent
Definition: xact.c:192
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:173
size_t Size
Definition: c.h:466
#define TransactionIdIsValid(xid)
Definition: transam.h:41

◆ ExitParallelMode()

void ExitParallelMode ( void  )

Definition at line 889 of file xact.c.

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

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

890 {
892 
893  Assert(s->parallelModeLevel > 0);
895 
896  --s->parallelModeLevel;
897 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
bool ParallelContextActive(void)
Definition: parallel.c:956
int parallelModeLevel
Definition: xact.c:191
#define Assert(condition)
Definition: c.h:732

◆ ForceSyncCommit()

void ForceSyncCommit ( void  )

Definition at line 966 of file xact.c.

References forceSyncCommit.

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

967 {
968  forceSyncCommit = true;
969 }
static bool forceSyncCommit
Definition: xact.c:244

◆ GetCurrentCommandId()

CommandId GetCurrentCommandId ( bool  used)

Definition at line 661 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().

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

◆ GetCurrentStatementStartTimestamp()

TimestampTz GetCurrentStatementStartTimestamp ( void  )

Definition at line 707 of file xact.c.

References stmtStartTimestamp.

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

708 {
709  return stmtStartTimestamp;
710 }
static TimestampTz stmtStartTimestamp
Definition: xact.c:232

◆ GetCurrentSubTransactionId()

◆ GetCurrentTransactionId()

◆ GetCurrentTransactionIdIfAny()

TransactionId GetCurrentTransactionIdIfAny ( void  )

Definition at line 416 of file xact.c.

References TransactionStateData::transactionId.

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

417 {
419 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
TransactionId transactionId
Definition: xact.c:173

◆ GetCurrentTransactionNestLevel()

◆ GetCurrentTransactionStartTimestamp()

TimestampTz GetCurrentTransactionStartTimestamp ( void  )

◆ GetCurrentTransactionStopTimestamp()

TimestampTz GetCurrentTransactionStopTimestamp ( void  )

Definition at line 719 of file xact.c.

References GetCurrentTimestamp(), and xactStopTimestamp.

Referenced by pgstat_report_stat().

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

◆ GetStableLatestTransactionId()

TransactionId GetStableLatestTransactionId ( void  )

Definition at line 443 of file xact.c.

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

Referenced by xid_age().

444 {
446  static TransactionId stablexid = InvalidTransactionId;
447 
448  if (lxid != MyProc->lxid)
449  {
450  lxid = MyProc->lxid;
451  stablexid = GetTopTransactionIdIfAny();
452  if (!TransactionIdIsValid(stablexid))
453  stablexid = ReadNewTransactionId();
454  }
455 
456  Assert(TransactionIdIsValid(stablexid));
457 
458  return stablexid;
459 }
uint32 TransactionId
Definition: c.h:507
PGPROC * MyProc
Definition: proc.c:67
#define InvalidTransactionId
Definition: transam.h:31
TransactionId ReadNewTransactionId(void)
Definition: varsup.c:250
uint32 LocalTransactionId
Definition: c.h:509
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:386
#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 371 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().

372 {
375  return XactTopTransactionId;
376 }
TransactionId XactTopTransactionId
Definition: xact.c:107
static TransactionStateData TopTransactionStateData
Definition: xact.c:202
#define TransactionIdIsValid(xid)
Definition: transam.h:41
static void AssignTransactionId(TransactionState s)
Definition: xact.c:471

◆ GetTopTransactionIdIfAny()

◆ IsAbortedTransactionBlockState()

◆ IsInParallelMode()

◆ IsInTransactionBlock()

bool IsInTransactionBlock ( bool  isTopLevel)

Definition at line 3286 of file xact.c.

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

Referenced by vacuum().

3287 {
3288  /*
3289  * Return true on same conditions that would make
3290  * PreventInTransactionBlock error out
3291  */
3292  if (IsTransactionBlock())
3293  return true;
3294 
3295  if (IsSubTransaction())
3296  return true;
3297 
3298  if (!isTopLevel)
3299  return true;
3300 
3303  return true;
3304 
3305  return false;
3306 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
TBlockState blockState
Definition: xact.c:178
bool IsTransactionBlock(void)
Definition: xact.c:4441
bool IsSubTransaction(void)
Definition: xact.c:4514

◆ IsSubTransaction()

◆ IsTransactionBlock()

bool IsTransactionBlock ( void  )

Definition at line 4441 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().

4442 {
4444 
4446  return false;
4447 
4448  return true;
4449 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
TBlockState blockState
Definition: xact.c:178

◆ IsTransactionOrTransactionBlock()

bool IsTransactionOrTransactionBlock ( void  )

◆ IsTransactionState()

bool IsTransactionState ( void  )

Definition at line 332 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().

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

◆ MarkCurrentTransactionIdLoggedIfAny()

void MarkCurrentTransactionIdLoggedIfAny ( void  )

Definition at line 427 of file xact.c.

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

Referenced by XLogInsertRecord().

428 {
431 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
TransactionId transactionId
Definition: xact.c:173
#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:164
struct xl_xact_xinfo xl_xact_xinfo
uint32 TransactionId
Definition: c.h:507
TransactionId xid
Definition: xact.h:253
#define MinSizeOfXactAbort
Definition: xact.h:290
#define XLOG_XACT_HAS_INFO
Definition: xact.h:153
#define XACT_XINFO_HAS_SUBXACTS
Definition: xact.h:160
struct xl_xact_dbinfo xl_xact_dbinfo
#define MinSizeOfXactRelfilenodes
Definition: xact.h:242
TimestampTz xact_time
Definition: xact.h:279
Oid tsId
Definition: xact.h:227
struct xl_xact_origin xl_xact_origin
RelFileNode xnodes[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:240
#define MinSizeOfXactSubxacts
Definition: xact.h:235
struct RelFileNode RelFileNode
struct xl_xact_twophase xl_xact_twophase
#define XACT_XINFO_HAS_DBINFO
Definition: xact.h:159
XLogRecPtr origin_lsn
Definition: xact.h:258
TransactionId * subxacts
Definition: xact.h:334
uint32 xinfo
Definition: xact.h:221
XLogRecPtr origin_lsn
Definition: xact.h:342
RelFileNode * xnodes
Definition: xact.h:337
int nsubxacts
Definition: xact.h:232
#define XACT_XINFO_HAS_TWOPHASE
Definition: xact.h:163
Oid dbId
Definition: xact.h:226
TransactionId twophase_xid
Definition: xact.h:339
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
TimestampTz xact_time
Definition: xact.h:327
TimestampTz origin_timestamp
Definition: xact.h:259
#define XACT_XINFO_HAS_RELFILENODES
Definition: xact.h:161
TimestampTz origin_timestamp
Definition: xact.h:343
#define XACT_XINFO_HAS_GID
Definition: xact.h:166
char twophase_gid[GIDSIZE]
Definition: xact.h:340
TransactionId subxacts[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:233

◆ 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:309
#define XACT_XINFO_HAS_ORIGIN
Definition: xact.h:164
struct xl_xact_xinfo xl_xact_xinfo
uint32 TransactionId
Definition: c.h:507
TimestampTz origin_timestamp
Definition: xact.h:320
TransactionId xid
Definition: xact.h:253
TransactionId twophase_xid
Definition: xact.h:314
TransactionId * subxacts
Definition: xact.h:306
#define XLOG_XACT_HAS_INFO
Definition: xact.h:153
SharedInvalidationMessage * msgs
Definition: xact.h:312
XLogRecPtr origin_lsn
Definition: xact.h:319
#define XACT_XINFO_HAS_SUBXACTS
Definition: xact.h:160
struct xl_xact_dbinfo xl_xact_dbinfo
#define MinSizeOfXactRelfilenodes
Definition: xact.h:242
Oid tsId
Definition: xact.h:227
struct xl_xact_origin xl_xact_origin
RelFileNode xnodes[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:240
#define MinSizeOfXactSubxacts
Definition: xact.h:235
#define MinSizeOfXactCommit
Definition: xact.h:275
SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:247
struct RelFileNode RelFileNode
TimestampTz xact_time
Definition: xact.h:264
struct xl_xact_twophase xl_xact_twophase
#define MinSizeOfXactInvals
Definition: xact.h:249
#define XACT_XINFO_HAS_DBINFO
Definition: xact.h:159
XLogRecPtr origin_lsn
Definition: xact.h:258
uint32 xinfo
Definition: xact.h:221
int nsubxacts
Definition: xact.h:232
#define XACT_XINFO_HAS_TWOPHASE
Definition: xact.h:163
Oid dbId
Definition: xact.h:226
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
TimestampTz origin_timestamp
Definition: xact.h:259
#define XACT_XINFO_HAS_INVALS
Definition: xact.h:162
#define XACT_XINFO_HAS_RELFILENODES
Definition: xact.h:161
int nmsgs
Definition: xact.h:246
#define XACT_XINFO_HAS_GID
Definition: xact.h:166
char twophase_gid[GIDSIZE]
Definition: xact.h:315
TransactionId subxacts[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:233
TimestampTz xact_time
Definition: xact.h:299

◆ PrepareTransactionBlock()

bool PrepareTransactionBlock ( const char *  gid)

Definition at line 3499 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().

3500 {
3501  TransactionState s;
3502  bool result;
3503 
3504  /* Set up to commit the current transaction */
3505  result = EndTransactionBlock();
3506 
3507  /* If successful, change outer tblock state to PREPARE */
3508  if (result)
3509  {
3511 
3512  while (s->parent != NULL)
3513  s = s->parent;
3514 
3515  if (s->blockState == TBLOCK_END)
3516  {
3517  /* Save GID where PrepareTransaction can find it again */
3519 
3521  }
3522  else
3523  {
3524  /*
3525  * ignore case where we are not in a transaction;
3526  * EndTransactionBlock already issued a warning.
3527  */
3530  /* Don't send back a PREPARE result tag... */
3531  result = false;
3532  }
3533  }
3534 
3535  return result;
3536 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
MemoryContext TopTransactionContext
Definition: mcxt.c:49
bool EndTransactionBlock(void)
Definition: xact.c:3551
TBlockState blockState
Definition: xact.c:178
struct TransactionStateData * parent
Definition: xact.c:192
#define Assert(condition)
Definition: c.h:732
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1148
static char * prepareGID
Definition: xact.c:239

◆ PreventInTransactionBlock()

void PreventInTransactionBlock ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3172 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().

3173 {
3174  /*
3175  * xact block already started?
3176  */
3177  if (IsTransactionBlock())
3178  ereport(ERROR,
3179  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3180  /* translator: %s represents an SQL statement name */
3181  errmsg("%s cannot run inside a transaction block",
3182  stmtType)));
3183 
3184  /*
3185  * subtransaction?
3186  */
3187  if (IsSubTransaction())
3188  ereport(ERROR,
3189  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3190  /* translator: %s represents an SQL statement name */
3191  errmsg("%s cannot run inside a subtransaction",
3192  stmtType)));
3193 
3194  /*
3195  * inside a function call?
3196  */
3197  if (!isTopLevel)
3198  ereport(ERROR,
3199  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3200  /* translator: %s represents an SQL statement name */
3201  errmsg("%s cannot be executed from a function", stmtType)));
3202 
3203  /* If we got past IsTransactionBlock test, should be in default state */
3206  elog(FATAL, "cannot prevent transaction chain");
3207  /* all okay */
3208 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
int errcode(int sqlerrcode)
Definition: elog.c:572
TBlockState blockState
Definition: xact.c:178
bool IsTransactionBlock(void)
Definition: xact.c:4441
#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:4514
int errmsg(const char *fmt,...)
Definition: elog.c:786
#define elog(elevel,...)
Definition: elog.h:226

◆ RegisterSubXactCallback()

void RegisterSubXactCallback ( SubXactCallback  callback,
void *  arg 
)

Definition at line 3376 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().

3377 {
3378  SubXactCallbackItem *item;
3379 
3380  item = (SubXactCallbackItem *)
3382  item->callback = callback;
3383  item->arg = arg;
3384  item->next = SubXact_callbacks;
3385  SubXact_callbacks = item;
3386 }
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:275
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
struct SubXactCallbackItem * next
Definition: xact.c:270
SubXactCallback callback
Definition: xact.c:271
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 3321 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().

3322 {
3323  XactCallbackItem *item;
3324 
3325  item = (XactCallbackItem *)
3327  item->callback = callback;
3328  item->arg = arg;
3329  item->next = Xact_callbacks;
3330  Xact_callbacks = item;
3331 }
struct XactCallbackItem * next
Definition: xact.c:258
void * arg
Definition: xact.c:260
XactCallback callback
Definition: xact.c:259
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:263
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:771
void * arg

◆ ReleaseCurrentSubTransaction()

void ReleaseCurrentSubTransaction ( void  )

Definition at line 4236 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().

4237 {
4239 
4240  /*
4241  * Workers synchronize transaction state at the beginning of each parallel
4242  * operation, so we can't account for commit of subtransactions after that
4243  * point. This should not happen anyway. Code calling this would
4244  * typically have called BeginInternalSubTransaction() first, failing
4245  * there.
4246  */
4247  if (IsInParallelMode())
4248  ereport(ERROR,
4249  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4250  errmsg("cannot commit subtransactions during a parallel operation")));
4251 
4252  if (s->blockState != TBLOCK_SUBINPROGRESS)
4253  elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4255  Assert(s->state == TRANS_INPROGRESS);
4258  s = CurrentTransactionState; /* changed by pop */
4259  Assert(s->state == TRANS_INPROGRESS);
4260 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext CurTransactionContext
Definition: mcxt.c:50
int errcode(int sqlerrcode)
Definition: elog.c:572
TBlockState blockState
Definition: xact.c:178
TransState state
Definition: xact.c:177
bool IsInParallelMode(void)
Definition: xact.c:909
#define ERROR
Definition: elog.h:43
static void CommitSubTransaction(void)
Definition: xact.c:4575
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5146
#define ereport(elevel, rest)
Definition: elog.h:141
#define Assert(condition)
Definition: c.h:732
int errmsg(const char *fmt,...)
Definition: elog.c:786
#define elog(elevel,...)
Definition: elog.h:226

◆ ReleaseSavepoint()

void ReleaseSavepoint ( const char *  name)

Definition at line 3929 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().

3930 {
3932  TransactionState target,
3933  xact;
3934 
3935  /*
3936  * Workers synchronize transaction state at the beginning of each parallel
3937  * operation, so we can't account for transaction state change after that
3938  * point. (Note that this check will certainly error out if s->blockState
3939  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
3940  * below.)
3941  */
3942  if (IsInParallelMode())
3943  ereport(ERROR,
3944  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3945  errmsg("cannot release savepoints during a parallel operation")));
3946 
3947  switch (s->blockState)
3948  {
3949  /*
3950  * We can't release a savepoint if there is no savepoint defined.
3951  */
3952  case TBLOCK_INPROGRESS:
3953  ereport(ERROR,
3954  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3955  errmsg("savepoint \"%s\" does not exist", name)));
3956  break;
3957 
3959  /* See comment about implicit transactions in DefineSavepoint */
3960  ereport(ERROR,
3961  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3962  /* translator: %s represents an SQL statement name */
3963  errmsg("%s can only be used in transaction blocks",
3964  "RELEASE SAVEPOINT")));
3965  break;
3966 
3967  /*
3968  * We are in a non-aborted subtransaction. This is the only valid
3969  * case.
3970  */
3971  case TBLOCK_SUBINPROGRESS:
3972  break;
3973 
3974  /* These cases are invalid. */
3975  case TBLOCK_DEFAULT:
3976  case TBLOCK_STARTED:
3977  case TBLOCK_BEGIN:
3979  case TBLOCK_SUBBEGIN:
3980  case TBLOCK_END:
3981  case TBLOCK_SUBRELEASE:
3982  case TBLOCK_SUBCOMMIT:
3983  case TBLOCK_ABORT:
3984  case TBLOCK_SUBABORT:
3985  case TBLOCK_ABORT_END:
3986  case TBLOCK_SUBABORT_END:
3987  case TBLOCK_ABORT_PENDING:
3989  case TBLOCK_SUBRESTART:
3991  case TBLOCK_PREPARE:
3992  elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3994  break;
3995  }
3996 
3997  for (target = s; PointerIsValid(target); target = target->parent)
3998  {
3999  if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4000  break;
4001  }
4002 
4003  if (!PointerIsValid(target))
4004  ereport(ERROR,
4005  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4006  errmsg("savepoint \"%s\" does not exist", name)));
4007 
4008  /* disallow crossing savepoint level boundaries */
4009  if (target->savepointLevel != s->savepointLevel)
4010  ereport(ERROR,
4011  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4012  errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4013 
4014  /*
4015  * Mark "commit pending" all subtransactions up to the target
4016  * subtransaction. The actual commits will happen when control gets to
4017  * CommitTransactionCommand.
4018  */
4019  xact = CurrentTransactionState;
4020  for (;;)
4021  {
4023  xact->blockState = TBLOCK_SUBRELEASE;
4024  if (xact == target)
4025  break;
4026  xact = xact->parent;
4027  Assert(PointerIsValid(xact));
4028  }
4029 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
int errcode(int sqlerrcode)
Definition: elog.c:572
TBlockState blockState
Definition: xact.c:178
bool IsInParallelMode(void)
Definition: xact.c:909
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
struct TransactionStateData * parent
Definition: xact.c:192
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5146
#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:786
#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 3238 of file xact.c.

References CheckTransactionBlock().

Referenced by PerformCursorOpen(), and standard_ProcessUtility().

3239 {
3240  CheckTransactionBlock(isTopLevel, true, stmtType);
3241 }
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3247

◆ RollbackAndReleaseCurrentSubTransaction()

void RollbackAndReleaseCurrentSubTransaction ( void  )

Definition at line 4270 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().

4271 {
4273 
4274  /*
4275  * Unlike ReleaseCurrentSubTransaction(), this is nominally permitted
4276  * during parallel operations. That's because we may be in the master,
4277  * recovering from an error thrown while we were in parallel mode. We
4278  * won't reach here in a worker, because BeginInternalSubTransaction()
4279  * will have failed.
4280  */
4281 
4282  switch (s->blockState)
4283  {
4284  /* Must be in a subtransaction */
4285  case TBLOCK_SUBINPROGRESS:
4286  case TBLOCK_SUBABORT:
4287  break;
4288 
4289  /* These cases are invalid. */
4290  case TBLOCK_DEFAULT:
4291  case TBLOCK_STARTED:
4292  case TBLOCK_BEGIN:
4295  case TBLOCK_SUBBEGIN:
4296  case TBLOCK_INPROGRESS:
4297  case TBLOCK_END:
4298  case TBLOCK_SUBRELEASE:
4299  case TBLOCK_SUBCOMMIT:
4300  case TBLOCK_ABORT:
4301  case TBLOCK_ABORT_END:
4302  case TBLOCK_SUBABORT_END:
4303  case TBLOCK_ABORT_PENDING:
4305  case TBLOCK_SUBRESTART:
4307  case TBLOCK_PREPARE:
4308  elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4310  break;
4311  }
4312 
4313  /*
4314  * Abort the current subtransaction, if needed.
4315  */
4316  if (s->blockState == TBLOCK_SUBINPROGRESS)
4318 
4319  /* And clean it up, too */
4321 
4322  s = CurrentTransactionState; /* changed by pop */
4324  s->blockState == TBLOCK_INPROGRESS ||
4326  s->blockState == TBLOCK_STARTED);
4327 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
#define AssertState(condition)
Definition: c.h:735
TBlockState blockState
Definition: xact.c:178
#define FATAL
Definition: elog.h:52
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5146
static void AbortSubTransaction(void)
Definition: xact.c:4684
static void CleanupSubTransaction(void)
Definition: xact.c:4833
#define elog(elevel,...)
Definition: elog.h:226

◆ RollbackToSavepoint()

void RollbackToSavepoint ( const char *  name)

Definition at line 4038 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().

4039 {
4041  TransactionState target,
4042  xact;
4043 
4044  /*
4045  * Workers synchronize transaction state at the beginning of each parallel
4046  * operation, so we can't account for transaction state change after that
4047  * point. (Note that this check will certainly error out if s->blockState
4048  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4049  * below.)
4050  */
4051  if (IsInParallelMode())
4052  ereport(ERROR,
4053  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4054  errmsg("cannot rollback to savepoints during a parallel operation")));
4055 
4056  switch (s->blockState)
4057  {
4058  /*
4059  * We can't rollback to a savepoint if there is no savepoint
4060  * defined.
4061  */
4062  case TBLOCK_INPROGRESS:
4063  case TBLOCK_ABORT:
4064  ereport(ERROR,
4065  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4066  errmsg("savepoint \"%s\" does not exist", name)));
4067  break;
4068 
4070  /* See comment about implicit transactions in DefineSavepoint */
4071  ereport(ERROR,
4072  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4073  /* translator: %s represents an SQL statement name */
4074  errmsg("%s can only be used in transaction blocks",
4075  "ROLLBACK TO SAVEPOINT")));
4076  break;
4077 
4078  /*
4079  * There is at least one savepoint, so proceed.
4080  */
4081  case TBLOCK_SUBINPROGRESS:
4082  case TBLOCK_SUBABORT:
4083  break;
4084 
4085  /* These cases are invalid. */
4086  case TBLOCK_DEFAULT:
4087  case TBLOCK_STARTED:
4088  case TBLOCK_BEGIN:
4090  case TBLOCK_SUBBEGIN:
4091  case TBLOCK_END:
4092  case TBLOCK_SUBRELEASE:
4093  case TBLOCK_SUBCOMMIT:
4094  case TBLOCK_ABORT_END:
4095  case TBLOCK_SUBABORT_END:
4096  case TBLOCK_ABORT_PENDING:
4098  case TBLOCK_SUBRESTART:
4100  case TBLOCK_PREPARE:
4101  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4103  break;
4104  }
4105 
4106  for (target = s; PointerIsValid(target); target = target->parent)
4107  {
4108  if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4109  break;
4110  }
4111 
4112  if (!PointerIsValid(target))
4113  ereport(ERROR,
4114  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4115  errmsg("savepoint \"%s\" does not exist", name)));
4116 
4117  /* disallow crossing savepoint level boundaries */
4118  if (target->savepointLevel != s->savepointLevel)
4119  ereport(ERROR,
4120  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4121  errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4122 
4123  /*
4124  * Mark "abort pending" all subtransactions up to the target
4125  * subtransaction. The actual aborts will happen when control gets to
4126  * CommitTransactionCommand.
4127  */
4128  xact = CurrentTransactionState;
4129  for (;;)
4130  {
4131  if (xact == target)
4132  break;
4133  if (xact->blockState == TBLOCK_SUBINPROGRESS)
4135  else if (xact->blockState == TBLOCK_SUBABORT)
4137  else
4138  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4140  xact = xact->parent;
4141  Assert(PointerIsValid(xact));
4142  }
4143 
4144  /* And mark the target as "restart pending" */
4145  if (xact->blockState == TBLOCK_SUBINPROGRESS)
4146  xact->blockState = TBLOCK_SUBRESTART;
4147  else if (xact->blockState == TBLOCK_SUBABORT)
4149  else
4150  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4152 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
int errcode(int sqlerrcode)
Definition: elog.c:572
TBlockState blockState
Definition: xact.c:178
bool IsInParallelMode(void)
Definition: xact.c:909
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
struct TransactionStateData * parent
Definition: xact.c:192
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5146
#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:786
#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 4992 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().

4993 {
4994  TransactionState s;
4995  Size nxids = 0;
4996  Size i = 0;
4997  Size c = 0;
4998  TransactionId *workspace;
4999  TransactionId *result = (TransactionId *) start_address;
5000 
5001  result[c++] = (TransactionId) XactIsoLevel;
5002  result[c++] = (TransactionId) XactDeferrable;
5003  result[c++] = XactTopTransactionId;
5004  result[c++] = CurrentTransactionState->transactionId;
5005  result[c++] = (TransactionId) currentCommandId;
5006  Assert(maxsize >= c * sizeof(TransactionId));
5007 
5008  /*
5009  * If we're running in a parallel worker and launching a parallel worker
5010  * of our own, we can just pass along the information that was passed to
5011  * us.
5012  */
5013  if (nParallelCurrentXids > 0)
5014  {
5015  result[c++] = nParallelCurrentXids;
5016  Assert(maxsize >= (nParallelCurrentXids + c) * sizeof(TransactionId));
5017  memcpy(&result[c], ParallelCurrentXids,
5019  return;
5020  }
5021 
5022  /*
5023  * OK, we need to generate a sorted list of XIDs that our workers should
5024  * view as current. First, figure out how many there are.
5025  */
5026  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5027  {
5029  nxids = add_size(nxids, 1);
5030  nxids = add_size(nxids, s->nChildXids);
5031  }
5032  Assert((c + 1 + nxids) * sizeof(TransactionId) <= maxsize);
5033 
5034  /* Copy them to our scratch space. */
5035  workspace = palloc(nxids * sizeof(TransactionId));
5036  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5037  {
5039  workspace[i++] = s->transactionId;
5040  memcpy(&workspace[i], s->childXids,
5041  s->nChildXids * sizeof(TransactionId));
5042  i += s->nChildXids;
5043  }
5044  Assert(i == nxids);
5045 
5046  /* Sort them. */
5047  qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5048 
5049  /* Copy data into output area. */
5050  result[c++] = (TransactionId) nxids;
5051  memcpy(&result[c], workspace, nxids * sizeof(TransactionId));
5052 }
TransactionId XactTopTransactionId
Definition: xact.c:107
bool XactDeferrable
Definition: xact.c:80
static TransactionState CurrentTransactionState
Definition: xact.c:214
uint32 TransactionId
Definition: c.h:507
int nParallelCurrentXids
Definition: xact.c:108
TransactionId * childXids
Definition: xact.c:183
struct TransactionStateData * parent
Definition: xact.c:192
char * c
Size add_size(Size s1, Size s2)
Definition: shmem.c:475
TransactionId transactionId
Definition: xact.c:173
TransactionId * ParallelCurrentXids
Definition: xact.c:109
#define Assert(condition)
Definition: c.h:732
size_t Size
Definition: c.h:466
int XactIsoLevel
Definition: xact.c:74
void * palloc(Size size)
Definition: mcxt.c:924
int i
#define qsort(a, b, c, d)
Definition: port.h:462
static CommandId currentCommandId
Definition: xact.c:221
#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 733 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().

734 {
735  if (!IsParallelWorker())
737  else
739 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
static TimestampTz stmtStartTimestamp
Definition: xact.c:232
#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 687 of file xact.c.

References Assert, IsParallelWorker, stmtStartTimestamp, and xactStartTimestamp.

Referenced by ParallelWorkerMain().

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

◆ StartParallelWorkerTransaction()

void StartParallelWorkerTransaction ( char *  tstatespace)

Definition at line 5060 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().

5061 {
5062  TransactionId *tstate = (TransactionId *) tstatespace;
5063 
5065  StartTransaction();
5066 
5067  XactIsoLevel = (int) tstate[0];
5068  XactDeferrable = (bool) tstate[1];
5069  XactTopTransactionId = tstate[2];
5071  currentCommandId = tstate[4];
5072  nParallelCurrentXids = (int) tstate[5];
5073  ParallelCurrentXids = &tstate[6];
5074 
5076 }
TransactionId XactTopTransactionId
Definition: xact.c:107
bool XactDeferrable
Definition: xact.c:80
static TransactionState CurrentTransactionState
Definition: xact.c:214
uint32 TransactionId
Definition: c.h:507
int nParallelCurrentXids
Definition: xact.c:108
char bool
Definition: c.h:308
TBlockState blockState
Definition: xact.c:178
TransactionId transactionId
Definition: xact.c:173
static void StartTransaction(void)
Definition: xact.c:1799
TransactionId * ParallelCurrentXids
Definition: xact.c:109
#define Assert(condition)
Definition: c.h:732
int XactIsoLevel
Definition: xact.c:74
static CommandId currentCommandId
Definition: xact.c:221

◆ StartTransactionCommand()

void StartTransactionCommand ( void  )

Definition at line 2692 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().

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

◆ SubTransactionIsActive()

bool SubTransactionIsActive ( SubTransactionId  subxid)

Definition at line 637 of file xact.c.

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

Referenced by fmgr_sql().

638 {
640 
641  for (s = CurrentTransactionState; s != NULL; s = s->parent)
642  {
643  if (s->state == TRANS_ABORT)
644  continue;
645  if (s->subTransactionId == subxid)
646  return true;
647  }
648  return false;
649 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
TransState state
Definition: xact.c:177
struct TransactionStateData * parent
Definition: xact.c:192
SubTransactionId subTransactionId
Definition: xact.c:174

◆ TransactionBlockStatusCode()

char TransactionBlockStatusCode ( void  )

Definition at line 4473 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().

4474 {
4476 
4477  switch (s->blockState)
4478  {
4479  case TBLOCK_DEFAULT:
4480  case TBLOCK_STARTED:
4481  return 'I'; /* idle --- not in transaction */
4482  case TBLOCK_BEGIN:
4483  case TBLOCK_SUBBEGIN:
4484  case TBLOCK_INPROGRESS:
4487  case TBLOCK_SUBINPROGRESS:
4488  case TBLOCK_END:
4489  case TBLOCK_SUBRELEASE:
4490  case TBLOCK_SUBCOMMIT:
4491  case TBLOCK_PREPARE:
4492  return 'T'; /* in transaction */
4493  case TBLOCK_ABORT:
4494  case TBLOCK_SUBABORT:
4495  case TBLOCK_ABORT_END:
4496  case TBLOCK_SUBABORT_END:
4497  case TBLOCK_ABORT_PENDING:
4499  case TBLOCK_SUBRESTART:
4501  return 'E'; /* in failed transaction */
4502  }
4503 
4504  /* should never get here */
4505  elog(FATAL, "invalid transaction block state: %s",
4507  return 0; /* keep compiler quiet */
4508 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
TBlockState blockState
Definition: xact.c:178
#define FATAL
Definition: elog.h:52
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5146
#define elog(elevel,...)
Definition: elog.h:226

◆ TransactionIdIsCurrentTransactionId()

bool TransactionIdIsCurrentTransactionId ( TransactionId  xid)

Definition at line 769 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().

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

◆ UnregisterSubXactCallback()

void UnregisterSubXactCallback ( SubXactCallback  callback,
void *  arg 
)

Definition at line 3389 of file xact.c.

References SubXactCallbackItem::next, and pfree().

3390 {
3391  SubXactCallbackItem *item;
3392  SubXactCallbackItem *prev;
3393 
3394  prev = NULL;
3395  for (item = SubXact_callbacks; item; prev = item, item = item->next)
3396  {
3397  if (item->callback == callback && item->arg == arg)
3398  {
3399  if (prev)
3400  prev->next = item->next;
3401  else
3402  SubXact_callbacks = item->next;
3403  pfree(item);
3404  break;
3405  }
3406  }
3407 }
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:275
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:270
void * arg

◆ UnregisterXactCallback()

void UnregisterXactCallback ( XactCallback  callback,
void *  arg 
)

Definition at line 3334 of file xact.c.

References XactCallbackItem::next, and pfree().

3335 {
3336  XactCallbackItem *item;
3337  XactCallbackItem *prev;
3338 
3339  prev = NULL;
3340  for (item = Xact_callbacks; item; prev = item, item = item->next)
3341  {
3342  if (item->callback == callback && item->arg == arg)
3343  {
3344  if (prev)
3345  prev->next = item->next;
3346  else
3347  Xact_callbacks = item->next;
3348  pfree(item);
3349  break;
3350  }
3351  }
3352 }
struct XactCallbackItem * next
Definition: xact.c:258
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:263
void * arg

◆ UserAbortTransactionBlock()

void UserAbortTransactionBlock ( void  )

Definition at line 3687 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().

3688 {
3690 
3691  switch (s->blockState)
3692  {
3693  /*
3694  * We are inside a transaction block and we got a ROLLBACK command
3695  * from the user, so tell CommitTransactionCommand to abort and
3696  * exit the transaction block.
3697  */
3698  case TBLOCK_INPROGRESS:
3700  break;
3701 
3702  /*
3703  * We are inside a failed transaction block and we got a ROLLBACK
3704  * command from the user. Abort processing is already done, so
3705  * CommitTransactionCommand just has to cleanup and go back to
3706  * idle state.
3707  */
3708  case TBLOCK_ABORT:
3710  break;
3711 
3712  /*
3713  * We are inside a subtransaction. Mark everything up to top
3714  * level as exitable.
3715  */
3716  case TBLOCK_SUBINPROGRESS:
3717  case TBLOCK_SUBABORT:
3718  while (s->parent != NULL)
3719  {
3720  if (s->blockState == TBLOCK_SUBINPROGRESS)
3722  else if (s->blockState == TBLOCK_SUBABORT)
3724  else
3725  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3727  s = s->parent;
3728  }
3729  if (s->blockState == TBLOCK_INPROGRESS)
3731  else if (s->blockState == TBLOCK_ABORT)
3733  else
3734  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3736  break;
3737 
3738  /*
3739  * The user issued ABORT when not inside a transaction. Issue a
3740  * WARNING and go to abort state. The upcoming call to
3741  * CommitTransactionCommand() will then put us back into the
3742  * default state.
3743  *
3744  * We do the same thing with ABORT inside an implicit transaction,
3745  * although in this case we might be rolling back actual database
3746  * state changes. (It's debatable whether we should issue a
3747  * WARNING in this case, but we have done so historically.)
3748  */
3749  case TBLOCK_STARTED:
3751  ereport(WARNING,
3752  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3753  errmsg("there is no transaction in progress")));
3755  break;
3756 
3757  /*
3758  * The user issued an ABORT that somehow ran inside a parallel
3759  * worker. We can't cope with that.
3760  */
3762  ereport(FATAL,
3763  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3764  errmsg("cannot abort during a parallel operation")));
3765  break;
3766 
3767  /* These cases are invalid. */
3768  case TBLOCK_DEFAULT:
3769  case TBLOCK_BEGIN:
3770  case TBLOCK_SUBBEGIN:
3771  case TBLOCK_END:
3772  case TBLOCK_SUBRELEASE:
3773  case TBLOCK_SUBCOMMIT:
3774  case TBLOCK_ABORT_END:
3775  case TBLOCK_SUBABORT_END:
3776  case TBLOCK_ABORT_PENDING:
3778  case TBLOCK_SUBRESTART:
3780  case TBLOCK_PREPARE:
3781  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3783  break;
3784  }
3785 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
int errcode(int sqlerrcode)
Definition: elog.c:572
TBlockState blockState
Definition: xact.c:178
#define FATAL
Definition: elog.h:52
struct TransactionStateData * parent
Definition: xact.c:192
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5146
#define ereport(elevel, rest)
Definition: elog.h:141
#define WARNING
Definition: elog.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:786
#define elog(elevel,...)
Definition: elog.h:226

◆ WarnNoTransactionBlock()

void WarnNoTransactionBlock ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3232 of file xact.c.

References CheckTransactionBlock().

Referenced by ExecSetVariableStmt(), and standard_ProcessUtility().

3233 {
3234  CheckTransactionBlock(isTopLevel, false, stmtType);
3235 }
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3247

◆ 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:140
unsigned char uint8
Definition: c.h:356
TransactionId xtop
Definition: xact.h:190
#define XLogRecGetOrigin(decoder)
Definition: xlogreader.h:229
#define XLogRecGetData(decoder)
Definition: xlogreader.h:230
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define XLOG_XACT_ABORT_PREPARED
Definition: xact.h:144
static void xact_desc_abort(StringInfo buf, uint8 info, xl_xact_abort *xlrec)
Definition: xactdesc.c:264
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:226
#define XLOG_XACT_ASSIGNMENT
Definition: xact.h:145
#define XLOG_XACT_ABORT
Definition: xact.h:142
#define XLOG_XACT_OPMASK
Definition: xact.h:150
static void xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
Definition: xactdesc.c:297
#define XLOG_XACT_COMMIT_PREPARED
Definition: xact.h:143
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:140
#define XLOG_XACT_PREPARE
Definition: xact.h:141
#define XLOG_XACT_ABORT_PREPARED
Definition: xact.h:144
#define XLOG_XACT_ASSIGNMENT
Definition: xact.h:145
#define XLOG_XACT_ABORT
Definition: xact.h:142
#define XLOG_XACT_OPMASK
Definition: xact.h:150
#define XLOG_XACT_COMMIT_PREPARED
Definition: xact.h:143

◆ xact_redo()

void xact_redo ( XLogReaderState record)

Definition at line 5766 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.

5767 {
5768  uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
5769 
5770  /* Backup blocks are not used in xact records */
5771  Assert(!XLogRecHasAnyBlockRefs(record));
5772 
5773  if (info == XLOG_XACT_COMMIT)
5774  {
5775  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
5776  xl_xact_parsed_commit parsed;
5777 
5778  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
5779  xact_redo_commit(&parsed, XLogRecGetXid(record),
5780  record->EndRecPtr, XLogRecGetOrigin(record));
5781  }
5782  else if (info == XLOG_XACT_COMMIT_PREPARED)
5783  {
5784  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
5785  xl_xact_parsed_commit parsed;
5786 
5787  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
5788  xact_redo_commit(&parsed, parsed.twophase_xid,
5789  record->EndRecPtr, XLogRecGetOrigin(record));
5790 
5791  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
5792  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5793  PrepareRedoRemove(parsed.twophase_xid, false);
5794  LWLockRelease(TwoPhaseStateLock);
5795  }
5796  else if (info == XLOG_XACT_ABORT)
5797  {
5798  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
5799  xl_xact_parsed_abort parsed;
5800 
5801  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
5802  xact_redo_abort(&parsed, XLogRecGetXid(record));
5803  }
5804  else if (info == XLOG_XACT_ABORT_PREPARED)
5805  {
5806  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
5807  xl_xact_parsed_abort parsed;
5808 
5809  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
5810  xact_redo_abort(&parsed, parsed.twophase_xid);
5811 
5812  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
5813  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5814  PrepareRedoRemove(parsed.twophase_xid, false);
5815  LWLockRelease(TwoPhaseStateLock);
5816  }
5817  else if (info == XLOG_XACT_PREPARE)
5818  {
5819  /*
5820  * Store xid and start/end pointers of the WAL record in TwoPhaseState
5821  * gxact entry.
5822  */
5823  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5825  record->ReadRecPtr,
5826  record->EndRecPtr,
5827  XLogRecGetOrigin(record));
5828  LWLockRelease(TwoPhaseStateLock);
5829  }
5830  else if (info == XLOG_XACT_ASSIGNMENT)
5831  {
5833 
5836  xlrec->nsubxacts, xlrec->xsub);
5837  }
5838  else
5839  elog(PANIC, "xact_redo: unknown op code %u", info);
5840 }
#define XLOG_XACT_COMMIT
Definition: xact.h:140
void PrepareRedoRemove(TransactionId xid, bool giveWarning)
Definition: twophase.c:2459
#define XLOG_XACT_PREPARE
Definition: xact.h:141
static void xact_redo_commit(xl_xact_parsed_commit *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:5534
TransactionId twophase_xid
Definition: xact.h:314
unsigned char uint8
Definition: c.h:356
TransactionId xtop
Definition: xact.h:190
TransactionId xsub[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:192
#define PANIC
Definition: elog.h:53
#define XLogRecGetOrigin(decoder)
Definition: xlogreader.h:229
XLogRecPtr EndRecPtr
Definition: xlogreader.h:120
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1725
#define XLogRecGetData(decoder)
Definition: xlogreader.h:230
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:144
XLogRecPtr ReadRecPtr
Definition: xlogreader.h:119
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:226
#define XLogRecGetXid(decoder)
Definition: xlogreader.h:228
#define XLOG_XACT_ASSIGNMENT
Definition: xact.h:145
static void xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid)
Definition: xact.c:5696
void PrepareRedoAdd(char *buf, XLogRecPtr start_lsn, XLogRecPtr end_lsn, RepOriginId origin_id)
Definition: twophase.c:2389
TransactionId twophase_xid
Definition: xact.h:339
#define Assert(condition)
Definition: c.h:732
#define XLOG_XACT_ABORT
Definition: xact.h:142
#define XLOG_XACT_OPMASK
Definition: xact.h:150
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:232
void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)
Definition: procarray.c:917
#define XLOG_XACT_COMMIT_PREPARED
Definition: xact.h:143
HotStandbyState standbyState
Definition: xlog.c:197

◆ xactGetCommittedChildren()

int xactGetCommittedChildren ( TransactionId **  ptr)

Definition at line 5229 of file xact.c.

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

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

5230 {
5232 
5233  if (s->nChildXids == 0)
5234  *ptr = NULL;
5235  else
5236  *ptr = s->childXids;
5237 
5238  return s->nChildXids;
5239 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
TransactionId * childXids
Definition: xact.c:183

◆ 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 5408 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, 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().

5413 {
5414  xl_xact_abort xlrec;
5415  xl_xact_xinfo xl_xinfo;
5416  xl_xact_subxacts xl_subxacts;
5417  xl_xact_relfilenodes xl_relfilenodes;
5418  xl_xact_twophase xl_twophase;
5419  xl_xact_dbinfo xl_dbinfo;
5420  xl_xact_origin xl_origin;
5421 
5422  uint8 info;
5423 
5424  Assert(CritSectionCount > 0);
5425 
5426  xl_xinfo.xinfo = 0;
5427 
5428  /* decide between a plain and 2pc abort */
5429  if (!TransactionIdIsValid(twophase_xid))
5430  info = XLOG_XACT_ABORT;
5431  else
5432  info = XLOG_XACT_ABORT_PREPARED;
5433 
5434 
5435  /* First figure out and collect all the information needed */
5436 
5437  xlrec.xact_time = abort_time;
5438 
5439  if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5440  xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5441 
5442  if (nsubxacts > 0)
5443  {
5444  xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5445  xl_subxacts.nsubxacts = nsubxacts;
5446  }
5447 
5448  if (nrels > 0)
5449  {
5450  xl_xinfo.xinfo |= XACT_XINFO_HAS_RELFILENODES;
5451  xl_relfilenodes.nrels = nrels;
5452  }
5453 
5454  if (TransactionIdIsValid(twophase_xid))
5455  {
5456  xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5457  xl_twophase.xid = twophase_xid;
5458  Assert(twophase_gid != NULL);
5459 
5460  if (XLogLogicalInfoActive())
5461  xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
5462  }
5463 
5464  if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
5465  {
5466  xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5467  xl_dbinfo.dbId = MyDatabaseId;
5468  xl_dbinfo.tsId = MyDatabaseTableSpace;
5469  }
5470 
5471  /* dump transaction origin information only for abort prepared */
5473  TransactionIdIsValid(twophase_xid) &&
5475  {
5476  xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
5477 
5480  }
5481 
5482  if (xl_xinfo.xinfo != 0)
5483  info |= XLOG_XACT_HAS_INFO;
5484 
5485  /* Then include all the collected data into the abort record. */
5486 
5487  XLogBeginInsert();
5488 
5489  XLogRegisterData((char *) (&xlrec), MinSizeOfXactAbort);
5490 
5491  if (xl_xinfo.xinfo != 0)
5492  XLogRegisterData((char *) (&xl_xinfo), sizeof(xl_xinfo));
5493 
5494  if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5495  XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
5496 
5497  if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5498  {
5499  XLogRegisterData((char *) (&xl_subxacts),
5501  XLogRegisterData((char *) subxacts,
5502  nsubxacts * sizeof(TransactionId));
5503  }
5504 
5505  if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILENODES)
5506  {
5507  XLogRegisterData((char *) (&xl_relfilenodes),
5509  XLogRegisterData((char *) rels,
5510  nrels * sizeof(RelFileNode));
5511  }
5512 
5513  if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5514  {
5515  XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
5516  if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
<