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)
 
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 check_XactIsoLevel(), InitPostgres(), and show_XactIsoLevel().

◆ XACT_READ_UNCOMMITTED

#define XACT_READ_UNCOMMITTED   0

Definition at line 35 of file xact.h.

Referenced by check_XactIsoLevel(), and show_XactIsoLevel().

◆ XACT_REPEATABLE_READ

#define XACT_REPEATABLE_READ   2

◆ XACT_SERIALIZABLE

#define XACT_SERIALIZABLE   3

Definition at line 38 of file xact.h.

Referenced by check_XactIsoLevel(), ImportSnapshot(), and show_XactIsoLevel().

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

2985 {
2987 
2988  switch (s->blockState)
2989  {
2990  case TBLOCK_DEFAULT:
2991  if (s->state == TRANS_DEFAULT)
2992  {
2993  /* we are idle, so nothing to do */
2994  }
2995  else
2996  {
2997  /*
2998  * We can get here after an error during transaction start
2999  * (state will be TRANS_START). Need to clean up the
3000  * incompletely started transaction. First, adjust the
3001  * low-level state to suppress warning message from
3002  * AbortTransaction.
3003  */
3004  if (s->state == TRANS_START)
3005  s->state = TRANS_INPROGRESS;
3006  AbortTransaction();
3008  }
3009  break;
3010 
3011  /*
3012  * If we aren't in a transaction block, we just do the basic abort
3013  * & cleanup transaction. For this purpose, we treat an implicit
3014  * transaction block as if it were a simple statement.
3015  */
3016  case TBLOCK_STARTED:
3018  AbortTransaction();
3021  break;
3022 
3023  /*
3024  * If we are in TBLOCK_BEGIN it means something screwed up right
3025  * after reading "BEGIN TRANSACTION". We assume that the user
3026  * will interpret the error as meaning the BEGIN failed to get him
3027  * into a transaction block, so we should abort and return to idle
3028  * state.
3029  */
3030  case TBLOCK_BEGIN:
3031  AbortTransaction();
3034  break;
3035 
3036  /*
3037  * We are somewhere in a transaction block and we've gotten a
3038  * failure, so we abort the transaction and set up the persistent
3039  * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3040  */
3041  case TBLOCK_INPROGRESS:
3043  AbortTransaction();
3044  s->blockState = TBLOCK_ABORT;
3045  /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3046  break;
3047 
3048  /*
3049  * Here, we failed while trying to COMMIT. Clean up the
3050  * transaction and return to idle state (we do not want to stay in
3051  * the transaction).
3052  */
3053  case TBLOCK_END:
3054  AbortTransaction();
3057  break;
3058 
3059  /*
3060  * Here, we are already in an aborted transaction state and are
3061  * waiting for a ROLLBACK, but for some reason we failed again! So
3062  * we just remain in the abort state.
3063  */
3064  case TBLOCK_ABORT:
3065  case TBLOCK_SUBABORT:
3066  break;
3067 
3068  /*
3069  * We are in a failed transaction and we got the ROLLBACK command.
3070  * We have already aborted, we just need to cleanup and go to idle
3071  * state.
3072  */
3073  case TBLOCK_ABORT_END:
3076  break;
3077 
3078  /*
3079  * We are in a live transaction and we got a ROLLBACK command.
3080  * Abort, cleanup, go to idle state.
3081  */
3082  case TBLOCK_ABORT_PENDING:
3083  AbortTransaction();
3086  break;
3087 
3088  /*
3089  * Here, we failed while trying to PREPARE. Clean up the
3090  * transaction and return to idle state (we do not want to stay in
3091  * the transaction).
3092  */
3093  case TBLOCK_PREPARE:
3094  AbortTransaction();
3097  break;
3098 
3099  /*
3100  * We got an error inside a subtransaction. Abort just the
3101  * subtransaction, and go to the persistent SUBABORT state until
3102  * we get ROLLBACK.
3103  */
3104  case TBLOCK_SUBINPROGRESS:
3107  break;
3108 
3109  /*
3110  * If we failed while trying to create a subtransaction, clean up
3111  * the broken subtransaction and abort the parent. The same
3112  * applies if we get a failure while ending a subtransaction.
3113  */
3114  case TBLOCK_SUBBEGIN:
3115  case TBLOCK_SUBRELEASE:
3116  case TBLOCK_SUBCOMMIT:
3118  case TBLOCK_SUBRESTART:
3122  break;
3123 
3124  /*
3125  * Same as above, except the Abort() was already done.
3126  */
3127  case TBLOCK_SUBABORT_END:
3131  break;
3132  }
3133 }
void AbortCurrentTransaction(void)
Definition: xact.c:2984
static TransactionState CurrentTransactionState
Definition: xact.c:232
TBlockState blockState
Definition: xact.c:177
TransState state
Definition: xact.c:176
static void CleanupTransaction(void)
Definition: xact.c:2624
static void AbortSubTransaction(void)
Definition: xact.c:4665
static void AbortTransaction(void)
Definition: xact.c:2444
static void CleanupSubTransaction(void)
Definition: xact.c:4814

◆ AbortOutOfAnyTransaction()

void AbortOutOfAnyTransaction ( void  )

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

4319 {
4321 
4322  /* Ensure we're not running in a doomed memory context */
4323  AtAbort_Memory();
4324 
4325  /*
4326  * Get out of any transaction or nested transaction
4327  */
4328  do
4329  {
4330  switch (s->blockState)
4331  {
4332  case TBLOCK_DEFAULT:
4333  if (s->state == TRANS_DEFAULT)
4334  {
4335  /* Not in a transaction, do nothing */
4336  }
4337  else
4338  {
4339  /*
4340  * We can get here after an error during transaction start
4341  * (state will be TRANS_START). Need to clean up the
4342  * incompletely started transaction. First, adjust the
4343  * low-level state to suppress warning message from
4344  * AbortTransaction.
4345  */
4346  if (s->state == TRANS_START)
4347  s->state = TRANS_INPROGRESS;
4348  AbortTransaction();
4350  }
4351  break;
4352  case TBLOCK_STARTED:
4353  case TBLOCK_BEGIN:
4354  case TBLOCK_INPROGRESS:
4357  case TBLOCK_END:
4358  case TBLOCK_ABORT_PENDING:
4359  case TBLOCK_PREPARE:
4360  /* In a transaction, so clean up */
4361  AbortTransaction();
4364  break;
4365  case TBLOCK_ABORT:
4366  case TBLOCK_ABORT_END:
4367 
4368  /*
4369  * AbortTransaction is already done, still need Cleanup.
4370  * However, if we failed partway through running ROLLBACK,
4371  * there will be an active portal running that command, which
4372  * we need to shut down before doing CleanupTransaction.
4373  */
4374  AtAbort_Portals();
4377  break;
4378 
4379  /*
4380  * In a subtransaction, so clean it up and abort parent too
4381  */
4382  case TBLOCK_SUBBEGIN:
4383  case TBLOCK_SUBINPROGRESS:
4384  case TBLOCK_SUBRELEASE:
4385  case TBLOCK_SUBCOMMIT:
4387  case TBLOCK_SUBRESTART:
4390  s = CurrentTransactionState; /* changed by pop */
4391  break;
4392 
4393  case TBLOCK_SUBABORT:
4394  case TBLOCK_SUBABORT_END:
4396  /* As above, but AbortSubTransaction already done */
4397  if (s->curTransactionOwner)
4398  {
4399  /* As in TBLOCK_ABORT, might have a live portal to zap */
4404  }
4406  s = CurrentTransactionState; /* changed by pop */
4407  break;
4408  }
4409  } while (s->blockState != TBLOCK_DEFAULT);
4410 
4411  /* Should be out of all subxacts now */
4412  Assert(s->parent == NULL);
4413 
4414  /* If we didn't actually have anything to do, revert to TopMemoryContext */
4415  AtCleanup_Memory();
4416 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
static void AtCleanup_Memory(void)
Definition: xact.c:1724
void AtAbort_Portals(void)
Definition: portalmem.c:762
TBlockState blockState
Definition: xact.c:177
TransState state
Definition: xact.c:176
ResourceOwner curTransactionOwner
Definition: xact.c:181
static void CleanupTransaction(void)
Definition: xact.c:2624
struct TransactionStateData * parent
Definition: xact.c:191
SubTransactionId subTransactionId
Definition: xact.c:173
static void AbortSubTransaction(void)
Definition: xact.c:4665
static void AtAbort_Memory(void)
Definition: xact.c:1634
static void AbortTransaction(void)
Definition: xact.c:2444
#define Assert(condition)
Definition: c.h:699
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition: portalmem.c:958
static void CleanupSubTransaction(void)
Definition: xact.c:4814

◆ BeginImplicitTransactionBlock()

void BeginImplicitTransactionBlock ( void  )

Definition at line 3778 of file xact.c.

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

Referenced by exec_simple_query().

3779 {
3781 
3782  /*
3783  * If we are in STARTED state (that is, no transaction block is open),
3784  * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
3785  * block.
3786  *
3787  * For caller convenience, we consider all other transaction states as
3788  * legal here; otherwise the caller would need its own state check, which
3789  * seems rather pointless.
3790  */
3791  if (s->blockState == TBLOCK_STARTED)
3793 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
TBlockState blockState
Definition: xact.c:177

◆ BeginInternalSubTransaction()

void BeginInternalSubTransaction ( const char *  name)

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

4147 {
4149 
4150  /*
4151  * Workers synchronize transaction state at the beginning of each parallel
4152  * operation, so we can't account for new subtransactions after that
4153  * point. We might be able to make an exception for the type of
4154  * subtransaction established by this function, which is typically used in
4155  * contexts where we're going to release or roll back the subtransaction
4156  * before proceeding further, so that no enduring change to the
4157  * transaction state occurs. For now, however, we prohibit this case along
4158  * with all the others.
4159  */
4160  if (IsInParallelMode())
4161  ereport(ERROR,
4162  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4163  errmsg("cannot start subtransactions during a parallel operation")));
4164 
4165  switch (s->blockState)
4166  {
4167  case TBLOCK_STARTED:
4168  case TBLOCK_INPROGRESS:
4170  case TBLOCK_END:
4171  case TBLOCK_PREPARE:
4172  case TBLOCK_SUBINPROGRESS:
4173  /* Normal subtransaction start */
4174  PushTransaction();
4175  s = CurrentTransactionState; /* changed by push */
4176 
4177  /*
4178  * Savepoint names, like the TransactionState block itself, live
4179  * in TopTransactionContext.
4180  */
4181  if (name)
4183  break;
4184 
4185  /* These cases are invalid. */
4186  case TBLOCK_DEFAULT:
4187  case TBLOCK_BEGIN:
4189  case TBLOCK_SUBBEGIN:
4190  case TBLOCK_SUBRELEASE:
4191  case TBLOCK_SUBCOMMIT:
4192  case TBLOCK_ABORT:
4193  case TBLOCK_SUBABORT:
4194  case TBLOCK_ABORT_END:
4195  case TBLOCK_SUBABORT_END:
4196  case TBLOCK_ABORT_PENDING:
4198  case TBLOCK_SUBRESTART:
4200  elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4202  break;
4203  }
4204 
4207 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
MemoryContext TopTransactionContext
Definition: mcxt.c:49
void CommitTransactionCommand(void)
Definition: xact.c:2744
int errcode(int sqlerrcode)
Definition: elog.c:575
TBlockState blockState
Definition: xact.c:177
bool IsInParallelMode(void)
Definition: xact.c:905
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5127
#define ereport(elevel, rest)
Definition: elog.h:141
static void PushTransaction(void)
Definition: xact.c:4847
void StartTransactionCommand(void)
Definition: xact.c:2673
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1148
#define elog
Definition: elog.h:240

◆ BeginTransactionBlock()

void BeginTransactionBlock ( void  )

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

3413 {
3415 
3416  switch (s->blockState)
3417  {
3418  /*
3419  * We are not inside a transaction block, so allow one to begin.
3420  */
3421  case TBLOCK_STARTED:
3422  s->blockState = TBLOCK_BEGIN;
3423  break;
3424 
3425  /*
3426  * BEGIN converts an implicit transaction block to a regular one.
3427  * (Note that we allow this even if we've already done some
3428  * commands, which is a bit odd but matches historical practice.)
3429  */
3431  s->blockState = TBLOCK_BEGIN;
3432  break;
3433 
3434  /*
3435  * Already a transaction block in progress.
3436  */
3437  case TBLOCK_INPROGRESS:
3439  case TBLOCK_SUBINPROGRESS:
3440  case TBLOCK_ABORT:
3441  case TBLOCK_SUBABORT:
3442  ereport(WARNING,
3443  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3444  errmsg("there is already a transaction in progress")));
3445  break;
3446 
3447  /* These cases are invalid. */
3448  case TBLOCK_DEFAULT:
3449  case TBLOCK_BEGIN:
3450  case TBLOCK_SUBBEGIN:
3451  case TBLOCK_END:
3452  case TBLOCK_SUBRELEASE:
3453  case TBLOCK_SUBCOMMIT:
3454  case TBLOCK_ABORT_END:
3455  case TBLOCK_SUBABORT_END:
3456  case TBLOCK_ABORT_PENDING:
3458  case TBLOCK_SUBRESTART:
3460  case TBLOCK_PREPARE:
3461  elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3463  break;
3464  }
3465 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
int errcode(int sqlerrcode)
Definition: elog.c:575
TBlockState blockState
Definition: xact.c:177
#define FATAL
Definition: elog.h:52
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5127
#define ereport(elevel, rest)
Definition: elog.h:141
#define WARNING
Definition: elog.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:240

◆ CommandCounterIncrement()

void CommandCounterIncrement ( void  )

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

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

◆ CommitTransactionCommand()

void CommitTransactionCommand ( void  )

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

2745 {
2747 
2748  switch (s->blockState)
2749  {
2750  /*
2751  * These shouldn't happen. TBLOCK_DEFAULT means the previous
2752  * StartTransactionCommand didn't set the STARTED state
2753  * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
2754  * by EndParallelWorkerTransaction(), not this function.
2755  */
2756  case TBLOCK_DEFAULT:
2758  elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2760  break;
2761 
2762  /*
2763  * If we aren't in a transaction block, just do our usual
2764  * transaction commit, and return to the idle state.
2765  */
2766  case TBLOCK_STARTED:
2769  break;
2770 
2771  /*
2772  * We are completing a "BEGIN TRANSACTION" command, so we change
2773  * to the "transaction block in progress" state and return. (We
2774  * assume the BEGIN did nothing to the database, so we need no
2775  * CommandCounterIncrement.)
2776  */
2777  case TBLOCK_BEGIN:
2779  break;
2780 
2781  /*
2782  * This is the case when we have finished executing a command
2783  * someplace within a transaction block. We increment the command
2784  * counter and return.
2785  */
2786  case TBLOCK_INPROGRESS:
2788  case TBLOCK_SUBINPROGRESS:
2790  break;
2791 
2792  /*
2793  * We are completing a "COMMIT" command. Do it and return to the
2794  * idle state.
2795  */
2796  case TBLOCK_END:
2799  break;
2800 
2801  /*
2802  * Here we are in the middle of a transaction block but one of the
2803  * commands caused an abort so we do nothing but remain in the
2804  * abort state. Eventually we will get a ROLLBACK command.
2805  */
2806  case TBLOCK_ABORT:
2807  case TBLOCK_SUBABORT:
2808  break;
2809 
2810  /*
2811  * Here we were in an aborted transaction block and we just got
2812  * the ROLLBACK command from the user, so clean up the
2813  * already-aborted transaction and return to the idle state.
2814  */
2815  case TBLOCK_ABORT_END:
2818  break;
2819 
2820  /*
2821  * Here we were in a perfectly good transaction block but the user
2822  * told us to ROLLBACK anyway. We have to abort the transaction
2823  * and then clean up.
2824  */
2825  case TBLOCK_ABORT_PENDING:
2826  AbortTransaction();
2829  break;
2830 
2831  /*
2832  * We are completing a "PREPARE TRANSACTION" command. Do it and
2833  * return to the idle state.
2834  */
2835  case TBLOCK_PREPARE:
2838  break;
2839 
2840  /*
2841  * We were just issued a SAVEPOINT inside a transaction block.
2842  * Start a subtransaction. (DefineSavepoint already did
2843  * PushTransaction, so as to have someplace to put the SUBBEGIN
2844  * state.)
2845  */
2846  case TBLOCK_SUBBEGIN:
2849  break;
2850 
2851  /*
2852  * We were issued a RELEASE command, so we end the current
2853  * subtransaction and return to the parent transaction. The parent
2854  * might be ended too, so repeat till we find an INPROGRESS
2855  * transaction or subtransaction.
2856  */
2857  case TBLOCK_SUBRELEASE:
2858  do
2859  {
2861  s = CurrentTransactionState; /* changed by pop */
2862  } while (s->blockState == TBLOCK_SUBRELEASE);
2863 
2866  break;
2867 
2868  /*
2869  * We were issued a COMMIT, so we end the current subtransaction
2870  * hierarchy and perform final commit. We do this by rolling up
2871  * any subtransactions into their parent, which leads to O(N^2)
2872  * operations with respect to resource owners - this isn't that
2873  * bad until we approach a thousands of savepoints but is
2874  * necessary for correctness should after triggers create new
2875  * resource owners.
2876  */
2877  case TBLOCK_SUBCOMMIT:
2878  do
2879  {
2881  s = CurrentTransactionState; /* changed by pop */
2882  } while (s->blockState == TBLOCK_SUBCOMMIT);
2883  /* If we had a COMMIT command, finish off the main xact too */
2884  if (s->blockState == TBLOCK_END)
2885  {
2886  Assert(s->parent == NULL);
2889  }
2890  else if (s->blockState == TBLOCK_PREPARE)
2891  {
2892  Assert(s->parent == NULL);
2895  }
2896  else
2897  elog(ERROR, "CommitTransactionCommand: unexpected state %s",
2899  break;
2900 
2901  /*
2902  * The current already-failed subtransaction is ending due to a
2903  * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2904  * examine the parent (which could be in any of several states).
2905  */
2906  case TBLOCK_SUBABORT_END:
2909  break;
2910 
2911  /*
2912  * As above, but it's not dead yet, so abort first.
2913  */
2918  break;
2919 
2920  /*
2921  * The current subtransaction is the target of a ROLLBACK TO
2922  * command. Abort and pop it, then start a new subtransaction
2923  * with the same name.
2924  */
2925  case TBLOCK_SUBRESTART:
2926  {
2927  char *name;
2928  int savepointLevel;
2929 
2930  /* save name and keep Cleanup from freeing it */
2931  name = s->name;
2932  s->name = NULL;
2933  savepointLevel = s->savepointLevel;
2934 
2937 
2938  DefineSavepoint(NULL);
2939  s = CurrentTransactionState; /* changed by push */
2940  s->name = name;
2941  s->savepointLevel = savepointLevel;
2942 
2943  /* This is the same as TBLOCK_SUBBEGIN case */
2947  }
2948  break;
2949 
2950  /*
2951  * Same as above, but the subtransaction had already failed, so we
2952  * don't need AbortSubTransaction.
2953  */
2955  {
2956  char *name;
2957  int savepointLevel;
2958 
2959  /* save name and keep Cleanup from freeing it */
2960  name = s->name;
2961  s->name = NULL;
2962  savepointLevel = s->savepointLevel;
2963 
2965 
2966  DefineSavepoint(NULL);
2967  s = CurrentTransactionState; /* changed by push */
2968  s->name = name;
2969  s->savepointLevel = savepointLevel;
2970 
2971  /* This is the same as TBLOCK_SUBBEGIN case */
2975  }
2976  break;
2977  }
2978 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
#define AssertState(condition)
Definition: c.h:702
void CommitTransactionCommand(void)
Definition: xact.c:2744
void DefineSavepoint(const char *name)
Definition: xact.c:3825
TBlockState blockState
Definition: xact.c:177
static void PrepareTransaction(void)
Definition: xact.c:2169
#define ERROR
Definition: elog.h:43
static void CommitSubTransaction(void)
Definition: xact.c:4556
#define FATAL
Definition: elog.h:52
static void CleanupTransaction(void)
Definition: xact.c:2624
struct TransactionStateData * parent
Definition: xact.c:191
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5127
static void AbortSubTransaction(void)
Definition: xact.c:4665
void CommandCounterIncrement(void)
Definition: xact.c:914
static void AbortTransaction(void)
Definition: xact.c:2444
#define Assert(condition)
Definition: c.h:699
static void CleanupSubTransaction(void)
Definition: xact.c:4814
const char * name
Definition: encode.c:521
static void CommitTransaction(void)
Definition: xact.c:1933
#define elog
Definition: elog.h:240
static void StartSubTransaction(void)
Definition: xact.c:4518

◆ DefineSavepoint()

void DefineSavepoint ( const char *  name)

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

3826 {
3828 
3829  /*
3830  * Workers synchronize transaction state at the beginning of each parallel
3831  * operation, so we can't account for new subtransactions after that
3832  * point. (Note that this check will certainly error out if s->blockState
3833  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
3834  * below.)
3835  */
3836  if (IsInParallelMode())
3837  ereport(ERROR,
3838  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3839  errmsg("cannot define savepoints during a parallel operation")));
3840 
3841  switch (s->blockState)
3842  {
3843  case TBLOCK_INPROGRESS:
3844  case TBLOCK_SUBINPROGRESS:
3845  /* Normal subtransaction start */
3846  PushTransaction();
3847  s = CurrentTransactionState; /* changed by push */
3848 
3849  /*
3850  * Savepoint names, like the TransactionState block itself, live
3851  * in TopTransactionContext.
3852  */
3853  if (name)
3855  break;
3856 
3857  /*
3858  * We disallow savepoint commands in implicit transaction blocks.
3859  * There would be no great difficulty in allowing them so far as
3860  * this module is concerned, but a savepoint seems inconsistent
3861  * with exec_simple_query's behavior of abandoning the whole query
3862  * string upon error. Also, the point of an implicit transaction
3863  * block (as opposed to a regular one) is to automatically close
3864  * after an error, so it's hard to see how a savepoint would fit
3865  * into that.
3866  *
3867  * The error messages for this are phrased as if there were no
3868  * active transaction block at all, which is historical but
3869  * perhaps could be improved.
3870  */
3872  ereport(ERROR,
3873  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3874  /* translator: %s represents an SQL statement name */
3875  errmsg("%s can only be used in transaction blocks",
3876  "SAVEPOINT")));
3877  break;
3878 
3879  /* These cases are invalid. */
3880  case TBLOCK_DEFAULT:
3881  case TBLOCK_STARTED:
3882  case TBLOCK_BEGIN:
3884  case TBLOCK_SUBBEGIN:
3885  case TBLOCK_END:
3886  case TBLOCK_SUBRELEASE:
3887  case TBLOCK_SUBCOMMIT:
3888  case TBLOCK_ABORT:
3889  case TBLOCK_SUBABORT:
3890  case TBLOCK_ABORT_END:
3891  case TBLOCK_SUBABORT_END:
3892  case TBLOCK_ABORT_PENDING:
3894  case TBLOCK_SUBRESTART:
3896  case TBLOCK_PREPARE:
3897  elog(FATAL, "DefineSavepoint: unexpected state %s",
3899  break;
3900  }
3901 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
MemoryContext TopTransactionContext
Definition: mcxt.c:49
int errcode(int sqlerrcode)
Definition: elog.c:575
TBlockState blockState
Definition: xact.c:177
bool IsInParallelMode(void)
Definition: xact.c:905
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5127
#define ereport(elevel, rest)
Definition: elog.h:141
static void PushTransaction(void)
Definition: xact.c:4847
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1148
#define elog
Definition: elog.h:240

◆ EndImplicitTransactionBlock()

void EndImplicitTransactionBlock ( void  )

Definition at line 3803 of file xact.c.

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

Referenced by exec_simple_query().

3804 {
3806 
3807  /*
3808  * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
3809  * allowing CommitTransactionCommand to commit whatever happened during
3810  * the implicit transaction block as though it were a single statement.
3811  *
3812  * For caller convenience, we consider all other transaction states as
3813  * legal here; otherwise the caller would need its own state check, which
3814  * seems rather pointless.
3815  */
3818 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
TBlockState blockState
Definition: xact.c:177

◆ EndParallelWorkerTransaction()

void EndParallelWorkerTransaction ( void  )

Definition at line 5064 of file xact.c.

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

Referenced by ParallelWorkerMain().

5065 {
5069 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
TBlockState blockState
Definition: xact.c:177
#define Assert(condition)
Definition: c.h:699
static void CommitTransaction(void)
Definition: xact.c:1933

◆ EndTransactionBlock()

bool EndTransactionBlock ( void  )

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

3533 {
3535  bool result = false;
3536 
3537  switch (s->blockState)
3538  {
3539  /*
3540  * We are in a transaction block, so tell CommitTransactionCommand
3541  * to COMMIT.
3542  */
3543  case TBLOCK_INPROGRESS:
3544  s->blockState = TBLOCK_END;
3545  result = true;
3546  break;
3547 
3548  /*
3549  * In an implicit transaction block, commit, but issue a warning
3550  * because there was no explicit BEGIN before this.
3551  */
3553  ereport(WARNING,
3554  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3555  errmsg("there is no transaction in progress")));
3556  s->blockState = TBLOCK_END;
3557  result = true;
3558  break;
3559 
3560  /*
3561  * We are in a failed transaction block. Tell
3562  * CommitTransactionCommand it's time to exit the block.
3563  */
3564  case TBLOCK_ABORT:
3566  break;
3567 
3568  /*
3569  * We are in a live subtransaction block. Set up to subcommit all
3570  * open subtransactions and then commit the main transaction.
3571  */
3572  case TBLOCK_SUBINPROGRESS:
3573  while (s->parent != NULL)
3574  {
3575  if (s->blockState == TBLOCK_SUBINPROGRESS)
3577  else
3578  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3580  s = s->parent;
3581  }
3582  if (s->blockState == TBLOCK_INPROGRESS)
3583  s->blockState = TBLOCK_END;
3584  else
3585  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3587  result = true;
3588  break;
3589 
3590  /*
3591  * Here we are inside an aborted subtransaction. Treat the COMMIT
3592  * as ROLLBACK: set up to abort everything and exit the main
3593  * transaction.
3594  */
3595  case TBLOCK_SUBABORT:
3596  while (s->parent != NULL)
3597  {
3598  if (s->blockState == TBLOCK_SUBINPROGRESS)
3600  else if (s->blockState == TBLOCK_SUBABORT)
3602  else
3603  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3605  s = s->parent;
3606  }
3607  if (s->blockState == TBLOCK_INPROGRESS)
3609  else if (s->blockState == TBLOCK_ABORT)
3611  else
3612  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3614  break;
3615 
3616  /*
3617  * The user issued COMMIT when not inside a transaction. Issue a
3618  * WARNING, staying in TBLOCK_STARTED state. The upcoming call to
3619  * CommitTransactionCommand() will then close the transaction and
3620  * put us back into the default state.
3621  */
3622  case TBLOCK_STARTED:
3623  ereport(WARNING,
3624  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3625  errmsg("there is no transaction in progress")));
3626  result = true;
3627  break;
3628 
3629  /*
3630  * The user issued a COMMIT that somehow ran inside a parallel
3631  * worker. We can't cope with that.
3632  */
3634  ereport(FATAL,
3635  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3636  errmsg("cannot commit during a parallel operation")));
3637  break;
3638 
3639  /* These cases are invalid. */
3640  case TBLOCK_DEFAULT:
3641  case TBLOCK_BEGIN:
3642  case TBLOCK_SUBBEGIN:
3643  case TBLOCK_END:
3644  case TBLOCK_SUBRELEASE:
3645  case TBLOCK_SUBCOMMIT:
3646  case TBLOCK_ABORT_END:
3647  case TBLOCK_SUBABORT_END:
3648  case TBLOCK_ABORT_PENDING:
3650  case TBLOCK_SUBRESTART:
3652  case TBLOCK_PREPARE:
3653  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3655  break;
3656  }
3657 
3658  return result;
3659 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
int errcode(int sqlerrcode)
Definition: elog.c:575
TBlockState blockState
Definition: xact.c:177
#define FATAL
Definition: elog.h:52
struct TransactionStateData * parent
Definition: xact.c:191
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5127
#define ereport(elevel, rest)
Definition: elog.h:141
#define WARNING
Definition: elog.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:240

◆ EnterParallelMode()

void EnterParallelMode ( void  )

Definition at line 872 of file xact.c.

References Assert, CurrentTransactionState, and TransactionStateData::parallelModeLevel.

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

873 {
875 
876  Assert(s->parallelModeLevel >= 0);
877 
878  ++s->parallelModeLevel;
879 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
int parallelModeLevel
Definition: xact.c:190
#define Assert(condition)
Definition: c.h:699

◆ EstimateTransactionStateSpace()

Size EstimateTransactionStateSpace ( void  )

Definition at line 4940 of file xact.c.

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

Referenced by InitializeParallelDSM().

4941 {
4942  TransactionState s;
4943  Size nxids = 6; /* iso level, deferrable, top & current XID,
4944  * command counter, XID count */
4945 
4946  for (s = CurrentTransactionState; s != NULL; s = s->parent)
4947  {
4949  nxids = add_size(nxids, 1);
4950  nxids = add_size(nxids, s->nChildXids);
4951  }
4952 
4953  nxids = add_size(nxids, nParallelCurrentXids);
4954  return mul_size(nxids, sizeof(TransactionId));
4955 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
uint32 TransactionId
Definition: c.h:474
int nParallelCurrentXids
Definition: xact.c:107
struct TransactionStateData * parent
Definition: xact.c:191
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:172
size_t Size
Definition: c.h:433
#define TransactionIdIsValid(xid)
Definition: transam.h:41

◆ ExitParallelMode()

void ExitParallelMode ( void  )

Definition at line 885 of file xact.c.

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

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

886 {
888 
889  Assert(s->parallelModeLevel > 0);
891 
892  --s->parallelModeLevel;
893 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
bool ParallelContextActive(void)
Definition: parallel.c:940
int parallelModeLevel
Definition: xact.c:190
#define Assert(condition)
Definition: c.h:699

◆ ForceSyncCommit()

void ForceSyncCommit ( void  )

Definition at line 962 of file xact.c.

References forceSyncCommit.

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

963 {
964  forceSyncCommit = true;
965 }
static bool forceSyncCommit
Definition: xact.c:262

◆ GetCurrentCommandId()

CommandId GetCurrentCommandId ( bool  used)

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

680 {
681  /* this is global to a transaction, not subtransaction-local */
682  if (used)
683  {
684  /*
685  * Forbid setting currentCommandIdUsed in a parallel worker, because
686  * we have no provision for communicating this back to the master. We
687  * could relax this restriction when currentCommandIdUsed was already
688  * true at the start of the parallel operation.
689  */
691  currentCommandIdUsed = true;
692  }
693  return currentCommandId;
694 }
#define IsParallelWorker()
Definition: parallel.h:60
#define Assert(condition)
Definition: c.h:699
static CommandId currentCommandId
Definition: xact.c:239
static bool currentCommandIdUsed
Definition: xact.c:240

◆ GetCurrentStatementStartTimestamp()

TimestampTz GetCurrentStatementStartTimestamp ( void  )

Definition at line 709 of file xact.c.

References stmtStartTimestamp.

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

710 {
711  return stmtStartTimestamp;
712 }
static TimestampTz stmtStartTimestamp
Definition: xact.c:250

◆ GetCurrentSubTransactionId()

◆ GetCurrentTransactionId()

◆ GetCurrentTransactionIdIfAny()

TransactionId GetCurrentTransactionIdIfAny ( void  )

Definition at line 434 of file xact.c.

References TransactionStateData::transactionId.

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

435 {
437 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
TransactionId transactionId
Definition: xact.c:172

◆ GetCurrentTransactionNestLevel()

◆ GetCurrentTransactionStartTimestamp()

TimestampTz GetCurrentTransactionStartTimestamp ( void  )

◆ GetCurrentTransactionStopTimestamp()

TimestampTz GetCurrentTransactionStopTimestamp ( void  )

Definition at line 721 of file xact.c.

References GetCurrentTimestamp(), and xactStopTimestamp.

Referenced by pgstat_report_stat().

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

◆ GetStableLatestTransactionId()

TransactionId GetStableLatestTransactionId ( void  )

Definition at line 461 of file xact.c.

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

Referenced by xid_age().

462 {
464  static TransactionId stablexid = InvalidTransactionId;
465 
466  if (lxid != MyProc->lxid)
467  {
468  lxid = MyProc->lxid;
469  stablexid = GetTopTransactionIdIfAny();
470  if (!TransactionIdIsValid(stablexid))
471  stablexid = ReadNewTransactionId();
472  }
473 
474  Assert(TransactionIdIsValid(stablexid));
475 
476  return stablexid;
477 }
uint32 TransactionId
Definition: c.h:474
PGPROC * MyProc
Definition: proc.c:67
#define InvalidTransactionId
Definition: transam.h:31
TransactionId ReadNewTransactionId(void)
Definition: varsup.c:250
uint32 LocalTransactionId
Definition: c.h:476
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:404
#define Assert(condition)
Definition: c.h:699
#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 389 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().

390 {
393  return XactTopTransactionId;
394 }
TransactionId XactTopTransactionId
Definition: xact.c:106
static TransactionStateData TopTransactionStateData
Definition: xact.c:201
#define TransactionIdIsValid(xid)
Definition: transam.h:41
static void AssignTransactionId(TransactionState s)
Definition: xact.c:489

◆ GetTopTransactionIdIfAny()

◆ IsAbortedTransactionBlockState()

◆ IsInParallelMode()

◆ IsInTransactionBlock()

bool IsInTransactionBlock ( bool  isTopLevel)

Definition at line 3267 of file xact.c.

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

Referenced by vacuum().

3268 {
3269  /*
3270  * Return true on same conditions that would make
3271  * PreventInTransactionBlock error out
3272  */
3273  if (IsTransactionBlock())
3274  return true;
3275 
3276  if (IsSubTransaction())
3277  return true;
3278 
3279  if (!isTopLevel)
3280  return true;
3281 
3284  return true;
3285 
3286  return false;
3287 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
TBlockState blockState
Definition: xact.c:177
bool IsTransactionBlock(void)
Definition: xact.c:4422
bool IsSubTransaction(void)
Definition: xact.c:4495

◆ IsSubTransaction()

◆ IsTransactionBlock()

bool IsTransactionBlock ( void  )

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

4423 {
4425 
4427  return false;
4428 
4429  return true;
4430 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
TBlockState blockState
Definition: xact.c:177

◆ IsTransactionOrTransactionBlock()

bool IsTransactionOrTransactionBlock ( void  )

◆ IsTransactionState()

bool IsTransactionState ( void  )

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

351 {
353 
354  /*
355  * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
356  * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
357  * TRANS_PREPARE since it might be too soon or too late within those
358  * transition states to do anything interesting. Hence, the only "valid"
359  * state is TRANS_INPROGRESS.
360  */
361  return (s->state == TRANS_INPROGRESS);
362 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
TransState state
Definition: xact.c:176

◆ MarkCurrentTransactionIdLoggedIfAny()

void MarkCurrentTransactionIdLoggedIfAny ( void  )

Definition at line 445 of file xact.c.

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

Referenced by XLogInsertRecord().

446 {
449 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
TransactionId transactionId
Definition: xact.c:172
#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:474
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:474
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 3480 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().

3481 {
3482  TransactionState s;
3483  bool result;
3484 
3485  /* Set up to commit the current transaction */
3486  result = EndTransactionBlock();
3487 
3488  /* If successful, change outer tblock state to PREPARE */
3489  if (result)
3490  {
3492 
3493  while (s->parent != NULL)
3494  s = s->parent;
3495 
3496  if (s->blockState == TBLOCK_END)
3497  {
3498  /* Save GID where PrepareTransaction can find it again */
3500 
3502  }
3503  else
3504  {
3505  /*
3506  * ignore case where we are not in a transaction;
3507  * EndTransactionBlock already issued a warning.
3508  */
3511  /* Don't send back a PREPARE result tag... */
3512  result = false;
3513  }
3514  }
3515 
3516  return result;
3517 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
MemoryContext TopTransactionContext
Definition: mcxt.c:49
bool EndTransactionBlock(void)
Definition: xact.c:3532
TBlockState blockState
Definition: xact.c:177
struct TransactionStateData * parent
Definition: xact.c:191
#define Assert(condition)
Definition: c.h:699
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1148
static char * prepareGID
Definition: xact.c:257

◆ PreventInTransactionBlock()

void PreventInTransactionBlock ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3153 of file xact.c.

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

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

3154 {
3155  /*
3156  * xact block already started?
3157  */
3158  if (IsTransactionBlock())
3159  ereport(ERROR,
3160  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3161  /* translator: %s represents an SQL statement name */
3162  errmsg("%s cannot run inside a transaction block",
3163  stmtType)));
3164 
3165  /*
3166  * subtransaction?
3167  */
3168  if (IsSubTransaction())
3169  ereport(ERROR,
3170  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3171  /* translator: %s represents an SQL statement name */
3172  errmsg("%s cannot run inside a subtransaction",
3173  stmtType)));
3174 
3175  /*
3176  * inside a function call?
3177  */
3178  if (!isTopLevel)
3179  ereport(ERROR,
3180  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3181  /* translator: %s represents an SQL statement name */
3182  errmsg("%s cannot be executed from a function", stmtType)));
3183 
3184  /* If we got past IsTransactionBlock test, should be in default state */
3187  elog(FATAL, "cannot prevent transaction chain");
3188  /* all okay */
3189 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
int errcode(int sqlerrcode)
Definition: elog.c:575
TBlockState blockState
Definition: xact.c:177
bool IsTransactionBlock(void)
Definition: xact.c:4422
#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:4495
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:240

◆ RegisterSubXactCallback()

void RegisterSubXactCallback ( SubXactCallback  callback,
void *  arg 
)

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

3358 {
3359  SubXactCallbackItem *item;
3360 
3361  item = (SubXactCallbackItem *)
3363  item->callback = callback;
3364  item->arg = arg;
3365  item->next = SubXact_callbacks;
3366  SubXact_callbacks = item;
3367 }
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:293
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
struct SubXactCallbackItem * next
Definition: xact.c:288
SubXactCallback callback
Definition: xact.c:289
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 3302 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().

3303 {
3304  XactCallbackItem *item;
3305 
3306  item = (XactCallbackItem *)
3308  item->callback = callback;
3309  item->arg = arg;
3310  item->next = Xact_callbacks;
3311  Xact_callbacks = item;
3312 }
struct XactCallbackItem * next
Definition: xact.c:276
void * arg
Definition: xact.c:278
XactCallback callback
Definition: xact.c:277
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:281
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:771
void * arg

◆ ReleaseCurrentSubTransaction()

void ReleaseCurrentSubTransaction ( void  )

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

4218 {
4220 
4221  /*
4222  * Workers synchronize transaction state at the beginning of each parallel
4223  * operation, so we can't account for commit of subtransactions after that
4224  * point. This should not happen anyway. Code calling this would
4225  * typically have called BeginInternalSubTransaction() first, failing
4226  * there.
4227  */
4228  if (IsInParallelMode())
4229  ereport(ERROR,
4230  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4231  errmsg("cannot commit subtransactions during a parallel operation")));
4232 
4233  if (s->blockState != TBLOCK_SUBINPROGRESS)
4234  elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4236  Assert(s->state == TRANS_INPROGRESS);
4239  s = CurrentTransactionState; /* changed by pop */
4240  Assert(s->state == TRANS_INPROGRESS);
4241 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext CurTransactionContext
Definition: mcxt.c:50
int errcode(int sqlerrcode)
Definition: elog.c:575
TBlockState blockState
Definition: xact.c:177
TransState state
Definition: xact.c:176
bool IsInParallelMode(void)
Definition: xact.c:905
#define ERROR
Definition: elog.h:43
static void CommitSubTransaction(void)
Definition: xact.c:4556
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5127
#define ereport(elevel, rest)
Definition: elog.h:141
#define Assert(condition)
Definition: c.h:699
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:240

◆ ReleaseSavepoint()

void ReleaseSavepoint ( const char *  name)

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

3911 {
3913  TransactionState target,
3914  xact;
3915 
3916  /*
3917  * Workers synchronize transaction state at the beginning of each parallel
3918  * operation, so we can't account for transaction state change after that
3919  * point. (Note that this check will certainly error out if s->blockState
3920  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
3921  * below.)
3922  */
3923  if (IsInParallelMode())
3924  ereport(ERROR,
3925  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3926  errmsg("cannot release savepoints during a parallel operation")));
3927 
3928  switch (s->blockState)
3929  {
3930  /*
3931  * We can't release a savepoint if there is no savepoint defined.
3932  */
3933  case TBLOCK_INPROGRESS:
3934  ereport(ERROR,
3935  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3936  errmsg("savepoint \"%s\" does not exist", name)));
3937  break;
3938 
3940  /* See comment about implicit transactions in DefineSavepoint */
3941  ereport(ERROR,
3942  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3943  /* translator: %s represents an SQL statement name */
3944  errmsg("%s can only be used in transaction blocks",
3945  "RELEASE SAVEPOINT")));
3946  break;
3947 
3948  /*
3949  * We are in a non-aborted subtransaction. This is the only valid
3950  * case.
3951  */
3952  case TBLOCK_SUBINPROGRESS:
3953  break;
3954 
3955  /* These cases are invalid. */
3956  case TBLOCK_DEFAULT:
3957  case TBLOCK_STARTED:
3958  case TBLOCK_BEGIN:
3960  case TBLOCK_SUBBEGIN:
3961  case TBLOCK_END:
3962  case TBLOCK_SUBRELEASE:
3963  case TBLOCK_SUBCOMMIT:
3964  case TBLOCK_ABORT:
3965  case TBLOCK_SUBABORT:
3966  case TBLOCK_ABORT_END:
3967  case TBLOCK_SUBABORT_END:
3968  case TBLOCK_ABORT_PENDING:
3970  case TBLOCK_SUBRESTART:
3972  case TBLOCK_PREPARE:
3973  elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3975  break;
3976  }
3977 
3978  for (target = s; PointerIsValid(target); target = target->parent)
3979  {
3980  if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3981  break;
3982  }
3983 
3984  if (!PointerIsValid(target))
3985  ereport(ERROR,
3986  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3987  errmsg("savepoint \"%s\" does not exist", name)));
3988 
3989  /* disallow crossing savepoint level boundaries */
3990  if (target->savepointLevel != s->savepointLevel)
3991  ereport(ERROR,
3992  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3993  errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
3994 
3995  /*
3996  * Mark "commit pending" all subtransactions up to the target
3997  * subtransaction. The actual commits will happen when control gets to
3998  * CommitTransactionCommand.
3999  */
4000  xact = CurrentTransactionState;
4001  for (;;)
4002  {
4004  xact->blockState = TBLOCK_SUBRELEASE;
4005  if (xact == target)
4006  break;
4007  xact = xact->parent;
4008  Assert(PointerIsValid(xact));
4009  }
4010 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
int errcode(int sqlerrcode)
Definition: elog.c:575
TBlockState blockState
Definition: xact.c:177
bool IsInParallelMode(void)
Definition: xact.c:905
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
struct TransactionStateData * parent
Definition: xact.c:191
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5127
#define ereport(elevel, rest)
Definition: elog.h:141
#define Assert(condition)
Definition: c.h:699
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:240
#define PointerIsValid(pointer)
Definition: c.h:593

◆ RequireTransactionBlock()

void RequireTransactionBlock ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3219 of file xact.c.

References CheckTransactionBlock().

Referenced by PerformCursorOpen(), and standard_ProcessUtility().

3220 {
3221  CheckTransactionBlock(isTopLevel, true, stmtType);
3222 }
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3228

◆ RollbackAndReleaseCurrentSubTransaction()

void RollbackAndReleaseCurrentSubTransaction ( void  )

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

4252 {
4254 
4255  /*
4256  * Unlike ReleaseCurrentSubTransaction(), this is nominally permitted
4257  * during parallel operations. That's because we may be in the master,
4258  * recovering from an error thrown while we were in parallel mode. We
4259  * won't reach here in a worker, because BeginInternalSubTransaction()
4260  * will have failed.
4261  */
4262 
4263  switch (s->blockState)
4264  {
4265  /* Must be in a subtransaction */
4266  case TBLOCK_SUBINPROGRESS:
4267  case TBLOCK_SUBABORT:
4268  break;
4269 
4270  /* These cases are invalid. */
4271  case TBLOCK_DEFAULT:
4272  case TBLOCK_STARTED:
4273  case TBLOCK_BEGIN:
4276  case TBLOCK_SUBBEGIN:
4277  case TBLOCK_INPROGRESS:
4278  case TBLOCK_END:
4279  case TBLOCK_SUBRELEASE:
4280  case TBLOCK_SUBCOMMIT:
4281  case TBLOCK_ABORT:
4282  case TBLOCK_ABORT_END:
4283  case TBLOCK_SUBABORT_END:
4284  case TBLOCK_ABORT_PENDING:
4286  case TBLOCK_SUBRESTART:
4288  case TBLOCK_PREPARE:
4289  elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4291  break;
4292  }
4293 
4294  /*
4295  * Abort the current subtransaction, if needed.
4296  */
4297  if (s->blockState == TBLOCK_SUBINPROGRESS)
4299 
4300  /* And clean it up, too */
4302 
4303  s = CurrentTransactionState; /* changed by pop */
4305  s->blockState == TBLOCK_INPROGRESS ||
4307  s->blockState == TBLOCK_STARTED);
4308 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
#define AssertState(condition)
Definition: c.h:702
TBlockState blockState
Definition: xact.c:177
#define FATAL
Definition: elog.h:52
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5127
static void AbortSubTransaction(void)
Definition: xact.c:4665
static void CleanupSubTransaction(void)
Definition: xact.c:4814
#define elog
Definition: elog.h:240

◆ RollbackToSavepoint()

void RollbackToSavepoint ( const char *  name)

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

4020 {
4022  TransactionState target,
4023  xact;
4024 
4025  /*
4026  * Workers synchronize transaction state at the beginning of each parallel
4027  * operation, so we can't account for transaction state change after that
4028  * point. (Note that this check will certainly error out if s->blockState
4029  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4030  * below.)
4031  */
4032  if (IsInParallelMode())
4033  ereport(ERROR,
4034  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4035  errmsg("cannot rollback to savepoints during a parallel operation")));
4036 
4037  switch (s->blockState)
4038  {
4039  /*
4040  * We can't rollback to a savepoint if there is no savepoint
4041  * defined.
4042  */
4043  case TBLOCK_INPROGRESS:
4044  case TBLOCK_ABORT:
4045  ereport(ERROR,
4046  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4047  errmsg("savepoint \"%s\" does not exist", name)));
4048  break;
4049 
4051  /* See comment about implicit transactions in DefineSavepoint */
4052  ereport(ERROR,
4053  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4054  /* translator: %s represents an SQL statement name */
4055  errmsg("%s can only be used in transaction blocks",
4056  "ROLLBACK TO SAVEPOINT")));
4057  break;
4058 
4059  /*
4060  * There is at least one savepoint, so proceed.
4061  */
4062  case TBLOCK_SUBINPROGRESS:
4063  case TBLOCK_SUBABORT:
4064  break;
4065 
4066  /* These cases are invalid. */
4067  case TBLOCK_DEFAULT:
4068  case TBLOCK_STARTED:
4069  case TBLOCK_BEGIN:
4071  case TBLOCK_SUBBEGIN:
4072  case TBLOCK_END:
4073  case TBLOCK_SUBRELEASE:
4074  case TBLOCK_SUBCOMMIT:
4075  case TBLOCK_ABORT_END:
4076  case TBLOCK_SUBABORT_END:
4077  case TBLOCK_ABORT_PENDING:
4079  case TBLOCK_SUBRESTART:
4081  case TBLOCK_PREPARE:
4082  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4084  break;
4085  }
4086 
4087  for (target = s; PointerIsValid(target); target = target->parent)
4088  {
4089  if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4090  break;
4091  }
4092 
4093  if (!PointerIsValid(target))
4094  ereport(ERROR,
4095  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4096  errmsg("savepoint \"%s\" does not exist", name)));
4097 
4098  /* disallow crossing savepoint level boundaries */
4099  if (target->savepointLevel != s->savepointLevel)
4100  ereport(ERROR,
4101  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4102  errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4103 
4104  /*
4105  * Mark "abort pending" all subtransactions up to the target
4106  * subtransaction. The actual aborts will happen when control gets to
4107  * CommitTransactionCommand.
4108  */
4109  xact = CurrentTransactionState;
4110  for (;;)
4111  {
4112  if (xact == target)
4113  break;
4114  if (xact->blockState == TBLOCK_SUBINPROGRESS)
4116  else if (xact->blockState == TBLOCK_SUBABORT)
4118  else
4119  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4121  xact = xact->parent;
4122  Assert(PointerIsValid(xact));
4123  }
4124 
4125  /* And mark the target as "restart pending" */
4126  if (xact->blockState == TBLOCK_SUBINPROGRESS)
4127  xact->blockState = TBLOCK_SUBRESTART;
4128  else if (xact->blockState == TBLOCK_SUBABORT)
4130  else
4131  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4133 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
int errcode(int sqlerrcode)
Definition: elog.c:575
TBlockState blockState
Definition: xact.c:177
bool IsInParallelMode(void)
Definition: xact.c:905
#define ERROR
Definition: elog.h:43
#define FATAL
Definition: elog.h:52
struct TransactionStateData * parent
Definition: xact.c:191
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5127
#define ereport(elevel, rest)
Definition: elog.h:141
#define Assert(condition)
Definition: c.h:699
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:240
#define PointerIsValid(pointer)
Definition: c.h:593

◆ SerializeTransactionState()

void SerializeTransactionState ( Size  maxsize,
char *  start_address 
)

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

4974 {
4975  TransactionState s;
4976  Size nxids = 0;
4977  Size i = 0;
4978  Size c = 0;
4979  TransactionId *workspace;
4980  TransactionId *result = (TransactionId *) start_address;
4981 
4982  result[c++] = (TransactionId) XactIsoLevel;
4983  result[c++] = (TransactionId) XactDeferrable;
4984  result[c++] = XactTopTransactionId;
4985  result[c++] = CurrentTransactionState->transactionId;
4986  result[c++] = (TransactionId) currentCommandId;
4987  Assert(maxsize >= c * sizeof(TransactionId));
4988 
4989  /*
4990  * If we're running in a parallel worker and launching a parallel worker
4991  * of our own, we can just pass along the information that was passed to
4992  * us.
4993  */
4994  if (nParallelCurrentXids > 0)
4995  {
4996  result[c++] = nParallelCurrentXids;
4997  Assert(maxsize >= (nParallelCurrentXids + c) * sizeof(TransactionId));
4998  memcpy(&result[c], ParallelCurrentXids,
5000  return;
5001  }
5002 
5003  /*
5004  * OK, we need to generate a sorted list of XIDs that our workers should
5005  * view as current. First, figure out how many there are.
5006  */
5007  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5008  {
5010  nxids = add_size(nxids, 1);
5011  nxids = add_size(nxids, s->nChildXids);
5012  }
5013  Assert((c + 1 + nxids) * sizeof(TransactionId) <= maxsize);
5014 
5015  /* Copy them to our scratch space. */
5016  workspace = palloc(nxids * sizeof(TransactionId));
5017  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5018  {
5020  workspace[i++] = s->transactionId;
5021  memcpy(&workspace[i], s->childXids,
5022  s->nChildXids * sizeof(TransactionId));
5023  i += s->nChildXids;
5024  }
5025  Assert(i == nxids);
5026 
5027  /* Sort them. */
5028  qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5029 
5030  /* Copy data into output area. */
5031  result[c++] = (TransactionId) nxids;
5032  memcpy(&result[c], workspace, nxids * sizeof(TransactionId));
5033 }
TransactionId XactTopTransactionId
Definition: xact.c:106
bool XactDeferrable
Definition: xact.c:79
static TransactionState CurrentTransactionState
Definition: xact.c:232
uint32 TransactionId
Definition: c.h:474
int nParallelCurrentXids
Definition: xact.c:107
TransactionId * childXids
Definition: xact.c:182
struct TransactionStateData * parent
Definition: xact.c:191
char * c
Size add_size(Size s1, Size s2)
Definition: shmem.c:475
TransactionId transactionId
Definition: xact.c:172
TransactionId * ParallelCurrentXids
Definition: xact.c:108
#define Assert(condition)
Definition: c.h:699
size_t Size
Definition: c.h:433
int XactIsoLevel
Definition: xact.c:73
void * palloc(Size size)
Definition: mcxt.c:924
int i
#define qsort(a, b, c, d)
Definition: port.h:421
static CommandId currentCommandId
Definition: xact.c:239
#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 732 of file xact.c.

References GetCurrentTimestamp(), and stmtStartTimestamp.

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

733 {
735 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
static TimestampTz stmtStartTimestamp
Definition: xact.c:250

◆ StartParallelWorkerTransaction()

void StartParallelWorkerTransaction ( char *  tstatespace)

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

5042 {
5043  TransactionId *tstate = (TransactionId *) tstatespace;
5044 
5046  StartTransaction();
5047 
5048  XactIsoLevel = (int) tstate[0];
5049  XactDeferrable = (bool) tstate[1];
5050  XactTopTransactionId = tstate[2];
5052  currentCommandId = tstate[4];
5053  nParallelCurrentXids = (int) tstate[5];
5054  ParallelCurrentXids = &tstate[6];
5055 
5057 }
TransactionId XactTopTransactionId
Definition: xact.c:106
bool XactDeferrable
Definition: xact.c:79
static TransactionState CurrentTransactionState
Definition: xact.c:232
uint32 TransactionId
Definition: c.h:474
int nParallelCurrentXids
Definition: xact.c:107
char bool
Definition: c.h:275
TBlockState blockState
Definition: xact.c:177
TransactionId transactionId
Definition: xact.c:172
static void StartTransaction(void)
Definition: xact.c:1795
TransactionId * ParallelCurrentXids
Definition: xact.c:108
#define Assert(condition)
Definition: c.h:699
int XactIsoLevel
Definition: xact.c:73
static CommandId currentCommandId
Definition: xact.c:239

◆ StartTransactionCommand()

void StartTransactionCommand ( void  )

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

2674 {
2676 
2677  switch (s->blockState)
2678  {
2679  /*
2680  * if we aren't in a transaction block, we just do our usual start
2681  * transaction.
2682  */
2683  case TBLOCK_DEFAULT:
2684  StartTransaction();
2686  break;
2687 
2688  /*
2689  * We are somewhere in a transaction block or subtransaction and
2690  * about to start a new command. For now we do nothing, but
2691  * someday we may do command-local resource initialization. (Note
2692  * that any needed CommandCounterIncrement was done by the
2693  * previous CommitTransactionCommand.)
2694  */
2695  case TBLOCK_INPROGRESS:
2697  case TBLOCK_SUBINPROGRESS:
2698  break;
2699 
2700  /*
2701  * Here we are in a failed transaction block (one of the commands
2702  * caused an abort) so we do nothing but remain in the abort
2703  * state. Eventually we will get a ROLLBACK command which will
2704  * get us out of this state. (It is up to other code to ensure
2705  * that no commands other than ROLLBACK will be processed in these
2706  * states.)
2707  */
2708  case TBLOCK_ABORT:
2709  case TBLOCK_SUBABORT:
2710  break;
2711 
2712  /* These cases are invalid. */
2713  case TBLOCK_STARTED:
2714  case TBLOCK_BEGIN:
2716  case TBLOCK_SUBBEGIN:
2717  case TBLOCK_END:
2718  case TBLOCK_SUBRELEASE:
2719  case TBLOCK_SUBCOMMIT:
2720  case TBLOCK_ABORT_END:
2721  case TBLOCK_SUBABORT_END:
2722  case TBLOCK_ABORT_PENDING:
2724  case TBLOCK_SUBRESTART:
2726  case TBLOCK_PREPARE:
2727  elog(ERROR, "StartTransactionCommand: unexpected state %s",
2729  break;
2730  }
2731 
2732  /*
2733  * We must switch to CurTransactionContext before returning. This is
2734  * already done if we called StartTransaction, otherwise not.
2735  */
2736  Assert(CurTransactionContext != NULL);
2738 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext CurTransactionContext
Definition: mcxt.c:50
TBlockState blockState
Definition: xact.c:177
#define ERROR
Definition: elog.h:43
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5127
static void StartTransaction(void)
Definition: xact.c:1795
#define Assert(condition)
Definition: c.h:699
#define elog
Definition: elog.h:240

◆ SubTransactionIsActive()

bool SubTransactionIsActive ( SubTransactionId  subxid)

Definition at line 655 of file xact.c.

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

Referenced by fmgr_sql().

656 {
658 
659  for (s = CurrentTransactionState; s != NULL; s = s->parent)
660  {
661  if (s->state == TRANS_ABORT)
662  continue;
663  if (s->subTransactionId == subxid)
664  return true;
665  }
666  return false;
667 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
TransState state
Definition: xact.c:176
struct TransactionStateData * parent
Definition: xact.c:191
SubTransactionId subTransactionId
Definition: xact.c:173

◆ TransactionBlockStatusCode()

char TransactionBlockStatusCode ( void  )

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

4455 {
4457 
4458  switch (s->blockState)
4459  {
4460  case TBLOCK_DEFAULT:
4461  case TBLOCK_STARTED:
4462  return 'I'; /* idle --- not in transaction */
4463  case TBLOCK_BEGIN:
4464  case TBLOCK_SUBBEGIN:
4465  case TBLOCK_INPROGRESS:
4468  case TBLOCK_SUBINPROGRESS:
4469  case TBLOCK_END:
4470  case TBLOCK_SUBRELEASE:
4471  case TBLOCK_SUBCOMMIT:
4472  case TBLOCK_PREPARE:
4473  return 'T'; /* in transaction */
4474  case TBLOCK_ABORT:
4475  case TBLOCK_SUBABORT:
4476  case TBLOCK_ABORT_END:
4477  case TBLOCK_SUBABORT_END:
4478  case TBLOCK_ABORT_PENDING:
4480  case TBLOCK_SUBRESTART:
4482  return 'E'; /* in failed transaction */
4483  }
4484 
4485  /* should never get here */
4486  elog(FATAL, "invalid transaction block state: %s",
4488  return 0; /* keep compiler quiet */
4489 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
TBlockState blockState
Definition: xact.c:177
#define FATAL
Definition: elog.h:52
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5127
#define elog
Definition: elog.h:240

◆ TransactionIdIsCurrentTransactionId()

bool TransactionIdIsCurrentTransactionId ( TransactionId  xid)

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

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

◆ UnregisterSubXactCallback()

void UnregisterSubXactCallback ( SubXactCallback  callback,
void *  arg 
)

Definition at line 3370 of file xact.c.

References SubXactCallbackItem::next, and pfree().

3371 {
3372  SubXactCallbackItem *item;
3373  SubXactCallbackItem *prev;
3374 
3375  prev = NULL;
3376  for (item = SubXact_callbacks; item; prev = item, item = item->next)
3377  {
3378  if (item->callback == callback && item->arg == arg)
3379  {
3380  if (prev)
3381  prev->next = item->next;
3382  else
3383  SubXact_callbacks = item->next;
3384  pfree(item);
3385  break;
3386  }
3387  }
3388 }
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:293
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:288
void * arg

◆ UnregisterXactCallback()

void UnregisterXactCallback ( XactCallback  callback,
void *  arg 
)

Definition at line 3315 of file xact.c.

References XactCallbackItem::next, and pfree().

3316 {
3317  XactCallbackItem *item;
3318  XactCallbackItem *prev;
3319 
3320  prev = NULL;
3321  for (item = Xact_callbacks; item; prev = item, item = item->next)
3322  {
3323  if (item->callback == callback && item->arg == arg)
3324  {
3325  if (prev)
3326  prev->next = item->next;
3327  else
3328  Xact_callbacks = item->next;
3329  pfree(item);
3330  break;
3331  }
3332  }
3333 }
struct XactCallbackItem * next
Definition: xact.c:276
void pfree(void *pointer)
Definition: mcxt.c:1031
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
static XactCallbackItem * Xact_callbacks
Definition: xact.c:281
void * arg

◆ UserAbortTransactionBlock()

void UserAbortTransactionBlock ( void  )

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

3669 {
3671 
3672  switch (s->blockState)
3673  {
3674  /*
3675  * We are inside a transaction block and we got a ROLLBACK command
3676  * from the user, so tell CommitTransactionCommand to abort and
3677  * exit the transaction block.
3678  */
3679  case TBLOCK_INPROGRESS:
3681  break;
3682 
3683  /*
3684  * We are inside a failed transaction block and we got a ROLLBACK
3685  * command from the user. Abort processing is already done, so
3686  * CommitTransactionCommand just has to cleanup and go back to
3687  * idle state.
3688  */
3689  case TBLOCK_ABORT:
3691  break;
3692 
3693  /*
3694  * We are inside a subtransaction. Mark everything up to top
3695  * level as exitable.
3696  */
3697  case TBLOCK_SUBINPROGRESS:
3698  case TBLOCK_SUBABORT:
3699  while (s->parent != NULL)
3700  {
3701  if (s->blockState == TBLOCK_SUBINPROGRESS)
3703  else if (s->blockState == TBLOCK_SUBABORT)
3705  else
3706  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3708  s = s->parent;
3709  }
3710  if (s->blockState == TBLOCK_INPROGRESS)
3712  else if (s->blockState == TBLOCK_ABORT)
3714  else
3715  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3717  break;
3718 
3719  /*
3720  * The user issued ABORT when not inside a transaction. Issue a
3721  * WARNING and go to abort state. The upcoming call to
3722  * CommitTransactionCommand() will then put us back into the
3723  * default state.
3724  *
3725  * We do the same thing with ABORT inside an implicit transaction,
3726  * although in this case we might be rolling back actual database
3727  * state changes. (It's debatable whether we should issue a
3728  * WARNING in this case, but we have done so historically.)
3729  */
3730  case TBLOCK_STARTED:
3732  ereport(WARNING,
3733  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3734  errmsg("there is no transaction in progress")));
3736  break;
3737 
3738  /*
3739  * The user issued an ABORT that somehow ran inside a parallel
3740  * worker. We can't cope with that.
3741  */
3743  ereport(FATAL,
3744  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3745  errmsg("cannot abort during a parallel operation")));
3746  break;
3747 
3748  /* These cases are invalid. */
3749  case TBLOCK_DEFAULT:
3750  case TBLOCK_BEGIN:
3751  case TBLOCK_SUBBEGIN:
3752  case TBLOCK_END:
3753  case TBLOCK_SUBRELEASE:
3754  case TBLOCK_SUBCOMMIT:
3755  case TBLOCK_ABORT_END:
3756  case TBLOCK_SUBABORT_END:
3757  case TBLOCK_ABORT_PENDING:
3759  case TBLOCK_SUBRESTART:
3761  case TBLOCK_PREPARE:
3762  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3764  break;
3765  }
3766 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
int errcode(int sqlerrcode)
Definition: elog.c:575
TBlockState blockState
Definition: xact.c:177
#define FATAL
Definition: elog.h:52
struct TransactionStateData * parent
Definition: xact.c:191
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5127
#define ereport(elevel, rest)
Definition: elog.h:141
#define WARNING
Definition: elog.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:240

◆ WarnNoTransactionBlock()

void WarnNoTransactionBlock ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3213 of file xact.c.

References CheckTransactionBlock().

Referenced by ExecSetVariableStmt(), and standard_ProcessUtility().

3214 {
3215  CheckTransactionBlock(isTopLevel, false, stmtType);
3216 }
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3228

◆ 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:323
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 5747 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.

5748 {
5749  uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
5750 
5751  /* Backup blocks are not used in xact records */
5752  Assert(!XLogRecHasAnyBlockRefs(record));
5753 
5754  if (info == XLOG_XACT_COMMIT)
5755  {
5756  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
5757  xl_xact_parsed_commit parsed;
5758 
5759  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
5760  xact_redo_commit(&parsed, XLogRecGetXid(record),
5761  record->EndRecPtr, XLogRecGetOrigin(record));
5762  }
5763  else if (info == XLOG_XACT_COMMIT_PREPARED)
5764  {
5765  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
5766  xl_xact_parsed_commit parsed;
5767 
5768  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
5769  xact_redo_commit(&parsed, parsed.twophase_xid,
5770  record->EndRecPtr, XLogRecGetOrigin(record));
5771 
5772  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
5773  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5774  PrepareRedoRemove(parsed.twophase_xid, false);
5775  LWLockRelease(TwoPhaseStateLock);
5776  }
5777  else if (info == XLOG_XACT_ABORT)
5778  {
5779  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
5780  xl_xact_parsed_abort parsed;
5781 
5782  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
5783  xact_redo_abort(&parsed, XLogRecGetXid(record));
5784  }
5785  else if (info == XLOG_XACT_ABORT_PREPARED)
5786  {
5787  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
5788  xl_xact_parsed_abort parsed;
5789 
5790  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
5791  xact_redo_abort(&parsed, parsed.twophase_xid);
5792 
5793  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
5794  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5795  PrepareRedoRemove(parsed.twophase_xid, false);
5796  LWLockRelease(TwoPhaseStateLock);
5797  }
5798  else if (info == XLOG_XACT_PREPARE)
5799  {
5800  /*
5801  * Store xid and start/end pointers of the WAL record in TwoPhaseState
5802  * gxact entry.
5803  */
5804  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5806  record->ReadRecPtr,
5807  record->EndRecPtr,
5808  XLogRecGetOrigin(record));
5809  LWLockRelease(TwoPhaseStateLock);
5810  }
5811  else if (info == XLOG_XACT_ASSIGNMENT)
5812  {
5814 
5817  xlrec->nsubxacts, xlrec->xsub);
5818  }
5819  else
5820  elog(PANIC, "xact_redo: unknown op code %u", info);
5821 }
#define XLOG_XACT_COMMIT
Definition: xact.h:140
void PrepareRedoRemove(TransactionId xid, bool giveWarning)
Definition: twophase.c:2480
#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:5515
TransactionId twophase_xid
Definition: xact.h:314
unsigned char uint8
Definition: c.h:323
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:5677
void PrepareRedoAdd(char *buf, XLogRecPtr start_lsn, XLogRecPtr end_lsn, RepOriginId origin_id)
Definition: twophase.c:2410
TransactionId twophase_xid
Definition: xact.h:339
#define Assert(condition)
Definition: c.h:699
#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 XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:232
void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)
Definition: procarray.c:912
#define elog
Definition: elog.h:240
#define XLOG_XACT_COMMIT_PREPARED
Definition: xact.h:143
HotStandbyState standbyState
Definition: xlog.c:197

◆ xactGetCommittedChildren()

int xactGetCommittedChildren ( TransactionId **  ptr)

Definition at line 5210 of file xact.c.

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

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

5211 {
5213 
5214  if (s->nChildXids == 0)
5215  *ptr = NULL;
5216  else
5217  *ptr = s->childXids;
5218 
5219  return s->nChildXids;
5220 }
static TransactionState CurrentTransactionState
Definition: xact.c:232
TransactionId * childXids
Definition: xact.c:182

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

5394 {
5395  xl_xact_abort xlrec;
5396  xl_xact_xinfo xl_xinfo;
5397  xl_xact_subxacts xl_subxacts;
5398  xl_xact_relfilenodes xl_relfilenodes;
5399  xl_xact_twophase xl_twophase;
5400  xl_xact_dbinfo xl_dbinfo;
5401  xl_xact_origin xl_origin;
5402 
5403  uint8 info;
5404 
5405  Assert(CritSectionCount > 0);
5406 
5407  xl_xinfo.xinfo = 0;
5408 
5409  /* decide between a plain and 2pc abort */
5410  if (!TransactionIdIsValid(twophase_xid))
5411  info = XLOG_XACT_ABORT;
5412  else
5413  info = XLOG_XACT_ABORT_PREPARED;
5414 
5415 
5416  /* First figure out and collect all the information needed */
5417 
5418  xlrec.xact_time = abort_time;
5419 
5420  if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5421  xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5422 
5423  if (nsubxacts > 0)
5424  {
5425  xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5426  xl_subxacts.nsubxacts = nsubxacts;
5427  }
5428 
5429  if (nrels > 0)
5430  {
5431  xl_xinfo.xinfo |= XACT_XINFO_HAS_RELFILENODES;
5432  xl_relfilenodes.nrels = nrels;
5433  }
5434 
5435  if (TransactionIdIsValid(twophase_xid))
5436  {
5437  xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5438  xl_twophase.xid = twophase_xid;
5439  Assert(twophase_gid != NULL);
5440 
5441  if (XLogLogicalInfoActive())
5442  xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
5443  }
5444 
5445  if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
5446  {
5447  xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5448  xl_dbinfo.dbId = MyDatabaseId;
5449  xl_dbinfo.tsId = MyDatabaseTableSpace;
5450  }
5451 
5452  /* dump transaction origin information only for abort prepared */
5454  TransactionIdIsValid(twophase_xid) &&
5456  {
5457  xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
5458 
5461  }
5462 
5463  if (xl_xinfo.xinfo != 0)
5464  info |= XLOG_XACT_HAS_INFO;
5465 
5466  /* Then include all the collected data into the abort record. */
5467 
5468  XLogBeginInsert();
5469 
5470  XLogRegisterData((char *) (&xlrec), MinSizeOfXactAbort);
5471 
5472  if (xl_xinfo.xinfo != 0)
5473  XLogRegisterData((char *) (&xl_xinfo), sizeof(xl_xinfo));
5474 
5475  if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5476  XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
5477 
5478  if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5479  {
5480  XLogRegisterData((char *) (&xl_subxacts),
5482  XLogRegisterData((char *) subxacts,
5483  nsubxacts * sizeof(TransactionId));
5484  }
5485 
5486  if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILENODES)
5487  {
5488  XLogRegisterData((char *) (&xl_relfilenodes),
5490  XLogRegisterData((char *) rels,
5491  nrels * sizeof(RelFileNode));
5492  }
5493 
5494  if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5495  {
5496  XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
5497  if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
5498  XLogRegisterData((char *) twophase_gid, strlen(twophase_gid) + 1);
5499  }
5500 
5501  if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5502  XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
5503 
5504  if (TransactionIdIsValid(twophase_xid))
5506 
5507  return XLogInsert(RM_XACT_ID, info);
5508 }
#define XACT_XINFO_HAS_ORIGIN
Definition: xact.h:164
uint32 TransactionId
Definition: c.h:474
TransactionId xid
Definition: xact.h:253
unsigned char uint8
Definition: c.h:323
#define MinSizeOfXactAbort
Definition: xact.h:290
#define XLOG_XACT_HAS_INFO
Definition: xact.h:153
#define XLOG_INCLUDE_ORIGIN
Definition: xlog.h:192
#define XACT_XINFO_HAS_SUBXACTS
Definition: xact.h:160
#define MinSizeOfXactRelfilenodes
Definition: xact.h:242
TimestampTz xact_time
Definition: xact.h:279