PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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 (char *gid)
 
void UserAbortTransactionBlock (void)
 
void BeginImplicitTransactionBlock (void)
 
void EndImplicitTransactionBlock (void)
 
void ReleaseSavepoint (List *options)
 
void DefineSavepoint (char *name)
 
void RollbackToSavepoint (List *options)
 
void BeginInternalSubTransaction (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

#define MinSizeOfXactAbort   sizeof(xl_xact_abort)

Definition at line 279 of file xact.h.

Referenced by ParseAbortRecord(), and XactLogAbortRecord().

#define MinSizeOfXactAssignment   offsetof(xl_xact_assignment, xsub)

Definition at line 187 of file xact.h.

Referenced by AssignTransactionId().

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

Definition at line 266 of file xact.h.

Referenced by ParseCommitRecord().

#define MinSizeOfXactInvals   offsetof(xl_xact_invals, msgs)

Definition at line 241 of file xact.h.

Referenced by ParseCommitRecord(), and XactLogCommitRecord().

#define MinSizeOfXactRelfilenodes   offsetof(xl_xact_relfilenodes, xnodes)
#define MinSizeOfXactSubxacts   offsetof(xl_xact_subxacts, subxacts)
#define SYNCHRONOUS_COMMIT_ON   SYNCHRONOUS_COMMIT_REMOTE_FLUSH

Definition at line 68 of file xact.h.

#define XACT_COMPLETION_APPLY_FEEDBACK   (1U << 29)

Definition at line 168 of file xact.h.

Referenced by XactLogCommitRecord().

#define XACT_COMPLETION_FORCE_SYNC_COMMIT   (1U << 31)

Definition at line 170 of file xact.h.

Referenced by XactLogCommitRecord().

#define XACT_COMPLETION_UPDATE_RELCACHE_FILE   (1U << 30)

Definition at line 169 of file xact.h.

Referenced by XactLogCommitRecord().

#define XACT_FLAGS_ACCESSEDTEMPREL   (1U << 0)
#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK   (1U << 1)
#define XACT_READ_COMMITTED   1

Definition at line 29 of file xact.h.

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

#define XACT_READ_UNCOMMITTED   0

Definition at line 28 of file xact.h.

Referenced by check_XactIsoLevel(), and show_XactIsoLevel().

#define XACT_REPEATABLE_READ   2
#define XACT_SERIALIZABLE   3

Definition at line 31 of file xact.h.

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

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

#define XACT_XINFO_HAS_DBINFO   (1U << 0)

Definition at line 152 of file xact.h.

Referenced by ParseCommitRecord(), and XactLogCommitRecord().

#define XACT_XINFO_HAS_INVALS   (1U << 3)

Definition at line 155 of file xact.h.

Referenced by ParseCommitRecord(), and XactLogCommitRecord().

#define XACT_XINFO_HAS_ORIGIN   (1U << 5)
#define XACT_XINFO_HAS_RELFILENODES   (1U << 2)
#define XACT_XINFO_HAS_SUBXACTS   (1U << 1)
#define XACT_XINFO_HAS_TWOPHASE   (1U << 4)
#define XactCompletionApplyFeedback (   xinfo)    ((xinfo & XACT_COMPLETION_APPLY_FEEDBACK) != 0)

Definition at line 173 of file xact.h.

Referenced by xact_redo_commit().

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

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

#define XLOG_XACT_ABORT   0x20
#define XLOG_XACT_ABORT_PREPARED   0x40
#define XLOG_XACT_ASSIGNMENT   0x50

Definition at line 138 of file xact.h.

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

#define XLOG_XACT_COMMIT_PREPARED   0x30
#define XLOG_XACT_HAS_INFO   0x80
#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

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

Definition at line 120 of file xact.h.

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

Definition at line 110 of file xact.h.

Enumeration Type Documentation

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.

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
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

void AbortCurrentTransaction ( void  )

Definition at line 2984 of file xact.c.

References AbortCurrentTransaction(), AbortSubTransaction(), AbortTransaction(), TransactionStateData::blockState, CleanupSubTransaction(), CleanupTransaction(), CurrentTransactionState, TransactionStateData::state, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, TBLOCK_SUBRESTART, TRANS_DEFAULT, TRANS_INPROGRESS, and TRANS_START.

Referenced by AbortCurrentTransaction(), AutoVacLauncherMain(), PostgresMain(), ReorderBufferCommit(), ReorderBufferImmediateInvalidation(), and SnapBuildClearExportedSnapshot().

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

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

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

Definition at line 3779 of file xact.c.

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

Referenced by exec_simple_query().

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

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

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

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

3414 {
3416 
3417  switch (s->blockState)
3418  {
3419  /*
3420  * We are not inside a transaction block, so allow one to begin.
3421  */
3422  case TBLOCK_STARTED:
3423  s->blockState = TBLOCK_BEGIN;
3424  break;
3425 
3426  /*
3427  * BEGIN converts an implicit transaction block to a regular one.
3428  * (Note that we allow this even if we've already done some
3429  * commands, which is a bit odd but matches historical practice.)
3430  */
3432  s->blockState = TBLOCK_BEGIN;
3433  break;
3434 
3435  /*
3436  * Already a transaction block in progress.
3437  */
3438  case TBLOCK_INPROGRESS:
3440  case TBLOCK_SUBINPROGRESS:
3441  case TBLOCK_ABORT:
3442  case TBLOCK_SUBABORT:
3443  ereport(WARNING,
3444  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3445  errmsg("there is already a transaction in progress")));
3446  break;
3447 
3448  /* These cases are invalid. */
3449  case TBLOCK_DEFAULT:
3450  case TBLOCK_BEGIN:
3451  case TBLOCK_SUBBEGIN:
3452  case TBLOCK_END:
3453  case TBLOCK_SUBRELEASE:
3454  case TBLOCK_SUBCOMMIT:
3455  case TBLOCK_ABORT_END:
3456  case TBLOCK_SUBABORT_END:
3457  case TBLOCK_ABORT_PENDING:
3459  case TBLOCK_SUBRESTART:
3461  case TBLOCK_PREPARE:
3462  elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3464  break;
3465  }
3466 }
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:5147
#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
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:52
#define InvalidCommandId
Definition: c.h:408
static void AtCCI_LocalCache(void)
Definition: xact.c:1358
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
void CommitTransactionCommand ( void  )

Definition at line 2744 of file xact.c.

References AbortSubTransaction(), AbortTransaction(), Assert, AssertState, TransactionStateData::blockState, BlockStateAsString(), CleanupSubTransaction(), CleanupTransaction(), CommandCounterIncrement(), CommitSubTransaction(), CommitTransaction(), CommitTransactionCommand(), CurrentTransactionState, DefineSavepoint(), elog, ERROR, FATAL, TransactionStateData::name, 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().

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

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

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

Definition at line 3804 of file xact.c.

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

Referenced by exec_simple_query().

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

Definition at line 5084 of file xact.c.

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

Referenced by ParallelWorkerMain().

5085 {
5089 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
TBlockState blockState
Definition: xact.c:178
#define Assert(condition)
Definition: c.h:681
static void CommitTransaction(void)
Definition: xact.c:1933
bool EndTransactionBlock ( void  )

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

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

Definition at line 4960 of file xact.c.

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

Referenced by InitializeParallelDSM().

4961 {
4962  TransactionState s;
4963  Size nxids = 6; /* iso level, deferrable, top & current XID,
4964  * command counter, XID count */
4965 
4966  for (s = CurrentTransactionState; s != NULL; s = s->parent)
4967  {
4969  nxids = add_size(nxids, 1);
4970  nxids = add_size(nxids, s->nChildXids);
4971  }
4972 
4973  nxids = add_size(nxids, nParallelCurrentXids);
4974  return mul_size(nxids, sizeof(TransactionId));
4975 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
uint32 TransactionId
Definition: c.h:391
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:350
#define TransactionIdIsValid(xid)
Definition: transam.h:41
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:698
int parallelModeLevel
Definition: xact.c:191
#define Assert(condition)
Definition: c.h:681
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
CommandId GetCurrentCommandId ( bool  used)

Definition at line 680 of file xact.c.

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

Referenced by ATRewriteTable(), CopyFrom(), 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:681
static CommandId currentCommandId
Definition: xact.c:240
static bool currentCommandIdUsed
Definition: xact.c:241
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
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
TimestampTz GetCurrentTransactionStartTimestamp ( void  )
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
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:391
PGPROC * MyProc
Definition: proc.c:67
#define InvalidTransactionId
Definition: transam.h:31
TransactionId ReadNewTransactionId(void)
Definition: varsup.c:250
uint32 LocalTransactionId
Definition: c.h:393
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:405
#define Assert(condition)
Definition: c.h:681
#define InvalidLocalTransactionId
Definition: lock.h:69
#define TransactionIdIsValid(xid)
Definition: transam.h:41
LocalTransactionId lxid
Definition: proc.h:106
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
bool IsInTransactionChain ( bool  isTopLevel)

Definition at line 3268 of file xact.c.

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

Referenced by vacuum().

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

Definition at line 4447 of file xact.c.

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

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

4448 {
4450 
4452  return false;
4453 
4454  return true;
4455 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
TBlockState blockState
Definition: xact.c:178
bool IsTransactionOrTransactionBlock ( void  )

Definition at line 4465 of file xact.c.

References TransactionStateData::blockState, CurrentTransactionState, and TBLOCK_DEFAULT.

Referenced by PostgresMain(), ProcessCatchupInterrupt(), ProcessNotifyInterrupt(), RecoveryConflictInterrupt(), ReorderBufferCommit(), ReorderBufferImmediateInvalidation(), SnapBuildExportSnapshot(), and StartupDecodingContext().

4466 {
4468 
4469  if (s->blockState == TBLOCK_DEFAULT)
4470  return false;
4471 
4472  return true;
4473 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
TBlockState blockState
Definition: xact.c:178
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(), 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
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
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:391
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
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:391
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
bool PrepareTransactionBlock ( char *  gid)

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

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

Definition at line 3153 of file xact.c.

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

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

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

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

3359 {
3360  SubXactCallbackItem *item;
3361 
3362  item = (SubXactCallbackItem *)
3364  item->callback = callback;
3365  item->arg = arg;
3366  item->next = SubXact_callbacks;
3367  SubXact_callbacks = item;
3368 }
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:706
void * arg
void RegisterXactCallback ( XactCallback  callback,
void *  arg 
)

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

3304 {
3305  XactCallbackItem *item;
3306 
3307  item = (XactCallbackItem *)
3309  item->callback = callback;
3310  item->arg = arg;
3311  item->next = Xact_callbacks;
3312  Xact_callbacks = item;
3313 }
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:706
void * arg
void ReleaseCurrentSubTransaction ( void  )

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

4243 {
4245 
4246  /*
4247  * Workers synchronize transaction state at the beginning of each parallel
4248  * operation, so we can't account for commit of subtransactions after that
4249  * point. This should not happen anyway. Code calling this would
4250  * typically have called BeginInternalSubTransaction() first, failing
4251  * there.
4252  */
4253  if (IsInParallelMode())
4254  ereport(ERROR,
4255  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4256  errmsg("cannot commit subtransactions during a parallel operation")));
4257 
4258  if (s->blockState != TBLOCK_SUBINPROGRESS)
4259  elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4261  Assert(s->state == TRANS_INPROGRESS);
4264  s = CurrentTransactionState; /* changed by pop */
4265  Assert(s->state == TRANS_INPROGRESS);
4266 }
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:4581
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5147
#define ereport(elevel, rest)
Definition: elog.h:122
#define Assert(condition)
Definition: c.h:681
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
void ReleaseSavepoint ( List options)

Definition at line 3911 of file xact.c.

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

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

Definition at line 3206 of file xact.c.

References CheckTransactionChain().

Referenced by PerformCursorOpen(), and standard_ProcessUtility().

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

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

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

Definition at line 4032 of file xact.c.

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

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

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

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

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

5062 {
5063  TransactionId *tstate = (TransactionId *) tstatespace;
5064 
5066  StartTransaction();
5067 
5068  XactIsoLevel = (int) tstate[0];
5069  XactDeferrable = (bool) tstate[1];
5070  XactTopTransactionId = tstate[2];
5072  currentCommandId = tstate[4];
5073  nParallelCurrentXids = (int) tstate[5];
5074  ParallelCurrentXids = &tstate[6];
5075 
5077 }
TransactionId XactTopTransactionId
Definition: xact.c:107
bool XactDeferrable
Definition: xact.c:80
static TransactionState CurrentTransactionState
Definition: xact.c:233
uint32 TransactionId
Definition: c.h:391
int nParallelCurrentXids
Definition: xact.c:108
char bool
Definition: c.h:202
TBlockState blockState
Definition: xact.c:178
TransactionId transactionId
Definition: xact.c:173
static void StartTransaction(void)
Definition: xact.c:1795
TransactionId * ParallelCurrentXids
Definition: xact.c:109
#define Assert(condition)
Definition: c.h:681
int XactIsoLevel
Definition: xact.c:74
static CommandId currentCommandId
Definition: xact.c:240
void StartTransactionCommand ( void  )

Definition at line 2673 of file xact.c.

References Assert, TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, CurTransactionContext, elog, ERROR, MemoryContextSwitchTo(), StartTransaction(), TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by ApplyWorkerMain(), autoprewarm_database_main(), BeginInternalSubTransaction(), BootstrapModeMain(), cluster(), DefineIndex(), do_autovacuum(), ensure_transaction(), get_database_list(), get_subscription_list(), IdentifySystem(), index_drop(), initialize_worker_spi(), InitPostgres(), LogicalRepSyncTableStart(), maybe_reread_subscription(), movedb(), ParallelWorkerMain(), perform_work_item(), pg_attribute_noreturn(), process_syncing_tables_for_apply(), ProcessCatchupInterrupt(), ProcessCompletedNotifies(), ProcessIncomingNotify(), ReindexMultipleTables(), RemoveTempRelationsCallback(), ReorderBufferCommit(), SnapBuildExportSnapshot(), start_xact_command(), vacuum(), and vacuum_rel().

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

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

4480 {
4482 
4483  switch (s->blockState)
4484  {
4485  case TBLOCK_DEFAULT:
4486  case TBLOCK_STARTED:
4487  return 'I'; /* idle --- not in transaction */
4488  case TBLOCK_BEGIN:
4489  case TBLOCK_SUBBEGIN:
4490  case TBLOCK_INPROGRESS:
4493  case TBLOCK_SUBINPROGRESS:
4494  case TBLOCK_END:
4495  case TBLOCK_SUBRELEASE:
4496  case TBLOCK_SUBCOMMIT:
4497  case TBLOCK_PREPARE:
4498  return 'T'; /* in transaction */
4499  case TBLOCK_ABORT:
4500  case TBLOCK_SUBABORT:
4501  case TBLOCK_ABORT_END:
4502  case TBLOCK_SUBABORT_END:
4503  case TBLOCK_ABORT_PENDING:
4505  case TBLOCK_SUBRESTART:
4507  return 'E'; /* in failed transaction */
4508  }
4509 
4510  /* should never get here */
4511  elog(FATAL, "invalid transaction block state: %s",
4513  return 0; /* keep compiler quiet */
4514 }
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:5147
#define elog
Definition: elog.h:219
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:391
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
void UnregisterSubXactCallback ( SubXactCallback  callback,
void *  arg 
)

Definition at line 3371 of file xact.c.

References SubXactCallbackItem::next, and pfree().

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

Definition at line 3316 of file xact.c.

References XactCallbackItem::next, and pfree().

3317 {
3318  XactCallbackItem *item;
3319  XactCallbackItem *prev;
3320 
3321  prev = NULL;
3322  for (item = Xact_callbacks; item; prev = item, item = item->next)
3323  {
3324  if (item->callback == callback && item->arg == arg)
3325  {
3326  if (prev)
3327  prev->next = item->next;
3328  else
3329  Xact_callbacks = item->next;
3330  pfree(item);
3331  break;
3332  }
3333  }
3334 }
struct XactCallbackItem * next
Definition: xact.c:277
void pfree(void *pointer)
Definition: mcxt.c:949
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
void UserAbortTransactionBlock ( void  )

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

3670 {
3672 
3673  switch (s->blockState)
3674  {
3675  /*
3676  * We are inside a transaction block and we got a ROLLBACK command
3677  * from the user, so tell CommitTransactionCommand to abort and
3678  * exit the transaction block.
3679  */
3680  case TBLOCK_INPROGRESS:
3682  break;
3683 
3684  /*
3685  * We are inside a failed transaction block and we got a ROLLBACK
3686  * command from the user. Abort processing is already done, so
3687  * CommitTransactionCommand just has to cleanup and go back to
3688  * idle state.
3689  */
3690  case TBLOCK_ABORT:
3692  break;
3693 
3694  /*
3695  * We are inside a subtransaction. Mark everything up to top
3696  * level as exitable.
3697  */
3698  case TBLOCK_SUBINPROGRESS:
3699  case TBLOCK_SUBABORT:
3700  while (s->parent != NULL)
3701  {
3702  if (s->blockState == TBLOCK_SUBINPROGRESS)
3704  else if (s->blockState == TBLOCK_SUBABORT)
3706  else
3707  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3709  s = s->parent;
3710  }
3711  if (s->blockState == TBLOCK_INPROGRESS)
3713  else if (s->blockState == TBLOCK_ABORT)
3715  else
3716  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3718  break;
3719 
3720  /*
3721  * The user issued ABORT when not inside a transaction. Issue a
3722  * WARNING and go to abort state. The upcoming call to
3723  * CommitTransactionCommand() will then put us back into the
3724  * default state.
3725  *
3726  * We do the same thing with ABORT inside an implicit transaction,
3727  * although in this case we might be rolling back actual database
3728  * state changes. (It's debatable whether we should issue a
3729  * WARNING in this case, but we have done so historically.)
3730  */
3731  case TBLOCK_STARTED:
3733  ereport(WARNING,
3734  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3735  errmsg("there is no transaction in progress")));
3737  break;
3738 
3739  /*
3740  * The user issued an ABORT that somehow ran inside a parallel
3741  * worker. We can't cope with that.
3742  */
3744  ereport(FATAL,
3745  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3746  errmsg("cannot abort during a parallel operation")));
3747  break;
3748 
3749  /* These cases are invalid. */
3750  case TBLOCK_DEFAULT:
3751  case TBLOCK_BEGIN:
3752  case TBLOCK_SUBBEGIN:
3753  case TBLOCK_END:
3754  case TBLOCK_SUBRELEASE:
3755  case TBLOCK_SUBCOMMIT:
3756  case TBLOCK_ABORT_END:
3757  case TBLOCK_SUBABORT_END:
3758  case TBLOCK_ABORT_PENDING:
3760  case TBLOCK_SUBRESTART:
3762  case TBLOCK_PREPARE:
3763  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3765  break;
3766  }
3767 }
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:5147
#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
void WarnNoTransactionChain ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3200 of file xact.c.

References CheckTransactionChain().

Referenced by ExecSetVariableStmt(), and standard_ProcessUtility().

3201 {
3202  CheckTransactionChain(isTopLevel, false, stmtType);
3203 }
static void CheckTransactionChain(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3229
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:256
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
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
void xact_redo ( XLogReaderState record)

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

5743 {
5744  uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
5745 
5746  /* Backup blocks are not used in xact records */
5747  Assert(!XLogRecHasAnyBlockRefs(record));
5748 
5749  if (info == XLOG_XACT_COMMIT)
5750  {
5751  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
5752  xl_xact_parsed_commit parsed;
5753 
5754  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
5755  xact_redo_commit(&parsed, XLogRecGetXid(record),
5756  record->EndRecPtr, XLogRecGetOrigin(record));
5757  }
5758  else if (info == XLOG_XACT_COMMIT_PREPARED)
5759  {
5760  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
5761  xl_xact_parsed_commit parsed;
5762 
5763  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
5764  xact_redo_commit(&parsed, parsed.twophase_xid,
5765  record->EndRecPtr, XLogRecGetOrigin(record));
5766 
5767  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
5768  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5769  PrepareRedoRemove(parsed.twophase_xid, false);
5770  LWLockRelease(TwoPhaseStateLock);
5771  }
5772  else if (info == XLOG_XACT_ABORT)
5773  {
5774  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
5775  xl_xact_parsed_abort parsed;
5776 
5777  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
5778  xact_redo_abort(&parsed, XLogRecGetXid(record));
5779  }
5780  else if (info == XLOG_XACT_ABORT_PREPARED)
5781  {
5782  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
5783  xl_xact_parsed_abort parsed;
5784 
5785  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
5786  xact_redo_abort(&parsed, parsed.twophase_xid);
5787 
5788  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
5789  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5790  PrepareRedoRemove(parsed.twophase_xid, false);
5791  LWLockRelease(TwoPhaseStateLock);
5792  }
5793  else if (info == XLOG_XACT_PREPARE)
5794  {
5795  /*
5796  * Store xid and start/end pointers of the WAL record in TwoPhaseState
5797  * gxact entry.
5798  */
5799  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5801  record->ReadRecPtr,
5802  record->EndRecPtr);
5803  LWLockRelease(TwoPhaseStateLock);
5804  }
5805  else if (info == XLOG_XACT_ASSIGNMENT)
5806  {
5808 
5811  xlrec->nsubxacts, xlrec->xsub);
5812  }
5813  else
5814  elog(PANIC, "xact_redo: unknown op code %u", info);
5815 }
#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:5489
TransactionId twophase_xid
Definition: xact.h:304
unsigned char uint8
Definition: c.h:256
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:1721
#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:5662
TransactionId twophase_xid
Definition: xact.h:321
#define Assert(condition)
Definition: c.h:681
#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:1117
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
int xactGetCommittedChildren ( TransactionId **  ptr)

Definition at line 5230 of file xact.c.

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

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

5231 {
5233 
5234  if (s->nChildXids == 0)
5235  *ptr = NULL;
5236  else
5237  *ptr = s->childXids;
5238 
5239  return s->nChildXids;
5240 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
TransactionId * childXids
Definition: xact.c:183
XLogRecPtr XactLogAbortRecord ( TimestampTz  abort_time,
int  nsubxacts,
TransactionId subxacts,
int  nrels,
RelFileNode rels,
int  xactflags,
TransactionId  twophase_xid 
)

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

5405 {
5406  xl_xact_abort xlrec;
5407  xl_xact_xinfo xl_xinfo;
5408  xl_xact_subxacts xl_subxacts;
5409  xl_xact_relfilenodes xl_relfilenodes;
5410  xl_xact_twophase xl_twophase;
5411 
5412  uint8 info;
5413 
5414  Assert(CritSectionCount > 0);
5415 
5416  xl_xinfo.xinfo = 0;
5417 
5418  /* decide between a plain and 2pc abort */
5419  if (!TransactionIdIsValid(twophase_xid))
5420  info = XLOG_XACT_ABORT;
5421  else
5422  info = XLOG_XACT_ABORT_PREPARED;
5423 
5424 
5425  /* First figure out and collect all the information needed */
5426 
5427  xlrec.xact_time = abort_time;
5428 
5429  if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5430  xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5431 
5432  if (nsubxacts > 0)
5433  {
5434  xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5435  xl_subxacts.nsubxacts = nsubxacts;
5436  }
5437 
5438  if (nrels > 0)
5439  {
5440  xl_xinfo.xinfo |= XACT_XINFO_HAS_RELFILENODES;
5441  xl_relfilenodes.nrels = nrels;
5442  }
5443 
5444  if (TransactionIdIsValid(twophase_xid))
5445  {
5446  xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5447  xl_twophase.xid = twophase_xid;
5448  }
5449 
5450  if (xl_xinfo.xinfo != 0)
5451  info |= XLOG_XACT_HAS_INFO;
5452 
5453  /* Then include all the collected data into the abort record. */
5454 
5455  XLogBeginInsert();
5456 
5457  XLogRegisterData((char *) (&xlrec), MinSizeOfXactAbort);
5458 
5459  if (xl_xinfo.xinfo != 0)
5460  XLogRegisterData((char *) (&xl_xinfo), sizeof(xl_xinfo));
5461 
5462  if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5463  {
5464  XLogRegisterData((char *) (&xl_subxacts),
5466  XLogRegisterData((char *) subxacts,
5467  nsubxacts * sizeof(TransactionId));
5468  }
5469 
5470  if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILENODES)
5471  {
5472  XLogRegisterData((char *) (&xl_relfilenodes),
5474  XLogRegisterData((char *) rels,
5475  nrels * sizeof(RelFileNode));
5476  }
5477 
5478  if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5479  XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
5480 
5481  return XLogInsert(RM_XACT_ID, info);
5482 }
uint32 TransactionId
Definition: c.h:391
TransactionId xid
Definition: xact.h:245
unsigned char uint8
Definition: c.h:256
#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:681
#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
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 5254 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().

5260 {
5261  xl_xact_commit xlrec;
5262  xl_xact_xinfo xl_xinfo;
5263  xl_xact_dbinfo xl_dbinfo;
5264  xl_xact_subxacts xl_subxacts;
5265  xl_xact_relfilenodes xl_relfilenodes;
5266  xl_xact_invals xl_invals;
5267  xl_xact_twophase xl_twophase;
5268  xl_xact_origin xl_origin;
5269 
5270  uint8 info;
5271 
5272  Assert(CritSectionCount > 0);
5273 
5274  xl_xinfo.xinfo = 0;
5275 
5276  /* decide between a plain and 2pc commit */
5277  if (!TransactionIdIsValid(twophase_xid))
5278  info = XLOG_XACT_COMMIT;
5279  else
5281 
5282  /* First figure out and collect all the information needed */
5283 
5284  xlrec.xact_time = commit_time;
5285 
5286  if (relcacheInval)
5288  if (forceSyncCommit)
5290  if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5291  xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5292 
5293  /*
5294  * Check if the caller would like to ask standbys for immediate feedback
5295  * once this commit is applied.
5296  */
5299 
5300  /*
5301  * Relcache invalidations requires information about the current database
5302  * and so does logical decoding.
5303  */
5304  if (nmsgs > 0 || XLogLogicalInfoActive())
5305  {
5306  xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5307  xl_dbinfo.dbId = MyDatabaseId;
5308  xl_dbinfo.tsId = MyDatabaseTableSpace;
5309  }
5310 
5311  if (nsubxacts > 0)
5312  {
5313  xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5314  xl_subxacts.nsubxacts = nsubxacts;
5315  }
5316 
5317  if (nrels > 0)
5318  {
5319  xl_xinfo.xinfo |= XACT_XINFO_HAS_RELFILENODES;
5320  xl_relfilenodes.nrels = nrels;
5321  }
5322 
5323  if (nmsgs > 0)
5324  {
5325  xl_xinfo.xinfo |= XACT_XINFO_HAS_INVALS;
5326  xl_invals.nmsgs = nmsgs;
5327  }
5328 
5329  if (TransactionIdIsValid(twophase_xid))
5330  {
5331  xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5332  xl_twophase.xid = twophase_xid;
5333  }
5334 
5335  /* dump transaction origin information */
5337  {
5338  xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
5339 
5342  }
5343 
5344  if (xl_xinfo.xinfo != 0)
5345  info |= XLOG_XACT_HAS_INFO;
5346 
5347  /* Then include all the collected data into the commit record. */
5348 
5349  XLogBeginInsert();
5350 
5351  XLogRegisterData((char *) (&xlrec), sizeof(xl_xact_commit));
5352 
5353  if (xl_xinfo.xinfo != 0)
5354  XLogRegisterData((char *) (&xl_xinfo.xinfo), sizeof(xl_xinfo.xinfo));
5355 
5356  if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5357  XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
5358 
5359  if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5360  {
5361  XLogRegisterData((char *) (&xl_subxacts),
5363  XLogRegisterData((char *) subxacts,
5364  nsubxacts * sizeof(TransactionId));
5365  }
5366 
5367  if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILENODES)
5368  {
5369  XLogRegisterData((char *) (&xl_relfilenodes),
5371  XLogRegisterData((char *) rels,
5372  nrels * sizeof(RelFileNode));
5373  }
5374 
5375  if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
5376  {
5377  XLogRegisterData((char *) (&xl_invals), MinSizeOfXactInvals);
5378  XLogRegisterData((char *) msgs,
5379  nmsgs * sizeof(SharedInvalidationMessage));
5380  }
5381 
5382  if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5383  XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
5384 
5385  if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5386  XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
5387 
5388  /* we allow filtering by xacts */
5390 
5391  return XLogInsert(RM_XACT_ID, info);
5392 }