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 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_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 struct xl_xact_parsed_abort xl_xact_parsed_abort
 

Enumerations

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

Functions

bool IsTransactionState (void)
 
bool IsAbortedTransactionBlockState (void)
 
TransactionId GetTopTransactionId (void)
 
TransactionId GetTopTransactionIdIfAny (void)
 
TransactionId GetCurrentTransactionId (void)
 
TransactionId GetCurrentTransactionIdIfAny (void)
 
TransactionId GetStableLatestTransactionId (void)
 
SubTransactionId GetCurrentSubTransactionId (void)
 
void MarkCurrentTransactionIdLoggedIfAny (void)
 
bool SubTransactionIsActive (SubTransactionId subxid)
 
CommandId GetCurrentCommandId (bool used)
 
TimestampTz GetCurrentTransactionStartTimestamp (void)
 
TimestampTz GetCurrentStatementStartTimestamp (void)
 
TimestampTz GetCurrentTransactionStopTimestamp (void)
 
void SetCurrentStatementStartTimestamp (void)
 
int GetCurrentTransactionNestLevel (void)
 
bool TransactionIdIsCurrentTransactionId (TransactionId xid)
 
void CommandCounterIncrement (void)
 
void ForceSyncCommit (void)
 
void StartTransactionCommand (void)
 
void CommitTransactionCommand (void)
 
void AbortCurrentTransaction (void)
 
void BeginTransactionBlock (void)
 
bool EndTransactionBlock (void)
 
bool PrepareTransactionBlock (const char *gid)
 
void UserAbortTransactionBlock (void)
 
void BeginImplicitTransactionBlock (void)
 
void EndImplicitTransactionBlock (void)
 
void ReleaseSavepoint (List *options)
 
void DefineSavepoint (const char *name)
 
void RollbackToSavepoint (List *options)
 
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 PreventTransactionChain (bool isTopLevel, const char *stmtType)
 
void RequireTransactionChain (bool isTopLevel, const char *stmtType)
 
void WarnNoTransactionChain (bool isTopLevel, const char *stmtType)
 
bool IsInTransactionChain (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)
 
XLogRecPtr XactLogAbortRecord (TimestampTz abort_time, int nsubxacts, TransactionId *subxacts, int nrels, RelFileNode *rels, int xactflags, TransactionId twophase_xid)
 
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

◆ IsolationIsSerializable

◆ IsolationUsesXactSnapshot

◆ MinSizeOfXactAbort

#define MinSizeOfXactAbort   sizeof(xl_xact_abort)

Definition at line 279 of file xact.h.

Referenced by ParseAbortRecord(), and XactLogAbortRecord().

◆ MinSizeOfXactAssignment

#define MinSizeOfXactAssignment   offsetof(xl_xact_assignment, xsub)

Definition at line 187 of file xact.h.

Referenced by AssignTransactionId().

◆ MinSizeOfXactCommit

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

Definition at line 266 of file xact.h.

Referenced by ParseCommitRecord().

◆ MinSizeOfXactInvals

#define MinSizeOfXactInvals   offsetof(xl_xact_invals, msgs)

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

◆ XACT_COMPLETION_APPLY_FEEDBACK

#define XACT_COMPLETION_APPLY_FEEDBACK   (1U << 29)

Definition at line 168 of file xact.h.

Referenced by XactLogCommitRecord().

◆ XACT_COMPLETION_FORCE_SYNC_COMMIT

#define XACT_COMPLETION_FORCE_SYNC_COMMIT   (1U << 31)

Definition at line 170 of file xact.h.

Referenced by XactLogCommitRecord().

◆ XACT_COMPLETION_UPDATE_RELCACHE_FILE

#define XACT_COMPLETION_UPDATE_RELCACHE_FILE   (1U << 30)

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

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

◆ XACT_READ_UNCOMMITTED

#define XACT_READ_UNCOMMITTED   0

Definition at line 28 of file xact.h.

Referenced by check_XactIsoLevel(), and show_XactIsoLevel().

◆ XACT_REPEATABLE_READ

#define XACT_REPEATABLE_READ   2

◆ XACT_SERIALIZABLE

#define XACT_SERIALIZABLE   3

Definition at line 31 of file xact.h.

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

◆ XACT_XINFO_HAS_AE_LOCKS

#define XACT_XINFO_HAS_AE_LOCKS   (1U << 6)

Definition at line 158 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)

Definition at line 152 of file xact.h.

Referenced by ParseCommitRecord(), and XactLogCommitRecord().

◆ XACT_XINFO_HAS_INVALS

#define XACT_XINFO_HAS_INVALS   (1U << 3)

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

Referenced by xact_redo_commit().

◆ XactCompletionForceSyncCommit

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

Definition at line 177 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 175 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 138 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 134 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 120 of file xact.h.

◆ XactCallback

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

Definition at line 110 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_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 112 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 57 of file xact.h.

58 {
59  SYNCHRONOUS_COMMIT_OFF, /* asynchronous commit */
60  SYNCHRONOUS_COMMIT_LOCAL_FLUSH, /* wait for local flush only */
61  SYNCHRONOUS_COMMIT_REMOTE_WRITE, /* wait for local flush and remote
62  * write */
63  SYNCHRONOUS_COMMIT_REMOTE_FLUSH, /* wait for local and remote flush */
64  SYNCHRONOUS_COMMIT_REMOTE_APPLY /* wait for local flush and remote apply */
SyncCommitLevel
Definition: xact.h:57

◆ 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 98 of file xact.h.

Function Documentation

◆ AbortCurrentTransaction()

void AbortCurrentTransaction ( void  )

Definition at line 2985 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(), and SnapBuildClearExportedSnapshot().

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

◆ AbortOutOfAnyTransaction()

void AbortOutOfAnyTransaction ( void  )

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

4345 {
4347 
4348  /* Ensure we're not running in a doomed memory context */
4349  AtAbort_Memory();
4350 
4351  /*
4352  * Get out of any transaction or nested transaction
4353  */
4354  do
4355  {
4356  switch (s->blockState)
4357  {
4358  case TBLOCK_DEFAULT:
4359  if (s->state == TRANS_DEFAULT)
4360  {
4361  /* Not in a transaction, do nothing */
4362  }
4363  else
4364  {
4365  /*
4366  * We can get here after an error during transaction start
4367  * (state will be TRANS_START). Need to clean up the
4368  * incompletely started transaction. First, adjust the
4369  * low-level state to suppress warning message from
4370  * AbortTransaction.
4371  */
4372  if (s->state == TRANS_START)
4373  s->state = TRANS_INPROGRESS;
4374  AbortTransaction();
4376  }
4377  break;
4378  case TBLOCK_STARTED:
4379  case TBLOCK_BEGIN:
4380  case TBLOCK_INPROGRESS:
4383  case TBLOCK_END:
4384  case TBLOCK_ABORT_PENDING:
4385  case TBLOCK_PREPARE:
4386  /* In a transaction, so clean up */
4387  AbortTransaction();
4390  break;
4391  case TBLOCK_ABORT:
4392  case TBLOCK_ABORT_END:
4393 
4394  /*
4395  * AbortTransaction is already done, still need Cleanup.
4396  * However, if we failed partway through running ROLLBACK,
4397  * there will be an active portal running that command, which
4398  * we need to shut down before doing CleanupTransaction.
4399  */
4400  AtAbort_Portals();
4403  break;
4404 
4405  /*
4406  * In a subtransaction, so clean it up and abort parent too
4407  */
4408  case TBLOCK_SUBBEGIN:
4409  case TBLOCK_SUBINPROGRESS:
4410  case TBLOCK_SUBRELEASE:
4411  case TBLOCK_SUBCOMMIT:
4413  case TBLOCK_SUBRESTART:
4416  s = CurrentTransactionState; /* changed by pop */
4417  break;
4418 
4419  case TBLOCK_SUBABORT:
4420  case TBLOCK_SUBABORT_END:
4422  /* As above, but AbortSubTransaction already done */
4423  if (s->curTransactionOwner)
4424  {
4425  /* As in TBLOCK_ABORT, might have a live portal to zap */
4430  }
4432  s = CurrentTransactionState; /* changed by pop */
4433  break;
4434  }
4435  } while (s->blockState != TBLOCK_DEFAULT);
4436 
4437  /* Should be out of all subxacts now */
4438  Assert(s->parent == NULL);
4439 
4440  /* If we didn't actually have anything to do, revert to TopMemoryContext */
4441  AtCleanup_Memory();
4442 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
static void AtCleanup_Memory(void)
Definition: xact.c:1725
void AtAbort_Portals(void)
Definition: portalmem.c:746
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:2625
struct TransactionStateData * parent
Definition: xact.c:192
SubTransactionId subTransactionId
Definition: xact.c:174
static void AbortSubTransaction(void)
Definition: xact.c:4690
static void AtAbort_Memory(void)
Definition: xact.c:1635
static void AbortTransaction(void)
Definition: xact.c:2445
#define Assert(condition)
Definition: c.h:680
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition: portalmem.c:901
static void CleanupSubTransaction(void)
Definition: xact.c:4835

◆ BeginImplicitTransactionBlock()

void BeginImplicitTransactionBlock ( void  )

Definition at line 3780 of file xact.c.

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

Referenced by exec_simple_query().

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

◆ BeginInternalSubTransaction()

void BeginInternalSubTransaction ( const char *  name)

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

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

◆ BeginTransactionBlock()

void BeginTransactionBlock ( void  )

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

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

◆ CommandCounterIncrement()

void CommandCounterIncrement ( void  )

Definition at line 915 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_update(), ATAddCheckConstraint(), ATExecAddColumn(), ATExecAlterColumnType(), ATExecCmd(), ATExecDropColumn(), ATExecDropConstraint(), ATExecDropIdentity(), ATExecSetTableSpace(), CommitSubTransaction(), CommitTransactionCommand(), create_ctas_internal(), create_toast_table(), CreateFKCheckTrigger(), createForeignKeyTriggers(), CreateForeignTable(), CreatePublication(), CreateRole(), CreateSchemaCommand(), 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(), InitTempTableNamespace(), inv_create(), inv_drop(), inv_truncate(), inv_write(), LogicalRepSyncTableStart(), make_new_heap(), makeConfigurationDependencies(), moveArrayTypeName(), OperatorShellMake(), OperatorUpd(), pg_import_system_collations(), PortalRunMulti(), PreCommit_on_commit_actions(), ProcedureCreate(), ProcessUtilitySlow(), recordExtensionInitPrivWorker(), reindex_relation(), RelationSetNewRelfilenode(), RenumberEnumType(), replorigin_create(), replorigin_drop(), ri_PerformCheck(), SetMatViewPopulatedState(), shdepReassignOwned(), SPI_cursor_open_internal(), and StoreConstraints().

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

◆ CommitTransactionCommand()

void CommitTransactionCommand ( void  )

Definition at line 2745 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(), vacuum(), and vacuum_rel().

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

◆ DefineSavepoint()

void DefineSavepoint ( const char *  name)

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

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

◆ EndImplicitTransactionBlock()

void EndImplicitTransactionBlock ( void  )

Definition at line 3805 of file xact.c.

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

Referenced by exec_simple_query().

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

◆ EndParallelWorkerTransaction()

void EndParallelWorkerTransaction ( void  )

Definition at line 5085 of file xact.c.

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

Referenced by ParallelWorkerMain().

5086 {
5090 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
TBlockState blockState
Definition: xact.c:178
#define Assert(condition)
Definition: c.h:680
static void CommitTransaction(void)
Definition: xact.c:1934

◆ EndTransactionBlock()

bool EndTransactionBlock ( void  )

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

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

◆ EnterParallelMode()

void EnterParallelMode ( void  )

Definition at line 873 of file xact.c.

References Assert, CurrentTransactionState, and TransactionStateData::parallelModeLevel.

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

874 {
876 
877  Assert(s->parallelModeLevel >= 0);
878 
879  ++s->parallelModeLevel;
880 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
int parallelModeLevel
Definition: xact.c:191
#define Assert(condition)
Definition: c.h:680

◆ EstimateTransactionStateSpace()

Size EstimateTransactionStateSpace ( void  )

Definition at line 4961 of file xact.c.

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

Referenced by InitializeParallelDSM().

4962 {
4963  TransactionState s;
4964  Size nxids = 6; /* iso level, deferrable, top & current XID,
4965  * command counter, XID count */
4966 
4967  for (s = CurrentTransactionState; s != NULL; s = s->parent)
4968  {
4970  nxids = add_size(nxids, 1);
4971  nxids = add_size(nxids, s->nChildXids);
4972  }
4973 
4974  nxids = add_size(nxids, nParallelCurrentXids);
4975  return mul_size(nxids, sizeof(TransactionId));
4976 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
uint32 TransactionId
Definition: c.h:455
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:414
#define TransactionIdIsValid(xid)
Definition: transam.h:41

◆ ExitParallelMode()

void ExitParallelMode ( void  )

Definition at line 886 of file xact.c.

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

Referenced by ExecutePlan(), and ParallelWorkerMain().

887 {
889 
890  Assert(s->parallelModeLevel > 0);
892 
893  --s->parallelModeLevel;
894 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
bool ParallelContextActive(void)
Definition: parallel.c:703
int parallelModeLevel
Definition: xact.c:191
#define Assert(condition)
Definition: c.h:680

◆ ForceSyncCommit()

void ForceSyncCommit ( void  )

Definition at line 963 of file xact.c.

References forceSyncCommit.

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

964 {
965  forceSyncCommit = true;
966 }
static bool forceSyncCommit
Definition: xact.c:263

◆ GetCurrentCommandId()

CommandId GetCurrentCommandId ( bool  used)

Definition at line 680 of file xact.c.

References Assert, currentCommandId, currentCommandIdUsed, and TransactionStateData::parallelModeLevel.

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

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

◆ GetCurrentStatementStartTimestamp()

TimestampTz GetCurrentStatementStartTimestamp ( void  )

Definition at line 710 of file xact.c.

References stmtStartTimestamp.

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

711 {
712  return stmtStartTimestamp;
713 }
static TimestampTz stmtStartTimestamp
Definition: xact.c:251

◆ GetCurrentSubTransactionId()

◆ GetCurrentTransactionId()

◆ GetCurrentTransactionIdIfAny()

TransactionId GetCurrentTransactionIdIfAny ( void  )

Definition at line 435 of file xact.c.

References TransactionStateData::transactionId.

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

436 {
438 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
TransactionId transactionId
Definition: xact.c:173

◆ GetCurrentTransactionNestLevel()

◆ GetCurrentTransactionStartTimestamp()

TimestampTz GetCurrentTransactionStartTimestamp ( void  )

◆ GetCurrentTransactionStopTimestamp()

TimestampTz GetCurrentTransactionStopTimestamp ( void  )

Definition at line 722 of file xact.c.

References GetCurrentTimestamp(), and xactStopTimestamp.

Referenced by pgstat_report_stat().

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

◆ GetStableLatestTransactionId()

TransactionId GetStableLatestTransactionId ( void  )

Definition at line 462 of file xact.c.

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

Referenced by xid_age().

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

391 {
394  return XactTopTransactionId;
395 }
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:490

◆ GetTopTransactionIdIfAny()

◆ IsAbortedTransactionBlockState()

◆ IsInParallelMode()

◆ IsInTransactionChain()

bool IsInTransactionChain ( bool  isTopLevel)

Definition at line 3269 of file xact.c.

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

Referenced by vacuum().

3270 {
3271  /*
3272  * Return true on same conditions that would make PreventTransactionChain
3273  * error out
3274  */
3275  if (IsTransactionBlock())
3276  return true;
3277 
3278  if (IsSubTransaction())
3279  return true;
3280 
3281  if (!isTopLevel)
3282  return true;
3283 
3286  return true;
3287 
3288  return false;
3289 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
TBlockState blockState
Definition: xact.c:178
bool IsTransactionBlock(void)
Definition: xact.c:4448
bool IsSubTransaction(void)
Definition: xact.c:4521

◆ IsSubTransaction()

◆ IsTransactionBlock()

bool IsTransactionBlock ( void  )

Definition at line 4448 of file xact.c.

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

Referenced by CheckTransactionChain(), CreateReplicationSlot(), exec_replication_command(), IsInTransactionChain(), and PreventTransactionChain().

4449 {
4451 
4453  return false;
4454 
4455  return true;
4456 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
TBlockState blockState
Definition: xact.c:178

◆ IsTransactionOrTransactionBlock()

bool IsTransactionOrTransactionBlock ( void  )

◆ IsTransactionState()

bool IsTransactionState ( void  )

Definition at line 351 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(), replorigin_create(), replorigin_drop(), SearchCatCacheInternal(), SetMultiXactIdLimit(), SetTransactionIdLimit(), SnapBuildClearExportedSnapshot(), and SocketBackend().

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

◆ MarkCurrentTransactionIdLoggedIfAny()

void MarkCurrentTransactionIdLoggedIfAny ( void  )

Definition at line 446 of file xact.c.

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

Referenced by XLogInsertRecord().

447 {
450 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
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 122 of file xactdesc.c.

References MinSizeOfXactAbort, MinSizeOfXactRelfilenodes, MinSizeOfXactSubxacts, xl_xact_relfilenodes::nrels, xl_xact_parsed_abort::nrels, xl_xact_subxacts::nsubxacts, xl_xact_parsed_abort::nsubxacts, xl_xact_subxacts::subxacts, xl_xact_parsed_abort::subxacts, xl_xact_parsed_abort::twophase_xid, xl_xact_abort::xact_time, xl_xact_parsed_abort::xact_time, 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().

123 {
124  char *data = ((char *) xlrec) + MinSizeOfXactAbort;
125 
126  memset(parsed, 0, sizeof(*parsed));
127 
128  parsed->xinfo = 0; /* default, if no XLOG_XACT_HAS_INFO is
129  * present */
130 
131  parsed->xact_time = xlrec->xact_time;
132 
133  if (info & XLOG_XACT_HAS_INFO)
134  {
135  xl_xact_xinfo *xl_xinfo = (xl_xact_xinfo *) data;
136 
137  parsed->xinfo = xl_xinfo->xinfo;
138 
139  data += sizeof(xl_xact_xinfo);
140  }
141 
142  if (parsed->xinfo & XACT_XINFO_HAS_SUBXACTS)
143  {
144  xl_xact_subxacts *xl_subxacts = (xl_xact_subxacts *) data;
145 
146  parsed->nsubxacts = xl_subxacts->nsubxacts;
147  parsed->subxacts = xl_subxacts->subxacts;
148 
149  data += MinSizeOfXactSubxacts;
150  data += parsed->nsubxacts * sizeof(TransactionId);
151  }
152 
153  if (parsed->xinfo & XACT_XINFO_HAS_RELFILENODES)
154  {
155  xl_xact_relfilenodes *xl_relfilenodes = (xl_xact_relfilenodes *) data;
156 
157  parsed->nrels = xl_relfilenodes->nrels;
158  parsed->xnodes = xl_relfilenodes->xnodes;
159 
161  data += xl_relfilenodes->nrels * sizeof(RelFileNode);
162  }
163 
164  if (parsed->xinfo & XACT_XINFO_HAS_TWOPHASE)
165  {
166  xl_xact_twophase *xl_twophase = (xl_xact_twophase *) data;
167 
168  parsed->twophase_xid = xl_twophase->xid;
169 
170  data += sizeof(xl_xact_twophase);
171  }
172 }
struct xl_xact_xinfo xl_xact_xinfo
uint32 TransactionId
Definition: c.h:455
TransactionId xid
Definition: xact.h:245
#define MinSizeOfXactAbort
Definition: xact.h:279
#define XLOG_XACT_HAS_INFO
Definition: xact.h:146
#define XACT_XINFO_HAS_SUBXACTS
Definition: xact.h:153
#define MinSizeOfXactRelfilenodes
Definition: xact.h:234
TimestampTz xact_time
Definition: xact.h:270
RelFileNode xnodes[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:232
#define MinSizeOfXactSubxacts
Definition: xact.h:227
struct RelFileNode RelFileNode
struct xl_xact_twophase xl_xact_twophase
TransactionId * subxacts
Definition: xact.h:316
uint32 xinfo
Definition: xact.h:213
RelFileNode * xnodes
Definition: xact.h:319
int nsubxacts
Definition: xact.h:224
#define XACT_XINFO_HAS_TWOPHASE
Definition: xact.h:156
TransactionId twophase_xid
Definition: xact.h:321
TimestampTz xact_time
Definition: xact.h:312
#define XACT_XINFO_HAS_RELFILENODES
Definition: xact.h:154
TransactionId subxacts[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:225

◆ ParseCommitRecord()

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

Definition at line 35 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, xl_xact_subxacts::subxacts, xl_xact_parsed_commit::subxacts, xl_xact_dbinfo::tsId, xl_xact_parsed_commit::tsId, xl_xact_parsed_commit::twophase_xid, xl_xact_commit::xact_time, xl_xact_parsed_commit::xact_time, XACT_XINFO_HAS_DBINFO, 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().

36 {
37  char *data = ((char *) xlrec) + MinSizeOfXactCommit;
38 
39  memset(parsed, 0, sizeof(*parsed));
40 
41  parsed->xinfo = 0; /* default, if no XLOG_XACT_HAS_INFO is
42  * present */
43 
44  parsed->xact_time = xlrec->xact_time;
45 
46  if (info & XLOG_XACT_HAS_INFO)
47  {
48  xl_xact_xinfo *xl_xinfo = (xl_xact_xinfo *) data;
49 
50  parsed->xinfo = xl_xinfo->xinfo;
51 
52  data += sizeof(xl_xact_xinfo);
53  }
54 
55  if (parsed->xinfo & XACT_XINFO_HAS_DBINFO)
56  {
57  xl_xact_dbinfo *xl_dbinfo = (xl_xact_dbinfo *) data;
58 
59  parsed->dbId = xl_dbinfo->dbId;
60  parsed->tsId = xl_dbinfo->tsId;
61 
62  data += sizeof(xl_xact_dbinfo);
63  }
64 
65  if (parsed->xinfo & XACT_XINFO_HAS_SUBXACTS)
66  {
67  xl_xact_subxacts *xl_subxacts = (xl_xact_subxacts *) data;
68 
69  parsed->nsubxacts = xl_subxacts->nsubxacts;
70  parsed->subxacts = xl_subxacts->subxacts;
71 
72  data += MinSizeOfXactSubxacts;
73  data += parsed->nsubxacts * sizeof(TransactionId);
74  }
75 
76  if (parsed->xinfo & XACT_XINFO_HAS_RELFILENODES)
77  {
78  xl_xact_relfilenodes *xl_relfilenodes = (xl_xact_relfilenodes *) data;
79 
80  parsed->nrels = xl_relfilenodes->nrels;
81  parsed->xnodes = xl_relfilenodes->xnodes;
82 
84  data += xl_relfilenodes->nrels * sizeof(RelFileNode);
85  }
86 
87  if (parsed->xinfo & XACT_XINFO_HAS_INVALS)
88  {
89  xl_xact_invals *xl_invals = (xl_xact_invals *) data;
90 
91  parsed->nmsgs = xl_invals->nmsgs;
92  parsed->msgs = xl_invals->msgs;
93 
94  data += MinSizeOfXactInvals;
95  data += xl_invals->nmsgs * sizeof(SharedInvalidationMessage);
96  }
97 
98  if (parsed->xinfo & XACT_XINFO_HAS_TWOPHASE)
99  {
100  xl_xact_twophase *xl_twophase = (xl_xact_twophase *) data;
101 
102  parsed->twophase_xid = xl_twophase->xid;
103 
104  data += sizeof(xl_xact_twophase);
105  }
106 
107  if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
108  {
109  xl_xact_origin xl_origin;
110 
111  /* we're only guaranteed 4 byte alignment, so copy onto stack */
112  memcpy(&xl_origin, data, sizeof(xl_origin));
113 
114  parsed->origin_lsn = xl_origin.origin_lsn;
115  parsed->origin_timestamp = xl_origin.origin_timestamp;
116 
117  data += sizeof(xl_xact_origin);
118  }
119 }
RelFileNode * xnodes
Definition: xact.h:299
#define XACT_XINFO_HAS_ORIGIN
Definition: xact.h:157
struct xl_xact_xinfo xl_xact_xinfo
uint32 TransactionId
Definition: c.h:455
TimestampTz origin_timestamp
Definition: xact.h:307
TransactionId xid
Definition: xact.h:245
TransactionId twophase_xid
Definition: xact.h:304
TransactionId * subxacts
Definition: xact.h:296
#define XLOG_XACT_HAS_INFO
Definition: xact.h:146
SharedInvalidationMessage * msgs
Definition: xact.h:302
XLogRecPtr origin_lsn
Definition: xact.h:306
#define XACT_XINFO_HAS_SUBXACTS
Definition: xact.h:153
struct xl_xact_dbinfo xl_xact_dbinfo
#define MinSizeOfXactRelfilenodes
Definition: xact.h:234
Oid tsId
Definition: xact.h:219
struct xl_xact_origin xl_xact_origin
RelFileNode xnodes[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:232
#define MinSizeOfXactSubxacts
Definition: xact.h:227
#define MinSizeOfXactCommit
Definition: xact.h:266
SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:239
struct RelFileNode RelFileNode
TimestampTz xact_time
Definition: xact.h:256
struct xl_xact_twophase xl_xact_twophase
#define MinSizeOfXactInvals
Definition: xact.h:241
#define XACT_XINFO_HAS_DBINFO
Definition: xact.h:152
XLogRecPtr origin_lsn
Definition: xact.h:250
uint32 xinfo
Definition: xact.h:213
int nsubxacts
Definition: xact.h:224
#define XACT_XINFO_HAS_TWOPHASE
Definition: xact.h:156
Oid dbId
Definition: xact.h:218
TimestampTz origin_timestamp
Definition: xact.h:251
#define XACT_XINFO_HAS_INVALS
Definition: xact.h:155
#define XACT_XINFO_HAS_RELFILENODES
Definition: xact.h:154
int nmsgs
Definition: xact.h:238
TransactionId subxacts[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:225
TimestampTz xact_time
Definition: xact.h:288

◆ PrepareTransactionBlock()

bool PrepareTransactionBlock ( const char *  gid)

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

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

◆ PreventTransactionChain()

void PreventTransactionChain ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3154 of file xact.c.

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

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

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

◆ RegisterSubXactCallback()

void RegisterSubXactCallback ( SubXactCallback  callback,
void *  arg 
)

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

3360 {
3361  SubXactCallbackItem *item;
3362 
3363  item = (SubXactCallbackItem *)
3365  item->callback = callback;
3366  item->arg = arg;
3367  item->next = SubXact_callbacks;
3368  SubXact_callbacks = item;
3369 }
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:294
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
struct SubXactCallbackItem * next
Definition: xact.c:289
SubXactCallback callback
Definition: xact.c:290
MemoryContext TopMemoryContext
Definition: mcxt.c:43
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:693
void * arg

◆ RegisterXactCallback()

void RegisterXactCallback ( XactCallback  callback,
void *  arg 
)

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

3305 {
3306  XactCallbackItem *item;
3307 
3308  item = (XactCallbackItem *)
3310  item->callback = callback;
3311  item->arg = arg;
3312  item->next = Xact_callbacks;
3313  Xact_callbacks = item;
3314 }
struct XactCallbackItem * next
Definition: xact.c:277
void * arg
Definition: xact.c:279
XactCallback callback
Definition: xact.c:278
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
MemoryContext TopMemoryContext
Definition: mcxt.c:43
static XactCallbackItem * Xact_callbacks
Definition: xact.c:282
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:693
void * arg

◆ ReleaseCurrentSubTransaction()

void ReleaseCurrentSubTransaction ( void  )

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

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

◆ ReleaseSavepoint()

void ReleaseSavepoint ( List options)

Definition at line 3912 of file xact.c.

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

3913 {
3915  TransactionState target,
3916  xact;
3917  ListCell *cell;
3918  char *name = NULL;
3919 
3920  /*
3921  * Workers synchronize transaction state at the beginning of each parallel
3922  * operation, so we can't account for transaction state change after that
3923  * point. (Note that this check will certainly error out if s->blockState
3924  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
3925  * below.)
3926  */
3927  if (IsInParallelMode())
3928  ereport(ERROR,
3929  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3930  errmsg("cannot release savepoints during a parallel operation")));
3931 
3932  switch (s->blockState)
3933  {
3934  /*
3935  * We can't release a savepoint if there is no savepoint defined.
3936  */
3937  case TBLOCK_INPROGRESS:
3938  ereport(ERROR,
3939  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3940  errmsg("no such savepoint")));
3941  break;
3942 
3944  /* See comment about implicit transactions in DefineSavepoint */
3945  ereport(ERROR,
3946  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3947  /* translator: %s represents an SQL statement name */
3948  errmsg("%s can only be used in transaction blocks",
3949  "RELEASE SAVEPOINT")));
3950  break;
3951 
3952  /*
3953  * We are in a non-aborted subtransaction. This is the only valid
3954  * case.
3955  */
3956  case TBLOCK_SUBINPROGRESS:
3957  break;
3958 
3959  /* These cases are invalid. */
3960  case TBLOCK_DEFAULT:
3961  case TBLOCK_STARTED:
3962  case TBLOCK_BEGIN:
3964  case TBLOCK_SUBBEGIN:
3965  case TBLOCK_END:
3966  case TBLOCK_SUBRELEASE:
3967  case TBLOCK_SUBCOMMIT:
3968  case TBLOCK_ABORT:
3969  case TBLOCK_SUBABORT:
3970  case TBLOCK_ABORT_END:
3971  case TBLOCK_SUBABORT_END:
3972  case TBLOCK_ABORT_PENDING:
3974  case TBLOCK_SUBRESTART:
3976  case TBLOCK_PREPARE:
3977  elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3979  break;
3980  }
3981 
3982  foreach(cell, options)
3983  {
3984  DefElem *elem = lfirst(cell);
3985 
3986  if (strcmp(elem->defname, "savepoint_name") == 0)
3987  name = strVal(elem->arg);
3988  }
3989 
3990  Assert(PointerIsValid(name));
3991 
3992  for (target = s; PointerIsValid(target); target = target->parent)
3993  {
3994  if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3995  break;
3996  }
3997 
3998  if (!PointerIsValid(target))
3999  ereport(ERROR,
4000  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4001  errmsg("no such savepoint")));
4002 
4003  /* disallow crossing savepoint level boundaries */
4004  if (target->savepointLevel != s->savepointLevel)
4005  ereport(ERROR,
4006  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4007  errmsg("no such savepoint")));
4008 
4009  /*
4010  * Mark "commit pending" all subtransactions up to the target
4011  * subtransaction. The actual commits will happen when control gets to
4012  * CommitTransactionCommand.
4013  */
4014  xact = CurrentTransactionState;
4015  for (;;)
4016  {
4018  xact->blockState = TBLOCK_SUBRELEASE;
4019  if (xact == target)
4020  break;
4021  xact = xact->parent;
4022  Assert(PointerIsValid(xact));
4023  }
4024 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
TBlockState blockState
Definition: xact.c:178
bool IsInParallelMode(void)
Definition: xact.c:906
#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:5148
#define ereport(elevel, rest)
Definition: elog.h:122
Node * arg
Definition: parsenodes.h:720
#define Assert(condition)
Definition: c.h:680
#define lfirst(lc)
Definition: pg_list.h:106
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * defname
Definition: parsenodes.h:719
#define elog
Definition: elog.h:219
#define PointerIsValid(pointer)
Definition: c.h:574

◆ RequireTransactionChain()

void RequireTransactionChain ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3207 of file xact.c.

References CheckTransactionChain().

Referenced by PerformCursorOpen(), and standard_ProcessUtility().

3208 {
3209  CheckTransactionChain(isTopLevel, true, stmtType);
3210 }
static void CheckTransactionChain(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3230

◆ RollbackAndReleaseCurrentSubTransaction()

void RollbackAndReleaseCurrentSubTransaction ( void  )

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

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

◆ RollbackToSavepoint()

void RollbackToSavepoint ( List options)

Definition at line 4033 of file xact.c.

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

4034 {
4036  TransactionState target,
4037  xact;
4038  ListCell *cell;
4039  char *name = NULL;
4040 
4041  /*
4042  * Workers synchronize transaction state at the beginning of each parallel
4043  * operation, so we can't account for transaction state change after that
4044  * point. (Note that this check will certainly error out if s->blockState
4045  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4046  * below.)
4047  */
4048  if (IsInParallelMode())
4049  ereport(ERROR,
4050  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4051  errmsg("cannot rollback to savepoints during a parallel operation")));
4052 
4053  switch (s->blockState)
4054  {
4055  /*
4056  * We can't rollback to a savepoint if there is no savepoint
4057  * defined.
4058  */
4059  case TBLOCK_INPROGRESS:
4060  case TBLOCK_ABORT:
4061  ereport(ERROR,
4062  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4063  errmsg("no such savepoint")));
4064  break;
4065 
4067  /* See comment about implicit transactions in DefineSavepoint */
4068  ereport(ERROR,
4069  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4070  /* translator: %s represents an SQL statement name */
4071  errmsg("%s can only be used in transaction blocks",
4072  "ROLLBACK TO SAVEPOINT")));
4073  break;
4074 
4075  /*
4076  * There is at least one savepoint, so proceed.
4077  */
4078  case TBLOCK_SUBINPROGRESS:
4079  case TBLOCK_SUBABORT:
4080  break;
4081 
4082  /* These cases are invalid. */
4083  case TBLOCK_DEFAULT:
4084  case TBLOCK_STARTED:
4085  case TBLOCK_BEGIN:
4087  case TBLOCK_SUBBEGIN:
4088  case TBLOCK_END:
4089  case TBLOCK_SUBRELEASE:
4090  case TBLOCK_SUBCOMMIT:
4091  case TBLOCK_ABORT_END:
4092  case TBLOCK_SUBABORT_END:
4093  case TBLOCK_ABORT_PENDING:
4095  case TBLOCK_SUBRESTART:
4097  case TBLOCK_PREPARE:
4098  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4100  break;
4101  }
4102 
4103  foreach(cell, options)
4104  {
4105  DefElem *elem = lfirst(cell);
4106 
4107  if (strcmp(elem->defname, "savepoint_name") == 0)
4108  name = strVal(elem->arg);
4109  }
4110 
4111  Assert(PointerIsValid(name));
4112 
4113  for (target = s; PointerIsValid(target); target = target->parent)
4114  {
4115  if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4116  break;
4117  }
4118 
4119  if (!PointerIsValid(target))
4120  ereport(ERROR,
4121  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4122  errmsg("no such savepoint")));
4123 
4124  /* disallow crossing savepoint level boundaries */
4125  if (target->savepointLevel != s->savepointLevel)
4126  ereport(ERROR,
4127  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4128  errmsg("no such savepoint")));
4129 
4130  /*
4131  * Mark "abort pending" all subtransactions up to the target
4132  * subtransaction. The actual aborts will happen when control gets to
4133  * CommitTransactionCommand.
4134  */
4135  xact = CurrentTransactionState;
4136  for (;;)
4137  {
4138  if (xact == target)
4139  break;
4140  if (xact->blockState == TBLOCK_SUBINPROGRESS)
4142  else if (xact->blockState == TBLOCK_SUBABORT)
4144  else
4145  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4147  xact = xact->parent;
4148  Assert(PointerIsValid(xact));
4149  }
4150 
4151  /* And mark the target as "restart pending" */
4152  if (xact->blockState == TBLOCK_SUBINPROGRESS)
4153  xact->blockState = TBLOCK_SUBRESTART;
4154  else if (xact->blockState == TBLOCK_SUBABORT)
4156  else
4157  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4159 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
TBlockState blockState
Definition: xact.c:178
bool IsInParallelMode(void)
Definition: xact.c:906
#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:5148
#define ereport(elevel, rest)
Definition: elog.h:122
Node * arg
Definition: parsenodes.h:720
#define Assert(condition)
Definition: c.h:680
#define lfirst(lc)
Definition: pg_list.h:106
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * defname
Definition: parsenodes.h:719
#define elog
Definition: elog.h:219
#define PointerIsValid(pointer)
Definition: c.h:574

◆ SerializeTransactionState()

void SerializeTransactionState ( Size  maxsize,
char *  start_address 
)

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

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

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

734 {
736 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
static TimestampTz stmtStartTimestamp
Definition: xact.c:251

◆ StartParallelWorkerTransaction()

void StartParallelWorkerTransaction ( char *  tstatespace)

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

5063 {
5064  TransactionId *tstate = (TransactionId *) tstatespace;
5065 
5067  StartTransaction();
5068 
5069  XactIsoLevel = (int) tstate[0];
5070  XactDeferrable = (bool) tstate[1];
5071  XactTopTransactionId = tstate[2];
5073  currentCommandId = tstate[4];
5074  nParallelCurrentXids = (int) tstate[5];
5075  ParallelCurrentXids = &tstate[6];
5076 
5078 }
TransactionId XactTopTransactionId
Definition: xact.c:107
bool XactDeferrable
Definition: xact.c:80
static TransactionState CurrentTransactionState
Definition: xact.c:233
uint32 TransactionId
Definition: c.h:455
int nParallelCurrentXids
Definition: xact.c:108
char bool
Definition: c.h:257
TBlockState blockState
Definition: xact.c:178
TransactionId transactionId
Definition: xact.c:173
static void StartTransaction(void)
Definition: xact.c:1796
TransactionId * ParallelCurrentXids
Definition: xact.c:109
#define Assert(condition)
Definition: c.h:680
int XactIsoLevel
Definition: xact.c:74
static CommandId currentCommandId
Definition: xact.c:240

◆ StartTransactionCommand()

void StartTransactionCommand ( void  )

Definition at line 2674 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(), start_xact_command(), vacuum(), and vacuum_rel().

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

◆ SubTransactionIsActive()

bool SubTransactionIsActive ( SubTransactionId  subxid)

Definition at line 656 of file xact.c.

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

Referenced by fmgr_sql().

657 {
659 
660  for (s = CurrentTransactionState; s != NULL; s = s->parent)
661  {
662  if (s->state == TRANS_ABORT)
663  continue;
664  if (s->subTransactionId == subxid)
665  return true;
666  }
667  return false;
668 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
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 4480 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().

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

◆ TransactionIdIsCurrentTransactionId()

bool TransactionIdIsCurrentTransactionId ( TransactionId  xid)

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

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

References SubXactCallbackItem::next, and pfree().

3373 {
3374  SubXactCallbackItem *item;
3375  SubXactCallbackItem *prev;
3376 
3377  prev = NULL;
3378  for (item = SubXact_callbacks; item; prev = item, item = item->next)
3379  {
3380  if (item->callback == callback && item->arg == arg)
3381  {
3382  if (prev)
3383  prev->next = item->next;
3384  else
3385  SubXact_callbacks = item->next;
3386  pfree(item);
3387  break;
3388  }
3389  }
3390 }
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:294
void pfree(void *pointer)
Definition: mcxt.c:936
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
struct SubXactCallbackItem * next
Definition: xact.c:289
void * arg

◆ UnregisterXactCallback()

void UnregisterXactCallback ( XactCallback  callback,
void *  arg 
)

Definition at line 3317 of file xact.c.

References XactCallbackItem::next, and pfree().

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

◆ UserAbortTransactionBlock()

void UserAbortTransactionBlock ( void  )

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

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

◆ WarnNoTransactionChain()

void WarnNoTransactionChain ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3201 of file xact.c.

References CheckTransactionChain().

Referenced by ExecSetVariableStmt(), and standard_ProcessUtility().

3202 {
3203  CheckTransactionChain(isTopLevel, false, stmtType);
3204 }
static void CheckTransactionChain(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3230

◆ xact_desc()

void xact_desc ( StringInfo  buf,
XLogReaderState record 
)

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

271 {
272  char *rec = XLogRecGetData(record);
273  uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
274 
275  if (info == XLOG_XACT_COMMIT || info == XLOG_XACT_COMMIT_PREPARED)
276  {
277  xl_xact_commit *xlrec = (xl_xact_commit *) rec;
278 
279  xact_desc_commit(buf, XLogRecGetInfo(record), xlrec,
280  XLogRecGetOrigin(record));
281  }
282  else if (info == XLOG_XACT_ABORT || info == XLOG_XACT_ABORT_PREPARED)
283  {
284  xl_xact_abort *xlrec = (xl_xact_abort *) rec;
285 
286  xact_desc_abort(buf, XLogRecGetInfo(record), xlrec);
287  }
288  else if (info == XLOG_XACT_ASSIGNMENT)
289  {
290  xl_xact_assignment *xlrec = (xl_xact_assignment *) rec;
291 
292  /*
293  * Note that we ignore the WAL record's xid, since we're more
294  * interested in the top-level xid that issued the record and which
295  * xids are being reported here.
296  */
297  appendStringInfo(buf, "xtop %u: ", xlrec->xtop);
298  xact_desc_assignment(buf, xlrec);
299  }
300 }
#define XLOG_XACT_COMMIT
Definition: xact.h:133
unsigned char uint8
Definition: c.h:304
TransactionId xtop
Definition: xact.h:182
#define XLogRecGetOrigin(decoder)
Definition: xlogreader.h:225
#define XLogRecGetData(decoder)
Definition: xlogreader.h:226
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define XLOG_XACT_ABORT_PREPARED
Definition: xact.h:137
static void xact_desc_abort(StringInfo buf, uint8 info, xl_xact_abort *xlrec)
Definition: xactdesc.c:226
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:222
#define XLOG_XACT_ASSIGNMENT
Definition: xact.h:138
#define XLOG_XACT_ABORT
Definition: xact.h:135
#define XLOG_XACT_OPMASK
Definition: xact.h:143
static void xact_desc_assignment(StringInfo buf, xl_xact_assignment *xlrec)
Definition: xactdesc.c:259
#define XLOG_XACT_COMMIT_PREPARED
Definition: xact.h:136
static void xact_desc_commit(StringInfo buf, uint8 info, xl_xact_commit *xlrec, RepOriginId origin_id)
Definition: xactdesc.c:175

◆ xact_identify()

const char* xact_identify ( uint8  info)

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

304 {
305  const char *id = NULL;
306 
307  switch (info & XLOG_XACT_OPMASK)
308  {
309  case XLOG_XACT_COMMIT:
310  id = "COMMIT";
311  break;
312  case XLOG_XACT_PREPARE:
313  id = "PREPARE";
314  break;
315  case XLOG_XACT_ABORT:
316  id = "ABORT";
317  break;
319  id = "COMMIT_PREPARED";
320  break;
322  id = "ABORT_PREPARED";
323  break;
325  id = "ASSIGNMENT";
326  break;
327  }
328 
329  return id;
330 }
#define XLOG_XACT_COMMIT
Definition: xact.h:133
#define XLOG_XACT_PREPARE
Definition: xact.h:134
#define XLOG_XACT_ABORT_PREPARED
Definition: xact.h:137
#define XLOG_XACT_ASSIGNMENT
Definition: xact.h:138
#define XLOG_XACT_ABORT
Definition: xact.h:135
#define XLOG_XACT_OPMASK
Definition: xact.h:143
#define XLOG_XACT_COMMIT_PREPARED
Definition: xact.h:136

◆ xact_redo()

void xact_redo ( XLogReaderState record)

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

5744 {
5745  uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
5746 
5747  /* Backup blocks are not used in xact records */
5748  Assert(!XLogRecHasAnyBlockRefs(record));
5749 
5750  if (info == XLOG_XACT_COMMIT)
5751  {
5752  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
5753  xl_xact_parsed_commit parsed;
5754 
5755  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
5756  xact_redo_commit(&parsed, XLogRecGetXid(record),
5757  record->EndRecPtr, XLogRecGetOrigin(record));
5758  }
5759  else if (info == XLOG_XACT_COMMIT_PREPARED)
5760  {
5761  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
5762  xl_xact_parsed_commit parsed;
5763 
5764  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
5765  xact_redo_commit(&parsed, parsed.twophase_xid,
5766  record->EndRecPtr, XLogRecGetOrigin(record));
5767 
5768  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
5769  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5770  PrepareRedoRemove(parsed.twophase_xid, false);
5771  LWLockRelease(TwoPhaseStateLock);
5772  }
5773  else if (info == XLOG_XACT_ABORT)
5774  {
5775  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
5776  xl_xact_parsed_abort parsed;
5777 
5778  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
5779  xact_redo_abort(&parsed, XLogRecGetXid(record));
5780  }
5781  else if (info == XLOG_XACT_ABORT_PREPARED)
5782  {
5783  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
5784  xl_xact_parsed_abort parsed;
5785 
5786  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
5787  xact_redo_abort(&parsed, parsed.twophase_xid);
5788 
5789  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
5790  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5791  PrepareRedoRemove(parsed.twophase_xid, false);
5792  LWLockRelease(TwoPhaseStateLock);
5793  }
5794  else if (info == XLOG_XACT_PREPARE)
5795  {
5796  /*
5797  * Store xid and start/end pointers of the WAL record in TwoPhaseState
5798  * gxact entry.
5799  */
5800  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5802  record->ReadRecPtr,
5803  record->EndRecPtr);
5804  LWLockRelease(TwoPhaseStateLock);
5805  }
5806  else if (info == XLOG_XACT_ASSIGNMENT)
5807  {
5809 
5812  xlrec->nsubxacts, xlrec->xsub);
5813  }
5814  else
5815  elog(PANIC, "xact_redo: unknown op code %u", info);
5816 }
#define XLOG_XACT_COMMIT
Definition: xact.h:133
void PrepareRedoRemove(TransactionId xid, bool giveWarning)
Definition: twophase.c:2374
#define XLOG_XACT_PREPARE
Definition: xact.h:134
static void xact_redo_commit(xl_xact_parsed_commit *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:5490
TransactionId twophase_xid
Definition: xact.h:304
unsigned char uint8
Definition: c.h:304
TransactionId xtop
Definition: xact.h:182
TransactionId xsub[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:184
#define PANIC
Definition: elog.h:53
#define XLogRecGetOrigin(decoder)
Definition: xlogreader.h:225
XLogRecPtr EndRecPtr
Definition: xlogreader.h:120
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1722
#define XLogRecGetData(decoder)
Definition: xlogreader.h:226
void ParseCommitRecord(uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *parsed)
Definition: xactdesc.c:35
#define XLOG_XACT_ABORT_PREPARED
Definition: xact.h:137
XLogRecPtr ReadRecPtr
Definition: xlogreader.h:119
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:222
void PrepareRedoAdd(char *buf, XLogRecPtr start_lsn, XLogRecPtr end_lsn)
Definition: twophase.c:2312
#define XLogRecGetXid(decoder)
Definition: xlogreader.h:224
#define XLOG_XACT_ASSIGNMENT
Definition: xact.h:138
static void xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid)
Definition: xact.c:5663
TransactionId twophase_xid
Definition: xact.h:321
#define Assert(condition)
Definition: c.h:680
#define XLOG_XACT_ABORT
Definition: xact.h:135
#define XLOG_XACT_OPMASK
Definition: xact.h:143
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1118
void ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed)
Definition: xactdesc.c:122
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:228
void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)
Definition: procarray.c:915
#define elog
Definition: elog.h:219
#define XLOG_XACT_COMMIT_PREPARED
Definition: xact.h:136
HotStandbyState standbyState
Definition: xlog.c:197

◆ xactGetCommittedChildren()

int xactGetCommittedChildren ( TransactionId **  ptr)

Definition at line 5231 of file xact.c.

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

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

5232 {
5234 
5235  if (s->nChildXids == 0)
5236  *ptr = NULL;
5237  else
5238  *ptr = s->childXids;
5239 
5240  return s->nChildXids;
5241 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
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 
)

Definition at line 5402 of file xact.c.

References Assert, CritSectionCount, MinSizeOfXactAbort, MinSizeOfXactRelfilenodes, MinSizeOfXactSubxacts, xl_xact_relfilenodes::nrels, xl_xact_subxacts::nsubxacts, TransactionIdIsValid, XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK, xl_xact_abort::xact_time, XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_RELFILENODES, XACT_XINFO_HAS_SUBXACTS, XACT_XINFO_HAS_TWOPHASE, xl_xact_twophase::xid, xl_xact_xinfo::xinfo, XLOG_XACT_ABORT, XLOG_XACT_ABORT_PREPARED, XLOG_XACT_HAS_INFO, XLogBeginInsert(), XLogInsert(), and XLogRegisterData().

Referenced by RecordTransactionAbort(), and RecordTransactionAbortPrepared().

5406 {
5407  xl_xact_abort xlrec;
5408  xl_xact_xinfo xl_xinfo;
5409  xl_xact_subxacts xl_subxacts;
5410  xl_xact_relfilenodes xl_relfilenodes;
5411  xl_xact_twophase xl_twophase;
5412 
5413  uint8 info;
5414 
5415  Assert(CritSectionCount > 0);
5416 
5417  xl_xinfo.xinfo = 0;
5418 
5419  /* decide between a plain and 2pc abort */
5420  if (!TransactionIdIsValid(twophase_xid))
5421  info = XLOG_XACT_ABORT;
5422  else
5423  info = XLOG_XACT_ABORT_PREPARED;
5424 
5425 
5426  /* First figure out and collect all the information needed */
5427 
5428  xlrec.xact_time = abort_time;
5429 
5430  if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5431  xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5432 
5433  if (nsubxacts > 0)
5434  {
5435  xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5436  xl_subxacts.nsubxacts = nsubxacts;
5437  }
5438 
5439  if (nrels > 0)
5440  {
5441  xl_xinfo.xinfo |= XACT_XINFO_HAS_RELFILENODES;
5442  xl_relfilenodes.nrels = nrels;
5443  }
5444 
5445  if (TransactionIdIsValid(twophase_xid))
5446  {
5447  xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5448  xl_twophase.xid = twophase_xid;
5449  }
5450 
5451  if (xl_xinfo.xinfo != 0)
5452  info |= XLOG_XACT_HAS_INFO;
5453 
5454  /* Then include all the collected data into the abort record. */
5455 
5456  XLogBeginInsert();
5457 
5458  XLogRegisterData((char *) (&xlrec), MinSizeOfXactAbort);
5459 
5460  if (xl_xinfo.xinfo != 0)
5461  XLogRegisterData((char *) (&xl_xinfo), sizeof(xl_xinfo));
5462 
5463  if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5464  {
5465  XLogRegisterData((char *) (&xl_subxacts),
5467  XLogRegisterData((char *) subxacts,
5468  nsubxacts * sizeof(TransactionId));
5469  }
5470 
5471  if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILENODES)
5472  {
5473  XLogRegisterData((char *) (&xl_relfilenodes),
5475  XLogRegisterData((char *) rels,
5476  nrels * sizeof(RelFileNode));
5477  }
5478 
5479  if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5480  XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
5481 
5482  return XLogInsert(RM_XACT_ID, info);
5483 }
uint32 TransactionId
Definition: c.h:455
TransactionId xid
Definition: xact.h:245
unsigned char uint8
Definition: c.h:304
#define MinSizeOfXactAbort
Definition: xact.h:279
#define XLOG_XACT_HAS_INFO
Definition: xact.h:146
#define XACT_XINFO_HAS_SUBXACTS
Definition: xact.h:153
#define MinSizeOfXactRelfilenodes
Definition: xact.h:234
TimestampTz xact_time
Definition: xact.h:270
#define XACT_XINFO_HAS_AE_LOCKS
Definition: xact.h:158
#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK
Definition: xact.h:92
#define MinSizeOfXactSubxacts
Definition: xact.h:227
#define XLOG_XACT_ABORT_PREPARED
Definition: xact.h:137
volatile uint32 CritSectionCount
Definition: globals.c:37
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
uint32 xinfo
Definition: xact.h:213
int nsubxacts
Definition: xact.h:224
#define XACT_XINFO_HAS_TWOPHASE
Definition: xact.h:156
#define Assert(condition)
Definition: c.h:680
#define XLOG_XACT_ABORT
Definition: xact.h:135
#define XACT_XINFO_HAS_RELFILENODES
Definition: xact.h:154
#define TransactionIdIsValid(xid)
Definition: transam.h:41
void XLogBeginInsert(void)
Definition: xloginsert.c:120

◆ XactLogCommitRecord()

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 
)

Definition at line 5255 of file xact.c.

References Assert, CritSectionCount, xl_xact_dbinfo::dbId, forceSyncCommit, InvalidRepOriginId, MinSizeOfXactInvals, MinSizeOfXactRelfilenodes, MinSizeOfXactSubxacts, MyDatabaseId, MyDatabaseTableSpace, xl_xact_invals::nmsgs, 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, synchronous_commit, SYNCHRONOUS_COMMIT_REMOTE_APPLY, TransactionIdIsValid, xl_xact_dbinfo::tsId, XACT_COMPLETION_APPLY_FEEDBACK, XACT_COMPLETION_FORCE_SYNC_COMMIT, XACT_COMPLETION_UPDATE_RELCACHE_FILE, XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK, xl_xact_commit::xact_time, XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_DBINFO, 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, XLOG_INCLUDE_ORIGIN, XLOG_XACT_COMMIT, XLOG_XACT_COMMIT_PREPARED, XLOG_XACT_HAS_INFO, XLogBeginInsert(), XLogInsert(), XLogLogicalInfoActive, XLogRegisterData(), and XLogSetRecordFlags().

Referenced by RecordTransactionCommit(), and RecordTransactionCommitPrepared().

5261 {
5262  xl_xact_commit xlrec;
5263  xl_xact_xinfo xl_xinfo;
5264  xl_xact_dbinfo xl_dbinfo;
5265  xl_xact_subxacts xl_subxacts;
5266  xl_xact_relfilenodes xl_relfilenodes;
5267  xl_xact_invals xl_invals;
5268  xl_xact_twophase xl_twophase;
5269  xl_xact_origin xl_origin;
5270 
5271  uint8 info;
5272 
5273  Assert(CritSectionCount > 0);
5274 
5275  xl_xinfo.xinfo = 0;
5276 
5277  /* decide between a plain and 2pc commit */
5278  if (!TransactionIdIsValid(twophase_xid))
5279  info = XLOG_XACT_COMMIT;
5280  else
5282 
5283  /* First figure out and collect all the information needed */
5284 
5285  xlrec.xact_time = commit_time;
5286 
5287  if (relcacheInval)
5289  if (forceSyncCommit)
5291  if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5292  xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5293 
5294  /*
5295  * Check if the caller would like to ask standbys for immediate feedback
5296  * once this commit is applied.
5297  */
5300 
5301  /*
5302  * Relcache invalidations requires information about the current database
5303  * and so does logical decoding.
5304  */
5305  if (nmsgs > 0 || XLogLogicalInfoActive())
5306  {
5307  xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5308  xl_dbinfo.dbId = MyDatabaseId;
5309  xl_dbinfo.tsId = MyDatabaseTableSpace;
5310  }
5311 
5312  if (nsubxacts > 0)
5313  {
5314  xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5315  xl_subxacts.nsubxacts = nsubxacts;
5316  }
5317