PostgreSQL Source Code git master
Loading...
Searching...
No Matches
xact.c File Reference
#include "postgres.h"
#include <time.h>
#include <unistd.h>
#include "access/commit_ts.h"
#include "access/multixact.h"
#include "access/parallel.h"
#include "access/subtrans.h"
#include "access/transam.h"
#include "access/twophase.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "access/xlogrecovery.h"
#include "access/xlogutils.h"
#include "access/xlogwait.h"
#include "catalog/index.h"
#include "catalog/namespace.h"
#include "catalog/pg_enum.h"
#include "catalog/storage.h"
#include "commands/async.h"
#include "commands/tablecmds.h"
#include "commands/trigger.h"
#include "common/pg_prng.h"
#include "executor/spi.h"
#include "libpq/be-fsstubs.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pg_trace.h"
#include "pgstat.h"
#include "replication/logical.h"
#include "replication/logicallauncher.h"
#include "replication/logicalworker.h"
#include "replication/origin.h"
#include "replication/snapbuild.h"
#include "replication/syncrep.h"
#include "storage/aio_subsys.h"
#include "storage/condition_variable.h"
#include "storage/fd.h"
#include "storage/lmgr.h"
#include "storage/md.h"
#include "storage/predicate.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/sinvaladt.h"
#include "storage/smgr.h"
#include "utils/builtins.h"
#include "utils/combocid.h"
#include "utils/guc.h"
#include "utils/inval.h"
#include "utils/memutils.h"
#include "utils/relmapper.h"
#include "utils/snapmgr.h"
#include "utils/timeout.h"
#include "utils/timestamp.h"
#include "utils/typcache.h"
#include "utils/wait_event.h"
Include dependency graph for xact.c:

Go to the source code of this file.

Data Structures

struct  TransactionStateData
 
struct  SerializedTransactionState
 
struct  XactCallbackItem
 
struct  SubXactCallbackItem
 

Macros

#define SerializedTransactionStateHeaderSize    offsetof(SerializedTransactionState, parallelCurrentXids)
 

Typedefs

typedef enum TransState TransState
 
typedef enum TBlockState TBlockState
 
typedef struct TransactionStateData TransactionStateData
 
typedef TransactionStateDataTransactionState
 
typedef struct SerializedTransactionState SerializedTransactionState
 
typedef struct XactCallbackItem XactCallbackItem
 
typedef struct SubXactCallbackItem SubXactCallbackItem
 

Enumerations

enum  TransState {
  TRANS_DEFAULT , TRANS_START , TRANS_INPROGRESS , TRANS_COMMIT ,
  TRANS_ABORT , TRANS_PREPARE
}
 
enum  TBlockState {
  TBLOCK_DEFAULT , TBLOCK_STARTED , TBLOCK_BEGIN , TBLOCK_INPROGRESS ,
  TBLOCK_IMPLICIT_INPROGRESS , TBLOCK_PARALLEL_INPROGRESS , TBLOCK_END , TBLOCK_ABORT ,
  TBLOCK_ABORT_END , TBLOCK_ABORT_PENDING , TBLOCK_PREPARE , TBLOCK_SUBBEGIN ,
  TBLOCK_SUBINPROGRESS , TBLOCK_SUBRELEASE , TBLOCK_SUBCOMMIT , TBLOCK_SUBABORT ,
  TBLOCK_SUBABORT_END , TBLOCK_SUBABORT_PENDING , TBLOCK_SUBRESTART , TBLOCK_SUBABORT_RESTART
}
 

Functions

static void AssignTransactionId (TransactionState s)
 
static void AbortTransaction (void)
 
static void AtAbort_Memory (void)
 
static void AtCleanup_Memory (void)
 
static void AtAbort_ResourceOwner (void)
 
static void AtCCI_LocalCache (void)
 
static void AtCommit_Memory (void)
 
static void AtStart_Cache (void)
 
static void AtStart_Memory (void)
 
static void AtStart_ResourceOwner (void)
 
static void CallXactCallbacks (XactEvent event)
 
static void CallSubXactCallbacks (SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
 
static void CleanupTransaction (void)
 
static void CheckTransactionBlock (bool isTopLevel, bool throwError, const char *stmtType)
 
static void CommitTransaction (void)
 
static TransactionId RecordTransactionAbort (bool isSubXact)
 
static void StartTransaction (void)
 
static bool CommitTransactionCommandInternal (void)
 
static bool AbortCurrentTransactionInternal (void)
 
static void StartSubTransaction (void)
 
static void CommitSubTransaction (void)
 
static void AbortSubTransaction (void)
 
static void CleanupSubTransaction (void)
 
static void PushTransaction (void)
 
static void PopTransaction (void)
 
static void AtSubAbort_Memory (void)
 
static void AtSubCleanup_Memory (void)
 
static void AtSubAbort_ResourceOwner (void)
 
static void AtSubCommit_Memory (void)
 
static void AtSubStart_Memory (void)
 
static void AtSubStart_ResourceOwner (void)
 
static void ShowTransactionState (const char *str)
 
static void ShowTransactionStateRec (const char *str, TransactionState s)
 
static const charBlockStateAsString (TBlockState blockState)
 
static const charTransStateAsString (TransState state)
 
bool IsTransactionState (void)
 
bool IsAbortedTransactionBlockState (void)
 
TransactionId GetTopTransactionId (void)
 
TransactionId GetTopTransactionIdIfAny (void)
 
TransactionId GetCurrentTransactionId (void)
 
TransactionId GetCurrentTransactionIdIfAny (void)
 
FullTransactionId GetTopFullTransactionId (void)
 
FullTransactionId GetTopFullTransactionIdIfAny (void)
 
FullTransactionId GetCurrentFullTransactionId (void)
 
FullTransactionId GetCurrentFullTransactionIdIfAny (void)
 
void MarkCurrentTransactionIdLoggedIfAny (void)
 
bool IsSubxactTopXidLogPending (void)
 
void MarkSubxactTopXidLogged (void)
 
TransactionId GetStableLatestTransactionId (void)
 
SubTransactionId GetCurrentSubTransactionId (void)
 
bool SubTransactionIsActive (SubTransactionId subxid)
 
CommandId GetCurrentCommandId (bool used)
 
void SetParallelStartTimestamps (TimestampTz xact_ts, TimestampTz stmt_ts)
 
TimestampTz GetCurrentTransactionStartTimestamp (void)
 
TimestampTz GetCurrentStatementStartTimestamp (void)
 
TimestampTz GetCurrentTransactionStopTimestamp (void)
 
void SetCurrentStatementStartTimestamp (void)
 
int GetCurrentTransactionNestLevel (void)
 
bool TransactionIdIsCurrentTransactionId (TransactionId xid)
 
bool TransactionStartedDuringRecovery (void)
 
int GetTopReadOnlyTransactionNestLevel (void)
 
void EnterParallelMode (void)
 
void ExitParallelMode (void)
 
bool IsInParallelMode (void)
 
void CommandCounterIncrement (void)
 
void ForceSyncCommit (void)
 
static TransactionId RecordTransactionCommit (void)
 
static void AtSubCommit_childXids (void)
 
static void AtSubAbort_childXids (void)
 
static void PrepareTransaction (void)
 
void StartTransactionCommand (void)
 
void SaveTransactionCharacteristics (SavedTransactionCharacteristics *s)
 
void RestoreTransactionCharacteristics (const SavedTransactionCharacteristics *s)
 
void CommitTransactionCommand (void)
 
void AbortCurrentTransaction (void)
 
void PreventInTransactionBlock (bool isTopLevel, const char *stmtType)
 
void WarnNoTransactionBlock (bool isTopLevel, const char *stmtType)
 
void RequireTransactionBlock (bool isTopLevel, const char *stmtType)
 
bool IsInTransactionBlock (bool isTopLevel)
 
void RegisterXactCallback (XactCallback callback, void *arg)
 
void UnregisterXactCallback (XactCallback callback, void *arg)
 
void RegisterSubXactCallback (SubXactCallback callback, void *arg)
 
void UnregisterSubXactCallback (SubXactCallback callback, void *arg)
 
void BeginTransactionBlock (void)
 
bool PrepareTransactionBlock (const char *gid)
 
bool EndTransactionBlock (bool chain)
 
void UserAbortTransactionBlock (bool chain)
 
void BeginImplicitTransactionBlock (void)
 
void EndImplicitTransactionBlock (void)
 
void DefineSavepoint (const char *name)
 
void ReleaseSavepoint (const char *name)
 
void RollbackToSavepoint (const char *name)
 
void BeginInternalSubTransaction (const char *name)
 
void ReleaseCurrentSubTransaction (void)
 
void RollbackAndReleaseCurrentSubTransaction (void)
 
void AbortOutOfAnyTransaction (void)
 
bool IsTransactionBlock (void)
 
bool IsTransactionOrTransactionBlock (void)
 
char TransactionBlockStatusCode (void)
 
bool IsSubTransaction (void)
 
Size EstimateTransactionStateSpace (void)
 
void SerializeTransactionState (Size maxsize, char *start_address)
 
void StartParallelWorkerTransaction (char *tstatespace)
 
void EndParallelWorkerTransaction (void)
 
int xactGetCommittedChildren (TransactionId **ptr)
 
XLogRecPtr XactLogCommitRecord (TimestampTz commit_time, int nsubxacts, TransactionId *subxacts, int nrels, RelFileLocator *rels, int ndroppedstats, xl_xact_stats_item *droppedstats, int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInval, int xactflags, TransactionId twophase_xid, const char *twophase_gid)
 
XLogRecPtr XactLogAbortRecord (TimestampTz abort_time, int nsubxacts, TransactionId *subxacts, int nrels, RelFileLocator *rels, int ndroppedstats, xl_xact_stats_item *droppedstats, int xactflags, TransactionId twophase_xid, const char *twophase_gid)
 
static void xact_redo_commit (xl_xact_parsed_commit *parsed, TransactionId xid, XLogRecPtr lsn, ReplOriginId origin_id)
 
static void xact_redo_abort (xl_xact_parsed_abort *parsed, TransactionId xid, XLogRecPtr lsn, ReplOriginId origin_id)
 
void xact_redo (XLogReaderState *record)
 

Variables

int DefaultXactIsoLevel = XACT_READ_COMMITTED
 
int XactIsoLevel = XACT_READ_COMMITTED
 
bool DefaultXactReadOnly = false
 
bool XactReadOnly
 
bool DefaultXactDeferrable = false
 
bool XactDeferrable
 
int synchronous_commit = SYNCHRONOUS_COMMIT_ON
 
TransactionId CheckXidAlive = InvalidTransactionId
 
bool bsysscan = false
 
static FullTransactionId XactTopFullTransactionId = {InvalidTransactionId}
 
static int nParallelCurrentXids = 0
 
static TransactionIdParallelCurrentXids
 
int MyXactFlags
 
static TransactionStateData TopTransactionStateData
 
static int nUnreportedXids
 
static TransactionId unreportedXids [PGPROC_MAX_CACHED_SUBXIDS]
 
static TransactionState CurrentTransactionState = &TopTransactionStateData
 
static SubTransactionId currentSubTransactionId
 
static CommandId currentCommandId
 
static bool currentCommandIdUsed
 
static TimestampTz xactStartTimestamp
 
static TimestampTz stmtStartTimestamp
 
static TimestampTz xactStopTimestamp
 
static charprepareGID
 
static bool forceSyncCommit = false
 
bool xact_is_sampled = false
 
static MemoryContext TransactionAbortContext = NULL
 
static XactCallbackItemXact_callbacks = NULL
 
static SubXactCallbackItemSubXact_callbacks = NULL
 

Macro Definition Documentation

◆ SerializedTransactionStateHeaderSize

#define SerializedTransactionStateHeaderSize    offsetof(SerializedTransactionState, parallelCurrentXids)

Definition at line 241 of file xact.c.

248 {
249 .state = TRANS_DEFAULT,
250 .blockState = TBLOCK_DEFAULT,
251 .topXidLogged = false,
252};
253
254/*
255 * unreportedXids holds XIDs of all subtransactions that have not yet been
256 * reported in an XLOG_XACT_ASSIGNMENT record.
257 */
258static int nUnreportedXids;
260
262
263/*
264 * The subtransaction ID and command ID assignment counters are global
265 * to a whole transaction, so we do not keep them in the state stack.
266 */
269static bool currentCommandIdUsed;
270
271/*
272 * xactStartTimestamp is the value of transaction_timestamp().
273 * stmtStartTimestamp is the value of statement_timestamp().
274 * xactStopTimestamp is the time at which we log a commit / abort WAL record,
275 * or if that was skipped, the time of the first subsequent
276 * GetCurrentTransactionStopTimestamp() call.
277 *
278 * These do not change as we enter and exit subtransactions, so we don't
279 * keep them inside the TransactionState stack.
280 */
284
285/*
286 * GID to be used for preparing the current transaction. This is also
287 * global to a whole transaction, so we don't keep it in the state stack.
288 */
289static char *prepareGID;
290
291/*
292 * Some commands want to force synchronous commit.
293 */
294static bool forceSyncCommit = false;
295
296/* Flag for logging statements in a transaction. */
297bool xact_is_sampled = false;
298
299/*
300 * Private context for transaction-abort work --- we reserve space for this
301 * at startup to ensure that AbortTransaction and AbortSubTransaction can work
302 * when we've run out of memory.
303 */
305
306/*
307 * List of add-on start- and end-of-xact callbacks
308 */
309typedef struct XactCallbackItem
310{
311 struct XactCallbackItem *next;
313 void *arg;
315
317
318/*
319 * List of add-on start- and end-of-subxact callbacks
320 */
321typedef struct SubXactCallbackItem
322{
325 void *arg;
327
329
330
331/* local function prototypes */
333static void AbortTransaction(void);
334static void AtAbort_Memory(void);
335static void AtCleanup_Memory(void);
336static void AtAbort_ResourceOwner(void);
337static void AtCCI_LocalCache(void);
338static void AtCommit_Memory(void);
339static void AtStart_Cache(void);
340static void AtStart_Memory(void);
341static void AtStart_ResourceOwner(void);
342static void CallXactCallbacks(XactEvent event);
343static void CallSubXactCallbacks(SubXactEvent event,
346static void CleanupTransaction(void);
347static void CheckTransactionBlock(bool isTopLevel, bool throwError,
348 const char *stmtType);
349static void CommitTransaction(void);
351static void StartTransaction(void);
352
353static bool CommitTransactionCommandInternal(void);
354static bool AbortCurrentTransactionInternal(void);
355
356static void StartSubTransaction(void);
357static void CommitSubTransaction(void);
358static void AbortSubTransaction(void);
359static void CleanupSubTransaction(void);
360static void PushTransaction(void);
361static void PopTransaction(void);
362
363static void AtSubAbort_Memory(void);
364static void AtSubCleanup_Memory(void);
365static void AtSubAbort_ResourceOwner(void);
366static void AtSubCommit_Memory(void);
367static void AtSubStart_Memory(void);
368static void AtSubStart_ResourceOwner(void);
369
370static void ShowTransactionState(const char *str);
371static void ShowTransactionStateRec(const char *str, TransactionState s);
372static const char *BlockStateAsString(TBlockState blockState);
373static const char *TransStateAsString(TransState state);
374
375
376/* ----------------------------------------------------------------
377 * transaction state accessors
378 * ----------------------------------------------------------------
379 */
380
381/*
382 * IsTransactionState
383 *
384 * This returns true if we are inside a valid transaction; that is,
385 * it is safe to initiate database access, take heavyweight locks, etc.
386 */
387bool
389{
391
392 /*
393 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
394 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
395 * TRANS_PREPARE since it might be too soon or too late within those
396 * transition states to do anything interesting. Hence, the only "valid"
397 * state is TRANS_INPROGRESS.
398 */
399 return (s->state == TRANS_INPROGRESS);
400}
401
402/*
403 * IsAbortedTransactionBlockState
404 *
405 * This returns true if we are within an aborted transaction block.
406 */
407bool
409{
411
412 if (s->blockState == TBLOCK_ABORT ||
414 return true;
415
416 return false;
417}
418
419
420/*
421 * GetTopTransactionId
422 *
423 * This will return the XID of the main transaction, assigning one if
424 * it's not yet set. Be careful to call this only inside a valid xact.
425 */
428{
432}
433
434/*
435 * GetTopTransactionIdIfAny
436 *
437 * This will return the XID of the main transaction, if one is assigned.
438 * It will return InvalidTransactionId if we are not currently inside a
439 * transaction, or inside a transaction that hasn't yet been assigned an XID.
440 */
443{
445}
446
447/*
448 * GetCurrentTransactionId
449 *
450 * This will return the XID of the current transaction (main or sub
451 * transaction), assigning one if it's not yet set. Be careful to call this
452 * only inside a valid xact.
453 */
456{
458
462}
463
464/*
465 * GetCurrentTransactionIdIfAny
466 *
467 * This will return the XID of the current sub xact, if one is assigned.
468 * It will return InvalidTransactionId if we are not currently inside a
469 * transaction, or inside a transaction that hasn't been assigned an XID yet.
470 */
473{
475}
476
477/*
478 * GetTopFullTransactionId
479 *
480 * This will return the FullTransactionId of the main transaction, assigning
481 * one if it's not yet set. Be careful to call this only inside a valid xact.
482 */
485{
489}
490
491/*
492 * GetTopFullTransactionIdIfAny
493 *
494 * This will return the FullTransactionId of the main transaction, if one is
495 * assigned. It will return InvalidFullTransactionId if we are not currently
496 * inside a transaction, or inside a transaction that hasn't yet been assigned
497 * one.
498 */
501{
503}
504
505/*
506 * GetCurrentFullTransactionId
507 *
508 * This will return the FullTransactionId of the current transaction (main or
509 * sub transaction), assigning one if it's not yet set. Be careful to call
510 * this only inside a valid xact.
511 */
514{
516
519 return s->fullTransactionId;
520}
521
522/*
523 * GetCurrentFullTransactionIdIfAny
524 *
525 * This will return the FullTransactionId of the current sub xact, if one is
526 * assigned. It will return InvalidFullTransactionId if we are not currently
527 * inside a transaction, or inside a transaction that hasn't been assigned one
528 * yet.
529 */
532{
534}
535
536/*
537 * MarkCurrentTransactionIdLoggedIfAny
538 *
539 * Remember that the current xid - if it is assigned - now has been wal logged.
540 */
541void
543{
546}
547
548/*
549 * IsSubxactTopXidLogPending
550 *
551 * This is used to decide whether we need to WAL log the top-level XID for
552 * operation in a subtransaction. We require that for logical decoding, see
553 * LogicalDecodingProcessRecord.
554 *
555 * This returns true if effective_wal_level is logical and we are inside
556 * a valid subtransaction, for which the assignment was not yet written to
557 * any WAL record.
558 */
559bool
561{
562 /* check whether it is already logged */
564 return false;
565
566 /* effective_wal_level has to be logical */
568 return false;
569
570 /* we need to be in a transaction state */
571 if (!IsTransactionState())
572 return false;
573
574 /* it has to be a subtransaction */
575 if (!IsSubTransaction())
576 return false;
577
578 /* the subtransaction has to have a XID assigned */
580 return false;
581
582 return true;
583}
584
585/*
586 * MarkSubxactTopXidLogged
587 *
588 * Remember that the top transaction id for the current subtransaction is WAL
589 * logged now.
590 */
591void
593{
595
597}
598
599/*
600 * GetStableLatestTransactionId
601 *
602 * Get the transaction's XID if it has one, else read the next-to-be-assigned
603 * XID. Once we have a value, return that same value for the remainder of the
604 * current transaction. This is meant to provide the reference point for the
605 * age(xid) function, but might be useful for other maintenance tasks as well.
606 */
609{
612
613 if (lxid != MyProc->vxid.lxid)
614 {
615 lxid = MyProc->vxid.lxid;
619 }
620
622
623 return stablexid;
624}
625
626/*
627 * AssignTransactionId
628 *
629 * Assigns a new permanent FullTransactionId to the given TransactionState.
630 * We do not assign XIDs to transactions until/unless this is called.
631 * Also, any parent TransactionStates that don't yet have XIDs are assigned
632 * one; this maintains the invariant that a child transaction has an XID
633 * following its parent's.
634 */
635static void
637{
638 bool isSubXact = (s->parent != NULL);
640 bool log_unknown_top = false;
641
642 /* Assert that caller didn't screw up */
645
646 /*
647 * Workers synchronize transaction state at the beginning of each parallel
648 * operation, so we can't account for new XIDs at this point.
649 */
653 errmsg("cannot assign transaction IDs during a parallel operation")));
654
655 /*
656 * Ensure parent(s) have XIDs, so that a child always has an XID later
657 * than its parent. Mustn't recurse here, or we might get a stack
658 * overflow if we're at the bottom of a huge stack of subtransactions none
659 * of which have XIDs yet.
660 */
662 {
664 TransactionState *parents;
665 size_t parentOffset = 0;
666
669 {
670 parents[parentOffset++] = p;
671 p = p->parent;
672 }
673
674 /*
675 * This is technically a recursive call, but the recursion will never
676 * be more than one layer deep.
677 */
678 while (parentOffset != 0)
679 AssignTransactionId(parents[--parentOffset]);
680
681 pfree(parents);
682 }
683
684 /*
685 * When effective_wal_level is logical, guarantee that a subtransaction's
686 * xid can only be seen in the WAL stream if its toplevel xid has been
687 * logged before. If necessary we log an xact_assignment record with fewer
688 * than PGPROC_MAX_CACHED_SUBXIDS. Note that it is fine if didLogXid isn't
689 * set for a transaction even though it appears in a WAL record, we just
690 * might superfluously log something. That can happen when an xid is
691 * included somewhere inside a wal record, but not in XLogRecord->xl_xid,
692 * like in xl_standby_locks.
693 */
696 log_unknown_top = true;
697
698 /*
699 * Generate a new FullTransactionId and record its xid in PGPROC and
700 * pg_subtrans.
701 *
702 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
703 * shared storage other than PGPROC; because if there's no room for it in
704 * PGPROC, the subtrans entry is needed to ensure that other backends see
705 * the Xid as "running". See GetNewTransactionId.
706 */
708 if (!isSubXact)
710
711 if (isSubXact)
714
715 /*
716 * If it's a top-level transaction, the predicate locking system needs to
717 * be told about it too.
718 */
719 if (!isSubXact)
721
722 /*
723 * Acquire lock on the transaction XID. (We assume this cannot block.) We
724 * have to ensure that the lock is assigned to the transaction's own
725 * ResourceOwner.
726 */
729
731
733
734 /*
735 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
736 * top-level transaction we issue a WAL record for the assignment. We
737 * include the top-level xid and all the subxids that have not yet been
738 * reported using XLOG_XACT_ASSIGNMENT records.
739 *
740 * This is required to limit the amount of shared memory required in a hot
741 * standby server to keep track of in-progress XIDs. See notes for
742 * RecordKnownAssignedTransactionIds().
743 *
744 * We don't keep track of the immediate parent of each subxid, only the
745 * top-level transaction that each subxact belongs to. This is correct in
746 * recovery only because aborted subtransactions are separately WAL
747 * logged.
748 *
749 * This is correct even for the case where several levels above us didn't
750 * have an xid assigned as we recursed up to them beforehand.
751 */
753 {
756
757 /*
758 * ensure this test matches similar one in
759 * RecoverPreparedTransactions()
760 */
763 {
765
766 /*
767 * xtop is always set by now because we recurse up transaction
768 * stack to the highest unassigned xid and then come back down
769 */
772 xlrec.nsubxacts = nUnreportedXids;
773
778
780
781 nUnreportedXids = 0;
782 /* mark top, not current xact as having been logged */
784 }
785 }
786}
787
788/*
789 * GetCurrentSubTransactionId
790 */
793{
795
796 return s->subTransactionId;
797}
798
799/*
800 * SubTransactionIsActive
801 *
802 * Test if the specified subxact ID is still active. Note caller is
803 * responsible for checking whether this ID is relevant to the current xact.
804 */
805bool
807{
809
810 for (s = CurrentTransactionState; s != NULL; s = s->parent)
811 {
812 if (s->state == TRANS_ABORT)
813 continue;
814 if (s->subTransactionId == subxid)
815 return true;
816 }
817 return false;
818}
819
820
821/*
822 * GetCurrentCommandId
823 *
824 * "used" must be true if the caller intends to use the command ID to mark
825 * inserted/updated/deleted tuples. false means the ID is being fetched
826 * for read-only purposes (ie, as a snapshot validity cutoff). See
827 * CommandCounterIncrement() for discussion.
828 */
830GetCurrentCommandId(bool used)
831{
832 /* this is global to a transaction, not subtransaction-local */
833 if (used)
834 {
835 /*
836 * Forbid setting currentCommandIdUsed in a parallel worker, because
837 * we have no provision for communicating this back to the leader. We
838 * could relax this restriction when currentCommandIdUsed was already
839 * true at the start of the parallel operation.
840 */
841 if (IsParallelWorker())
844 errmsg("cannot modify data in a parallel worker")));
845
847 }
848 return currentCommandId;
849}
850
851/*
852 * SetParallelStartTimestamps
853 *
854 * In a parallel worker, we should inherit the parent transaction's
855 * timestamps rather than setting our own. The parallel worker
856 * infrastructure must call this to provide those values before
857 * calling StartTransaction() or SetCurrentStatementStartTimestamp().
858 */
859void
861{
863 xactStartTimestamp = xact_ts;
864 stmtStartTimestamp = stmt_ts;
865}
866
867/*
868 * GetCurrentTransactionStartTimestamp
869 */
872{
873 return xactStartTimestamp;
874}
875
876/*
877 * GetCurrentStatementStartTimestamp
878 */
881{
882 return stmtStartTimestamp;
883}
884
885/*
886 * GetCurrentTransactionStopTimestamp
887 *
888 * If the transaction stop time hasn't already been set, which can happen if
889 * we decided we don't need to log an XLOG record, set xactStopTimestamp.
890 */
893{
895
896 /* should only be called after commit / abort processing */
897 Assert(s->state == TRANS_DEFAULT ||
898 s->state == TRANS_COMMIT ||
899 s->state == TRANS_ABORT ||
900 s->state == TRANS_PREPARE);
901
902 if (xactStopTimestamp == 0)
904
905 return xactStopTimestamp;
906}
907
908/*
909 * SetCurrentStatementStartTimestamp
910 *
911 * In a parallel worker, this should already have been provided by a call
912 * to SetParallelStartTimestamps().
913 */
914void
916{
917 if (!IsParallelWorker())
919 else
921}
922
923/*
924 * GetCurrentTransactionNestLevel
925 *
926 * Note: this will return zero when not inside any transaction, one when
927 * inside a top-level transaction, etc.
928 */
929int
931{
933
934 return s->nestingLevel;
935}
936
937
938/*
939 * TransactionIdIsCurrentTransactionId
940 */
941bool
943{
945
946 /*
947 * We always say that BootstrapTransactionId is "not my transaction ID"
948 * even when it is (ie, during bootstrap). Along with the fact that
949 * transam.c always treats BootstrapTransactionId as already committed,
950 * this causes the heapam_visibility.c routines to see all tuples as
951 * committed, which is what we need during bootstrap. (Bootstrap mode
952 * only inserts tuples, it never updates or deletes them, so all tuples
953 * can be presumed good immediately.)
954 *
955 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
956 * not my transaction ID, so we can just return "false" immediately for
957 * any non-normal XID.
958 */
959 if (!TransactionIdIsNormal(xid))
960 return false;
961
963 return true;
964
965 /*
966 * In parallel workers, the XIDs we must consider as current are stored in
967 * ParallelCurrentXids rather than the transaction-state stack. Note that
968 * the XIDs in this array are sorted numerically rather than according to
969 * transactionIdPrecedes order.
970 */
971 if (nParallelCurrentXids > 0)
972 {
973 int low,
974 high;
975
976 low = 0;
977 high = nParallelCurrentXids - 1;
978 while (low <= high)
979 {
980 int middle;
982
983 middle = low + (high - low) / 2;
985 if (probe == xid)
986 return true;
987 else if (probe < xid)
988 low = middle + 1;
989 else
990 high = middle - 1;
991 }
992 return false;
993 }
994
995 /*
996 * We will return true for the Xid of the current subtransaction, any of
997 * its subcommitted children, any of its parents, or any of their
998 * previously subcommitted children. However, a transaction being aborted
999 * is no longer "current", even though it may still have an entry on the
1000 * state stack.
1001 */
1002 for (s = CurrentTransactionState; s != NULL; s = s->parent)
1003 {
1004 int low,
1005 high;
1006
1007 if (s->state == TRANS_ABORT)
1008 continue;
1010 continue; /* it can't have any child XIDs either */
1012 return true;
1013 /* As the childXids array is ordered, we can use binary search */
1014 low = 0;
1015 high = s->nChildXids - 1;
1016 while (low <= high)
1017 {
1018 int middle;
1020
1021 middle = low + (high - low) / 2;
1022 probe = s->childXids[middle];
1023 if (TransactionIdEquals(probe, xid))
1024 return true;
1025 else if (TransactionIdPrecedes(probe, xid))
1026 low = middle + 1;
1027 else
1028 high = middle - 1;
1029 }
1030 }
1031
1032 return false;
1033}
1034
1035/*
1036 * TransactionStartedDuringRecovery
1037 *
1038 * Returns true if the current transaction started while recovery was still
1039 * in progress. Recovery might have ended since so RecoveryInProgress() might
1040 * return false already.
1041 */
1042bool
1044{
1046}
1047
1048/*
1049 * GetTopReadOnlyTransactionNestLevel
1050 *
1051 * Note: this will return zero when not inside any transaction or when neither
1052 * a top-level transaction nor subtransactions are read-only, one when the
1053 * top-level transaction is read-only, two when one level of subtransaction is
1054 * read-only, etc.
1055 *
1056 * Note: subtransactions of the topmost read-only transaction are also
1057 * read-only, because they inherit read-only mode from the transaction, and
1058 * thus can't change to read-write mode (see check_transaction_read_only).
1059 */
1060int
1062{
1064
1065 if (!XactReadOnly)
1066 return 0;
1067 while (s->nestingLevel > 1)
1068 {
1069 if (!s->prevXactReadOnly)
1070 return s->nestingLevel;
1071 s = s->parent;
1072 }
1073 return s->nestingLevel;
1074}
1075
1076/*
1077 * EnterParallelMode
1078 */
1079void
1081{
1083
1084 Assert(s->parallelModeLevel >= 0);
1085
1086 ++s->parallelModeLevel;
1087}
1088
1089/*
1090 * ExitParallelMode
1091 */
1092void
1093ExitParallelMode(void)
1094{
1096
1097 Assert(s->parallelModeLevel > 0);
1100
1101 --s->parallelModeLevel;
1102}
1103
1104/*
1105 * IsInParallelMode
1106 *
1107 * Are we in a parallel operation, as either the leader or a worker? Check
1108 * this to prohibit operations that change backend-local state expected to
1109 * match across all workers. Mere caches usually don't require such a
1110 * restriction. State modified in a strict push/pop fashion, such as the
1111 * active snapshot stack, is often fine.
1112 *
1113 * We say we are in parallel mode if we are in a subxact of a transaction
1114 * that's initiated a parallel operation; for most purposes that context
1115 * has all the same restrictions.
1116 */
1117bool
1118IsInParallelMode(void)
1119{
1121
1122 return s->parallelModeLevel != 0 || s->parallelChildXact;
1123}
1124
1125/*
1126 * CommandCounterIncrement
1127 */
1128void
1130{
1131 /*
1132 * If the current value of the command counter hasn't been "used" to mark
1133 * tuples, we need not increment it, since there's no need to distinguish
1134 * a read-only command from others. This helps postpone command counter
1135 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
1136 */
1138 {
1139 /*
1140 * Workers synchronize transaction state at the beginning of each
1141 * parallel operation, so we can't account for new commands after that
1142 * point.
1143 */
1145 ereport(ERROR,
1147 errmsg("cannot start commands during a parallel operation")));
1148
1149 currentCommandId += 1;
1151 {
1152 currentCommandId -= 1;
1153 ereport(ERROR,
1155 errmsg("cannot have more than 2^32-2 commands in a transaction")));
1156 }
1157 currentCommandIdUsed = false;
1158
1159 /* Propagate new command ID into static snapshots */
1161
1162 /*
1163 * Make any catalog changes done by the just-completed command visible
1164 * in the local syscache. We obviously don't need to do this after a
1165 * read-only command. (But see hacks in inval.c to make real sure we
1166 * don't think a command that queued inval messages was read-only.)
1167 */
1169 }
1170}
1171
1172/*
1173 * ForceSyncCommit
1174 *
1175 * Interface routine to allow commands to force a synchronous commit of the
1176 * current top-level transaction. Currently, two-phase commit does not
1177 * persist and restore this variable. So long as all callers use
1178 * PreventInTransactionBlock(), that omission has no consequences.
1179 */
1180void
1181ForceSyncCommit(void)
1182{
1183 forceSyncCommit = true;
1184}
1185
1186
1187/* ----------------------------------------------------------------
1188 * StartTransaction stuff
1189 * ----------------------------------------------------------------
1190 */
1191
1192/*
1193 * AtStart_Cache
1194 */
1195static void
1196AtStart_Cache(void)
1197{
1199}
1200
1201/*
1202 * AtStart_Memory
1203 */
1204static void
1205AtStart_Memory(void)
1206{
1208
1209 /*
1210 * Remember the memory context that was active prior to transaction start.
1211 */
1213
1214 /*
1215 * If this is the first time through, create a private context for
1216 * AbortTransaction to work in. By reserving some space now, we can
1217 * insulate AbortTransaction from out-of-memory scenarios. Like
1218 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1219 * size, so that space will be reserved immediately.
1220 */
1224 "TransactionAbortContext",
1225 32 * 1024,
1226 32 * 1024,
1227 32 * 1024);
1228
1229 /*
1230 * Likewise, if this is the first time through, create a top-level context
1231 * for transaction-local data. This context will be reset at transaction
1232 * end, and then re-used in later transactions.
1233 */
1237 "TopTransactionContext",
1239
1240 /*
1241 * In a top-level transaction, CurTransactionContext is the same as
1242 * TopTransactionContext.
1243 */
1246
1247 /* Make the CurTransactionContext active. */
1249}
1250
1251/*
1252 * AtStart_ResourceOwner
1253 */
1254static void
1256{
1258
1259 /*
1260 * We shouldn't have a transaction resource owner already.
1261 */
1263
1264 /*
1265 * Create a toplevel resource owner for the transaction.
1266 */
1267 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1268
1272}
1273
1274/* ----------------------------------------------------------------
1275 * StartSubTransaction stuff
1276 * ----------------------------------------------------------------
1277 */
1278
1279/*
1280 * AtSubStart_Memory
1281 */
1282static void
1284{
1286
1288
1289 /*
1290 * Remember the context that was active prior to subtransaction start.
1291 */
1293
1294 /*
1295 * Create a CurTransactionContext, which will be used to hold data that
1296 * survives subtransaction commit but disappears on subtransaction abort.
1297 * We make it a child of the immediate parent's CurTransactionContext.
1298 */
1300 "CurTransactionContext",
1303
1304 /* Make the CurTransactionContext active. */
1306}
1307
1308/*
1309 * AtSubStart_ResourceOwner
1310 */
1311static void
1313{
1315
1316 Assert(s->parent != NULL);
1317
1318 /*
1319 * Create a resource owner for the subtransaction. We make it a child of
1320 * the immediate parent's resource owner.
1321 */
1324 "SubTransaction");
1325
1328}
1329
1330/* ----------------------------------------------------------------
1331 * CommitTransaction stuff
1332 * ----------------------------------------------------------------
1333 */
1334
1335/*
1336 * RecordTransactionCommit
1337 *
1338 * Returns latest XID among xact and its children, or InvalidTransactionId
1339 * if the xact has no XID. (We compute that here just because it's easier.)
1340 *
1341 * If you change this function, see RecordTransactionCommitPrepared also.
1342 */
1343static TransactionId
1345{
1349 int nrels;
1350 RelFileLocator *rels;
1351 int nchildren;
1352 TransactionId *children;
1353 int ndroppedstats = 0;
1355 int nmsgs = 0;
1357 bool RelcacheInitFileInval = false;
1358 bool wrote_xlog;
1359
1360 /*
1361 * Log pending invalidations for logical decoding of in-progress
1362 * transactions. Normally for DDLs, we log this at each command end,
1363 * however, for certain cases where we directly update the system table
1364 * without a transaction block, the invalidations are not logged till this
1365 * time.
1366 */
1369
1370 /* Get data needed for commit record */
1371 nrels = smgrGetPendingDeletes(true, &rels);
1376 &RelcacheInitFileInval);
1377 wrote_xlog = (XactLastRecEnd != 0);
1378
1379 /*
1380 * If we haven't been assigned an XID yet, we neither can, nor do we want
1381 * to write a COMMIT record.
1382 */
1383 if (!markXidCommitted)
1384 {
1385 /*
1386 * We expect that every RelationDropStorage is followed by a catalog
1387 * update, and hence XID assignment, so we shouldn't get here with any
1388 * pending deletes. Same is true for dropping stats.
1389 *
1390 * Use a real test not just an Assert to check this, since it's a bit
1391 * fragile.
1392 */
1393 if (nrels != 0 || ndroppedstats != 0)
1394 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
1395
1396 /* Can't have child XIDs either; AssignTransactionId enforces this */
1397 Assert(nchildren == 0);
1398
1399 /*
1400 * Transactions without an assigned xid can contain invalidation
1401 * messages. While inplace updates do this, this is not known to be
1402 * necessary; see comment at inplace CacheInvalidateHeapTuple().
1403 * Extensions might still rely on this capability, and standbys may
1404 * need to process those invals. We can't emit a commit record
1405 * without an xid, and we don't want to force assigning an xid,
1406 * because that'd be problematic for e.g. vacuum. Hence we emit a
1407 * bespoke record for the invalidations. We don't want to use that in
1408 * case a commit record is emitted, so they happen synchronously with
1409 * commits (besides not wanting to emit more WAL records).
1410 *
1411 * XXX Every known use of this capability is a defect. Since an XID
1412 * isn't controlling visibility of the change that prompted invals,
1413 * other sessions need the inval even if this transactions aborts.
1414 *
1415 * ON COMMIT DELETE ROWS does a nontransactional index_build(), which
1416 * queues a relcache inval, including in transactions without an xid
1417 * that had read the (empty) table. Standbys don't need any ON COMMIT
1418 * DELETE ROWS invals, but we've not done the work to withhold them.
1419 */
1420 if (nmsgs != 0)
1421 {
1423 RelcacheInitFileInval);
1424 wrote_xlog = true; /* not strictly necessary */
1425 }
1426
1427 /*
1428 * If we didn't create XLOG entries, we're done here; otherwise we
1429 * should trigger flushing those entries the same as a commit record
1430 * would. This will primarily happen for HOT pruning and the like; we
1431 * want these to be flushed to disk in due time.
1432 */
1433 if (!wrote_xlog)
1434 goto cleanup;
1435 }
1436 else
1437 {
1438 bool replorigin;
1439
1440 /*
1441 * Are we using the replication origins feature? Or, in other words,
1442 * are we replaying remote actions?
1443 */
1446
1447 /*
1448 * Mark ourselves as within our "commit critical section". This
1449 * forces any concurrent checkpoint to wait until we've updated
1450 * pg_xact. Without this, it is possible for the checkpoint to set
1451 * REDO after the XLOG record but fail to flush the pg_xact update to
1452 * disk, leading to loss of the transaction commit if the system
1453 * crashes a little later.
1454 *
1455 * Note: we could, but don't bother to, set this flag in
1456 * RecordTransactionAbort. That's because loss of a transaction abort
1457 * is noncritical; the presumption would be that it aborted, anyway.
1458 *
1459 * It's safe to change the delayChkptFlags flag of our own backend
1460 * without holding the ProcArrayLock, since we're the only one
1461 * modifying it. This makes checkpoint's determination of which xacts
1462 * are delaying the checkpoint a bit fuzzy, but it doesn't matter.
1463 *
1464 * Note, it is important to get the commit timestamp after marking the
1465 * transaction in the commit critical section. See
1466 * RecordTransactionCommitPrepared.
1467 */
1471
1473
1474 /*
1475 * Ensures the DELAY_CHKPT_IN_COMMIT flag write is globally visible
1476 * before commit time is written.
1477 */
1479
1480 /*
1481 * Insert the commit XLOG record.
1482 */
1484 nchildren, children, nrels, rels,
1486 nmsgs, invalMessages,
1487 RelcacheInitFileInval,
1489 InvalidTransactionId, NULL /* plain commit */ );
1490
1491 if (replorigin)
1492 /* Move LSNs forward for this replication origin */
1495
1496 /*
1497 * Record commit timestamp. The value comes from plain commit
1498 * timestamp if there's no replication origin; otherwise, the
1499 * timestamp was already set in replorigin_xact_state.origin_timestamp
1500 * by replication.
1501 *
1502 * We don't need to WAL-log anything here, as the commit record
1503 * written above already contains the data.
1504 */
1505
1508
1512 }
1513
1514 /*
1515 * Check if we want to commit asynchronously. We can allow the XLOG flush
1516 * to happen asynchronously if synchronous_commit=off, or if the current
1517 * transaction has not performed any WAL-logged operation or didn't assign
1518 * an xid. The transaction can end up not writing any WAL, even if it has
1519 * an xid, if it only wrote to temporary and/or unlogged tables. It can
1520 * end up having written WAL without an xid if it did HOT pruning. In
1521 * case of a crash, the loss of such a transaction will be irrelevant;
1522 * temp tables will be lost anyway, unlogged tables will be truncated and
1523 * HOT pruning will be done again later. (Given the foregoing, you might
1524 * think that it would be unnecessary to emit the XLOG record at all in
1525 * this case, but we don't currently try to do that. It would certainly
1526 * cause problems at least in Hot Standby mode, where the
1527 * KnownAssignedXids machinery requires tracking every XID assignment. It
1528 * might be OK to skip it only when wal_level < replica, but for now we
1529 * don't.)
1530 *
1531 * However, if we're doing cleanup of any non-temp rels or committing any
1532 * command that wanted to force sync commit, then we must flush XLOG
1533 * immediately. (We must not allow asynchronous commit if there are any
1534 * non-temp tables to be deleted, because we might delete the files before
1535 * the COMMIT record is flushed to disk. We do allow asynchronous commit
1536 * if all to-be-deleted tables are temporary though, since they are lost
1537 * anyway if we crash.)
1538 */
1539 if ((wrote_xlog && markXidCommitted &&
1541 forceSyncCommit || nrels > 0)
1542 {
1544
1545 /*
1546 * Now we may update the CLOG, if we wrote a COMMIT record above
1547 */
1548 if (markXidCommitted)
1549 TransactionIdCommitTree(xid, nchildren, children);
1550 }
1551 else
1552 {
1553 /*
1554 * Asynchronous commit case:
1555 *
1556 * This enables possible committed transaction loss in the case of a
1557 * postmaster crash because WAL buffers are left unwritten. Ideally we
1558 * could issue the WAL write without the fsync, but some
1559 * wal_sync_methods do not allow separate write/fsync.
1560 *
1561 * Report the latest async commit LSN, so that the WAL writer knows to
1562 * flush this commit.
1563 */
1565
1566 /*
1567 * We must not immediately update the CLOG, since we didn't flush the
1568 * XLOG. Instead, we store the LSN up to which the XLOG must be
1569 * flushed before the CLOG may be updated.
1570 */
1571 if (markXidCommitted)
1573 }
1574
1575 /*
1576 * If we entered a commit critical section, leave it now, and let
1577 * checkpoints proceed.
1578 */
1579 if (markXidCommitted)
1580 {
1583 }
1584
1585 /* Compute latestXid while we have the child XIDs handy */
1586 latestXid = TransactionIdLatest(xid, nchildren, children);
1587
1588 /*
1589 * Wait for synchronous replication, if required. Similar to the decision
1590 * above about using committing asynchronously we only want to wait if
1591 * this backend assigned an xid and wrote WAL. No need to wait if an xid
1592 * was assigned due to temporary/unlogged tables or due to HOT pruning.
1593 *
1594 * Note that at this stage we have marked clog, but still show as running
1595 * in the procarray and continue to hold locks.
1596 */
1599
1600 /* remember end of last commit record */
1602
1603 /* Reset XactLastRecEnd until the next transaction writes something */
1604 XactLastRecEnd = 0;
1605cleanup:
1606 /* Clean up local data */
1607 if (rels)
1608 pfree(rels);
1609 if (ndroppedstats)
1611
1612 return latestXid;
1613}
1614
1615
1616/*
1617 * AtCCI_LocalCache
1618 */
1619static void
1620AtCCI_LocalCache(void)
1621{
1622 /*
1623 * Make any pending relation map changes visible. We must do this before
1624 * processing local sinval messages, so that the map changes will get
1625 * reflected into the relcache when relcache invals are processed.
1626 */
1628
1629 /*
1630 * Make catalog changes visible to me for the next command.
1631 */
1633}
1634
1635/*
1636 * AtCommit_Memory
1637 */
1638static void
1639AtCommit_Memory(void)
1640{
1642
1643 /*
1644 * Return to the memory context that was current before we started the
1645 * transaction. (In principle, this could not be any of the contexts we
1646 * are about to delete. If it somehow is, assertions in mcxt.c will
1647 * complain.)
1648 */
1650
1651 /*
1652 * Release all transaction-local memory. TopTransactionContext survives
1653 * but becomes empty; any sub-contexts go away.
1654 */
1657
1658 /*
1659 * Clear these pointers as a pro-forma matter. (Notionally, while
1660 * TopTransactionContext still exists, it's currently not associated with
1661 * this TransactionState struct.)
1662 */
1665}
1666
1667/* ----------------------------------------------------------------
1668 * CommitSubTransaction stuff
1669 * ----------------------------------------------------------------
1670 */
1671
1672/*
1673 * AtSubCommit_Memory
1674 */
1675static void
1677{
1679
1680 Assert(s->parent != NULL);
1681
1682 /* Return to parent transaction level's memory context. */
1685
1686 /*
1687 * Ordinarily we cannot throw away the child's CurTransactionContext,
1688 * since the data it contains will be needed at upper commit. However, if
1689 * there isn't actually anything in it, we can throw it away. This avoids
1690 * a small memory leak in the common case of "trivial" subxacts.
1691 */
1693 {
1696 }
1697}
1698
1699/*
1700 * AtSubCommit_childXids
1701 *
1702 * Pass my own XID and my child XIDs up to my parent as committed children.
1703 */
1704static void
1706{
1708 int new_nChildXids;
1709
1710 Assert(s->parent != NULL);
1711
1712 /*
1713 * The parent childXids array will need to hold my XID and all my
1714 * childXids, in addition to the XIDs already there.
1715 */
1717
1718 /* Allocate or enlarge the parent array if necessary */
1720 {
1721 int new_maxChildXids;
1723
1724 /*
1725 * Make it 2x what's needed right now, to avoid having to enlarge it
1726 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1727 * is what ensures that we don't need to worry about integer overflow
1728 * here or in the calculation of new_nChildXids.)
1729 */
1731 (int) (MaxAllocSize / sizeof(TransactionId)));
1732
1734 ereport(ERROR,
1736 errmsg("maximum number of committed subtransactions (%d) exceeded",
1737 (int) (MaxAllocSize / sizeof(TransactionId)))));
1738
1739 /*
1740 * We keep the child-XID arrays in TopTransactionContext; this avoids
1741 * setting up child-transaction contexts for what might be just a few
1742 * bytes of grandchild XIDs.
1743 */
1744 if (s->parent->childXids == NULL)
1748 else
1751
1754 }
1755
1756 /*
1757 * Copy all my XIDs to parent's array.
1758 *
1759 * Note: We rely on the fact that the XID of a child always follows that
1760 * of its parent. By copying the XID of this subtransaction before the
1761 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1762 * all XIDs already in the array belong to subtransactions started and
1763 * subcommitted before us, so their XIDs must precede ours.
1764 */
1766
1767 if (s->nChildXids > 0)
1768 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1769 s->childXids,
1770 s->nChildXids * sizeof(TransactionId));
1771
1773
1774 /* Release child's array to avoid leakage */
1775 if (s->childXids != NULL)
1776 pfree(s->childXids);
1777 /* We must reset these to avoid double-free if fail later in commit */
1778 s->childXids = NULL;
1779 s->nChildXids = 0;
1780 s->maxChildXids = 0;
1781}
1782
1783/* ----------------------------------------------------------------
1784 * AbortTransaction stuff
1785 * ----------------------------------------------------------------
1786 */
1787
1788/*
1789 * RecordTransactionAbort
1790 *
1791 * Returns latest XID among xact and its children, or InvalidTransactionId
1792 * if the xact has no XID. (We compute that here just because it's easier.)
1793 */
1794static TransactionId
1796{
1799 int nrels;
1800 RelFileLocator *rels;
1801 int ndroppedstats = 0;
1803 int nchildren;
1804 TransactionId *children;
1805 TimestampTz xact_time;
1806 bool replorigin;
1807
1808 /*
1809 * If we haven't been assigned an XID, nobody will care whether we aborted
1810 * or not. Hence, we're done in that case. It does not matter if we have
1811 * rels to delete (note that this routine is not responsible for actually
1812 * deleting 'em). We cannot have any child XIDs, either.
1813 */
1814 if (!TransactionIdIsValid(xid))
1815 {
1816 /* Reset XactLastRecEnd until the next transaction writes something */
1817 if (!isSubXact)
1818 XactLastRecEnd = 0;
1819 return InvalidTransactionId;
1820 }
1821
1822 /*
1823 * We have a valid XID, so we should write an ABORT record for it.
1824 *
1825 * We do not flush XLOG to disk here, since the default assumption after a
1826 * crash would be that we aborted, anyway. For the same reason, we don't
1827 * need to worry about interlocking against checkpoint start.
1828 */
1829
1830 /*
1831 * Check that we haven't aborted halfway through RecordTransactionCommit.
1832 */
1833 if (TransactionIdDidCommit(xid))
1834 elog(PANIC, "cannot abort transaction %u, it was already committed",
1835 xid);
1836
1837 /*
1838 * Are we using the replication origins feature? Or, in other words, are
1839 * we replaying remote actions?
1840 */
1843
1844 /* Fetch the data we need for the abort record */
1845 nrels = smgrGetPendingDeletes(false, &rels);
1848
1849 /* XXX do we really need a critical section here? */
1851
1852 /* Write the ABORT record */
1853 if (isSubXact)
1854 xact_time = GetCurrentTimestamp();
1855 else
1856 {
1858 }
1859
1860 XactLogAbortRecord(xact_time,
1861 nchildren, children,
1862 nrels, rels,
1865 NULL);
1866
1867 if (replorigin)
1868 /* Move LSNs forward for this replication origin */
1871
1872 /*
1873 * Report the latest async abort LSN, so that the WAL writer knows to
1874 * flush this abort. There's nothing to be gained by delaying this, since
1875 * WALWriter may as well do this when it can. This is important with
1876 * streaming replication because if we don't flush WAL regularly we will
1877 * find that large aborts leave us with a long backlog for when commits
1878 * occur after the abort, increasing our window of data loss should
1879 * problems occur at that point.
1880 */
1881 if (!isSubXact)
1883
1884 /*
1885 * Mark the transaction aborted in clog. This is not absolutely necessary
1886 * but we may as well do it while we are here; also, in the subxact case
1887 * it is helpful because XactLockTableWait makes use of it to avoid
1888 * waiting for already-aborted subtransactions. It is OK to do it without
1889 * having flushed the ABORT record to disk, because in event of a crash
1890 * we'd be assumed to have aborted anyway.
1891 */
1892 TransactionIdAbortTree(xid, nchildren, children);
1893
1895
1896 /* Compute latestXid while we have the child XIDs handy */
1897 latestXid = TransactionIdLatest(xid, nchildren, children);
1898
1899 /*
1900 * If we're aborting a subtransaction, we can immediately remove failed
1901 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1902 * subxacts, because we already have the child XID array at hand. For
1903 * main xacts, the equivalent happens just after this function returns.
1904 */
1905 if (isSubXact)
1907
1908 /* Reset XactLastRecEnd until the next transaction writes something */
1909 if (!isSubXact)
1910 XactLastRecEnd = 0;
1911
1912 /* And clean up local data */
1913 if (rels)
1914 pfree(rels);
1915 if (ndroppedstats)
1917
1918 return latestXid;
1919}
1920
1921/*
1922 * AtAbort_Memory
1923 */
1924static void
1925AtAbort_Memory(void)
1926{
1927 /*
1928 * Switch into TransactionAbortContext, which should have some free space
1929 * even if nothing else does. We'll work in this context until we've
1930 * finished cleaning up.
1931 *
1932 * It is barely possible to get here when we've not been able to create
1933 * TransactionAbortContext yet; if so use TopMemoryContext.
1934 */
1937 else
1939}
1940
1941/*
1942 * AtSubAbort_Memory
1943 */
1944static void
1946{
1948
1950}
1951
1952
1953/*
1954 * AtAbort_ResourceOwner
1955 */
1956static void
1958{
1959 /*
1960 * Make sure we have a valid ResourceOwner, if possible (else it will be
1961 * NULL, which is OK)
1962 */
1964}
1965
1966/*
1967 * AtSubAbort_ResourceOwner
1968 */
1969static void
1971{
1973
1974 /* Make sure we have a valid ResourceOwner */
1976}
1977
1978
1979/*
1980 * AtSubAbort_childXids
1981 */
1982static void
1984{
1986
1987 /*
1988 * We keep the child-XID arrays in TopTransactionContext (see
1989 * AtSubCommit_childXids). This means we'd better free the array
1990 * explicitly at abort to avoid leakage.
1991 */
1992 if (s->childXids != NULL)
1993 pfree(s->childXids);
1994 s->childXids = NULL;
1995 s->nChildXids = 0;
1996 s->maxChildXids = 0;
1997
1998 /*
1999 * We could prune the unreportedXids array here. But we don't bother. That
2000 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
2001 * would likely introduce more CPU time into the more common paths, so we
2002 * choose not to do that.
2003 */
2004}
2005
2006/* ----------------------------------------------------------------
2007 * CleanupTransaction stuff
2008 * ----------------------------------------------------------------
2009 */
2010
2011/*
2012 * AtCleanup_Memory
2013 */
2014static void
2015AtCleanup_Memory(void)
2016{
2018
2019 /* Should be at top level */
2020 Assert(s->parent == NULL);
2021
2022 /*
2023 * Return to the memory context that was current before we started the
2024 * transaction. (In principle, this could not be any of the contexts we
2025 * are about to delete. If it somehow is, assertions in mcxt.c will
2026 * complain.)
2027 */
2029
2030 /*
2031 * Clear the special abort context for next time.
2032 */
2035
2036 /*
2037 * Release all transaction-local memory, the same as in AtCommit_Memory,
2038 * except we must cope with the possibility that we didn't get as far as
2039 * creating TopTransactionContext.
2040 */
2043
2044 /*
2045 * Clear these pointers as a pro-forma matter. (Notionally, while
2046 * TopTransactionContext still exists, it's currently not associated with
2047 * this TransactionState struct.)
2048 */
2051}
2052
2053
2054/* ----------------------------------------------------------------
2055 * CleanupSubTransaction stuff
2056 * ----------------------------------------------------------------
2057 */
2058
2059/*
2060 * AtSubCleanup_Memory
2061 */
2062static void
2064{
2066
2067 Assert(s->parent != NULL);
2068
2069 /*
2070 * Return to the memory context that was current before we started the
2071 * subtransaction. (In principle, this could not be any of the contexts
2072 * we are about to delete. If it somehow is, assertions in mcxt.c will
2073 * complain.)
2074 */
2076
2077 /* Update CurTransactionContext (might not be same as priorContext) */
2079
2080 /*
2081 * Clear the special abort context for next time.
2082 */
2085
2086 /*
2087 * Delete the subxact local memory contexts. Its CurTransactionContext can
2088 * go too (note this also kills CurTransactionContexts from any children
2089 * of the subxact).
2090 */
2091 if (s->curTransactionContext)
2094}
2095
2096/* ----------------------------------------------------------------
2097 * interface routines
2098 * ----------------------------------------------------------------
2099 */
2100
2101/*
2102 * StartTransaction
2103 */
2104static void
2105StartTransaction(void)
2106{
2109
2110 /*
2111 * Let's just make sure the state stack is empty
2112 */
2115
2117
2118 /* check the current transaction state */
2119 Assert(s->state == TRANS_DEFAULT);
2120
2121 /*
2122 * Set the current transaction state information appropriately during
2123 * start processing. Note that once the transaction status is switched
2124 * this process cannot fail until the user ID and the security context
2125 * flags are fetched below.
2126 */
2127 s->state = TRANS_START;
2128 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
2129
2130 /* Determine if statements are logged in this transaction */
2132 (log_xact_sample_rate == 1 ||
2134
2135 /*
2136 * initialize current transaction state fields
2137 *
2138 * note: prevXactReadOnly is not used at the outermost level
2139 */
2140 s->nestingLevel = 1;
2141 s->gucNestLevel = 1;
2142 s->childXids = NULL;
2143 s->nChildXids = 0;
2144 s->maxChildXids = 0;
2145
2146 /*
2147 * Once the current user ID and the security context flags are fetched,
2148 * both will be properly reset even if transaction startup fails.
2149 */
2151
2152 /* SecurityRestrictionContext should never be set outside a transaction */
2153 Assert(s->prevSecContext == 0);
2154
2155 /*
2156 * Make sure we've reset xact state variables
2157 *
2158 * If recovery is still in progress, mark this transaction as read-only.
2159 * We have lower level defences in XLogInsert and elsewhere to stop us
2160 * from modifying data during recovery, but this gives the normal
2161 * indication to the user that the transaction is read-only.
2162 */
2163 if (RecoveryInProgress())
2164 {
2165 s->startedInRecovery = true;
2166 XactReadOnly = true;
2167 }
2168 else
2169 {
2170 s->startedInRecovery = false;
2172 }
2175 forceSyncCommit = false;
2176 MyXactFlags = 0;
2177
2178 /*
2179 * reinitialize within-transaction counters
2180 */
2184 currentCommandIdUsed = false;
2185
2186 /*
2187 * initialize reported xid accounting
2188 */
2189 nUnreportedXids = 0;
2190 s->didLogXid = false;
2191
2192 /*
2193 * must initialize resource-management stuff first
2194 */
2197
2198 /*
2199 * Assign a new LocalTransactionId, and combine it with the proc number to
2200 * form a virtual transaction id.
2201 */
2202 vxid.procNumber = MyProcNumber;
2204
2205 /*
2206 * Lock the virtual transaction id before we announce it in the proc array
2207 */
2209
2210 /*
2211 * Advertise it in the proc array. We assume assignment of
2212 * localTransactionId is atomic, and the proc number should be set
2213 * already.
2214 */
2217
2219
2220 /*
2221 * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2222 * be the same as the first command's statement_timestamp(), so don't do a
2223 * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2224 * for transactions started inside procedures (i.e., nonatomic SPI
2225 * contexts), we do need to advance the timestamp. Also, in a parallel
2226 * worker, the timestamp should already have been provided by a call to
2227 * SetParallelStartTimestamps().
2228 */
2229 if (!IsParallelWorker())
2230 {
2233 else
2235 }
2236 else
2239 /* Mark xactStopTimestamp as unset. */
2241
2242 /*
2243 * initialize other subsystems for new transaction
2244 */
2245 AtStart_GUC();
2246 AtStart_Cache();
2248
2249 /*
2250 * done with start processing, set current transaction state to "in
2251 * progress"
2252 */
2254
2255 /* Schedule transaction timeout */
2256 if (TransactionTimeout > 0)
2258
2259 ShowTransactionState("StartTransaction");
2260}
2261
2262
2263/*
2264 * CommitTransaction
2265 *
2266 * NB: if you change this routine, better look at PrepareTransaction too!
2267 */
2268static void
2270{
2273 bool is_parallel_worker;
2274
2276
2277 /* Enforce parallel mode restrictions during parallel worker commit. */
2280
2281 ShowTransactionState("CommitTransaction");
2282
2283 /*
2284 * check the current transaction state
2285 */
2286 if (s->state != TRANS_INPROGRESS)
2287 elog(WARNING, "CommitTransaction while in %s state",
2289 Assert(s->parent == NULL);
2290
2291 /*
2292 * Do pre-commit processing that involves calling user-defined code, such
2293 * as triggers. SECURITY_RESTRICTED_OPERATION contexts must not queue an
2294 * action that would run here, because that would bypass the sandbox.
2295 * Since closing cursors could queue trigger actions, triggers could open
2296 * cursors, etc, we have to keep looping until there's nothing left to do.
2297 */
2298 for (;;)
2299 {
2300 /*
2301 * Fire all currently pending deferred triggers.
2302 */
2304
2305 /*
2306 * Close open portals (converting holdable ones into static portals).
2307 * If there weren't any, we are done ... otherwise loop back to check
2308 * if they queued deferred triggers. Lather, rinse, repeat.
2309 */
2310 if (!PreCommit_Portals(false))
2311 break;
2312 }
2313
2314 /*
2315 * The remaining actions cannot call any user-defined code, so it's safe
2316 * to start shutting down within-transaction services. But note that most
2317 * of this stuff could still throw an error, which would switch us into
2318 * the transaction-abort path.
2319 */
2320
2323
2324 /*
2325 * If this xact has started any unfinished parallel operation, clean up
2326 * its workers, warning about leaked resources. (But we don't actually
2327 * reset parallelModeLevel till entering TRANS_COMMIT, a bit below. This
2328 * keeps parallel mode restrictions active as long as possible in a
2329 * parallel worker.)
2330 */
2331 AtEOXact_Parallel(true);
2333 {
2334 if (s->parallelModeLevel != 1)
2335 elog(WARNING, "parallelModeLevel is %d not 1 at end of parallel worker transaction",
2337 }
2338 else
2339 {
2340 if (s->parallelModeLevel != 0)
2341 elog(WARNING, "parallelModeLevel is %d not 0 at end of transaction",
2343 }
2344
2345 /* Shut down the deferred-trigger manager */
2346 AfterTriggerEndXact(true);
2347
2348 /*
2349 * Let ON COMMIT management do its thing (must happen after closing
2350 * cursors, to avoid dangling-reference problems)
2351 */
2353
2354 /*
2355 * Synchronize files that are created and not WAL-logged during this
2356 * transaction. This must happen before AtEOXact_RelationMap(), so that we
2357 * don't see committed-but-broken files after a crash.
2358 */
2360
2361 /* close large objects before lower-level cleanup */
2363
2364 /*
2365 * Insert notifications sent by NOTIFY commands into the queue. This
2366 * should be late in the pre-commit sequence to minimize time spent
2367 * holding the notify-insertion lock. However, this could result in
2368 * creating a snapshot, so we must do it before serializable cleanup.
2369 */
2371
2372 /*
2373 * Mark serializable transaction as complete for predicate locking
2374 * purposes. This should be done as late as we can put it and still allow
2375 * errors to be raised for failure patterns found at commit. This is not
2376 * appropriate in a parallel worker however, because we aren't committing
2377 * the leader's transaction and its serializable state will live on.
2378 */
2379 if (!is_parallel_worker)
2381
2382 /* Prevent cancel/die interrupt while cleaning up */
2384
2385 /* Commit updates to the relation map --- do this as late as possible */
2387
2388 /*
2389 * set the current transaction state information appropriately during
2390 * commit processing
2391 */
2392 s->state = TRANS_COMMIT;
2393 s->parallelModeLevel = 0;
2394 s->parallelChildXact = false; /* should be false already */
2395
2396 /* Disable transaction timeout */
2397 if (TransactionTimeout > 0)
2399
2400 if (!is_parallel_worker)
2401 {
2402 /*
2403 * We need to mark our XIDs as committed in pg_xact. This is where we
2404 * durably commit.
2405 */
2407 }
2408 else
2409 {
2410 /*
2411 * We must not mark our XID committed; the parallel leader is
2412 * responsible for that.
2413 */
2415
2416 /*
2417 * Make sure the leader will know about any WAL we wrote before it
2418 * commits.
2419 */
2421 }
2422
2424
2425 /*
2426 * Let others know about no transaction in progress by me. Note that this
2427 * must be done _before_ releasing locks we hold and _after_
2428 * RecordTransactionCommit.
2429 */
2431
2432 /*
2433 * This is all post-commit cleanup. Note that if an error is raised here,
2434 * it's too late to abort the transaction. This should be just
2435 * noncritical resource releasing.
2436 *
2437 * The ordering of operations is not entirely random. The idea is:
2438 * release resources visible to other backends (eg, files, buffer pins);
2439 * then release locks; then release backend-local resources. We want to
2440 * release locks at the point where any backend waiting for us will see
2441 * our transaction as being fully cleaned up.
2442 *
2443 * Resources that can be associated with individual queries are handled by
2444 * the ResourceOwner mechanism. The other calls here are for backend-wide
2445 * state.
2446 */
2447
2450
2454 true, true);
2455
2456 AtEOXact_Aio(true);
2457
2458 /* Check we've released all buffer pins */
2459 AtEOXact_Buffers(true);
2460
2461 /* Clean up the relation cache */
2463
2464 /* Clean up the type cache */
2466
2467 /*
2468 * Make catalog changes visible to all backends. This has to happen after
2469 * relcache references are dropped (see comments for
2470 * AtEOXact_RelationCache), but before locks are released (if anyone is
2471 * waiting for lock on a relation we've modified, we want them to know
2472 * about the catalog change before they start using the relation).
2473 */
2474 AtEOXact_Inval(true);
2475
2477
2480 true, true);
2483 true, true);
2484
2485 /*
2486 * Likewise, dropping of files deleted during the transaction is best done
2487 * after releasing relcache and buffer pins. (This is not strictly
2488 * necessary during commit, since such pins should have been released
2489 * already, but this ordering is definitely critical during abort.) Since
2490 * this may take many seconds, also delay until after releasing locks.
2491 * Other backends will observe the attendant catalog changes and not
2492 * attempt to access affected files.
2493 */
2495
2496 /*
2497 * Send out notification signals to other backends (and do other
2498 * post-commit NOTIFY cleanup). This must not happen until after our
2499 * transaction is fully done from the viewpoint of other backends.
2500 */
2502
2503 /*
2504 * Everything after this should be purely internal-to-this-backend
2505 * cleanup.
2506 */
2507 AtEOXact_GUC(true, 1);
2508 AtEOXact_SPI(true);
2509 AtEOXact_Enum();
2512 AtEOXact_SMgr();
2513 AtEOXact_Files(true);
2515 AtEOXact_HashTables(true);
2516 AtEOXact_RI(true);
2518 AtEOXact_Snapshot(true, false);
2523
2528
2530
2533 s->nestingLevel = 0;
2534 s->gucNestLevel = 0;
2535 s->childXids = NULL;
2536 s->nChildXids = 0;
2537 s->maxChildXids = 0;
2538
2541
2542 /*
2543 * done with commit processing, set current transaction state back to
2544 * default
2545 */
2546 s->state = TRANS_DEFAULT;
2547
2549}
2550
2551
2552/*
2553 * PrepareTransaction
2554 *
2555 * NB: if you change this routine, better look at CommitTransaction too!
2556 */
2557static void
2559{
2563 TimestampTz prepared_at;
2564
2566
2567 ShowTransactionState("PrepareTransaction");
2568
2569 /*
2570 * check the current transaction state
2571 */
2572 if (s->state != TRANS_INPROGRESS)
2573 elog(WARNING, "PrepareTransaction while in %s state",
2575 Assert(s->parent == NULL);
2576
2577 /*
2578 * Do pre-commit processing that involves calling user-defined code, such
2579 * as triggers. Since closing cursors could queue trigger actions,
2580 * triggers could open cursors, etc, we have to keep looping until there's
2581 * nothing left to do.
2582 */
2583 for (;;)
2584 {
2585 /*
2586 * Fire all currently pending deferred triggers.
2587 */
2589
2590 /*
2591 * Close open portals (converting holdable ones into static portals).
2592 * If there weren't any, we are done ... otherwise loop back to check
2593 * if they queued deferred triggers. Lather, rinse, repeat.
2594 */
2595 if (!PreCommit_Portals(true))
2596 break;
2597 }
2598
2600
2601 /*
2602 * The remaining actions cannot call any user-defined code, so it's safe
2603 * to start shutting down within-transaction services. But note that most
2604 * of this stuff could still throw an error, which would switch us into
2605 * the transaction-abort path.
2606 */
2607
2608 /* Shut down the deferred-trigger manager */
2609 AfterTriggerEndXact(true);
2610
2611 /*
2612 * Let ON COMMIT management do its thing (must happen after closing
2613 * cursors, to avoid dangling-reference problems)
2614 */
2616
2617 /*
2618 * Synchronize files that are created and not WAL-logged during this
2619 * transaction. This must happen before EndPrepare(), so that we don't see
2620 * committed-but-broken files after a crash and COMMIT PREPARED.
2621 */
2622 smgrDoPendingSyncs(true, false);
2623
2624 /* close large objects before lower-level cleanup */
2626
2627 /* NOTIFY requires no work at this point */
2628
2629 /*
2630 * Mark serializable transaction as complete for predicate locking
2631 * purposes. This should be done as late as we can put it and still allow
2632 * errors to be raised for failure patterns found at commit.
2633 */
2635
2636 /*
2637 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2638 * this transaction. Having the prepared xact hold locks on another
2639 * backend's temp table seems a bad idea --- for instance it would prevent
2640 * the backend from exiting. There are other problems too, such as how to
2641 * clean up the source backend's local buffers and ON COMMIT state if the
2642 * prepared xact includes a DROP of a temp table.
2643 *
2644 * Other objects types, like functions, operators or extensions, share the
2645 * same restriction as they should not be created, locked or dropped as
2646 * this can mess up with this session or even a follow-up session trying
2647 * to use the same temporary namespace.
2648 *
2649 * We must check this after executing any ON COMMIT actions, because they
2650 * might still access a temp relation.
2651 *
2652 * XXX In principle this could be relaxed to allow some useful special
2653 * cases, such as a temp table created and dropped all within the
2654 * transaction. That seems to require much more bookkeeping though.
2655 */
2657 ereport(ERROR,
2659 errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2660
2661 /*
2662 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2663 * supported if we added cleanup logic to twophase.c, but for now it
2664 * doesn't seem worth the trouble.
2665 */
2667 ereport(ERROR,
2669 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2670
2671 /* Prevent cancel/die interrupt while cleaning up */
2673
2674 /*
2675 * set the current transaction state information appropriately during
2676 * prepare processing
2677 */
2678 s->state = TRANS_PREPARE;
2679
2680 /* Disable transaction timeout */
2681 if (TransactionTimeout > 0)
2683
2684 prepared_at = GetCurrentTimestamp();
2685
2686 /*
2687 * Reserve the GID for this transaction. This could fail if the requested
2688 * GID is invalid or already in use.
2689 */
2690 gxact = MarkAsPreparing(fxid, prepareGID, prepared_at,
2692 prepareGID = NULL;
2693
2694 /*
2695 * Collect data for the 2PC state file. Note that in general, no actual
2696 * state change should happen in the called modules during this step,
2697 * since it's still possible to fail before commit, and in that case we
2698 * want transaction abort to be able to clean up. (In particular, the
2699 * AtPrepare routines may error out if they find cases they cannot
2700 * handle.) State cleanup should happen in the PostPrepare routines
2701 * below. However, some modules can go ahead and clear state here because
2702 * they wouldn't do anything with it during abort anyway.
2703 *
2704 * Note: because the 2PC state file records will be replayed in the same
2705 * order they are made, the order of these calls has to match the order in
2706 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2707 * PREPARED; in particular, pay attention to whether things should happen
2708 * before or after releasing the transaction's locks.
2709 */
2711
2718
2719 /*
2720 * Here is where we really truly prepare.
2721 *
2722 * We have to record transaction prepares even if we didn't make any
2723 * updates, because the transaction manager might get confused if we lose
2724 * a global transaction.
2725 */
2727
2728 /*
2729 * Now we clean up backend-internal state and release internal resources.
2730 */
2731
2732 /* Reset XactLastRecEnd until the next transaction writes something */
2733 XactLastRecEnd = 0;
2734
2735 /*
2736 * Transfer our locks to a dummy PGPROC. This has to be done before
2737 * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2738 * conclude "xact already committed or aborted" for our locks.
2739 */
2740 PostPrepare_Locks(fxid);
2741
2742 /*
2743 * Let others know about no transaction in progress by me. This has to be
2744 * done *after* the prepared transaction has been marked valid, else
2745 * someone may think it is unlocked and recyclable.
2746 */
2748
2749 /*
2750 * In normal commit-processing, this is all non-critical post-transaction
2751 * cleanup. When the transaction is prepared, however, it's important
2752 * that the locks and other per-backend resources are transferred to the
2753 * prepared transaction's PGPROC entry. Note that if an error is raised
2754 * here, it's too late to abort the transaction. XXX: This probably should
2755 * be in a critical section, to force a PANIC if any of this fails, but
2756 * that cure could be worse than the disease.
2757 */
2758
2760
2763 true, true);
2764
2765 AtEOXact_Aio(true);
2766
2767 /* Check we've released all buffer pins */
2768 AtEOXact_Buffers(true);
2769
2770 /* Clean up the relation cache */
2772
2773 /* Clean up the type cache */
2775
2776 /* notify doesn't need a postprepare call */
2777
2779
2781
2783
2785
2787
2790 true, true);
2793 true, true);
2794
2795 /*
2796 * Allow another backend to finish the transaction. After
2797 * PostPrepare_Twophase(), the transaction is completely detached from our
2798 * backend. The rest is just non-critical cleanup of backend-local state.
2799 */
2801
2802 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2803 AtEOXact_GUC(true, 1);
2804 AtEOXact_SPI(true);
2805 AtEOXact_Enum();
2807 AtEOXact_Namespace(true, false);
2808 AtEOXact_SMgr();
2809 AtEOXact_Files(true);
2811 AtEOXact_HashTables(true);
2812 AtEOXact_RI(true);
2813 /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2814 AtEOXact_Snapshot(true, true);
2815 /* we treat PREPARE as ROLLBACK so far as waking workers goes */
2820
2826
2828
2831 s->nestingLevel = 0;
2832 s->gucNestLevel = 0;
2833 s->childXids = NULL;
2834 s->nChildXids = 0;
2835 s->maxChildXids = 0;
2836
2839
2840 /*
2841 * done with 1st phase commit processing, set current transaction state
2842 * back to default
2843 */
2844 s->state = TRANS_DEFAULT;
2845
2847}
2848
2849
2850/*
2851 * AbortTransaction
2852 */
2853static void
2854AbortTransaction(void)
2855{
2858 bool is_parallel_worker;
2859
2860 /* Prevent cancel/die interrupt while cleaning up */
2862
2863 /* Disable transaction timeout */
2864 if (TransactionTimeout > 0)
2866
2867 /* Make sure we have a valid memory context and resource owner */
2870
2871 /*
2872 * Release any LW locks we might be holding as quickly as possible.
2873 * (Regular locks, however, must be held till we finish aborting.)
2874 * Releasing LW locks is critical since we might try to grab them again
2875 * while cleaning up!
2876 */
2878
2879 /*
2880 * Cleanup waiting for LSN if any.
2881 */
2883
2884 /* Clear wait information and command progress indicator */
2887
2889
2890 /* Clean up buffer content locks, too */
2891 UnlockBuffers();
2892
2893 /* Reset WAL record construction state */
2895
2896 /* Cancel condition variable sleep */
2898
2899 /*
2900 * Also clean up any open wait for lock, since the lock manager will choke
2901 * if we try to wait for another lock before doing this.
2902 */
2904
2905 /*
2906 * If any timeout events are still active, make sure the timeout interrupt
2907 * is scheduled. This covers possible loss of a timeout interrupt due to
2908 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2909 * We delay this till after LockErrorCleanup so that we don't uselessly
2910 * reschedule lock or deadlock check timeouts.
2911 */
2913
2914 /*
2915 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2916 * handler. We do this fairly early in the sequence so that the timeout
2917 * infrastructure will be functional if needed while aborting.
2918 */
2920
2921 /*
2922 * check the current transaction state
2923 */
2925 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2926 elog(WARNING, "AbortTransaction while in %s state",
2928 Assert(s->parent == NULL);
2929
2930 /*
2931 * set the current transaction state information appropriately during the
2932 * abort processing
2933 */
2934 s->state = TRANS_ABORT;
2935
2936 /*
2937 * Reset user ID which might have been changed transiently. We need this
2938 * to clean up in case control escaped out of a SECURITY DEFINER function
2939 * or other local change of CurrentUserId; therefore, the prior value of
2940 * SecurityRestrictionContext also needs to be restored.
2941 *
2942 * (Note: it is not necessary to restore session authorization or role
2943 * settings here because those can only be changed via GUC, and GUC will
2944 * take care of rolling them back if need be.)
2945 */
2947
2948 /* Forget about any active REINDEX. */
2950
2951 /* Reset logical streaming state. */
2953
2954 /* Reset snapshot export state. */
2956
2957 /*
2958 * If this xact has started any unfinished parallel operation, clean up
2959 * its workers and exit parallel mode. Don't warn about leaked resources.
2960 */
2961 AtEOXact_Parallel(false);
2962 s->parallelModeLevel = 0;
2963 s->parallelChildXact = false; /* should be false already */
2964
2965 /*
2966 * do abort processing
2967 */
2968 AfterTriggerEndXact(false); /* 'false' means it's abort */
2971 AtEOXact_LargeObject(false);
2975
2976 /*
2977 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2978 * far as assigning an XID to advertise). But if we're inside a parallel
2979 * worker, skip this; the user backend must be the one to write the abort
2980 * record.
2981 */
2982 if (!is_parallel_worker)
2984 else
2985 {
2987
2988 /*
2989 * Since the parallel leader won't get our value of XactLastRecEnd in
2990 * this case, we nudge WAL-writer ourselves in this case. See related
2991 * comments in RecordTransactionAbort for why this matters.
2992 */
2994 }
2995
2997
2998 /*
2999 * Let others know about no transaction in progress by me. Note that this
3000 * must be done _before_ releasing locks we hold and _after_
3001 * RecordTransactionAbort.
3002 */
3004
3005 /*
3006 * Post-abort cleanup. See notes in CommitTransaction() concerning
3007 * ordering. We can skip all of it if the transaction failed before
3008 * creating a resource owner.
3009 */
3011 {
3014 else
3016
3019 false, true);
3020 AtEOXact_Aio(false);
3021 AtEOXact_Buffers(false);
3024 AtEOXact_Inval(false);
3028 false, true);
3031 false, true);
3032 smgrDoPendingDeletes(false);
3033
3034 AtEOXact_GUC(false, 1);
3035 AtEOXact_SPI(false);
3036 AtEOXact_Enum();
3039 AtEOXact_SMgr();
3040 AtEOXact_Files(false);
3042 AtEOXact_HashTables(false);
3043 AtEOXact_RI(false);
3049 }
3050
3051 /*
3052 * State remains TRANS_ABORT until CleanupTransaction().
3053 */
3055}
3056
3057/*
3058 * CleanupTransaction
3059 */
3060static void
3062{
3064
3065 /*
3066 * State should still be TRANS_ABORT from AbortTransaction().
3067 */
3068 if (s->state != TRANS_ABORT)
3069 elog(FATAL, "CleanupTransaction: unexpected state %s",
3071
3072 /*
3073 * do abort cleanup processing
3074 */
3075 AtCleanup_Portals(); /* now safe to release portal memory */
3076 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
3077
3078 CurrentResourceOwner = NULL; /* and resource owner */
3084
3085 AtCleanup_Memory(); /* and transaction memory */
3086
3089 s->nestingLevel = 0;
3090 s->gucNestLevel = 0;
3091 s->childXids = NULL;
3092 s->nChildXids = 0;
3093 s->maxChildXids = 0;
3094 s->parallelModeLevel = 0;
3095 s->parallelChildXact = false;
3096
3099
3100 /*
3101 * done with abort processing, set current transaction state back to
3102 * default
3103 */
3104 s->state = TRANS_DEFAULT;
3105}
3106
3107/*
3108 * StartTransactionCommand
3109 */
3110void
3112{
3114
3115 switch (s->blockState)
3116 {
3117 /*
3118 * if we aren't in a transaction block, we just do our usual start
3119 * transaction.
3120 */
3121 case TBLOCK_DEFAULT:
3124 break;
3125
3126 /*
3127 * We are somewhere in a transaction block or subtransaction and
3128 * about to start a new command. For now we do nothing, but
3129 * someday we may do command-local resource initialization. (Note
3130 * that any needed CommandCounterIncrement was done by the
3131 * previous CommitTransactionCommand.)
3132 */
3133 case TBLOCK_INPROGRESS:
3136 break;
3137
3138 /*
3139 * Here we are in a failed transaction block (one of the commands
3140 * caused an abort) so we do nothing but remain in the abort
3141 * state. Eventually we will get a ROLLBACK command which will
3142 * get us out of this state. (It is up to other code to ensure
3143 * that no commands other than ROLLBACK will be processed in these
3144 * states.)
3145 */
3146 case TBLOCK_ABORT:
3147 case TBLOCK_SUBABORT:
3148 break;
3149
3150 /* These cases are invalid. */
3151 case TBLOCK_STARTED:
3152 case TBLOCK_BEGIN:
3154 case TBLOCK_SUBBEGIN:
3155 case TBLOCK_END:
3156 case TBLOCK_SUBRELEASE:
3157 case TBLOCK_SUBCOMMIT:
3158 case TBLOCK_ABORT_END:
3162 case TBLOCK_SUBRESTART:
3164 case TBLOCK_PREPARE:
3165 elog(ERROR, "StartTransactionCommand: unexpected state %s",
3167 break;
3168 }
3169
3170 /*
3171 * We must switch to CurTransactionContext before returning. This is
3172 * already done if we called StartTransaction, otherwise not.
3173 */
3176}
3177
3178
3179/*
3180 * Simple system for saving and restoring transaction characteristics
3181 * (isolation level, read only, deferrable). We need this for transaction
3182 * chaining, so that we can set the characteristics of the new transaction to
3183 * be the same as the previous one. (We need something like this because the
3184 * GUC system resets the characteristics at transaction end, so for example
3185 * just skipping the reset in StartTransaction() won't work.)
3186 */
3187void
3189{
3193}
3194
3195void
3197{
3201}
3202
3203/*
3204 * CommitTransactionCommand -- a wrapper function handling the
3205 * loop over subtransactions to avoid a potentially dangerous recursion
3206 * in CommitTransactionCommandInternal().
3207 */
3208void
3210{
3211 /*
3212 * Repeatedly call CommitTransactionCommandInternal() until all the work
3213 * is done.
3214 */
3216 {
3217 }
3218}
3219
3220/*
3221 * CommitTransactionCommandInternal - a function doing an iteration of work
3222 * regarding handling the commit transaction command. In the case of
3223 * subtransactions more than one iterations could be required. Returns
3224 * true when no more iterations required, false otherwise.
3225 */
3226static bool
3228{
3231
3232 /* Must save in case we need to restore below */
3234
3235 switch (s->blockState)
3236 {
3237 /*
3238 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3239 * StartTransactionCommand didn't set the STARTED state
3240 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3241 * by EndParallelWorkerTransaction(), not this function.
3242 */
3243 case TBLOCK_DEFAULT:
3245 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3247 break;
3248
3249 /*
3250 * If we aren't in a transaction block, just do our usual
3251 * transaction commit, and return to the idle state.
3252 */
3253 case TBLOCK_STARTED:
3256 break;
3257
3258 /*
3259 * We are completing a "BEGIN TRANSACTION" command, so we change
3260 * to the "transaction block in progress" state and return. (We
3261 * assume the BEGIN did nothing to the database, so we need no
3262 * CommandCounterIncrement.)
3263 */
3264 case TBLOCK_BEGIN:
3266 break;
3267
3268 /*
3269 * This is the case when we have finished executing a command
3270 * someplace within a transaction block. We increment the command
3271 * counter and return.
3272 */
3273 case TBLOCK_INPROGRESS:
3277 break;
3278
3279 /*
3280 * We are completing a "COMMIT" command. Do it and return to the
3281 * idle state.
3282 */
3283 case TBLOCK_END:
3286 if (s->chain)
3287 {
3290 s->chain = false;
3292 }
3293 break;
3294
3295 /*
3296 * Here we are in the middle of a transaction block but one of the
3297 * commands caused an abort so we do nothing but remain in the
3298 * abort state. Eventually we will get a ROLLBACK command.
3299 */
3300 case TBLOCK_ABORT:
3301 case TBLOCK_SUBABORT:
3302 break;
3303
3304 /*
3305 * Here we were in an aborted transaction block and we just got
3306 * the ROLLBACK command from the user, so clean up the
3307 * already-aborted transaction and return to the idle state.
3308 */
3309 case TBLOCK_ABORT_END:
3312 if (s->chain)
3313 {
3316 s->chain = false;
3318 }
3319 break;
3320
3321 /*
3322 * Here we were in a perfectly good transaction block but the user
3323 * told us to ROLLBACK anyway. We have to abort the transaction
3324 * and then clean up.
3325 */
3330 if (s->chain)
3331 {
3334 s->chain = false;
3336 }
3337 break;
3338
3339 /*
3340 * We are completing a "PREPARE TRANSACTION" command. Do it and
3341 * return to the idle state.
3342 */
3343 case TBLOCK_PREPARE:
3346 break;
3347
3348 /*
3349 * The user issued a SAVEPOINT inside a transaction block. Start a
3350 * subtransaction. (DefineSavepoint already did PushTransaction,
3351 * so as to have someplace to put the SUBBEGIN state.)
3352 */
3353 case TBLOCK_SUBBEGIN:
3356 break;
3357
3358 /*
3359 * The user issued a RELEASE command, so we end the current
3360 * subtransaction and return to the parent transaction. The parent
3361 * might be ended too, so repeat till we find an INPROGRESS
3362 * transaction or subtransaction.
3363 */
3364 case TBLOCK_SUBRELEASE:
3365 do
3366 {
3368 s = CurrentTransactionState; /* changed by pop */
3369 } while (s->blockState == TBLOCK_SUBRELEASE);
3370
3373 break;
3374
3375 /*
3376 * The user issued a COMMIT, so we end the current subtransaction
3377 * hierarchy and perform final commit. We do this by rolling up
3378 * any subtransactions into their parent, which leads to O(N^2)
3379 * operations with respect to resource owners - this isn't that
3380 * bad until we approach a thousands of savepoints but is
3381 * necessary for correctness should after triggers create new
3382 * resource owners.
3383 */
3384 case TBLOCK_SUBCOMMIT:
3385 do
3386 {
3388 s = CurrentTransactionState; /* changed by pop */
3389 } while (s->blockState == TBLOCK_SUBCOMMIT);
3390 /* If we had a COMMIT command, finish off the main xact too */
3391 if (s->blockState == TBLOCK_END)
3392 {
3393 Assert(s->parent == NULL);
3396 if (s->chain)
3397 {
3400 s->chain = false;
3402 }
3403 }
3404 else if (s->blockState == TBLOCK_PREPARE)
3405 {
3406 Assert(s->parent == NULL);
3409 }
3410 else
3411 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3413 break;
3414
3415 /*
3416 * The current already-failed subtransaction is ending due to a
3417 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3418 * examine the parent (which could be in any of several states).
3419 * As we need to examine the parent, return false to request the
3420 * caller to do the next iteration.
3421 */
3424 return false;
3425
3426 /*
3427 * As above, but it's not dead yet, so abort first.
3428 */
3432 return false;
3433
3434 /*
3435 * The current subtransaction is the target of a ROLLBACK TO
3436 * command. Abort and pop it, then start a new subtransaction
3437 * with the same name.
3438 */
3439 case TBLOCK_SUBRESTART:
3440 {
3441 char *name;
3442 int savepointLevel;
3443
3444 /* save name and keep Cleanup from freeing it */
3445 name = s->name;
3446 s->name = NULL;
3447 savepointLevel = s->savepointLevel;
3448
3451
3453 s = CurrentTransactionState; /* changed by push */
3454 s->name = name;
3455 s->savepointLevel = savepointLevel;
3456
3457 /* This is the same as TBLOCK_SUBBEGIN case */
3461 }
3462 break;
3463
3464 /*
3465 * Same as above, but the subtransaction had already failed, so we
3466 * don't need AbortSubTransaction.
3467 */
3469 {
3470 char *name;
3471 int savepointLevel;
3472
3473 /* save name and keep Cleanup from freeing it */
3474 name = s->name;
3475 s->name = NULL;
3476 savepointLevel = s->savepointLevel;
3477
3479
3481 s = CurrentTransactionState; /* changed by push */
3482 s->name = name;
3483 s->savepointLevel = savepointLevel;
3484
3485 /* This is the same as TBLOCK_SUBBEGIN case */
3489 }
3490 break;
3491 }
3492
3493 /* Done, no more iterations required */
3494 return true;
3495}
3496
3497/*
3498 * AbortCurrentTransaction -- a wrapper function handling the
3499 * loop over subtransactions to avoid potentially dangerous recursion in
3500 * AbortCurrentTransactionInternal().
3501 */
3502void
3504{
3505 /*
3506 * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3507 * done.
3508 */
3510 {
3511 }
3512}
3513
3514/*
3515 * AbortCurrentTransactionInternal - a function doing an iteration of work
3516 * regarding handling the current transaction abort. In the case of
3517 * subtransactions more than one iterations could be required. Returns
3518 * true when no more iterations required, false otherwise.
3519 */
3520static bool
3522{
3524
3525 switch (s->blockState)
3526 {
3527 case TBLOCK_DEFAULT:
3528 if (s->state == TRANS_DEFAULT)
3529 {
3530 /* we are idle, so nothing to do */
3531 }
3532 else
3533 {
3534 /*
3535 * We can get here after an error during transaction start
3536 * (state will be TRANS_START). Need to clean up the
3537 * incompletely started transaction. First, adjust the
3538 * low-level state to suppress warning message from
3539 * AbortTransaction.
3540 */
3541 if (s->state == TRANS_START)
3545 }
3546 break;
3547
3548 /*
3549 * If we aren't in a transaction block, we just do the basic abort
3550 * & cleanup transaction. For this purpose, we treat an implicit
3551 * transaction block as if it were a simple statement.
3552 */
3553 case TBLOCK_STARTED:
3558 break;
3559
3560 /*
3561 * If we are in TBLOCK_BEGIN it means something screwed up right
3562 * after reading "BEGIN TRANSACTION". We assume that the user
3563 * will interpret the error as meaning the BEGIN failed to get him
3564 * into a transaction block, so we should abort and return to idle
3565 * state.
3566 */
3567 case TBLOCK_BEGIN:
3571 break;
3572
3573 /*
3574 * We are somewhere in a transaction block and we've gotten a
3575 * failure, so we abort the transaction and set up the persistent
3576 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3577 */
3578 case TBLOCK_INPROGRESS:
3582 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3583 break;
3584
3585 /*
3586 * Here, we failed while trying to COMMIT. Clean up the
3587 * transaction and return to idle state (we do not want to stay in
3588 * the transaction).
3589 */
3590 case TBLOCK_END:
3594 break;
3595
3596 /*
3597 * Here, we are already in an aborted transaction state and are
3598 * waiting for a ROLLBACK, but for some reason we failed again! So
3599 * we just remain in the abort state.
3600 */
3601 case TBLOCK_ABORT:
3602 case TBLOCK_SUBABORT:
3603 break;
3604
3605 /*
3606 * We are in a failed transaction and we got the ROLLBACK command.
3607 * We have already aborted, we just need to cleanup and go to idle
3608 * state.
3609 */
3610 case TBLOCK_ABORT_END:
3613 break;
3614
3615 /*
3616 * We are in a live transaction and we got a ROLLBACK command.
3617 * Abort, cleanup, go to idle state.
3618 */
3623 break;
3624
3625 /*
3626 * Here, we failed while trying to PREPARE. Clean up the
3627 * transaction and return to idle state (we do not want to stay in
3628 * the transaction).
3629 */
3630 case TBLOCK_PREPARE:
3634 break;
3635
3636 /*
3637 * We got an error inside a subtransaction. Abort just the
3638 * subtransaction, and go to the persistent SUBABORT state until
3639 * we get ROLLBACK.
3640 */
3644 break;
3645
3646 /*
3647 * If we failed while trying to create a subtransaction, clean up
3648 * the broken subtransaction and abort the parent. The same
3649 * applies if we get a failure while ending a subtransaction. As
3650 * we need to abort the parent, return false to request the caller
3651 * to do the next iteration.
3652 */
3653 case TBLOCK_SUBBEGIN:
3654 case TBLOCK_SUBRELEASE:
3655 case TBLOCK_SUBCOMMIT:
3657 case TBLOCK_SUBRESTART:
3660 return false;
3661
3662 /*
3663 * Same as above, except the Abort() was already done.
3664 */
3668 return false;
3669 }
3670
3671 /* Done, no more iterations required */
3672 return true;
3673}
3674
3675/*
3676 * PreventInTransactionBlock
3677 *
3678 * This routine is to be called by statements that must not run inside
3679 * a transaction block, typically because they have non-rollback-able
3680 * side effects or do internal commits.
3681 *
3682 * If this routine completes successfully, then the calling statement is
3683 * guaranteed that if it completes without error, its results will be
3684 * committed immediately.
3685 *
3686 * If we have already started a transaction block, issue an error; also issue
3687 * an error if we appear to be running inside a user-defined function (which
3688 * could issue more commands and possibly cause a failure after the statement
3689 * completes). Subtransactions are verboten too.
3690 *
3691 * We must also set XACT_FLAGS_NEEDIMMEDIATECOMMIT in MyXactFlags, to ensure
3692 * that postgres.c follows through by committing after the statement is done.
3693 *
3694 * isTopLevel: passed down from ProcessUtility to determine whether we are
3695 * inside a function. (We will always fail if this is false, but it's
3696 * convenient to centralize the check here instead of making callers do it.)
3697 * stmtType: statement type name, for error messages.
3698 */
3699void
3700PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
3701{
3702 /*
3703 * xact block already started?
3704 */
3705 if (IsTransactionBlock())
3706 ereport(ERROR,
3708 /* translator: %s represents an SQL statement name */
3709 errmsg("%s cannot run inside a transaction block",
3710 stmtType)));
3711
3712 /*
3713 * subtransaction?
3714 */
3715 if (IsSubTransaction())
3716 ereport(ERROR,
3718 /* translator: %s represents an SQL statement name */
3719 errmsg("%s cannot run inside a subtransaction",
3720 stmtType)));
3721
3722 /*
3723 * inside a function call?
3724 */
3725 if (!isTopLevel)
3726 ereport(ERROR,
3728 /* translator: %s represents an SQL statement name */
3729 errmsg("%s cannot be executed from a function or procedure",
3730 stmtType)));
3731
3732 /* If we got past IsTransactionBlock test, should be in default state */
3735 elog(FATAL, "cannot prevent transaction chain");
3736
3737 /* All okay. Set the flag to make sure the right thing happens later. */
3739}
3740
3741/*
3742 * WarnNoTransactionBlock
3743 * RequireTransactionBlock
3744 *
3745 * These two functions allow for warnings or errors if a command is executed
3746 * outside of a transaction block. This is useful for commands that have no
3747 * effects that persist past transaction end (and so calling them outside a
3748 * transaction block is presumably an error). DECLARE CURSOR is an example.
3749 * While top-level transaction control commands (BEGIN/COMMIT/ABORT) and SET
3750 * that have no effect issue warnings, all other no-effect commands generate
3751 * errors.
3752 *
3753 * If we appear to be running inside a user-defined function, we do not
3754 * issue anything, since the function could issue more commands that make
3755 * use of the current statement's results. Likewise subtransactions.
3756 * Thus these are inverses for PreventInTransactionBlock.
3757 *
3758 * isTopLevel: passed down from ProcessUtility to determine whether we are
3759 * inside a function.
3760 * stmtType: statement type name, for warning or error messages.
3761 */
3762void
3763WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
3764{
3765 CheckTransactionBlock(isTopLevel, false, stmtType);
3766}
3767
3768void
3769RequireTransactionBlock(bool isTopLevel, const char *stmtType)
3770{
3771 CheckTransactionBlock(isTopLevel, true, stmtType);
3772}
3773
3774/*
3775 * This is the implementation of the above two.
3776 */
3777static void
3778CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
3779{
3780 /*
3781 * xact block already started?
3782 */
3783 if (IsTransactionBlock())
3784 return;
3785
3786 /*
3787 * subtransaction?
3788 */
3789 if (IsSubTransaction())
3790 return;
3791
3792 /*
3793 * inside a function call?
3794 */
3795 if (!isTopLevel)
3796 return;
3797
3800 /* translator: %s represents an SQL statement name */
3801 errmsg("%s can only be used in transaction blocks",
3802 stmtType)));
3803}
3804
3805/*
3806 * IsInTransactionBlock
3807 *
3808 * This routine is for statements that need to behave differently inside
3809 * a transaction block than when running as single commands. ANALYZE is
3810 * currently the only example.
3811 *
3812 * If this routine returns "false", then the calling statement is allowed
3813 * to perform internal transaction-commit-and-start cycles; there is not a
3814 * risk of messing up any transaction already in progress. (Note that this
3815 * is not the identical guarantee provided by PreventInTransactionBlock,
3816 * since we will not force a post-statement commit.)
3817 *
3818 * isTopLevel: passed down from ProcessUtility to determine whether we are
3819 * inside a function.
3820 */
3821bool
3823{
3824 /*
3825 * Return true on same conditions that would make
3826 * PreventInTransactionBlock error out
3827 */
3828 if (IsTransactionBlock())
3829 return true;
3830
3831 if (IsSubTransaction())
3832 return true;
3833
3834 if (!isTopLevel)
3835 return true;
3836
3839 return true;
3840
3841 return false;
3842}
3843
3844
3845/*
3846 * Register or deregister callback functions for start- and end-of-xact
3847 * operations.
3848 *
3849 * These functions are intended for use by dynamically loaded modules.
3850 * For built-in modules we generally just hardwire the appropriate calls
3851 * (mainly because it's easier to control the order that way, where needed).
3852 *
3853 * At transaction end, the callback occurs post-commit or post-abort, so the
3854 * callback functions can only do noncritical cleanup.
3855 */
3856void
3858{
3859 XactCallbackItem *item;
3860
3861 item = (XactCallbackItem *)
3863 item->callback = callback;
3864 item->arg = arg;
3865 item->next = Xact_callbacks;
3866 Xact_callbacks = item;
3867}
3868
3869void
3871{
3872 XactCallbackItem *item;
3873 XactCallbackItem *prev;
3874
3875 prev = NULL;
3876 for (item = Xact_callbacks; item; prev = item, item = item->next)
3877 {
3878 if (item->callback == callback && item->arg == arg)
3879 {
3880 if (prev)
3881 prev->next = item->next;
3882 else
3883 Xact_callbacks = item->next;
3884 pfree(item);
3885 break;
3886 }
3887 }
3888}
3889
3890static void
3892{
3893 XactCallbackItem *item;
3895
3896 for (item = Xact_callbacks; item; item = next)
3897 {
3898 /* allow callbacks to unregister themselves when called */
3899 next = item->next;
3900 item->callback(event, item->arg);
3901 }
3902}
3903
3904
3905/*
3906 * Register or deregister callback functions for start- and end-of-subxact
3907 * operations.
3908 *
3909 * Pretty much same as above, but for subtransaction events.
3910 *
3911 * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3912 * so the callback functions can only do noncritical cleanup. At
3913 * subtransaction start, the callback is called when the subtransaction has
3914 * finished initializing.
3915 */
3916void
3918{
3919 SubXactCallbackItem *item;
3920
3921 item = (SubXactCallbackItem *)
3923 item->callback = callback;
3924 item->arg = arg;
3925 item->next = SubXact_callbacks;
3926 SubXact_callbacks = item;
3927}
3928
3929void
3931{
3932 SubXactCallbackItem *item;
3933 SubXactCallbackItem *prev;
3934
3935 prev = NULL;
3936 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3937 {
3938 if (item->callback == callback && item->arg == arg)
3939 {
3940 if (prev)
3941 prev->next = item->next;
3942 else
3943 SubXact_callbacks = item->next;
3944 pfree(item);
3945 break;
3946 }
3947 }
3948}
3949
3950static void
3954{
3955 SubXactCallbackItem *item;
3957
3958 for (item = SubXact_callbacks; item; item = next)
3959 {
3960 /* allow callbacks to unregister themselves when called */
3961 next = item->next;
3962 item->callback(event, mySubid, parentSubid, item->arg);
3963 }
3964}
3965
3966
3967/* ----------------------------------------------------------------
3968 * transaction block support
3969 * ----------------------------------------------------------------
3970 */
3971
3972/*
3973 * BeginTransactionBlock
3974 * This executes a BEGIN command.
3975 */
3976void
3978{
3980
3981 switch (s->blockState)
3982 {
3983 /*
3984 * We are not inside a transaction block, so allow one to begin.
3985 */
3986 case TBLOCK_STARTED:
3988 break;
3989
3990 /*
3991 * BEGIN converts an implicit transaction block to a regular one.
3992 * (Note that we allow this even if we've already done some
3993 * commands, which is a bit odd but matches historical practice.)
3994 */
3997 break;
3998
3999 /*
4000 * Already a transaction block in progress.
4001 */
4002 case TBLOCK_INPROGRESS:
4005 case TBLOCK_ABORT:
4006 case TBLOCK_SUBABORT:
4009 errmsg("there is already a transaction in progress")));
4010 break;
4011
4012 /* These cases are invalid. */
4013 case TBLOCK_DEFAULT:
4014 case TBLOCK_BEGIN:
4015 case TBLOCK_SUBBEGIN:
4016 case TBLOCK_END:
4017 case TBLOCK_SUBRELEASE:
4018 case TBLOCK_SUBCOMMIT:
4019 case TBLOCK_ABORT_END:
4023 case TBLOCK_SUBRESTART:
4025 case TBLOCK_PREPARE:
4026 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
4028 break;
4029 }
4030}
4031
4032/*
4033 * PrepareTransactionBlock
4034 * This executes a PREPARE command.
4035 *
4036 * Since PREPARE may actually do a ROLLBACK, the result indicates what
4037 * happened: true for PREPARE, false for ROLLBACK.
4038 *
4039 * Note that we don't actually do anything here except change blockState.
4040 * The real work will be done in the upcoming PrepareTransaction().
4041 * We do it this way because it's not convenient to change memory context,
4042 * resource owner, etc while executing inside a Portal.
4043 */
4044bool
4045PrepareTransactionBlock(const char *gid)
4046{
4048 bool result;
4049
4050 /* Set up to commit the current transaction */
4051 result = EndTransactionBlock(false);
4052
4053 /* If successful, change outer tblock state to PREPARE */
4054 if (result)
4055 {
4057
4058 while (s->parent != NULL)
4059 s = s->parent;
4060
4061 if (s->blockState == TBLOCK_END)
4062 {
4063 /* Save GID where PrepareTransaction can find it again */
4065
4067 }
4068 else
4069 {
4070 /*
4071 * ignore case where we are not in a transaction;
4072 * EndTransactionBlock already issued a warning.
4073 */
4076 /* Don't send back a PREPARE result tag... */
4077 result = false;
4078 }
4079 }
4080
4081 return result;
4082}
4083
4084/*
4085 * EndTransactionBlock
4086 * This executes a COMMIT command.
4087 *
4088 * Since COMMIT may actually do a ROLLBACK, the result indicates what
4089 * happened: true for COMMIT, false for ROLLBACK.
4090 *
4091 * Note that we don't actually do anything here except change blockState.
4092 * The real work will be done in the upcoming CommitTransactionCommand().
4093 * We do it this way because it's not convenient to change memory context,
4094 * resource owner, etc while executing inside a Portal.
4095 */
4096bool
4097EndTransactionBlock(bool chain)
4098{
4100 bool result = false;
4101
4102 switch (s->blockState)
4103 {
4104 /*
4105 * We are in a transaction block, so tell CommitTransactionCommand
4106 * to COMMIT.
4107 */
4108 case TBLOCK_INPROGRESS:
4110 result = true;
4111 break;
4112
4113 /*
4114 * We are in an implicit transaction block. If AND CHAIN was
4115 * specified, error. Otherwise commit, but issue a warning
4116 * because there was no explicit BEGIN before this.
4117 */
4119 if (chain)
4120 ereport(ERROR,
4122 /* translator: %s represents an SQL statement name */
4123 errmsg("%s can only be used in transaction blocks",
4124 "COMMIT AND CHAIN")));
4125 else
4128 errmsg("there is no transaction in progress")));
4130 result = true;
4131 break;
4132
4133 /*
4134 * We are in a failed transaction block. Tell
4135 * CommitTransactionCommand it's time to exit the block.
4136 */
4137 case TBLOCK_ABORT:
4139 break;
4140
4141 /*
4142 * We are in a live subtransaction block. Set up to subcommit all
4143 * open subtransactions and then commit the main transaction.
4144 */
4146 while (s->parent != NULL)
4147 {
4150 else
4151 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4153 s = s->parent;
4154 }
4155 if (s->blockState == TBLOCK_INPROGRESS)
4157 else
4158 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4160 result = true;
4161 break;
4162
4163 /*
4164 * Here we are inside an aborted subtransaction. Treat the COMMIT
4165 * as ROLLBACK: set up to abort everything and exit the main
4166 * transaction.
4167 */
4168 case TBLOCK_SUBABORT:
4169 while (s->parent != NULL)
4170 {
4173 else if (s->blockState == TBLOCK_SUBABORT)
4175 else
4176 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4178 s = s->parent;
4179 }
4180 if (s->blockState == TBLOCK_INPROGRESS)
4182 else if (s->blockState == TBLOCK_ABORT)
4184 else
4185 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4187 break;
4188
4189 /*
4190 * The user issued COMMIT when not inside a transaction. For
4191 * COMMIT without CHAIN, issue a WARNING, staying in
4192 * TBLOCK_STARTED state. The upcoming call to
4193 * CommitTransactionCommand() will then close the transaction and
4194 * put us back into the default state. For COMMIT AND CHAIN,
4195 * error.
4196 */
4197 case TBLOCK_STARTED:
4198 if (chain)
4199 ereport(ERROR,
4201 /* translator: %s represents an SQL statement name */
4202 errmsg("%s can only be used in transaction blocks",
4203 "COMMIT AND CHAIN")));
4204 else
4207 errmsg("there is no transaction in progress")));
4208 result = true;
4209 break;
4210
4211 /*
4212 * The user issued a COMMIT that somehow ran inside a parallel
4213 * worker. We can't cope with that.
4214 */
4216 ereport(FATAL,
4218 errmsg("cannot commit during a parallel operation")));
4219 break;
4220
4221 /* These cases are invalid. */
4222 case TBLOCK_DEFAULT:
4223 case TBLOCK_BEGIN:
4224 case TBLOCK_SUBBEGIN:
4225 case TBLOCK_END:
4226 case TBLOCK_SUBRELEASE:
4227 case TBLOCK_SUBCOMMIT:
4228 case TBLOCK_ABORT_END:
4232 case TBLOCK_SUBRESTART:
4234 case TBLOCK_PREPARE:
4235 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4237 break;
4238 }
4239
4241 s->blockState == TBLOCK_END ||
4244
4245 s->chain = chain;
4246
4247 return result;
4248}
4249
4250/*
4251 * UserAbortTransactionBlock
4252 * This executes a ROLLBACK command.
4253 *
4254 * As above, we don't actually do anything here except change blockState.
4255 */
4256void
4257UserAbortTransactionBlock(bool chain)
4258{
4260
4261 switch (s->blockState)
4262 {
4263 /*
4264 * We are inside a transaction block and we got a ROLLBACK command
4265 * from the user, so tell CommitTransactionCommand to abort and
4266 * exit the transaction block.
4267 */
4268 case TBLOCK_INPROGRESS:
4270 break;
4271
4272 /*
4273 * We are inside a failed transaction block and we got a ROLLBACK
4274 * command from the user. Abort processing is already done, so
4275 * CommitTransactionCommand just has to cleanup and go back to
4276 * idle state.
4277 */
4278 case TBLOCK_ABORT:
4280 break;
4281
4282 /*
4283 * We are inside a subtransaction. Mark everything up to top
4284 * level as exitable.
4285 */
4287 case TBLOCK_SUBABORT:
4288 while (s->parent != NULL)
4289 {
4292 else if (s->blockState == TBLOCK_SUBABORT)
4294 else
4295 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4297 s = s->parent;
4298 }
4299 if (s->blockState == TBLOCK_INPROGRESS)
4301 else if (s->blockState == TBLOCK_ABORT)
4303 else
4304 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4306 break;
4307
4308 /*
4309 * The user issued ABORT when not inside a transaction. For
4310 * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4311 * The upcoming call to CommitTransactionCommand() will then put
4312 * us back into the default state. For ROLLBACK AND CHAIN, error.
4313 *
4314 * We do the same thing with ABORT inside an implicit transaction,
4315 * although in this case we might be rolling back actual database
4316 * state changes. (It's debatable whether we should issue a
4317 * WARNING in this case, but we have done so historically.)
4318 */
4319 case TBLOCK_STARTED:
4321 if (chain)
4322 ereport(ERROR,
4324 /* translator: %s represents an SQL statement name */
4325 errmsg("%s can only be used in transaction blocks",
4326 "ROLLBACK AND CHAIN")));
4327 else
4330 errmsg("there is no transaction in progress")));
4332 break;
4333
4334 /*
4335 * The user issued an ABORT that somehow ran inside a parallel
4336 * worker. We can't cope with that.
4337 */
4339 ereport(FATAL,
4341 errmsg("cannot abort during a parallel operation")));
4342 break;
4343
4344 /* These cases are invalid. */
4345 case TBLOCK_DEFAULT:
4346 case TBLOCK_BEGIN:
4347 case TBLOCK_SUBBEGIN:
4348 case TBLOCK_END:
4349 case TBLOCK_SUBRELEASE:
4350 case TBLOCK_SUBCOMMIT:
4351 case TBLOCK_ABORT_END:
4355 case TBLOCK_SUBRESTART:
4357 case TBLOCK_PREPARE:
4358 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4360 break;
4361 }
4362
4365
4366 s->chain = chain;
4367}
4368
4369/*
4370 * BeginImplicitTransactionBlock
4371 * Start an implicit transaction block if we're not already in one.
4372 *
4373 * Unlike BeginTransactionBlock, this is called directly from the main loop
4374 * in postgres.c, not within a Portal. So we can just change blockState
4375 * without a lot of ceremony. We do not expect caller to do
4376 * CommitTransactionCommand/StartTransactionCommand.
4377 */
4378void
4380{
4382
4383 /*
4384 * If we are in STARTED state (that is, no transaction block is open),
4385 * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4386 * block.
4387 *
4388 * For caller convenience, we consider all other transaction states as
4389 * legal here; otherwise the caller would need its own state check, which
4390 * seems rather pointless.
4391 */
4392 if (s->blockState == TBLOCK_STARTED)
4394}
4395
4396/*
4397 * EndImplicitTransactionBlock
4398 * End an implicit transaction block, if we're in one.
4399 *
4400 * Like EndTransactionBlock, we just make any needed blockState change here.
4401 * The real work will be done in the upcoming CommitTransactionCommand().
4402 */
4403void
4405{
4407
4408 /*
4409 * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4410 * allowing CommitTransactionCommand to commit whatever happened during
4411 * the implicit transaction block as though it were a single statement.
4412 *
4413 * For caller convenience, we consider all other transaction states as
4414 * legal here; otherwise the caller would need its own state check, which
4415 * seems rather pointless.
4416 */
4419}
4420
4421/*
4422 * DefineSavepoint
4423 * This executes a SAVEPOINT command.
4424 */
4425void
4426DefineSavepoint(const char *name)
4427{
4429
4430 /*
4431 * Workers synchronize transaction state at the beginning of each parallel
4432 * operation, so we can't account for new subtransactions after that
4433 * point. (Note that this check will certainly error out if s->blockState
4434 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4435 * below.)
4436 */
4438 ereport(ERROR,
4440 errmsg("cannot define savepoints during a parallel operation")));
4441
4442 switch (s->blockState)
4443 {
4444 case TBLOCK_INPROGRESS:
4446 /* Normal subtransaction start */
4448 s = CurrentTransactionState; /* changed by push */
4449
4450 /*
4451 * Savepoint names, like the TransactionState block itself, live
4452 * in TopTransactionContext.
4453 */
4454 if (name)
4456 break;
4457
4458 /*
4459 * We disallow savepoint commands in implicit transaction blocks.
4460 * There would be no great difficulty in allowing them so far as
4461 * this module is concerned, but a savepoint seems inconsistent
4462 * with exec_simple_query's behavior of abandoning the whole query
4463 * string upon error. Also, the point of an implicit transaction
4464 * block (as opposed to a regular one) is to automatically close
4465 * after an error, so it's hard to see how a savepoint would fit
4466 * into that.
4467 *
4468 * The error messages for this are phrased as if there were no
4469 * active transaction block at all, which is historical but
4470 * perhaps could be improved.
4471 */
4473 ereport(ERROR,
4475 /* translator: %s represents an SQL statement name */
4476 errmsg("%s can only be used in transaction blocks",
4477 "SAVEPOINT")));
4478 break;
4479
4480 /* These cases are invalid. */
4481 case TBLOCK_DEFAULT:
4482 case TBLOCK_STARTED:
4483 case TBLOCK_BEGIN:
4485 case TBLOCK_SUBBEGIN:
4486 case TBLOCK_END:
4487 case TBLOCK_SUBRELEASE:
4488 case TBLOCK_SUBCOMMIT:
4489 case TBLOCK_ABORT:
4490 case TBLOCK_SUBABORT:
4491 case TBLOCK_ABORT_END:
4495 case TBLOCK_SUBRESTART:
4497 case TBLOCK_PREPARE:
4498 elog(FATAL, "DefineSavepoint: unexpected state %s",
4500 break;
4501 }
4502}
4503
4504/*
4505 * ReleaseSavepoint
4506 * This executes a RELEASE command.
4507 *
4508 * As above, we don't actually do anything here except change blockState.
4509 */
4510void
4511ReleaseSavepoint(const char *name)
4512{
4514 TransactionState target,
4515 xact;
4516
4517 /*
4518 * Workers synchronize transaction state at the beginning of each parallel
4519 * operation, so we can't account for transaction state change after that
4520 * point. (Note that this check will certainly error out if s->blockState
4521 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4522 * below.)
4523 */
4525 ereport(ERROR,
4527 errmsg("cannot release savepoints during a parallel operation")));
4528
4529 switch (s->blockState)
4530 {
4531 /*
4532 * We can't release a savepoint if there is no savepoint defined.
4533 */
4534 case TBLOCK_INPROGRESS:
4535 ereport(ERROR,
4537 errmsg("savepoint \"%s\" does not exist", name)));
4538 break;
4539
4541 /* See comment about implicit transactions in DefineSavepoint */
4542 ereport(ERROR,
4544 /* translator: %s represents an SQL statement name */
4545 errmsg("%s can only be used in transaction blocks",
4546 "RELEASE SAVEPOINT")));
4547 break;
4548
4549 /*
4550 * We are in a non-aborted subtransaction. This is the only valid
4551 * case.
4552 */
4554 break;
4555
4556 /* These cases are invalid. */
4557 case TBLOCK_DEFAULT:
4558 case TBLOCK_STARTED:
4559 case TBLOCK_BEGIN:
4561 case TBLOCK_SUBBEGIN:
4562 case TBLOCK_END:
4563 case TBLOCK_SUBRELEASE:
4564 case TBLOCK_SUBCOMMIT:
4565 case TBLOCK_ABORT:
4566 case TBLOCK_SUBABORT:
4567 case TBLOCK_ABORT_END:
4571 case TBLOCK_SUBRESTART:
4573 case TBLOCK_PREPARE:
4574 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4576 break;
4577 }
4578
4579 for (target = s; target; target = target->parent)
4580 {
4581 if (target->name && strcmp(target->name, name) == 0)
4582 break;
4583 }
4584
4585 if (!target)
4586 ereport(ERROR,
4588 errmsg("savepoint \"%s\" does not exist", name)));
4589
4590 /* disallow crossing savepoint level boundaries */
4591 if (target->savepointLevel != s->savepointLevel)
4592 ereport(ERROR,
4594 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4595
4596 /*
4597 * Mark "commit pending" all subtransactions up to the target
4598 * subtransaction. The actual commits will happen when control gets to
4599 * CommitTransactionCommand.
4600 */
4602 for (;;)
4603 {
4604 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
4605 xact->blockState = TBLOCK_SUBRELEASE;
4606 if (xact == target)
4607 break;
4608 xact = xact->parent;
4609 Assert(xact);
4610 }
4611}
4612
4613/*
4614 * RollbackToSavepoint
4615 * This executes a ROLLBACK TO <savepoint> command.
4616 *
4617 * As above, we don't actually do anything here except change blockState.
4618 */
4619void
4620RollbackToSavepoint(const char *name)
4621{
4623 TransactionState target,
4624 xact;
4625
4626 /*
4627 * Workers synchronize transaction state at the beginning of each parallel
4628 * operation, so we can't account for transaction state change after that
4629 * point. (Note that this check will certainly error out if s->blockState
4630 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4631 * below.)
4632 */
4634 ereport(ERROR,
4636 errmsg("cannot rollback to savepoints during a parallel operation")));
4637
4638 switch (s->blockState)
4639 {
4640 /*
4641 * We can't rollback to a savepoint if there is no savepoint
4642 * defined.
4643 */
4644 case TBLOCK_INPROGRESS:
4645 case TBLOCK_ABORT:
4646 ereport(ERROR,
4648 errmsg("savepoint \"%s\" does not exist", name)));
4649 break;
4650
4652 /* See comment about implicit transactions in DefineSavepoint */
4653 ereport(ERROR,
4655 /* translator: %s represents an SQL statement name */
4656 errmsg("%s can only be used in transaction blocks",
4657 "ROLLBACK TO SAVEPOINT")));
4658 break;
4659
4660 /*
4661 * There is at least one savepoint, so proceed.
4662 */
4664 case TBLOCK_SUBABORT:
4665 break;
4666
4667 /* These cases are invalid. */
4668 case TBLOCK_DEFAULT:
4669 case TBLOCK_STARTED:
4670 case TBLOCK_BEGIN:
4672 case TBLOCK_SUBBEGIN:
4673 case TBLOCK_END:
4674 case TBLOCK_SUBRELEASE:
4675 case TBLOCK_SUBCOMMIT:
4676 case TBLOCK_ABORT_END:
4680 case TBLOCK_SUBRESTART:
4682 case TBLOCK_PREPARE:
4683 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4685 break;
4686 }
4687
4688 for (target = s; target; target = target->parent)
4689 {
4690 if (target->name && strcmp(target->name, name) == 0)
4691 break;
4692 }
4693
4694 if (!target)
4695 ereport(ERROR,
4697 errmsg("savepoint \"%s\" does not exist", name)));
4698
4699 /* disallow crossing savepoint level boundaries */
4700 if (target->savepointLevel != s->savepointLevel)
4701 ereport(ERROR,
4703 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4704
4705 /*
4706 * Mark "abort pending" all subtransactions up to the target
4707 * subtransaction. The actual aborts will happen when control gets to
4708 * CommitTransactionCommand.
4709 */
4711 for (;;)
4712 {
4713 if (xact == target)
4714 break;
4715 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4717 else if (xact->blockState == TBLOCK_SUBABORT)
4718 xact->blockState = TBLOCK_SUBABORT_END;
4719 else
4720 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4721 BlockStateAsString(xact->blockState));
4722 xact = xact->parent;
4723 Assert(xact);
4724 }
4725
4726 /* And mark the target as "restart pending" */
4727 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4728 xact->blockState = TBLOCK_SUBRESTART;
4729 else if (xact->blockState == TBLOCK_SUBABORT)
4730 xact->blockState = TBLOCK_SUBABORT_RESTART;
4731 else
4732 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4733 BlockStateAsString(xact->blockState));
4734}
4735
4736/*
4737 * BeginInternalSubTransaction
4738 * This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
4739 * TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_END,
4740 * and TBLOCK_PREPARE states, and therefore it can safely be used in
4741 * functions that might be called when not inside a BEGIN block or when
4742 * running deferred triggers at COMMIT/PREPARE time. Also, it
4743 * automatically does CommitTransactionCommand/StartTransactionCommand
4744 * instead of expecting the caller to do it.
4745 */
4746void
4748{
4751
4752 /*
4753 * Errors within this function are improbable, but if one does happen we
4754 * force a FATAL exit. Callers generally aren't prepared to handle losing
4755 * control, and moreover our transaction state is probably corrupted if we
4756 * fail partway through; so an ordinary ERROR longjmp isn't okay.
4757 */
4758 ExitOnAnyError = true;
4759
4760 /*
4761 * We do not check for parallel mode here. It's permissible to start and
4762 * end "internal" subtransactions while in parallel mode, so long as no
4763 * new XIDs or command IDs are assigned. Enforcement of that occurs in
4764 * AssignTransactionId() and CommandCounterIncrement().
4765 */
4766
4767 switch (s->blockState)
4768 {
4769 case TBLOCK_STARTED:
4770 case TBLOCK_INPROGRESS:
4773 case TBLOCK_END:
4774 case TBLOCK_PREPARE:
4776 /* Normal subtransaction start */
4778 s = CurrentTransactionState; /* changed by push */
4779
4780 /*
4781 * Savepoint names, like the TransactionState block itself, live
4782 * in TopTransactionContext.
4783 */
4784 if (name)
4786 break;
4787
4788 /* These cases are invalid. */
4789 case TBLOCK_DEFAULT:
4790 case TBLOCK_BEGIN:
4791 case TBLOCK_SUBBEGIN:
4792 case TBLOCK_SUBRELEASE:
4793 case TBLOCK_SUBCOMMIT:
4794 case TBLOCK_ABORT:
4795 case TBLOCK_SUBABORT:
4796 case TBLOCK_ABORT_END:
4800 case TBLOCK_SUBRESTART:
4802 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4804 break;
4805 }
4806
4809
4811}
4812
4813/*
4814 * ReleaseCurrentSubTransaction
4815 *
4816 * RELEASE (ie, commit) the innermost subtransaction, regardless of its
4817 * savepoint name (if any).
4818 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4819 */
4820void
4822{
4824
4825 /*
4826 * We do not check for parallel mode here. It's permissible to start and
4827 * end "internal" subtransactions while in parallel mode, so long as no
4828 * new XIDs or command IDs are assigned.
4829 */
4830
4832 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4837 s = CurrentTransactionState; /* changed by pop */
4839}
4840
4841/*
4842 * RollbackAndReleaseCurrentSubTransaction
4843 *
4844 * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
4845 * of its savepoint name (if any).
4846 * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4847 */
4848void
4850{
4852
4853 /*
4854 * We do not check for parallel mode here. It's permissible to start and
4855 * end "internal" subtransactions while in parallel mode, so long as no
4856 * new XIDs or command IDs are assigned.
4857 */
4858
4859 switch (s->blockState)
4860 {
4861 /* Must be in a subtransaction */
4863 case TBLOCK_SUBABORT:
4864 break;
4865
4866 /* These cases are invalid. */
4867 case TBLOCK_DEFAULT:
4868 case TBLOCK_STARTED:
4869 case TBLOCK_BEGIN:
4872 case TBLOCK_SUBBEGIN:
4873 case TBLOCK_INPROGRESS:
4874 case TBLOCK_END:
4875 case TBLOCK_SUBRELEASE:
4876 case TBLOCK_SUBCOMMIT:
4877 case TBLOCK_ABORT:
4878 case TBLOCK_ABORT_END:
4882 case TBLOCK_SUBRESTART:
4884 case TBLOCK_PREPARE:
4885 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4887 break;
4888 }
4889
4890 /*
4891 * Abort the current subtransaction, if needed.
4892 */
4895
4896 /* And clean it up, too */
4898
4899 s = CurrentTransactionState; /* changed by pop */
4905}
4906
4907/*
4908 * AbortOutOfAnyTransaction
4909 *
4910 * This routine is provided for error recovery purposes. It aborts any
4911 * active transaction or transaction block, leaving the system in a known
4912 * idle state.
4913 */
4914void
4916{
4918
4919 /* Ensure we're not running in a doomed memory context */
4921
4922 /*
4923 * Get out of any transaction or nested transaction
4924 */
4925 do
4926 {
4927 switch (s->blockState)
4928 {
4929 case TBLOCK_DEFAULT:
4930 if (s->state == TRANS_DEFAULT)
4931 {
4932 /* Not in a transaction, do nothing */
4933 }
4934 else
4935 {
4936 /*
4937 * We can get here after an error during transaction start
4938 * (state will be TRANS_START). Need to clean up the
4939 * incompletely started transaction. First, adjust the
4940 * low-level state to suppress warning message from
4941 * AbortTransaction.
4942 */
4943 if (s->state == TRANS_START)
4947 }
4948 break;
4949 case TBLOCK_STARTED:
4950 case TBLOCK_BEGIN:
4951 case TBLOCK_INPROGRESS:
4954 case TBLOCK_END:
4956 case TBLOCK_PREPARE:
4957 /* In a transaction, so clean up */
4961 break;
4962 case TBLOCK_ABORT:
4963 case TBLOCK_ABORT_END:
4964
4965 /*
4966 * AbortTransaction is already done, still need Cleanup.
4967 * However, if we failed partway through running ROLLBACK,
4968 * there will be an active portal running that command, which
4969 * we need to shut down before doing CleanupTransaction.
4970 */
4974 break;
4975
4976 /*
4977 * In a subtransaction, so clean it up and abort parent too
4978 */
4979 case TBLOCK_SUBBEGIN:
4981 case TBLOCK_SUBRELEASE:
4982 case TBLOCK_SUBCOMMIT:
4984 case TBLOCK_SUBRESTART:
4987 s = CurrentTransactionState; /* changed by pop */
4988 break;
4989
4990 case TBLOCK_SUBABORT:
4993 /* As above, but AbortSubTransaction already done */
4994 if (s->curTransactionOwner)
4995 {
4996 /* As in TBLOCK_ABORT, might have a live portal to zap */
5001 }
5003 s = CurrentTransactionState; /* changed by pop */
5004 break;
5005 }
5006 } while (s->blockState != TBLOCK_DEFAULT);
5007
5008 /* Should be out of all subxacts now */
5009 Assert(s->parent == NULL);
5010
5011 /*
5012 * Revert to TopMemoryContext, to ensure we exit in a well-defined state
5013 * whether there were any transactions to close or not. (Callers that
5014 * don't intend to exit soon should switch to some other context to avoid
5015 * long-term memory leaks.)
5016 */
5018}
5019
5020/*
5021 * IsTransactionBlock --- are we within a transaction block?
5022 */
5023bool
5025{
5027
5029 return false;
5030
5031 return true;
5032}
5033
5034/*
5035 * IsTransactionOrTransactionBlock --- are we within either a transaction
5036 * or a transaction block? (The backend is only really "idle" when this
5037 * returns false.)
5038 *
5039 * This should match up with IsTransactionBlock and IsTransactionState.
5040 */
5041bool
5043{
5045
5046 if (s->blockState == TBLOCK_DEFAULT)
5047 return false;
5048
5049 return true;
5050}
5051
5052/*
5053 * TransactionBlockStatusCode - return status code to send in ReadyForQuery
5054 */
5055char
5057{
5059
5060 switch (s->blockState)
5061 {
5062 case TBLOCK_DEFAULT:
5063 case TBLOCK_STARTED:
5064 return 'I'; /* idle --- not in transaction */
5065 case TBLOCK_BEGIN:
5066 case TBLOCK_SUBBEGIN:
5067 case TBLOCK_INPROGRESS:
5071 case TBLOCK_END:
5072 case TBLOCK_SUBRELEASE:
5073 case TBLOCK_SUBCOMMIT:
5074 case TBLOCK_PREPARE:
5075 return 'T'; /* in transaction */
5076 case TBLOCK_ABORT:
5077 case TBLOCK_SUBABORT:
5078 case TBLOCK_ABORT_END:
5082 case TBLOCK_SUBRESTART:
5084 return 'E'; /* in failed transaction */
5085 }
5086
5087 /* should never get here */
5088 elog(FATAL, "invalid transaction block state: %s",
5090 return 0; /* keep compiler quiet */
5091}
5092
5093/*
5094 * IsSubTransaction
5095 */
5096bool
5097IsSubTransaction(void)
5098{
5100
5101 if (s->nestingLevel >= 2)
5102 return true;
5103
5104 return false;
5105}
5106
5107/*
5108 * StartSubTransaction
5109 *
5110 * If you're wondering why this is separate from PushTransaction: it's because
5111 * we can't conveniently do this stuff right inside DefineSavepoint. The
5112 * SAVEPOINT utility command will be executed inside a Portal, and if we
5113 * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
5114 * the Portal will undo those settings. So we make DefineSavepoint just
5115 * push a dummy transaction block, and when control returns to the main
5116 * idle loop, CommitTransactionCommand will be called, and we'll come here
5117 * to finish starting the subtransaction.
5118 */
5119static void
5121{
5123
5124 if (s->state != TRANS_DEFAULT)
5125 elog(WARNING, "StartSubTransaction while in %s state",
5127
5128 s->state = TRANS_START;
5129
5130 /*
5131 * Initialize subsystems for new subtransaction
5132 *
5133 * must initialize resource-management stuff first
5134 */
5138
5140
5141 /*
5142 * Call start-of-subxact callbacks
5143 */
5146
5147 ShowTransactionState("StartSubTransaction");
5148}
5149
5150/*
5151 * CommitSubTransaction
5152 *
5153 * The caller has to make sure to always reassign CurrentTransactionState
5154 * if it has a local pointer to it after calling this function.
5155 */
5156static void
5158{
5160
5161 ShowTransactionState("CommitSubTransaction");
5162
5163 if (s->state != TRANS_INPROGRESS)
5164 elog(WARNING, "CommitSubTransaction while in %s state",
5166
5167 /* Pre-commit processing goes here */
5168
5171
5172 /*
5173 * If this subxact has started any unfinished parallel operation, clean up
5174 * its workers and exit parallel mode. Warn about leaked resources.
5175 */
5177 if (s->parallelModeLevel != 0)
5178 {
5179 elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5181 s->parallelModeLevel = 0;
5182 }
5183
5184 /* Do the actual "commit", such as it is */
5185 s->state = TRANS_COMMIT;
5186
5187 /* Must CCI to ensure commands of subtransaction are seen as done */
5189
5190 /*
5191 * Prior to 8.4 we marked subcommit in clog at this point. We now only
5192 * perform that step, if required, as part of the atomic update of the
5193 * whole transaction tree at top level commit or abort.
5194 */
5195
5196 /* Post-commit cleanup */
5202 s->parent->nestingLevel,
5207
5210
5213 true, false);
5217 AtEOSubXact_Inval(true);
5219
5220 /*
5221 * The only lock we actually release here is the subtransaction XID lock.
5222 */
5226
5227 /*
5228 * Other locks should get transferred to their parent resource owner.
5229 */
5232 true, false);
5235 true, false);
5236
5237 AtEOXact_GUC(true, s->gucNestLevel);
5248
5249 /*
5250 * We need to restore the upper transaction's read-only state, in case the
5251 * upper is read-write while the child is read-only; GUC will incorrectly
5252 * think it should leave the child state in place.
5253 */
5255
5260
5262
5263 s->state = TRANS_DEFAULT;
5264
5266}
5267
5268/*
5269 * AbortSubTransaction
5270 */
5271static void
5273{
5275
5276 /* Prevent cancel/die interrupt while cleaning up */
5278
5279 /* Make sure we have a valid memory context and resource owner */
5282
5283 /*
5284 * Release any LW locks we might be holding as quickly as possible.
5285 * (Regular locks, however, must be held till we finish aborting.)
5286 * Releasing LW locks is critical since we might try to grab them again
5287 * while cleaning up!
5288 *
5289 * FIXME This may be incorrect --- Are there some locks we should keep?
5290 * Buffer locks, for example? I don't think so but I'm not sure.
5291 */
5293
5294 /*
5295 * Cleanup waiting for LSN if any.
5296 */
5298
5301
5303
5304 UnlockBuffers();
5305
5306 /* Reset WAL record construction state */
5308
5309 /* Cancel condition variable sleep */
5311
5312 /*
5313 * Also clean up any open wait for lock, since the lock manager will choke
5314 * if we try to wait for another lock before doing this.
5315 */
5317
5318 /*
5319 * If any timeout events are still active, make sure the timeout interrupt
5320 * is scheduled. This covers possible loss of a timeout interrupt due to
5321 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5322 * We delay this till after LockErrorCleanup so that we don't uselessly
5323 * reschedule lock or deadlock check timeouts.
5324 */
5326
5327 /*
5328 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5329 * handler. We do this fairly early in the sequence so that the timeout
5330 * infrastructure will be functional if needed while aborting.
5331 */
5333
5334 /*
5335 * check the current transaction state
5336 */
5337 ShowTransactionState("AbortSubTransaction");
5338
5339 if (s->state != TRANS_INPROGRESS)
5340 elog(WARNING, "AbortSubTransaction while in %s state",
5342
5343 s->state = TRANS_ABORT;
5344
5345 /*
5346 * Reset user ID which might have been changed transiently. (See notes in
5347 * AbortTransaction.)
5348 */
5350
5351 /* Forget about any active REINDEX. */
5353
5354 /* Reset logical streaming state. */
5356
5357 /*
5358 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5359 * exports are not supported in subtransactions.
5360 */
5361
5362 /*
5363 * If this subxact has started any unfinished parallel operation, clean up
5364 * its workers and exit parallel mode. Don't warn about leaked resources.
5365 */
5367 s->parallelModeLevel = 0;
5368
5369 /*
5370 * We can skip all this stuff if the subxact failed before creating a
5371 * ResourceOwner...
5372 */
5373 if (s->curTransactionOwner)
5374 {
5383
5384 /* Advertise the fact that we aborted in pg_xact. */
5386
5387 /* Post-abort cleanup */
5390
5393
5396 false, false);
5397
5398 AtEOXact_Aio(false);
5402 AtEOSubXact_Inval(false);
5405 false, false);
5408 false, false);
5410
5411 AtEOXact_GUC(false, s->gucNestLevel);
5422 }
5423
5424 /*
5425 * Restore the upper transaction's read-only state, too. This should be
5426 * redundant with GUC's cleanup but we may as well do it for consistency
5427 * with the commit case.
5428 */
5430
5432}
5433
5434/*
5435 * CleanupSubTransaction
5436 *
5437 * The caller has to make sure to always reassign CurrentTransactionState
5438 * if it has a local pointer to it after calling this function.
5439 */
5440static void
5442{
5444
5445 ShowTransactionState("CleanupSubTransaction");
5446
5447 if (s->state != TRANS_ABORT)
5448 elog(WARNING, "CleanupSubTransaction while in %s state",
5450
5452
5455 if (s->curTransactionOwner)
5458
5460
5461 s->state = TRANS_DEFAULT;
5462
5464}
5465
5466/*
5467 * PushTransaction
5468 * Create transaction state stack entry for a subtransaction
5469 *
5470 * The caller has to make sure to always reassign CurrentTransactionState
5471 * if it has a local pointer to it after calling this function.
5472 */
5473static void
5474PushTransaction(void)
5475{
5478
5479 /*
5480 * We keep subtransaction state nodes in TopTransactionContext.
5481 */
5482 s = (TransactionState)
5484 sizeof(TransactionStateData));
5485
5486 /*
5487 * Assign a subtransaction ID, watching out for counter wraparound.
5488 */
5491 {
5493 pfree(s);
5494 ereport(ERROR,
5496 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5497 }
5498
5499 /*
5500 * We can now stack a minimally valid subtransaction without fear of
5501 * failure.
5502 */
5503 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5505 s->parent = p;
5506 s->nestingLevel = p->nestingLevel + 1;
5509 s->state = TRANS_DEFAULT;
5514 s->parallelModeLevel = 0;
5516 s->topXidLogged = false;
5517
5519
5520 /*
5521 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5522 * with the subtransaction from here on out; in particular they should not
5523 * assume that it necessarily has a transaction context, resource owner,
5524 * or XID.
5525 */
5526}
5527
5528/*
5529 * PopTransaction
5530 * Pop back to parent transaction state
5531 *
5532 * The caller has to make sure to always reassign CurrentTransactionState
5533 * if it has a local pointer to it after calling this function.
5534 */
5535static void
5536PopTransaction(void)
5537{
5539
5540 if (s->state != TRANS_DEFAULT)
5541 elog(WARNING, "PopTransaction while in %s state",
5543
5544 if (s->parent == NULL)
5545 elog(FATAL, "PopTransaction with no parent");
5546
5548
5549 /* Let's just make sure CurTransactionContext is good */
5552
5553 /* Ditto for ResourceOwner links */
5556
5557 /* Free the old child structure */
5558 if (s->name)
5559 pfree(s->name);
5560 pfree(s);
5561}
5562
5563/*
5564 * EstimateTransactionStateSpace
5565 * Estimate the amount of space that will be needed by
5566 * SerializeTransactionState. It would be OK to overestimate slightly,
5567 * but it's simple for us to work out the precise value, so we do.
5568 */
5569Size
5571{
5573 Size nxids = 0;
5575
5576 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5577 {
5579 nxids = add_size(nxids, 1);
5581 }
5582
5583 return add_size(size, mul_size(sizeof(TransactionId), nxids));
5584}
5585
5586/*
5587 * SerializeTransactionState
5588 * Write out relevant details of our transaction state that will be
5589 * needed by a parallel worker.
5590 *
5591 * We need to save and restore XactDeferrable, XactIsoLevel, and the XIDs
5592 * associated with this transaction. These are serialized into a
5593 * caller-supplied buffer big enough to hold the number of bytes reported by
5594 * EstimateTransactionStateSpace(). We emit the XIDs in sorted order for the
5595 * convenience of the receiving process.
5596 */
5597void
5599{
5601 Size nxids = 0;
5602 Size i = 0;
5603 TransactionId *workspace;
5605
5607
5609 result->xactDeferrable = XactDeferrable;
5610 result->topFullTransactionId = XactTopFullTransactionId;
5611 result->currentFullTransactionId =
5613 result->currentCommandId = currentCommandId;
5614
5615 /*
5616 * If we're running in a parallel worker and launching a parallel worker
5617 * of our own, we can just pass along the information that was passed to
5618 * us.
5619 */
5620 if (nParallelCurrentXids > 0)
5621 {
5622 result->nParallelCurrentXids = nParallelCurrentXids;
5623 memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
5625 return;
5626 }
5627
5628 /*
5629 * OK, we need to generate a sorted list of XIDs that our workers should
5630 * view as current. First, figure out how many there are.
5631 */
5632 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5633 {
5635 nxids = add_size(nxids, 1);
5637 }
5639 <= maxsize);
5640
5641 /* Copy them to our scratch space. */
5642 workspace = palloc(nxids * sizeof(TransactionId));
5643 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5644 {
5646 workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5647 if (s->nChildXids > 0)
5648 memcpy(&workspace[i], s->childXids,
5649 s->nChildXids * sizeof(TransactionId));
5650 i += s->nChildXids;
5651 }
5652 Assert(i == nxids);
5653
5654 /* Sort them. */
5655 qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5656
5657 /* Copy data into output area. */
5658 result->nParallelCurrentXids = nxids;
5659 memcpy(&result->parallelCurrentXids[0], workspace,
5660 nxids * sizeof(TransactionId));
5661}
5662
5663/*
5664 * StartParallelWorkerTransaction
5665 * Start a parallel worker transaction, restoring the relevant
5666 * transaction state serialized by SerializeTransactionState.
5667 */
5668void
5670{
5672
5675
5677 XactIsoLevel = tstate->xactIsoLevel;
5678 XactDeferrable = tstate->xactDeferrable;
5679 XactTopFullTransactionId = tstate->topFullTransactionId;
5681 tstate->currentFullTransactionId;
5682 currentCommandId = tstate->currentCommandId;
5683 nParallelCurrentXids = tstate->nParallelCurrentXids;
5684 ParallelCurrentXids = &tstate->parallelCurrentXids[0];
5685
5687}
5688
5689/*
5690 * EndParallelWorkerTransaction
5691 * End a parallel worker transaction.
5692 */
5693void
5695{
5699}
5700
5701/*
5702 * ShowTransactionState
5703 * Debug support
5704 */
5705static void
5706ShowTransactionState(const char *str)
5707{
5708 /* skip work if message will definitely not be printed */
5711}
5712
5713/*
5714 * ShowTransactionStateRec
5715 * Recursive subroutine for ShowTransactionState
5716 */
5717static void
5719{
5721
5722 if (s->parent)
5723 {
5724 /*
5725 * Since this function recurses, it could be driven to stack overflow.
5726 * This is just a debugging aid, so we can leave out some details
5727 * instead of erroring out with check_stack_depth().
5728 */
5729 if (stack_is_too_deep())
5731 (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5732 str, s->nestingLevel)));
5733 else
5735 }
5736
5738 if (s->nChildXids > 0)
5739 {
5740 int i;
5741
5742 appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5743 for (i = 1; i < s->nChildXids; i++)
5744 appendStringInfo(&buf, " %u", s->childXids[i]);
5745 }
5747 (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5748 str, s->nestingLevel,
5749 s->name ? s->name : "unnamed",
5750 BlockStateAsString(s->blockState),
5752 XidFromFullTransactionId(s->fullTransactionId),
5753 s->subTransactionId,
5755 currentCommandIdUsed ? " (used)" : "",
5756 buf.data)));
5757 pfree(buf.data);
5758}
5759
5760/*
5761 * BlockStateAsString
5762 * Debug support
5763 */
5764static const char *
5766{
5767 switch (blockState)
5768 {
5769 case TBLOCK_DEFAULT:
5770 return "DEFAULT";
5771 case TBLOCK_STARTED:
5772 return "STARTED";
5773 case TBLOCK_BEGIN:
5774 return "BEGIN";
5775 case TBLOCK_INPROGRESS:
5776 return "INPROGRESS";
5778 return "IMPLICIT_INPROGRESS";
5780 return "PARALLEL_INPROGRESS";
5781 case TBLOCK_END:
5782 return "END";
5783 case TBLOCK_ABORT:
5784 return "ABORT";
5785 case TBLOCK_ABORT_END:
5786 return "ABORT_END";
5788 return "ABORT_PENDING";
5789 case TBLOCK_PREPARE:
5790 return "PREPARE";
5791 case TBLOCK_SUBBEGIN:
5792 return "SUBBEGIN";
5794 return "SUBINPROGRESS";
5795 case TBLOCK_SUBRELEASE:
5796 return "SUBRELEASE";
5797 case TBLOCK_SUBCOMMIT:
5798 return "SUBCOMMIT";
5799 case TBLOCK_SUBABORT:
5800 return "SUBABORT";
5802 return "SUBABORT_END";
5804 return "SUBABORT_PENDING";
5805 case TBLOCK_SUBRESTART:
5806 return "SUBRESTART";
5808 return "SUBABORT_RESTART";
5809 }
5810 return "UNRECOGNIZED";
5811}
5812
5813/*
5814 * TransStateAsString
5815 * Debug support
5816 */
5817static const char *
5819{
5820 switch (state)
5821 {
5822 case TRANS_DEFAULT:
5823 return "DEFAULT";
5824 case TRANS_START:
5825 return "START";
5826 case TRANS_INPROGRESS:
5827 return "INPROGRESS";
5828 case TRANS_COMMIT:
5829 return "COMMIT";
5830 case TRANS_ABORT:
5831 return "ABORT";
5832 case TRANS_PREPARE:
5833 return "PREPARE";
5834 }
5835 return "UNRECOGNIZED";
5836}
5837
5838/*
5839 * xactGetCommittedChildren
5840 *
5841 * Gets the list of committed children of the current transaction. The return
5842 * value is the number of child transactions. *ptr is set to point to an
5843 * array of TransactionIds. The array is allocated in TopTransactionContext;
5844 * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
5845 * If there are no subxacts, *ptr is set to NULL.
5846 */
5847int
5849{
5851
5852 if (s->nChildXids == 0)
5853 *ptr = NULL;
5854 else
5855 *ptr = s->childXids;
5856
5857 return s->nChildXids;
5858}
5859
5860/*
5861 * XLOG support routines
5862 */
5863
5864
5865/*
5866 * Log the commit record for a plain or twophase transaction commit.
5867 *
5868 * A 2pc commit will be emitted when twophase_xid is valid, a plain one
5869 * otherwise.
5870 */
5873 int nsubxacts, TransactionId *subxacts,
5874 int nrels, RelFileLocator *rels,
5876 int nmsgs, SharedInvalidationMessage *msgs,
5877 bool relcacheInval,
5878 int xactflags, TransactionId twophase_xid,
5879 const char *twophase_gid)
5880{
5890 uint8 info;
5891
5893
5894 xl_xinfo.xinfo = 0;
5895
5896 /* decide between a plain and 2pc commit */
5897 if (!TransactionIdIsValid(twophase_xid))
5898 info = XLOG_XACT_COMMIT;
5899 else
5901
5902 /* First figure out and collect all the information needed */
5903
5904 xlrec.xact_time = commit_time;
5905
5906 if (relcacheInval)
5908 if (forceSyncCommit)
5912
5913 /*
5914 * Check if the caller would like to ask standbys for immediate feedback
5915 * once this commit is applied.
5916 */
5919
5920 /*
5921 * Relcache invalidations requires information about the current database
5922 * and so does logical decoding.
5923 */
5924 if (nmsgs > 0 || XLogLogicalInfoActive())
5925 {
5927 xl_dbinfo.dbId = MyDatabaseId;
5929 }
5930
5931 if (nsubxacts > 0)
5932 {
5934 xl_subxacts.nsubxacts = nsubxacts;
5935 }
5936
5937 if (nrels > 0)
5938 {
5940 xl_relfilelocators.nrels = nrels;
5941 info |= XLR_SPECIAL_REL_UPDATE;
5942 }
5943
5944 if (ndroppedstats > 0)
5945 {
5948 }
5949
5950 if (nmsgs > 0)
5951 {
5953 xl_invals.nmsgs = nmsgs;
5954 }
5955
5956 if (TransactionIdIsValid(twophase_xid))
5957 {
5959 xl_twophase.xid = twophase_xid;
5960 Assert(twophase_gid != NULL);
5961
5964 }
5965
5966 /* dump transaction origin information */
5968 {
5970
5973 }
5974
5975 if (xl_xinfo.xinfo != 0)
5976 info |= XLOG_XACT_HAS_INFO;
5977
5978 /* Then include all the collected data into the commit record. */
5979
5981
5983
5984 if (xl_xinfo.xinfo != 0)
5985 XLogRegisterData(&xl_xinfo.xinfo, sizeof(xl_xinfo.xinfo));
5986
5987 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5989
5991 {
5994 XLogRegisterData(subxacts,
5995 nsubxacts * sizeof(TransactionId));
5996 }
5997
5999 {
6002 XLogRegisterData(rels,
6003 nrels * sizeof(RelFileLocator));
6004 }
6005
6007 {
6012 }
6013
6014 if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
6015 {
6017 XLogRegisterData(msgs,
6018 nmsgs * sizeof(SharedInvalidationMessage));
6019 }
6020
6022 {
6024 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6025 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6026 }
6027
6028 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6030
6031 /* we allow filtering by xacts */
6033
6034 return XLogInsert(RM_XACT_ID, info);
6035}
6036
6037/*
6038 * Log the commit record for a plain or twophase transaction abort.
6039 *
6040 * A 2pc abort will be emitted when twophase_xid is valid, a plain one
6041 * otherwise.
6042 */
6045 int nsubxacts, TransactionId *subxacts,
6046 int nrels, RelFileLocator *rels,
6048 int xactflags, TransactionId twophase_xid,
6049 const char *twophase_gid)
6050{
6059
6060 uint8 info;
6061
6063
6064 xl_xinfo.xinfo = 0;
6065
6066 /* decide between a plain and 2pc abort */
6067 if (!TransactionIdIsValid(twophase_xid))
6068 info = XLOG_XACT_ABORT;
6069 else
6071
6072
6073 /* First figure out and collect all the information needed */
6074
6075 xlrec.xact_time = abort_time;
6076
6079
6080 if (nsubxacts > 0)
6081 {
6083 xl_subxacts.nsubxacts = nsubxacts;
6084 }
6085
6086 if (nrels > 0)
6087 {
6089 xl_relfilelocators.nrels = nrels;
6090 info |= XLR_SPECIAL_REL_UPDATE;
6091 }
6092
6093 if (ndroppedstats > 0)
6094 {
6097 }
6098
6099 if (TransactionIdIsValid(twophase_xid))
6100 {
6102 xl_twophase.xid = twophase_xid;
6103 Assert(twophase_gid != NULL);
6104
6107 }
6108
6109 if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6110 {
6112 xl_dbinfo.dbId = MyDatabaseId;
6114 }
6115
6116 /*
6117 * Dump transaction origin information. We need this during recovery to
6118 * update the replication origin progress.
6119 */
6121 {
6123
6126 }
6127
6128 if (xl_xinfo.xinfo != 0)
6129 info |= XLOG_XACT_HAS_INFO;
6130
6131 /* Then include all the collected data into the abort record. */
6132
6134
6136
6137 if (xl_xinfo.xinfo != 0)
6139
6140 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6142
6144 {
6147 XLogRegisterData(subxacts,
6148 nsubxacts * sizeof(TransactionId));
6149 }
6150
6152 {
6155 XLogRegisterData(rels,
6156 nrels * sizeof(RelFileLocator));
6157 }
6158
6160 {
6165 }
6166
6168 {
6170 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6171 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6172 }
6173
6174 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6176
6177 /* Include the replication origin */
6179
6180 return XLogInsert(RM_XACT_ID, info);
6181}
6182
6183/*
6184 * Before 9.0 this was a fairly short function, but now it performs many
6185 * actions for which the order of execution is critical.
6186 */
6187static void
6189 TransactionId xid,
6190 XLogRecPtr lsn,
6191 ReplOriginId origin_id)
6192{
6194 TimestampTz commit_time;
6195
6197
6198 max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
6199
6200 /* Make sure nextXid is beyond any XID mentioned in the record. */
6202
6203 Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) ==
6204 (origin_id == InvalidReplOriginId));
6205
6206 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6207 commit_time = parsed->origin_timestamp;
6208 else
6209 commit_time = parsed->xact_time;
6210
6211 /* Set the transaction commit timestamp and metadata */
6212 TransactionTreeSetCommitTsData(xid, parsed->nsubxacts, parsed->subxacts,
6213 commit_time, origin_id);
6214
6216 {
6217 /*
6218 * Mark the transaction committed in pg_xact.
6219 */
6220 TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
6221 }
6222 else
6223 {
6224 /*
6225 * If a transaction completion record arrives that has as-yet
6226 * unobserved subtransactions then this will not have been fully
6227 * handled by the call to RecordKnownAssignedTransactionIds() in the
6228 * main recovery loop in PerformWalRecovery(). So we need to do
6229 * bookkeeping again to cover that case. This is confusing and it is
6230 * easy to think this call is irrelevant, which has happened three
6231 * times in development already. Leave it in.
6232 */
6234
6235 /*
6236 * Mark the transaction committed in pg_xact. We use async commit
6237 * protocol during recovery to provide information on database
6238 * consistency for when users try to set hint bits. It is important
6239 * that we do not set hint bits until the minRecoveryPoint is past
6240 * this commit record. This ensures that if we crash we don't see hint
6241 * bits set on changes made by transactions that haven't yet
6242 * recovered. It's unlikely but it's good to be safe.
6243 */
6244 TransactionIdAsyncCommitTree(xid, parsed->nsubxacts, parsed->subxacts, lsn);
6245
6246 /*
6247 * We must mark clog before we update the ProcArray.
6248 */
6249 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6250
6251 /*
6252 * Send any cache invalidations attached to the commit. We must
6253 * maintain the same order of invalidation then release locks as
6254 * occurs in CommitTransaction().
6255 */
6258 parsed->dbId, parsed->tsId);
6259
6260 /*
6261 * Release locks, if any. We do this for both two phase and normal one
6262 * phase transactions. In effect we are ignoring the prepare phase and
6263 * just going straight to lock release.
6264 */
6265 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6266 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6267 }
6268
6269 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6270 {
6271 /* recover apply progress */
6272 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6273 false /* backward */ , false /* WAL */ );
6274 }
6275
6276 /* Make sure files supposed to be dropped are dropped */
6277 if (parsed->nrels > 0)
6278 {
6279 /*
6280 * First update minimum recovery point to cover this WAL record. Once
6281 * a relation is deleted, there's no going back. The buffer manager
6282 * enforces the WAL-first rule for normal updates to relation files,
6283 * so that the minimum recovery point is always updated before the
6284 * corresponding change in the data file is flushed to disk, but we
6285 * have to do the same here since we're bypassing the buffer manager.
6286 *
6287 * Doing this before deleting the files means that if a deletion fails
6288 * for some reason, you cannot start up the system even after restart,
6289 * until you fix the underlying situation so that the deletion will
6290 * succeed. Alternatively, we could update the minimum recovery point
6291 * after deletion, but that would leave a small window where the
6292 * WAL-first rule would be violated.
6293 */
6294 XLogFlush(lsn);
6295
6296 /* Make sure files supposed to be dropped are dropped */
6297 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6298 }
6299
6300 if (parsed->nstats > 0)
6301 {
6302 /* see equivalent call for relations above */
6303 XLogFlush(lsn);
6304
6305 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6306 }
6307
6308 /*
6309 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
6310 * in normal operation. For example, in CREATE DATABASE, we copy all files
6311 * from the template database, and then commit the transaction. If we
6312 * crash after all the files have been copied but before the commit, you
6313 * have files in the data directory without an entry in pg_database. To
6314 * minimize the window for that, we use ForceSyncCommit() to rush the
6315 * commit record to disk as quick as possible. We have the same window
6316 * during recovery, and forcing an XLogFlush() (which updates
6317 * minRecoveryPoint during recovery) helps to reduce that problem window,
6318 * for any user that requested ForceSyncCommit().
6319 */
6321 XLogFlush(lsn);
6322
6323 /*
6324 * If asked by the primary (because someone is waiting for a synchronous
6325 * commit = remote_apply), we will need to ask walreceiver to send a reply
6326 * immediately.
6327 */
6330}
6331
6332/*
6333 * Be careful with the order of execution, as with xact_redo_commit().
6334 * The two functions are similar but differ in key places.
6335 *
6336 * Note also that an abort can be for a subtransaction and its children,
6337 * not just for a top level abort. That means we have to consider
6338 * topxid != xid, whereas in commit we would find topxid == xid always
6339 * because subtransaction commit is never WAL logged.
6340 */
6341static void
6343 XLogRecPtr lsn, ReplOriginId origin_id)
6344{
6346
6348
6349 /* Make sure nextXid is beyond any XID mentioned in the record. */
6351 parsed->nsubxacts,
6352 parsed->subxacts);
6354
6356 {
6357 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6358 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6359 }
6360 else
6361 {
6362 /*
6363 * If a transaction completion record arrives that has as-yet
6364 * unobserved subtransactions then this will not have been fully
6365 * handled by the call to RecordKnownAssignedTransactionIds() in the
6366 * main recovery loop in PerformWalRecovery(). So we need to do
6367 * bookkeeping again to cover that case. This is confusing and it is
6368 * easy to think this call is irrelevant, which has happened three
6369 * times in development already. Leave it in.
6370 */
6372
6373 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6374 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6375
6376 /*
6377 * We must update the ProcArray after we have marked clog.
6378 */
6379 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6380
6381 /*
6382 * There are no invalidation messages to send or undo.
6383 */
6384
6385 /*
6386 * Release locks, if any. There are no invalidations to send.
6387 */
6388 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6389 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6390 }
6391
6392 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6393 {
6394 /* recover apply progress */
6395 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6396 false /* backward */ , false /* WAL */ );
6397 }
6398
6399 /* Make sure files supposed to be dropped are dropped */
6400 if (parsed->nrels > 0)
6401 {
6402 /*
6403 * See comments about update of minimum recovery point on truncation,
6404 * in xact_redo_commit().
6405 */
6406 XLogFlush(lsn);
6407
6408 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6409 }
6410
6411 if (parsed->nstats > 0)
6412 {
6413 /* see equivalent call for relations above */
6414 XLogFlush(lsn);
6415
6416 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6417 }
6418}
6419
6420void
6422{
6423 uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6424
6425 /* Backup blocks are not used in xact records */
6427
6428 if (info == XLOG_XACT_COMMIT)
6429 {
6432
6435 record->EndRecPtr, XLogRecGetOrigin(record));
6436 }
6437 else if (info == XLOG_XACT_COMMIT_PREPARED)
6438 {
6441
6443 xact_redo_commit(&parsed, parsed.twophase_xid,
6444 record->EndRecPtr, XLogRecGetOrigin(record));
6445
6446 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6448 PrepareRedoRemove(parsed.twophase_xid, false);
6450 }
6451 else if (info == XLOG_XACT_ABORT)
6452 {
6455
6458 record->EndRecPtr, XLogRecGetOrigin(record));
6459 }
6460 else if (info == XLOG_XACT_ABORT_PREPARED)
6461 {
6464
6466 xact_redo_abort(&parsed, parsed.twophase_xid,
6467 record->EndRecPtr, XLogRecGetOrigin(record));
6468
6469 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6471 PrepareRedoRemove(parsed.twophase_xid, false);
6473 }
6474 else if (info == XLOG_XACT_PREPARE)
6475 {
6476 /*
6477 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6478 * gxact entry.
6479 */
6482 XLogRecGetData(record),
6483 record->ReadRecPtr,
6484 record->EndRecPtr,
6485 XLogRecGetOrigin(record));
6487 }
6488 else if (info == XLOG_XACT_ASSIGNMENT)
6489 {
6491
6494 xlrec->nsubxacts, xlrec->xsub);
6495 }
6496 else if (info == XLOG_XACT_INVALIDATIONS)
6497 {
6498 /*
6499 * XXX we do ignore this for now, what matters are invalidations
6500 * written into the commit record.
6501 */
6502 }
6503 else
6504 elog(PANIC, "xact_redo: unknown op code %u", info);
6505}
void pgaio_error_cleanup(void)
Definition aio.c:1175
void AtEOXact_Aio(bool is_commit)
Definition aio.c:1203
void AtCommit_Notify(void)
Definition async.c:1378
void AtAbort_Notify(void)
Definition async.c:2420
void PreCommit_Notify(void)
Definition async.c:1185
void AtSubAbort_Notify(void)
Definition async.c:2509
void AtPrepare_Notify(void)
Definition async.c:1160
void AtSubCommit_Notify(void)
Definition async.c:2439
#define pg_write_barrier()
Definition atomics.h:155
void ParallelWorkerReportLastRecEnd(XLogRecPtr last_xlog_end)
Definition parallel.c:1594
bool ParallelContextActive(void)
Definition parallel.c:1033
void AtEOSubXact_Parallel(bool isCommit, SubTransactionId mySubId)
Definition parallel.c:1263
void AtEOXact_Parallel(bool isCommit)
Definition parallel.c:1284
sigset_t UnBlockSig
Definition pqsignal.c:22
void AtEOXact_LogicalRepWorkers(bool isCommit)
Definition worker.c:6348
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1649
void pgstat_progress_end_command(void)
void pgstat_report_xact_timestamp(TimestampTz tstamp)
void AtEOXact_LargeObject(bool isCommit)
Definition be-fsstubs.c:607
void AtEOSubXact_LargeObject(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition be-fsstubs.c:653
static int32 next
Definition blutils.c:225
static void cleanup(void)
Definition bootstrap.c:886
void AtEOXact_Buffers(bool isCommit)
Definition bufmgr.c:4222
void UnlockBuffers(void)
Definition bufmgr.c:5875
#define InvalidCommandId
Definition c.h:812
#define TopSubTransactionId
Definition c.h:802
#define Min(x, y)
Definition c.h:1150
uint8_t uint8
Definition c.h:681
uint32 SubTransactionId
Definition c.h:799
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:308
#define InvalidSubTransactionId
Definition c.h:801
#define Assert(condition)
Definition c.h:1002
#define FirstCommandId
Definition c.h:811
uint32 LocalTransactionId
Definition c.h:797
uint32 CommandId
Definition c.h:809
uint32 TransactionId
Definition c.h:795
size_t Size
Definition c.h:748
uint32 result
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
void AtEOXact_ComboCid(void)
Definition combocid.c:182
void TransactionTreeSetCommitTsData(TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz timestamp, ReplOriginId nodeid)
Definition commit_ts.c:150
bool ConditionVariableCancelSleep(void)
int64 TimestampTz
Definition timestamp.h:39
void AtEOXact_HashTables(bool isCommit)
Definition dynahash.c:1864
void AtEOSubXact_HashTables(bool isCommit, int nestDepth)
Definition dynahash.c:1890
Datum arg
Definition elog.c:1323
bool message_level_is_interesting(int elevel)
Definition elog.c:285
int errcode(int sqlerrcode)
Definition elog.c:875
#define FATAL
Definition elog.h:42
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define WARNING
Definition elog.h:37
#define PANIC
Definition elog.h:44
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
#define DEBUG5
Definition elog.h:27
void AtEOXact_Files(bool isCommit)
Definition fd.c:3212
void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition fd.c:3181
#define MaxAllocSize
Definition fe_memutils.h:22
#define palloc_array(type, count)
Definition fe_memutils.h:91
ProcNumber MyProcNumber
Definition globals.c:92
Oid MyDatabaseTableSpace
Definition globals.c:98
volatile uint32 CritSectionCount
Definition globals.c:45
bool ExitOnAnyError
Definition globals.c:125
Oid MyDatabaseId
Definition globals.c:96
int NewGUCNestLevel(void)
Definition guc.c:2142
void AtStart_GUC(void)
Definition guc.c:2122
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition guc.c:2169
double log_xact_sample_rate
Definition guc_tables.c:576
const char * str
#define IsParallelWorker()
Definition parallel.h:62
void ResetReindexState(int nestLevel)
Definition index.c:4234
void PostPrepare_Inval(void)
Definition inval.c:993
void LogLogicalInvalidations(void)
Definition inval.c:1936
void AcceptInvalidationMessages(void)
Definition inval.c:930
int xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs, bool *RelcacheInitFileInval)
Definition inval.c:1012
void AtEOXact_Inval(bool isCommit)
Definition inval.c:1196
void AtEOSubXact_Inval(bool isCommit)
Definition inval.c:1307
void CommandEndInvalidationMessages(void)
Definition inval.c:1406
void ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs, int nmsgs, bool RelcacheInitFileInval, Oid dbid, Oid tsid)
Definition inval.c:1135
int i
Definition isn.c:77
void AtEOXact_ApplyLauncher(bool isCommit)
Definition launcher.c:1166
void XactLockTableDelete(TransactionId xid)
Definition lmgr.c:639
void XactLockTableInsert(TransactionId xid)
Definition lmgr.c:622
void PostPrepare_Locks(FullTransactionId fxid)
Definition lock.c:3579
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
Definition lock.c:4600
void AtPrepare_Locks(void)
Definition lock.c:3483
#define InvalidLocalTransactionId
Definition lock.h:68
void ResetLogicalStreamingState(void)
Definition logical.c:1941
void AtEOXact_LogicalCtl(void)
Definition logicalctl.c:233
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1150
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1767
void LWLockReleaseAll(void)
Definition lwlock.c:1866
@ LW_EXCLUSIVE
Definition lwlock.h:104
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition mcxt.c:1897
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1235
bool MemoryContextIsEmpty(MemoryContext context)
Definition mcxt.c:795
void MemoryContextReset(MemoryContext context)
Definition mcxt.c:406
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition mcxt.c:1269
Size add_size(Size s1, Size s2)
Definition mcxt.c:1733
MemoryContext TopTransactionContext
Definition mcxt.c:172
void * repalloc(void *pointer, Size size)
Definition mcxt.c:1635
void pfree(void *pointer)
Definition mcxt.c:1619
MemoryContext TopMemoryContext
Definition mcxt.c:167
Size mul_size(Size s1, Size s2)
Definition mcxt.c:1752
void * palloc(Size size)
Definition mcxt.c:1390
MemoryContext CurTransactionContext
Definition mcxt.c:173
MemoryContext CurrentMemoryContext
Definition mcxt.c:161
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:475
void DropRelationFiles(RelFileLocator *delrels, int ndelrels, bool isRedo)
Definition md.c:1614
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
#define RESUME_INTERRUPTS()
Definition miscadmin.h:138
#define START_CRIT_SECTION()
Definition miscadmin.h:152
#define HOLD_INTERRUPTS()
Definition miscadmin.h:136
#define END_CRIT_SECTION()
Definition miscadmin.h:154
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition miscinit.c:613
Oid GetUserId(void)
Definition miscinit.c:470
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition miscinit.c:620
void PostPrepare_MultiXact(FullTransactionId fxid)
Definition multixact.c:1670
void AtPrepare_MultiXact(void)
Definition multixact.c:1656
void AtEOXact_MultiXact(void)
Definition multixact.c:1628
void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition namespace.c:4630
void AtEOXact_Namespace(bool isCommit, bool parallel)
Definition namespace.c:4584
static char * errmsg
ReplOriginXactState replorigin_xact_state
Definition origin.c:168
void replorigin_advance(ReplOriginId node, XLogRecPtr remote_commit, XLogRecPtr local_commit, bool go_backward, bool wal_log)
Definition origin.c:928
void replorigin_session_advance(XLogRecPtr remote_commit, XLogRecPtr local_commit)
Definition origin.c:1335
#define DoNotReplicateId
Definition origin.h:34
#define InvalidReplOriginId
Definition origin.h:33
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:138
const void * data
void AtEOXact_Enum(void)
Definition pg_enum.c:739
double pg_prng_double(pg_prng_state *state)
Definition pg_prng.c:268
pg_prng_state pg_global_prng_state
Definition pg_prng.c:34
static char buf[DEFAULT_XLOG_SEG_SIZE]
void AtPrepare_PgStat(void)
void pgstat_execute_transactional_drops(int ndrops, struct xl_xact_stats_item *items, bool is_redo)
void AtEOXact_PgStat(bool isCommit, bool parallel)
Definition pgstat_xact.c:40
void PostPrepare_PgStat(void)
int pgstat_get_transactional_drops(bool isCommit, xl_xact_stats_item **items)
void AtEOSubXact_PgStat(bool isCommit, int nestDepth)
#define qsort(a, b, c, d)
Definition port.h:496
void AtAbort_Portals(void)
Definition portalmem.c:782
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition portalmem.c:981
bool PreCommit_Portals(bool isPrepare)
Definition portalmem.c:678
void AtSubCommit_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, int parentLevel, ResourceOwner parentXactOwner)
Definition portalmem.c:945
void AtCleanup_Portals(void)
Definition portalmem.c:860
void AtSubCleanup_Portals(SubTransactionId mySubid)
Definition portalmem.c:1094
void PreCommit_CheckForSerializationFailure(void)
Definition predicate.c:4632
void PostPrepare_PredicateLocks(FullTransactionId fxid)
Definition predicate.c:4788
void AtPrepare_PredicateLocks(void)
Definition predicate.c:4719
void RegisterPredicateLockingXid(TransactionId xid)
Definition predicate.c:1888
static int fb(int x)
#define DELAY_CHKPT_IN_COMMIT
Definition proc.h:141
#define PGPROC_MAX_CACHED_SUBXIDS
Definition proc.h:43
void XidCacheRemoveRunningXids(TransactionId xid, int nxids, const TransactionId *xids, TransactionId latestXid)
Definition procarray.c:3998
void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
Definition procarray.c:663
void RecordKnownAssignedTransactionIds(TransactionId xid)
Definition procarray.c:4443
void ProcArrayClearTransaction(PGPROC *proc)
Definition procarray.c:899
void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)
Definition procarray.c:1309
void ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids, TransactionId *subxids, TransactionId max_xid)
Definition procarray.c:4512
void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition relcache.c:3380
void AtEOXact_RelationCache(bool isCommit)
Definition relcache.c:3228
void AtPrepare_RelationMap(void)
Definition relmapper.c:589
void AtEOXact_RelationMap(bool isCommit, bool isParallelWorker)
Definition relmapper.c:542
void AtCCI_RelationMap(void)
Definition relmapper.c:505
ResourceOwner TopTransactionResourceOwner
Definition resowner.c:175
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition resowner.c:428
ResourceOwner CurrentResourceOwner
Definition resowner.c:173
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition resowner.c:665
void ResourceOwnerDelete(ResourceOwner owner)
Definition resowner.c:878
ResourceOwner CurTransactionResourceOwner
Definition resowner.c:174
@ RESOURCE_RELEASE_LOCKS
Definition resowner.h:55
@ RESOURCE_RELEASE_BEFORE_LOCKS
Definition resowner.h:54
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition resowner.h:56
void AtEOXact_RI(bool isCommit)
LocalTransactionId GetNextLocalTransactionId(void)
Definition sinvaladt.c:703
void AtEOXact_SMgr(void)
Definition smgr.c:1017
void SnapBuildResetExportedSnapshotState(void)
Definition snapbuild.c:630
void AtSubAbort_Snapshot(int level)
Definition snapmgr.c:982
void AtEOXact_Snapshot(bool isCommit, bool resetXmin)
Definition snapmgr.c:1016
void AtSubCommit_Snapshot(int level)
Definition snapmgr.c:961
bool XactHasExportedSnapshots(void)
Definition snapmgr.c:1573
void SnapshotSetCommandId(CommandId curcid)
Definition snapmgr.c:490
void AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid)
Definition spi.c:483
bool SPI_inside_nonatomic_context(void)
Definition spi.c:582
void AtEOXact_SPI(bool isCommit)
Definition spi.c:429
PGPROC * MyProc
Definition proc.c:71
int TransactionTimeout
Definition proc.c:66
void LockErrorCleanup(void)
Definition proc.c:828
bool stack_is_too_deep(void)
void StandbyReleaseLockTree(TransactionId xid, int nsubxids, TransactionId *subxids)
Definition standby.c:1094
void LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInitFileInval)
Definition standby.c:1473
void AtSubCommit_smgr(void)
Definition storage.c:955
void AtSubAbort_smgr(void)
Definition storage.c:975
int smgrGetPendingDeletes(bool forCommit, RelFileLocator **ptr)
Definition storage.c:893
void PostPrepare_smgr(void)
Definition storage.c:934
void smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
Definition storage.c:741
void smgrDoPendingDeletes(bool isCommit)
Definition storage.c:673
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition stringinfo.c:145
void initStringInfo(StringInfo str)
Definition stringinfo.c:97
LocalTransactionId lxid
Definition proc.h:231
ProcNumber procNumber
Definition proc.h:226
int delayChkptFlags
Definition proc.h:260
struct PGPROC::@134 vxid
ReplOriginId origin
Definition origin.h:45
XLogRecPtr origin_lsn
Definition origin.h:46
TimestampTz origin_timestamp
Definition origin.h:47
struct SubXactCallbackItem * next
Definition xact.c:324
SubXactCallback callback
Definition xact.c:325
TransState state
Definition xact.c:201
SubTransactionId subTransactionId
Definition xact.c:198
FullTransactionId fullTransactionId
Definition xact.c:197
struct TransactionStateData * parent
Definition xact.c:220
MemoryContext priorContext
Definition xact.c:207
bool parallelChildXact
Definition xact.c:217
MemoryContext curTransactionContext
Definition xact.c:205
TBlockState blockState
Definition xact.c:202
bool prevXactReadOnly
Definition xact.c:213
TransactionId * childXids
Definition xact.c:208
bool startedInRecovery
Definition xact.c:214
ResourceOwner curTransactionOwner
Definition xact.c:206
LocalTransactionId localTransactionId
Definition lock.h:65
ProcNumber procNumber
Definition lock.h:64
XLogRecPtr EndRecPtr
Definition xlogreader.h:206
XLogRecPtr ReadRecPtr
Definition xlogreader.h:205
struct XactCallbackItem * next
Definition xact.c:312
void * arg
Definition xact.c:314
XactCallback callback
Definition xact.c:313
TransactionId xtop
Definition xact.h:221
void SubTransSetParent(TransactionId xid, TransactionId parent)
Definition subtrans.c:92
void SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
Definition syncrep.c:149
void AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
void PreCommit_on_commit_actions(void)
void AtEOXact_on_commit_actions(bool isCommit)
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition timeout.c:560
void reschedule_timeouts(void)
Definition timeout.c:540
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition timeout.c:685
@ TRANSACTION_TIMEOUT
Definition timeout.h:34
void TransactionIdAsyncCommitTree(TransactionId xid, int nxids, TransactionId *xids, XLogRecPtr lsn)
Definition transam.c:252
TransactionId TransactionIdLatest(TransactionId mainxid, int nxids, const TransactionId *xids)
Definition transam.c:281
bool TransactionIdDidCommit(TransactionId transactionId)
Definition transam.c:126
void TransactionIdCommitTree(TransactionId xid, int nxids, TransactionId *xids)
Definition transam.c:240
void TransactionIdAbortTree(TransactionId xid, int nxids, TransactionId *xids)
Definition transam.c:270
static TransactionId ReadNextTransactionId(void)
Definition transam.h:375
#define InvalidTransactionId
Definition transam.h:31
#define TransactionIdEquals(id1, id2)
Definition transam.h:43
#define XidFromFullTransactionId(x)
Definition transam.h:48
#define TransactionIdIsValid(xid)
Definition transam.h:41
#define TransactionIdIsNormal(xid)
Definition transam.h:42
#define InvalidFullTransactionId
Definition transam.h:56
#define FullTransactionIdIsValid(x)
Definition transam.h:55
static bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition transam.h:263
void AfterTriggerBeginXact(void)
Definition trigger.c:5131
void AfterTriggerEndSubXact(bool isCommit)
Definition trigger.c:5519
void AfterTriggerFireDeferred(void)
Definition trigger.c:5354
void AfterTriggerEndXact(bool isCommit)
Definition trigger.c:5417
void AfterTriggerBeginSubXact(void)
Definition trigger.c:5471
GlobalTransaction MarkAsPreparing(FullTransactionId fxid, const char *gid, TimestampTz prepared_at, Oid owner, Oid databaseid)
Definition twophase.c:365
void PrepareRedoAdd(FullTransactionId fxid, char *buf, XLogRecPtr start_lsn, XLogRecPtr end_lsn, ReplOriginId origin_id)
Definition twophase.c:2513
void AtAbort_Twophase(void)
Definition twophase.c:310
void PrepareRedoRemove(TransactionId xid, bool giveWarning)
Definition twophase.c:2670
void EndPrepare(GlobalTransaction gxact)
Definition twophase.c:1151
void StartPrepare(GlobalTransaction gxact)
Definition twophase.c:1058
void PostPrepare_Twophase(void)
Definition twophase.c:350
void AtEOXact_TypeCache(void)
Definition typcache.c:3219
void AtEOSubXact_TypeCache(void)
Definition typcache.c:3225
void AdvanceNextFullTransactionIdPastXid(TransactionId xid)
Definition varsup.c:299
FullTransactionId GetNewTransactionId(bool isSubXact)
Definition varsup.c:68
static void pgstat_report_wait_end(void)
Definition wait_event.h:83
const char * name
static bool CommitTransactionCommandInternal(void)
Definition xact.c:3228
bool IsTransactionOrTransactionBlock(void)
Definition xact.c:5043
void SerializeTransactionState(Size maxsize, char *start_address)
Definition xact.c:5599
void ExitParallelMode(void)
Definition xact.c:1094
static TimestampTz xactStartTimestamp
Definition xact.c:282
static bool currentCommandIdUsed
Definition xact.c:270
static void AtSubCommit_Memory(void)
Definition xact.c:1677
void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
Definition xact.c:3189
static void CleanupSubTransaction(void)
Definition xact.c:5442
void BeginInternalSubTransaction(const char *name)
Definition xact.c:4748
static void AtStart_Memory(void)
Definition xact.c:1206
FullTransactionId GetCurrentFullTransactionId(void)
Definition xact.c:514
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition xact.c:3197
static XactCallbackItem * Xact_callbacks
Definition xact.c:317
void WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
Definition xact.c:3764
static TimestampTz stmtStartTimestamp
Definition xact.c:283
SubTransactionId GetCurrentSubTransactionId(void)
Definition xact.c:793
int synchronous_commit
Definition xact.c:89
void UserAbortTransactionBlock(bool chain)
Definition xact.c:4258
bool IsInTransactionBlock(bool isTopLevel)
Definition xact.c:3823
bool PrepareTransactionBlock(const char *gid)
Definition xact.c:4046
static void AtSubCleanup_Memory(void)
Definition xact.c:2064
static void StartTransaction(void)
Definition xact.c:2106
int GetCurrentTransactionNestLevel(void)
Definition xact.c:931
void xact_redo(XLogReaderState *record)
Definition xact.c:6422
TransactionId GetTopTransactionId(void)
Definition xact.c:428
static void AtSubCommit_childXids(void)
Definition xact.c:1706
static void CallSubXactCallbacks(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition xact.c:3952
void EnterParallelMode(void)
Definition xact.c:1081
static void AtAbort_ResourceOwner(void)
Definition xact.c:1958
TransactionId GetStableLatestTransactionId(void)
Definition xact.c:609
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition xact.c:3779
void UnregisterSubXactCallback(SubXactCallback callback, void *arg)
Definition xact.c:3931
bool XactDeferrable
Definition xact.c:87
static bool forceSyncCommit
Definition xact.c:295
void BeginImplicitTransactionBlock(void)
Definition xact.c:4380
static void CallXactCallbacks(XactEvent event)
Definition xact.c:3892
static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS]
Definition xact.c:260
void RequireTransactionBlock(bool isTopLevel, const char *stmtType)
Definition xact.c:3770
static void AtSubAbort_Memory(void)
Definition xact.c:1946
static SubXactCallbackItem * SubXact_callbacks
Definition xact.c:329
void DefineSavepoint(const char *name)
Definition xact.c:4427
bool DefaultXactDeferrable
Definition xact.c:86
static void CleanupTransaction(void)
Definition xact.c:3062
static int nUnreportedXids
Definition xact.c:259
static const char * TransStateAsString(TransState state)
Definition xact.c:5819
static TimestampTz xactStopTimestamp
Definition xact.c:284
bool TransactionStartedDuringRecovery(void)
Definition xact.c:1044
static void CommitSubTransaction(void)
Definition xact.c:5158
bool XactReadOnly
Definition xact.c:84
static void PushTransaction(void)
Definition xact.c:5475
static TransactionId RecordTransactionCommit(void)
Definition xact.c:1345
static char * prepareGID
Definition xact.c:290
void UnregisterXactCallback(XactCallback callback, void *arg)
Definition xact.c:3871
bool IsTransactionState(void)
Definition xact.c:389
static MemoryContext TransactionAbortContext
Definition xact.c:305
void CommandCounterIncrement(void)
Definition xact.c:1130
TransState
Definition xact.c:144
@ TRANS_INPROGRESS
Definition xact.c:147
@ TRANS_START
Definition xact.c:146
@ TRANS_COMMIT
Definition xact.c:148
@ TRANS_ABORT
Definition xact.c:149
@ TRANS_DEFAULT
Definition xact.c:145
@ TRANS_PREPARE
Definition xact.c:150
void PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
Definition xact.c:3701
static void AtCleanup_Memory(void)
Definition xact.c:2016
Size EstimateTransactionStateSpace(void)
Definition xact.c:5571
TransactionStateData * TransactionState
Definition xact.c:223
static void AtSubAbort_childXids(void)
Definition xact.c:1984
TransactionId GetTopTransactionIdIfAny(void)
Definition xact.c:443
static bool AbortCurrentTransactionInternal(void)
Definition xact.c:3522
static SubTransactionId currentSubTransactionId
Definition xact.c:268
static void AssignTransactionId(TransactionState s)
Definition xact.c:637
char TransactionBlockStatusCode(void)
Definition xact.c:5057
void RollbackAndReleaseCurrentSubTransaction(void)
Definition xact.c:4850
static int nParallelCurrentXids
Definition xact.c:128
FullTransactionId GetCurrentFullTransactionIdIfAny(void)
Definition xact.c:532
static void CommitTransaction(void)
Definition xact.c:2270
void StartTransactionCommand(void)
Definition xact.c:3112
static void PopTransaction(void)
Definition xact.c:5537
bool IsAbortedTransactionBlockState(void)
Definition xact.c:409
void ReleaseCurrentSubTransaction(void)
Definition xact.c:4822
void EndImplicitTransactionBlock(void)
Definition xact.c:4405
void StartParallelWorkerTransaction(char *tstatespace)
Definition xact.c:5670
void SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts)
Definition xact.c:861
static void AtSubAbort_ResourceOwner(void)
Definition xact.c:1971
void ReleaseSavepoint(const char *name)
Definition xact.c:4512
static TransactionStateData TopTransactionStateData
Definition xact.c:249
static FullTransactionId XactTopFullTransactionId
Definition xact.c:127
static void ShowTransactionState(const char *str)
Definition xact.c:5707
int XactIsoLevel
Definition xact.c:81
static void PrepareTransaction(void)
Definition xact.c:2559
FullTransactionId GetTopFullTransactionId(void)
Definition xact.c:485
static CommandId currentCommandId
Definition xact.c:269
XLogRecPtr XactLogCommitRecord(TimestampTz commit_time, int nsubxacts, TransactionId *subxacts, int nrels, RelFileLocator *rels, int ndroppedstats, xl_xact_stats_item *droppedstats, int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInval, int xactflags, TransactionId twophase_xid, const char *twophase_gid)
Definition xact.c:5873
void ForceSyncCommit(void)
Definition xact.c:1182
int GetTopReadOnlyTransactionNestLevel(void)
Definition xact.c:1062
static TransactionId RecordTransactionAbort(bool isSubXact)
Definition xact.c:1796
static void AtCommit_Memory(void)
Definition xact.c:1640
static void AbortSubTransaction(void)
Definition xact.c:5273
bool IsSubTransaction(void)
Definition xact.c:5098
void MarkSubxactTopXidLogged(void)
Definition xact.c:593
void SetCurrentStatementStartTimestamp(void)
Definition xact.c:916
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition xact.c:943
static void xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid, XLogRecPtr lsn, ReplOriginId origin_id)
Definition xact.c:6343
bool IsTransactionBlock(void)
Definition xact.c:5025
bool IsInParallelMode(void)
Definition xact.c:1119
int xactGetCommittedChildren(TransactionId **ptr)
Definition xact.c:5849
TransactionId GetCurrentTransactionIdIfAny(void)
Definition xact.c:473
void BeginTransactionBlock(void)
Definition xact.c:3978
static void AtStart_ResourceOwner(void)
Definition xact.c:1256
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition xact.c:881
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition xact.c:872
static const char * BlockStateAsString(TBlockState blockState)
Definition xact.c:5766
void EndParallelWorkerTransaction(void)
Definition xact.c:5695
static void AtAbort_Memory(void)
Definition xact.c:1926
void RegisterXactCallback(XactCallback callback, void *arg)
Definition xact.c:3858
void CommitTransactionCommand(void)
Definition xact.c:3210
void RollbackToSavepoint(const char *name)
Definition xact.c:4621
bool SubTransactionIsActive(SubTransactionId subxid)
Definition xact.c:807
TBlockState
Definition xact.c:160
@ TBLOCK_DEFAULT
Definition xact.c:162
@ TBLOCK_SUBABORT_END
Definition xact.c:182
@ TBLOCK_STARTED
Definition xact.c:163
@ TBLOCK_SUBCOMMIT
Definition xact.c:180
@ TBLOCK_IMPLICIT_INPROGRESS
Definition xact.c:168
@ TBLOCK_ABORT_END
Definition xact.c:172
@ TBLOCK_PREPARE
Definition xact.c:174
@ TBLOCK_ABORT_PENDING
Definition xact.c:173
@ TBLOCK_ABORT
Definition xact.c:171
@ TBLOCK_SUBRELEASE
Definition xact.c:179
@ TBLOCK_SUBBEGIN
Definition xact.c:177
@ TBLOCK_SUBABORT
Definition xact.c:181
@ TBLOCK_SUBRESTART
Definition xact.c:184
@ TBLOCK_INPROGRESS
Definition xact.c:167
@ TBLOCK_END
Definition xact.c:170
@ TBLOCK_PARALLEL_INPROGRESS
Definition xact.c:169
@ TBLOCK_SUBABORT_RESTART
Definition xact.c:185
@ TBLOCK_SUBABORT_PENDING
Definition xact.c:183
@ TBLOCK_BEGIN
Definition xact.c:166
@ TBLOCK_SUBINPROGRESS
Definition xact.c:178
void RegisterSubXactCallback(SubXactCallback callback, void *arg)
Definition xact.c:3918
FullTransactionId GetTopFullTransactionIdIfAny(void)
Definition xact.c:501
TransactionId GetCurrentTransactionId(void)
Definition xact.c:456
static void AbortTransaction(void)
Definition xact.c:2855
static void AtStart_Cache(void)
Definition xact.c:1197
static void AtSubStart_ResourceOwner(void)
Definition xact.c:1313
int DefaultXactIsoLevel
Definition xact.c:80
static void AtSubStart_Memory(void)
Definition xact.c:1284
bool xact_is_sampled
Definition xact.c:298
bool EndTransactionBlock(bool chain)
Definition xact.c:4098
bool IsSubxactTopXidLogPending(void)
Definition xact.c:561
#define SerializedTransactionStateHeaderSize
Definition xact.c:241
void AbortOutOfAnyTransaction(void)
Definition xact.c:4916
int MyXactFlags
Definition xact.c:138
static void ShowTransactionStateRec(const char *str, TransactionState s)
Definition xact.c:5719
static TransactionState CurrentTransactionState
Definition xact.c:262
void AbortCurrentTransaction(void)
Definition xact.c:3504
static void StartSubTransaction(void)
Definition xact.c:5121
static TransactionId * ParallelCurrentXids
Definition xact.c:129
bool DefaultXactReadOnly
Definition xact.c:83
TimestampTz GetCurrentTransactionStopTimestamp(void)
Definition xact.c:893
static void AtCCI_LocalCache(void)
Definition xact.c:1621
XLogRecPtr XactLogAbortRecord(TimestampTz abort_time, int nsubxacts, TransactionId *subxacts, int nrels, RelFileLocator *rels, int ndroppedstats, xl_xact_stats_item *droppedstats, int xactflags, TransactionId twophase_xid, const char *twophase_gid)
Definition xact.c:6045
void MarkCurrentTransactionIdLoggedIfAny(void)
Definition xact.c:543
static void xact_redo_commit(xl_xact_parsed_commit *parsed, TransactionId xid, XLogRecPtr lsn, ReplOriginId origin_id)
Definition xact.c:6189
CommandId GetCurrentCommandId(bool used)
Definition xact.c:831
#define XactCompletionForceSyncCommit(xinfo)
Definition xact.h:216
#define MinSizeOfXactInvals
Definition xact.h:308
void(* SubXactCallback)(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg)
Definition xact.h:149
#define MinSizeOfXactSubxacts
Definition xact.h:267
#define XLOG_XACT_COMMIT_PREPARED
Definition xact.h:173
#define XLOG_XACT_INVALIDATIONS
Definition xact.h:176
#define XACT_COMPLETION_UPDATE_RELCACHE_FILE
Definition xact.h:208
SubXactEvent
Definition xact.h:142
@ SUBXACT_EVENT_PRE_COMMIT_SUB
Definition xact.h:146
@ SUBXACT_EVENT_START_SUB
Definition xact.h:143
@ SUBXACT_EVENT_ABORT_SUB
Definition xact.h:145
@ SUBXACT_EVENT_COMMIT_SUB
Definition xact.h:144
void(* XactCallback)(XactEvent event, void *arg)
Definition xact.h:139
#define XACT_XINFO_HAS_GID
Definition xact.h:196
#define XACT_COMPLETION_FORCE_SYNC_COMMIT
Definition xact.h:209
#define XACT_XINFO_HAS_ORIGIN
Definition xact.h:194
@ SYNCHRONOUS_COMMIT_REMOTE_APPLY
Definition xact.h:76
@ SYNCHRONOUS_COMMIT_OFF
Definition xact.h:71
#define XLOG_XACT_PREPARE
Definition xact.h:171
XactEvent
Definition xact.h:128
@ XACT_EVENT_PRE_PREPARE
Definition xact.h:136
@ XACT_EVENT_COMMIT
Definition xact.h:129
@ XACT_EVENT_PARALLEL_PRE_COMMIT
Definition xact.h:135
@ XACT_EVENT_PARALLEL_COMMIT
Definition xact.h:130
@ XACT_EVENT_ABORT
Definition xact.h:131
@ XACT_EVENT_PRE_COMMIT
Definition xact.h:134
@ XACT_EVENT_PARALLEL_ABORT
Definition xact.h:132
@ XACT_EVENT_PREPARE
Definition xact.h:133
#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK
Definition xact.h:109
#define XACT_XINFO_HAS_TWOPHASE
Definition xact.h:193
#define XLOG_XACT_COMMIT
Definition xact.h:170
#define XLOG_XACT_OPMASK
Definition xact.h:180
#define MinSizeOfXactRelfileLocators
Definition xact.h:274
#define XLOG_XACT_ABORT
Definition xact.h:172
#define MinSizeOfXactStatsItems
Definition xact.h:301
#define XACT_XINFO_HAS_RELFILELOCATORS
Definition xact.h:191
#define MinSizeOfXactAbort
Definition xact.h:351
#define XACT_COMPLETION_APPLY_FEEDBACK
Definition xact.h:207
#define MinSizeOfXactAssignment
Definition xact.h:226
#define XACT_XINFO_HAS_DBINFO
Definition xact.h:189
#define XACT_FLAGS_NEEDIMMEDIATECOMMIT
Definition xact.h:115
#define XactCompletionApplyFeedback(xinfo)
Definition xact.h:212
#define XLOG_XACT_ASSIGNMENT
Definition xact.h:175
#define XACT_XINFO_HAS_INVALS
Definition xact.h:192
#define XLOG_XACT_ABORT_PREPARED
Definition xact.h:174
#define XACT_XINFO_HAS_AE_LOCKS
Definition xact.h:195
#define XLOG_XACT_HAS_INFO
Definition xact.h:183
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE
Definition xact.h:103
#define XactCompletionRelcacheInitFileInval(xinfo)
Definition xact.h:214
#define XACT_XINFO_HAS_SUBXACTS
Definition xact.h:190
#define XACT_XINFO_HAS_DROPPED_STATS
Definition xact.h:197
void ParseCommitRecord(uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *parsed)
Definition xactdesc.c:35
void ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed)
Definition xactdesc.c:141
int xidComparator(const void *arg1, const void *arg2)
Definition xid.c:152
bool RecoveryInProgress(void)
Definition xlog.c:6835
XLogRecPtr XactLastRecEnd
Definition xlog.c:261
XLogRecPtr XactLastCommitEnd
Definition xlog.c:262
void XLogFlush(XLogRecPtr record)
Definition xlog.c:2800
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition xlog.c:2630
#define XLogLogicalInfoActive()
Definition xlog.h:137
#define XLOG_INCLUDE_ORIGIN
Definition xlog.h:166
#define XLogStandbyInfoActive()
Definition xlog.h:126
uint16 ReplOriginId
Definition xlogdefs.h:69
uint64 XLogRecPtr
Definition xlogdefs.h:21
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition xloginsert.c:482
void XLogRegisterData(const void *data, uint32 len)
Definition xloginsert.c:372
void XLogSetRecordFlags(uint8 flags)
Definition xloginsert.c:464
void XLogResetInsertion(void)
Definition xloginsert.c:226
void XLogBeginInsert(void)
Definition xloginsert.c:153
#define XLogRecGetOrigin(decoder)
Definition xlogreader.h:413
#define XLogRecGetInfo(decoder)
Definition xlogreader.h:410
#define XLogRecGetData(decoder)
Definition xlogreader.h:415
#define XLogRecGetXid(decoder)
Definition xlogreader.h:412
#define XLogRecHasAnyBlockRefs(decoder)
Definition xlogreader.h:417
#define XLR_SPECIAL_REL_UPDATE
Definition xlogrecord.h:82
void XLogRequestWalReceiverReply(void)
HotStandbyState standbyState
Definition xlogutils.c:53
@ STANDBY_DISABLED
Definition xlogutils.h:52
@ STANDBY_INITIALIZED
Definition xlogutils.h:53
void WaitLSNCleanup(void)
Definition xlogwait.c:366

Typedef Documentation

◆ SerializedTransactionState

◆ SubXactCallbackItem

◆ TBlockState

◆ TransactionState

Definition at line 223 of file xact.c.

◆ TransactionStateData

◆ TransState

◆ XactCallbackItem

Enumeration Type Documentation

◆ TBlockState

Enumerator
TBLOCK_DEFAULT 
TBLOCK_STARTED 
TBLOCK_BEGIN 
TBLOCK_INPROGRESS 
TBLOCK_IMPLICIT_INPROGRESS 
TBLOCK_PARALLEL_INPROGRESS 
TBLOCK_END 
TBLOCK_ABORT 
TBLOCK_ABORT_END 
TBLOCK_ABORT_PENDING 
TBLOCK_PREPARE 
TBLOCK_SUBBEGIN 
TBLOCK_SUBINPROGRESS 
TBLOCK_SUBRELEASE 
TBLOCK_SUBCOMMIT 
TBLOCK_SUBABORT 
TBLOCK_SUBABORT_END 
TBLOCK_SUBABORT_PENDING 
TBLOCK_SUBRESTART 
TBLOCK_SUBABORT_RESTART 

Definition at line 159 of file xact.c.

160{
161 /* not-in-transaction-block states */
162 TBLOCK_DEFAULT, /* idle */
163 TBLOCK_STARTED, /* running single-query transaction */
164
165 /* transaction block states */
166 TBLOCK_BEGIN, /* starting transaction block */
167 TBLOCK_INPROGRESS, /* live transaction */
168 TBLOCK_IMPLICIT_INPROGRESS, /* live transaction after implicit BEGIN */
169 TBLOCK_PARALLEL_INPROGRESS, /* live transaction inside parallel worker */
170 TBLOCK_END, /* COMMIT received */
171 TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
172 TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
173 TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
174 TBLOCK_PREPARE, /* live xact, PREPARE received */
175
176 /* subtransaction states */
177 TBLOCK_SUBBEGIN, /* starting a subtransaction */
178 TBLOCK_SUBINPROGRESS, /* live subtransaction */
179 TBLOCK_SUBRELEASE, /* RELEASE received */
180 TBLOCK_SUBCOMMIT, /* COMMIT received while TBLOCK_SUBINPROGRESS */
181 TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
182 TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
183 TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
184 TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
185 TBLOCK_SUBABORT_RESTART, /* failed subxact, ROLLBACK TO received */

◆ TransState

Enumerator
TRANS_DEFAULT 
TRANS_START 
TRANS_INPROGRESS 
TRANS_COMMIT 
TRANS_ABORT 
TRANS_PREPARE 

Definition at line 143 of file xact.c.

144{
145 TRANS_DEFAULT, /* idle */
146 TRANS_START, /* transaction starting */
147 TRANS_INPROGRESS, /* inside a valid transaction */
148 TRANS_COMMIT, /* commit in progress */
149 TRANS_ABORT, /* abort in progress */
150 TRANS_PREPARE, /* prepare in progress */
151} TransState;

Function Documentation

◆ AbortCurrentTransaction()

void AbortCurrentTransaction ( void  )

Definition at line 3504 of file xact.c.

3505{
3506 /*
3507 * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3508 * done.
3509 */
3511 {
3512 }
3513}

References AbortCurrentTransactionInternal().

Referenced by _SPI_commit(), _SPI_rollback(), AutoVacLauncherMain(), pa_stream_abort(), PostgresMain(), ReorderBufferImmediateInvalidation(), ReorderBufferProcessTXN(), and SnapBuildClearExportedSnapshot().

◆ AbortCurrentTransactionInternal()

static bool AbortCurrentTransactionInternal ( void  )
static

Definition at line 3522 of file xact.c.

3523{
3525
3526 switch (s->blockState)
3527 {
3528 case TBLOCK_DEFAULT:
3529 if (s->state == TRANS_DEFAULT)
3530 {
3531 /* we are idle, so nothing to do */
3532 }
3533 else
3534 {
3535 /*
3536 * We can get here after an error during transaction start
3537 * (state will be TRANS_START). Need to clean up the
3538 * incompletely started transaction. First, adjust the
3539 * low-level state to suppress warning message from
3540 * AbortTransaction.
3541 */
3542 if (s->state == TRANS_START)
3546 }
3547 break;
3548
3549 /*
3550 * If we aren't in a transaction block, we just do the basic abort
3551 * & cleanup transaction. For this purpose, we treat an implicit
3552 * transaction block as if it were a simple statement.
3553 */
3554 case TBLOCK_STARTED:
3559 break;
3560
3561 /*
3562 * If we are in TBLOCK_BEGIN it means something screwed up right
3563 * after reading "BEGIN TRANSACTION". We assume that the user
3564 * will interpret the error as meaning the BEGIN failed to get him
3565 * into a transaction block, so we should abort and return to idle
3566 * state.
3567 */
3568 case TBLOCK_BEGIN:
3572 break;
3573
3574 /*
3575 * We are somewhere in a transaction block and we've gotten a
3576 * failure, so we abort the transaction and set up the persistent
3577 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3578 */
3579 case TBLOCK_INPROGRESS:
3583 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3584 break;
3585
3586 /*
3587 * Here, we failed while trying to COMMIT. Clean up the
3588 * transaction and return to idle state (we do not want to stay in
3589 * the transaction).
3590 */
3591 case TBLOCK_END:
3595 break;
3596
3597 /*
3598 * Here, we are already in an aborted transaction state and are
3599 * waiting for a ROLLBACK, but for some reason we failed again! So
3600 * we just remain in the abort state.
3601 */
3602 case TBLOCK_ABORT:
3603 case TBLOCK_SUBABORT:
3604 break;
3605
3606 /*
3607 * We are in a failed transaction and we got the ROLLBACK command.
3608 * We have already aborted, we just need to cleanup and go to idle
3609 * state.
3610 */
3611 case TBLOCK_ABORT_END:
3614 break;
3615
3616 /*
3617 * We are in a live transaction and we got a ROLLBACK command.
3618 * Abort, cleanup, go to idle state.
3619 */
3624 break;
3625
3626 /*
3627 * Here, we failed while trying to PREPARE. Clean up the
3628 * transaction and return to idle state (we do not want to stay in
3629 * the transaction).
3630 */
3631 case TBLOCK_PREPARE:
3635 break;
3636
3637 /*
3638 * We got an error inside a subtransaction. Abort just the
3639 * subtransaction, and go to the persistent SUBABORT state until
3640 * we get ROLLBACK.
3641 */
3645 break;
3646
3647 /*
3648 * If we failed while trying to create a subtransaction, clean up
3649 * the broken subtransaction and abort the parent. The same
3650 * applies if we get a failure while ending a subtransaction. As
3651 * we need to abort the parent, return false to request the caller
3652 * to do the next iteration.
3653 */
3654 case TBLOCK_SUBBEGIN:
3655 case TBLOCK_SUBRELEASE:
3656 case TBLOCK_SUBCOMMIT:
3658 case TBLOCK_SUBRESTART:
3661 return false;
3662
3663 /*
3664 * Same as above, except the Abort() was already done.
3665 */
3669 return false;
3670 }
3671
3672 /* Done, no more iterations required */
3673 return true;
3674}

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

◆ AbortOutOfAnyTransaction()

void AbortOutOfAnyTransaction ( void  )

Definition at line 4916 of file xact.c.

4917{
4919
4920 /* Ensure we're not running in a doomed memory context */
4922
4923 /*
4924 * Get out of any transaction or nested transaction
4925 */
4926 do
4927 {
4928 switch (s->blockState)
4929 {
4930 case TBLOCK_DEFAULT:
4931 if (s->state == TRANS_DEFAULT)
4932 {
4933 /* Not in a transaction, do nothing */
4934 }
4935 else
4936 {
4937 /*
4938 * We can get here after an error during transaction start
4939 * (state will be TRANS_START). Need to clean up the
4940 * incompletely started transaction. First, adjust the
4941 * low-level state to suppress warning message from
4942 * AbortTransaction.
4943 */
4944 if (s->state == TRANS_START)
4948 }
4949 break;
4950 case TBLOCK_STARTED:
4951 case TBLOCK_BEGIN:
4952 case TBLOCK_INPROGRESS:
4955 case TBLOCK_END:
4957 case TBLOCK_PREPARE:
4958 /* In a transaction, so clean up */
4962 break;
4963 case TBLOCK_ABORT:
4964 case TBLOCK_ABORT_END:
4965
4966 /*
4967 * AbortTransaction is already done, still need Cleanup.
4968 * However, if we failed partway through running ROLLBACK,
4969 * there will be an active portal running that command, which
4970 * we need to shut down before doing CleanupTransaction.
4971 */
4975 break;
4976
4977 /*
4978 * In a subtransaction, so clean it up and abort parent too
4979 */
4980 case TBLOCK_SUBBEGIN:
4982 case TBLOCK_SUBRELEASE:
4983 case TBLOCK_SUBCOMMIT:
4985 case TBLOCK_SUBRESTART:
4988 s = CurrentTransactionState; /* changed by pop */
4989 break;
4990
4991 case TBLOCK_SUBABORT:
4994 /* As above, but AbortSubTransaction already done */
4995 if (s->curTransactionOwner)
4996 {
4997 /* As in TBLOCK_ABORT, might have a live portal to zap */
5002 }
5004 s = CurrentTransactionState; /* changed by pop */
5005 break;
5006 }
5007 } while (s->blockState != TBLOCK_DEFAULT);
5008
5009 /* Should be out of all subxacts now */
5010 Assert(s->parent == NULL);
5011
5012 /*
5013 * Revert to TopMemoryContext, to ensure we exit in a well-defined state
5014 * whether there were any transactions to close or not. (Callers that
5015 * don't intend to exit soon should switch to some other context to avoid
5016 * long-term memory leaks.)
5017 */
5019}

References AbortSubTransaction(), AbortTransaction(), Assert, AtAbort_Memory(), AtAbort_Portals(), AtSubAbort_Portals(), TransactionStateData::blockState, CleanupSubTransaction(), CleanupTransaction(), CurrentTransactionState, TransactionStateData::curTransactionOwner, fb(), MemoryContextSwitchTo(), 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, TopMemoryContext, TRANS_DEFAULT, TRANS_INPROGRESS, and TRANS_START.

Referenced by DisableSubscriptionAndExit(), do_autovacuum(), perform_work_item(), RemoveTempRelationsCallback(), ShutdownPostgres(), start_apply(), start_sequence_sync(), and start_table_sync().

◆ AbortSubTransaction()

static void AbortSubTransaction ( void  )
static

Definition at line 5273 of file xact.c.

5274{
5276
5277 /* Prevent cancel/die interrupt while cleaning up */
5279
5280 /* Make sure we have a valid memory context and resource owner */
5283
5284 /*
5285 * Release any LW locks we might be holding as quickly as possible.
5286 * (Regular locks, however, must be held till we finish aborting.)
5287 * Releasing LW locks is critical since we might try to grab them again
5288 * while cleaning up!
5289 *
5290 * FIXME This may be incorrect --- Are there some locks we should keep?
5291 * Buffer locks, for example? I don't think so but I'm not sure.
5292 */
5294
5295 /*
5296 * Cleanup waiting for LSN if any.
5297 */
5299
5302
5304
5305 UnlockBuffers();
5306
5307 /* Reset WAL record construction state */
5309
5310 /* Cancel condition variable sleep */
5312
5313 /*
5314 * Also clean up any open wait for lock, since the lock manager will choke
5315 * if we try to wait for another lock before doing this.
5316 */
5318
5319 /*
5320 * If any timeout events are still active, make sure the timeout interrupt
5321 * is scheduled. This covers possible loss of a timeout interrupt due to
5322 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5323 * We delay this till after LockErrorCleanup so that we don't uselessly
5324 * reschedule lock or deadlock check timeouts.
5325 */
5327
5328 /*
5329 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5330 * handler. We do this fairly early in the sequence so that the timeout
5331 * infrastructure will be functional if needed while aborting.
5332 */
5334
5335 /*
5336 * check the current transaction state
5337 */
5338 ShowTransactionState("AbortSubTransaction");
5339
5340 if (s->state != TRANS_INPROGRESS)
5341 elog(WARNING, "AbortSubTransaction while in %s state",
5343
5344 s->state = TRANS_ABORT;
5345
5346 /*
5347 * Reset user ID which might have been changed transiently. (See notes in
5348 * AbortTransaction.)
5349 */
5351
5352 /* Forget about any active REINDEX. */
5354
5355 /* Reset logical streaming state. */
5357
5358 /*
5359 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5360 * exports are not supported in subtransactions.
5361 */
5362
5363 /*
5364 * If this subxact has started any unfinished parallel operation, clean up
5365 * its workers and exit parallel mode. Don't warn about leaked resources.
5366 */
5368 s->parallelModeLevel = 0;
5369
5370 /*
5371 * We can skip all this stuff if the subxact failed before creating a
5372 * ResourceOwner...
5373 */
5374 if (s->curTransactionOwner)
5375 {
5384
5385 /* Advertise the fact that we aborted in pg_xact. */
5387
5388 /* Post-abort cleanup */
5391
5394
5397 false, false);
5398
5399 AtEOXact_Aio(false);
5403 AtEOSubXact_Inval(false);
5406 false, false);
5409 false, false);
5411
5412 AtEOXact_GUC(false, s->gucNestLevel);
5423 }
5424
5425 /*
5426 * Restore the upper transaction's read-only state, too. This should be
5427 * redundant with GUC's cleanup but we may as well do it for consistency
5428 * with the commit case.
5429 */
5431
5433}

References AfterTriggerEndSubXact(), AtEOSubXact_Files(), AtEOSubXact_HashTables(), AtEOSubXact_Inval(), AtEOSubXact_LargeObject(), AtEOSubXact_Namespace(), AtEOSubXact_on_commit_actions(), AtEOSubXact_Parallel(), AtEOSubXact_PgStat(), AtEOSubXact_RelationCache(), AtEOSubXact_SPI(), AtEOSubXact_TypeCache(), AtEOXact_Aio(), AtEOXact_GUC(), AtSubAbort_childXids(), AtSubAbort_Memory(), AtSubAbort_Notify(), AtSubAbort_Portals(), AtSubAbort_ResourceOwner(), AtSubAbort_smgr(), AtSubAbort_Snapshot(), CallSubXactCallbacks(), ConditionVariableCancelSleep(), CurrentTransactionState, TransactionStateData::curTransactionOwner, elog, fb(), TransactionStateData::fullTransactionId, FullTransactionIdIsValid, TransactionStateData::gucNestLevel, HOLD_INTERRUPTS, LockErrorCleanup(), LWLockReleaseAll(), TransactionStateData::nestingLevel, TransactionStateData::parallelModeLevel, TransactionStateData::parent, pgaio_error_cleanup(), pgstat_progress_end_command(), pgstat_report_wait_end(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, TransactionStateData::prevXactReadOnly, RecordTransactionAbort(), reschedule_timeouts(), ResetLogicalStreamingState(), ResetReindexState(), RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerRelease(), RESUME_INTERRUPTS, SetUserIdAndSecContext(), ShowTransactionState(), TransactionStateData::state, TransactionStateData::subTransactionId, SUBXACT_EVENT_ABORT_SUB, TRANS_ABORT, TRANS_INPROGRESS, TransStateAsString(), UnBlockSig, UnlockBuffers(), WaitLSNCleanup(), WARNING, XactReadOnly, and XLogResetInsertion().

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), CommitTransactionCommandInternal(), and RollbackAndReleaseCurrentSubTransaction().

◆ AbortTransaction()

static void AbortTransaction ( void  )
static

Definition at line 2855 of file xact.c.

2856{
2859 bool is_parallel_worker;
2860
2861 /* Prevent cancel/die interrupt while cleaning up */
2863
2864 /* Disable transaction timeout */
2865 if (TransactionTimeout > 0)
2867
2868 /* Make sure we have a valid memory context and resource owner */
2871
2872 /*
2873 * Release any LW locks we might be holding as quickly as possible.
2874 * (Regular locks, however, must be held till we finish aborting.)
2875 * Releasing LW locks is critical since we might try to grab them again
2876 * while cleaning up!
2877 */
2879
2880 /*
2881 * Cleanup waiting for LSN if any.
2882 */
2884
2885 /* Clear wait information and command progress indicator */
2888
2890
2891 /* Clean up buffer content locks, too */
2892 UnlockBuffers();
2893
2894 /* Reset WAL record construction state */
2896
2897 /* Cancel condition variable sleep */
2899
2900 /*
2901 * Also clean up any open wait for lock, since the lock manager will choke
2902 * if we try to wait for another lock before doing this.
2903 */
2905
2906 /*
2907 * If any timeout events are still active, make sure the timeout interrupt
2908 * is scheduled. This covers possible loss of a timeout interrupt due to
2909 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2910 * We delay this till after LockErrorCleanup so that we don't uselessly
2911 * reschedule lock or deadlock check timeouts.
2912 */
2914
2915 /*
2916 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2917 * handler. We do this fairly early in the sequence so that the timeout
2918 * infrastructure will be functional if needed while aborting.
2919 */
2921
2922 /*
2923 * check the current transaction state
2924 */
2926 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2927 elog(WARNING, "AbortTransaction while in %s state",
2929 Assert(s->parent == NULL);
2930
2931 /*
2932 * set the current transaction state information appropriately during the
2933 * abort processing
2934 */
2935 s->state = TRANS_ABORT;
2936
2937 /*
2938 * Reset user ID which might have been changed transiently. We need this
2939 * to clean up in case control escaped out of a SECURITY DEFINER function
2940 * or other local change of CurrentUserId; therefore, the prior value of
2941 * SecurityRestrictionContext also needs to be restored.
2942 *
2943 * (Note: it is not necessary to restore session authorization or role
2944 * settings here because those can only be changed via GUC, and GUC will
2945 * take care of rolling them back if need be.)
2946 */
2948
2949 /* Forget about any active REINDEX. */
2951
2952 /* Reset logical streaming state. */
2954
2955 /* Reset snapshot export state. */
2957
2958 /*
2959 * If this xact has started any unfinished parallel operation, clean up
2960 * its workers and exit parallel mode. Don't warn about leaked resources.
2961 */
2962 AtEOXact_Parallel(false);
2963 s->parallelModeLevel = 0;
2964 s->parallelChildXact = false; /* should be false already */
2965
2966 /*
2967 * do abort processing
2968 */
2969 AfterTriggerEndXact(false); /* 'false' means it's abort */
2972 AtEOXact_LargeObject(false);
2976
2977 /*
2978 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2979 * far as assigning an XID to advertise). But if we're inside a parallel
2980 * worker, skip this; the user backend must be the one to write the abort
2981 * record.
2982 */
2983 if (!is_parallel_worker)
2985 else
2986 {
2988
2989 /*
2990 * Since the parallel leader won't get our value of XactLastRecEnd in
2991 * this case, we nudge WAL-writer ourselves in this case. See related
2992 * comments in RecordTransactionAbort for why this matters.
2993 */
2995 }
2996
2998
2999 /*
3000 * Let others know about no transaction in progress by me. Note that this
3001 * must be done _before_ releasing locks we hold and _after_
3002 * RecordTransactionAbort.
3003 */
3005
3006 /*
3007 * Post-abort cleanup. See notes in CommitTransaction() concerning
3008 * ordering. We can skip all of it if the transaction failed before
3009 * creating a resource owner.
3010 */
3012 {
3015 else
3017
3020 false, true);
3021 AtEOXact_Aio(false);
3022 AtEOXact_Buffers(false);
3025 AtEOXact_Inval(false);
3029 false, true);
3032 false, true);
3033 smgrDoPendingDeletes(false);
3034
3035 AtEOXact_GUC(false, 1);
3036 AtEOXact_SPI(false);
3037 AtEOXact_Enum();
3040 AtEOXact_SMgr();
3041 AtEOXact_Files(false);
3043 AtEOXact_HashTables(false);
3044 AtEOXact_RI(false);
3050 }
3051
3052 /*
3053 * State remains TRANS_ABORT until CleanupTransaction().
3054 */
3056}

References AfterTriggerEndXact(), Assert, AtAbort_Memory(), AtAbort_Notify(), AtAbort_Portals(), AtAbort_ResourceOwner(), AtAbort_Twophase(), AtEOXact_Aio(), AtEOXact_ApplyLauncher(), AtEOXact_Buffers(), AtEOXact_ComboCid(), AtEOXact_Enum(), AtEOXact_Files(), AtEOXact_GUC(), AtEOXact_HashTables(), AtEOXact_Inval(), AtEOXact_LargeObject(), AtEOXact_LogicalCtl(), AtEOXact_LogicalRepWorkers(), AtEOXact_MultiXact(), AtEOXact_Namespace(), AtEOXact_on_commit_actions(), AtEOXact_Parallel(), AtEOXact_PgStat(), AtEOXact_RelationCache(), AtEOXact_RelationMap(), AtEOXact_RI(), AtEOXact_SMgr(), AtEOXact_SPI(), AtEOXact_TypeCache(), TransactionStateData::blockState, CallXactCallbacks(), ConditionVariableCancelSleep(), CurrentTransactionState, disable_timeout(), elog, fb(), HOLD_INTERRUPTS, InvalidTransactionId, LockErrorCleanup(), LWLockReleaseAll(), PGPROC::lxid, MyProc, TransactionStateData::nestingLevel, TransactionStateData::parallelChildXact, TransactionStateData::parallelModeLevel, TransactionStateData::parent, pgaio_error_cleanup(), pgstat_progress_end_command(), pgstat_report_wait_end(), pgstat_report_xact_timestamp(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, ProcArrayEndTransaction(), RecordTransactionAbort(), reschedule_timeouts(), ResetLogicalStreamingState(), ResetReindexState(), RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerRelease(), RESUME_INTERRUPTS, SetUserIdAndSecContext(), smgrDoPendingDeletes(), smgrDoPendingSyncs(), SnapBuildResetExportedSnapshotState(), TransactionStateData::state, TBLOCK_PARALLEL_INPROGRESS, TopTransactionResourceOwner, TRANS_ABORT, TRANS_INPROGRESS, TRANS_PREPARE, TRANSACTION_TIMEOUT, TransactionTimeout, TransStateAsString(), UnBlockSig, UnlockBuffers(), PGPROC::vxid, WaitLSNCleanup(), WARNING, XACT_EVENT_ABORT, XACT_EVENT_PARALLEL_ABORT, XactLastRecEnd, XLogResetInsertion(), and XLogSetAsyncXactLSN().

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), and CommitTransactionCommandInternal().

◆ AssignTransactionId()

static void AssignTransactionId ( TransactionState  s)
static

Definition at line 637 of file xact.c.

638{
639 bool isSubXact = (s->parent != NULL);
641 bool log_unknown_top = false;
642
643 /* Assert that caller didn't screw up */
646
647 /*
648 * Workers synchronize transaction state at the beginning of each parallel
649 * operation, so we can't account for new XIDs at this point.
650 */
654 errmsg("cannot assign transaction IDs during a parallel operation")));
655
656 /*
657 * Ensure parent(s) have XIDs, so that a child always has an XID later
658 * than its parent. Mustn't recurse here, or we might get a stack
659 * overflow if we're at the bottom of a huge stack of subtransactions none
660 * of which have XIDs yet.
661 */
663 {
665 TransactionState *parents;
666 size_t parentOffset = 0;
667
670 {
671 parents[parentOffset++] = p;
672 p = p->parent;
673 }
674
675 /*
676 * This is technically a recursive call, but the recursion will never
677 * be more than one layer deep.
678 */
679 while (parentOffset != 0)
680 AssignTransactionId(parents[--parentOffset]);
681
682 pfree(parents);
683 }
684
685 /*
686 * When effective_wal_level is logical, guarantee that a subtransaction's
687 * xid can only be seen in the WAL stream if its toplevel xid has been
688 * logged before. If necessary we log an xact_assignment record with fewer
689 * than PGPROC_MAX_CACHED_SUBXIDS. Note that it is fine if didLogXid isn't
690 * set for a transaction even though it appears in a WAL record, we just
691 * might superfluously log something. That can happen when an xid is
692 * included somewhere inside a wal record, but not in XLogRecord->xl_xid,
693 * like in xl_standby_locks.
694 */
697 log_unknown_top = true;
698
699 /*
700 * Generate a new FullTransactionId and record its xid in PGPROC and
701 * pg_subtrans.
702 *
703 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
704 * shared storage other than PGPROC; because if there's no room for it in
705 * PGPROC, the subtrans entry is needed to ensure that other backends see
706 * the Xid as "running". See GetNewTransactionId.
707 */
709 if (!isSubXact)
711
712 if (isSubXact)
715
716 /*
717 * If it's a top-level transaction, the predicate locking system needs to
718 * be told about it too.
719 */
720 if (!isSubXact)
722
723 /*
724 * Acquire lock on the transaction XID. (We assume this cannot block.) We
725 * have to ensure that the lock is assigned to the transaction's own
726 * ResourceOwner.
727 */
730
732
734
735 /*
736 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
737 * top-level transaction we issue a WAL record for the assignment. We
738 * include the top-level xid and all the subxids that have not yet been
739 * reported using XLOG_XACT_ASSIGNMENT records.
740 *
741 * This is required to limit the amount of shared memory required in a hot
742 * standby server to keep track of in-progress XIDs. See notes for
743 * RecordKnownAssignedTransactionIds().
744 *
745 * We don't keep track of the immediate parent of each subxid, only the
746 * top-level transaction that each subxact belongs to. This is correct in
747 * recovery only because aborted subtransactions are separately WAL
748 * logged.
749 *
750 * This is correct even for the case where several levels above us didn't
751 * have an xid assigned as we recursed up to them beforehand.
752 */
754 {
757
758 /*
759 * ensure this test matches similar one in
760 * RecoverPreparedTransactions()
761 */
764 {
766
767 /*
768 * xtop is always set by now because we recurse up transaction
769 * stack to the highest unassigned xid and then come back down
770 */
773 xlrec.nsubxacts = nUnreportedXids;
774
779
781
782 nUnreportedXids = 0;
783 /* mark top, not current xact as having been logged */
785 }
786 }
787}

References Assert, AssignTransactionId(), CurrentResourceOwner, TransactionStateData::curTransactionOwner, TransactionStateData::didLogXid, ereport, errcode(), errmsg, ERROR, fb(), TransactionStateData::fullTransactionId, FullTransactionIdIsValid, GetNewTransactionId(), GetTopTransactionId(), IsInParallelMode(), IsParallelWorker, MinSizeOfXactAssignment, TransactionStateData::nestingLevel, nUnreportedXids, palloc_array, TransactionStateData::parent, pfree(), PGPROC_MAX_CACHED_SUBXIDS, RegisterPredicateLockingXid(), TransactionStateData::state, SubTransSetParent(), TopTransactionStateData, TRANS_INPROGRESS, TransactionIdIsValid, unreportedXids, XactLockTableInsert(), XactTopFullTransactionId, XidFromFullTransactionId, XLOG_XACT_ASSIGNMENT, XLogBeginInsert(), XLogInsert(), XLogLogicalInfoActive, XLogRegisterData(), XLogStandbyInfoActive, and xl_xact_assignment::xtop.

Referenced by AssignTransactionId(), GetCurrentFullTransactionId(), GetCurrentTransactionId(), GetTopFullTransactionId(), and GetTopTransactionId().

◆ AtAbort_Memory()

static void AtAbort_Memory ( void  )
static

Definition at line 1926 of file xact.c.

1927{
1928 /*
1929 * Switch into TransactionAbortContext, which should have some free space
1930 * even if nothing else does. We'll work in this context until we've
1931 * finished cleaning up.
1932 *
1933 * It is barely possible to get here when we've not been able to create
1934 * TransactionAbortContext yet; if so use TopMemoryContext.
1935 */
1938 else
1940}

References fb(), MemoryContextSwitchTo(), TopMemoryContext, and TransactionAbortContext.

Referenced by AbortOutOfAnyTransaction(), and AbortTransaction().

◆ AtAbort_ResourceOwner()

static void AtAbort_ResourceOwner ( void  )
static

Definition at line 1958 of file xact.c.

1959{
1960 /*
1961 * Make sure we have a valid ResourceOwner, if possible (else it will be
1962 * NULL, which is OK)
1963 */
1965}

References CurrentResourceOwner, and TopTransactionResourceOwner.

Referenced by AbortTransaction().

◆ AtCCI_LocalCache()

static void AtCCI_LocalCache ( void  )
static

Definition at line 1621 of file xact.c.

1622{
1623 /*
1624 * Make any pending relation map changes visible. We must do this before
1625 * processing local sinval messages, so that the map changes will get
1626 * reflected into the relcache when relcache invals are processed.
1627 */
1629
1630 /*
1631 * Make catalog changes visible to me for the next command.
1632 */
1634}

References AtCCI_RelationMap(), and CommandEndInvalidationMessages().

Referenced by CommandCounterIncrement().

◆ AtCleanup_Memory()

static void AtCleanup_Memory ( void  )
static

Definition at line 2016 of file xact.c.

2017{
2019
2020 /* Should be at top level */
2021 Assert(s->parent == NULL);
2022
2023 /*
2024 * Return to the memory context that was current before we started the
2025 * transaction. (In principle, this could not be any of the contexts we
2026 * are about to delete. If it somehow is, assertions in mcxt.c will
2027 * complain.)
2028 */
2030
2031 /*
2032 * Clear the special abort context for next time.
2033 */
2036
2037 /*
2038 * Release all transaction-local memory, the same as in AtCommit_Memory,
2039 * except we must cope with the possibility that we didn't get as far as
2040 * creating TopTransactionContext.
2041 */
2044
2045 /*
2046 * Clear these pointers as a pro-forma matter. (Notionally, while
2047 * TopTransactionContext still exists, it's currently not associated with
2048 * this TransactionState struct.)
2049 */
2052}

References Assert, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, fb(), MemoryContextReset(), MemoryContextSwitchTo(), TransactionStateData::parent, TransactionStateData::priorContext, TopTransactionContext, and TransactionAbortContext.

Referenced by CleanupTransaction().

◆ AtCommit_Memory()

static void AtCommit_Memory ( void  )
static

Definition at line 1640 of file xact.c.

1641{
1643
1644 /*
1645 * Return to the memory context that was current before we started the
1646 * transaction. (In principle, this could not be any of the contexts we
1647 * are about to delete. If it somehow is, assertions in mcxt.c will
1648 * complain.)
1649 */
1651
1652 /*
1653 * Release all transaction-local memory. TopTransactionContext survives
1654 * but becomes empty; any sub-contexts go away.
1655 */
1658
1659 /*
1660 * Clear these pointers as a pro-forma matter. (Notionally, while
1661 * TopTransactionContext still exists, it's currently not associated with
1662 * this TransactionState struct.)
1663 */
1666}

References Assert, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, fb(), MemoryContextReset(), MemoryContextSwitchTo(), TransactionStateData::priorContext, and TopTransactionContext.

Referenced by CommitTransaction(), and PrepareTransaction().

◆ AtStart_Cache()

static void AtStart_Cache ( void  )
static

Definition at line 1197 of file xact.c.

1198{
1200}

References AcceptInvalidationMessages().

Referenced by StartTransaction().

◆ AtStart_Memory()

static void AtStart_Memory ( void  )
static

Definition at line 1206 of file xact.c.

1207{
1209
1210 /*
1211 * Remember the memory context that was active prior to transaction start.
1212 */
1214
1215 /*
1216 * If this is the first time through, create a private context for
1217 * AbortTransaction to work in. By reserving some space now, we can
1218 * insulate AbortTransaction from out-of-memory scenarios. Like
1219 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1220 * size, so that space will be reserved immediately.
1221 */
1225 "TransactionAbortContext",
1226 32 * 1024,
1227 32 * 1024,
1228 32 * 1024);
1229
1230 /*
1231 * Likewise, if this is the first time through, create a top-level context
1232 * for transaction-local data. This context will be reset at transaction
1233 * end, and then re-used in later transactions.
1234 */
1238 "TopTransactionContext",
1240
1241 /*
1242 * In a top-level transaction, CurTransactionContext is the same as
1243 * TopTransactionContext.
1244 */
1247
1248 /* Make the CurTransactionContext active. */
1250}

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, CurrentMemoryContext, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, fb(), MemoryContextSwitchTo(), TransactionStateData::priorContext, TopMemoryContext, TopTransactionContext, and TransactionAbortContext.

Referenced by StartTransaction().

◆ AtStart_ResourceOwner()

static void AtStart_ResourceOwner ( void  )
static

Definition at line 1256 of file xact.c.

1257{
1259
1260 /*
1261 * We shouldn't have a transaction resource owner already.
1262 */
1264
1265 /*
1266 * Create a toplevel resource owner for the transaction.
1267 */
1268 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1269
1273}

References Assert, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, fb(), ResourceOwnerCreate(), and TopTransactionResourceOwner.

Referenced by StartTransaction().

◆ AtSubAbort_childXids()

static void AtSubAbort_childXids ( void  )
static

Definition at line 1984 of file xact.c.

1985{
1987
1988 /*
1989 * We keep the child-XID arrays in TopTransactionContext (see
1990 * AtSubCommit_childXids). This means we'd better free the array
1991 * explicitly at abort to avoid leakage.
1992 */
1993 if (s->childXids != NULL)
1994 pfree(s->childXids);
1995 s->childXids = NULL;
1996 s->nChildXids = 0;
1997 s->maxChildXids = 0;
1998
1999 /*
2000 * We could prune the unreportedXids array here. But we don't bother. That
2001 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
2002 * would likely introduce more CPU time into the more common paths, so we
2003 * choose not to do that.
2004 */
2005}

References TransactionStateData::childXids, CurrentTransactionState, fb(), TransactionStateData::maxChildXids, TransactionStateData::nChildXids, and pfree().

Referenced by AbortSubTransaction().

◆ AtSubAbort_Memory()

static void AtSubAbort_Memory ( void  )
static

◆ AtSubAbort_ResourceOwner()

static void AtSubAbort_ResourceOwner ( void  )
static

Definition at line 1971 of file xact.c.

1972{
1974
1975 /* Make sure we have a valid ResourceOwner */
1977}

References CurrentResourceOwner, CurrentTransactionState, and TransactionStateData::curTransactionOwner.

Referenced by AbortSubTransaction().

◆ AtSubCleanup_Memory()

static void AtSubCleanup_Memory ( void  )
static

Definition at line 2064 of file xact.c.

2065{
2067
2068 Assert(s->parent != NULL);
2069
2070 /*
2071 * Return to the memory context that was current before we started the
2072 * subtransaction. (In principle, this could not be any of the contexts
2073 * we are about to delete. If it somehow is, assertions in mcxt.c will
2074 * complain.)
2075 */
2077
2078 /* Update CurTransactionContext (might not be same as priorContext) */
2080
2081 /*
2082 * Clear the special abort context for next time.
2083 */
2086
2087 /*
2088 * Delete the subxact local memory contexts. Its CurTransactionContext can
2089 * go too (note this also kills CurTransactionContexts from any children
2090 * of the subxact).
2091 */
2092 if (s->curTransactionContext)
2095}

References Assert, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, fb(), MemoryContextDelete(), MemoryContextReset(), MemoryContextSwitchTo(), TransactionStateData::parent, TransactionStateData::priorContext, and TransactionAbortContext.

Referenced by CleanupSubTransaction().

◆ AtSubCommit_childXids()

static void AtSubCommit_childXids ( void  )
static

Definition at line 1706 of file xact.c.

1707{
1709 int new_nChildXids;
1710
1711 Assert(s->parent != NULL);
1712
1713 /*
1714 * The parent childXids array will need to hold my XID and all my
1715 * childXids, in addition to the XIDs already there.
1716 */
1718
1719 /* Allocate or enlarge the parent array if necessary */
1721 {
1722 int new_maxChildXids;
1724
1725 /*
1726 * Make it 2x what's needed right now, to avoid having to enlarge it
1727 * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1728 * is what ensures that we don't need to worry about integer overflow
1729 * here or in the calculation of new_nChildXids.)
1730 */
1732 (int) (MaxAllocSize / sizeof(TransactionId)));
1733
1735 ereport(ERROR,
1737 errmsg("maximum number of committed subtransactions (%d) exceeded",
1738 (int) (MaxAllocSize / sizeof(TransactionId)))));
1739
1740 /*
1741 * We keep the child-XID arrays in TopTransactionContext; this avoids
1742 * setting up child-transaction contexts for what might be just a few
1743 * bytes of grandchild XIDs.
1744 */
1745 if (s->parent->childXids == NULL)
1749 else
1752
1755 }
1756
1757 /*
1758 * Copy all my XIDs to parent's array.
1759 *
1760 * Note: We rely on the fact that the XID of a child always follows that
1761 * of its parent. By copying the XID of this subtransaction before the
1762 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1763 * all XIDs already in the array belong to subtransactions started and
1764 * subcommitted before us, so their XIDs must precede ours.
1765 */
1767
1768 if (s->nChildXids > 0)
1769 memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1770 s->childXids,
1771 s->nChildXids * sizeof(TransactionId));
1772
1774
1775 /* Release child's array to avoid leakage */
1776 if (s->childXids != NULL)
1777 pfree(s->childXids);
1778 /* We must reset these to avoid double-free if fail later in commit */
1779 s->childXids = NULL;
1780 s->nChildXids = 0;
1781 s->maxChildXids = 0;
1782}

References Assert, TransactionStateData::childXids, CurrentTransactionState, ereport, errcode(), errmsg, ERROR, fb(), TransactionStateData::fullTransactionId, MaxAllocSize, TransactionStateData::maxChildXids, memcpy(), MemoryContextAlloc(), Min, TransactionStateData::nChildXids, TransactionStateData::parent, pfree(), repalloc(), TopTransactionContext, and XidFromFullTransactionId.

Referenced by CommitSubTransaction().

◆ AtSubCommit_Memory()

static void AtSubCommit_Memory ( void  )
static

Definition at line 1677 of file xact.c.

1678{
1680
1681 Assert(s->parent != NULL);
1682
1683 /* Return to parent transaction level's memory context. */
1686
1687 /*
1688 * Ordinarily we cannot throw away the child's CurTransactionContext,
1689 * since the data it contains will be needed at upper commit. However, if
1690 * there isn't actually anything in it, we can throw it away. This avoids
1691 * a small memory leak in the common case of "trivial" subxacts.
1692 */
1694 {
1697 }
1698}

References Assert, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, fb(), MemoryContextDelete(), MemoryContextIsEmpty(), MemoryContextSwitchTo(), and TransactionStateData::parent.

Referenced by CommitSubTransaction().

◆ AtSubStart_Memory()

static void AtSubStart_Memory ( void  )
static

Definition at line 1284 of file xact.c.

1285{
1287
1289
1290 /*
1291 * Remember the context that was active prior to subtransaction start.
1292 */
1294
1295 /*
1296 * Create a CurTransactionContext, which will be used to hold data that
1297 * survives subtransaction commit but disappears on subtransaction abort.
1298 * We make it a child of the immediate parent's CurTransactionContext.
1299 */
1301 "CurTransactionContext",
1304
1305 /* Make the CurTransactionContext active. */
1307}

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, CurrentMemoryContext, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, fb(), MemoryContextSwitchTo(), and TransactionStateData::priorContext.

Referenced by StartSubTransaction().

◆ AtSubStart_ResourceOwner()

static void AtSubStart_ResourceOwner ( void  )
static

Definition at line 1313 of file xact.c.

1314{
1316
1317 Assert(s->parent != NULL);
1318
1319 /*
1320 * Create a resource owner for the subtransaction. We make it a child of
1321 * the immediate parent's resource owner.
1322 */
1325 "SubTransaction");
1326
1329}

References Assert, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, fb(), TransactionStateData::parent, and ResourceOwnerCreate().

Referenced by StartSubTransaction().

◆ BeginImplicitTransactionBlock()

void BeginImplicitTransactionBlock ( void  )

Definition at line 4380 of file xact.c.

4381{
4383
4384 /*
4385 * If we are in STARTED state (that is, no transaction block is open),
4386 * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4387 * block.
4388 *
4389 * For caller convenience, we consider all other transaction states as
4390 * legal here; otherwise the caller would need its own state check, which
4391 * seems rather pointless.
4392 */
4393 if (s->blockState == TBLOCK_STARTED)
4395}

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

Referenced by exec_simple_query(), and start_xact_command().

◆ BeginInternalSubTransaction()

void BeginInternalSubTransaction ( const char name)

Definition at line 4748 of file xact.c.

4749{
4752
4753 /*
4754 * Errors within this function are improbable, but if one does happen we
4755 * force a FATAL exit. Callers generally aren't prepared to handle losing
4756 * control, and moreover our transaction state is probably corrupted if we
4757 * fail partway through; so an ordinary ERROR longjmp isn't okay.
4758 */
4759 ExitOnAnyError = true;
4760
4761 /*
4762 * We do not check for parallel mode here. It's permissible to start and
4763 * end "internal" subtransactions while in parallel mode, so long as no
4764 * new XIDs or command IDs are assigned. Enforcement of that occurs in
4765 * AssignTransactionId() and CommandCounterIncrement().
4766 */
4767
4768 switch (s->blockState)
4769 {
4770 case TBLOCK_STARTED:
4771 case TBLOCK_INPROGRESS:
4774 case TBLOCK_END:
4775 case TBLOCK_PREPARE:
4777 /* Normal subtransaction start */
4779 s = CurrentTransactionState; /* changed by push */
4780
4781 /*
4782 * Savepoint names, like the TransactionState block itself, live
4783 * in TopTransactionContext.
4784 */
4785 if (name)
4787 break;
4788
4789 /* These cases are invalid. */
4790 case TBLOCK_DEFAULT:
4791 case TBLOCK_BEGIN:
4792 case TBLOCK_SUBBEGIN:
4793 case TBLOCK_SUBRELEASE:
4794 case TBLOCK_SUBCOMMIT:
4795 case TBLOCK_ABORT:
4796 case TBLOCK_SUBABORT:
4797 case TBLOCK_ABORT_END:
4801 case TBLOCK_SUBRESTART:
4803 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4805 break;
4806 }
4807
4810
4812}

References TransactionStateData::blockState, BlockStateAsString(), CommitTransactionCommand(), CurrentTransactionState, elog, ExitOnAnyError, FATAL, fb(), MemoryContextStrdup(), TransactionStateData::name, 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(), ReorderBufferImmediateInvalidation(), and ReorderBufferProcessTXN().

◆ BeginTransactionBlock()

void BeginTransactionBlock ( void  )

Definition at line 3978 of file xact.c.

3979{
3981
3982 switch (s->blockState)
3983 {
3984 /*
3985 * We are not inside a transaction block, so allow one to begin.
3986 */
3987 case TBLOCK_STARTED:
3989 break;
3990
3991 /*
3992 * BEGIN converts an implicit transaction block to a regular one.
3993 * (Note that we allow this even if we've already done some
3994 * commands, which is a bit odd but matches historical practice.)
3995 */
3998 break;
3999
4000 /*
4001 * Already a transaction block in progress.
4002 */
4003 case TBLOCK_INPROGRESS:
4006 case TBLOCK_ABORT:
4007 case TBLOCK_SUBABORT:
4010 errmsg("there is already a transaction in progress")));
4011 break;
4012
4013 /* These cases are invalid. */
4014 case TBLOCK_DEFAULT:
4015 case TBLOCK_BEGIN:
4016 case TBLOCK_SUBBEGIN:
4017 case TBLOCK_END:
4018 case TBLOCK_SUBRELEASE:
4019 case TBLOCK_SUBCOMMIT:
4020 case TBLOCK_ABORT_END:
4024 case TBLOCK_SUBRESTART:
4026 case TBLOCK_PREPARE:
4027 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
4029 break;
4030 }
4031}

References TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg, FATAL, fb(), 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 apply_handle_prepare_internal(), pa_start_subtrans(), and standard_ProcessUtility().

◆ BlockStateAsString()

static const char * BlockStateAsString ( TBlockState  blockState)
static

Definition at line 5766 of file xact.c.

5767{
5768 switch (blockState)
5769 {
5770 case TBLOCK_DEFAULT:
5771 return "DEFAULT";
5772 case TBLOCK_STARTED:
5773 return "STARTED";
5774 case TBLOCK_BEGIN:
5775 return "BEGIN";
5776 case TBLOCK_INPROGRESS:
5777 return "INPROGRESS";
5779 return "IMPLICIT_INPROGRESS";
5781 return "PARALLEL_INPROGRESS";
5782 case TBLOCK_END:
5783 return "END";
5784 case TBLOCK_ABORT:
5785 return "ABORT";
5786 case TBLOCK_ABORT_END:
5787 return "ABORT_END";
5789 return "ABORT_PENDING";
5790 case TBLOCK_PREPARE:
5791 return "PREPARE";
5792 case TBLOCK_SUBBEGIN:
5793 return "SUBBEGIN";
5795 return "SUBINPROGRESS";
5796 case TBLOCK_SUBRELEASE:
5797 return "SUBRELEASE";
5798 case TBLOCK_SUBCOMMIT:
5799 return "SUBCOMMIT";
5800 case TBLOCK_SUBABORT:
5801 return "SUBABORT";
5803 return "SUBABORT_END";
5805 return "SUBABORT_PENDING";
5806 case TBLOCK_SUBRESTART:
5807 return "SUBRESTART";
5809 return "SUBABORT_RESTART";
5810 }
5811 return "UNRECOGNIZED";
5812}

References 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 BeginInternalSubTransaction(), BeginTransactionBlock(), CommitTransactionCommandInternal(), DefineSavepoint(), EndTransactionBlock(), ReleaseCurrentSubTransaction(), ReleaseSavepoint(), RollbackAndReleaseCurrentSubTransaction(), RollbackToSavepoint(), ShowTransactionStateRec(), StartTransactionCommand(), TransactionBlockStatusCode(), and UserAbortTransactionBlock().

◆ CallSubXactCallbacks()

static void CallSubXactCallbacks ( SubXactEvent  event,
SubTransactionId  mySubid,
SubTransactionId  parentSubid 
)
static

Definition at line 3952 of file xact.c.

3955{
3956 SubXactCallbackItem *item;
3958
3959 for (item = SubXact_callbacks; item; item = next)
3960 {
3961 /* allow callbacks to unregister themselves when called */
3962 next = item->next;
3963 item->callback(event, mySubid, parentSubid, item->arg);
3964 }
3965}

References SubXactCallbackItem::arg, SubXactCallbackItem::callback, fb(), next, SubXactCallbackItem::next, and SubXact_callbacks.

Referenced by AbortSubTransaction(), CommitSubTransaction(), and StartSubTransaction().

◆ CallXactCallbacks()

static void CallXactCallbacks ( XactEvent  event)
static

Definition at line 3892 of file xact.c.

3893{
3894 XactCallbackItem *item;
3896
3897 for (item = Xact_callbacks; item; item = next)
3898 {
3899 /* allow callbacks to unregister themselves when called */
3900 next = item->next;
3901 item->callback(event, item->arg);
3902 }
3903}

References XactCallbackItem::arg, XactCallbackItem::callback, next, XactCallbackItem::next, and Xact_callbacks.

Referenced by AbortTransaction(), CommitTransaction(), and PrepareTransaction().

◆ CheckTransactionBlock()

static void CheckTransactionBlock ( bool  isTopLevel,
bool  throwError,
const char stmtType 
)
static

Definition at line 3779 of file xact.c.

3780{
3781 /*
3782 * xact block already started?
3783 */
3784 if (IsTransactionBlock())
3785 return;
3786
3787 /*
3788 * subtransaction?
3789 */
3790 if (IsSubTransaction())
3791 return;
3792
3793 /*
3794 * inside a function call?
3795 */
3796 if (!isTopLevel)
3797 return;
3798
3801 /* translator: %s represents an SQL statement name */
3802 errmsg("%s can only be used in transaction blocks",
3803 stmtType)));
3804}

References ereport, errcode(), errmsg, ERROR, fb(), IsSubTransaction(), IsTransactionBlock(), and WARNING.

Referenced by RequireTransactionBlock(), and WarnNoTransactionBlock().

◆ CleanupSubTransaction()

◆ CleanupTransaction()

static void CleanupTransaction ( void  )
static

Definition at line 3062 of file xact.c.

3063{
3065
3066 /*
3067 * State should still be TRANS_ABORT from AbortTransaction().
3068 */
3069 if (s->state != TRANS_ABORT)
3070 elog(FATAL, "CleanupTransaction: unexpected state %s",
3072
3073 /*
3074 * do abort cleanup processing
3075 */
3076 AtCleanup_Portals(); /* now safe to release portal memory */
3077 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
3078
3079 CurrentResourceOwner = NULL; /* and resource owner */
3085
3086 AtCleanup_Memory(); /* and transaction memory */
3087
3090 s->nestingLevel = 0;
3091 s->gucNestLevel = 0;
3092 s->childXids = NULL;
3093 s->nChildXids = 0;
3094 s->maxChildXids = 0;
3095 s->parallelModeLevel = 0;
3096 s->parallelChildXact = false;
3097
3100
3101 /*
3102 * done with abort processing, set current transaction state back to
3103 * default
3104 */
3105 s->state = TRANS_DEFAULT;
3106}

References AtCleanup_Memory(), AtCleanup_Portals(), AtEOXact_Snapshot(), TransactionStateData::childXids, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, elog, FATAL, fb(), TransactionStateData::fullTransactionId, TransactionStateData::gucNestLevel, InvalidFullTransactionId, InvalidSubTransactionId, TransactionStateData::maxChildXids, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, nParallelCurrentXids, TransactionStateData::parallelChildXact, TransactionStateData::parallelModeLevel, ResourceOwnerDelete(), TransactionStateData::state, TransactionStateData::subTransactionId, TopTransactionResourceOwner, TRANS_ABORT, TRANS_DEFAULT, TransStateAsString(), and XactTopFullTransactionId.

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), and CommitTransactionCommandInternal().

◆ CommandCounterIncrement()

void CommandCounterIncrement ( void  )

Definition at line 1130 of file xact.c.

1131{
1132 /*
1133 * If the current value of the command counter hasn't been "used" to mark
1134 * tuples, we need not increment it, since there's no need to distinguish
1135 * a read-only command from others. This helps postpone command counter
1136 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
1137 */
1139 {
1140 /*
1141 * Workers synchronize transaction state at the beginning of each
1142 * parallel operation, so we can't account for new commands after that
1143 * point.
1144 */
1146 ereport(ERROR,
1148 errmsg("cannot start commands during a parallel operation")));
1149
1150 currentCommandId += 1;
1152 {
1153 currentCommandId -= 1;
1154 ereport(ERROR,
1156 errmsg("cannot have more than 2^32-2 commands in a transaction")));
1157 }
1158 currentCommandIdUsed = false;
1159
1160 /* Propagate new command ID into static snapshots */
1162
1163 /*
1164 * Make any catalog changes done by the just-completed command visible
1165 * in the local syscache. We obviously don't need to do this after a
1166 * read-only command. (But see hacks in inval.c to make real sure we
1167 * don't think a command that queued inval messages was read-only.)
1168 */
1170 }
1171}

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

Referenced by _SPI_execute_plan(), acquire_inherited_sample_rows(), addFkConstraint(), AddRoleMems(), AlterPropGraph(), AlterPublicationAllFlags(), AlterPublicationOptions(), AlterRole(), apply_concurrent_changes(), ATAddCheckNNConstraint(), ATExecAddColumn(), ATExecAlterColumnType(), ATExecAlterConstrInheritability(), ATExecCmd(), ATExecDropColumn(), ATExecDropExpression(), ATExecDropIdentity(), ATExecMergePartitions(), ATExecSetAccessMethodNoStorage(), ATExecSetCompression(), ATExecSetExpression(), ATExecSetNotNull(), ATExecSetTableSpace(), ATExecSetTableSpaceNoStorage(), ATExecSplitPartition(), ATParseTransformCmd(), ATRewriteTables(), AttachPartitionEnsureIndexes(), AttachPartitionForeignKey(), btadjustmembers(), CommitSubTransaction(), CommitTransactionCommandInternal(), compute_return_type(), copy_attribute_defaults(), copy_index_constraints(), copy_table_data(), create_conflict_log_table(), create_ctas_internal(), create_toast_table(), CreateFKCheckTrigger(), createForeignKeyActionTriggers(), CreateForeignTable(), createPartitionTable(), CreatePropGraph(), CreatePublication(), CreateRole(), CreateSchemaCommand(), createTableConstraints(), CreateTriggerFiringOn(), DefineCollation(), DefineDomain(), DefineIndex(), DefineRange(), DefineRelation(), DefineVirtualRelation(), delete_pg_statistic(), delete_pg_statistic_ext_data(), deleteOneObject(), DetachPartitionFinalize(), do_analyze_rel(), DropClonedTriggersFromPartition(), dropconstraint_internal(), DropForeignKeyConstraintTriggers(), DropRole(), end_replication_step(), EventTriggerDDLCommandEnd(), EventTriggerDDLCommandStart(), EventTriggerInvoke(), EventTriggerSQLDrop(), EventTriggerTableRewrite(), exec_eval_simple_expr(), exec_execute_message(), exec_parse_message(), exec_simple_query(), ExecGrant_common(), ExecGrant_Largeobject(), ExecGrant_Parameter(), ExecGrant_Relation(), execute_sql_string(), ExplainOnePlan(), finish_heap_swap(), fmgr_sql(), hashadjustmembers(), ImportForeignSchema(), index_build(), index_create(), IndexSetParentIndex(), InitTempTableNamespace(), insert_element_record(), inv_create(), inv_drop(), inv_truncate(), inv_write(), LogicalRepSyncTableStart(), make_new_heap(), makeConfigurationDependencies(), moveArrayTypeName(), objectNamesToOids(), OperatorShellMake(), OperatorUpd(), pg_import_system_collations(), PortalRunMulti(), ProcedureCreate(), process_single_relation(), ProcessSyncingTablesForApply(), ProcessUtilitySlow(), rebuild_relation_finish_concurrent(), recordExtensionInitPrivWorker(), reindex_index(), reindex_relation(), ReindexRelationConcurrently(), relation_statistics_update_internal(), RelationSetNewRelfilenumber(), RemoveInheritedConstraint(), RemoveRoleFromInitPriv(), RemoveRoleFromObjectPolicy(), RenumberEnumType(), ReplaceRoleInInitPriv(), replorigin_create(), replorigin_drop_by_name(), ri_FastPathBatchFlush(), ri_FastPathCheck(), ri_PerformCheck(), set_attnotnull(), SetDatabaseHasLoginEventTriggers(), SetDefaultACL(), SetMatViewPopulatedState(), shdepReassignOwned(), SPI_cursor_open_internal(), standard_ProcessUtility(), StoreConstraints(), StorePartitionBound(), upsert_pg_statistic(), upsert_pg_statistic_ext_data(), vacuum(), and validatePartitionedIndex().

◆ CommitSubTransaction()

static void CommitSubTransaction ( void  )
static

Definition at line 5158 of file xact.c.

5159{
5161
5162 ShowTransactionState("CommitSubTransaction");
5163
5164 if (s->state != TRANS_INPROGRESS)
5165 elog(WARNING, "CommitSubTransaction while in %s state",
5167
5168 /* Pre-commit processing goes here */
5169
5172
5173 /*
5174 * If this subxact has started any unfinished parallel operation, clean up
5175 * its workers and exit parallel mode. Warn about leaked resources.
5176 */
5178 if (s->parallelModeLevel != 0)
5179 {
5180 elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5182 s->parallelModeLevel = 0;
5183 }
5184
5185 /* Do the actual "commit", such as it is */
5186 s->state = TRANS_COMMIT;
5187
5188 /* Must CCI to ensure commands of subtransaction are seen as done */
5190
5191 /*
5192 * Prior to 8.4 we marked subcommit in clog at this point. We now only
5193 * perform that step, if required, as part of the atomic update of the
5194 * whole transaction tree at top level commit or abort.
5195 */
5196
5197 /* Post-commit cleanup */
5203 s->parent->nestingLevel,
5208
5211
5214 true, false);
5218 AtEOSubXact_Inval(true);
5220
5221 /*
5222 * The only lock we actually release here is the subtransaction XID lock.
5223 */
5227
5228 /*
5229 * Other locks should get transferred to their parent resource owner.
5230 */
5233 true, false);
5236 true, false);
5237
5238 AtEOXact_GUC(true, s->gucNestLevel);
5249
5250 /*
5251 * We need to restore the upper transaction's read-only state, in case the
5252 * upper is read-write while the child is read-only; GUC will incorrectly
5253 * think it should leave the child state in place.
5254 */
5256
5261
5263
5264 s->state = TRANS_DEFAULT;
5265
5267}

References AfterTriggerEndSubXact(), AtEOSubXact_Files(), AtEOSubXact_HashTables(), AtEOSubXact_Inval(), AtEOSubXact_LargeObject(), AtEOSubXact_Namespace(), AtEOSubXact_on_commit_actions(), AtEOSubXact_Parallel(), AtEOSubXact_PgStat(), AtEOSubXact_RelationCache(), AtEOSubXact_SPI(), AtEOSubXact_TypeCache(), AtEOXact_GUC(), AtSubCommit_childXids(), AtSubCommit_Memory(), AtSubCommit_Notify(), AtSubCommit_Portals(), AtSubCommit_smgr(), AtSubCommit_Snapshot(), CallSubXactCallbacks(), CommandCounterIncrement(), CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, elog, fb(), TransactionStateData::fullTransactionId, FullTransactionIdIsValid, TransactionStateData::gucNestLevel, TransactionStateData::nestingLevel, TransactionStateData::parallelModeLevel, TransactionStateData::parent, PopTransaction(), TransactionStateData::prevXactReadOnly, RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerDelete(), ResourceOwnerRelease(), ShowTransactionState(), TransactionStateData::state, TransactionStateData::subTransactionId, SUBXACT_EVENT_COMMIT_SUB, SUBXACT_EVENT_PRE_COMMIT_SUB, TRANS_COMMIT, TRANS_DEFAULT, TRANS_INPROGRESS, TransStateAsString(), WARNING, XactLockTableDelete(), XactReadOnly, and XidFromFullTransactionId.

Referenced by CommitTransactionCommandInternal(), and ReleaseCurrentSubTransaction().

◆ CommitTransaction()

static void CommitTransaction ( void  )
static

Definition at line 2270 of file xact.c.

2271{
2274 bool is_parallel_worker;
2275
2277
2278 /* Enforce parallel mode restrictions during parallel worker commit. */
2281
2282 ShowTransactionState("CommitTransaction");
2283
2284 /*
2285 * check the current transaction state
2286 */
2287 if (s->state != TRANS_INPROGRESS)
2288 elog(WARNING, "CommitTransaction while in %s state",
2290 Assert(s->parent == NULL);
2291
2292 /*
2293 * Do pre-commit processing that involves calling user-defined code, such
2294 * as triggers. SECURITY_RESTRICTED_OPERATION contexts must not queue an
2295 * action that would run here, because that would bypass the sandbox.
2296 * Since closing cursors could queue trigger actions, triggers could open
2297 * cursors, etc, we have to keep looping until there's nothing left to do.
2298 */
2299 for (;;)
2300 {
2301 /*
2302 * Fire all currently pending deferred triggers.
2303 */
2305
2306 /*
2307 * Close open portals (converting holdable ones into static portals).
2308 * If there weren't any, we are done ... otherwise loop back to check
2309 * if they queued deferred triggers. Lather, rinse, repeat.
2310 */
2311 if (!PreCommit_Portals(false))
2312 break;
2313 }
2314
2315 /*
2316 * The remaining actions cannot call any user-defined code, so it's safe
2317 * to start shutting down within-transaction services. But note that most
2318 * of this stuff could still throw an error, which would switch us into
2319 * the transaction-abort path.
2320 */
2321
2324
2325 /*
2326 * If this xact has started any unfinished parallel operation, clean up
2327 * its workers, warning about leaked resources. (But we don't actually
2328 * reset parallelModeLevel till entering TRANS_COMMIT, a bit below. This
2329 * keeps parallel mode restrictions active as long as possible in a
2330 * parallel worker.)
2331 */
2332 AtEOXact_Parallel(true);
2334 {
2335 if (s->parallelModeLevel != 1)
2336 elog(WARNING, "parallelModeLevel is %d not 1 at end of parallel worker transaction",
2338 }
2339 else
2340 {
2341 if (s->parallelModeLevel != 0)
2342 elog(WARNING, "parallelModeLevel is %d not 0 at end of transaction",
2344 }
2345
2346 /* Shut down the deferred-trigger manager */
2347 AfterTriggerEndXact(true);
2348
2349 /*
2350 * Let ON COMMIT management do its thing (must happen after closing
2351 * cursors, to avoid dangling-reference problems)
2352 */
2354
2355 /*
2356 * Synchronize files that are created and not WAL-logged during this
2357 * transaction. This must happen before AtEOXact_RelationMap(), so that we
2358 * don't see committed-but-broken files after a crash.
2359 */
2361
2362 /* close large objects before lower-level cleanup */
2364
2365 /*
2366 * Insert notifications sent by NOTIFY commands into the queue. This
2367 * should be late in the pre-commit sequence to minimize time spent
2368 * holding the notify-insertion lock. However, this could result in
2369 * creating a snapshot, so we must do it before serializable cleanup.
2370 */
2372
2373 /*
2374 * Mark serializable transaction as complete for predicate locking
2375 * purposes. This should be done as late as we can put it and still allow
2376 * errors to be raised for failure patterns found at commit. This is not
2377 * appropriate in a parallel worker however, because we aren't committing
2378 * the leader's transaction and its serializable state will live on.
2379 */
2380 if (!is_parallel_worker)
2382
2383 /* Prevent cancel/die interrupt while cleaning up */
2385
2386 /* Commit updates to the relation map --- do this as late as possible */
2388
2389 /*
2390 * set the current transaction state information appropriately during
2391 * commit processing
2392 */
2393 s->state = TRANS_COMMIT;
2394 s->parallelModeLevel = 0;
2395 s->parallelChildXact = false; /* should be false already */
2396
2397 /* Disable transaction timeout */
2398 if (TransactionTimeout > 0)
2400
2401 if (!is_parallel_worker)
2402 {
2403 /*
2404 * We need to mark our XIDs as committed in pg_xact. This is where we
2405 * durably commit.
2406 */
2408 }
2409 else
2410 {
2411 /*
2412 * We must not mark our XID committed; the parallel leader is
2413 * responsible for that.
2414 */
2416
2417 /*
2418 * Make sure the leader will know about any WAL we wrote before it
2419 * commits.
2420 */
2422 }
2423
2425
2426 /*
2427 * Let others know about no transaction in progress by me. Note that this
2428 * must be done _before_ releasing locks we hold and _after_
2429 * RecordTransactionCommit.
2430 */
2432
2433 /*
2434 * This is all post-commit cleanup. Note that if an error is raised here,
2435 * it's too late to abort the transaction. This should be just
2436 * noncritical resource releasing.
2437 *
2438 * The ordering of operations is not entirely random. The idea is:
2439 * release resources visible to other backends (eg, files, buffer pins);
2440 * then release locks; then release backend-local resources. We want to
2441 * release locks at the point where any backend waiting for us will see
2442 * our transaction as being fully cleaned up.
2443 *
2444 * Resources that can be associated with individual queries are handled by
2445 * the ResourceOwner mechanism. The other calls here are for backend-wide
2446 * state.
2447 */
2448
2451
2455 true, true);
2456
2457 AtEOXact_Aio(true);
2458
2459 /* Check we've released all buffer pins */
2460 AtEOXact_Buffers(true);
2461
2462 /* Clean up the relation cache */
2464
2465 /* Clean up the type cache */
2467
2468 /*
2469 * Make catalog changes visible to all backends. This has to happen after
2470 * relcache references are dropped (see comments for
2471 * AtEOXact_RelationCache), but before locks are released (if anyone is
2472 * waiting for lock on a relation we've modified, we want them to know
2473 * about the catalog change before they start using the relation).
2474 */
2475 AtEOXact_Inval(true);
2476
2478
2481 true, true);
2484 true, true);
2485
2486 /*
2487 * Likewise, dropping of files deleted during the transaction is best done
2488 * after releasing relcache and buffer pins. (This is not strictly
2489 * necessary during commit, since such pins should have been released
2490 * already, but this ordering is definitely critical during abort.) Since
2491 * this may take many seconds, also delay until after releasing locks.
2492 * Other backends will observe the attendant catalog changes and not
2493 * attempt to access affected files.
2494 */
2496
2497 /*
2498 * Send out notification signals to other backends (and do other
2499 * post-commit NOTIFY cleanup). This must not happen until after our
2500 * transaction is fully done from the viewpoint of other backends.
2501 */
2503
2504 /*
2505 * Everything after this should be purely internal-to-this-backend
2506 * cleanup.
2507 */
2508 AtEOXact_GUC(true, 1);
2509 AtEOXact_SPI(true);
2510 AtEOXact_Enum();
2513 AtEOXact_SMgr();
2514 AtEOXact_Files(true);
2516 AtEOXact_HashTables(true);
2517 AtEOXact_RI(true);
2519 AtEOXact_Snapshot(true, false);
2524
2529
2531
2534 s->nestingLevel = 0;
2535 s->gucNestLevel = 0;
2536 s->childXids = NULL;
2537 s->nChildXids = 0;
2538 s->maxChildXids = 0;
2539
2542
2543 /*
2544 * done with commit processing, set current transaction state back to
2545 * default
2546 */
2547 s->state = TRANS_DEFAULT;
2548
2550}

References AfterTriggerEndXact(), AfterTriggerFireDeferred(), Assert, AtCommit_Memory(), AtCommit_Notify(), AtEOXact_Aio(), AtEOXact_ApplyLauncher(), AtEOXact_Buffers(), AtEOXact_ComboCid(), AtEOXact_Enum(), AtEOXact_Files(), AtEOXact_GUC(), AtEOXact_HashTables(), AtEOXact_Inval(), AtEOXact_LargeObject(), AtEOXact_LogicalCtl(), AtEOXact_LogicalRepWorkers(), AtEOXact_MultiXact(), AtEOXact_Namespace(), AtEOXact_on_commit_actions(), AtEOXact_Parallel(), AtEOXact_PgStat(), AtEOXact_RelationCache(), AtEOXact_RelationMap(), AtEOXact_RI(), AtEOXact_SMgr(), AtEOXact_Snapshot(), AtEOXact_SPI(), AtEOXact_TypeCache(), TransactionStateData::blockState, CallXactCallbacks(), TransactionStateData::childXids, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, disable_timeout(), elog, EnterParallelMode(), fb(), TransactionStateData::fullTransactionId, TransactionStateData::gucNestLevel, HOLD_INTERRUPTS, InvalidFullTransactionId, InvalidSubTransactionId, InvalidTransactionId, PGPROC::lxid, TransactionStateData::maxChildXids, MyProc, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, nParallelCurrentXids, TransactionStateData::parallelChildXact, TransactionStateData::parallelModeLevel, ParallelWorkerReportLastRecEnd(), TransactionStateData::parent, pgstat_report_xact_timestamp(), PreCommit_CheckForSerializationFailure(), PreCommit_Notify(), PreCommit_on_commit_actions(), PreCommit_Portals(), ProcArrayEndTransaction(), RecordTransactionCommit(), RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerDelete(), ResourceOwnerRelease(), RESUME_INTERRUPTS, ShowTransactionState(), smgrDoPendingDeletes(), smgrDoPendingSyncs(), TransactionStateData::state, TransactionStateData::subTransactionId, TBLOCK_PARALLEL_INPROGRESS, TopTransactionResourceOwner, TRANS_COMMIT, TRANS_DEFAULT, TRANS_INPROGRESS, TRANSACTION_TIMEOUT, TransactionTimeout, TransStateAsString(), PGPROC::vxid, WARNING, XACT_EVENT_COMMIT, XACT_EVENT_PARALLEL_COMMIT, XACT_EVENT_PARALLEL_PRE_COMMIT, XACT_EVENT_PRE_COMMIT, XactLastRecEnd, and XactTopFullTransactionId.

Referenced by CommitTransactionCommandInternal(), EndParallelWorkerTransaction(), EndRestoreLOs(), IssueCommandPerBlob(), restore_toc_entries_prefork(), restore_toc_entry(), and RestoreArchive().

◆ CommitTransactionCommand()

void CommitTransactionCommand ( void  )

Definition at line 3210 of file xact.c.

3211{
3212 /*
3213 * Repeatedly call CommitTransactionCommandInternal() until all the work
3214 * is done.
3215 */
3217 {
3218 }
3219}

References CommitTransactionCommandInternal().

Referenced by _SPI_commit(), AllTablesyncsReady(), apply_handle_commit_internal(), apply_handle_commit_prepared(), apply_handle_prepare(), apply_handle_prepare_internal(), apply_handle_rollback_prepared(), apply_handle_stream_prepare(), ATExecDetachPartition(), autoprewarm_database_main(), bbsink_server_new(), BeginInternalSubTransaction(), BootstrapModeMain(), BuildDatabaseList(), BuildRelationList(), clear_subscription_skip_lsn(), copy_sequences(), DatabaseExists(), DefineIndex(), DisableSubscriptionAndExit(), do_autovacuum(), EventTriggerOnLogin(), exec_replication_command(), ExecRepack(), finish_xact_command(), FinishSyncWorker(), get_database_list(), get_subscription_list(), HasSubscriptionTablesCached(), IdentifySystem(), index_drop(), initialize_worker_spi(), InitializeLogRepWorker(), InitPostgres(), LogicalRepSyncSequences(), LogicalRepSyncTableStart(), maybe_reread_subscription(), movedb(), pa_start_subtrans(), pa_stream_abort(), ParallelApplyWorkerMain(), ParallelWorkerMain(), process_single_relation(), ProcessCatchupInterrupt(), ProcessIncomingNotify(), ProcessSequencesForSync(), ProcessSingleRelationByOid(), ProcessSyncingTablesForApply(), ProcessSyncingTablesForSync(), ReindexMultipleInternal(), ReindexRelationConcurrently(), RemoveTempRelationsCallback(), RepackWorkerMain(), ReplSlotSyncWorkerMain(), run_apply_worker(), shell_check_detail(), stream_abort_internal(), stream_stop_internal(), update_retention_status(), vacuum(), vacuum_rel(), validate_remote_info(), and worker_spi_main().

◆ CommitTransactionCommandInternal()

static bool CommitTransactionCommandInternal ( void  )
static

Definition at line 3228 of file xact.c.

3229{
3232
3233 /* Must save in case we need to restore below */
3235
3236 switch (s->blockState)
3237 {
3238 /*
3239 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3240 * StartTransactionCommand didn't set the STARTED state
3241 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3242 * by EndParallelWorkerTransaction(), not this function.
3243 */
3244 case TBLOCK_DEFAULT:
3246 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3248 break;
3249
3250 /*
3251 * If we aren't in a transaction block, just do our usual
3252 * transaction commit, and return to the idle state.
3253 */
3254 case TBLOCK_STARTED:
3257 break;
3258
3259 /*
3260 * We are completing a "BEGIN TRANSACTION" command, so we change
3261 * to the "transaction block in progress" state and return. (We
3262 * assume the BEGIN did nothing to the database, so we need no
3263 * CommandCounterIncrement.)
3264 */
3265 case TBLOCK_BEGIN:
3267 break;
3268
3269 /*
3270 * This is the case when we have finished executing a command
3271 * someplace within a transaction block. We increment the command
3272 * counter and return.
3273 */
3274 case TBLOCK_INPROGRESS:
3278 break;
3279
3280 /*
3281 * We are completing a "COMMIT" command. Do it and return to the
3282 * idle state.
3283 */
3284 case TBLOCK_END:
3287 if (s->chain)
3288 {
3291 s->chain = false;
3293 }
3294 break;
3295
3296 /*
3297 * Here we are in the middle of a transaction block but one of the
3298 * commands caused an abort so we do nothing but remain in the
3299 * abort state. Eventually we will get a ROLLBACK command.
3300 */
3301 case TBLOCK_ABORT:
3302 case TBLOCK_SUBABORT:
3303 break;
3304
3305 /*
3306 * Here we were in an aborted transaction block and we just got
3307 * the ROLLBACK command from the user, so clean up the
3308 * already-aborted transaction and return to the idle state.
3309 */
3310 case TBLOCK_ABORT_END:
3313 if (s->chain)
3314 {
3317 s->chain = false;
3319 }
3320 break;
3321
3322 /*
3323 * Here we were in a perfectly good transaction block but the user
3324 * told us to ROLLBACK anyway. We have to abort the transaction
3325 * and then clean up.
3326 */
3331 if (s->chain)
3332 {
3335 s->chain = false;
3337 }
3338 break;
3339
3340 /*
3341 * We are completing a "PREPARE TRANSACTION" command. Do it and
3342 * return to the idle state.
3343 */
3344 case TBLOCK_PREPARE:
3347 break;
3348
3349 /*
3350 * The user issued a SAVEPOINT inside a transaction block. Start a
3351 * subtransaction. (DefineSavepoint already did PushTransaction,
3352 * so as to have someplace to put the SUBBEGIN state.)
3353 */
3354 case TBLOCK_SUBBEGIN:
3357 break;
3358
3359 /*
3360 * The user issued a RELEASE command, so we end the current
3361 * subtransaction and return to the parent transaction. The parent
3362 * might be ended too, so repeat till we find an INPROGRESS
3363 * transaction or subtransaction.
3364 */
3365 case TBLOCK_SUBRELEASE:
3366 do
3367 {
3369 s = CurrentTransactionState; /* changed by pop */
3370 } while (s->blockState == TBLOCK_SUBRELEASE);
3371
3374 break;
3375
3376 /*
3377 * The user issued a COMMIT, so we end the current subtransaction
3378 * hierarchy and perform final commit. We do this by rolling up
3379 * any subtransactions into their parent, which leads to O(N^2)
3380 * operations with respect to resource owners - this isn't that
3381 * bad until we approach a thousands of savepoints but is
3382 * necessary for correctness should after triggers create new
3383 * resource owners.
3384 */
3385 case TBLOCK_SUBCOMMIT:
3386 do
3387 {
3389 s = CurrentTransactionState; /* changed by pop */
3390 } while (s->blockState == TBLOCK_SUBCOMMIT);
3391 /* If we had a COMMIT command, finish off the main xact too */
3392 if (s->blockState == TBLOCK_END)
3393 {
3394 Assert(s->parent == NULL);
3397 if (s->chain)
3398 {
3401 s->chain = false;
3403 }
3404 }
3405 else if (s->blockState == TBLOCK_PREPARE)
3406 {
3407 Assert(s->parent == NULL);
3410 }
3411 else
3412 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3414 break;
3415
3416 /*
3417 * The current already-failed subtransaction is ending due to a
3418 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3419 * examine the parent (which could be in any of several states).
3420 * As we need to examine the parent, return false to request the
3421 * caller to do the next iteration.
3422 */
3425 return false;
3426
3427 /*
3428 * As above, but it's not dead yet, so abort first.
3429 */
3433 return false;
3434
3435 /*
3436 * The current subtransaction is the target of a ROLLBACK TO
3437 * command. Abort and pop it, then start a new subtransaction
3438 * with the same name.
3439 */
3440 case TBLOCK_SUBRESTART:
3441 {
3442 char *name;
3443 int savepointLevel;
3444
3445 /* save name and keep Cleanup from freeing it */
3446 name = s->name;
3447 s->name = NULL;
3448 savepointLevel = s->savepointLevel;
3449
3452
3454 s = CurrentTransactionState; /* changed by push */
3455 s->name = name;
3456 s->savepointLevel = savepointLevel;
3457
3458 /* This is the same as TBLOCK_SUBBEGIN case */
3462 }
3463 break;
3464
3465 /*
3466 * Same as above, but the subtransaction had already failed, so we
3467 * don't need AbortSubTransaction.
3468 */
3470 {
3471 char *name;
3472 int savepointLevel;
3473
3474 /* save name and keep Cleanup from freeing it */
3475 name = s->name;
3476 s->name = NULL;
3477 savepointLevel = s->savepointLevel;
3478
3480
3482 s = CurrentTransactionState; /* changed by push */
3483 s->name = name;
3484 s->savepointLevel = savepointLevel;
3485
3486 /* This is the same as TBLOCK_SUBBEGIN case */
3490 }
3491 break;
3492 }
3493
3494 /* Done, no more iterations required */
3495 return true;
3496}

References AbortSubTransaction(), AbortTransaction(), Assert, TransactionStateData::blockState, BlockStateAsString(), TransactionStateData::chain, CleanupSubTransaction(), CleanupTransaction(), CommandCounterIncrement(), CommitSubTransaction(), CommitTransaction(), CurrentTransactionState, DefineSavepoint(), elog, ERROR, FATAL, fb(), TransactionStateData::name, name, TransactionStateData::parent, PrepareTransaction(), RestoreTransactionCharacteristics(), TransactionStateData::savepointLevel, SaveTransactionCharacteristics(), StartSubTransaction(), 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 CommitTransactionCommand().

◆ DefineSavepoint()

void DefineSavepoint ( const char name)

Definition at line 4427 of file xact.c.

4428{
4430
4431 /*
4432 * Workers synchronize transaction state at the beginning of each parallel
4433 * operation, so we can't account for new subtransactions after that
4434 * point. (Note that this check will certainly error out if s->blockState
4435 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4436 * below.)
4437 */
4439 ereport(ERROR,
4441 errmsg("cannot define savepoints during a parallel operation")));
4442
4443 switch (s->blockState)
4444 {
4445 case TBLOCK_INPROGRESS:
4447 /* Normal subtransaction start */
4449 s = CurrentTransactionState; /* changed by push */
4450
4451 /*
4452 * Savepoint names, like the TransactionState block itself, live
4453 * in TopTransactionContext.
4454 */
4455 if (name)
4457 break;
4458
4459 /*
4460 * We disallow savepoint commands in implicit transaction blocks.
4461 * There would be no great difficulty in allowing them so far as
4462 * this module is concerned, but a savepoint seems inconsistent
4463 * with exec_simple_query's behavior of abandoning the whole query
4464 * string upon error. Also, the point of an implicit transaction
4465 * block (as opposed to a regular one) is to automatically close
4466 * after an error, so it's hard to see how a savepoint would fit
4467 * into that.
4468 *
4469 * The error messages for this are phrased as if there were no
4470 * active transaction block at all, which is historical but
4471 * perhaps could be improved.
4472 */
4474 ereport(ERROR,
4476 /* translator: %s represents an SQL statement name */
4477 errmsg("%s can only be used in transaction blocks",
4478 "SAVEPOINT")));
4479 break;
4480
4481 /* These cases are invalid. */
4482 case TBLOCK_DEFAULT:
4483 case TBLOCK_STARTED:
4484 case TBLOCK_BEGIN:
4486 case TBLOCK_SUBBEGIN:
4487 case TBLOCK_END:
4488 case TBLOCK_SUBRELEASE:
4489 case TBLOCK_SUBCOMMIT:
4490 case TBLOCK_ABORT:
4491 case TBLOCK_SUBABORT:
4492 case TBLOCK_ABORT_END:
4496 case TBLOCK_SUBRESTART:
4498 case TBLOCK_PREPARE:
4499 elog(FATAL, "DefineSavepoint: unexpected state %s",
4501 break;
4502 }
4503}

References TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg, ERROR, FATAL, fb(), IsInParallelMode(), IsParallelWorker, MemoryContextStrdup(), TransactionStateData::name, 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 CommitTransactionCommandInternal(), pa_start_subtrans(), and standard_ProcessUtility().

◆ EndImplicitTransactionBlock()

void EndImplicitTransactionBlock ( void  )

Definition at line 4405 of file xact.c.

4406{
4408
4409 /*
4410 * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4411 * allowing CommitTransactionCommand to commit whatever happened during
4412 * the implicit transaction block as though it were a single statement.
4413 *
4414 * For caller convenience, we consider all other transaction states as
4415 * legal here; otherwise the caller would need its own state check, which
4416 * seems rather pointless.
4417 */
4420}

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

Referenced by exec_simple_query(), and PostgresMain().

◆ EndParallelWorkerTransaction()

◆ EndTransactionBlock()

bool EndTransactionBlock ( bool  chain)

Definition at line 4098 of file xact.c.

4099{
4101 bool result = false;
4102
4103 switch (s->blockState)
4104 {
4105 /*
4106 * We are in a transaction block, so tell CommitTransactionCommand
4107 * to COMMIT.
4108 */
4109 case TBLOCK_INPROGRESS:
4111 result = true;
4112 break;
4113
4114 /*
4115 * We are in an implicit transaction block. If AND CHAIN was
4116 * specified, error. Otherwise commit, but issue a warning
4117 * because there was no explicit BEGIN before this.
4118 */
4120 if (chain)
4121 ereport(ERROR,
4123 /* translator: %s represents an SQL statement name */
4124 errmsg("%s can only be used in transaction blocks",
4125 "COMMIT AND CHAIN")));
4126 else
4129 errmsg("there is no transaction in progress")));
4131 result = true;
4132 break;
4133
4134 /*
4135 * We are in a failed transaction block. Tell
4136 * CommitTransactionCommand it's time to exit the block.
4137 */
4138 case TBLOCK_ABORT:
4140 break;
4141
4142 /*
4143 * We are in a live subtransaction block. Set up to subcommit all
4144 * open subtransactions and then commit the main transaction.
4145 */
4147 while (s->parent != NULL)
4148 {
4151 else
4152 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4154 s = s->parent;
4155 }
4156 if (s->blockState == TBLOCK_INPROGRESS)
4158 else
4159 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4161 result = true;
4162 break;
4163
4164 /*
4165 * Here we are inside an aborted subtransaction. Treat the COMMIT
4166 * as ROLLBACK: set up to abort everything and exit the main
4167 * transaction.
4168 */
4169 case TBLOCK_SUBABORT:
4170 while (s->parent != NULL)
4171 {
4174 else if (s->blockState == TBLOCK_SUBABORT)
4176 else
4177 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4179 s = s->parent;
4180 }
4181 if (s->blockState == TBLOCK_INPROGRESS)
4183 else if (s->blockState == TBLOCK_ABORT)
4185 else
4186 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4188 break;
4189
4190 /*
4191 * The user issued COMMIT when not inside a transaction. For
4192 * COMMIT without CHAIN, issue a WARNING, staying in
4193 * TBLOCK_STARTED state. The upcoming call to
4194 * CommitTransactionCommand() will then close the transaction and
4195 * put us back into the default state. For COMMIT AND CHAIN,
4196 * error.
4197 */
4198 case TBLOCK_STARTED:
4199 if (chain)
4200 ereport(ERROR,
4202 /* translator: %s represents an SQL statement name */
4203 errmsg("%s can only be used in transaction blocks",
4204 "COMMIT AND CHAIN")));
4205 else
4208 errmsg("there is no transaction in progress")));
4209 result = true;
4210 break;
4211
4212 /*
4213 * The user issued a COMMIT that somehow ran inside a parallel
4214 * worker. We can't cope with that.
4215 */
4217 ereport(FATAL,
4219 errmsg("cannot commit during a parallel operation")));
4220 break;
4221
4222 /* These cases are invalid. */
4223 case TBLOCK_DEFAULT:
4224 case TBLOCK_BEGIN:
4225 case TBLOCK_SUBBEGIN:
4226 case TBLOCK_END:
4227 case TBLOCK_SUBRELEASE:
4228 case TBLOCK_SUBCOMMIT:
4229 case TBLOCK_ABORT_END:
4233 case TBLOCK_SUBRESTART:
4235 case TBLOCK_PREPARE:
4236 elog(FATAL, "EndTransactionBlock: unexpected state %s",
4238 break;
4239 }
4240
4242 s->blockState == TBLOCK_END ||
4245
4246 s->chain = chain;
4247
4248 return result;
4249}

References Assert, TransactionStateData::blockState, BlockStateAsString(), TransactionStateData::chain, CurrentTransactionState, elog, ereport, errcode(), errmsg, ERROR, FATAL, fb(), TransactionStateData::parent, result, 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 apply_handle_commit_internal(), pa_stream_abort(), PrepareTransactionBlock(), and standard_ProcessUtility().

◆ EnterParallelMode()

◆ EstimateTransactionStateSpace()

◆ ExitParallelMode()

◆ ForceSyncCommit()

void ForceSyncCommit ( void  )

Definition at line 1182 of file xact.c.

1183{
1184 forceSyncCommit = true;
1185}

References forceSyncCommit.

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

◆ GetCurrentCommandId()

CommandId GetCurrentCommandId ( bool  used)

Definition at line 831 of file xact.c.

832{
833 /* this is global to a transaction, not subtransaction-local */
834 if (used)
835 {
836 /*
837 * Forbid setting currentCommandIdUsed in a parallel worker, because
838 * we have no provision for communicating this back to the leader. We
839 * could relax this restriction when currentCommandIdUsed was already
840 * true at the start of the parallel operation.
841 */
842 if (IsParallelWorker())
845 errmsg("cannot modify data in a parallel worker")));
846
848 }
849 return currentCommandId;
850}

References currentCommandId, currentCommandIdUsed, ereport, errcode(), errmsg, ERROR, fb(), and IsParallelWorker.

Referenced by apply_concurrent_delete(), apply_concurrent_insert(), apply_concurrent_update(), ATRewriteTable(), CatalogTuplesMultiInsertWithInfo(), CopyFrom(), create_edata_for_relation(), create_estate_for_relation(), FindConflictTuple(), GetSnapshotData(), GetSnapshotDataReuse(), heap_inplace_lock(), heap_insert_for_repack(), intorel_startup(), MergePartitionsMoveRows(), pgrowlocks(), RegisterRelcacheInvalidation(), RelationFindReplTupleByIndex(), RelationFindReplTupleSeq(), ri_LockPKTuple(), simple_heap_delete(), simple_heap_insert(), simple_heap_update(), simple_table_tuple_delete(), simple_table_tuple_insert(), simple_table_tuple_update(), SplitPartitionMoveRows(), standard_ExecutorStart(), toast_save_datum(), transientrel_startup(), and UpdateActiveSnapshotCommandId().

◆ GetCurrentFullTransactionId()

◆ GetCurrentFullTransactionIdIfAny()

FullTransactionId GetCurrentFullTransactionIdIfAny ( void  )

Definition at line 532 of file xact.c.

References CurrentTransactionState, and TransactionStateData::fullTransactionId.

◆ GetCurrentStatementStartTimestamp()

TimestampTz GetCurrentStatementStartTimestamp ( void  )

◆ GetCurrentSubTransactionId()

◆ GetCurrentTransactionId()

◆ GetCurrentTransactionIdIfAny()

◆ GetCurrentTransactionNestLevel()

◆ GetCurrentTransactionStartTimestamp()

◆ GetCurrentTransactionStopTimestamp()

TimestampTz GetCurrentTransactionStopTimestamp ( void  )

Definition at line 893 of file xact.c.

894{
896
897 /* should only be called after commit / abort processing */
898 Assert(s->state == TRANS_DEFAULT ||
899 s->state == TRANS_COMMIT ||
900 s->state == TRANS_ABORT ||
901 s->state == TRANS_PREPARE);
902
903 if (xactStopTimestamp == 0)
905
906 return xactStopTimestamp;
907}

References Assert, CurrentTransactionState, GetCurrentTimestamp(), PG_USED_FOR_ASSERTS_ONLY, TRANS_ABORT, TRANS_COMMIT, TRANS_DEFAULT, TRANS_PREPARE, and xactStopTimestamp.

Referenced by pgstat_relation_flush_cb(), pgstat_report_stat(), RecordTransactionAbort(), and RecordTransactionCommit().

◆ GetStableLatestTransactionId()

◆ GetTopFullTransactionId()

◆ GetTopFullTransactionIdIfAny()

FullTransactionId GetTopFullTransactionIdIfAny ( void  )

Definition at line 501 of file xact.c.

502{
504}

References XactTopFullTransactionId.

Referenced by pg_current_xact_id_if_assigned().

◆ GetTopReadOnlyTransactionNestLevel()

int GetTopReadOnlyTransactionNestLevel ( void  )

Definition at line 1062 of file xact.c.

1063{
1065
1066 if (!XactReadOnly)
1067 return 0;
1068 while (s->nestingLevel > 1)
1069 {
1070 if (!s->prevXactReadOnly)
1071 return s->nestingLevel;
1072 s = s->parent;
1073 }
1074 return s->nestingLevel;
1075}

References CurrentTransactionState, TransactionStateData::nestingLevel, TransactionStateData::parent, TransactionStateData::prevXactReadOnly, and XactReadOnly.

Referenced by begin_remote_xact().

◆ GetTopTransactionId()

◆ GetTopTransactionIdIfAny()

◆ IsAbortedTransactionBlockState()

◆ IsInParallelMode()

◆ IsInTransactionBlock()

bool IsInTransactionBlock ( bool  isTopLevel)

Definition at line 3823 of file xact.c.

3824{
3825 /*
3826 * Return true on same conditions that would make
3827 * PreventInTransactionBlock error out
3828 */
3829 if (IsTransactionBlock())
3830 return true;
3831
3832 if (IsSubTransaction())
3833 return true;
3834
3835 if (!isTopLevel)
3836 return true;
3837
3840 return true;
3841
3842 return false;
3843}

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

Referenced by vacuum().

◆ IsSubTransaction()

◆ IsSubxactTopXidLogPending()

bool IsSubxactTopXidLogPending ( void  )

Definition at line 561 of file xact.c.

562{
563 /* check whether it is already logged */
565 return false;
566
567 /* effective_wal_level has to be logical */
569 return false;
570
571 /* we need to be in a transaction state */
572 if (!IsTransactionState())
573 return false;
574
575 /* it has to be a subtransaction */
576 if (!IsSubTransaction())
577 return false;
578
579 /* the subtransaction has to have a XID assigned */
581 return false;
582
583 return true;
584}

References CurrentTransactionState, GetCurrentTransactionIdIfAny(), IsSubTransaction(), IsTransactionState(), TransactionStateData::topXidLogged, TransactionIdIsValid, and XLogLogicalInfoActive.

Referenced by MarkSubxactTopXidLogged(), and XLogRecordAssemble().

◆ IsTransactionBlock()

◆ IsTransactionOrTransactionBlock()

◆ IsTransactionState()

bool IsTransactionState ( void  )

Definition at line 389 of file xact.c.

390{
392
393 /*
394 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
395 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
396 * TRANS_PREPARE since it might be too soon or too late within those
397 * transition states to do anything interesting. Hence, the only "valid"
398 * state is TRANS_INPROGRESS.
399 */
400 return (s->state == TRANS_INPROGRESS);
401}

References CurrentTransactionState, TransactionStateData::state, and TRANS_INPROGRESS.

Referenced by AcceptInvalidationMessages(), apply_handle_commit_internal(), apply_handle_origin(), assign_transaction_timeout(), begin_replication_step(), check_client_encoding(), check_default_table_access_method(), check_default_tablespace(), check_default_text_search_config(), check_role(), check_session_authorization(), check_temp_tablespaces(), check_transaction_isolation(), check_transaction_read_only(), clear_subscription_skip_lsn(), ConditionalCatalogCacheInitializeCache(), CreateInitDecodingContext(), ensure_last_message(), FetchRelationStates(), FinishSyncWorker(), IsSubxactTopXidLogPending(), LogicalParallelApplyLoop(), LogicalRepApplyLoop(), LogLogicalMessage(), maybe_reread_subscription(), pa_send_data(), pa_start_subtrans(), pg_do_encoding_conversion(), PrepareClientEncoding(), PrepareTempTablespaces(), ProcessSyncingTablesForApply(), ProcessSyncingTablesForSync(), RelationCacheInvalidate(), RelationFlushRelation(), RelationInitPhysicalAddr(), replorigin_create(), replorigin_drop_by_name(), ReplSlotSyncWorkerMain(), SetMultiXactIdLimit(), SetTransactionIdLimit(), SnapBuildClearExportedSnapshot(), SocketBackend(), stream_stop_internal(), SyncReplicationSlots(), update_retention_status(), and validate_remote_info().

◆ MarkCurrentTransactionIdLoggedIfAny()

◆ MarkSubxactTopXidLogged()

void MarkSubxactTopXidLogged ( void  )

◆ PopTransaction()

static void PopTransaction ( void  )
static

Definition at line 5537 of file xact.c.

5538{
5540
5541 if (s->state != TRANS_DEFAULT)
5542 elog(WARNING, "PopTransaction while in %s state",
5544
5545 if (s->parent == NULL)
5546 elog(FATAL, "PopTransaction with no parent");
5547
5549
5550 /* Let's just make sure CurTransactionContext is good */
5553
5554 /* Ditto for ResourceOwner links */
5557
5558 /* Free the old child structure */
5559 if (s->name)
5560 pfree(s->name);
5561 pfree(s);
5562}

References CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, elog, FATAL, fb(), MemoryContextSwitchTo(), TransactionStateData::name, TransactionStateData::parent, pfree(), TransactionStateData::state, TRANS_DEFAULT, TransStateAsString(), and WARNING.

Referenced by CleanupSubTransaction(), and CommitSubTransaction().

◆ PrepareTransaction()

static void PrepareTransaction ( void  )
static

Definition at line 2559 of file xact.c.

2560{
2564 TimestampTz prepared_at;
2565
2567
2568 ShowTransactionState("PrepareTransaction");
2569
2570 /*
2571 * check the current transaction state
2572 */
2573 if (s->state != TRANS_INPROGRESS)
2574 elog(WARNING, "PrepareTransaction while in %s state",
2576 Assert(s->parent == NULL);
2577
2578 /*
2579 * Do pre-commit processing that involves calling user-defined code, such
2580 * as triggers. Since closing cursors could queue trigger actions,
2581 * triggers could open cursors, etc, we have to keep looping until there's
2582 * nothing left to do.
2583 */
2584 for (;;)
2585 {
2586 /*
2587 * Fire all currently pending deferred triggers.
2588 */
2590
2591 /*
2592 * Close open portals (converting holdable ones into static portals).
2593 * If there weren't any, we are done ... otherwise loop back to check
2594 * if they queued deferred triggers. Lather, rinse, repeat.
2595 */
2596 if (!PreCommit_Portals(true))
2597 break;
2598 }
2599
2601
2602 /*
2603 * The remaining actions cannot call any user-defined code, so it's safe
2604 * to start shutting down within-transaction services. But note that most
2605 * of this stuff could still throw an error, which would switch us into
2606 * the transaction-abort path.
2607 */
2608
2609 /* Shut down the deferred-trigger manager */
2610 AfterTriggerEndXact(true);
2611
2612 /*
2613 * Let ON COMMIT management do its thing (must happen after closing
2614 * cursors, to avoid dangling-reference problems)
2615 */
2617
2618 /*
2619 * Synchronize files that are created and not WAL-logged during this
2620 * transaction. This must happen before EndPrepare(), so that we don't see
2621 * committed-but-broken files after a crash and COMMIT PREPARED.
2622 */
2623 smgrDoPendingSyncs(true, false);
2624
2625 /* close large objects before lower-level cleanup */
2627
2628 /* NOTIFY requires no work at this point */
2629
2630 /*
2631 * Mark serializable transaction as complete for predicate locking
2632 * purposes. This should be done as late as we can put it and still allow
2633 * errors to be raised for failure patterns found at commit.
2634 */
2636
2637 /*
2638 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2639 * this transaction. Having the prepared xact hold locks on another
2640 * backend's temp table seems a bad idea --- for instance it would prevent
2641 * the backend from exiting. There are other problems too, such as how to
2642 * clean up the source backend's local buffers and ON COMMIT state if the
2643 * prepared xact includes a DROP of a temp table.
2644 *
2645 * Other objects types, like functions, operators or extensions, share the
2646 * same restriction as they should not be created, locked or dropped as
2647 * this can mess up with this session or even a follow-up session trying
2648 * to use the same temporary namespace.
2649 *
2650 * We must check this after executing any ON COMMIT actions, because they
2651 * might still access a temp relation.
2652 *
2653 * XXX In principle this could be relaxed to allow some useful special
2654 * cases, such as a temp table created and dropped all within the
2655 * transaction. That seems to require much more bookkeeping though.
2656 */
2658 ereport(ERROR,
2660 errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2661
2662 /*
2663 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2664 * supported if we added cleanup logic to twophase.c, but for now it
2665 * doesn't seem worth the trouble.
2666 */
2668 ereport(ERROR,
2670 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2671
2672 /* Prevent cancel/die interrupt while cleaning up */
2674
2675 /*
2676 * set the current transaction state information appropriately during
2677 * prepare processing
2678 */
2679 s->state = TRANS_PREPARE;
2680
2681 /* Disable transaction timeout */
2682 if (TransactionTimeout > 0)
2684
2685 prepared_at = GetCurrentTimestamp();
2686
2687 /*
2688 * Reserve the GID for this transaction. This could fail if the requested
2689 * GID is invalid or already in use.
2690 */
2691 gxact = MarkAsPreparing(fxid, prepareGID, prepared_at,
2693 prepareGID = NULL;
2694
2695 /*
2696 * Collect data for the 2PC state file. Note that in general, no actual
2697 * state change should happen in the called modules during this step,
2698 * since it's still possible to fail before commit, and in that case we
2699 * want transaction abort to be able to clean up. (In particular, the
2700 * AtPrepare routines may error out if they find cases they cannot
2701 * handle.) State cleanup should happen in the PostPrepare routines
2702 * below. However, some modules can go ahead and clear state here because
2703 * they wouldn't do anything with it during abort anyway.
2704 *
2705 * Note: because the 2PC state file records will be replayed in the same
2706 * order they are made, the order of these calls has to match the order in
2707 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2708 * PREPARED; in particular, pay attention to whether things should happen
2709 * before or after releasing the transaction's locks.
2710 */
2712
2719
2720 /*
2721 * Here is where we really truly prepare.
2722 *
2723 * We have to record transaction prepares even if we didn't make any
2724 * updates, because the transaction manager might get confused if we lose
2725 * a global transaction.
2726 */
2728
2729 /*
2730 * Now we clean up backend-internal state and release internal resources.
2731 */
2732
2733 /* Reset XactLastRecEnd until the next transaction writes something */
2734 XactLastRecEnd = 0;
2735
2736 /*
2737 * Transfer our locks to a dummy PGPROC. This has to be done before
2738 * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2739 * conclude "xact already committed or aborted" for our locks.
2740 */
2741 PostPrepare_Locks(fxid);
2742
2743 /*
2744 * Let others know about no transaction in progress by me. This has to be
2745 * done *after* the prepared transaction has been marked valid, else
2746 * someone may think it is unlocked and recyclable.
2747 */
2749
2750 /*
2751 * In normal commit-processing, this is all non-critical post-transaction
2752 * cleanup. When the transaction is prepared, however, it's important
2753 * that the locks and other per-backend resources are transferred to the
2754 * prepared transaction's PGPROC entry. Note that if an error is raised
2755 * here, it's too late to abort the transaction. XXX: This probably should
2756 * be in a critical section, to force a PANIC if any of this fails, but
2757 * that cure could be worse than the disease.
2758 */
2759
2761
2764 true, true);
2765
2766 AtEOXact_Aio(true);
2767
2768 /* Check we've released all buffer pins */
2769 AtEOXact_Buffers(true);
2770
2771 /* Clean up the relation cache */
2773
2774 /* Clean up the type cache */
2776
2777 /* notify doesn't need a postprepare call */
2778
2780
2782
2784
2786
2788
2791 true, true);
2794 true, true);
2795
2796 /*
2797 * Allow another backend to finish the transaction. After
2798 * PostPrepare_Twophase(), the transaction is completely detached from our
2799 * backend. The rest is just non-critical cleanup of backend-local state.
2800 */
2802
2803 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2804 AtEOXact_GUC(true, 1);
2805 AtEOXact_SPI(true);
2806 AtEOXact_Enum();
2808 AtEOXact_Namespace(true, false);
2809 AtEOXact_SMgr();
2810 AtEOXact_Files(true);
2812 AtEOXact_HashTables(true);
2813 AtEOXact_RI(true);
2814 /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2815 AtEOXact_Snapshot(true, true);
2816 /* we treat PREPARE as ROLLBACK so far as waking workers goes */
2821
2827
2829
2832 s->nestingLevel = 0;
2833 s->gucNestLevel = 0;
2834 s->childXids = NULL;
2835 s->nChildXids = 0;
2836 s->maxChildXids = 0;
2837
2840
2841 /*
2842 * done with 1st phase commit processing, set current transaction state
2843 * back to default
2844 */
2845 s->state = TRANS_DEFAULT;
2846
2848}

References AfterTriggerEndXact(), AfterTriggerFireDeferred(), Assert, AtCommit_Memory(), AtEOXact_Aio(), AtEOXact_ApplyLauncher(), AtEOXact_Buffers(), AtEOXact_ComboCid(), AtEOXact_Enum(), AtEOXact_Files(), AtEOXact_GUC(), AtEOXact_HashTables(), AtEOXact_LargeObject(), AtEOXact_LogicalCtl(), AtEOXact_LogicalRepWorkers(), AtEOXact_Namespace(), AtEOXact_on_commit_actions(), AtEOXact_RelationCache(), AtEOXact_RI(), AtEOXact_SMgr(), AtEOXact_Snapshot(), AtEOXact_SPI(), AtEOXact_TypeCache(), AtPrepare_Locks(), AtPrepare_MultiXact(), AtPrepare_Notify(), AtPrepare_PgStat(), AtPrepare_PredicateLocks(), AtPrepare_RelationMap(), CallXactCallbacks(), TransactionStateData::childXids, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, disable_timeout(), elog, EndPrepare(), ereport, errcode(), errmsg, ERROR, fb(), TransactionStateData::fullTransactionId, GetCurrentFullTransactionId(), GetCurrentTimestamp(), GetUserId(), TransactionStateData::gucNestLevel, HOLD_INTERRUPTS, InvalidFullTransactionId, InvalidSubTransactionId, IsInParallelMode(), MarkAsPreparing(), TransactionStateData::maxChildXids, MyDatabaseId, MyProc, MyXactFlags, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, nParallelCurrentXids, TransactionStateData::parent, pgstat_report_xact_timestamp(), PostPrepare_Inval(), PostPrepare_Locks(), PostPrepare_MultiXact(), PostPrepare_PgStat(), PostPrepare_PredicateLocks(), PostPrepare_smgr(), PostPrepare_Twophase(), PreCommit_CheckForSerializationFailure(), PreCommit_on_commit_actions(), PreCommit_Portals(), prepareGID, ProcArrayClearTransaction(), RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerDelete(), ResourceOwnerRelease(), RESUME_INTERRUPTS, ShowTransactionState(), smgrDoPendingSyncs(), StartPrepare(), TransactionStateData::state, TransactionStateData::subTransactionId, TopTransactionResourceOwner, TRANS_DEFAULT, TRANS_INPROGRESS, TRANS_PREPARE, TRANSACTION_TIMEOUT, TransactionTimeout, TransStateAsString(), WARNING, XACT_EVENT_PRE_PREPARE, XACT_EVENT_PREPARE, XACT_FLAGS_ACCESSEDTEMPNAMESPACE, XactHasExportedSnapshots(), XactLastRecEnd, and XactTopFullTransactionId.

Referenced by CommitTransactionCommandInternal().

◆ PrepareTransactionBlock()

bool PrepareTransactionBlock ( const char gid)

Definition at line 4046 of file xact.c.

4047{
4049 bool result;
4050
4051 /* Set up to commit the current transaction */
4052 result = EndTransactionBlock(false);
4053
4054 /* If successful, change outer tblock state to PREPARE */
4055 if (result)
4056 {
4058
4059 while (s->parent != NULL)
4060 s = s->parent;
4061
4062 if (s->blockState == TBLOCK_END)
4063 {
4064 /* Save GID where PrepareTransaction can find it again */
4066
4068 }
4069 else
4070 {
4071 /*
4072 * ignore case where we are not in a transaction;
4073 * EndTransactionBlock already issued a warning.
4074 */
4077 /* Don't send back a PREPARE result tag... */
4078 result = false;
4079 }
4080 }
4081
4082 return result;
4083}

References Assert, TransactionStateData::blockState, CurrentTransactionState, EndTransactionBlock(), fb(), MemoryContextStrdup(), TransactionStateData::parent, prepareGID, result, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, and TopTransactionContext.

Referenced by apply_handle_prepare_internal(), and standard_ProcessUtility().

◆ PreventInTransactionBlock()

void PreventInTransactionBlock ( bool  isTopLevel,
const char stmtType 
)

Definition at line 3701 of file xact.c.

3702{
3703 /*
3704 * xact block already started?
3705 */
3706 if (IsTransactionBlock())
3707 ereport(ERROR,
3709 /* translator: %s represents an SQL statement name */
3710 errmsg("%s cannot run inside a transaction block",
3711 stmtType)));
3712
3713 /*
3714 * subtransaction?
3715 */
3716 if (IsSubTransaction())
3717 ereport(ERROR,
3719 /* translator: %s represents an SQL statement name */
3720 errmsg("%s cannot run inside a subtransaction",
3721 stmtType)));
3722
3723 /*
3724 * inside a function call?
3725 */
3726 if (!isTopLevel)
3727 ereport(ERROR,
3729 /* translator: %s represents an SQL statement name */
3730 errmsg("%s cannot be executed from a function or procedure",
3731 stmtType)));
3732
3733 /* If we got past IsTransactionBlock test, should be in default state */
3736 elog(FATAL, "cannot prevent transaction chain");
3737
3738 /* All okay. Set the flag to make sure the right thing happens later. */
3740}

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

Referenced by AlterDatabase(), AlterSubscription(), CheckAlterSubOption(), DiscardAll(), DropSubscription(), exec_replication_command(), ExecDropStmt(), ExecReindex(), ExecRepack(), ProcessUtilitySlow(), ReindexPartitions(), standard_ProcessUtility(), and vacuum().

◆ PushTransaction()

static void PushTransaction ( void  )
static

Definition at line 5475 of file xact.c.

5476{
5479
5480 /*
5481 * We keep subtransaction state nodes in TopTransactionContext.
5482 */
5483 s = (TransactionState)
5485 sizeof(TransactionStateData));
5486
5487 /*
5488 * Assign a subtransaction ID, watching out for counter wraparound.
5489 */
5492 {
5494 pfree(s);
5495 ereport(ERROR,
5497 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5498 }
5499
5500 /*
5501 * We can now stack a minimally valid subtransaction without fear of
5502 * failure.
5503 */
5504 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5506 s->parent = p;
5507 s->nestingLevel = p->nestingLevel + 1;
5510 s->state = TRANS_DEFAULT;
5515 s->parallelModeLevel = 0;
5517 s->topXidLogged = false;
5518
5520
5521 /*
5522 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5523 * with the subtransaction from here on out; in particular they should not
5524 * assume that it necessarily has a transaction context, resource owner,
5525 * or XID.
5526 */
5527}

References TransactionStateData::blockState, currentSubTransactionId, CurrentTransactionState, ereport, errcode(), errmsg, ERROR, fb(), TransactionStateData::fullTransactionId, GetUserIdAndSecContext(), TransactionStateData::gucNestLevel, InvalidFullTransactionId, InvalidSubTransactionId, MemoryContextAllocZero(), TransactionStateData::nestingLevel, NewGUCNestLevel(), TransactionStateData::parallelChildXact, TransactionStateData::parallelModeLevel, TransactionStateData::parent, pfree(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, TransactionStateData::prevXactReadOnly, TransactionStateData::savepointLevel, TransactionStateData::startedInRecovery, TransactionStateData::state, TransactionStateData::subTransactionId, TBLOCK_SUBBEGIN, TopTransactionContext, TransactionStateData::topXidLogged, TRANS_DEFAULT, and XactReadOnly.

Referenced by BeginInternalSubTransaction(), and DefineSavepoint().

◆ RecordTransactionAbort()

static TransactionId RecordTransactionAbort ( bool  isSubXact)
static

Definition at line 1796 of file xact.c.

1797{
1800 int nrels;
1801 RelFileLocator *rels;
1802 int ndroppedstats = 0;
1804 int nchildren;
1805 TransactionId *children;
1806 TimestampTz xact_time;
1807 bool replorigin;
1808
1809 /*
1810 * If we haven't been assigned an XID, nobody will care whether we aborted
1811 * or not. Hence, we're done in that case. It does not matter if we have
1812 * rels to delete (note that this routine is not responsible for actually
1813 * deleting 'em). We cannot have any child XIDs, either.
1814 */
1815 if (!TransactionIdIsValid(xid))
1816 {
1817 /* Reset XactLastRecEnd until the next transaction writes something */
1818 if (!isSubXact)
1819 XactLastRecEnd = 0;
1820 return InvalidTransactionId;
1821 }
1822
1823 /*
1824 * We have a valid XID, so we should write an ABORT record for it.
1825 *
1826 * We do not flush XLOG to disk here, since the default assumption after a
1827 * crash would be that we aborted, anyway. For the same reason, we don't
1828 * need to worry about interlocking against checkpoint start.
1829 */
1830
1831 /*
1832 * Check that we haven't aborted halfway through RecordTransactionCommit.
1833 */
1834 if (TransactionIdDidCommit(xid))
1835 elog(PANIC, "cannot abort transaction %u, it was already committed",
1836 xid);
1837
1838 /*
1839 * Are we using the replication origins feature? Or, in other words, are
1840 * we replaying remote actions?
1841 */
1844
1845 /* Fetch the data we need for the abort record */
1846 nrels = smgrGetPendingDeletes(false, &rels);
1849
1850 /* XXX do we really need a critical section here? */
1852
1853 /* Write the ABORT record */
1854 if (isSubXact)
1855 xact_time = GetCurrentTimestamp();
1856 else
1857 {
1859 }
1860
1861 XactLogAbortRecord(xact_time,
1862 nchildren, children,
1863 nrels, rels,
1866 NULL);
1867
1868 if (replorigin)
1869 /* Move LSNs forward for this replication origin */
1872
1873 /*
1874 * Report the latest async abort LSN, so that the WAL writer knows to
1875 * flush this abort. There's nothing to be gained by delaying this, since
1876 * WALWriter may as well do this when it can. This is important with
1877 * streaming replication because if we don't flush WAL regularly we will
1878 * find that large aborts leave us with a long backlog for when commits
1879 * occur after the abort, increasing our window of data loss should
1880 * problems occur at that point.
1881 */
1882 if (!isSubXact)
1884
1885 /*
1886 * Mark the transaction aborted in clog. This is not absolutely necessary
1887 * but we may as well do it while we are here; also, in the subxact case
1888 * it is helpful because XactLockTableWait makes use of it to avoid
1889 * waiting for already-aborted subtransactions. It is OK to do it without
1890 * having flushed the ABORT record to disk, because in event of a crash
1891 * we'd be assumed to have aborted anyway.
1892 */
1893 TransactionIdAbortTree(xid, nchildren, children);
1894
1896
1897 /* Compute latestXid while we have the child XIDs handy */
1898 latestXid = TransactionIdLatest(xid, nchildren, children);
1899
1900 /*
1901 * If we're aborting a subtransaction, we can immediately remove failed
1902 * XIDs from PGPROC's cache of running child XIDs. We do that here for
1903 * subxacts, because we already have the child XID array at hand. For
1904 * main xacts, the equivalent happens just after this function returns.
1905 */
1906 if (isSubXact)
1908
1909 /* Reset XactLastRecEnd until the next transaction writes something */
1910 if (!isSubXact)
1911 XactLastRecEnd = 0;
1912
1913 /* And clean up local data */
1914 if (rels)
1915 pfree(rels);
1916 if (ndroppedstats)
1918
1919 return latestXid;
1920}

References DoNotReplicateId, elog, END_CRIT_SECTION, fb(), GetCurrentTimestamp(), GetCurrentTransactionIdIfAny(), GetCurrentTransactionStopTimestamp(), InvalidReplOriginId, InvalidTransactionId, MyXactFlags, ReplOriginXactState::origin, ReplOriginXactState::origin_lsn, PANIC, pfree(), pgstat_get_transactional_drops(), replorigin_session_advance(), replorigin_xact_state, smgrGetPendingDeletes(), START_CRIT_SECTION, TransactionIdAbortTree(), TransactionIdDidCommit(), TransactionIdIsValid, TransactionIdLatest(), xactGetCommittedChildren(), XactLastRecEnd, XactLogAbortRecord(), XidCacheRemoveRunningXids(), and XLogSetAsyncXactLSN().

Referenced by AbortSubTransaction(), and AbortTransaction().

◆ RecordTransactionCommit()

static TransactionId RecordTransactionCommit ( void  )
static

Definition at line 1345 of file xact.c.

1346{
1350 int nrels;
1351 RelFileLocator *rels;
1352 int nchildren;
1353 TransactionId *children;
1354 int ndroppedstats = 0;
1356 int nmsgs = 0;
1358 bool RelcacheInitFileInval = false;
1359 bool wrote_xlog;
1360
1361 /*
1362 * Log pending invalidations for logical decoding of in-progress
1363 * transactions. Normally for DDLs, we log this at each command end,
1364 * however, for certain cases where we directly update the system table
1365 * without a transaction block, the invalidations are not logged till this
1366 * time.
1367 */
1370
1371 /* Get data needed for commit record */
1372 nrels = smgrGetPendingDeletes(true, &rels);
1377 &RelcacheInitFileInval);
1378 wrote_xlog = (XactLastRecEnd != 0);
1379
1380 /*
1381 * If we haven't been assigned an XID yet, we neither can, nor do we want
1382 * to write a COMMIT record.
1383 */
1384 if (!markXidCommitted)
1385 {
1386 /*
1387 * We expect that every RelationDropStorage is followed by a catalog
1388 * update, and hence XID assignment, so we shouldn't get here with any
1389 * pending deletes. Same is true for dropping stats.
1390 *
1391 * Use a real test not just an Assert to check this, since it's a bit
1392 * fragile.
1393 */
1394 if (nrels != 0 || ndroppedstats != 0)
1395 elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
1396
1397 /* Can't have child XIDs either; AssignTransactionId enforces this */
1398 Assert(nchildren == 0);
1399
1400 /*
1401 * Transactions without an assigned xid can contain invalidation
1402 * messages. While inplace updates do this, this is not known to be
1403 * necessary; see comment at inplace CacheInvalidateHeapTuple().
1404 * Extensions might still rely on this capability, and standbys may
1405 * need to process those invals. We can't emit a commit record
1406 * without an xid, and we don't want to force assigning an xid,
1407 * because that'd be problematic for e.g. vacuum. Hence we emit a
1408 * bespoke record for the invalidations. We don't want to use that in
1409 * case a commit record is emitted, so they happen synchronously with
1410 * commits (besides not wanting to emit more WAL records).
1411 *
1412 * XXX Every known use of this capability is a defect. Since an XID
1413 * isn't controlling visibility of the change that prompted invals,
1414 * other sessions need the inval even if this transactions aborts.
1415 *
1416 * ON COMMIT DELETE ROWS does a nontransactional index_build(), which
1417 * queues a relcache inval, including in transactions without an xid
1418 * that had read the (empty) table. Standbys don't need any ON COMMIT
1419 * DELETE ROWS invals, but we've not done the work to withhold them.
1420 */
1421 if (nmsgs != 0)
1422 {
1424 RelcacheInitFileInval);
1425 wrote_xlog = true; /* not strictly necessary */
1426 }
1427
1428 /*
1429 * If we didn't create XLOG entries, we're done here; otherwise we
1430 * should trigger flushing those entries the same as a commit record
1431 * would. This will primarily happen for HOT pruning and the like; we
1432 * want these to be flushed to disk in due time.
1433 */
1434 if (!wrote_xlog)
1435 goto cleanup;
1436 }
1437 else
1438 {
1439 bool replorigin;
1440
1441 /*
1442 * Are we using the replication origins feature? Or, in other words,
1443 * are we replaying remote actions?
1444 */
1447
1448 /*
1449 * Mark ourselves as within our "commit critical section". This
1450 * forces any concurrent checkpoint to wait until we've updated
1451 * pg_xact. Without this, it is possible for the checkpoint to set
1452 * REDO after the XLOG record but fail to flush the pg_xact update to
1453 * disk, leading to loss of the transaction commit if the system
1454 * crashes a little later.
1455 *
1456 * Note: we could, but don't bother to, set this flag in
1457 * RecordTransactionAbort. That's because loss of a transaction abort
1458 * is noncritical; the presumption would be that it aborted, anyway.
1459 *
1460 * It's safe to change the delayChkptFlags flag of our own backend
1461 * without holding the ProcArrayLock, since we're the only one
1462 * modifying it. This makes checkpoint's determination of which xacts
1463 * are delaying the checkpoint a bit fuzzy, but it doesn't matter.
1464 *
1465 * Note, it is important to get the commit timestamp after marking the
1466 * transaction in the commit critical section. See
1467 * RecordTransactionCommitPrepared.
1468 */
1472
1474
1475 /*
1476 * Ensures the DELAY_CHKPT_IN_COMMIT flag write is globally visible
1477 * before commit time is written.
1478 */
1480
1481 /*
1482 * Insert the commit XLOG record.
1483 */
1485 nchildren, children, nrels, rels,
1487 nmsgs, invalMessages,
1488 RelcacheInitFileInval,
1490 InvalidTransactionId, NULL /* plain commit */ );
1491
1492 if (replorigin)
1493 /* Move LSNs forward for this replication origin */
1496
1497 /*
1498 * Record commit timestamp. The value comes from plain commit
1499 * timestamp if there's no replication origin; otherwise, the
1500 * timestamp was already set in replorigin_xact_state.origin_timestamp
1501 * by replication.
1502 *
1503 * We don't need to WAL-log anything here, as the commit record
1504 * written above already contains the data.
1505 */
1506
1509
1513 }
1514
1515 /*
1516 * Check if we want to commit asynchronously. We can allow the XLOG flush
1517 * to happen asynchronously if synchronous_commit=off, or if the current
1518 * transaction has not performed any WAL-logged operation or didn't assign
1519 * an xid. The transaction can end up not writing any WAL, even if it has
1520 * an xid, if it only wrote to temporary and/or unlogged tables. It can
1521 * end up having written WAL without an xid if it did HOT pruning. In
1522 * case of a crash, the loss of such a transaction will be irrelevant;
1523 * temp tables will be lost anyway, unlogged tables will be truncated and
1524 * HOT pruning will be done again later. (Given the foregoing, you might
1525 * think that it would be unnecessary to emit the XLOG record at all in
1526 * this case, but we don't currently try to do that. It would certainly
1527 * cause problems at least in Hot Standby mode, where the
1528 * KnownAssignedXids machinery requires tracking every XID assignment. It
1529 * might be OK to skip it only when wal_level < replica, but for now we
1530 * don't.)
1531 *
1532 * However, if we're doing cleanup of any non-temp rels or committing any
1533 * command that wanted to force sync commit, then we must flush XLOG
1534 * immediately. (We must not allow asynchronous commit if there are any
1535 * non-temp tables to be deleted, because we might delete the files before
1536 * the COMMIT record is flushed to disk. We do allow asynchronous commit
1537 * if all to-be-deleted tables are temporary though, since they are lost
1538 * anyway if we crash.)
1539 */
1540 if ((wrote_xlog && markXidCommitted &&
1542 forceSyncCommit || nrels > 0)
1543 {
1545
1546 /*
1547 * Now we may update the CLOG, if we wrote a COMMIT record above
1548 */
1549 if (markXidCommitted)
1550 TransactionIdCommitTree(xid, nchildren, children);
1551 }
1552 else
1553 {
1554 /*
1555 * Asynchronous commit case:
1556 *
1557 * This enables possible committed transaction loss in the case of a
1558 * postmaster crash because WAL buffers are left unwritten. Ideally we
1559 * could issue the WAL write without the fsync, but some
1560 * wal_sync_methods do not allow separate write/fsync.
1561 *
1562 * Report the latest async commit LSN, so that the WAL writer knows to
1563 * flush this commit.
1564 */
1566
1567 /*
1568 * We must not immediately update the CLOG, since we didn't flush the
1569 * XLOG. Instead, we store the LSN up to which the XLOG must be
1570 * flushed before the CLOG may be updated.
1571 */
1572 if (markXidCommitted)
1574 }
1575
1576 /*
1577 * If we entered a commit critical section, leave it now, and let
1578 * checkpoints proceed.
1579 */
1580 if (markXidCommitted)
1581 {
1584 }
1585
1586 /* Compute latestXid while we have the child XIDs handy */
1587 latestXid = TransactionIdLatest(xid, nchildren, children);
1588
1589 /*
1590 * Wait for synchronous replication, if required. Similar to the decision
1591 * above about using committing asynchronously we only want to wait if
1592 * this backend assigned an xid and wrote WAL. No need to wait if an xid
1593 * was assigned due to temporary/unlogged tables or due to HOT pruning.
1594 *
1595 * Note that at this stage we have marked clog, but still show as running
1596 * in the procarray and continue to hold locks.
1597 */
1600
1601 /* remember end of last commit record */
1603
1604 /* Reset XactLastRecEnd until the next transaction writes something */
1605 XactLastRecEnd = 0;
1606cleanup:
1607 /* Clean up local data */
1608 if (rels)
1609 pfree(rels);
1610 if (ndroppedstats)
1612
1613 return latestXid;
1614}

References Assert, cleanup(), DELAY_CHKPT_IN_COMMIT, PGPROC::delayChkptFlags, DoNotReplicateId, elog, END_CRIT_SECTION, ERROR, fb(), forceSyncCommit, GetCurrentTransactionStopTimestamp(), GetTopTransactionIdIfAny(), InvalidReplOriginId, InvalidTransactionId, LogLogicalInvalidations(), LogStandbyInvalidations(), MyProc, MyXactFlags, ReplOriginXactState::origin, ReplOriginXactState::origin_lsn, ReplOriginXactState::origin_timestamp, pfree(), pg_write_barrier, pgstat_get_transactional_drops(), replorigin_session_advance(), replorigin_xact_state, smgrGetPendingDeletes(), START_CRIT_SECTION, synchronous_commit, SYNCHRONOUS_COMMIT_OFF, SyncRepWaitForLSN(), TransactionIdAsyncCommitTree(), TransactionIdCommitTree(), TransactionIdIsValid, TransactionIdLatest(), TransactionTreeSetCommitTsData(), xactGetCommittedChildren(), xactGetCommittedInvalidationMessages(), XactLastCommitEnd, XactLastRecEnd, XactLogCommitRecord(), xactStopTimestamp, XLogFlush(), XLogLogicalInfoActive, XLogSetAsyncXactLSN(), and XLogStandbyInfoActive.

Referenced by CommitTransaction().

◆ RegisterSubXactCallback()

void RegisterSubXactCallback ( SubXactCallback  callback,
void arg 
)

◆ RegisterXactCallback()

void RegisterXactCallback ( XactCallback  callback,
void arg 
)

◆ ReleaseCurrentSubTransaction()

void ReleaseCurrentSubTransaction ( void  )

Definition at line 4822 of file xact.c.

4823{
4825
4826 /*
4827 * We do not check for parallel mode here. It's permissible to start and
4828 * end "internal" subtransactions while in parallel mode, so long as no
4829 * new XIDs or command IDs are assigned.
4830 */
4831
4833 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4838 s = CurrentTransactionState; /* changed by pop */
4840}

References Assert, TransactionStateData::blockState, BlockStateAsString(), CommitSubTransaction(), CurrentTransactionState, CurTransactionContext, elog, ERROR, 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().

◆ ReleaseSavepoint()

void ReleaseSavepoint ( const char name)

Definition at line 4512 of file xact.c.

4513{
4515 TransactionState target,
4516 xact;
4517
4518 /*
4519 * Workers synchronize transaction state at the beginning of each parallel
4520 * operation, so we can't account for transaction state change after that
4521 * point. (Note that this check will certainly error out if s->blockState
4522 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4523 * below.)
4524 */
4526 ereport(ERROR,
4528 errmsg("cannot release savepoints during a parallel operation")));
4529
4530 switch (s->blockState)
4531 {
4532 /*
4533 * We can't release a savepoint if there is no savepoint defined.
4534 */
4535 case TBLOCK_INPROGRESS:
4536 ereport(ERROR,
4538 errmsg("savepoint \"%s\" does not exist", name)));
4539 break;
4540
4542 /* See comment about implicit transactions in DefineSavepoint */
4543 ereport(ERROR,
4545 /* translator: %s represents an SQL statement name */
4546 errmsg("%s can only be used in transaction blocks",
4547 "RELEASE SAVEPOINT")));
4548 break;
4549
4550 /*
4551 * We are in a non-aborted subtransaction. This is the only valid
4552 * case.
4553 */
4555 break;
4556
4557 /* These cases are invalid. */
4558 case TBLOCK_DEFAULT:
4559 case TBLOCK_STARTED:
4560 case TBLOCK_BEGIN:
4562 case TBLOCK_SUBBEGIN:
4563 case TBLOCK_END:
4564 case TBLOCK_SUBRELEASE:
4565 case TBLOCK_SUBCOMMIT:
4566 case TBLOCK_ABORT:
4567 case TBLOCK_SUBABORT:
4568 case TBLOCK_ABORT_END:
4572 case TBLOCK_SUBRESTART:
4574 case TBLOCK_PREPARE:
4575 elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4577 break;
4578 }
4579
4580 for (target = s; target; target = target->parent)
4581 {
4582 if (target->name && strcmp(target->name, name) == 0)
4583 break;
4584 }
4585
4586 if (!target)
4587 ereport(ERROR,
4589 errmsg("savepoint \"%s\" does not exist", name)));
4590
4591 /* disallow crossing savepoint level boundaries */
4592 if (target->savepointLevel != s->savepointLevel)
4593 ereport(ERROR,
4595 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4596
4597 /*
4598 * Mark "commit pending" all subtransactions up to the target
4599 * subtransaction. The actual commits will happen when control gets to
4600 * CommitTransactionCommand.
4601 */
4603 for (;;)
4604 {
4605 Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
4606 xact->blockState = TBLOCK_SUBRELEASE;
4607 if (xact == target)
4608 break;
4609 xact = xact->parent;
4610 Assert(xact);
4611 }
4612}

References Assert, TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg, ERROR, FATAL, fb(), IsInParallelMode(), IsParallelWorker, TransactionStateData::name, name, TransactionStateData::parent, TransactionStateData::savepointLevel, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by standard_ProcessUtility().

◆ RequireTransactionBlock()

void RequireTransactionBlock ( bool  isTopLevel,
const char stmtType 
)

Definition at line 3770 of file xact.c.

3771{
3772 CheckTransactionBlock(isTopLevel, true, stmtType);
3773}

References CheckTransactionBlock(), and fb().

Referenced by PerformCursorOpen(), and standard_ProcessUtility().

◆ RestoreTransactionCharacteristics()

◆ RollbackAndReleaseCurrentSubTransaction()

void RollbackAndReleaseCurrentSubTransaction ( void  )

Definition at line 4850 of file xact.c.

4851{
4853
4854 /*
4855 * We do not check for parallel mode here. It's permissible to start and
4856 * end "internal" subtransactions while in parallel mode, so long as no
4857 * new XIDs or command IDs are assigned.
4858 */
4859
4860 switch (s->blockState)
4861 {
4862 /* Must be in a subtransaction */
4864 case TBLOCK_SUBABORT:
4865 break;
4866
4867 /* These cases are invalid. */
4868 case TBLOCK_DEFAULT:
4869 case TBLOCK_STARTED:
4870 case TBLOCK_BEGIN:
4873 case TBLOCK_SUBBEGIN:
4874 case TBLOCK_INPROGRESS:
4875 case TBLOCK_END:
4876 case TBLOCK_SUBRELEASE:
4877 case TBLOCK_SUBCOMMIT:
4878 case TBLOCK_ABORT:
4879 case TBLOCK_ABORT_END:
4883 case TBLOCK_SUBRESTART:
4885 case TBLOCK_PREPARE:
4886 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4888 break;
4889 }
4890
4891 /*
4892 * Abort the current subtransaction, if needed.
4893 */
4896
4897 /* And clean it up, too */
4899
4900 s = CurrentTransactionState; /* changed by pop */
4906}

References AbortSubTransaction(), Assert, 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(), ReorderBufferImmediateInvalidation(), and ReorderBufferProcessTXN().

◆ RollbackToSavepoint()

void RollbackToSavepoint ( const char name)

Definition at line 4621 of file xact.c.

4622{
4624 TransactionState target,
4625 xact;
4626
4627 /*
4628 * Workers synchronize transaction state at the beginning of each parallel
4629 * operation, so we can't account for transaction state change after that
4630 * point. (Note that this check will certainly error out if s->blockState
4631 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4632 * below.)
4633 */
4635 ereport(ERROR,
4637 errmsg("cannot rollback to savepoints during a parallel operation")));
4638
4639 switch (s->blockState)
4640 {
4641 /*
4642 * We can't rollback to a savepoint if there is no savepoint
4643 * defined.
4644 */
4645 case TBLOCK_INPROGRESS:
4646 case TBLOCK_ABORT:
4647 ereport(ERROR,
4649 errmsg("savepoint \"%s\" does not exist", name)));
4650 break;
4651
4653 /* See comment about implicit transactions in DefineSavepoint */
4654 ereport(ERROR,
4656 /* translator: %s represents an SQL statement name */
4657 errmsg("%s can only be used in transaction blocks",
4658 "ROLLBACK TO SAVEPOINT")));
4659 break;
4660
4661 /*
4662 * There is at least one savepoint, so proceed.
4663 */
4665 case TBLOCK_SUBABORT:
4666 break;
4667
4668 /* These cases are invalid. */
4669 case TBLOCK_DEFAULT:
4670 case TBLOCK_STARTED:
4671 case TBLOCK_BEGIN:
4673 case TBLOCK_SUBBEGIN:
4674 case TBLOCK_END:
4675 case TBLOCK_SUBRELEASE:
4676 case TBLOCK_SUBCOMMIT:
4677 case TBLOCK_ABORT_END:
4681 case TBLOCK_SUBRESTART:
4683 case TBLOCK_PREPARE:
4684 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4686 break;
4687 }
4688
4689 for (target = s; target; target = target->parent)
4690 {
4691 if (target->name && strcmp(target->name, name) == 0)
4692 break;
4693 }
4694
4695 if (!target)
4696 ereport(ERROR,
4698 errmsg("savepoint \"%s\" does not exist", name)));
4699
4700 /* disallow crossing savepoint level boundaries */
4701 if (target->savepointLevel != s->savepointLevel)
4702 ereport(ERROR,
4704 errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4705
4706 /*
4707 * Mark "abort pending" all subtransactions up to the target
4708 * subtransaction. The actual aborts will happen when control gets to
4709 * CommitTransactionCommand.
4710 */
4712 for (;;)
4713 {
4714 if (xact == target)
4715 break;
4716 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4718 else if (xact->blockState == TBLOCK_SUBABORT)
4719 xact->blockState = TBLOCK_SUBABORT_END;
4720 else
4721 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4722 BlockStateAsString(xact->blockState));
4723 xact = xact->parent;
4724 Assert(xact);
4725 }
4726
4727 /* And mark the target as "restart pending" */
4728 if (xact->blockState == TBLOCK_SUBINPROGRESS)
4729 xact->blockState = TBLOCK_SUBRESTART;
4730 else if (xact->blockState == TBLOCK_SUBABORT)
4731 xact->blockState = TBLOCK_SUBABORT_RESTART;
4732 else
4733 elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4734 BlockStateAsString(xact->blockState));
4735}

References Assert, TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg, ERROR, FATAL, fb(), IsInParallelMode(), IsParallelWorker, TransactionStateData::name, name, TransactionStateData::parent, TransactionStateData::savepointLevel, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by pa_stream_abort(), and standard_ProcessUtility().

◆ SaveTransactionCharacteristics()

◆ SerializeTransactionState()

void SerializeTransactionState ( Size  maxsize,
char start_address 
)

Definition at line 5599 of file xact.c.

5600{
5602 Size nxids = 0;
5603 Size i = 0;
5604 TransactionId *workspace;
5606
5608
5610 result->xactDeferrable = XactDeferrable;
5611 result->topFullTransactionId = XactTopFullTransactionId;
5612 result->currentFullTransactionId =
5614 result->currentCommandId = currentCommandId;
5615
5616 /*
5617 * If we're running in a parallel worker and launching a parallel worker
5618 * of our own, we can just pass along the information that was passed to
5619 * us.
5620 */
5621 if (nParallelCurrentXids > 0)
5622 {
5623 result->nParallelCurrentXids = nParallelCurrentXids;
5624 memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
5626 return;
5627 }
5628
5629 /*
5630 * OK, we need to generate a sorted list of XIDs that our workers should
5631 * view as current. First, figure out how many there are.
5632 */
5633 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5634 {
5636 nxids = add_size(nxids, 1);
5638 }
5640 <= maxsize);
5641
5642 /* Copy them to our scratch space. */
5643 workspace = palloc(nxids * sizeof(TransactionId));
5644 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5645 {
5647 workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5648 if (s->nChildXids > 0)
5649 memcpy(&workspace[i], s->childXids,
5650 s->nChildXids * sizeof(TransactionId));
5651 i += s->nChildXids;
5652 }
5653 Assert(i == nxids);
5654
5655 /* Sort them. */
5656 qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5657
5658 /* Copy data into output area. */
5659 result->nParallelCurrentXids = nxids;
5660 memcpy(&result->parallelCurrentXids[0], workspace,
5661 nxids * sizeof(TransactionId));
5662}

References add_size(), Assert, TransactionStateData::childXids, currentCommandId, CurrentTransactionState, fb(), TransactionStateData::fullTransactionId, FullTransactionIdIsValid, i, memcpy(), TransactionStateData::nChildXids, nParallelCurrentXids, palloc(), ParallelCurrentXids, TransactionStateData::parent, qsort, result, SerializedTransactionStateHeaderSize, XactDeferrable, XactIsoLevel, SerializedTransactionState::xactIsoLevel, XactTopFullTransactionId, xidComparator(), and XidFromFullTransactionId.

Referenced by InitializeParallelDSM().

◆ SetCurrentStatementStartTimestamp()

◆ SetParallelStartTimestamps()

void SetParallelStartTimestamps ( TimestampTz  xact_ts,
TimestampTz  stmt_ts 
)

Definition at line 861 of file xact.c.

862{
864 xactStartTimestamp = xact_ts;
865 stmtStartTimestamp = stmt_ts;
866}

References Assert, IsParallelWorker, stmtStartTimestamp, and xactStartTimestamp.

Referenced by ParallelWorkerMain().

◆ ShowTransactionState()

static void ShowTransactionState ( const char str)
static

◆ ShowTransactionStateRec()

static void ShowTransactionStateRec ( const char str,
TransactionState  s 
)
static

Definition at line 5719 of file xact.c.

5720{
5722
5723 if (s->parent)
5724 {
5725 /*
5726 * Since this function recurses, it could be driven to stack overflow.
5727 * This is just a debugging aid, so we can leave out some details
5728 * instead of erroring out with check_stack_depth().
5729 */
5730 if (stack_is_too_deep())
5732 (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5733 str, s->nestingLevel)));
5734 else
5736 }
5737
5739 if (s->nChildXids > 0)
5740 {
5741 int i;
5742
5743 appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5744 for (i = 1; i < s->nChildXids; i++)
5745 appendStringInfo(&buf, " %u", s->childXids[i]);
5746 }
5748 (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5749 str, s->nestingLevel,
5750 s->name ? s->name : "unnamed",
5751 BlockStateAsString(s->blockState),
5753 XidFromFullTransactionId(s->fullTransactionId),
5754 s->subTransactionId,
5756 currentCommandIdUsed ? " (used)" : "",
5757 buf.data)));
5758 pfree(buf.data);
5759}

References appendStringInfo(), TransactionStateData::blockState, BlockStateAsString(), buf, TransactionStateData::childXids, currentCommandId, currentCommandIdUsed, DEBUG5, ereport, errmsg_internal(), TransactionStateData::fullTransactionId, i, initStringInfo(), TransactionStateData::name, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, TransactionStateData::parent, pfree(), ShowTransactionStateRec(), stack_is_too_deep(), TransactionStateData::state, str, TransactionStateData::subTransactionId, TransStateAsString(), and XidFromFullTransactionId.

Referenced by ShowTransactionState(), and ShowTransactionStateRec().

◆ StartParallelWorkerTransaction()

◆ StartSubTransaction()

static void StartSubTransaction ( void  )
static

Definition at line 5121 of file xact.c.

5122{
5124
5125 if (s->state != TRANS_DEFAULT)
5126 elog(WARNING, "StartSubTransaction while in %s state",
5128
5129 s->state = TRANS_START;
5130
5131 /*
5132 * Initialize subsystems for new subtransaction
5133 *
5134 * must initialize resource-management stuff first
5135 */
5139
5141
5142 /*
5143 * Call start-of-subxact callbacks
5144 */
5147
5148 ShowTransactionState("StartSubTransaction");
5149}

References AfterTriggerBeginSubXact(), AtSubStart_Memory(), AtSubStart_ResourceOwner(), CallSubXactCallbacks(), CurrentTransactionState, elog, TransactionStateData::parent, ShowTransactionState(), TransactionStateData::state, TransactionStateData::subTransactionId, SUBXACT_EVENT_START_SUB, TRANS_DEFAULT, TRANS_INPROGRESS, TRANS_START, TransStateAsString(), and WARNING.

Referenced by CommitTransactionCommandInternal().

◆ StartTransaction()

static void StartTransaction ( void  )
static

Definition at line 2106 of file xact.c.

2107{
2110
2111 /*
2112 * Let's just make sure the state stack is empty
2113 */
2116
2118
2119 /* check the current transaction state */
2120 Assert(s->state == TRANS_DEFAULT);
2121
2122 /*
2123 * Set the current transaction state information appropriately during
2124 * start processing. Note that once the transaction status is switched
2125 * this process cannot fail until the user ID and the security context
2126 * flags are fetched below.
2127 */
2128 s->state = TRANS_START;
2129 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
2130
2131 /* Determine if statements are logged in this transaction */
2133 (log_xact_sample_rate == 1 ||
2135
2136 /*
2137 * initialize current transaction state fields
2138 *
2139 * note: prevXactReadOnly is not used at the outermost level
2140 */
2141 s->nestingLevel = 1;
2142 s->gucNestLevel = 1;
2143 s->childXids = NULL;
2144 s->nChildXids = 0;
2145 s->maxChildXids = 0;
2146
2147 /*
2148 * Once the current user ID and the security context flags are fetched,
2149 * both will be properly reset even if transaction startup fails.
2150 */
2152
2153 /* SecurityRestrictionContext should never be set outside a transaction */
2154 Assert(s->prevSecContext == 0);
2155
2156 /*
2157 * Make sure we've reset xact state variables
2158 *
2159 * If recovery is still in progress, mark this transaction as read-only.
2160 * We have lower level defences in XLogInsert and elsewhere to stop us
2161 * from modifying data during recovery, but this gives the normal
2162 * indication to the user that the transaction is read-only.
2163 */
2164 if (RecoveryInProgress())
2165 {
2166 s->startedInRecovery = true;
2167 XactReadOnly = true;
2168 }
2169 else
2170 {
2171 s->startedInRecovery = false;
2173 }
2176 forceSyncCommit = false;
2177 MyXactFlags = 0;
2178
2179 /*
2180 * reinitialize within-transaction counters
2181 */
2185 currentCommandIdUsed = false;
2186
2187 /*
2188 * initialize reported xid accounting
2189 */
2190 nUnreportedXids = 0;
2191 s->didLogXid = false;
2192
2193 /*
2194 * must initialize resource-management stuff first
2195 */
2198
2199 /*
2200 * Assign a new LocalTransactionId, and combine it with the proc number to
2201 * form a virtual transaction id.
2202 */
2203 vxid.procNumber = MyProcNumber;
2205
2206 /*
2207 * Lock the virtual transaction id before we announce it in the proc array
2208 */
2210
2211 /*
2212 * Advertise it in the proc array. We assume assignment of
2213 * localTransactionId is atomic, and the proc number should be set
2214 * already.
2215 */
2218
2220
2221 /*
2222 * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2223 * be the same as the first command's statement_timestamp(), so don't do a
2224 * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2225 * for transactions started inside procedures (i.e., nonatomic SPI
2226 * contexts), we do need to advance the timestamp. Also, in a parallel
2227 * worker, the timestamp should already have been provided by a call to
2228 * SetParallelStartTimestamps().
2229 */
2230 if (!IsParallelWorker())
2231 {
2234 else
2236 }
2237 else
2240 /* Mark xactStopTimestamp as unset. */
2242
2243 /*
2244 * initialize other subsystems for new transaction
2245 */
2246 AtStart_GUC();
2247 AtStart_Cache();
2249
2250 /*
2251 * done with start processing, set current transaction state to "in
2252 * progress"
2253 */
2255
2256 /* Schedule transaction timeout */
2257 if (TransactionTimeout > 0)
2259
2260 ShowTransactionState("StartTransaction");
2261}

References AfterTriggerBeginXact(), Assert, AtStart_Cache(), AtStart_GUC(), AtStart_Memory(), AtStart_ResourceOwner(), TransactionStateData::childXids, currentCommandId, currentCommandIdUsed, currentSubTransactionId, CurrentTransactionState, DefaultXactDeferrable, DefaultXactIsoLevel, DefaultXactReadOnly, TransactionStateData::didLogXid, enable_timeout_after(), fb(), FirstCommandId, forceSyncCommit, TransactionStateData::fullTransactionId, FullTransactionIdIsValid, GetCurrentTimestamp(), GetNextLocalTransactionId(), GetUserIdAndSecContext(), TransactionStateData::gucNestLevel, InvalidFullTransactionId, IsParallelWorker, VirtualTransactionId::localTransactionId, log_xact_sample_rate, PGPROC::lxid, TransactionStateData::maxChildXids, MyProc, MyProcNumber, MyXactFlags, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, nUnreportedXids, pg_global_prng_state, pg_prng_double(), pgstat_report_xact_timestamp(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, VirtualTransactionId::procNumber, PGPROC::procNumber, RecoveryInProgress(), ShowTransactionState(), SPI_inside_nonatomic_context(), TransactionStateData::startedInRecovery, TransactionStateData::state, stmtStartTimestamp, TransactionStateData::subTransactionId, TopSubTransactionId, TopTransactionStateData, TRANS_DEFAULT, TRANS_INPROGRESS, TRANS_START, TRANSACTION_TIMEOUT, TransactionTimeout, VirtualXactLockTableInsert(), PGPROC::vxid, xact_is_sampled, XactDeferrable, XactIsoLevel, XactReadOnly, xactStartTimestamp, xactStopTimestamp, and XactTopFullTransactionId.

Referenced by _doSetFixedOutputState(), CommitTransactionCommandInternal(), IssueCommandPerBlob(), restore_toc_entry(), RestoreArchive(), StartParallelWorkerTransaction(), StartRestoreLOs(), and StartTransactionCommand().

◆ StartTransactionCommand()

void StartTransactionCommand ( void  )

Definition at line 3112 of file xact.c.

3113{
3115
3116 switch (s->blockState)
3117 {
3118 /*
3119 * if we aren't in a transaction block, we just do our usual start
3120 * transaction.
3121 */
3122 case TBLOCK_DEFAULT:
3125 break;
3126
3127 /*
3128 * We are somewhere in a transaction block or subtransaction and
3129 * about to start a new command. For now we do nothing, but
3130 * someday we may do command-local resource initialization. (Note
3131 * that any needed CommandCounterIncrement was done by the
3132 * previous CommitTransactionCommand.)
3133 */
3134 case TBLOCK_INPROGRESS:
3137 break;
3138
3139 /*
3140 * Here we are in a failed transaction block (one of the commands
3141 * caused an abort) so we do nothing but remain in the abort
3142 * state. Eventually we will get a ROLLBACK command which will
3143 * get us out of this state. (It is up to other code to ensure
3144 * that no commands other than ROLLBACK will be processed in these
3145 * states.)
3146 */
3147 case TBLOCK_ABORT:
3148 case TBLOCK_SUBABORT:
3149 break;
3150
3151 /* These cases are invalid. */
3152 case TBLOCK_STARTED:
3153 case TBLOCK_BEGIN:
3155 case TBLOCK_SUBBEGIN:
3156 case TBLOCK_END:
3157 case TBLOCK_SUBRELEASE:
3158 case TBLOCK_SUBCOMMIT:
3159 case TBLOCK_ABORT_END:
3163 case TBLOCK_SUBRESTART:
3165 case TBLOCK_PREPARE:
3166 elog(ERROR, "StartTransactionCommand: unexpected state %s",
3168 break;
3169 }
3170
3171 /*
3172 * We must switch to CurTransactionContext before returning. This is
3173 * already done if we called StartTransaction, otherwise not.
3174 */
3177}

References Assert, TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, CurTransactionContext, elog, ERROR, fb(), 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 _SPI_commit(), _SPI_rollback(), apply_handle_commit_internal(), ATExecDetachPartition(), autoprewarm_database_main(), bbsink_server_new(), begin_replication_step(), BeginInternalSubTransaction(), BootstrapModeMain(), BuildDatabaseList(), BuildRelationList(), clear_subscription_skip_lsn(), copy_sequences(), DatabaseExists(), DefineIndex(), DisableSubscriptionAndExit(), do_autovacuum(), EventTriggerOnLogin(), exec_replication_command(), ExecRepack(), FetchRelationStates(), FinishSyncWorker(), get_database_list(), get_subscription_list(), IdentifySystem(), index_drop(), initialize_worker_spi(), InitializeLogRepWorker(), InitPostgres(), LogicalRepSyncSequences(), LogicalRepSyncTableStart(), maybe_reread_subscription(), movedb(), pa_start_subtrans(), ParallelApplyWorkerMain(), ParallelWorkerMain(), perform_work_item(), process_single_relation(), ProcessCatchupInterrupt(), ProcessIncomingNotify(), ProcessSingleRelationByOid(), ProcessSyncingTablesForApply(), ProcessSyncingTablesForSync(), ReindexMultipleInternal(), ReindexRelationConcurrently(), RemoveTempRelationsCallback(), ReorderBufferProcessTXN(), RepackWorkerMain(), ReplSlotSyncWorkerMain(), run_apply_worker(), shell_check_detail(), SnapBuildExportSnapshot(), start_xact_command(), update_retention_status(), vacuum(), vacuum_rel(), validate_remote_info(), and worker_spi_main().

◆ SubTransactionIsActive()

bool SubTransactionIsActive ( SubTransactionId  subxid)

Definition at line 807 of file xact.c.

808{
810
811 for (s = CurrentTransactionState; s != NULL; s = s->parent)
812 {
813 if (s->state == TRANS_ABORT)
814 continue;
815 if (s->subTransactionId == subxid)
816 return true;
817 }
818 return false;
819}

References CurrentTransactionState, fb(), TransactionStateData::parent, TransactionStateData::state, TransactionStateData::subTransactionId, and TRANS_ABORT.

◆ TransactionBlockStatusCode()

char TransactionBlockStatusCode ( void  )

Definition at line 5057 of file xact.c.

5058{
5060
5061 switch (s->blockState)
5062 {
5063 case TBLOCK_DEFAULT:
5064 case TBLOCK_STARTED:
5065 return 'I'; /* idle --- not in transaction */
5066 case TBLOCK_BEGIN:
5067 case TBLOCK_SUBBEGIN:
5068 case TBLOCK_INPROGRESS:
5072 case TBLOCK_END:
5073 case TBLOCK_SUBRELEASE:
5074 case TBLOCK_SUBCOMMIT:
5075 case TBLOCK_PREPARE:
5076 return 'T'; /* in transaction */
5077 case TBLOCK_ABORT:
5078 case TBLOCK_SUBABORT:
5079 case TBLOCK_ABORT_END:
5083 case TBLOCK_SUBRESTART:
5085 return 'E'; /* in failed transaction */
5086 }
5087
5088 /* should never get here */
5089 elog(FATAL, "invalid transaction block state: %s",
5091 return 0; /* keep compiler quiet */
5092}

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

◆ TransactionIdIsCurrentTransactionId()

bool TransactionIdIsCurrentTransactionId ( TransactionId  xid)

Definition at line 943 of file xact.c.

944{
946
947 /*
948 * We always say that BootstrapTransactionId is "not my transaction ID"
949 * even when it is (ie, during bootstrap). Along with the fact that
950 * transam.c always treats BootstrapTransactionId as already committed,
951 * this causes the heapam_visibility.c routines to see all tuples as
952 * committed, which is what we need during bootstrap. (Bootstrap mode
953 * only inserts tuples, it never updates or deletes them, so all tuples
954 * can be presumed good immediately.)
955 *
956 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
957 * not my transaction ID, so we can just return "false" immediately for
958 * any non-normal XID.
959 */
960 if (!TransactionIdIsNormal(xid))
961 return false;
962
964 return true;
965
966 /*
967 * In parallel workers, the XIDs we must consider as current are stored in
968 * ParallelCurrentXids rather than the transaction-state stack. Note that
969 * the XIDs in this array are sorted numerically rather than according to
970 * transactionIdPrecedes order.
971 */
972 if (nParallelCurrentXids > 0)
973 {
974 int low,
975 high;
976
977 low = 0;
978 high = nParallelCurrentXids - 1;
979 while (low <= high)
980 {
981 int middle;
983
984 middle = low + (high - low) / 2;
986 if (probe == xid)
987 return true;
988 else if (probe < xid)
989 low = middle + 1;
990 else
991 high = middle - 1;
992 }
993 return false;
994 }
995
996 /*
997 * We will return true for the Xid of the current subtransaction, any of
998 * its subcommitted children, any of its parents, or any of their
999 * previously subcommitted children. However, a transaction being aborted
1000 * is no longer "current", even though it may still have an entry on the
1001 * state stack.
1002 */
1003 for (s = CurrentTransactionState; s != NULL; s = s->parent)
1004 {
1005 int low,
1006 high;
1007
1008 if (s->state == TRANS_ABORT)
1009 continue;
1011 continue; /* it can't have any child XIDs either */
1013 return true;
1014 /* As the childXids array is ordered, we can use binary search */
1015 low = 0;
1016 high = s->nChildXids - 1;
1017 while (low <= high)
1018 {
1019 int middle;
1021
1022 middle = low + (high - low) / 2;
1023 probe = s->childXids[middle];
1024 if (TransactionIdEquals(probe, xid))
1025 return true;
1026 else if (TransactionIdPrecedes(probe, xid))
1027 low = middle + 1;
1028 else
1029 high = middle - 1;
1030 }
1031 }
1032
1033 return false;
1034}

References TransactionStateData::childXids, CurrentTransactionState, fb(), TransactionStateData::fullTransactionId, FullTransactionIdIsValid, GetTopTransactionIdIfAny(), TransactionStateData::nChildXids, nParallelCurrentXids, ParallelCurrentXids, TransactionStateData::parent, TransactionStateData::state, TRANS_ABORT, TransactionIdEquals, TransactionIdIsNormal, TransactionIdPrecedes(), and XidFromFullTransactionId.

Referenced by compute_new_xmax_infomask(), Do_MultiXactIdWait(), DoesMultiXactIdConflict(), ExecCheckTupleVisible(), ExecMergeMatched(), ExecOnConflictLockRow(), FreezeMultiXactId(), get_xid_status(), heap_delete(), heap_inplace_lock(), heap_lock_tuple(), heap_update(), heapam_index_build_range_scan(), heapam_relation_copy_for_cluster(), heapam_scan_analyze_next_tuple(), heapam_tuple_lock(), HeapTupleCleanMoved(), HeapTupleHeaderAdjustCmax(), HeapTupleHeaderGetCmax(), HeapTupleHeaderGetCmin(), HeapTupleHeaderIsOnlyLocked(), HeapTupleSatisfiesDirty(), HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesSelf(), HeapTupleSatisfiesUpdate(), HeapTupleSatisfiesVacuumHorizon(), MultiXactIdIsRunning(), PredicateLockTID(), SnapBuildWaitSnapshot(), test_lockmode_for_conflict(), TransactionIdIsInProgress(), tts_buffer_is_current_xact_tuple(), and tts_heap_is_current_xact_tuple().

◆ TransactionStartedDuringRecovery()

bool TransactionStartedDuringRecovery ( void  )

Definition at line 1044 of file xact.c.

1045{
1047}

References CurrentTransactionState, and TransactionStateData::startedInRecovery.

Referenced by RelationGetIndexScan().

◆ TransStateAsString()

static const char * TransStateAsString ( TransState  state)
static

Definition at line 5819 of file xact.c.

5820{
5821 switch (state)
5822 {
5823 case TRANS_DEFAULT:
5824 return "DEFAULT";
5825 case TRANS_START:
5826 return "START";
5827 case TRANS_INPROGRESS:
5828 return "INPROGRESS";
5829 case TRANS_COMMIT:
5830 return "COMMIT";
5831 case TRANS_ABORT:
5832 return "ABORT";
5833 case TRANS_PREPARE:
5834 return "PREPARE";
5835 }
5836 return "UNRECOGNIZED";
5837}

References TRANS_ABORT, TRANS_COMMIT, TRANS_DEFAULT, TRANS_INPROGRESS, TRANS_PREPARE, and TRANS_START.

Referenced by AbortSubTransaction(), AbortTransaction(), CleanupSubTransaction(), CleanupTransaction(), CommitSubTransaction(), CommitTransaction(), PopTransaction(), PrepareTransaction(), ShowTransactionStateRec(), and StartSubTransaction().

◆ UnregisterSubXactCallback()

void UnregisterSubXactCallback ( SubXactCallback  callback,
void arg 
)

Definition at line 3931 of file xact.c.

3932{
3933 SubXactCallbackItem *item;
3934 SubXactCallbackItem *prev;
3935
3936 prev = NULL;
3937 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3938 {
3939 if (item->callback == callback && item->arg == arg)
3940 {
3941 if (prev)
3942 prev->next = item->next;
3943 else
3944 SubXact_callbacks = item->next;
3945 pfree(item);
3946 break;
3947 }
3948 }
3949}

References SubXactCallbackItem::arg, arg, SubXactCallbackItem::callback, callback(), fb(), SubXactCallbackItem::next, pfree(), and SubXact_callbacks.

◆ UnregisterXactCallback()

void UnregisterXactCallback ( XactCallback  callback,
void arg 
)

Definition at line 3871 of file xact.c.

3872{
3873 XactCallbackItem *item;
3874 XactCallbackItem *prev;
3875
3876 prev = NULL;
3877 for (item = Xact_callbacks; item; prev = item, item = item->next)
3878 {
3879 if (item->callback == callback && item->arg == arg)
3880 {
3881 if (prev)
3882 prev->next = item->next;
3883 else
3884 Xact_callbacks = item->next;
3885 pfree(item);
3886 break;
3887 }
3888 }
3889}

References XactCallbackItem::arg, arg, XactCallbackItem::callback, callback(), fb(), XactCallbackItem::next, pfree(), and Xact_callbacks.

◆ UserAbortTransactionBlock()

void UserAbortTransactionBlock ( bool  chain)

Definition at line 4258 of file xact.c.

4259{
4261
4262 switch (s->blockState)
4263 {
4264 /*
4265 * We are inside a transaction block and we got a ROLLBACK command
4266 * from the user, so tell CommitTransactionCommand to abort and
4267 * exit the transaction block.
4268 */
4269 case TBLOCK_INPROGRESS:
4271 break;
4272
4273 /*
4274 * We are inside a failed transaction block and we got a ROLLBACK
4275 * command from the user. Abort processing is already done, so
4276 * CommitTransactionCommand just has to cleanup and go back to
4277 * idle state.
4278 */
4279 case TBLOCK_ABORT:
4281 break;
4282
4283 /*
4284 * We are inside a subtransaction. Mark everything up to top
4285 * level as exitable.
4286 */
4288 case TBLOCK_SUBABORT:
4289 while (s->parent != NULL)
4290 {
4293 else if (s->blockState == TBLOCK_SUBABORT)
4295 else
4296 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4298 s = s->parent;
4299 }
4300 if (s->blockState == TBLOCK_INPROGRESS)
4302 else if (s->blockState == TBLOCK_ABORT)
4304 else
4305 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4307 break;
4308
4309 /*
4310 * The user issued ABORT when not inside a transaction. For
4311 * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4312 * The upcoming call to CommitTransactionCommand() will then put
4313 * us back into the default state. For ROLLBACK AND CHAIN, error.
4314 *
4315 * We do the same thing with ABORT inside an implicit transaction,
4316 * although in this case we might be rolling back actual database
4317 * state changes. (It's debatable whether we should issue a
4318 * WARNING in this case, but we have done so historically.)
4319 */
4320 case TBLOCK_STARTED:
4322 if (chain)
4323 ereport(ERROR,
4325 /* translator: %s represents an SQL statement name */
4326 errmsg("%s can only be used in transaction blocks",
4327 "ROLLBACK AND CHAIN")));
4328 else
4331 errmsg("there is no transaction in progress")));
4333 break;
4334
4335 /*
4336 * The user issued an ABORT that somehow ran inside a parallel
4337 * worker. We can't cope with that.
4338 */
4340 ereport(FATAL,
4342 errmsg("cannot abort during a parallel operation")));
4343 break;
4344
4345 /* These cases are invalid. */
4346 case TBLOCK_DEFAULT:
4347 case TBLOCK_BEGIN:
4348 case TBLOCK_SUBBEGIN:
4349 case TBLOCK_END:
4350 case TBLOCK_SUBRELEASE:
4351 case TBLOCK_SUBCOMMIT:
4352 case TBLOCK_ABORT_END:
4356 case TBLOCK_SUBRESTART:
4358 case TBLOCK_PREPARE:
4359 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4361 break;
4362 }
4363
4366
4367 s->chain = chain;
4368}

References Assert, TransactionStateData::blockState, BlockStateAsString(), TransactionStateData::chain, CurrentTransactionState, elog, ereport, errcode(), errmsg, ERROR, FATAL, fb(), 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().

◆ WarnNoTransactionBlock()

void WarnNoTransactionBlock ( bool  isTopLevel,
const char stmtType 
)

Definition at line 3764 of file xact.c.

3765{
3766 CheckTransactionBlock(isTopLevel, false, stmtType);
3767}

References CheckTransactionBlock(), and fb().

Referenced by ExecSetVariableStmt(), and standard_ProcessUtility().

◆ xact_redo()

void xact_redo ( XLogReaderState record)

Definition at line 6422 of file xact.c.

6423{
6424 uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6425
6426 /* Backup blocks are not used in xact records */
6428
6429 if (info == XLOG_XACT_COMMIT)
6430 {
6433
6436 record->EndRecPtr, XLogRecGetOrigin(record));
6437 }
6438 else if (info == XLOG_XACT_COMMIT_PREPARED)
6439 {
6442
6444 xact_redo_commit(&parsed, parsed.twophase_xid,
6445 record->EndRecPtr, XLogRecGetOrigin(record));
6446
6447 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6449 PrepareRedoRemove(parsed.twophase_xid, false);
6451 }
6452 else if (info == XLOG_XACT_ABORT)
6453 {
6456
6459 record->EndRecPtr, XLogRecGetOrigin(record));
6460 }
6461 else if (info == XLOG_XACT_ABORT_PREPARED)
6462 {
6465
6467 xact_redo_abort(&parsed, parsed.twophase_xid,
6468 record->EndRecPtr, XLogRecGetOrigin(record));
6469
6470 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6472 PrepareRedoRemove(parsed.twophase_xid, false);
6474 }
6475 else if (info == XLOG_XACT_PREPARE)
6476 {
6477 /*
6478 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6479 * gxact entry.
6480 */
6483 XLogRecGetData(record),
6484 record->ReadRecPtr,
6485 record->EndRecPtr,
6486 XLogRecGetOrigin(record));
6488 }
6489 else if (info == XLOG_XACT_ASSIGNMENT)
6490 {
6492
6495 xlrec->nsubxacts, xlrec->xsub);
6496 }
6497 else if (info == XLOG_XACT_INVALIDATIONS)
6498 {
6499 /*
6500 * XXX we do ignore this for now, what matters are invalidations
6501 * written into the commit record.
6502 */
6503 }
6504 else
6505 elog(PANIC, "xact_redo: unknown op code %u", info);
6506}

References Assert, elog, XLogReaderState::EndRecPtr, fb(), InvalidFullTransactionId, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), PANIC, ParseAbortRecord(), ParseCommitRecord(), PrepareRedoAdd(), PrepareRedoRemove(), ProcArrayApplyXidAssignment(), XLogReaderState::ReadRecPtr, STANDBY_INITIALIZED, standbyState, 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_INVALIDATIONS, XLOG_XACT_OPMASK, XLOG_XACT_PREPARE, XLogRecGetData, XLogRecGetInfo, XLogRecGetOrigin, XLogRecGetXid, and XLogRecHasAnyBlockRefs.

◆ xact_redo_abort()

static void xact_redo_abort ( xl_xact_parsed_abort parsed,
TransactionId  xid,
XLogRecPtr  lsn,
ReplOriginId  origin_id 
)
static

Definition at line 6343 of file xact.c.

6345{
6347
6349
6350 /* Make sure nextXid is beyond any XID mentioned in the record. */
6352 parsed->nsubxacts,
6353 parsed->subxacts);
6355
6357 {
6358 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6359 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6360 }
6361 else
6362 {
6363 /*
6364 * If a transaction completion record arrives that has as-yet
6365 * unobserved subtransactions then this will not have been fully
6366 * handled by the call to RecordKnownAssignedTransactionIds() in the
6367 * main recovery loop in PerformWalRecovery(). So we need to do
6368 * bookkeeping again to cover that case. This is confusing and it is
6369 * easy to think this call is irrelevant, which has happened three
6370 * times in development already. Leave it in.
6371 */
6373
6374 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6375 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6376
6377 /*
6378 * We must update the ProcArray after we have marked clog.
6379 */
6380 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6381
6382 /*
6383 * There are no invalidation messages to send or undo.
6384 */
6385
6386 /*
6387 * Release locks, if any. There are no invalidations to send.
6388 */
6389 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6390 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6391 }
6392
6393 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6394 {
6395 /* recover apply progress */
6396 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6397 false /* backward */ , false /* WAL */ );
6398 }
6399
6400 /* Make sure files supposed to be dropped are dropped */
6401 if (parsed->nrels > 0)
6402 {
6403 /*
6404 * See comments about update of minimum recovery point on truncation,
6405 * in xact_redo_commit().
6406 */
6407 XLogFlush(lsn);
6408
6409 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6410 }
6411
6412 if (parsed->nstats > 0)
6413 {
6414 /* see equivalent call for relations above */
6415 XLogFlush(lsn);
6416
6417 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6418 }
6419}

References AdvanceNextFullTransactionIdPastXid(), Assert, DropRelationFiles(), ExpireTreeKnownAssignedTransactionIds(), fb(), pgstat_execute_transactional_drops(), RecordKnownAssignedTransactionIds(), replorigin_advance(), STANDBY_DISABLED, StandbyReleaseLockTree(), standbyState, TransactionIdAbortTree(), TransactionIdIsValid, TransactionIdLatest(), XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_ORIGIN, and XLogFlush().

Referenced by xact_redo().

◆ xact_redo_commit()

static void xact_redo_commit ( xl_xact_parsed_commit parsed,
TransactionId  xid,
XLogRecPtr  lsn,
ReplOriginId  origin_id 
)
static

Definition at line 6189 of file xact.c.

6193{
6195 TimestampTz commit_time;
6196
6198
6199 max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
6200
6201 /* Make sure nextXid is beyond any XID mentioned in the record. */
6203
6204 Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) ==
6205 (origin_id == InvalidReplOriginId));
6206
6207 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6208 commit_time = parsed->origin_timestamp;
6209 else
6210 commit_time = parsed->xact_time;
6211
6212 /* Set the transaction commit timestamp and metadata */
6213 TransactionTreeSetCommitTsData(xid, parsed->nsubxacts, parsed->subxacts,
6214 commit_time, origin_id);
6215
6217 {
6218 /*
6219 * Mark the transaction committed in pg_xact.
6220 */
6221 TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
6222 }
6223 else
6224 {
6225 /*
6226 * If a transaction completion record arrives that has as-yet
6227 * unobserved subtransactions then this will not have been fully
6228 * handled by the call to RecordKnownAssignedTransactionIds() in the
6229 * main recovery loop in PerformWalRecovery(). So we need to do
6230 * bookkeeping again to cover that case. This is confusing and it is
6231 * easy to think this call is irrelevant, which has happened three
6232 * times in development already. Leave it in.
6233 */
6235
6236 /*
6237 * Mark the transaction committed in pg_xact. We use async commit
6238 * protocol during recovery to provide information on database
6239 * consistency for when users try to set hint bits. It is important
6240 * that we do not set hint bits until the minRecoveryPoint is past
6241 * this commit record. This ensures that if we crash we don't see hint
6242 * bits set on changes made by transactions that haven't yet
6243 * recovered. It's unlikely but it's good to be safe.
6244 */
6245 TransactionIdAsyncCommitTree(xid, parsed->nsubxacts, parsed->subxacts, lsn);
6246
6247 /*
6248 * We must mark clog before we update the ProcArray.
6249 */
6250 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6251
6252 /*
6253 * Send any cache invalidations attached to the commit. We must
6254 * maintain the same order of invalidation then release locks as
6255 * occurs in CommitTransaction().
6256 */
6259 parsed->dbId, parsed->tsId);
6260
6261 /*
6262 * Release locks, if any. We do this for both two phase and normal one
6263 * phase transactions. In effect we are ignoring the prepare phase and
6264 * just going straight to lock release.
6265 */
6266 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6267 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6268 }
6269
6270 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6271 {
6272 /* recover apply progress */
6273 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6274 false /* backward */ , false /* WAL */ );
6275 }
6276
6277 /* Make sure files supposed to be dropped are dropped */
6278 if (parsed->nrels > 0)
6279 {
6280 /*
6281 * First update minimum recovery point to cover this WAL record. Once
6282 * a relation is deleted, there's no going back. The buffer manager
6283 * enforces the WAL-first rule for normal updates to relation files,
6284 * so that the minimum recovery point is always updated before the
6285 * corresponding change in the data file is flushed to disk, but we
6286 * have to do the same here since we're bypassing the buffer manager.
6287 *
6288 * Doing this before deleting the files means that if a deletion fails
6289 * for some reason, you cannot start up the system even after restart,
6290 * until you fix the underlying situation so that the deletion will
6291 * succeed. Alternatively, we could update the minimum recovery point
6292 * after deletion, but that would leave a small window where the
6293 * WAL-first rule would be violated.
6294 */
6295 XLogFlush(lsn);
6296
6297 /* Make sure files supposed to be dropped are dropped */
6298 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6299 }
6300
6301 if (parsed->nstats > 0)
6302 {
6303 /* see equivalent call for relations above */
6304 XLogFlush(lsn);
6305
6306 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6307 }
6308
6309 /*
6310 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
6311 * in normal operation. For example, in CREATE DATABASE, we copy all files
6312 * from the template database, and then commit the transaction. If we
6313 * crash after all the files have been copied but before the commit, you
6314 * have files in the data directory without an entry in pg_database. To
6315 * minimize the window for that, we use ForceSyncCommit() to rush the
6316 * commit record to disk as quick as possible. We have the same window
6317 * during recovery, and forcing an XLogFlush() (which updates
6318 * minRecoveryPoint during recovery) helps to reduce that problem window,
6319 * for any user that requested ForceSyncCommit().
6320 */
6322 XLogFlush(lsn);
6323
6324 /*
6325 * If asked by the primary (because someone is waiting for a synchronous
6326 * commit = remote_apply), we will need to ask walreceiver to send a reply
6327 * immediately.
6328 */
6331}

References AdvanceNextFullTransactionIdPastXid(), Assert, DropRelationFiles(), ExpireTreeKnownAssignedTransactionIds(), fb(), InvalidReplOriginId, pgstat_execute_transactional_drops(), ProcessCommittedInvalidationMessages(), RecordKnownAssignedTransactionIds(), replorigin_advance(), STANDBY_DISABLED, StandbyReleaseLockTree(), standbyState, TransactionIdAsyncCommitTree(), TransactionIdCommitTree(), TransactionIdIsValid, TransactionIdLatest(), TransactionTreeSetCommitTsData(), XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_ORIGIN, XactCompletionApplyFeedback, XactCompletionForceSyncCommit, XactCompletionRelcacheInitFileInval, XLogFlush(), and XLogRequestWalReceiverReply().

Referenced by xact_redo().

◆ xactGetCommittedChildren()

int xactGetCommittedChildren ( TransactionId **  ptr)

Definition at line 5849 of file xact.c.

5850{
5852
5853 if (s->nChildXids == 0)
5854 *ptr = NULL;
5855 else
5856 *ptr = s->childXids;
5857
5858 return s->nChildXids;
5859}

References TransactionStateData::childXids, CurrentTransactionState, fb(), and TransactionStateData::nChildXids.

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

◆ XactLogAbortRecord()

XLogRecPtr XactLogAbortRecord ( TimestampTz  abort_time,
int  nsubxacts,
TransactionId subxacts,
int  nrels,
RelFileLocator rels,
int  ndroppedstats,
xl_xact_stats_item droppedstats,
int  xactflags,
TransactionId  twophase_xid,
const char twophase_gid 
)

Definition at line 6045 of file xact.c.

6051{
6060
6061 uint8 info;
6062
6064
6065 xl_xinfo.xinfo = 0;
6066
6067 /* decide between a plain and 2pc abort */
6068 if (!TransactionIdIsValid(twophase_xid))
6069 info = XLOG_XACT_ABORT;
6070 else
6072
6073
6074 /* First figure out and collect all the information needed */
6075
6076 xlrec.xact_time = abort_time;
6077
6080
6081 if (nsubxacts > 0)
6082 {
6084 xl_subxacts.nsubxacts = nsubxacts;
6085 }
6086
6087 if (nrels > 0)
6088 {
6090 xl_relfilelocators.nrels = nrels;
6091 info |= XLR_SPECIAL_REL_UPDATE;
6092 }
6093
6094 if (ndroppedstats > 0)
6095 {
6098 }
6099
6100 if (TransactionIdIsValid(twophase_xid))
6101 {
6103 xl_twophase.xid = twophase_xid;
6104 Assert(twophase_gid != NULL);
6105
6108 }
6109
6110 if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6111 {
6113 xl_dbinfo.dbId = MyDatabaseId;
6115 }
6116
6117 /*
6118 * Dump transaction origin information. We need this during recovery to
6119 * update the replication origin progress.
6120 */
6122 {
6124
6127 }
6128
6129 if (xl_xinfo.xinfo != 0)
6130 info |= XLOG_XACT_HAS_INFO;
6131
6132 /* Then include all the collected data into the abort record. */
6133
6135
6137
6138 if (xl_xinfo.xinfo != 0)
6140
6141 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6143
6145 {
6148 XLogRegisterData(subxacts,
6149 nsubxacts * sizeof(TransactionId));
6150 }
6151
6153 {
6156 XLogRegisterData(rels,
6157 nrels * sizeof(RelFileLocator));
6158 }
6159
6161 {
6166 }
6167
6169 {
6171 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6172 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6173 }
6174
6175 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6177
6178 /* Include the replication origin */
6180
6181 return XLogInsert(RM_XACT_ID, info);
6182}

References Assert, CritSectionCount, fb(), InvalidReplOriginId, MinSizeOfXactAbort, MinSizeOfXactRelfileLocators, MinSizeOfXactStatsItems, MinSizeOfXactSubxacts, MyDatabaseId, MyDatabaseTableSpace, ReplOriginXactState::origin, ReplOriginXactState::origin_lsn, ReplOriginXactState::origin_timestamp, replorigin_xact_state, TransactionIdIsValid, XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK, XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_DBINFO, XACT_XINFO_HAS_DROPPED_STATS, XACT_XINFO_HAS_GID, XACT_XINFO_HAS_ORIGIN, XACT_XINFO_HAS_RELFILELOCATORS, XACT_XINFO_HAS_SUBXACTS, XACT_XINFO_HAS_TWOPHASE, XLOG_INCLUDE_ORIGIN, XLOG_XACT_ABORT, XLOG_XACT_ABORT_PREPARED, XLOG_XACT_HAS_INFO, XLogBeginInsert(), XLogInsert(), XLogLogicalInfoActive, XLogRegisterData(), XLogSetRecordFlags(), and XLR_SPECIAL_REL_UPDATE.

Referenced by RecordTransactionAbort(), and RecordTransactionAbortPrepared().

◆ XactLogCommitRecord()

XLogRecPtr XactLogCommitRecord ( TimestampTz  commit_time,
int  nsubxacts,
TransactionId subxacts,
int  nrels,
RelFileLocator rels,
int  ndroppedstats,
xl_xact_stats_item droppedstats,
int  nmsgs,
SharedInvalidationMessage msgs,
bool  relcacheInval,
int  xactflags,
TransactionId  twophase_xid,
const char twophase_gid 
)

Definition at line 5873 of file xact.c.

5881{
5891 uint8 info;
5892
5894
5895 xl_xinfo.xinfo = 0;
5896
5897 /* decide between a plain and 2pc commit */
5898 if (!TransactionIdIsValid(twophase_xid))
5899 info = XLOG_XACT_COMMIT;
5900 else
5902
5903 /* First figure out and collect all the information needed */
5904
5905 xlrec.xact_time = commit_time;
5906
5907 if (relcacheInval)
5909 if (forceSyncCommit)
5913
5914 /*
5915 * Check if the caller would like to ask standbys for immediate feedback
5916 * once this commit is applied.
5917 */
5920
5921 /*
5922 * Relcache invalidations requires information about the current database
5923 * and so does logical decoding.
5924 */
5925 if (nmsgs > 0 || XLogLogicalInfoActive())
5926 {
5928 xl_dbinfo.dbId = MyDatabaseId;
5930 }
5931
5932 if (nsubxacts > 0)
5933 {
5935 xl_subxacts.nsubxacts = nsubxacts;
5936 }
5937
5938 if (nrels > 0)
5939 {
5941 xl_relfilelocators.nrels = nrels;
5942 info |= XLR_SPECIAL_REL_UPDATE;
5943 }
5944
5945 if (ndroppedstats > 0)
5946 {
5949 }
5950
5951 if (nmsgs > 0)
5952 {
5954 xl_invals.nmsgs = nmsgs;
5955 }
5956
5957 if (TransactionIdIsValid(twophase_xid))
5958 {
5960 xl_twophase.xid = twophase_xid;
5961 Assert(twophase_gid != NULL);
5962
5965 }
5966
5967 /* dump transaction origin information */
5969 {
5971
5974 }
5975
5976 if (xl_xinfo.xinfo != 0)
5977 info |= XLOG_XACT_HAS_INFO;
5978
5979 /* Then include all the collected data into the commit record. */
5980
5982
5984
5985 if (xl_xinfo.xinfo != 0)
5986 XLogRegisterData(&xl_xinfo.xinfo, sizeof(xl_xinfo.xinfo));
5987
5988 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5990
5992 {
5995 XLogRegisterData(subxacts,
5996 nsubxacts * sizeof(TransactionId));
5997 }
5998
6000 {
6003 XLogRegisterData(rels,
6004 nrels * sizeof(RelFileLocator));
6005 }
6006
6008 {
6013 }
6014
6015 if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
6016 {
6018 XLogRegisterData(msgs,
6019 nmsgs * sizeof(SharedInvalidationMessage));
6020 }
6021
6023 {
6025 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6026 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6027 }
6028
6029 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6031
6032 /* we allow filtering by xacts */
6034
6035 return XLogInsert(RM_XACT_ID, info);
6036}

References Assert, CritSectionCount, fb(), forceSyncCommit, InvalidReplOriginId, MinSizeOfXactInvals, MinSizeOfXactRelfileLocators, MinSizeOfXactStatsItems, MinSizeOfXactSubxacts, MyDatabaseId, MyDatabaseTableSpace, ReplOriginXactState::origin, ReplOriginXactState::origin_lsn, ReplOriginXactState::origin_timestamp, replorigin_xact_state, synchronous_commit, SYNCHRONOUS_COMMIT_REMOTE_APPLY, TransactionIdIsValid, XACT_COMPLETION_APPLY_FEEDBACK, XACT_COMPLETION_FORCE_SYNC_COMMIT, XACT_COMPLETION_UPDATE_RELCACHE_FILE, XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK, XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_DBINFO, XACT_XINFO_HAS_DROPPED_STATS, XACT_XINFO_HAS_GID, XACT_XINFO_HAS_INVALS, XACT_XINFO_HAS_ORIGIN, XACT_XINFO_HAS_RELFILELOCATORS, XACT_XINFO_HAS_SUBXACTS, XACT_XINFO_HAS_TWOPHASE, XLOG_INCLUDE_ORIGIN, XLOG_XACT_COMMIT, XLOG_XACT_COMMIT_PREPARED, XLOG_XACT_HAS_INFO, XLogBeginInsert(), XLogInsert(), XLogLogicalInfoActive, XLogRegisterData(), XLogSetRecordFlags(), and XLR_SPECIAL_REL_UPDATE.

Referenced by RecordTransactionCommit(), and RecordTransactionCommitPrepared().

Variable Documentation

◆ bsysscan

◆ CheckXidAlive

◆ currentCommandId

◆ currentCommandIdUsed

bool currentCommandIdUsed
static

◆ currentSubTransactionId

SubTransactionId currentSubTransactionId
static

Definition at line 268 of file xact.c.

Referenced by PushTransaction(), and StartTransaction().

◆ CurrentTransactionState

TransactionState CurrentTransactionState = &TopTransactionStateData
static

Definition at line 262 of file xact.c.

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), AbortSubTransaction(), AbortTransaction(), AtCleanup_Memory(), AtCommit_Memory(), AtStart_Memory(), AtStart_ResourceOwner(), AtSubAbort_childXids(), AtSubAbort_ResourceOwner(), AtSubCleanup_Memory(), AtSubCommit_childXids(), AtSubCommit_Memory(), AtSubStart_Memory(), AtSubStart_ResourceOwner(), BeginImplicitTransactionBlock(), BeginInternalSubTransaction(), BeginTransactionBlock(), CleanupSubTransaction(), CleanupTransaction(), CommitSubTransaction(), CommitTransaction(), CommitTransactionCommandInternal(), DefineSavepoint(), EndImplicitTransactionBlock(), EndParallelWorkerTransaction(), EndTransactionBlock(), EnterParallelMode(), EstimateTransactionStateSpace(), ExitParallelMode(), GetCurrentFullTransactionId(), GetCurrentFullTransactionIdIfAny(), GetCurrentSubTransactionId(), GetCurrentTransactionId(), GetCurrentTransactionIdIfAny(), GetCurrentTransactionNestLevel(), GetCurrentTransactionStopTimestamp(), GetTopReadOnlyTransactionNestLevel(), IsAbortedTransactionBlockState(), IsInParallelMode(), IsInTransactionBlock(), IsSubTransaction(), IsSubxactTopXidLogPending(), IsTransactionBlock(), IsTransactionOrTransactionBlock(), IsTransactionState(), MarkCurrentTransactionIdLoggedIfAny(), MarkSubxactTopXidLogged(), PopTransaction(), PrepareTransaction(), PrepareTransactionBlock(), PreventInTransactionBlock(), PushTransaction(), ReleaseCurrentSubTransaction(), ReleaseSavepoint(), RollbackAndReleaseCurrentSubTransaction(), RollbackToSavepoint(), SerializeTransactionState(), ShowTransactionState(), StartParallelWorkerTransaction(), StartSubTransaction(), StartTransaction(), StartTransactionCommand(), SubTransactionIsActive(), TransactionBlockStatusCode(), TransactionIdIsCurrentTransactionId(), TransactionStartedDuringRecovery(), UserAbortTransactionBlock(), and xactGetCommittedChildren().

◆ DefaultXactDeferrable

bool DefaultXactDeferrable = false

Definition at line 86 of file xact.c.

Referenced by StartTransaction().

◆ DefaultXactIsoLevel

int DefaultXactIsoLevel = XACT_READ_COMMITTED

Definition at line 80 of file xact.c.

Referenced by StartTransaction().

◆ DefaultXactReadOnly

bool DefaultXactReadOnly = false

Definition at line 83 of file xact.c.

Referenced by StartTransaction().

◆ forceSyncCommit

bool forceSyncCommit = false
static

◆ MyXactFlags

◆ nParallelCurrentXids

◆ nUnreportedXids

int nUnreportedXids
static

Definition at line 259 of file xact.c.

Referenced by AssignTransactionId(), and StartTransaction().

◆ ParallelCurrentXids

TransactionId* ParallelCurrentXids
static

◆ prepareGID

char* prepareGID
static

Definition at line 290 of file xact.c.

Referenced by PrepareTransaction(), and PrepareTransactionBlock().

◆ stmtStartTimestamp

◆ SubXact_callbacks

SubXactCallbackItem* SubXact_callbacks = NULL
static

◆ synchronous_commit

int synchronous_commit = SYNCHRONOUS_COMMIT_ON

Definition at line 89 of file xact.c.

Referenced by AutoVacWorkerMain(), RecordTransactionCommit(), and XactLogCommitRecord().

◆ TopTransactionStateData

TransactionStateData TopTransactionStateData
static
Initial value:
= {
.state = TRANS_DEFAULT,
.blockState = TBLOCK_DEFAULT,
.topXidLogged = false,
}

Definition at line 249 of file xact.c.

249 {
250 .state = TRANS_DEFAULT,
251 .blockState = TBLOCK_DEFAULT,
252 .topXidLogged = false,
253};

Referenced by AssignTransactionId(), GetTopFullTransactionId(), GetTopTransactionId(), and StartTransaction().

◆ TransactionAbortContext

MemoryContext TransactionAbortContext = NULL
static

◆ unreportedXids

TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS]
static

Definition at line 260 of file xact.c.

Referenced by AssignTransactionId().

◆ Xact_callbacks

XactCallbackItem* Xact_callbacks = NULL
static

Definition at line 317 of file xact.c.

Referenced by CallXactCallbacks(), RegisterXactCallback(), and UnregisterXactCallback().

◆ xact_is_sampled

bool xact_is_sampled = false

Definition at line 298 of file xact.c.

Referenced by check_log_duration(), and StartTransaction().

◆ XactDeferrable

◆ XactIsoLevel

◆ XactReadOnly

◆ xactStartTimestamp

TimestampTz xactStartTimestamp
static

◆ xactStopTimestamp

TimestampTz xactStopTimestamp
static

◆ XactTopFullTransactionId