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

Go to the source code of this file.

Data Structures

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

Macros

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

Typedefs

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

Enumerations

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

Functions

bool IsTransactionState (void)
 
bool IsAbortedTransactionBlockState (void)
 
TransactionId GetTopTransactionId (void)
 
TransactionId GetTopTransactionIdIfAny (void)
 
TransactionId GetCurrentTransactionId (void)
 
TransactionId GetCurrentTransactionIdIfAny (void)
 
TransactionId GetStableLatestTransactionId (void)
 
SubTransactionId GetCurrentSubTransactionId (void)
 
void MarkCurrentTransactionIdLoggedIfAny (void)
 
bool SubTransactionIsActive (SubTransactionId subxid)
 
CommandId GetCurrentCommandId (bool used)
 
void SetParallelStartTimestamps (TimestampTz xact_ts, TimestampTz stmt_ts)
 
TimestampTz GetCurrentTransactionStartTimestamp (void)
 
TimestampTz GetCurrentStatementStartTimestamp (void)
 
TimestampTz GetCurrentTransactionStopTimestamp (void)
 
void SetCurrentStatementStartTimestamp (void)
 
int GetCurrentTransactionNestLevel (void)
 
bool TransactionIdIsCurrentTransactionId (TransactionId xid)
 
void CommandCounterIncrement (void)
 
void ForceSyncCommit (void)
 
void StartTransactionCommand (void)
 
void CommitTransactionCommand (void)
 
void AbortCurrentTransaction (void)
 
void BeginTransactionBlock (void)
 
bool EndTransactionBlock (void)
 
bool PrepareTransactionBlock (const char *gid)
 
void UserAbortTransactionBlock (void)
 
void BeginImplicitTransactionBlock (void)
 
void EndImplicitTransactionBlock (void)
 
void ReleaseSavepoint (const char *name)
 
void DefineSavepoint (const char *name)
 
void RollbackToSavepoint (const char *name)
 
void BeginInternalSubTransaction (const char *name)
 
void ReleaseCurrentSubTransaction (void)
 
void RollbackAndReleaseCurrentSubTransaction (void)
 
bool IsSubTransaction (void)
 
Size EstimateTransactionStateSpace (void)
 
void SerializeTransactionState (Size maxsize, char *start_address)
 
void StartParallelWorkerTransaction (char *tstatespace)
 
void EndParallelWorkerTransaction (void)
 
bool IsTransactionBlock (void)
 
bool IsTransactionOrTransactionBlock (void)
 
char TransactionBlockStatusCode (void)
 
void AbortOutOfAnyTransaction (void)
 
void PreventInTransactionBlock (bool isTopLevel, const char *stmtType)
 
void RequireTransactionBlock (bool isTopLevel, const char *stmtType)
 
void WarnNoTransactionBlock (bool isTopLevel, const char *stmtType)
 
bool IsInTransactionBlock (bool isTopLevel)
 
void RegisterXactCallback (XactCallback callback, void *arg)
 
void UnregisterXactCallback (XactCallback callback, void *arg)
 
void RegisterSubXactCallback (SubXactCallback callback, void *arg)
 
void UnregisterSubXactCallback (SubXactCallback callback, void *arg)
 
int xactGetCommittedChildren (TransactionId **ptr)
 
XLogRecPtr XactLogCommitRecord (TimestampTz commit_time, int nsubxacts, TransactionId *subxacts, int nrels, RelFileNode *rels, int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInval, bool forceSync, int xactflags, TransactionId twophase_xid, const char *twophase_gid)
 
XLogRecPtr XactLogAbortRecord (TimestampTz abort_time, int nsubxacts, TransactionId *subxacts, int nrels, RelFileNode *rels, int xactflags, TransactionId twophase_xid, const char *twophase_gid)
 
void xact_redo (XLogReaderState *record)
 
void xact_desc (StringInfo buf, XLogReaderState *record)
 
const char * xact_identify (uint8 info)
 
void ParseCommitRecord (uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *parsed)
 
void ParseAbortRecord (uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed)
 
void EnterParallelMode (void)
 
void ExitParallelMode (void)
 
bool IsInParallelMode (void)
 

Variables

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

Macro Definition Documentation

◆ GIDSIZE

#define GIDSIZE   200

Definition at line 30 of file xact.h.

Referenced by MarkAsPreparing().

◆ IsolationIsSerializable

◆ IsolationUsesXactSnapshot

◆ MinSizeOfXactAbort

#define MinSizeOfXactAbort   sizeof(xl_xact_abort)

Definition at line 290 of file xact.h.

Referenced by ParseAbortRecord(), and XactLogAbortRecord().

◆ MinSizeOfXactAssignment

#define MinSizeOfXactAssignment   offsetof(xl_xact_assignment, xsub)

Definition at line 195 of file xact.h.

Referenced by AssignTransactionId().

◆ MinSizeOfXactCommit

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

Definition at line 275 of file xact.h.

Referenced by ParseCommitRecord().

◆ MinSizeOfXactInvals

#define MinSizeOfXactInvals   offsetof(xl_xact_invals, msgs)

Definition at line 249 of file xact.h.

Referenced by ParseCommitRecord(), and XactLogCommitRecord().

◆ MinSizeOfXactRelfilenodes

#define MinSizeOfXactRelfilenodes   offsetof(xl_xact_relfilenodes, xnodes)

◆ MinSizeOfXactSubxacts

#define MinSizeOfXactSubxacts   offsetof(xl_xact_subxacts, subxacts)

◆ SYNCHRONOUS_COMMIT_ON

#define SYNCHRONOUS_COMMIT_ON   SYNCHRONOUS_COMMIT_REMOTE_FLUSH

Definition at line 75 of file xact.h.

◆ XACT_COMPLETION_APPLY_FEEDBACK

#define XACT_COMPLETION_APPLY_FEEDBACK   (1U << 29)

Definition at line 176 of file xact.h.

Referenced by XactLogCommitRecord().

◆ XACT_COMPLETION_FORCE_SYNC_COMMIT

#define XACT_COMPLETION_FORCE_SYNC_COMMIT   (1U << 31)

Definition at line 178 of file xact.h.

Referenced by XactLogCommitRecord().

◆ XACT_COMPLETION_UPDATE_RELCACHE_FILE

#define XACT_COMPLETION_UPDATE_RELCACHE_FILE   (1U << 30)

Definition at line 177 of file xact.h.

Referenced by XactLogCommitRecord().

◆ XACT_FLAGS_ACCESSEDTEMPREL

#define XACT_FLAGS_ACCESSEDTEMPREL   (1U << 0)

◆ XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK

#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK   (1U << 1)

◆ XACT_READ_COMMITTED

#define XACT_READ_COMMITTED   1

Definition at line 36 of file xact.h.

Referenced by InitPostgres().

◆ XACT_READ_UNCOMMITTED

#define XACT_READ_UNCOMMITTED   0

Definition at line 35 of file xact.h.

◆ XACT_REPEATABLE_READ

#define XACT_REPEATABLE_READ   2

Definition at line 37 of file xact.h.

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

◆ XACT_SERIALIZABLE

#define XACT_SERIALIZABLE   3

Definition at line 38 of file xact.h.

Referenced by check_XactIsoLevel(), and ImportSnapshot().

◆ XACT_XINFO_HAS_AE_LOCKS

#define XACT_XINFO_HAS_AE_LOCKS   (1U << 6)

Definition at line 165 of file xact.h.

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

◆ XACT_XINFO_HAS_DBINFO

#define XACT_XINFO_HAS_DBINFO   (1U << 0)

◆ XACT_XINFO_HAS_GID

#define XACT_XINFO_HAS_GID   (1U << 7)

◆ XACT_XINFO_HAS_INVALS

#define XACT_XINFO_HAS_INVALS   (1U << 3)

Definition at line 162 of file xact.h.

Referenced by ParseCommitRecord(), and XactLogCommitRecord().

◆ XACT_XINFO_HAS_ORIGIN

#define XACT_XINFO_HAS_ORIGIN   (1U << 5)

◆ XACT_XINFO_HAS_RELFILENODES

#define XACT_XINFO_HAS_RELFILENODES   (1U << 2)

◆ XACT_XINFO_HAS_SUBXACTS

#define XACT_XINFO_HAS_SUBXACTS   (1U << 1)

◆ XACT_XINFO_HAS_TWOPHASE

#define XACT_XINFO_HAS_TWOPHASE   (1U << 4)

◆ XactCompletionApplyFeedback

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

Definition at line 181 of file xact.h.

Referenced by xact_redo_commit().

◆ XactCompletionForceSyncCommit

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

Definition at line 185 of file xact.h.

Referenced by xact_desc_commit(), and xact_redo_commit().

◆ XactCompletionRelcacheInitFileInval

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

Definition at line 183 of file xact.h.

Referenced by xact_desc_commit(), and xact_redo_commit().

◆ XLOG_XACT_ABORT

#define XLOG_XACT_ABORT   0x20

◆ XLOG_XACT_ABORT_PREPARED

#define XLOG_XACT_ABORT_PREPARED   0x40

◆ XLOG_XACT_ASSIGNMENT

#define XLOG_XACT_ASSIGNMENT   0x50

Definition at line 145 of file xact.h.

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

◆ XLOG_XACT_COMMIT

◆ XLOG_XACT_COMMIT_PREPARED

#define XLOG_XACT_COMMIT_PREPARED   0x30

◆ XLOG_XACT_HAS_INFO

#define XLOG_XACT_HAS_INFO   0x80

◆ XLOG_XACT_OPMASK

◆ XLOG_XACT_PREPARE

#define XLOG_XACT_PREPARE   0x10

Definition at line 141 of file xact.h.

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

Typedef Documentation

◆ SubXactCallback

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

Definition at line 127 of file xact.h.

◆ XactCallback

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

Definition at line 117 of file xact.h.

◆ xl_xact_abort

◆ xl_xact_assignment

◆ xl_xact_commit

◆ xl_xact_dbinfo

◆ xl_xact_invals

◆ xl_xact_origin

◆ xl_xact_parsed_abort

◆ xl_xact_parsed_commit

◆ xl_xact_parsed_prepare

◆ xl_xact_relfilenodes

◆ xl_xact_subxacts

◆ xl_xact_twophase

◆ xl_xact_xinfo

Enumeration Type Documentation

◆ SubXactEvent

Enumerator
SUBXACT_EVENT_START_SUB 
SUBXACT_EVENT_COMMIT_SUB 
SUBXACT_EVENT_ABORT_SUB 
SUBXACT_EVENT_PRE_COMMIT_SUB 

Definition at line 119 of file xact.h.

◆ SyncCommitLevel

Enumerator
SYNCHRONOUS_COMMIT_OFF 
SYNCHRONOUS_COMMIT_LOCAL_FLUSH 
SYNCHRONOUS_COMMIT_REMOTE_WRITE 
SYNCHRONOUS_COMMIT_REMOTE_FLUSH 
SYNCHRONOUS_COMMIT_REMOTE_APPLY 

Definition at line 64 of file xact.h.

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

◆ XactEvent

enum XactEvent
Enumerator
XACT_EVENT_COMMIT 
XACT_EVENT_PARALLEL_COMMIT 
XACT_EVENT_ABORT 
XACT_EVENT_PARALLEL_ABORT 
XACT_EVENT_PREPARE 
XACT_EVENT_PRE_COMMIT 
XACT_EVENT_PARALLEL_PRE_COMMIT 
XACT_EVENT_PRE_PREPARE 

Definition at line 105 of file xact.h.

Function Documentation

◆ AbortCurrentTransaction()

void AbortCurrentTransaction ( void  )

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

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

◆ AbortOutOfAnyTransaction()

void AbortOutOfAnyTransaction ( void  )

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

4342 {
4344 
4345  /* Ensure we're not running in a doomed memory context */
4346  AtAbort_Memory();
4347 
4348  /*
4349  * Get out of any transaction or nested transaction
4350  */
4351  do
4352  {
4353  switch (s->blockState)
4354  {
4355  case TBLOCK_DEFAULT:
4356  if (s->state == TRANS_DEFAULT)
4357  {
4358  /* Not in a transaction, do nothing */
4359  }
4360  else
4361  {
4362  /*
4363  * We can get here after an error during transaction start
4364  * (state will be TRANS_START). Need to clean up the
4365  * incompletely started transaction. First, adjust the
4366  * low-level state to suppress warning message from
4367  * AbortTransaction.
4368  */
4369  if (s->state == TRANS_START)
4370  s->state = TRANS_INPROGRESS;
4371  AbortTransaction();
4373  }
4374  break;
4375  case TBLOCK_STARTED:
4376  case TBLOCK_BEGIN:
4377  case TBLOCK_INPROGRESS:
4380  case TBLOCK_END:
4381  case TBLOCK_ABORT_PENDING:
4382  case TBLOCK_PREPARE:
4383  /* In a transaction, so clean up */
4384  AbortTransaction();
4387  break;
4388  case TBLOCK_ABORT:
4389  case TBLOCK_ABORT_END:
4390 
4391  /*
4392  * AbortTransaction is already done, still need Cleanup.
4393  * However, if we failed partway through running ROLLBACK,
4394  * there will be an active portal running that command, which
4395  * we need to shut down before doing CleanupTransaction.
4396  */
4397  AtAbort_Portals();
4400  break;
4401 
4402  /*
4403  * In a subtransaction, so clean it up and abort parent too
4404  */
4405  case TBLOCK_SUBBEGIN:
4406  case TBLOCK_SUBINPROGRESS:
4407  case TBLOCK_SUBRELEASE:
4408  case TBLOCK_SUBCOMMIT:
4410  case TBLOCK_SUBRESTART:
4413  s = CurrentTransactionState; /* changed by pop */
4414  break;
4415 
4416  case TBLOCK_SUBABORT:
4417  case TBLOCK_SUBABORT_END:
4419  /* As above, but AbortSubTransaction already done */
4420  if (s->curTransactionOwner)
4421  {
4422  /* As in TBLOCK_ABORT, might have a live portal to zap */
4427  }
4429  s = CurrentTransactionState; /* changed by pop */
4430  break;
4431  }
4432  } while (s->blockState != TBLOCK_DEFAULT);
4433 
4434  /* Should be out of all subxacts now */
4435  Assert(s->parent == NULL);
4436 
4437  /* If we didn't actually have anything to do, revert to TopMemoryContext */
4438  AtCleanup_Memory();
4439 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
static void AtCleanup_Memory(void)
Definition: xact.c:1728
void AtAbort_Portals(void)
Definition: portalmem.c:772
TBlockState blockState
Definition: xact.c:178
TransState state
Definition: xact.c:177
ResourceOwner curTransactionOwner
Definition: xact.c:182
static void CleanupTransaction(void)
Definition: xact.c:2647
struct TransactionStateData * parent
Definition: xact.c:192
SubTransactionId subTransactionId
Definition: xact.c:174
static void AbortSubTransaction(void)
Definition: xact.c:4688
static void AtAbort_Memory(void)
Definition: xact.c:1638
static void AbortTransaction(void)
Definition: xact.c:2466
#define Assert(condition)
Definition: c.h:732
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition: portalmem.c:968
static void CleanupSubTransaction(void)
Definition: xact.c:4837

◆ BeginImplicitTransactionBlock()

void BeginImplicitTransactionBlock ( void  )

Definition at line 3801 of file xact.c.

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

Referenced by exec_simple_query().

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

◆ BeginInternalSubTransaction()

void BeginInternalSubTransaction ( const char *  name)

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

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

◆ BeginTransactionBlock()

void BeginTransactionBlock ( void  )

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

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

◆ CommandCounterIncrement()

void CommandCounterIncrement ( void  )

Definition at line 918 of file xact.c.

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

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

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

◆ CommitTransactionCommand()

void CommitTransactionCommand ( void  )

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

2768 {
2770 
2771  switch (s->blockState)
2772  {
2773  /*
2774  * These shouldn't happen. TBLOCK_DEFAULT means the previous
2775  * StartTransactionCommand didn't set the STARTED state
2776  * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
2777  * by EndParallelWorkerTransaction(), not this function.
2778  */
2779  case TBLOCK_DEFAULT:
2781  elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2783  break;
2784 
2785  /*
2786  * If we aren't in a transaction block, just do our usual
2787  * transaction commit, and return to the idle state.
2788  */
2789  case TBLOCK_STARTED:
2792  break;
2793 
2794  /*
2795  * We are completing a "BEGIN TRANSACTION" command, so we change
2796  * to the "transaction block in progress" state and return. (We
2797  * assume the BEGIN did nothing to the database, so we need no
2798  * CommandCounterIncrement.)
2799  */
2800  case TBLOCK_BEGIN:
2802  break;
2803 
2804  /*
2805  * This is the case when we have finished executing a command
2806  * someplace within a transaction block. We increment the command
2807  * counter and return.
2808  */
2809  case TBLOCK_INPROGRESS:
2811  case TBLOCK_SUBINPROGRESS:
2813  break;
2814 
2815  /*
2816  * We are completing a "COMMIT" command. Do it and return to the
2817  * idle state.
2818  */
2819  case TBLOCK_END:
2822  break;
2823 
2824  /*
2825  * Here we are in the middle of a transaction block but one of the
2826  * commands caused an abort so we do nothing but remain in the
2827  * abort state. Eventually we will get a ROLLBACK command.
2828  */
2829  case TBLOCK_ABORT:
2830  case TBLOCK_SUBABORT:
2831  break;
2832 
2833  /*
2834  * Here we were in an aborted transaction block and we just got
2835  * the ROLLBACK command from the user, so clean up the
2836  * already-aborted transaction and return to the idle state.
2837  */
2838  case TBLOCK_ABORT_END:
2841  break;
2842 
2843  /*
2844  * Here we were in a perfectly good transaction block but the user
2845  * told us to ROLLBACK anyway. We have to abort the transaction
2846  * and then clean up.
2847  */
2848  case TBLOCK_ABORT_PENDING:
2849  AbortTransaction();
2852  break;
2853 
2854  /*
2855  * We are completing a "PREPARE TRANSACTION" command. Do it and
2856  * return to the idle state.
2857  */
2858  case TBLOCK_PREPARE:
2861  break;
2862 
2863  /*
2864  * We were just issued a SAVEPOINT inside a transaction block.
2865  * Start a subtransaction. (DefineSavepoint already did
2866  * PushTransaction, so as to have someplace to put the SUBBEGIN
2867  * state.)
2868  */
2869  case TBLOCK_SUBBEGIN:
2872  break;
2873 
2874  /*
2875  * We were issued a RELEASE command, so we end the current
2876  * subtransaction and return to the parent transaction. The parent
2877  * might be ended too, so repeat till we find an INPROGRESS
2878  * transaction or subtransaction.
2879  */
2880  case TBLOCK_SUBRELEASE:
2881  do
2882  {
2884  s = CurrentTransactionState; /* changed by pop */
2885  } while (s->blockState == TBLOCK_SUBRELEASE);
2886 
2889  break;
2890 
2891  /*
2892  * We were issued a COMMIT, so we end the current subtransaction
2893  * hierarchy and perform final commit. We do this by rolling up
2894  * any subtransactions into their parent, which leads to O(N^2)
2895  * operations with respect to resource owners - this isn't that
2896  * bad until we approach a thousands of savepoints but is
2897  * necessary for correctness should after triggers create new
2898  * resource owners.
2899  */
2900  case TBLOCK_SUBCOMMIT:
2901  do
2902  {
2904  s = CurrentTransactionState; /* changed by pop */
2905  } while (s->blockState == TBLOCK_SUBCOMMIT);
2906  /* If we had a COMMIT command, finish off the main xact too */
2907  if (s->blockState == TBLOCK_END)
2908  {
2909  Assert(s->parent == NULL);
2912  }
2913  else if (s->blockState == TBLOCK_PREPARE)
2914  {
2915  Assert(s->parent == NULL);
2918  }
2919  else
2920  elog(ERROR, "CommitTransactionCommand: unexpected state %s",
2922  break;
2923 
2924  /*
2925  * The current already-failed subtransaction is ending due to a
2926  * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2927  * examine the parent (which could be in any of several states).
2928  */
2929  case TBLOCK_SUBABORT_END:
2932  break;
2933 
2934  /*
2935  * As above, but it's not dead yet, so abort first.
2936  */
2941  break;
2942 
2943  /*
2944  * The current subtransaction is the target of a ROLLBACK TO
2945  * command. Abort and pop it, then start a new subtransaction
2946  * with the same name.
2947  */
2948  case TBLOCK_SUBRESTART:
2949  {
2950  char *name;
2951  int savepointLevel;
2952 
2953  /* save name and keep Cleanup from freeing it */
2954  name = s->name;
2955  s->name = NULL;
2956  savepointLevel = s->savepointLevel;
2957 
2960 
2961  DefineSavepoint(NULL);
2962  s = CurrentTransactionState; /* changed by push */
2963  s->name = name;
2964  s->savepointLevel = savepointLevel;
2965 
2966  /* This is the same as TBLOCK_SUBBEGIN case */
2970  }
2971  break;
2972 
2973  /*
2974  * Same as above, but the subtransaction had already failed, so we
2975  * don't need AbortSubTransaction.
2976  */
2978  {
2979  char *name;
2980  int savepointLevel;
2981 
2982  /* save name and keep Cleanup from freeing it */
2983  name = s->name;
2984  s->name = NULL;
2985  savepointLevel = s->savepointLevel;
2986 
2988 
2989  DefineSavepoint(NULL);
2990  s = CurrentTransactionState; /* changed by push */
2991  s->name = name;
2992  s->savepointLevel = savepointLevel;
2993 
2994  /* This is the same as TBLOCK_SUBBEGIN case */
2998  }
2999  break;
3000  }
3001 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
#define AssertState(condition)
Definition: c.h:735
void CommitTransactionCommand(void)
Definition: xact.c:2767
void DefineSavepoint(const char *name)
Definition: xact.c:3848
TBlockState blockState
Definition: xact.c:178
static void PrepareTransaction(void)
Definition: xact.c:2190
#define ERROR
Definition: elog.h:43
static void CommitSubTransaction(void)
Definition: xact.c:4579
#define FATAL
Definition: elog.h:52
static void CleanupTransaction(void)
Definition: xact.c:2647
struct TransactionStateData * parent
Definition: xact.c:192
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5150
static void AbortSubTransaction(void)
Definition: xact.c:4688
void CommandCounterIncrement(void)
Definition: xact.c:918
static void AbortTransaction(void)
Definition: xact.c:2466
#define Assert(condition)
Definition: c.h:732
static void CleanupSubTransaction(void)
Definition: xact.c:4837
const char * name
Definition: encode.c:521
#define elog(elevel,...)
Definition: elog.h:226
static void CommitTransaction(void)
Definition: xact.c:1953
static void StartSubTransaction(void)
Definition: xact.c:4541

◆ DefineSavepoint()

void DefineSavepoint ( const char *  name)

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

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

◆ EndImplicitTransactionBlock()

void EndImplicitTransactionBlock ( void  )

Definition at line 3826 of file xact.c.

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

Referenced by exec_simple_query().

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

◆ EndParallelWorkerTransaction()

void EndParallelWorkerTransaction ( void  )

Definition at line 5087 of file xact.c.

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

Referenced by ParallelWorkerMain().

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

◆ EndTransactionBlock()

bool EndTransactionBlock ( void  )

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

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

◆ EnterParallelMode()

void EnterParallelMode ( void  )

Definition at line 876 of file xact.c.

References Assert, CurrentTransactionState, and TransactionStateData::parallelModeLevel.

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

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

◆ EstimateTransactionStateSpace()

Size EstimateTransactionStateSpace ( void  )

Definition at line 4963 of file xact.c.

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

Referenced by InitializeParallelDSM().

4964 {
4965  TransactionState s;
4966  Size nxids = 6; /* iso level, deferrable, top & current XID,
4967  * command counter, XID count */
4968 
4969  for (s = CurrentTransactionState; s != NULL; s = s->parent)
4970  {
4972  nxids = add_size(nxids, 1);
4973  nxids = add_size(nxids, s->nChildXids);
4974  }
4975 
4976  nxids = add_size(nxids, nParallelCurrentXids);
4977  return mul_size(nxids, sizeof(TransactionId));
4978 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
uint32 TransactionId
Definition: c.h:507
int nParallelCurrentXids
Definition: xact.c:108
struct TransactionStateData * parent
Definition: xact.c:192
Size mul_size(Size s1, Size s2)
Definition: shmem.c:492
Size add_size(Size s1, Size s2)
Definition: shmem.c:475
TransactionId transactionId
Definition: xact.c:173
size_t Size
Definition: c.h:466
#define TransactionIdIsValid(xid)
Definition: transam.h:41

◆ ExitParallelMode()

void ExitParallelMode ( void  )

Definition at line 889 of file xact.c.

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

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

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

◆ ForceSyncCommit()

void ForceSyncCommit ( void  )

Definition at line 966 of file xact.c.

References forceSyncCommit.

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

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

◆ GetCurrentCommandId()

CommandId GetCurrentCommandId ( bool  used)

Definition at line 661 of file xact.c.

References Assert, currentCommandId, currentCommandIdUsed, and IsParallelWorker.

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

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

◆ GetCurrentStatementStartTimestamp()

TimestampTz GetCurrentStatementStartTimestamp ( void  )

Definition at line 707 of file xact.c.

References stmtStartTimestamp.

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

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

◆ GetCurrentSubTransactionId()

◆ GetCurrentTransactionId()

◆ GetCurrentTransactionIdIfAny()

TransactionId GetCurrentTransactionIdIfAny ( void  )

Definition at line 416 of file xact.c.

References TransactionStateData::transactionId.

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

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

◆ GetCurrentTransactionNestLevel()

◆ GetCurrentTransactionStartTimestamp()

TimestampTz GetCurrentTransactionStartTimestamp ( void  )

◆ GetCurrentTransactionStopTimestamp()

TimestampTz GetCurrentTransactionStopTimestamp ( void  )

Definition at line 719 of file xact.c.

References GetCurrentTimestamp(), and xactStopTimestamp.

Referenced by pgstat_report_stat().

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

◆ GetStableLatestTransactionId()

TransactionId GetStableLatestTransactionId ( void  )

Definition at line 443 of file xact.c.

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

Referenced by xid_age().

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

◆ GetTopTransactionId()

TransactionId GetTopTransactionId ( void  )

Definition at line 371 of file xact.c.

References AssignTransactionId(), TransactionIdIsValid, and XactTopTransactionId.

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

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

◆ GetTopTransactionIdIfAny()

◆ IsAbortedTransactionBlockState()

◆ IsInParallelMode()

◆ IsInTransactionBlock()

bool IsInTransactionBlock ( bool  isTopLevel)

Definition at line 3290 of file xact.c.

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

Referenced by vacuum().

3291 {
3292  /*
3293  * Return true on same conditions that would make
3294  * PreventInTransactionBlock error out
3295  */
3296  if (IsTransactionBlock())
3297  return true;
3298 
3299  if (IsSubTransaction())
3300  return true;
3301 
3302  if (!isTopLevel)
3303  return true;
3304 
3307  return true;
3308 
3309  return false;
3310 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
TBlockState blockState
Definition: xact.c:178
bool IsTransactionBlock(void)
Definition: xact.c:4445
bool IsSubTransaction(void)
Definition: xact.c:4518

◆ IsSubTransaction()

◆ IsTransactionBlock()

bool IsTransactionBlock ( void  )

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

4446 {
4448 
4450  return false;
4451 
4452  return true;
4453 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
TBlockState blockState
Definition: xact.c:178

◆ IsTransactionOrTransactionBlock()

bool IsTransactionOrTransactionBlock ( void  )

◆ IsTransactionState()

bool IsTransactionState ( void  )

Definition at line 332 of file xact.c.

References CurrentTransactionState, TransactionStateData::state, and TRANS_INPROGRESS.

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

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

◆ MarkCurrentTransactionIdLoggedIfAny()

void MarkCurrentTransactionIdLoggedIfAny ( void  )

Definition at line 427 of file xact.c.

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

Referenced by XLogInsertRecord().

428 {
431 }
static TransactionState CurrentTransactionState
Definition: xact.c:214
TransactionId transactionId
Definition: xact.c:173
#define TransactionIdIsValid(xid)
Definition: transam.h:41

◆ ParseAbortRecord()

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

Definition at line 129 of file xactdesc.c.

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

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

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

◆ ParseCommitRecord()

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

Definition at line 34 of file xactdesc.c.

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

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

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

◆ PrepareTransactionBlock()

bool PrepareTransactionBlock ( const char *  gid)

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

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

◆ PreventInTransactionBlock()

void PreventInTransactionBlock ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3176 of file xact.c.

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

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

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

◆ RegisterSubXactCallback()

void RegisterSubXactCallback ( SubXactCallback  callback,
void *  arg 
)

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

3381 {
3382  SubXactCallbackItem *item;
3383 
3384  item = (SubXactCallbackItem *)
3386  item->callback = callback;
3387  item->arg = arg;
3388  item->next = SubXact_callbacks;
3389  SubXact_callbacks = item;
3390 }
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:275
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
struct SubXactCallbackItem * next
Definition: xact.c:270
SubXactCallback callback
Definition: xact.c:271
MemoryContext TopMemoryContext
Definition: mcxt.c:44
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:771
void * arg

◆ RegisterXactCallback()

void RegisterXactCallback ( XactCallback  callback,
void *  arg 
)

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

3326 {
3327  XactCallbackItem *item;
3328 
3329  item = (XactCallbackItem *)
3331  item->callback = callback;
3332  item->arg = arg;
3333  item->next = Xact_callbacks;
3334  Xact_callbacks = item;
3335 }
struct XactCallbackItem * next
Definition: xact.c:258
void * arg
Definition: xact.c:260
XactCallback callback
Definition: xact.c:259
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
MemoryContext TopMemoryContext
Definition: mcxt.c:44
static XactCallbackItem * Xact_callbacks
Definition: xact.c:263
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:771
void * arg

◆ ReleaseCurrentSubTransaction()

void ReleaseCurrentSubTransaction ( void  )

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

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

◆ ReleaseSavepoint()

void ReleaseSavepoint ( const char *  name)

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

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

◆ RequireTransactionBlock()

void RequireTransactionBlock ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3242 of file xact.c.

References CheckTransactionBlock().

Referenced by PerformCursorOpen(), and standard_ProcessUtility().

3243 {
3244  CheckTransactionBlock(isTopLevel, true, stmtType);
3245 }
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3251

◆ RollbackAndReleaseCurrentSubTransaction()

void RollbackAndReleaseCurrentSubTransaction ( void  )

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

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

◆ RollbackToSavepoint()

void RollbackToSavepoint ( const char *  name)

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

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

◆ SerializeTransactionState()

void SerializeTransactionState ( Size  maxsize,
char *  start_address 
)

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

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

◆ SetCurrentStatementStartTimestamp()

void SetCurrentStatementStartTimestamp ( void  )

Definition at line 733 of file xact.c.

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

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

734 {
735  if (!IsParallelWorker())
737  else
739 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
static TimestampTz stmtStartTimestamp
Definition: xact.c:232
#define IsParallelWorker()
Definition: parallel.h:60
#define Assert(condition)
Definition: c.h:732

◆ SetParallelStartTimestamps()

void SetParallelStartTimestamps ( TimestampTz  xact_ts,
TimestampTz  stmt_ts 
)

Definition at line 687 of file xact.c.

References Assert, IsParallelWorker, stmtStartTimestamp, and xactStartTimestamp.

Referenced by ParallelWorkerMain().

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

◆ StartParallelWorkerTransaction()

void StartParallelWorkerTransaction ( char *  tstatespace)

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

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

◆ StartTransactionCommand()

void StartTransactionCommand ( void  )

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

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

◆ SubTransactionIsActive()

bool SubTransactionIsActive ( SubTransactionId  subxid)

Definition at line 637 of file xact.c.

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

Referenced by fmgr_sql().

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

◆ TransactionBlockStatusCode()

char TransactionBlockStatusCode ( void  )

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

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

◆ TransactionIdIsCurrentTransactionId()

bool TransactionIdIsCurrentTransactionId ( TransactionId  xid)

Definition at line 769 of file xact.c.

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

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

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

◆ UnregisterSubXactCallback()

void UnregisterSubXactCallback ( SubXactCallback  callback,
void *  arg 
)

Definition at line 3393 of file xact.c.

References SubXactCallbackItem::next, and pfree().

3394 {
3395  SubXactCallbackItem *item;
3396  SubXactCallbackItem *prev;
3397 
3398  prev = NULL;
3399  for (item = SubXact_callbacks; item; prev = item, item = item->next)
3400  {
3401  if (item->callback == callback && item->arg == arg)
3402  {
3403  if (prev)
3404  prev->next = item->next;
3405  else
3406  SubXact_callbacks = item->next;
3407  pfree(item);
3408  break;
3409  }
3410  }
3411 }
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:275
void pfree(void *pointer)
Definition: mcxt.c:1031
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
struct SubXactCallbackItem * next
Definition: xact.c:270
void * arg

◆ UnregisterXactCallback()

void UnregisterXactCallback ( XactCallback  callback,
void *  arg 
)

Definition at line 3338 of file xact.c.

References XactCallbackItem::next, and pfree().

3339 {
3340  XactCallbackItem *item;
3341  XactCallbackItem *prev;
3342 
3343  prev = NULL;
3344  for (item = Xact_callbacks; item; prev = item, item = item->next)
3345  {
3346  if (item->callback == callback && item->arg == arg)
3347  {
3348  if (prev)
3349  prev->next = item->next;
3350  else
3351  Xact_callbacks = item->next;
3352  pfree(item);
3353  break;
3354  }
3355  }
3356 }
struct XactCallbackItem * next
Definition: xact.c:258
void pfree(void *pointer)
Definition: mcxt.c:1031
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
static XactCallbackItem * Xact_callbacks
Definition: xact.c:263
void * arg

◆ UserAbortTransactionBlock()

void UserAbortTransactionBlock ( void  )

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

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

◆ WarnNoTransactionBlock()

void WarnNoTransactionBlock ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3236 of file xact.c.

References CheckTransactionBlock().

Referenced by ExecSetVariableStmt(), and standard_ProcessUtility().

3237 {
3238  CheckTransactionBlock(isTopLevel, false, stmtType);
3239 }
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3251

◆ xact_desc()

void xact_desc ( StringInfo  buf,
XLogReaderState record 
)

Definition at line 308 of file xactdesc.c.

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

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

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

◆ xactGetCommittedChildren()

int xactGetCommittedChildren ( TransactionId **  ptr)

Definition at line 5233 of file xact.c.

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

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

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

◆ XactLogAbortRecord()

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

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

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