1 /*-------------------------------------------------------------------------
2  *
3  * xact.c
4  *	  top level transaction system support routines
5  *
6  * See src/backend/access/transam/README for more information.
7  *
8  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
9  * Portions Copyright (c) 1994, Regents of the University of California
10  *
11  *
12  * IDENTIFICATION
13  *	  src/backend/access/transam/xact.c
14  *
15  *-------------------------------------------------------------------------
16  */
17 
18 #include "postgres.h"
19 
20 #include <time.h>
21 #include <unistd.h>
22 
23 #include "access/commit_ts.h"
24 #include "access/multixact.h"
25 #include "access/parallel.h"
26 #include "access/subtrans.h"
27 #include "access/transam.h"
28 #include "access/twophase.h"
29 #include "access/xact.h"
30 #include "access/xlog.h"
31 #include "access/xloginsert.h"
32 #include "access/xlogutils.h"
33 #include "catalog/catalog.h"
34 #include "catalog/index.h"
35 #include "catalog/namespace.h"
36 #include "catalog/storage.h"
37 #include "commands/async.h"
38 #include "commands/tablecmds.h"
39 #include "commands/trigger.h"
40 #include "executor/spi.h"
41 #include "libpq/be-fsstubs.h"
42 #include "libpq/pqsignal.h"
43 #include "miscadmin.h"
44 #include "pgstat.h"
45 #include "replication/logical.h"
46 #include "replication/logicallauncher.h"
47 #include "replication/origin.h"
48 #include "replication/snapbuild.h"
49 #include "replication/syncrep.h"
50 #include "replication/walsender.h"
51 #include "storage/condition_variable.h"
52 #include "storage/fd.h"
53 #include "storage/lmgr.h"
54 #include "storage/predicate.h"
55 #include "storage/proc.h"
56 #include "storage/procarray.h"
57 #include "storage/sinvaladt.h"
58 #include "storage/smgr.h"
59 #include "utils/builtins.h"
60 #include "utils/catcache.h"
61 #include "utils/combocid.h"
62 #include "utils/guc.h"
63 #include "utils/inval.h"
64 #include "utils/memutils.h"
65 #include "utils/relmapper.h"
66 #include "utils/snapmgr.h"
67 #include "utils/timeout.h"
68 #include "utils/timestamp.h"
69 #include "pg_trace.h"
70 
71 
72 /*
73  *	User-tweakable parameters
74  */
75 int			DefaultXactIsoLevel = XACT_READ_COMMITTED;
76 int			XactIsoLevel;
77 
78 bool		DefaultXactReadOnly = false;
79 bool		XactReadOnly;
80 
81 bool		DefaultXactDeferrable = false;
82 bool		XactDeferrable;
83 
84 int			synchronous_commit = SYNCHRONOUS_COMMIT_ON;
85 
86 /*
87  * When running as a parallel worker, we place only a single
88  * TransactionStateData on the parallel worker's state stack, and the XID
89  * reflected there will be that of the *innermost* currently-active
90  * subtransaction in the backend that initiated parallelism.  However,
91  * GetTopTransactionId() and TransactionIdIsCurrentTransactionId()
92  * need to return the same answers in the parallel worker as they would have
93  * in the user backend, so we need some additional bookkeeping.
94  *
95  * XactTopTransactionId stores the XID of our toplevel transaction, which
96  * will be the same as TopTransactionState.transactionId in an ordinary
97  * backend; but in a parallel backend, which does not have the entire
98  * transaction state, it will instead be copied from the backend that started
99  * the parallel operation.
100  *
101  * nParallelCurrentXids will be 0 and ParallelCurrentXids NULL in an ordinary
102  * backend, but in a parallel backend, nParallelCurrentXids will contain the
103  * number of XIDs that need to be considered current, and ParallelCurrentXids
104  * will contain the XIDs themselves.  This includes all XIDs that were current
105  * or sub-committed in the parent at the time the parallel operation began.
106  * The XIDs are stored sorted in numerical order (not logical order) to make
107  * lookups as fast as possible.
108  */
109 TransactionId XactTopTransactionId = InvalidTransactionId;
110 int			nParallelCurrentXids = 0;
111 TransactionId *ParallelCurrentXids;
112 
113 /*
114  * Miscellaneous flag bits to record events which occur on the top level
115  * transaction. These flags are only persisted in MyXactFlags and are intended
116  * so we remember to do certain things later on in the transaction. This is
117  * globally accessible, so can be set from anywhere in the code that requires
118  * recording flags.
119  */
120 int			MyXactFlags;
121 
122 /*
123  *	transaction states - transaction state from server perspective
124  */
125 typedef enum TransState
126 {
127 	TRANS_DEFAULT,				/* idle */
128 	TRANS_START,				/* transaction starting */
129 	TRANS_INPROGRESS,			/* inside a valid transaction */
130 	TRANS_COMMIT,				/* commit in progress */
131 	TRANS_ABORT,				/* abort in progress */
132 	TRANS_PREPARE				/* prepare in progress */
133 } TransState;
134 
135 /*
136  *	transaction block states - transaction state of client queries
137  *
138  * Note: the subtransaction states are used only for non-topmost
139  * transactions; the others appear only in the topmost transaction.
140  */
141 typedef enum TBlockState
142 {
143 	/* not-in-transaction-block states */
144 	TBLOCK_DEFAULT,				/* idle */
145 	TBLOCK_STARTED,				/* running single-query transaction */
146 
147 	/* transaction block states */
148 	TBLOCK_BEGIN,				/* starting transaction block */
149 	TBLOCK_INPROGRESS,			/* live transaction */
150 	TBLOCK_PARALLEL_INPROGRESS, /* live transaction inside parallel worker */
151 	TBLOCK_END,					/* COMMIT received */
152 	TBLOCK_ABORT,				/* failed xact, awaiting ROLLBACK */
153 	TBLOCK_ABORT_END,			/* failed xact, ROLLBACK received */
154 	TBLOCK_ABORT_PENDING,		/* live xact, ROLLBACK received */
155 	TBLOCK_PREPARE,				/* live xact, PREPARE received */
156 
157 	/* subtransaction states */
158 	TBLOCK_SUBBEGIN,			/* starting a subtransaction */
159 	TBLOCK_SUBINPROGRESS,		/* live subtransaction */
160 	TBLOCK_SUBRELEASE,			/* RELEASE received */
161 	TBLOCK_SUBCOMMIT,			/* COMMIT received while TBLOCK_SUBINPROGRESS */
162 	TBLOCK_SUBABORT,			/* failed subxact, awaiting ROLLBACK */
163 	TBLOCK_SUBABORT_END,		/* failed subxact, ROLLBACK received */
164 	TBLOCK_SUBABORT_PENDING,	/* live subxact, ROLLBACK received */
165 	TBLOCK_SUBRESTART,			/* live subxact, ROLLBACK TO received */
166 	TBLOCK_SUBABORT_RESTART		/* failed subxact, ROLLBACK TO received */
167 } TBlockState;
168 
169 /*
170  *	transaction state structure
171  */
172 typedef struct TransactionStateData
173 {
174 	TransactionId transactionId;	/* my XID, or Invalid if none */
175 	SubTransactionId subTransactionId;	/* my subxact ID */
176 	char	   *name;			/* savepoint name, if any */
177 	int			savepointLevel; /* savepoint level */
178 	TransState	state;			/* low-level state */
179 	TBlockState blockState;		/* high-level state */
180 	int			nestingLevel;	/* transaction nesting depth */
181 	int			gucNestLevel;	/* GUC context nesting depth */
182 	MemoryContext curTransactionContext;	/* my xact-lifetime context */
183 	ResourceOwner curTransactionOwner;	/* my query resources */
184 	TransactionId *childXids;	/* subcommitted child XIDs, in XID order */
185 	int			nChildXids;		/* # of subcommitted child XIDs */
186 	int			maxChildXids;	/* allocated size of childXids[] */
187 	Oid			prevUser;		/* previous CurrentUserId setting */
188 	int			prevSecContext; /* previous SecurityRestrictionContext */
189 	bool		prevXactReadOnly;	/* entry-time xact r/o state */
190 	bool		startedInRecovery;	/* did we start in recovery? */
191 	bool		didLogXid;		/* has xid been included in WAL record? */
192 	int			parallelModeLevel;	/* Enter/ExitParallelMode counter */
193 	struct TransactionStateData *parent;	/* back link to parent */
194 } TransactionStateData;
195 
196 typedef TransactionStateData *TransactionState;
197 
198 /*
199  * CurrentTransactionState always points to the current transaction state
200  * block.  It will point to TopTransactionStateData when not in a
201  * transaction at all, or when in a top-level transaction.
202  */
203 static TransactionStateData TopTransactionStateData = {
204 	0,							/* transaction id */
205 	0,							/* subtransaction id */
206 	NULL,						/* savepoint name */
207 	0,							/* savepoint level */
208 	TRANS_DEFAULT,				/* transaction state */
209 	TBLOCK_DEFAULT,				/* transaction block state from the client
210 								 * perspective */
211 	0,							/* transaction nesting depth */
212 	0,							/* GUC context nesting depth */
213 	NULL,						/* cur transaction context */
214 	NULL,						/* cur transaction resource owner */
215 	NULL,						/* subcommitted child Xids */
216 	0,							/* # of subcommitted child Xids */
217 	0,							/* allocated size of childXids[] */
218 	InvalidOid,					/* previous CurrentUserId setting */
219 	0,							/* previous SecurityRestrictionContext */
220 	false,						/* entry-time xact r/o state */
221 	false,						/* startedInRecovery */
222 	false,						/* didLogXid */
223 	0,							/* parallelMode */
224 	NULL						/* link to parent state block */
225 };
226 
227 /*
228  * unreportedXids holds XIDs of all subtransactions that have not yet been
229  * reported in an XLOG_XACT_ASSIGNMENT record.
230  */
231 static int	nUnreportedXids;
232 static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS];
233 
234 static TransactionState CurrentTransactionState = &TopTransactionStateData;
235 
236 /*
237  * The subtransaction ID and command ID assignment counters are global
238  * to a whole transaction, so we do not keep them in the state stack.
239  */
240 static SubTransactionId currentSubTransactionId;
241 static CommandId currentCommandId;
242 static bool currentCommandIdUsed;
243 
244 /*
245  * xactStartTimestamp is the value of transaction_timestamp().
246  * stmtStartTimestamp is the value of statement_timestamp().
247  * xactStopTimestamp is the time at which we log a commit or abort WAL record.
248  * These do not change as we enter and exit subtransactions, so we don't
249  * keep them inside the TransactionState stack.
250  */
251 static TimestampTz xactStartTimestamp;
252 static TimestampTz stmtStartTimestamp;
253 static TimestampTz xactStopTimestamp;
254 
255 /*
256  * GID to be used for preparing the current transaction.  This is also
257  * global to a whole transaction, so we don't keep it in the state stack.
258  */
259 static char *prepareGID;
260 
261 /*
262  * Some commands want to force synchronous commit.
263  */
264 static bool forceSyncCommit = false;
265 
266 /*
267  * Private context for transaction-abort work --- we reserve space for this
268  * at startup to ensure that AbortTransaction and AbortSubTransaction can work
269  * when we've run out of memory.
270  */
271 static MemoryContext TransactionAbortContext = NULL;
272 
273 /*
274  * List of add-on start- and end-of-xact callbacks
275  */
276 typedef struct XactCallbackItem
277 {
278 	struct XactCallbackItem *next;
279 	XactCallback callback;
280 	void	   *arg;
281 } XactCallbackItem;
282 
283 static XactCallbackItem *Xact_callbacks = NULL;
284 
285 /*
286  * List of add-on start- and end-of-subxact callbacks
287  */
288 typedef struct SubXactCallbackItem
289 {
290 	struct SubXactCallbackItem *next;
291 	SubXactCallback callback;
292 	void	   *arg;
293 } SubXactCallbackItem;
294 
295 static SubXactCallbackItem *SubXact_callbacks = NULL;
296 
297 
298 /* local function prototypes */
299 static void AssignTransactionId(TransactionState s);
300 static void AbortTransaction(void);
301 static void AtAbort_Memory(void);
302 static void AtCleanup_Memory(void);
303 static void AtAbort_ResourceOwner(void);
304 static void AtCCI_LocalCache(void);
305 static void AtCommit_Memory(void);
306 static void AtStart_Cache(void);
307 static void AtStart_Memory(void);
308 static void AtStart_ResourceOwner(void);
309 static void CallXactCallbacks(XactEvent event);
310 static void CallSubXactCallbacks(SubXactEvent event,
311 					 SubTransactionId mySubid,
312 					 SubTransactionId parentSubid);
313 static void CleanupTransaction(void);
314 static void CheckTransactionChain(bool isTopLevel, bool throwError,
315 					  const char *stmtType);
316 static void CommitTransaction(void);
317 static TransactionId RecordTransactionAbort(bool isSubXact);
318 static void StartTransaction(void);
319 
320 static void StartSubTransaction(void);
321 static void CommitSubTransaction(void);
322 static void AbortSubTransaction(void);
323 static void CleanupSubTransaction(void);
324 static void PushTransaction(void);
325 static void PopTransaction(void);
326 
327 static void AtSubAbort_Memory(void);
328 static void AtSubCleanup_Memory(void);
329 static void AtSubAbort_ResourceOwner(void);
330 static void AtSubCommit_Memory(void);
331 static void AtSubStart_Memory(void);
332 static void AtSubStart_ResourceOwner(void);
333 
334 static void ShowTransactionState(const char *str);
335 static void ShowTransactionStateRec(const char *str, TransactionState state);
336 static const char *BlockStateAsString(TBlockState blockState);
337 static const char *TransStateAsString(TransState state);
338 
339 
340 /* ----------------------------------------------------------------
341  *	transaction state accessors
342  * ----------------------------------------------------------------
343  */
344 
345 /*
346  *	IsTransactionState
347  *
348  *	This returns true if we are inside a valid transaction; that is,
349  *	it is safe to initiate database access, take heavyweight locks, etc.
350  */
351 bool
IsTransactionState(void)352 IsTransactionState(void)
353 {
354 	TransactionState s = CurrentTransactionState;
355 
356 	/*
357 	 * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states.  However, we
358 	 * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
359 	 * TRANS_PREPARE since it might be too soon or too late within those
360 	 * transition states to do anything interesting.  Hence, the only "valid"
361 	 * state is TRANS_INPROGRESS.
362 	 */
363 	return (s->state == TRANS_INPROGRESS);
364 }
365 
366 /*
367  *	IsAbortedTransactionBlockState
368  *
369  *	This returns true if we are within an aborted transaction block.
370  */
371 bool
IsAbortedTransactionBlockState(void)372 IsAbortedTransactionBlockState(void)
373 {
374 	TransactionState s = CurrentTransactionState;
375 
376 	if (s->blockState == TBLOCK_ABORT ||
377 		s->blockState == TBLOCK_SUBABORT)
378 		return true;
379 
380 	return false;
381 }
382 
383 
384 /*
385  *	GetTopTransactionId
386  *
387  * This will return the XID of the main transaction, assigning one if
388  * it's not yet set.  Be careful to call this only inside a valid xact.
389  */
390 TransactionId
GetTopTransactionId(void)391 GetTopTransactionId(void)
392 {
393 	if (!TransactionIdIsValid(XactTopTransactionId))
394 		AssignTransactionId(&TopTransactionStateData);
395 	return XactTopTransactionId;
396 }
397 
398 /*
399  *	GetTopTransactionIdIfAny
400  *
401  * This will return the XID of the main transaction, if one is assigned.
402  * It will return InvalidTransactionId if we are not currently inside a
403  * transaction, or inside a transaction that hasn't yet been assigned an XID.
404  */
405 TransactionId
GetTopTransactionIdIfAny(void)406 GetTopTransactionIdIfAny(void)
407 {
408 	return XactTopTransactionId;
409 }
410 
411 /*
412  *	GetCurrentTransactionId
413  *
414  * This will return the XID of the current transaction (main or sub
415  * transaction), assigning one if it's not yet set.  Be careful to call this
416  * only inside a valid xact.
417  */
418 TransactionId
GetCurrentTransactionId(void)419 GetCurrentTransactionId(void)
420 {
421 	TransactionState s = CurrentTransactionState;
422 
423 	if (!TransactionIdIsValid(s->transactionId))
424 		AssignTransactionId(s);
425 	return s->transactionId;
426 }
427 
428 /*
429  *	GetCurrentTransactionIdIfAny
430  *
431  * This will return the XID of the current sub xact, if one is assigned.
432  * It will return InvalidTransactionId if we are not currently inside a
433  * transaction, or inside a transaction that hasn't been assigned an XID yet.
434  */
435 TransactionId
GetCurrentTransactionIdIfAny(void)436 GetCurrentTransactionIdIfAny(void)
437 {
438 	return CurrentTransactionState->transactionId;
439 }
440 
441 /*
442  *	MarkCurrentTransactionIdLoggedIfAny
443  *
444  * Remember that the current xid - if it is assigned - now has been wal logged.
445  */
446 void
MarkCurrentTransactionIdLoggedIfAny(void)447 MarkCurrentTransactionIdLoggedIfAny(void)
448 {
449 	if (TransactionIdIsValid(CurrentTransactionState->transactionId))
450 		CurrentTransactionState->didLogXid = true;
451 }
452 
453 
454 /*
455  *	GetStableLatestTransactionId
456  *
457  * Get the transaction's XID if it has one, else read the next-to-be-assigned
458  * XID.  Once we have a value, return that same value for the remainder of the
459  * current transaction.  This is meant to provide the reference point for the
460  * age(xid) function, but might be useful for other maintenance tasks as well.
461  */
462 TransactionId
GetStableLatestTransactionId(void)463 GetStableLatestTransactionId(void)
464 {
465 	static LocalTransactionId lxid = InvalidLocalTransactionId;
466 	static TransactionId stablexid = InvalidTransactionId;
467 
468 	if (lxid != MyProc->lxid)
469 	{
470 		lxid = MyProc->lxid;
471 		stablexid = GetTopTransactionIdIfAny();
472 		if (!TransactionIdIsValid(stablexid))
473 			stablexid = ReadNewTransactionId();
474 	}
475 
476 	Assert(TransactionIdIsValid(stablexid));
477 
478 	return stablexid;
479 }
480 
481 /*
482  * AssignTransactionId
483  *
484  * Assigns a new permanent XID to the given TransactionState.
485  * We do not assign XIDs to transactions until/unless this is called.
486  * Also, any parent TransactionStates that don't yet have XIDs are assigned
487  * one; this maintains the invariant that a child transaction has an XID
488  * following its parent's.
489  */
490 static void
AssignTransactionId(TransactionState s)491 AssignTransactionId(TransactionState s)
492 {
493 	bool		isSubXact = (s->parent != NULL);
494 	ResourceOwner currentOwner;
495 	bool		log_unknown_top = false;
496 
497 	/* Assert that caller didn't screw up */
498 	Assert(!TransactionIdIsValid(s->transactionId));
499 	Assert(s->state == TRANS_INPROGRESS);
500 
501 	/*
502 	 * Workers synchronize transaction state at the beginning of each parallel
503 	 * operation, so we can't account for new XIDs at this point.
504 	 */
505 	if (IsInParallelMode() || IsParallelWorker())
506 		elog(ERROR, "cannot assign XIDs during a parallel operation");
507 
508 	/*
509 	 * Ensure parent(s) have XIDs, so that a child always has an XID later
510 	 * than its parent.  Musn't recurse here, or we might get a stack overflow
511 	 * if we're at the bottom of a huge stack of subtransactions none of which
512 	 * have XIDs yet.
513 	 */
514 	if (isSubXact && !TransactionIdIsValid(s->parent->transactionId))
515 	{
516 		TransactionState p = s->parent;
517 		TransactionState *parents;
518 		size_t		parentOffset = 0;
519 
520 		parents = palloc(sizeof(TransactionState) * s->nestingLevel);
521 		while (p != NULL && !TransactionIdIsValid(p->transactionId))
522 		{
523 			parents[parentOffset++] = p;
524 			p = p->parent;
525 		}
526 
527 		/*
528 		 * This is technically a recursive call, but the recursion will never
529 		 * be more than one layer deep.
530 		 */
531 		while (parentOffset != 0)
532 			AssignTransactionId(parents[--parentOffset]);
533 
534 		pfree(parents);
535 	}
536 
537 	/*
538 	 * When wal_level=logical, guarantee that a subtransaction's xid can only
539 	 * be seen in the WAL stream if its toplevel xid has been logged before.
540 	 * If necessary we log an xact_assignment record with fewer than
541 	 * PGPROC_MAX_CACHED_SUBXIDS. Note that it is fine if didLogXid isn't set
542 	 * for a transaction even though it appears in a WAL record, we just might
543 	 * superfluously log something. That can happen when an xid is included
544 	 * somewhere inside a wal record, but not in XLogRecord->xl_xid, like in
545 	 * xl_standby_locks.
546 	 */
547 	if (isSubXact && XLogLogicalInfoActive() &&
548 		!TopTransactionStateData.didLogXid)
549 		log_unknown_top = true;
550 
551 	/*
552 	 * Generate a new Xid and record it in PG_PROC and pg_subtrans.
553 	 *
554 	 * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
555 	 * shared storage other than PG_PROC; because if there's no room for it in
556 	 * PG_PROC, the subtrans entry is needed to ensure that other backends see
557 	 * the Xid as "running".  See GetNewTransactionId.
558 	 */
559 	s->transactionId = GetNewTransactionId(isSubXact);
560 	if (!isSubXact)
561 		XactTopTransactionId = s->transactionId;
562 
563 	if (isSubXact)
564 		SubTransSetParent(s->transactionId, s->parent->transactionId);
565 
566 	/*
567 	 * If it's a top-level transaction, the predicate locking system needs to
568 	 * be told about it too.
569 	 */
570 	if (!isSubXact)
571 		RegisterPredicateLockingXid(s->transactionId);
572 
573 	/*
574 	 * Acquire lock on the transaction XID.  (We assume this cannot block.) We
575 	 * have to ensure that the lock is assigned to the transaction's own
576 	 * ResourceOwner.
577 	 */
578 	currentOwner = CurrentResourceOwner;
579 	PG_TRY();
580 	{
581 		CurrentResourceOwner = s->curTransactionOwner;
582 		XactLockTableInsert(s->transactionId);
583 	}
584 	PG_CATCH();
585 	{
586 		/* Ensure CurrentResourceOwner is restored on error */
587 		CurrentResourceOwner = currentOwner;
588 		PG_RE_THROW();
589 	}
590 	PG_END_TRY();
591 	CurrentResourceOwner = currentOwner;
592 
593 	/*
594 	 * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
595 	 * top-level transaction we issue a WAL record for the assignment. We
596 	 * include the top-level xid and all the subxids that have not yet been
597 	 * reported using XLOG_XACT_ASSIGNMENT records.
598 	 *
599 	 * This is required to limit the amount of shared memory required in a hot
600 	 * standby server to keep track of in-progress XIDs. See notes for
601 	 * RecordKnownAssignedTransactionIds().
602 	 *
603 	 * We don't keep track of the immediate parent of each subxid, only the
604 	 * top-level transaction that each subxact belongs to. This is correct in
605 	 * recovery only because aborted subtransactions are separately WAL
606 	 * logged.
607 	 *
608 	 * This is correct even for the case where several levels above us didn't
609 	 * have an xid assigned as we recursed up to them beforehand.
610 	 */
611 	if (isSubXact && XLogStandbyInfoActive())
612 	{
613 		unreportedXids[nUnreportedXids] = s->transactionId;
614 		nUnreportedXids++;
615 
616 		/*
617 		 * ensure this test matches similar one in
618 		 * RecoverPreparedTransactions()
619 		 */
620 		if (nUnreportedXids >= PGPROC_MAX_CACHED_SUBXIDS ||
621 			log_unknown_top)
622 		{
623 			xl_xact_assignment xlrec;
624 
625 			/*
626 			 * xtop is always set by now because we recurse up transaction
627 			 * stack to the highest unassigned xid and then come back down
628 			 */
629 			xlrec.xtop = GetTopTransactionId();
630 			Assert(TransactionIdIsValid(xlrec.xtop));
631 			xlrec.nsubxacts = nUnreportedXids;
632 
633 			XLogBeginInsert();
634 			XLogRegisterData((char *) &xlrec, MinSizeOfXactAssignment);
635 			XLogRegisterData((char *) unreportedXids,
636 							 nUnreportedXids * sizeof(TransactionId));
637 
638 			(void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT);
639 
640 			nUnreportedXids = 0;
641 			/* mark top, not current xact as having been logged */
642 			TopTransactionStateData.didLogXid = true;
643 		}
644 	}
645 }
646 
647 /*
648  *	GetCurrentSubTransactionId
649  */
650 SubTransactionId
GetCurrentSubTransactionId(void)651 GetCurrentSubTransactionId(void)
652 {
653 	TransactionState s = CurrentTransactionState;
654 
655 	return s->subTransactionId;
656 }
657 
658 /*
659  *	SubTransactionIsActive
660  *
661  * Test if the specified subxact ID is still active.  Note caller is
662  * responsible for checking whether this ID is relevant to the current xact.
663  */
664 bool
SubTransactionIsActive(SubTransactionId subxid)665 SubTransactionIsActive(SubTransactionId subxid)
666 {
667 	TransactionState s;
668 
669 	for (s = CurrentTransactionState; s != NULL; s = s->parent)
670 	{
671 		if (s->state == TRANS_ABORT)
672 			continue;
673 		if (s->subTransactionId == subxid)
674 			return true;
675 	}
676 	return false;
677 }
678 
679 
680 /*
681  *	GetCurrentCommandId
682  *
683  * "used" must be TRUE if the caller intends to use the command ID to mark
684  * inserted/updated/deleted tuples.  FALSE means the ID is being fetched
685  * for read-only purposes (ie, as a snapshot validity cutoff).  See
686  * CommandCounterIncrement() for discussion.
687  */
688 CommandId
GetCurrentCommandId(bool used)689 GetCurrentCommandId(bool used)
690 {
691 	/* this is global to a transaction, not subtransaction-local */
692 	if (used)
693 	{
694 		/*
695 		 * Forbid setting currentCommandIdUsed in parallel mode, because we
696 		 * have no provision for communicating this back to the master.  We
697 		 * could relax this restriction when currentCommandIdUsed was already
698 		 * true at the start of the parallel operation.
699 		 */
700 		Assert(CurrentTransactionState->parallelModeLevel == 0);
701 		currentCommandIdUsed = true;
702 	}
703 	return currentCommandId;
704 }
705 
706 /*
707  *	SetParallelStartTimestamps
708  *
709  * In a parallel worker, we should inherit the parent transaction's
710  * timestamps rather than setting our own.  The parallel worker
711  * infrastructure must call this to provide those values before
712  * calling StartTransaction() or SetCurrentStatementStartTimestamp().
713  */
714 void
SetParallelStartTimestamps(TimestampTz xact_ts,TimestampTz stmt_ts)715 SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts)
716 {
717 	Assert(IsParallelWorker());
718 	xactStartTimestamp = xact_ts;
719 	stmtStartTimestamp = stmt_ts;
720 }
721 
722 /*
723  *	GetCurrentTransactionStartTimestamp
724  */
725 TimestampTz
GetCurrentTransactionStartTimestamp(void)726 GetCurrentTransactionStartTimestamp(void)
727 {
728 	return xactStartTimestamp;
729 }
730 
731 /*
732  *	GetCurrentStatementStartTimestamp
733  */
734 TimestampTz
GetCurrentStatementStartTimestamp(void)735 GetCurrentStatementStartTimestamp(void)
736 {
737 	return stmtStartTimestamp;
738 }
739 
740 /*
741  *	GetCurrentTransactionStopTimestamp
742  *
743  * We return current time if the transaction stop time hasn't been set
744  * (which can happen if we decide we don't need to log an XLOG record).
745  */
746 TimestampTz
GetCurrentTransactionStopTimestamp(void)747 GetCurrentTransactionStopTimestamp(void)
748 {
749 	if (xactStopTimestamp != 0)
750 		return xactStopTimestamp;
751 	return GetCurrentTimestamp();
752 }
753 
754 /*
755  *	SetCurrentStatementStartTimestamp
756  *
757  * In a parallel worker, this should already have been provided by a call
758  * to SetParallelStartTimestamps().
759  */
760 void
SetCurrentStatementStartTimestamp(void)761 SetCurrentStatementStartTimestamp(void)
762 {
763 	if (!IsParallelWorker())
764 		stmtStartTimestamp = GetCurrentTimestamp();
765 	else
766 		Assert(stmtStartTimestamp != 0);
767 }
768 
769 /*
770  *	SetCurrentTransactionStopTimestamp
771  */
772 static inline void
SetCurrentTransactionStopTimestamp(void)773 SetCurrentTransactionStopTimestamp(void)
774 {
775 	xactStopTimestamp = GetCurrentTimestamp();
776 }
777 
778 /*
779  *	GetCurrentTransactionNestLevel
780  *
781  * Note: this will return zero when not inside any transaction, one when
782  * inside a top-level transaction, etc.
783  */
784 int
GetCurrentTransactionNestLevel(void)785 GetCurrentTransactionNestLevel(void)
786 {
787 	TransactionState s = CurrentTransactionState;
788 
789 	return s->nestingLevel;
790 }
791 
792 
793 /*
794  *	TransactionIdIsCurrentTransactionId
795  */
796 bool
TransactionIdIsCurrentTransactionId(TransactionId xid)797 TransactionIdIsCurrentTransactionId(TransactionId xid)
798 {
799 	TransactionState s;
800 
801 	/*
802 	 * We always say that BootstrapTransactionId is "not my transaction ID"
803 	 * even when it is (ie, during bootstrap).  Along with the fact that
804 	 * transam.c always treats BootstrapTransactionId as already committed,
805 	 * this causes the tqual.c routines to see all tuples as committed, which
806 	 * is what we need during bootstrap.  (Bootstrap mode only inserts tuples,
807 	 * it never updates or deletes them, so all tuples can be presumed good
808 	 * immediately.)
809 	 *
810 	 * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
811 	 * not my transaction ID, so we can just return "false" immediately for
812 	 * any non-normal XID.
813 	 */
814 	if (!TransactionIdIsNormal(xid))
815 		return false;
816 
817 	/*
818 	 * In parallel workers, the XIDs we must consider as current are stored in
819 	 * ParallelCurrentXids rather than the transaction-state stack.  Note that
820 	 * the XIDs in this array are sorted numerically rather than according to
821 	 * transactionIdPrecedes order.
822 	 */
823 	if (nParallelCurrentXids > 0)
824 	{
825 		int			low,
826 					high;
827 
828 		low = 0;
829 		high = nParallelCurrentXids - 1;
830 		while (low <= high)
831 		{
832 			int			middle;
833 			TransactionId probe;
834 
835 			middle = low + (high - low) / 2;
836 			probe = ParallelCurrentXids[middle];
837 			if (probe == xid)
838 				return true;
839 			else if (probe < xid)
840 				low = middle + 1;
841 			else
842 				high = middle - 1;
843 		}
844 		return false;
845 	}
846 
847 	/*
848 	 * We will return true for the Xid of the current subtransaction, any of
849 	 * its subcommitted children, any of its parents, or any of their
850 	 * previously subcommitted children.  However, a transaction being aborted
851 	 * is no longer "current", even though it may still have an entry on the
852 	 * state stack.
853 	 */
854 	for (s = CurrentTransactionState; s != NULL; s = s->parent)
855 	{
856 		int			low,
857 					high;
858 
859 		if (s->state == TRANS_ABORT)
860 			continue;
861 		if (!TransactionIdIsValid(s->transactionId))
862 			continue;			/* it can't have any child XIDs either */
863 		if (TransactionIdEquals(xid, s->transactionId))
864 			return true;
865 		/* As the childXids array is ordered, we can use binary search */
866 		low = 0;
867 		high = s->nChildXids - 1;
868 		while (low <= high)
869 		{
870 			int			middle;
871 			TransactionId probe;
872 
873 			middle = low + (high - low) / 2;
874 			probe = s->childXids[middle];
875 			if (TransactionIdEquals(probe, xid))
876 				return true;
877 			else if (TransactionIdPrecedes(probe, xid))
878 				low = middle + 1;
879 			else
880 				high = middle - 1;
881 		}
882 	}
883 
884 	return false;
885 }
886 
887 /*
888  *	TransactionStartedDuringRecovery
889  *
890  * Returns true if the current transaction started while recovery was still
891  * in progress. Recovery might have ended since so RecoveryInProgress() might
892  * return false already.
893  */
894 bool
TransactionStartedDuringRecovery(void)895 TransactionStartedDuringRecovery(void)
896 {
897 	return CurrentTransactionState->startedInRecovery;
898 }
899 
900 /*
901  *	EnterParallelMode
902  */
903 void
EnterParallelMode(void)904 EnterParallelMode(void)
905 {
906 	TransactionState s = CurrentTransactionState;
907 
908 	Assert(s->parallelModeLevel >= 0);
909 
910 	++s->parallelModeLevel;
911 }
912 
913 /*
914  *	ExitParallelMode
915  */
916 void
ExitParallelMode(void)917 ExitParallelMode(void)
918 {
919 	TransactionState s = CurrentTransactionState;
920 
921 	Assert(s->parallelModeLevel > 0);
922 	Assert(s->parallelModeLevel > 1 || !ParallelContextActive());
923 
924 	--s->parallelModeLevel;
925 }
926 
927 /*
928  *	IsInParallelMode
929  *
930  * Are we in a parallel operation, as either the master or a worker?  Check
931  * this to prohibit operations that change backend-local state expected to
932  * match across all workers.  Mere caches usually don't require such a
933  * restriction.  State modified in a strict push/pop fashion, such as the
934  * active snapshot stack, is often fine.
935  */
936 bool
IsInParallelMode(void)937 IsInParallelMode(void)
938 {
939 	return CurrentTransactionState->parallelModeLevel != 0;
940 }
941 
942 /*
943  *	CommandCounterIncrement
944  */
945 void
CommandCounterIncrement(void)946 CommandCounterIncrement(void)
947 {
948 	/*
949 	 * If the current value of the command counter hasn't been "used" to mark
950 	 * tuples, we need not increment it, since there's no need to distinguish
951 	 * a read-only command from others.  This helps postpone command counter
952 	 * overflow, and keeps no-op CommandCounterIncrement operations cheap.
953 	 */
954 	if (currentCommandIdUsed)
955 	{
956 		/*
957 		 * Workers synchronize transaction state at the beginning of each
958 		 * parallel operation, so we can't account for new commands after that
959 		 * point.
960 		 */
961 		if (IsInParallelMode() || IsParallelWorker())
962 			elog(ERROR, "cannot start commands during a parallel operation");
963 
964 		currentCommandId += 1;
965 		if (currentCommandId == InvalidCommandId)
966 		{
967 			currentCommandId -= 1;
968 			ereport(ERROR,
969 					(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
970 					 errmsg("cannot have more than 2^32-2 commands in a transaction")));
971 		}
972 		currentCommandIdUsed = false;
973 
974 		/* Propagate new command ID into static snapshots */
975 		SnapshotSetCommandId(currentCommandId);
976 
977 		/*
978 		 * Make any catalog changes done by the just-completed command visible
979 		 * in the local syscache.  We obviously don't need to do this after a
980 		 * read-only command.  (But see hacks in inval.c to make real sure we
981 		 * don't think a command that queued inval messages was read-only.)
982 		 */
983 		AtCCI_LocalCache();
984 	}
985 }
986 
987 /*
988  * ForceSyncCommit
989  *
990  * Interface routine to allow commands to force a synchronous commit of the
991  * current top-level transaction
992  */
993 void
ForceSyncCommit(void)994 ForceSyncCommit(void)
995 {
996 	forceSyncCommit = true;
997 }
998 
999 
1000 /* ----------------------------------------------------------------
1001  *						StartTransaction stuff
1002  * ----------------------------------------------------------------
1003  */
1004 
1005 /*
1006  *	AtStart_Cache
1007  */
1008 static void
AtStart_Cache(void)1009 AtStart_Cache(void)
1010 {
1011 	AcceptInvalidationMessages();
1012 }
1013 
1014 /*
1015  *	AtStart_Memory
1016  */
1017 static void
AtStart_Memory(void)1018 AtStart_Memory(void)
1019 {
1020 	TransactionState s = CurrentTransactionState;
1021 
1022 	/*
1023 	 * If this is the first time through, create a private context for
1024 	 * AbortTransaction to work in.  By reserving some space now, we can
1025 	 * insulate AbortTransaction from out-of-memory scenarios.  Like
1026 	 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1027 	 * size, so that space will be reserved immediately.
1028 	 */
1029 	if (TransactionAbortContext == NULL)
1030 		TransactionAbortContext =
1031 			AllocSetContextCreate(TopMemoryContext,
1032 								  "TransactionAbortContext",
1033 								  32 * 1024,
1034 								  32 * 1024,
1035 								  32 * 1024);
1036 
1037 	/*
1038 	 * We shouldn't have a transaction context already.
1039 	 */
1040 	Assert(TopTransactionContext == NULL);
1041 
1042 	/*
1043 	 * Create a toplevel context for the transaction.
1044 	 */
1045 	TopTransactionContext =
1046 		AllocSetContextCreate(TopMemoryContext,
1047 							  "TopTransactionContext",
1048 							  ALLOCSET_DEFAULT_SIZES);
1049 
1050 	/*
1051 	 * In a top-level transaction, CurTransactionContext is the same as
1052 	 * TopTransactionContext.
1053 	 */
1054 	CurTransactionContext = TopTransactionContext;
1055 	s->curTransactionContext = CurTransactionContext;
1056 
1057 	/* Make the CurTransactionContext active. */
1058 	MemoryContextSwitchTo(CurTransactionContext);
1059 }
1060 
1061 /*
1062  *	AtStart_ResourceOwner
1063  */
1064 static void
AtStart_ResourceOwner(void)1065 AtStart_ResourceOwner(void)
1066 {
1067 	TransactionState s = CurrentTransactionState;
1068 
1069 	/*
1070 	 * We shouldn't have a transaction resource owner already.
1071 	 */
1072 	Assert(TopTransactionResourceOwner == NULL);
1073 
1074 	/*
1075 	 * Create a toplevel resource owner for the transaction.
1076 	 */
1077 	s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1078 
1079 	TopTransactionResourceOwner = s->curTransactionOwner;
1080 	CurTransactionResourceOwner = s->curTransactionOwner;
1081 	CurrentResourceOwner = s->curTransactionOwner;
1082 }
1083 
1084 /* ----------------------------------------------------------------
1085  *						StartSubTransaction stuff
1086  * ----------------------------------------------------------------
1087  */
1088 
1089 /*
1090  * AtSubStart_Memory
1091  */
1092 static void
AtSubStart_Memory(void)1093 AtSubStart_Memory(void)
1094 {
1095 	TransactionState s = CurrentTransactionState;
1096 
1097 	Assert(CurTransactionContext != NULL);
1098 
1099 	/*
1100 	 * Create a CurTransactionContext, which will be used to hold data that
1101 	 * survives subtransaction commit but disappears on subtransaction abort.
1102 	 * We make it a child of the immediate parent's CurTransactionContext.
1103 	 */
1104 	CurTransactionContext = AllocSetContextCreate(CurTransactionContext,
1105 												  "CurTransactionContext",
1106 												  ALLOCSET_DEFAULT_SIZES);
1107 	s->curTransactionContext = CurTransactionContext;
1108 
1109 	/* Make the CurTransactionContext active. */
1110 	MemoryContextSwitchTo(CurTransactionContext);
1111 }
1112 
1113 /*
1114  * AtSubStart_ResourceOwner
1115  */
1116 static void
AtSubStart_ResourceOwner(void)1117 AtSubStart_ResourceOwner(void)
1118 {
1119 	TransactionState s = CurrentTransactionState;
1120 
1121 	Assert(s->parent != NULL);
1122 
1123 	/*
1124 	 * Create a resource owner for the subtransaction.  We make it a child of
1125 	 * the immediate parent's resource owner.
1126 	 */
1127 	s->curTransactionOwner =
1128 		ResourceOwnerCreate(s->parent->curTransactionOwner,
1129 							"SubTransaction");
1130 
1131 	CurTransactionResourceOwner = s->curTransactionOwner;
1132 	CurrentResourceOwner = s->curTransactionOwner;
1133 }
1134 
1135 /* ----------------------------------------------------------------
1136  *						CommitTransaction stuff
1137  * ----------------------------------------------------------------
1138  */
1139 
1140 /*
1141  *	RecordTransactionCommit
1142  *
1143  * Returns latest XID among xact and its children, or InvalidTransactionId
1144  * if the xact has no XID.  (We compute that here just because it's easier.)
1145  *
1146  * If you change this function, see RecordTransactionCommitPrepared also.
1147  */
1148 static TransactionId
RecordTransactionCommit(void)1149 RecordTransactionCommit(void)
1150 {
1151 	TransactionId xid = GetTopTransactionIdIfAny();
1152 	bool		markXidCommitted = TransactionIdIsValid(xid);
1153 	TransactionId latestXid = InvalidTransactionId;
1154 	int			nrels;
1155 	RelFileNode *rels;
1156 	int			nchildren;
1157 	TransactionId *children;
1158 	int			nmsgs = 0;
1159 	SharedInvalidationMessage *invalMessages = NULL;
1160 	bool		RelcacheInitFileInval = false;
1161 	bool		wrote_xlog;
1162 
1163 	/* Get data needed for commit record */
1164 	nrels = smgrGetPendingDeletes(true, &rels);
1165 	nchildren = xactGetCommittedChildren(&children);
1166 	if (XLogStandbyInfoActive())
1167 		nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
1168 													 &RelcacheInitFileInval);
1169 	wrote_xlog = (XactLastRecEnd != 0);
1170 
1171 	/*
1172 	 * If we haven't been assigned an XID yet, we neither can, nor do we want
1173 	 * to write a COMMIT record.
1174 	 */
1175 	if (!markXidCommitted)
1176 	{
1177 		/*
1178 		 * We expect that every smgrscheduleunlink is followed by a catalog
1179 		 * update, and hence XID assignment, so we shouldn't get here with any
1180 		 * pending deletes.  Use a real test not just an Assert to check this,
1181 		 * since it's a bit fragile.
1182 		 */
1183 		if (nrels != 0)
1184 			elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
1185 
1186 		/* Can't have child XIDs either; AssignTransactionId enforces this */
1187 		Assert(nchildren == 0);
1188 
1189 		/*
1190 		 * Transactions without an assigned xid can contain invalidation
1191 		 * messages (e.g. explicit relcache invalidations or catcache
1192 		 * invalidations for inplace updates); standbys need to process those.
1193 		 * We can't emit a commit record without an xid, and we don't want to
1194 		 * force assigning an xid, because that'd be problematic for e.g.
1195 		 * vacuum.  Hence we emit a bespoke record for the invalidations. We
1196 		 * don't want to use that in case a commit record is emitted, so they
1197 		 * happen synchronously with commits (besides not wanting to emit more
1198 		 * WAL recoreds).
1199 		 */
1200 		if (nmsgs != 0)
1201 		{
1202 			LogStandbyInvalidations(nmsgs, invalMessages,
1203 									RelcacheInitFileInval);
1204 			wrote_xlog = true;	/* not strictly necessary */
1205 		}
1206 
1207 		/*
1208 		 * If we didn't create XLOG entries, we're done here; otherwise we
1209 		 * should trigger flushing those entries the same as a commit record
1210 		 * would.  This will primarily happen for HOT pruning and the like; we
1211 		 * want these to be flushed to disk in due time.
1212 		 */
1213 		if (!wrote_xlog)
1214 			goto cleanup;
1215 	}
1216 	else
1217 	{
1218 		bool		replorigin;
1219 
1220 		/*
1221 		 * Are we using the replication origins feature?  Or, in other words,
1222 		 * are we replaying remote actions?
1223 		 */
1224 		replorigin = (replorigin_session_origin != InvalidRepOriginId &&
1225 					  replorigin_session_origin != DoNotReplicateId);
1226 
1227 		/*
1228 		 * Begin commit critical section and insert the commit XLOG record.
1229 		 */
1230 		/* Tell bufmgr and smgr to prepare for commit */
1231 		BufmgrCommit();
1232 
1233 		/*
1234 		 * Mark ourselves as within our "commit critical section".  This
1235 		 * forces any concurrent checkpoint to wait until we've updated
1236 		 * pg_xact.  Without this, it is possible for the checkpoint to set
1237 		 * REDO after the XLOG record but fail to flush the pg_xact update to
1238 		 * disk, leading to loss of the transaction commit if the system
1239 		 * crashes a little later.
1240 		 *
1241 		 * Note: we could, but don't bother to, set this flag in
1242 		 * RecordTransactionAbort.  That's because loss of a transaction abort
1243 		 * is noncritical; the presumption would be that it aborted, anyway.
1244 		 *
1245 		 * It's safe to change the delayChkpt flag of our own backend without
1246 		 * holding the ProcArrayLock, since we're the only one modifying it.
1247 		 * This makes checkpoint's determination of which xacts are delayChkpt
1248 		 * a bit fuzzy, but it doesn't matter.
1249 		 */
1250 		START_CRIT_SECTION();
1251 		MyPgXact->delayChkpt = true;
1252 
1253 		SetCurrentTransactionStopTimestamp();
1254 
1255 		XactLogCommitRecord(xactStopTimestamp,
1256 							nchildren, children, nrels, rels,
1257 							nmsgs, invalMessages,
1258 							RelcacheInitFileInval, forceSyncCommit,
1259 							MyXactFlags,
1260 							InvalidTransactionId /* plain commit */ );
1261 
1262 		if (replorigin)
1263 			/* Move LSNs forward for this replication origin */
1264 			replorigin_session_advance(replorigin_session_origin_lsn,
1265 									   XactLastRecEnd);
1266 
1267 		/*
1268 		 * Record commit timestamp.  The value comes from plain commit
1269 		 * timestamp if there's no replication origin; otherwise, the
1270 		 * timestamp was already set in replorigin_session_origin_timestamp by
1271 		 * replication.
1272 		 *
1273 		 * We don't need to WAL-log anything here, as the commit record
1274 		 * written above already contains the data.
1275 		 */
1276 
1277 		if (!replorigin || replorigin_session_origin_timestamp == 0)
1278 			replorigin_session_origin_timestamp = xactStopTimestamp;
1279 
1280 		TransactionTreeSetCommitTsData(xid, nchildren, children,
1281 									   replorigin_session_origin_timestamp,
1282 									   replorigin_session_origin, false);
1283 	}
1284 
1285 	/*
1286 	 * Check if we want to commit asynchronously.  We can allow the XLOG flush
1287 	 * to happen asynchronously if synchronous_commit=off, or if the current
1288 	 * transaction has not performed any WAL-logged operation or didn't assign
1289 	 * an xid.  The transaction can end up not writing any WAL, even if it has
1290 	 * an xid, if it only wrote to temporary and/or unlogged tables.  It can
1291 	 * end up having written WAL without an xid if it did HOT pruning.  In
1292 	 * case of a crash, the loss of such a transaction will be irrelevant;
1293 	 * temp tables will be lost anyway, unlogged tables will be truncated and
1294 	 * HOT pruning will be done again later. (Given the foregoing, you might
1295 	 * think that it would be unnecessary to emit the XLOG record at all in
1296 	 * this case, but we don't currently try to do that.  It would certainly
1297 	 * cause problems at least in Hot Standby mode, where the
1298 	 * KnownAssignedXids machinery requires tracking every XID assignment.  It
1299 	 * might be OK to skip it only when wal_level < replica, but for now we
1300 	 * don't.)
1301 	 *
1302 	 * However, if we're doing cleanup of any non-temp rels or committing any
1303 	 * command that wanted to force sync commit, then we must flush XLOG
1304 	 * immediately.  (We must not allow asynchronous commit if there are any
1305 	 * non-temp tables to be deleted, because we might delete the files before
1306 	 * the COMMIT record is flushed to disk.  We do allow asynchronous commit
1307 	 * if all to-be-deleted tables are temporary though, since they are lost
1308 	 * anyway if we crash.)
1309 	 */
1310 	if ((wrote_xlog && markXidCommitted &&
1311 		 synchronous_commit > SYNCHRONOUS_COMMIT_OFF) ||
1312 		forceSyncCommit || nrels > 0)
1313 	{
1314 		XLogFlush(XactLastRecEnd);
1315 
1316 		/*
1317 		 * Now we may update the CLOG, if we wrote a COMMIT record above
1318 		 */
1319 		if (markXidCommitted)
1320 			TransactionIdCommitTree(xid, nchildren, children);
1321 	}
1322 	else
1323 	{
1324 		/*
1325 		 * Asynchronous commit case:
1326 		 *
1327 		 * This enables possible committed transaction loss in the case of a
1328 		 * postmaster crash because WAL buffers are left unwritten. Ideally we
1329 		 * could issue the WAL write without the fsync, but some
1330 		 * wal_sync_methods do not allow separate write/fsync.
1331 		 *
1332 		 * Report the latest async commit LSN, so that the WAL writer knows to
1333 		 * flush this commit.
1334 		 */
1335 		XLogSetAsyncXactLSN(XactLastRecEnd);
1336 
1337 		/*
1338 		 * We must not immediately update the CLOG, since we didn't flush the
1339 		 * XLOG. Instead, we store the LSN up to which the XLOG must be
1340 		 * flushed before the CLOG may be updated.
1341 		 */
1342 		if (markXidCommitted)
1343 			TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1344 	}
1345 
1346 	/*
1347 	 * If we entered a commit critical section, leave it now, and let
1348 	 * checkpoints proceed.
1349 	 */
1350 	if (markXidCommitted)
1351 	{
1352 		MyPgXact->delayChkpt = false;
1353 		END_CRIT_SECTION();
1354 	}
1355 
1356 	/* Compute latestXid while we have the child XIDs handy */
1357 	latestXid = TransactionIdLatest(xid, nchildren, children);
1358 
1359 	/*
1360 	 * Wait for synchronous replication, if required. Similar to the decision
1361 	 * above about using committing asynchronously we only want to wait if
1362 	 * this backend assigned an xid and wrote WAL.  No need to wait if an xid
1363 	 * was assigned due to temporary/unlogged tables or due to HOT pruning.
1364 	 *
1365 	 * Note that at this stage we have marked clog, but still show as running
1366 	 * in the procarray and continue to hold locks.
1367 	 */
1368 	if (wrote_xlog && markXidCommitted)
1369 		SyncRepWaitForLSN(XactLastRecEnd, true);
1370 
1371 	/* remember end of last commit record */
1372 	XactLastCommitEnd = XactLastRecEnd;
1373 
1374 	/* Reset XactLastRecEnd until the next transaction writes something */
1375 	XactLastRecEnd = 0;
1376 cleanup:
1377 	/* Clean up local data */
1378 	if (rels)
1379 		pfree(rels);
1380 
1381 	return latestXid;
1382 }
1383 
1384 
1385 /*
1386  *	AtCCI_LocalCache
1387  */
1388 static void
AtCCI_LocalCache(void)1389 AtCCI_LocalCache(void)
1390 {
1391 	/*
1392 	 * Make any pending relation map changes visible.  We must do this before
1393 	 * processing local sinval messages, so that the map changes will get
1394 	 * reflected into the relcache when relcache invals are processed.
1395 	 */
1396 	AtCCI_RelationMap();
1397 
1398 	/*
1399 	 * Make catalog changes visible to me for the next command.
1400 	 */
1401 	CommandEndInvalidationMessages();
1402 }
1403 
1404 /*
1405  *	AtCommit_Memory
1406  */
1407 static void
AtCommit_Memory(void)1408 AtCommit_Memory(void)
1409 {
1410 	/*
1411 	 * Now that we're "out" of a transaction, have the system allocate things
1412 	 * in the top memory context instead of per-transaction contexts.
1413 	 */
1414 	MemoryContextSwitchTo(TopMemoryContext);
1415 
1416 	/*
1417 	 * Release all transaction-local memory.
1418 	 */
1419 	Assert(TopTransactionContext != NULL);
1420 	MemoryContextDelete(TopTransactionContext);
1421 	TopTransactionContext = NULL;
1422 	CurTransactionContext = NULL;
1423 	CurrentTransactionState->curTransactionContext = NULL;
1424 }
1425 
1426 /* ----------------------------------------------------------------
1427  *						CommitSubTransaction stuff
1428  * ----------------------------------------------------------------
1429  */
1430 
1431 /*
1432  * AtSubCommit_Memory
1433  */
1434 static void
AtSubCommit_Memory(void)1435 AtSubCommit_Memory(void)
1436 {
1437 	TransactionState s = CurrentTransactionState;
1438 
1439 	Assert(s->parent != NULL);
1440 
1441 	/* Return to parent transaction level's memory context. */
1442 	CurTransactionContext = s->parent->curTransactionContext;
1443 	MemoryContextSwitchTo(CurTransactionContext);
1444 
1445 	/*
1446 	 * Ordinarily we cannot throw away the child's CurTransactionContext,
1447 	 * since the data it contains will be needed at upper commit.  However, if
1448 	 * there isn't actually anything in it, we can throw it away.  This avoids
1449 	 * a small memory leak in the common case of "trivial" subxacts.
1450 	 */
1451 	if (MemoryContextIsEmpty(s->curTransactionContext))
1452 	{
1453 		MemoryContextDelete(s->curTransactionContext);
1454 		s->curTransactionContext = NULL;
1455 	}
1456 }
1457 
1458 /*
1459  * AtSubCommit_childXids
1460  *
1461  * Pass my own XID and my child XIDs up to my parent as committed children.
1462  */
1463 static void
AtSubCommit_childXids(void)1464 AtSubCommit_childXids(void)
1465 {
1466 	TransactionState s = CurrentTransactionState;
1467 	int			new_nChildXids;
1468 
1469 	Assert(s->parent != NULL);
1470 
1471 	/*
1472 	 * The parent childXids array will need to hold my XID and all my
1473 	 * childXids, in addition to the XIDs already there.
1474 	 */
1475 	new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1476 
1477 	/* Allocate or enlarge the parent array if necessary */
1478 	if (s->parent->maxChildXids < new_nChildXids)
1479 	{
1480 		int			new_maxChildXids;
1481 		TransactionId *new_childXids;
1482 
1483 		/*
1484 		 * Make it 2x what's needed right now, to avoid having to enlarge it
1485 		 * repeatedly. But we can't go above MaxAllocSize.  (The latter limit
1486 		 * is what ensures that we don't need to worry about integer overflow
1487 		 * here or in the calculation of new_nChildXids.)
1488 		 */
1489 		new_maxChildXids = Min(new_nChildXids * 2,
1490 							   (int) (MaxAllocSize / sizeof(TransactionId)));
1491 
1492 		if (new_maxChildXids < new_nChildXids)
1493 			ereport(ERROR,
1494 					(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1495 					 errmsg("maximum number of committed subtransactions (%d) exceeded",
1496 							(int) (MaxAllocSize / sizeof(TransactionId)))));
1497 
1498 		/*
1499 		 * We keep the child-XID arrays in TopTransactionContext; this avoids
1500 		 * setting up child-transaction contexts for what might be just a few
1501 		 * bytes of grandchild XIDs.
1502 		 */
1503 		if (s->parent->childXids == NULL)
1504 			new_childXids =
1505 				MemoryContextAlloc(TopTransactionContext,
1506 								   new_maxChildXids * sizeof(TransactionId));
1507 		else
1508 			new_childXids = repalloc(s->parent->childXids,
1509 									 new_maxChildXids * sizeof(TransactionId));
1510 
1511 		s->parent->childXids = new_childXids;
1512 		s->parent->maxChildXids = new_maxChildXids;
1513 	}
1514 
1515 	/*
1516 	 * Copy all my XIDs to parent's array.
1517 	 *
1518 	 * Note: We rely on the fact that the XID of a child always follows that
1519 	 * of its parent.  By copying the XID of this subtransaction before the
1520 	 * XIDs of its children, we ensure that the array stays ordered. Likewise,
1521 	 * all XIDs already in the array belong to subtransactions started and
1522 	 * subcommitted before us, so their XIDs must precede ours.
1523 	 */
1524 	s->parent->childXids[s->parent->nChildXids] = s->transactionId;
1525 
1526 	if (s->nChildXids > 0)
1527 		memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1528 			   s->childXids,
1529 			   s->nChildXids * sizeof(TransactionId));
1530 
1531 	s->parent->nChildXids = new_nChildXids;
1532 
1533 	/* Release child's array to avoid leakage */
1534 	if (s->childXids != NULL)
1535 		pfree(s->childXids);
1536 	/* We must reset these to avoid double-free if fail later in commit */
1537 	s->childXids = NULL;
1538 	s->nChildXids = 0;
1539 	s->maxChildXids = 0;
1540 }
1541 
1542 /* ----------------------------------------------------------------
1543  *						AbortTransaction stuff
1544  * ----------------------------------------------------------------
1545  */
1546 
1547 /*
1548  *	RecordTransactionAbort
1549  *
1550  * Returns latest XID among xact and its children, or InvalidTransactionId
1551  * if the xact has no XID.  (We compute that here just because it's easier.)
1552  */
1553 static TransactionId
RecordTransactionAbort(bool isSubXact)1554 RecordTransactionAbort(bool isSubXact)
1555 {
1556 	TransactionId xid = GetCurrentTransactionIdIfAny();
1557 	TransactionId latestXid;
1558 	int			nrels;
1559 	RelFileNode *rels;
1560 	int			nchildren;
1561 	TransactionId *children;
1562 	TimestampTz xact_time;
1563 
1564 	/*
1565 	 * If we haven't been assigned an XID, nobody will care whether we aborted
1566 	 * or not.  Hence, we're done in that case.  It does not matter if we have
1567 	 * rels to delete (note that this routine is not responsible for actually
1568 	 * deleting 'em).  We cannot have any child XIDs, either.
1569 	 */
1570 	if (!TransactionIdIsValid(xid))
1571 	{
1572 		/* Reset XactLastRecEnd until the next transaction writes something */
1573 		if (!isSubXact)
1574 			XactLastRecEnd = 0;
1575 		return InvalidTransactionId;
1576 	}
1577 
1578 	/*
1579 	 * We have a valid XID, so we should write an ABORT record for it.
1580 	 *
1581 	 * We do not flush XLOG to disk here, since the default assumption after a
1582 	 * crash would be that we aborted, anyway.  For the same reason, we don't
1583 	 * need to worry about interlocking against checkpoint start.
1584 	 */
1585 
1586 	/*
1587 	 * Check that we haven't aborted halfway through RecordTransactionCommit.
1588 	 */
1589 	if (TransactionIdDidCommit(xid))
1590 		elog(PANIC, "cannot abort transaction %u, it was already committed",
1591 			 xid);
1592 
1593 	/* Fetch the data we need for the abort record */
1594 	nrels = smgrGetPendingDeletes(false, &rels);
1595 	nchildren = xactGetCommittedChildren(&children);
1596 
1597 	/* XXX do we really need a critical section here? */
1598 	START_CRIT_SECTION();
1599 
1600 	/* Write the ABORT record */
1601 	if (isSubXact)
1602 		xact_time = GetCurrentTimestamp();
1603 	else
1604 	{
1605 		SetCurrentTransactionStopTimestamp();
1606 		xact_time = xactStopTimestamp;
1607 	}
1608 
1609 	XactLogAbortRecord(xact_time,
1610 					   nchildren, children,
1611 					   nrels, rels,
1612 					   MyXactFlags, InvalidTransactionId);
1613 
1614 	/*
1615 	 * Report the latest async abort LSN, so that the WAL writer knows to
1616 	 * flush this abort. There's nothing to be gained by delaying this, since
1617 	 * WALWriter may as well do this when it can. This is important with
1618 	 * streaming replication because if we don't flush WAL regularly we will
1619 	 * find that large aborts leave us with a long backlog for when commits
1620 	 * occur after the abort, increasing our window of data loss should
1621 	 * problems occur at that point.
1622 	 */
1623 	if (!isSubXact)
1624 		XLogSetAsyncXactLSN(XactLastRecEnd);
1625 
1626 	/*
1627 	 * Mark the transaction aborted in clog.  This is not absolutely necessary
1628 	 * but we may as well do it while we are here; also, in the subxact case
1629 	 * it is helpful because XactLockTableWait makes use of it to avoid
1630 	 * waiting for already-aborted subtransactions.  It is OK to do it without
1631 	 * having flushed the ABORT record to disk, because in event of a crash
1632 	 * we'd be assumed to have aborted anyway.
1633 	 */
1634 	TransactionIdAbortTree(xid, nchildren, children);
1635 
1636 	END_CRIT_SECTION();
1637 
1638 	/* Compute latestXid while we have the child XIDs handy */
1639 	latestXid = TransactionIdLatest(xid, nchildren, children);
1640 
1641 	/*
1642 	 * If we're aborting a subtransaction, we can immediately remove failed
1643 	 * XIDs from PGPROC's cache of running child XIDs.  We do that here for
1644 	 * subxacts, because we already have the child XID array at hand.  For
1645 	 * main xacts, the equivalent happens just after this function returns.
1646 	 */
1647 	if (isSubXact)
1648 		XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1649 
1650 	/* Reset XactLastRecEnd until the next transaction writes something */
1651 	if (!isSubXact)
1652 		XactLastRecEnd = 0;
1653 
1654 	/* And clean up local data */
1655 	if (rels)
1656 		pfree(rels);
1657 
1658 	return latestXid;
1659 }
1660 
1661 /*
1662  *	AtAbort_Memory
1663  */
1664 static void
AtAbort_Memory(void)1665 AtAbort_Memory(void)
1666 {
1667 	/*
1668 	 * Switch into TransactionAbortContext, which should have some free space
1669 	 * even if nothing else does.  We'll work in this context until we've
1670 	 * finished cleaning up.
1671 	 *
1672 	 * It is barely possible to get here when we've not been able to create
1673 	 * TransactionAbortContext yet; if so use TopMemoryContext.
1674 	 */
1675 	if (TransactionAbortContext != NULL)
1676 		MemoryContextSwitchTo(TransactionAbortContext);
1677 	else
1678 		MemoryContextSwitchTo(TopMemoryContext);
1679 }
1680 
1681 /*
1682  * AtSubAbort_Memory
1683  */
1684 static void
AtSubAbort_Memory(void)1685 AtSubAbort_Memory(void)
1686 {
1687 	Assert(TransactionAbortContext != NULL);
1688 
1689 	MemoryContextSwitchTo(TransactionAbortContext);
1690 }
1691 
1692 
1693 /*
1694  *	AtAbort_ResourceOwner
1695  */
1696 static void
AtAbort_ResourceOwner(void)1697 AtAbort_ResourceOwner(void)
1698 {
1699 	/*
1700 	 * Make sure we have a valid ResourceOwner, if possible (else it will be
1701 	 * NULL, which is OK)
1702 	 */
1703 	CurrentResourceOwner = TopTransactionResourceOwner;
1704 }
1705 
1706 /*
1707  * AtSubAbort_ResourceOwner
1708  */
1709 static void
AtSubAbort_ResourceOwner(void)1710 AtSubAbort_ResourceOwner(void)
1711 {
1712 	TransactionState s = CurrentTransactionState;
1713 
1714 	/* Make sure we have a valid ResourceOwner */
1715 	CurrentResourceOwner = s->curTransactionOwner;
1716 }
1717 
1718 
1719 /*
1720  * AtSubAbort_childXids
1721  */
1722 static void
AtSubAbort_childXids(void)1723 AtSubAbort_childXids(void)
1724 {
1725 	TransactionState s = CurrentTransactionState;
1726 
1727 	/*
1728 	 * We keep the child-XID arrays in TopTransactionContext (see
1729 	 * AtSubCommit_childXids).  This means we'd better free the array
1730 	 * explicitly at abort to avoid leakage.
1731 	 */
1732 	if (s->childXids != NULL)
1733 		pfree(s->childXids);
1734 	s->childXids = NULL;
1735 	s->nChildXids = 0;
1736 	s->maxChildXids = 0;
1737 
1738 	/*
1739 	 * We could prune the unreportedXids array here. But we don't bother. That
1740 	 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1741 	 * would likely introduce more CPU time into the more common paths, so we
1742 	 * choose not to do that.
1743 	 */
1744 }
1745 
1746 /* ----------------------------------------------------------------
1747  *						CleanupTransaction stuff
1748  * ----------------------------------------------------------------
1749  */
1750 
1751 /*
1752  *	AtCleanup_Memory
1753  */
1754 static void
AtCleanup_Memory(void)1755 AtCleanup_Memory(void)
1756 {
1757 	Assert(CurrentTransactionState->parent == NULL);
1758 
1759 	/*
1760 	 * Now that we're "out" of a transaction, have the system allocate things
1761 	 * in the top memory context instead of per-transaction contexts.
1762 	 */
1763 	MemoryContextSwitchTo(TopMemoryContext);
1764 
1765 	/*
1766 	 * Clear the special abort context for next time.
1767 	 */
1768 	if (TransactionAbortContext != NULL)
1769 		MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1770 
1771 	/*
1772 	 * Release all transaction-local memory.
1773 	 */
1774 	if (TopTransactionContext != NULL)
1775 		MemoryContextDelete(TopTransactionContext);
1776 	TopTransactionContext = NULL;
1777 	CurTransactionContext = NULL;
1778 	CurrentTransactionState->curTransactionContext = NULL;
1779 }
1780 
1781 
1782 /* ----------------------------------------------------------------
1783  *						CleanupSubTransaction stuff
1784  * ----------------------------------------------------------------
1785  */
1786 
1787 /*
1788  * AtSubCleanup_Memory
1789  */
1790 static void
AtSubCleanup_Memory(void)1791 AtSubCleanup_Memory(void)
1792 {
1793 	TransactionState s = CurrentTransactionState;
1794 
1795 	Assert(s->parent != NULL);
1796 
1797 	/* Make sure we're not in an about-to-be-deleted context */
1798 	MemoryContextSwitchTo(s->parent->curTransactionContext);
1799 	CurTransactionContext = s->parent->curTransactionContext;
1800 
1801 	/*
1802 	 * Clear the special abort context for next time.
1803 	 */
1804 	if (TransactionAbortContext != NULL)
1805 		MemoryContextResetAndDeleteChildren(TransactionAbortContext);
1806 
1807 	/*
1808 	 * Delete the subxact local memory contexts. Its CurTransactionContext can
1809 	 * go too (note this also kills CurTransactionContexts from any children
1810 	 * of the subxact).
1811 	 */
1812 	if (s->curTransactionContext)
1813 		MemoryContextDelete(s->curTransactionContext);
1814 	s->curTransactionContext = NULL;
1815 }
1816 
1817 /* ----------------------------------------------------------------
1818  *						interface routines
1819  * ----------------------------------------------------------------
1820  */
1821 
1822 /*
1823  *	StartTransaction
1824  */
1825 static void
StartTransaction(void)1826 StartTransaction(void)
1827 {
1828 	TransactionState s;
1829 	VirtualTransactionId vxid;
1830 
1831 	/*
1832 	 * Let's just make sure the state stack is empty
1833 	 */
1834 	s = &TopTransactionStateData;
1835 	CurrentTransactionState = s;
1836 
1837 	Assert(XactTopTransactionId == InvalidTransactionId);
1838 
1839 	/* check the current transaction state */
1840 	Assert(s->state == TRANS_DEFAULT);
1841 
1842 	/*
1843 	 * Set the current transaction state information appropriately during
1844 	 * start processing.  Note that once the transaction status is switched
1845 	 * this process cannot fail until the user ID and the security context
1846 	 * flags are fetched below.
1847 	 */
1848 	s->state = TRANS_START;
1849 	s->transactionId = InvalidTransactionId;	/* until assigned */
1850 
1851 	/*
1852 	 * initialize current transaction state fields
1853 	 *
1854 	 * note: prevXactReadOnly is not used at the outermost level
1855 	 */
1856 	s->nestingLevel = 1;
1857 	s->gucNestLevel = 1;
1858 	s->childXids = NULL;
1859 	s->nChildXids = 0;
1860 	s->maxChildXids = 0;
1861 
1862 	/*
1863 	 * Once the current user ID and the security context flags are fetched,
1864 	 * both will be properly reset even if transaction startup fails.
1865 	 */
1866 	GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
1867 
1868 	/* SecurityRestrictionContext should never be set outside a transaction */
1869 	Assert(s->prevSecContext == 0);
1870 
1871 	/*
1872 	 * Make sure we've reset xact state variables
1873 	 *
1874 	 * If recovery is still in progress, mark this transaction as read-only.
1875 	 * We have lower level defences in XLogInsert and elsewhere to stop us
1876 	 * from modifying data during recovery, but this gives the normal
1877 	 * indication to the user that the transaction is read-only.
1878 	 */
1879 	if (RecoveryInProgress())
1880 	{
1881 		s->startedInRecovery = true;
1882 		XactReadOnly = true;
1883 	}
1884 	else
1885 	{
1886 		s->startedInRecovery = false;
1887 		XactReadOnly = DefaultXactReadOnly;
1888 	}
1889 	XactDeferrable = DefaultXactDeferrable;
1890 	XactIsoLevel = DefaultXactIsoLevel;
1891 	forceSyncCommit = false;
1892 	MyXactFlags = 0;
1893 
1894 	/*
1895 	 * reinitialize within-transaction counters
1896 	 */
1897 	s->subTransactionId = TopSubTransactionId;
1898 	currentSubTransactionId = TopSubTransactionId;
1899 	currentCommandId = FirstCommandId;
1900 	currentCommandIdUsed = false;
1901 
1902 	/*
1903 	 * initialize reported xid accounting
1904 	 */
1905 	nUnreportedXids = 0;
1906 	s->didLogXid = false;
1907 
1908 	/*
1909 	 * must initialize resource-management stuff first
1910 	 */
1911 	AtStart_Memory();
1912 	AtStart_ResourceOwner();
1913 
1914 	/*
1915 	 * Assign a new LocalTransactionId, and combine it with the backendId to
1916 	 * form a virtual transaction id.
1917 	 */
1918 	vxid.backendId = MyBackendId;
1919 	vxid.localTransactionId = GetNextLocalTransactionId();
1920 
1921 	/*
1922 	 * Lock the virtual transaction id before we announce it in the proc array
1923 	 */
1924 	VirtualXactLockTableInsert(vxid);
1925 
1926 	/*
1927 	 * Advertise it in the proc array.  We assume assignment of
1928 	 * LocalTransactionID is atomic, and the backendId should be set already.
1929 	 */
1930 	Assert(MyProc->backendId == vxid.backendId);
1931 	MyProc->lxid = vxid.localTransactionId;
1932 
1933 	TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
1934 
1935 	/*
1936 	 * set transaction_timestamp() (a/k/a now()).  We want this to be the same
1937 	 * as the first command's statement_timestamp(), so don't do a fresh
1938 	 * GetCurrentTimestamp() call (which'd be expensive anyway).  In a
1939 	 * parallel worker, this should already have been provided by a call to
1940 	 * SetParallelStartTimestamps().
1941 	 *
1942 	 * Also, mark xactStopTimestamp as unset.
1943 	 */
1944 	if (!IsParallelWorker())
1945 		xactStartTimestamp = stmtStartTimestamp;
1946 	else
1947 		Assert(xactStartTimestamp != 0);
1948 	xactStopTimestamp = 0;
1949 	pgstat_report_xact_timestamp(xactStartTimestamp);
1950 
1951 	/*
1952 	 * initialize other subsystems for new transaction
1953 	 */
1954 	AtStart_GUC();
1955 	AtStart_Cache();
1956 	AfterTriggerBeginXact();
1957 
1958 	/*
1959 	 * done with start processing, set current transaction state to "in
1960 	 * progress"
1961 	 */
1962 	s->state = TRANS_INPROGRESS;
1963 
1964 	ShowTransactionState("StartTransaction");
1965 }
1966 
1967 
1968 /*
1969  *	CommitTransaction
1970  *
1971  * NB: if you change this routine, better look at PrepareTransaction too!
1972  */
1973 static void
CommitTransaction(void)1974 CommitTransaction(void)
1975 {
1976 	TransactionState s = CurrentTransactionState;
1977 	TransactionId latestXid;
1978 	bool		is_parallel_worker;
1979 
1980 	is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
1981 
1982 	/* Enforce parallel mode restrictions during parallel worker commit. */
1983 	if (is_parallel_worker)
1984 		EnterParallelMode();
1985 
1986 	ShowTransactionState("CommitTransaction");
1987 
1988 	/*
1989 	 * check the current transaction state
1990 	 */
1991 	if (s->state != TRANS_INPROGRESS)
1992 		elog(WARNING, "CommitTransaction while in %s state",
1993 			 TransStateAsString(s->state));
1994 	Assert(s->parent == NULL);
1995 
1996 	/*
1997 	 * Do pre-commit processing that involves calling user-defined code, such
1998 	 * as triggers.  SECURITY_RESTRICTED_OPERATION contexts must not queue an
1999 	 * action that would run here, because that would bypass the sandbox.
2000 	 * Since closing cursors could queue trigger actions, triggers could open
2001 	 * cursors, etc, we have to keep looping until there's nothing left to do.
2002 	 */
2003 	for (;;)
2004 	{
2005 		/*
2006 		 * Fire all currently pending deferred triggers.
2007 		 */
2008 		AfterTriggerFireDeferred();
2009 
2010 		/*
2011 		 * Close open portals (converting holdable ones into static portals).
2012 		 * If there weren't any, we are done ... otherwise loop back to check
2013 		 * if they queued deferred triggers.  Lather, rinse, repeat.
2014 		 */
2015 		if (!PreCommit_Portals(false))
2016 			break;
2017 	}
2018 
2019 	/*
2020 	 * The remaining actions cannot call any user-defined code, so it's safe
2021 	 * to start shutting down within-transaction services.  But note that most
2022 	 * of this stuff could still throw an error, which would switch us into
2023 	 * the transaction-abort path.
2024 	 */
2025 
2026 	CallXactCallbacks(is_parallel_worker ? XACT_EVENT_PARALLEL_PRE_COMMIT
2027 					  : XACT_EVENT_PRE_COMMIT);
2028 
2029 	/* If we might have parallel workers, clean them up now. */
2030 	if (IsInParallelMode())
2031 		AtEOXact_Parallel(true);
2032 
2033 	/* Shut down the deferred-trigger manager */
2034 	AfterTriggerEndXact(true);
2035 
2036 	/*
2037 	 * Let ON COMMIT management do its thing (must happen after closing
2038 	 * cursors, to avoid dangling-reference problems)
2039 	 */
2040 	PreCommit_on_commit_actions();
2041 
2042 	/* close large objects before lower-level cleanup */
2043 	AtEOXact_LargeObject(true);
2044 
2045 	/*
2046 	 * Insert notifications sent by NOTIFY commands into the queue.  This
2047 	 * should be late in the pre-commit sequence to minimize time spent
2048 	 * holding the notify-insertion lock.  However, this could result in
2049 	 * creating a snapshot, so we must do it before serializable cleanup.
2050 	 */
2051 	PreCommit_Notify();
2052 
2053 	/*
2054 	 * Mark serializable transaction as complete for predicate locking
2055 	 * purposes.  This should be done as late as we can put it and still allow
2056 	 * errors to be raised for failure patterns found at commit.
2057 	 */
2058 	PreCommit_CheckForSerializationFailure();
2059 
2060 	/* Prevent cancel/die interrupt while cleaning up */
2061 	HOLD_INTERRUPTS();
2062 
2063 	/* Commit updates to the relation map --- do this as late as possible */
2064 	AtEOXact_RelationMap(true);
2065 
2066 	/*
2067 	 * set the current transaction state information appropriately during
2068 	 * commit processing
2069 	 */
2070 	s->state = TRANS_COMMIT;
2071 	s->parallelModeLevel = 0;
2072 
2073 	if (!is_parallel_worker)
2074 	{
2075 		/*
2076 		 * We need to mark our XIDs as committed in pg_xact.  This is where we
2077 		 * durably commit.
2078 		 */
2079 		latestXid = RecordTransactionCommit();
2080 	}
2081 	else
2082 	{
2083 		/*
2084 		 * We must not mark our XID committed; the parallel master is
2085 		 * responsible for that.
2086 		 */
2087 		latestXid = InvalidTransactionId;
2088 
2089 		/*
2090 		 * Make sure the master will know about any WAL we wrote before it
2091 		 * commits.
2092 		 */
2093 		ParallelWorkerReportLastRecEnd(XactLastRecEnd);
2094 	}
2095 
2096 	TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
2097 
2098 	/*
2099 	 * Let others know about no transaction in progress by me. Note that this
2100 	 * must be done _before_ releasing locks we hold and _after_
2101 	 * RecordTransactionCommit.
2102 	 */
2103 	ProcArrayEndTransaction(MyProc, latestXid);
2104 
2105 	/*
2106 	 * This is all post-commit cleanup.  Note that if an error is raised here,
2107 	 * it's too late to abort the transaction.  This should be just
2108 	 * noncritical resource releasing.
2109 	 *
2110 	 * The ordering of operations is not entirely random.  The idea is:
2111 	 * release resources visible to other backends (eg, files, buffer pins);
2112 	 * then release locks; then release backend-local resources. We want to
2113 	 * release locks at the point where any backend waiting for us will see
2114 	 * our transaction as being fully cleaned up.
2115 	 *
2116 	 * Resources that can be associated with individual queries are handled by
2117 	 * the ResourceOwner mechanism.  The other calls here are for backend-wide
2118 	 * state.
2119 	 */
2120 
2121 	CallXactCallbacks(is_parallel_worker ? XACT_EVENT_PARALLEL_COMMIT
2122 					  : XACT_EVENT_COMMIT);
2123 
2124 	ResourceOwnerRelease(TopTransactionResourceOwner,
2125 						 RESOURCE_RELEASE_BEFORE_LOCKS,
2126 						 true, true);
2127 
2128 	/* Check we've released all buffer pins */
2129 	AtEOXact_Buffers(true);
2130 
2131 	/* Clean up the relation cache */
2132 	AtEOXact_RelationCache(true);
2133 
2134 	/*
2135 	 * Make catalog changes visible to all backends.  This has to happen after
2136 	 * relcache references are dropped (see comments for
2137 	 * AtEOXact_RelationCache), but before locks are released (if anyone is
2138 	 * waiting for lock on a relation we've modified, we want them to know
2139 	 * about the catalog change before they start using the relation).
2140 	 */
2141 	AtEOXact_Inval(true);
2142 
2143 	AtEOXact_MultiXact();
2144 
2145 	ResourceOwnerRelease(TopTransactionResourceOwner,
2146 						 RESOURCE_RELEASE_LOCKS,
2147 						 true, true);
2148 	ResourceOwnerRelease(TopTransactionResourceOwner,
2149 						 RESOURCE_RELEASE_AFTER_LOCKS,
2150 						 true, true);
2151 
2152 	/*
2153 	 * Likewise, dropping of files deleted during the transaction is best done
2154 	 * after releasing relcache and buffer pins.  (This is not strictly
2155 	 * necessary during commit, since such pins should have been released
2156 	 * already, but this ordering is definitely critical during abort.)  Since
2157 	 * this may take many seconds, also delay until after releasing locks.
2158 	 * Other backends will observe the attendant catalog changes and not
2159 	 * attempt to access affected files.
2160 	 */
2161 	smgrDoPendingDeletes(true);
2162 
2163 	AtCommit_Notify();
2164 	AtEOXact_GUC(true, 1);
2165 	AtEOXact_SPI(true);
2166 	AtEOXact_on_commit_actions(true);
2167 	AtEOXact_Namespace(true, is_parallel_worker);
2168 	AtEOXact_SMgr();
2169 	AtEOXact_Files();
2170 	AtEOXact_ComboCid();
2171 	AtEOXact_HashTables(true);
2172 	AtEOXact_PgStat(true, is_parallel_worker);
2173 	AtEOXact_Snapshot(true, false);
2174 	AtEOXact_ApplyLauncher(true);
2175 	pgstat_report_xact_timestamp(0);
2176 
2177 	CurrentResourceOwner = NULL;
2178 	ResourceOwnerDelete(TopTransactionResourceOwner);
2179 	s->curTransactionOwner = NULL;
2180 	CurTransactionResourceOwner = NULL;
2181 	TopTransactionResourceOwner = NULL;
2182 
2183 	AtCommit_Memory();
2184 
2185 	s->transactionId = InvalidTransactionId;
2186 	s->subTransactionId = InvalidSubTransactionId;
2187 	s->nestingLevel = 0;
2188 	s->gucNestLevel = 0;
2189 	s->childXids = NULL;
2190 	s->nChildXids = 0;
2191 	s->maxChildXids = 0;
2192 
2193 	XactTopTransactionId = InvalidTransactionId;
2194 	nParallelCurrentXids = 0;
2195 
2196 	/*
2197 	 * done with commit processing, set current transaction state back to
2198 	 * default
2199 	 */
2200 	s->state = TRANS_DEFAULT;
2201 
2202 	RESUME_INTERRUPTS();
2203 }
2204 
2205 
2206 /*
2207  *	PrepareTransaction
2208  *
2209  * NB: if you change this routine, better look at CommitTransaction too!
2210  */
2211 static void
PrepareTransaction(void)2212 PrepareTransaction(void)
2213 {
2214 	TransactionState s = CurrentTransactionState;
2215 	TransactionId xid = GetCurrentTransactionId();
2216 	GlobalTransaction gxact;
2217 	TimestampTz prepared_at;
2218 
2219 	Assert(!IsInParallelMode());
2220 
2221 	ShowTransactionState("PrepareTransaction");
2222 
2223 	/*
2224 	 * check the current transaction state
2225 	 */
2226 	if (s->state != TRANS_INPROGRESS)
2227 		elog(WARNING, "PrepareTransaction while in %s state",
2228 			 TransStateAsString(s->state));
2229 	Assert(s->parent == NULL);
2230 
2231 	/*
2232 	 * Do pre-commit processing that involves calling user-defined code, such
2233 	 * as triggers.  Since closing cursors could queue trigger actions,
2234 	 * triggers could open cursors, etc, we have to keep looping until there's
2235 	 * nothing left to do.
2236 	 */
2237 	for (;;)
2238 	{
2239 		/*
2240 		 * Fire all currently pending deferred triggers.
2241 		 */
2242 		AfterTriggerFireDeferred();
2243 
2244 		/*
2245 		 * Close open portals (converting holdable ones into static portals).
2246 		 * If there weren't any, we are done ... otherwise loop back to check
2247 		 * if they queued deferred triggers.  Lather, rinse, repeat.
2248 		 */
2249 		if (!PreCommit_Portals(true))
2250 			break;
2251 	}
2252 
2253 	CallXactCallbacks(XACT_EVENT_PRE_PREPARE);
2254 
2255 	/*
2256 	 * The remaining actions cannot call any user-defined code, so it's safe
2257 	 * to start shutting down within-transaction services.  But note that most
2258 	 * of this stuff could still throw an error, which would switch us into
2259 	 * the transaction-abort path.
2260 	 */
2261 
2262 	/* Shut down the deferred-trigger manager */
2263 	AfterTriggerEndXact(true);
2264 
2265 	/*
2266 	 * Let ON COMMIT management do its thing (must happen after closing
2267 	 * cursors, to avoid dangling-reference problems)
2268 	 */
2269 	PreCommit_on_commit_actions();
2270 
2271 	/* close large objects before lower-level cleanup */
2272 	AtEOXact_LargeObject(true);
2273 
2274 	/* NOTIFY requires no work at this point */
2275 
2276 	/*
2277 	 * Mark serializable transaction as complete for predicate locking
2278 	 * purposes.  This should be done as late as we can put it and still allow
2279 	 * errors to be raised for failure patterns found at commit.
2280 	 */
2281 	PreCommit_CheckForSerializationFailure();
2282 
2283 	/*
2284 	 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2285 	 * this transaction.  Having the prepared xact hold locks on another
2286 	 * backend's temp table seems a bad idea --- for instance it would prevent
2287 	 * the backend from exiting.  There are other problems too, such as how to
2288 	 * clean up the source backend's local buffers and ON COMMIT state if the
2289 	 * prepared xact includes a DROP of a temp table.
2290 	 *
2291 	 * We must check this after executing any ON COMMIT actions, because they
2292 	 * might still access a temp relation.
2293 	 *
2294 	 * XXX In principle this could be relaxed to allow some useful special
2295 	 * cases, such as a temp table created and dropped all within the
2296 	 * transaction.  That seems to require much more bookkeeping though.
2297 	 */
2298 	if ((MyXactFlags & XACT_FLAGS_ACCESSEDTEMPREL))
2299 		ereport(ERROR,
2300 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2301 				 errmsg("cannot PREPARE a transaction that has operated on temporary tables")));
2302 
2303 	/*
2304 	 * Similarly, PREPARE TRANSACTION is not allowed if the temporary
2305 	 * namespace has been involved in this transaction as we cannot allow it
2306 	 * to create, lock, or even drop objects within the temporary namespace
2307 	 * as this can mess up with this session or even a follow-up session
2308 	 * trying to use the same temporary namespace.
2309 	 */
2310 	if ((MyXactFlags & XACT_FLAGS_ACCESSEDTEMPNAMESPACE))
2311 		ereport(ERROR,
2312 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2313 				 errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2314 
2315 	/*
2316 	 * Likewise, don't allow PREPARE after pg_export_snapshot.  This could be
2317 	 * supported if we added cleanup logic to twophase.c, but for now it
2318 	 * doesn't seem worth the trouble.
2319 	 */
2320 	if (XactHasExportedSnapshots())
2321 		ereport(ERROR,
2322 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2323 				 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2324 
2325 	/*
2326 	 * Don't allow PREPARE but for transaction that has/might kill logical
2327 	 * replication workers.
2328 	 */
2329 	if (XactManipulatesLogicalReplicationWorkers())
2330 		ereport(ERROR,
2331 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2332 				 errmsg("cannot PREPARE a transaction that has manipulated logical replication workers")));
2333 
2334 	/* Prevent cancel/die interrupt while cleaning up */
2335 	HOLD_INTERRUPTS();
2336 
2337 	/*
2338 	 * set the current transaction state information appropriately during
2339 	 * prepare processing
2340 	 */
2341 	s->state = TRANS_PREPARE;
2342 
2343 	prepared_at = GetCurrentTimestamp();
2344 
2345 	/* Tell bufmgr and smgr to prepare for commit */
2346 	BufmgrCommit();
2347 
2348 	/*
2349 	 * Reserve the GID for this transaction. This could fail if the requested
2350 	 * GID is invalid or already in use.
2351 	 */
2352 	gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
2353 							GetUserId(), MyDatabaseId);
2354 	prepareGID = NULL;
2355 
2356 	/*
2357 	 * Collect data for the 2PC state file.  Note that in general, no actual
2358 	 * state change should happen in the called modules during this step,
2359 	 * since it's still possible to fail before commit, and in that case we
2360 	 * want transaction abort to be able to clean up.  (In particular, the
2361 	 * AtPrepare routines may error out if they find cases they cannot
2362 	 * handle.)  State cleanup should happen in the PostPrepare routines
2363 	 * below.  However, some modules can go ahead and clear state here because
2364 	 * they wouldn't do anything with it during abort anyway.
2365 	 *
2366 	 * Note: because the 2PC state file records will be replayed in the same
2367 	 * order they are made, the order of these calls has to match the order in
2368 	 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2369 	 * PREPARED; in particular, pay attention to whether things should happen
2370 	 * before or after releasing the transaction's locks.
2371 	 */
2372 	StartPrepare(gxact);
2373 
2374 	AtPrepare_Notify();
2375 	AtPrepare_Locks();
2376 	AtPrepare_PredicateLocks();
2377 	AtPrepare_PgStat();
2378 	AtPrepare_MultiXact();
2379 	AtPrepare_RelationMap();
2380 
2381 	/*
2382 	 * Here is where we really truly prepare.
2383 	 *
2384 	 * We have to record transaction prepares even if we didn't make any
2385 	 * updates, because the transaction manager might get confused if we lose
2386 	 * a global transaction.
2387 	 */
2388 	EndPrepare(gxact);
2389 
2390 	/*
2391 	 * Now we clean up backend-internal state and release internal resources.
2392 	 */
2393 
2394 	/* Reset XactLastRecEnd until the next transaction writes something */
2395 	XactLastRecEnd = 0;
2396 
2397 	/*
2398 	 * Transfer our locks to a dummy PGPROC.  This has to be done before
2399 	 * ProcArrayClearTransaction().  Otherwise, a GetLockConflicts() would
2400 	 * conclude "xact already committed or aborted" for our locks.
2401 	 */
2402 	PostPrepare_Locks(xid);
2403 
2404 	/*
2405 	 * Let others know about no transaction in progress by me.  This has to be
2406 	 * done *after* the prepared transaction has been marked valid, else
2407 	 * someone may think it is unlocked and recyclable.
2408 	 */
2409 	ProcArrayClearTransaction(MyProc);
2410 
2411 	/*
2412 	 * In normal commit-processing, this is all non-critical post-transaction
2413 	 * cleanup.  When the transaction is prepared, however, it's important
2414 	 * that the locks and other per-backend resources are transferred to the
2415 	 * prepared transaction's PGPROC entry.  Note that if an error is raised
2416 	 * here, it's too late to abort the transaction. XXX: This probably should
2417 	 * be in a critical section, to force a PANIC if any of this fails, but
2418 	 * that cure could be worse than the disease.
2419 	 */
2420 
2421 	CallXactCallbacks(XACT_EVENT_PREPARE);
2422 
2423 	ResourceOwnerRelease(TopTransactionResourceOwner,
2424 						 RESOURCE_RELEASE_BEFORE_LOCKS,
2425 						 true, true);
2426 
2427 	/* Check we've released all buffer pins */
2428 	AtEOXact_Buffers(true);
2429 
2430 	/* Clean up the relation cache */
2431 	AtEOXact_RelationCache(true);
2432 
2433 	/* notify doesn't need a postprepare call */
2434 
2435 	PostPrepare_PgStat();
2436 
2437 	PostPrepare_Inval();
2438 
2439 	PostPrepare_smgr();
2440 
2441 	PostPrepare_MultiXact(xid);
2442 
2443 	PostPrepare_PredicateLocks(xid);
2444 
2445 	ResourceOwnerRelease(TopTransactionResourceOwner,
2446 						 RESOURCE_RELEASE_LOCKS,
2447 						 true, true);
2448 	ResourceOwnerRelease(TopTransactionResourceOwner,
2449 						 RESOURCE_RELEASE_AFTER_LOCKS,
2450 						 true, true);
2451 
2452 	/*
2453 	 * Allow another backend to finish the transaction.  After
2454 	 * PostPrepare_Twophase(), the transaction is completely detached from our
2455 	 * backend.  The rest is just non-critical cleanup of backend-local state.
2456 	 */
2457 	PostPrepare_Twophase();
2458 
2459 	/* PREPARE acts the same as COMMIT as far as GUC is concerned */
2460 	AtEOXact_GUC(true, 1);
2461 	AtEOXact_SPI(true);
2462 	AtEOXact_on_commit_actions(true);
2463 	AtEOXact_Namespace(true, false);
2464 	AtEOXact_SMgr();
2465 	AtEOXact_Files();
2466 	AtEOXact_ComboCid();
2467 	AtEOXact_HashTables(true);
2468 	/* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2469 	AtEOXact_Snapshot(true, true);
2470 	pgstat_report_xact_timestamp(0);
2471 
2472 	CurrentResourceOwner = NULL;
2473 	ResourceOwnerDelete(TopTransactionResourceOwner);
2474 	s->curTransactionOwner = NULL;
2475 	CurTransactionResourceOwner = NULL;
2476 	TopTransactionResourceOwner = NULL;
2477 
2478 	AtCommit_Memory();
2479 
2480 	s->transactionId = InvalidTransactionId;
2481 	s->subTransactionId = InvalidSubTransactionId;
2482 	s->nestingLevel = 0;
2483 	s->gucNestLevel = 0;
2484 	s->childXids = NULL;
2485 	s->nChildXids = 0;
2486 	s->maxChildXids = 0;
2487 
2488 	XactTopTransactionId = InvalidTransactionId;
2489 	nParallelCurrentXids = 0;
2490 
2491 	/*
2492 	 * done with 1st phase commit processing, set current transaction state
2493 	 * back to default
2494 	 */
2495 	s->state = TRANS_DEFAULT;
2496 
2497 	RESUME_INTERRUPTS();
2498 }
2499 
2500 
2501 /*
2502  *	AbortTransaction
2503  */
2504 static void
AbortTransaction(void)2505 AbortTransaction(void)
2506 {
2507 	TransactionState s = CurrentTransactionState;
2508 	TransactionId latestXid;
2509 	bool		is_parallel_worker;
2510 
2511 	/* Prevent cancel/die interrupt while cleaning up */
2512 	HOLD_INTERRUPTS();
2513 
2514 	/* Make sure we have a valid memory context and resource owner */
2515 	AtAbort_Memory();
2516 	AtAbort_ResourceOwner();
2517 
2518 	/*
2519 	 * Release any LW locks we might be holding as quickly as possible.
2520 	 * (Regular locks, however, must be held till we finish aborting.)
2521 	 * Releasing LW locks is critical since we might try to grab them again
2522 	 * while cleaning up!
2523 	 */
2524 	LWLockReleaseAll();
2525 
2526 	/* Clear wait information and command progress indicator */
2527 	pgstat_report_wait_end();
2528 	pgstat_progress_end_command();
2529 
2530 	/* Clean up buffer I/O and buffer context locks, too */
2531 	AbortBufferIO();
2532 	UnlockBuffers();
2533 
2534 	/* Reset WAL record construction state */
2535 	XLogResetInsertion();
2536 
2537 	/* Cancel condition variable sleep */
2538 	ConditionVariableCancelSleep();
2539 
2540 	/*
2541 	 * Also clean up any open wait for lock, since the lock manager will choke
2542 	 * if we try to wait for another lock before doing this.
2543 	 */
2544 	LockErrorCleanup();
2545 
2546 	/*
2547 	 * If any timeout events are still active, make sure the timeout interrupt
2548 	 * is scheduled.  This covers possible loss of a timeout interrupt due to
2549 	 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2550 	 * We delay this till after LockErrorCleanup so that we don't uselessly
2551 	 * reschedule lock or deadlock check timeouts.
2552 	 */
2553 	reschedule_timeouts();
2554 
2555 	/*
2556 	 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2557 	 * handler.  We do this fairly early in the sequence so that the timeout
2558 	 * infrastructure will be functional if needed while aborting.
2559 	 */
2560 	PG_SETMASK(&UnBlockSig);
2561 
2562 	/*
2563 	 * check the current transaction state
2564 	 */
2565 	is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2566 	if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2567 		elog(WARNING, "AbortTransaction while in %s state",
2568 			 TransStateAsString(s->state));
2569 	Assert(s->parent == NULL);
2570 
2571 	/*
2572 	 * set the current transaction state information appropriately during the
2573 	 * abort processing
2574 	 */
2575 	s->state = TRANS_ABORT;
2576 
2577 	/*
2578 	 * Reset user ID which might have been changed transiently.  We need this
2579 	 * to clean up in case control escaped out of a SECURITY DEFINER function
2580 	 * or other local change of CurrentUserId; therefore, the prior value of
2581 	 * SecurityRestrictionContext also needs to be restored.
2582 	 *
2583 	 * (Note: it is not necessary to restore session authorization or role
2584 	 * settings here because those can only be changed via GUC, and GUC will
2585 	 * take care of rolling them back if need be.)
2586 	 */
2587 	SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
2588 
2589 	/* Forget about any active REINDEX. */
2590 	ResetReindexState(s->nestingLevel);
2591 
2592 	/* Reset snapshot export state. */
2593 	SnapBuildResetExportedSnapshotState();
2594 
2595 	/* If in parallel mode, clean up workers and exit parallel mode. */
2596 	if (IsInParallelMode())
2597 	{
2598 		AtEOXact_Parallel(false);
2599 		s->parallelModeLevel = 0;
2600 	}
2601 
2602 	/*
2603 	 * do abort processing
2604 	 */
2605 	AfterTriggerEndXact(false); /* 'false' means it's abort */
2606 	AtAbort_Portals();
2607 	AtEOXact_LargeObject(false);
2608 	AtAbort_Notify();
2609 	AtEOXact_RelationMap(false);
2610 	AtAbort_Twophase();
2611 
2612 	/*
2613 	 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2614 	 * far as assigning an XID to advertise).  But if we're inside a parallel
2615 	 * worker, skip this; the user backend must be the one to write the abort
2616 	 * record.
2617 	 */
2618 	if (!is_parallel_worker)
2619 		latestXid = RecordTransactionAbort(false);
2620 	else
2621 	{
2622 		latestXid = InvalidTransactionId;
2623 
2624 		/*
2625 		 * Since the parallel master won't get our value of XactLastRecEnd in
2626 		 * this case, we nudge WAL-writer ourselves in this case.  See related
2627 		 * comments in RecordTransactionAbort for why this matters.
2628 		 */
2629 		XLogSetAsyncXactLSN(XactLastRecEnd);
2630 	}
2631 
2632 	TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
2633 
2634 	/*
2635 	 * Let others know about no transaction in progress by me. Note that this
2636 	 * must be done _before_ releasing locks we hold and _after_
2637 	 * RecordTransactionAbort.
2638 	 */
2639 	ProcArrayEndTransaction(MyProc, latestXid);
2640 
2641 	/*
2642 	 * Post-abort cleanup.  See notes in CommitTransaction() concerning
2643 	 * ordering.  We can skip all of it if the transaction failed before
2644 	 * creating a resource owner.
2645 	 */
2646 	if (TopTransactionResourceOwner != NULL)
2647 	{
2648 		if (is_parallel_worker)
2649 			CallXactCallbacks(XACT_EVENT_PARALLEL_ABORT);
2650 		else
2651 			CallXactCallbacks(XACT_EVENT_ABORT);
2652 
2653 		ResourceOwnerRelease(TopTransactionResourceOwner,
2654 							 RESOURCE_RELEASE_BEFORE_LOCKS,
2655 							 false, true);
2656 		AtEOXact_Buffers(false);
2657 		AtEOXact_RelationCache(false);
2658 		AtEOXact_Inval(false);
2659 		AtEOXact_MultiXact();
2660 		ResourceOwnerRelease(TopTransactionResourceOwner,
2661 							 RESOURCE_RELEASE_LOCKS,
2662 							 false, true);
2663 		ResourceOwnerRelease(TopTransactionResourceOwner,
2664 							 RESOURCE_RELEASE_AFTER_LOCKS,
2665 							 false, true);
2666 		smgrDoPendingDeletes(false);
2667 
2668 		AtEOXact_GUC(false, 1);
2669 		AtEOXact_SPI(false);
2670 		AtEOXact_on_commit_actions(false);
2671 		AtEOXact_Namespace(false, is_parallel_worker);
2672 		AtEOXact_SMgr();
2673 		AtEOXact_Files();
2674 		AtEOXact_ComboCid();
2675 		AtEOXact_HashTables(false);
2676 		AtEOXact_PgStat(false, is_parallel_worker);
2677 		AtEOXact_ApplyLauncher(false);
2678 		pgstat_report_xact_timestamp(0);
2679 	}
2680 
2681 	/*
2682 	 * State remains TRANS_ABORT until CleanupTransaction().
2683 	 */
2684 	RESUME_INTERRUPTS();
2685 }
2686 
2687 /*
2688  *	CleanupTransaction
2689  */
2690 static void
CleanupTransaction(void)2691 CleanupTransaction(void)
2692 {
2693 	TransactionState s = CurrentTransactionState;
2694 
2695 	/*
2696 	 * State should still be TRANS_ABORT from AbortTransaction().
2697 	 */
2698 	if (s->state != TRANS_ABORT)
2699 		elog(FATAL, "CleanupTransaction: unexpected state %s",
2700 			 TransStateAsString(s->state));
2701 
2702 	/*
2703 	 * do abort cleanup processing
2704 	 */
2705 	AtCleanup_Portals();		/* now safe to release portal memory */
2706 	AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
2707 
2708 	CurrentResourceOwner = NULL;	/* and resource owner */
2709 	if (TopTransactionResourceOwner)
2710 		ResourceOwnerDelete(TopTransactionResourceOwner);
2711 	s->curTransactionOwner = NULL;
2712 	CurTransactionResourceOwner = NULL;
2713 	TopTransactionResourceOwner = NULL;
2714 
2715 	AtCleanup_Memory();			/* and transaction memory */
2716 
2717 	s->transactionId = InvalidTransactionId;
2718 	s->subTransactionId = InvalidSubTransactionId;
2719 	s->nestingLevel = 0;
2720 	s->gucNestLevel = 0;
2721 	s->childXids = NULL;
2722 	s->nChildXids = 0;
2723 	s->maxChildXids = 0;
2724 	s->parallelModeLevel = 0;
2725 
2726 	XactTopTransactionId = InvalidTransactionId;
2727 	nParallelCurrentXids = 0;
2728 
2729 	/*
2730 	 * done with abort processing, set current transaction state back to
2731 	 * default
2732 	 */
2733 	s->state = TRANS_DEFAULT;
2734 }
2735 
2736 /*
2737  *	StartTransactionCommand
2738  */
2739 void
StartTransactionCommand(void)2740 StartTransactionCommand(void)
2741 {
2742 	TransactionState s = CurrentTransactionState;
2743 
2744 	switch (s->blockState)
2745 	{
2746 			/*
2747 			 * if we aren't in a transaction block, we just do our usual start
2748 			 * transaction.
2749 			 */
2750 		case TBLOCK_DEFAULT:
2751 			StartTransaction();
2752 			s->blockState = TBLOCK_STARTED;
2753 			break;
2754 
2755 			/*
2756 			 * We are somewhere in a transaction block or subtransaction and
2757 			 * about to start a new command.  For now we do nothing, but
2758 			 * someday we may do command-local resource initialization. (Note
2759 			 * that any needed CommandCounterIncrement was done by the
2760 			 * previous CommitTransactionCommand.)
2761 			 */
2762 		case TBLOCK_INPROGRESS:
2763 		case TBLOCK_SUBINPROGRESS:
2764 			break;
2765 
2766 			/*
2767 			 * Here we are in a failed transaction block (one of the commands
2768 			 * caused an abort) so we do nothing but remain in the abort
2769 			 * state.  Eventually we will get a ROLLBACK command which will
2770 			 * get us out of this state.  (It is up to other code to ensure
2771 			 * that no commands other than ROLLBACK will be processed in these
2772 			 * states.)
2773 			 */
2774 		case TBLOCK_ABORT:
2775 		case TBLOCK_SUBABORT:
2776 			break;
2777 
2778 			/* These cases are invalid. */
2779 		case TBLOCK_STARTED:
2780 		case TBLOCK_BEGIN:
2781 		case TBLOCK_PARALLEL_INPROGRESS:
2782 		case TBLOCK_SUBBEGIN:
2783 		case TBLOCK_END:
2784 		case TBLOCK_SUBRELEASE:
2785 		case TBLOCK_SUBCOMMIT:
2786 		case TBLOCK_ABORT_END:
2787 		case TBLOCK_SUBABORT_END:
2788 		case TBLOCK_ABORT_PENDING:
2789 		case TBLOCK_SUBABORT_PENDING:
2790 		case TBLOCK_SUBRESTART:
2791 		case TBLOCK_SUBABORT_RESTART:
2792 		case TBLOCK_PREPARE:
2793 			elog(ERROR, "StartTransactionCommand: unexpected state %s",
2794 				 BlockStateAsString(s->blockState));
2795 			break;
2796 	}
2797 
2798 	/*
2799 	 * We must switch to CurTransactionContext before returning. This is
2800 	 * already done if we called StartTransaction, otherwise not.
2801 	 */
2802 	Assert(CurTransactionContext != NULL);
2803 	MemoryContextSwitchTo(CurTransactionContext);
2804 }
2805 
2806 /*
2807  *	CommitTransactionCommand
2808  */
2809 void
CommitTransactionCommand(void)2810 CommitTransactionCommand(void)
2811 {
2812 	TransactionState s = CurrentTransactionState;
2813 
2814 	switch (s->blockState)
2815 	{
2816 			/*
2817 			 * These shouldn't happen.  TBLOCK_DEFAULT means the previous
2818 			 * StartTransactionCommand didn't set the STARTED state
2819 			 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
2820 			 * by EndParallelWorkerTransaction(), not this function.
2821 			 */
2822 		case TBLOCK_DEFAULT:
2823 		case TBLOCK_PARALLEL_INPROGRESS:
2824 			elog(FATAL, "CommitTransactionCommand: unexpected state %s",
2825 				 BlockStateAsString(s->blockState));
2826 			break;
2827 
2828 			/*
2829 			 * If we aren't in a transaction block, just do our usual
2830 			 * transaction commit, and return to the idle state.
2831 			 */
2832 		case TBLOCK_STARTED:
2833 			CommitTransaction();
2834 			s->blockState = TBLOCK_DEFAULT;
2835 			break;
2836 
2837 			/*
2838 			 * We are completing a "BEGIN TRANSACTION" command, so we change
2839 			 * to the "transaction block in progress" state and return.  (We
2840 			 * assume the BEGIN did nothing to the database, so we need no
2841 			 * CommandCounterIncrement.)
2842 			 */
2843 		case TBLOCK_BEGIN:
2844 			s->blockState = TBLOCK_INPROGRESS;
2845 			break;
2846 
2847 			/*
2848 			 * This is the case when we have finished executing a command
2849 			 * someplace within a transaction block.  We increment the command
2850 			 * counter and return.
2851 			 */
2852 		case TBLOCK_INPROGRESS:
2853 		case TBLOCK_SUBINPROGRESS:
2854 			CommandCounterIncrement();
2855 			break;
2856 
2857 			/*
2858 			 * We are completing a "COMMIT" command.  Do it and return to the
2859 			 * idle state.
2860 			 */
2861 		case TBLOCK_END:
2862 			CommitTransaction();
2863 			s->blockState = TBLOCK_DEFAULT;
2864 			break;
2865 
2866 			/*
2867 			 * Here we are in the middle of a transaction block but one of the
2868 			 * commands caused an abort so we do nothing but remain in the
2869 			 * abort state.  Eventually we will get a ROLLBACK command.
2870 			 */
2871 		case TBLOCK_ABORT:
2872 		case TBLOCK_SUBABORT:
2873 			break;
2874 
2875 			/*
2876 			 * Here we were in an aborted transaction block and we just got
2877 			 * the ROLLBACK command from the user, so clean up the
2878 			 * already-aborted transaction and return to the idle state.
2879 			 */
2880 		case TBLOCK_ABORT_END:
2881 			CleanupTransaction();
2882 			s->blockState = TBLOCK_DEFAULT;
2883 			break;
2884 
2885 			/*
2886 			 * Here we were in a perfectly good transaction block but the user
2887 			 * told us to ROLLBACK anyway.  We have to abort the transaction
2888 			 * and then clean up.
2889 			 */
2890 		case TBLOCK_ABORT_PENDING:
2891 			AbortTransaction();
2892 			CleanupTransaction();
2893 			s->blockState = TBLOCK_DEFAULT;
2894 			break;
2895 
2896 			/*
2897 			 * We are completing a "PREPARE TRANSACTION" command.  Do it and
2898 			 * return to the idle state.
2899 			 */
2900 		case TBLOCK_PREPARE:
2901 			PrepareTransaction();
2902 			s->blockState = TBLOCK_DEFAULT;
2903 			break;
2904 
2905 			/*
2906 			 * We were just issued a SAVEPOINT inside a transaction block.
2907 			 * Start a subtransaction.  (DefineSavepoint already did
2908 			 * PushTransaction, so as to have someplace to put the SUBBEGIN
2909 			 * state.)
2910 			 */
2911 		case TBLOCK_SUBBEGIN:
2912 			StartSubTransaction();
2913 			s->blockState = TBLOCK_SUBINPROGRESS;
2914 			break;
2915 
2916 			/*
2917 			 * We were issued a RELEASE command, so we end the current
2918 			 * subtransaction and return to the parent transaction. The parent
2919 			 * might be ended too, so repeat till we find an INPROGRESS
2920 			 * transaction or subtransaction.
2921 			 */
2922 		case TBLOCK_SUBRELEASE:
2923 			do
2924 			{
2925 				CommitSubTransaction();
2926 				s = CurrentTransactionState;	/* changed by pop */
2927 			} while (s->blockState == TBLOCK_SUBRELEASE);
2928 
2929 			Assert(s->blockState == TBLOCK_INPROGRESS ||
2930 				   s->blockState == TBLOCK_SUBINPROGRESS);
2931 			break;
2932 
2933 			/*
2934 			 * We were issued a COMMIT, so we end the current subtransaction
2935 			 * hierarchy and perform final commit. We do this by rolling up
2936 			 * any subtransactions into their parent, which leads to O(N^2)
2937 			 * operations with respect to resource owners - this isn't that
2938 			 * bad until we approach a thousands of savepoints but is
2939 			 * necessary for correctness should after triggers create new
2940 			 * resource owners.
2941 			 */
2942 		case TBLOCK_SUBCOMMIT:
2943 			do
2944 			{
2945 				CommitSubTransaction();
2946 				s = CurrentTransactionState;	/* changed by pop */
2947 			} while (s->blockState == TBLOCK_SUBCOMMIT);
2948 			/* If we had a COMMIT command, finish off the main xact too */
2949 			if (s->blockState == TBLOCK_END)
2950 			{
2951 				Assert(s->parent == NULL);
2952 				CommitTransaction();
2953 				s->blockState = TBLOCK_DEFAULT;
2954 			}
2955 			else if (s->blockState == TBLOCK_PREPARE)
2956 			{
2957 				Assert(s->parent == NULL);
2958 				PrepareTransaction();
2959 				s->blockState = TBLOCK_DEFAULT;
2960 			}
2961 			else
2962 				elog(ERROR, "CommitTransactionCommand: unexpected state %s",
2963 					 BlockStateAsString(s->blockState));
2964 			break;
2965 
2966 			/*
2967 			 * The current already-failed subtransaction is ending due to a
2968 			 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
2969 			 * examine the parent (which could be in any of several states).
2970 			 */
2971 		case TBLOCK_SUBABORT_END:
2972 			CleanupSubTransaction();
2973 			CommitTransactionCommand();
2974 			break;
2975 
2976 			/*
2977 			 * As above, but it's not dead yet, so abort first.
2978 			 */
2979 		case TBLOCK_SUBABORT_PENDING:
2980 			AbortSubTransaction();
2981 			CleanupSubTransaction();
2982 			CommitTransactionCommand();
2983 			break;
2984 
2985 			/*
2986 			 * The current subtransaction is the target of a ROLLBACK TO
2987 			 * command.  Abort and pop it, then start a new subtransaction
2988 			 * with the same name.
2989 			 */
2990 		case TBLOCK_SUBRESTART:
2991 			{
2992 				char	   *name;
2993 				int			savepointLevel;
2994 
2995 				/* save name and keep Cleanup from freeing it */
2996 				name = s->name;
2997 				s->name = NULL;
2998 				savepointLevel = s->savepointLevel;
2999 
3000 				AbortSubTransaction();
3001 				CleanupSubTransaction();
3002 
3003 				DefineSavepoint(NULL);
3004 				s = CurrentTransactionState;	/* changed by push */
3005 				s->name = name;
3006 				s->savepointLevel = savepointLevel;
3007 
3008 				/* This is the same as TBLOCK_SUBBEGIN case */
3009 				AssertState(s->blockState == TBLOCK_SUBBEGIN);
3010 				StartSubTransaction();
3011 				s->blockState = TBLOCK_SUBINPROGRESS;
3012 			}
3013 			break;
3014 
3015 			/*
3016 			 * Same as above, but the subtransaction had already failed, so we
3017 			 * don't need AbortSubTransaction.
3018 			 */
3019 		case TBLOCK_SUBABORT_RESTART:
3020 			{
3021 				char	   *name;
3022 				int			savepointLevel;
3023 
3024 				/* save name and keep Cleanup from freeing it */
3025 				name = s->name;
3026 				s->name = NULL;
3027 				savepointLevel = s->savepointLevel;
3028 
3029 				CleanupSubTransaction();
3030 
3031 				DefineSavepoint(NULL);
3032 				s = CurrentTransactionState;	/* changed by push */
3033 				s->name = name;
3034 				s->savepointLevel = savepointLevel;
3035 
3036 				/* This is the same as TBLOCK_SUBBEGIN case */
3037 				AssertState(s->blockState == TBLOCK_SUBBEGIN);
3038 				StartSubTransaction();
3039 				s->blockState = TBLOCK_SUBINPROGRESS;
3040 			}
3041 			break;
3042 	}
3043 }
3044 
3045 /*
3046  *	AbortCurrentTransaction
3047  */
3048 void
AbortCurrentTransaction(void)3049 AbortCurrentTransaction(void)
3050 {
3051 	TransactionState s = CurrentTransactionState;
3052 
3053 	switch (s->blockState)
3054 	{
3055 		case TBLOCK_DEFAULT:
3056 			if (s->state == TRANS_DEFAULT)
3057 			{
3058 				/* we are idle, so nothing to do */
3059 			}
3060 			else
3061 			{
3062 				/*
3063 				 * We can get here after an error during transaction start
3064 				 * (state will be TRANS_START).  Need to clean up the
3065 				 * incompletely started transaction.  First, adjust the
3066 				 * low-level state to suppress warning message from
3067 				 * AbortTransaction.
3068 				 */
3069 				if (s->state == TRANS_START)
3070 					s->state = TRANS_INPROGRESS;
3071 				AbortTransaction();
3072 				CleanupTransaction();
3073 			}
3074 			break;
3075 
3076 			/*
3077 			 * if we aren't in a transaction block, we just do the basic abort
3078 			 * & cleanup transaction.
3079 			 */
3080 		case TBLOCK_STARTED:
3081 			AbortTransaction();
3082 			CleanupTransaction();
3083 			s->blockState = TBLOCK_DEFAULT;
3084 			break;
3085 
3086 			/*
3087 			 * If we are in TBLOCK_BEGIN it means something screwed up right
3088 			 * after reading "BEGIN TRANSACTION".  We assume that the user
3089 			 * will interpret the error as meaning the BEGIN failed to get him
3090 			 * into a transaction block, so we should abort and return to idle
3091 			 * state.
3092 			 */
3093 		case TBLOCK_BEGIN:
3094 			AbortTransaction();
3095 			CleanupTransaction();
3096 			s->blockState = TBLOCK_DEFAULT;
3097 			break;
3098 
3099 			/*
3100 			 * We are somewhere in a transaction block and we've gotten a
3101 			 * failure, so we abort the transaction and set up the persistent
3102 			 * ABORT state.  We will stay in ABORT until we get a ROLLBACK.
3103 			 */
3104 		case TBLOCK_INPROGRESS:
3105 		case TBLOCK_PARALLEL_INPROGRESS:
3106 			AbortTransaction();
3107 			s->blockState = TBLOCK_ABORT;
3108 			/* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3109 			break;
3110 
3111 			/*
3112 			 * Here, we failed while trying to COMMIT.  Clean up the
3113 			 * transaction and return to idle state (we do not want to stay in
3114 			 * the transaction).
3115 			 */
3116 		case TBLOCK_END:
3117 			AbortTransaction();
3118 			CleanupTransaction();
3119 			s->blockState = TBLOCK_DEFAULT;
3120 			break;
3121 
3122 			/*
3123 			 * Here, we are already in an aborted transaction state and are
3124 			 * waiting for a ROLLBACK, but for some reason we failed again! So
3125 			 * we just remain in the abort state.
3126 			 */
3127 		case TBLOCK_ABORT:
3128 		case TBLOCK_SUBABORT:
3129 			break;
3130 
3131 			/*
3132 			 * We are in a failed transaction and we got the ROLLBACK command.
3133 			 * We have already aborted, we just need to cleanup and go to idle
3134 			 * state.
3135 			 */
3136 		case TBLOCK_ABORT_END:
3137 			CleanupTransaction();
3138 			s->blockState = TBLOCK_DEFAULT;
3139 			break;
3140 
3141 			/*
3142 			 * We are in a live transaction and we got a ROLLBACK command.
3143 			 * Abort, cleanup, go to idle state.
3144 			 */
3145 		case TBLOCK_ABORT_PENDING:
3146 			AbortTransaction();
3147 			CleanupTransaction();
3148 			s->blockState = TBLOCK_DEFAULT;
3149 			break;
3150 
3151 			/*
3152 			 * Here, we failed while trying to PREPARE.  Clean up the
3153 			 * transaction and return to idle state (we do not want to stay in
3154 			 * the transaction).
3155 			 */
3156 		case TBLOCK_PREPARE:
3157 			AbortTransaction();
3158 			CleanupTransaction();
3159 			s->blockState = TBLOCK_DEFAULT;
3160 			break;
3161 
3162 			/*
3163 			 * We got an error inside a subtransaction.  Abort just the
3164 			 * subtransaction, and go to the persistent SUBABORT state until
3165 			 * we get ROLLBACK.
3166 			 */
3167 		case TBLOCK_SUBINPROGRESS:
3168 			AbortSubTransaction();
3169 			s->blockState = TBLOCK_SUBABORT;
3170 			break;
3171 
3172 			/*
3173 			 * If we failed while trying to create a subtransaction, clean up
3174 			 * the broken subtransaction and abort the parent.  The same
3175 			 * applies if we get a failure while ending a subtransaction.
3176 			 */
3177 		case TBLOCK_SUBBEGIN:
3178 		case TBLOCK_SUBRELEASE:
3179 		case TBLOCK_SUBCOMMIT:
3180 		case TBLOCK_SUBABORT_PENDING:
3181 		case TBLOCK_SUBRESTART:
3182 			AbortSubTransaction();
3183 			CleanupSubTransaction();
3184 			AbortCurrentTransaction();
3185 			break;
3186 
3187 			/*
3188 			 * Same as above, except the Abort() was already done.
3189 			 */
3190 		case TBLOCK_SUBABORT_END:
3191 		case TBLOCK_SUBABORT_RESTART:
3192 			CleanupSubTransaction();
3193 			AbortCurrentTransaction();
3194 			break;
3195 	}
3196 }
3197 
3198 /*
3199  *	PreventTransactionChain
3200  *
3201  *	This routine is to be called by statements that must not run inside
3202  *	a transaction block, typically because they have non-rollback-able
3203  *	side effects or do internal commits.
3204  *
3205  *	If we have already started a transaction block, issue an error; also issue
3206  *	an error if we appear to be running inside a user-defined function (which
3207  *	could issue more commands and possibly cause a failure after the statement
3208  *	completes).  Subtransactions are verboten too.
3209  *
3210  *	isTopLevel: passed down from ProcessUtility to determine whether we are
3211  *	inside a function or multi-query querystring.  (We will always fail if
3212  *	this is false, but it's convenient to centralize the check here instead of
3213  *	making callers do it.)
3214  *	stmtType: statement type name, for error messages.
3215  */
3216 void
PreventTransactionChain(bool isTopLevel,const char * stmtType)3217 PreventTransactionChain(bool isTopLevel, const char *stmtType)
3218 {
3219 	/*
3220 	 * xact block already started?
3221 	 */
3222 	if (IsTransactionBlock())
3223 		ereport(ERROR,
3224 				(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3225 		/* translator: %s represents an SQL statement name */
3226 				 errmsg("%s cannot run inside a transaction block",
3227 						stmtType)));
3228 
3229 	/*
3230 	 * subtransaction?
3231 	 */
3232 	if (IsSubTransaction())
3233 		ereport(ERROR,
3234 				(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3235 		/* translator: %s represents an SQL statement name */
3236 				 errmsg("%s cannot run inside a subtransaction",
3237 						stmtType)));
3238 
3239 	/*
3240 	 * inside a function call?
3241 	 */
3242 	if (!isTopLevel)
3243 		ereport(ERROR,
3244 				(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3245 		/* translator: %s represents an SQL statement name */
3246 				 errmsg("%s cannot be executed from a function or multi-command string",
3247 						stmtType)));
3248 
3249 	/* If we got past IsTransactionBlock test, should be in default state */
3250 	if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
3251 		CurrentTransactionState->blockState != TBLOCK_STARTED)
3252 		elog(FATAL, "cannot prevent transaction chain");
3253 	/* all okay */
3254 }
3255 
3256 /*
3257  *	These two functions allow for warnings or errors if a command is
3258  *	executed outside of a transaction block.
3259  *
3260  *	While top-level transaction control commands (BEGIN/COMMIT/ABORT) and
3261  *	SET that have no effect issue warnings, all other no-effect commands
3262  *	generate errors.
3263  */
3264 void
WarnNoTransactionChain(bool isTopLevel,const char * stmtType)3265 WarnNoTransactionChain(bool isTopLevel, const char *stmtType)
3266 {
3267 	CheckTransactionChain(isTopLevel, false, stmtType);
3268 }
3269 
3270 void
RequireTransactionChain(bool isTopLevel,const char * stmtType)3271 RequireTransactionChain(bool isTopLevel, const char *stmtType)
3272 {
3273 	CheckTransactionChain(isTopLevel, true, stmtType);
3274 }
3275 
3276 /*
3277  *	RequireTransactionChain
3278  *
3279  *	This routine is to be called by statements that must run inside
3280  *	a transaction block, because they have no effects that persist past
3281  *	transaction end (and so calling them outside a transaction block
3282  *	is presumably an error).  DECLARE CURSOR is an example.
3283  *
3284  *	If we appear to be running inside a user-defined function, we do not
3285  *	issue anything, since the function could issue more commands that make
3286  *	use of the current statement's results.  Likewise subtransactions.
3287  *	Thus this is an inverse for PreventTransactionChain.
3288  *
3289  *	isTopLevel: passed down from ProcessUtility to determine whether we are
3290  *	inside a function.
3291  *	stmtType: statement type name, for warning or error messages.
3292  */
3293 static void
CheckTransactionChain(bool isTopLevel,bool throwError,const char * stmtType)3294 CheckTransactionChain(bool isTopLevel, bool throwError, const char *stmtType)
3295 {
3296 	/*
3297 	 * xact block already started?
3298 	 */
3299 	if (IsTransactionBlock())
3300 		return;
3301 
3302 	/*
3303 	 * subtransaction?
3304 	 */
3305 	if (IsSubTransaction())
3306 		return;
3307 
3308 	/*
3309 	 * inside a function call?
3310 	 */
3311 	if (!isTopLevel)
3312 		return;
3313 
3314 	ereport(throwError ? ERROR : WARNING,
3315 			(errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3316 	/* translator: %s represents an SQL statement name */
3317 			 errmsg("%s can only be used in transaction blocks",
3318 					stmtType)));
3319 	return;
3320 }
3321 
3322 /*
3323  *	IsInTransactionChain
3324  *
3325  *	This routine is for statements that need to behave differently inside
3326  *	a transaction block than when running as single commands.  ANALYZE is
3327  *	currently the only example.
3328  *
3329  *	isTopLevel: passed down from ProcessUtility to determine whether we are
3330  *	inside a function.
3331  */
3332 bool
IsInTransactionChain(bool isTopLevel)3333 IsInTransactionChain(bool isTopLevel)
3334 {
3335 	/*
3336 	 * Return true on same conditions that would make PreventTransactionChain
3337 	 * error out
3338 	 */
3339 	if (IsTransactionBlock())
3340 		return true;
3341 
3342 	if (IsSubTransaction())
3343 		return true;
3344 
3345 	if (!isTopLevel)
3346 		return true;
3347 
3348 	if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
3349 		CurrentTransactionState->blockState != TBLOCK_STARTED)
3350 		return true;
3351 
3352 	return false;
3353 }
3354 
3355 
3356 /*
3357  * Register or deregister callback functions for start- and end-of-xact
3358  * operations.
3359  *
3360  * These functions are intended for use by dynamically loaded modules.
3361  * For built-in modules we generally just hardwire the appropriate calls
3362  * (mainly because it's easier to control the order that way, where needed).
3363  *
3364  * At transaction end, the callback occurs post-commit or post-abort, so the
3365  * callback functions can only do noncritical cleanup.
3366  */
3367 void
RegisterXactCallback(XactCallback callback,void * arg)3368 RegisterXactCallback(XactCallback callback, void *arg)
3369 {
3370 	XactCallbackItem *item;
3371 
3372 	item = (XactCallbackItem *)
3373 		MemoryContextAlloc(TopMemoryContext, sizeof(XactCallbackItem));
3374 	item->callback = callback;
3375 	item->arg = arg;
3376 	item->next = Xact_callbacks;
3377 	Xact_callbacks = item;
3378 }
3379 
3380 void
UnregisterXactCallback(XactCallback callback,void * arg)3381 UnregisterXactCallback(XactCallback callback, void *arg)
3382 {
3383 	XactCallbackItem *item;
3384 	XactCallbackItem *prev;
3385 
3386 	prev = NULL;
3387 	for (item = Xact_callbacks; item; prev = item, item = item->next)
3388 	{
3389 		if (item->callback == callback && item->arg == arg)
3390 		{
3391 			if (prev)
3392 				prev->next = item->next;
3393 			else
3394 				Xact_callbacks = item->next;
3395 			pfree(item);
3396 			break;
3397 		}
3398 	}
3399 }
3400 
3401 static void
CallXactCallbacks(XactEvent event)3402 CallXactCallbacks(XactEvent event)
3403 {
3404 	XactCallbackItem *item;
3405 
3406 	for (item = Xact_callbacks; item; item = item->next)
3407 		(*item->callback) (event, item->arg);
3408 }
3409 
3410 
3411 /*
3412  * Register or deregister callback functions for start- and end-of-subxact
3413  * operations.
3414  *
3415  * Pretty much same as above, but for subtransaction events.
3416  *
3417  * At subtransaction end, the callback occurs post-subcommit or post-subabort,
3418  * so the callback functions can only do noncritical cleanup.  At
3419  * subtransaction start, the callback is called when the subtransaction has
3420  * finished initializing.
3421  */
3422 void
RegisterSubXactCallback(SubXactCallback callback,void * arg)3423 RegisterSubXactCallback(SubXactCallback callback, void *arg)
3424 {
3425 	SubXactCallbackItem *item;
3426 
3427 	item = (SubXactCallbackItem *)
3428 		MemoryContextAlloc(TopMemoryContext, sizeof(SubXactCallbackItem));
3429 	item->callback = callback;
3430 	item->arg = arg;
3431 	item->next = SubXact_callbacks;
3432 	SubXact_callbacks = item;
3433 }
3434 
3435 void
UnregisterSubXactCallback(SubXactCallback callback,void * arg)3436 UnregisterSubXactCallback(SubXactCallback callback, void *arg)
3437 {
3438 	SubXactCallbackItem *item;
3439 	SubXactCallbackItem *prev;
3440 
3441 	prev = NULL;
3442 	for (item = SubXact_callbacks; item; prev = item, item = item->next)
3443 	{
3444 		if (item->callback == callback && item->arg == arg)
3445 		{
3446 			if (prev)
3447 				prev->next = item->next;
3448 			else
3449 				SubXact_callbacks = item->next;
3450 			pfree(item);
3451 			break;
3452 		}
3453 	}
3454 }
3455 
3456 static void
CallSubXactCallbacks(SubXactEvent event,SubTransactionId mySubid,SubTransactionId parentSubid)3457 CallSubXactCallbacks(SubXactEvent event,
3458 					 SubTransactionId mySubid,
3459 					 SubTransactionId parentSubid)
3460 {
3461 	SubXactCallbackItem *item;
3462 
3463 	for (item = SubXact_callbacks; item; item = item->next)
3464 		(*item->callback) (event, mySubid, parentSubid, item->arg);
3465 }
3466 
3467 
3468 /* ----------------------------------------------------------------
3469  *					   transaction block support
3470  * ----------------------------------------------------------------
3471  */
3472 
3473 /*
3474  *	BeginTransactionBlock
3475  *		This executes a BEGIN command.
3476  */
3477 void
BeginTransactionBlock(void)3478 BeginTransactionBlock(void)
3479 {
3480 	TransactionState s = CurrentTransactionState;
3481 
3482 	switch (s->blockState)
3483 	{
3484 			/*
3485 			 * We are not inside a transaction block, so allow one to begin.
3486 			 */
3487 		case TBLOCK_STARTED:
3488 			s->blockState = TBLOCK_BEGIN;
3489 			break;
3490 
3491 			/*
3492 			 * Already a transaction block in progress.
3493 			 */
3494 		case TBLOCK_INPROGRESS:
3495 		case TBLOCK_PARALLEL_INPROGRESS:
3496 		case TBLOCK_SUBINPROGRESS:
3497 		case TBLOCK_ABORT:
3498 		case TBLOCK_SUBABORT:
3499 			ereport(WARNING,
3500 					(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3501 					 errmsg("there is already a transaction in progress")));
3502 			break;
3503 
3504 			/* These cases are invalid. */
3505 		case TBLOCK_DEFAULT:
3506 		case TBLOCK_BEGIN:
3507 		case TBLOCK_SUBBEGIN:
3508 		case TBLOCK_END:
3509 		case TBLOCK_SUBRELEASE:
3510 		case TBLOCK_SUBCOMMIT:
3511 		case TBLOCK_ABORT_END:
3512 		case TBLOCK_SUBABORT_END:
3513 		case TBLOCK_ABORT_PENDING:
3514 		case TBLOCK_SUBABORT_PENDING:
3515 		case TBLOCK_SUBRESTART:
3516 		case TBLOCK_SUBABORT_RESTART:
3517 		case TBLOCK_PREPARE:
3518 			elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3519 				 BlockStateAsString(s->blockState));
3520 			break;
3521 	}
3522 }
3523 
3524 /*
3525  *	PrepareTransactionBlock
3526  *		This executes a PREPARE command.
3527  *
3528  * Since PREPARE may actually do a ROLLBACK, the result indicates what
3529  * happened: TRUE for PREPARE, FALSE for ROLLBACK.
3530  *
3531  * Note that we don't actually do anything here except change blockState.
3532  * The real work will be done in the upcoming PrepareTransaction().
3533  * We do it this way because it's not convenient to change memory context,
3534  * resource owner, etc while executing inside a Portal.
3535  */
3536 bool
PrepareTransactionBlock(char * gid)3537 PrepareTransactionBlock(char *gid)
3538 {
3539 	TransactionState s;
3540 	bool		result;
3541 
3542 	/* Set up to commit the current transaction */
3543 	result = EndTransactionBlock();
3544 
3545 	/* If successful, change outer tblock state to PREPARE */
3546 	if (result)
3547 	{
3548 		s = CurrentTransactionState;
3549 
3550 		while (s->parent != NULL)
3551 			s = s->parent;
3552 
3553 		if (s->blockState == TBLOCK_END)
3554 		{
3555 			/* Save GID where PrepareTransaction can find it again */
3556 			prepareGID = MemoryContextStrdup(TopTransactionContext, gid);
3557 
3558 			s->blockState = TBLOCK_PREPARE;
3559 		}
3560 		else
3561 		{
3562 			/*
3563 			 * ignore case where we are not in a transaction;
3564 			 * EndTransactionBlock already issued a warning.
3565 			 */
3566 			Assert(s->blockState == TBLOCK_STARTED);
3567 			/* Don't send back a PREPARE result tag... */
3568 			result = false;
3569 		}
3570 	}
3571 
3572 	return result;
3573 }
3574 
3575 /*
3576  *	EndTransactionBlock
3577  *		This executes a COMMIT command.
3578  *
3579  * Since COMMIT may actually do a ROLLBACK, the result indicates what
3580  * happened: TRUE for COMMIT, FALSE for ROLLBACK.
3581  *
3582  * Note that we don't actually do anything here except change blockState.
3583  * The real work will be done in the upcoming CommitTransactionCommand().
3584  * We do it this way because it's not convenient to change memory context,
3585  * resource owner, etc while executing inside a Portal.
3586  */
3587 bool
EndTransactionBlock(void)3588 EndTransactionBlock(void)
3589 {
3590 	TransactionState s = CurrentTransactionState;
3591 	bool		result = false;
3592 
3593 	switch (s->blockState)
3594 	{
3595 			/*
3596 			 * We are in a transaction block, so tell CommitTransactionCommand
3597 			 * to COMMIT.
3598 			 */
3599 		case TBLOCK_INPROGRESS:
3600 			s->blockState = TBLOCK_END;
3601 			result = true;
3602 			break;
3603 
3604 			/*
3605 			 * We are in a failed transaction block.  Tell
3606 			 * CommitTransactionCommand it's time to exit the block.
3607 			 */
3608 		case TBLOCK_ABORT:
3609 			s->blockState = TBLOCK_ABORT_END;
3610 			break;
3611 
3612 			/*
3613 			 * We are in a live subtransaction block.  Set up to subcommit all
3614 			 * open subtransactions and then commit the main transaction.
3615 			 */
3616 		case TBLOCK_SUBINPROGRESS:
3617 			while (s->parent != NULL)
3618 			{
3619 				if (s->blockState == TBLOCK_SUBINPROGRESS)
3620 					s->blockState = TBLOCK_SUBCOMMIT;
3621 				else
3622 					elog(FATAL, "EndTransactionBlock: unexpected state %s",
3623 						 BlockStateAsString(s->blockState));
3624 				s = s->parent;
3625 			}
3626 			if (s->blockState == TBLOCK_INPROGRESS)
3627 				s->blockState = TBLOCK_END;
3628 			else
3629 				elog(FATAL, "EndTransactionBlock: unexpected state %s",
3630 					 BlockStateAsString(s->blockState));
3631 			result = true;
3632 			break;
3633 
3634 			/*
3635 			 * Here we are inside an aborted subtransaction.  Treat the COMMIT
3636 			 * as ROLLBACK: set up to abort everything and exit the main
3637 			 * transaction.
3638 			 */
3639 		case TBLOCK_SUBABORT:
3640 			while (s->parent != NULL)
3641 			{
3642 				if (s->blockState == TBLOCK_SUBINPROGRESS)
3643 					s->blockState = TBLOCK_SUBABORT_PENDING;
3644 				else if (s->blockState == TBLOCK_SUBABORT)
3645 					s->blockState = TBLOCK_SUBABORT_END;
3646 				else
3647 					elog(FATAL, "EndTransactionBlock: unexpected state %s",
3648 						 BlockStateAsString(s->blockState));
3649 				s = s->parent;
3650 			}
3651 			if (s->blockState == TBLOCK_INPROGRESS)
3652 				s->blockState = TBLOCK_ABORT_PENDING;
3653 			else if (s->blockState == TBLOCK_ABORT)
3654 				s->blockState = TBLOCK_ABORT_END;
3655 			else
3656 				elog(FATAL, "EndTransactionBlock: unexpected state %s",
3657 					 BlockStateAsString(s->blockState));
3658 			break;
3659 
3660 			/*
3661 			 * The user issued COMMIT when not inside a transaction.  Issue a
3662 			 * WARNING, staying in TBLOCK_STARTED state.  The upcoming call to
3663 			 * CommitTransactionCommand() will then close the transaction and
3664 			 * put us back into the default state.
3665 			 */
3666 		case TBLOCK_STARTED:
3667 			ereport(WARNING,
3668 					(errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3669 					 errmsg("there is no transaction in progress")));
3670 			result = true;
3671 			break;
3672 
3673 			/*
3674 			 * The user issued a COMMIT that somehow ran inside a parallel
3675 			 * worker.  We can't cope with that.
3676 			 */
3677 		case TBLOCK_PARALLEL_INPROGRESS:
3678 			ereport(FATAL,
3679 					(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3680 					 errmsg("cannot commit during a parallel operation")));
3681 			break;
3682 
3683 			/* These cases are invalid. */
3684 		case TBLOCK_DEFAULT:
3685 		case TBLOCK_BEGIN:
3686 		case TBLOCK_SUBBEGIN:
3687 		case TBLOCK_END:
3688 		case TBLOCK_SUBRELEASE:
3689 		case TBLOCK_SUBCOMMIT:
3690 		case TBLOCK_ABORT_END:
3691 		case TBLOCK_SUBABORT_END:
3692 		case TBLOCK_ABORT_PENDING:
3693 		case TBLOCK_SUBABORT_PENDING:
3694 		case TBLOCK_SUBRESTART:
3695 		case TBLOCK_SUBABORT_RESTART:
3696 		case TBLOCK_PREPARE:
3697 			elog(FATAL, "EndTransactionBlock: unexpected state %s",
3698 				 BlockStateAsString(s->blockState));
3699 			break;
3700 	}
3701 
3702 	return result;
3703 }
3704 
3705 /*
3706  *	UserAbortTransactionBlock
3707  *		This executes a ROLLBACK command.
3708  *
3709  * As above, we don't actually do anything here except change blockState.
3710  */
3711 void
UserAbortTransactionBlock(void)3712 UserAbortTransactionBlock(void)
3713 {
3714 	TransactionState s = CurrentTransactionState;
3715 
3716 	switch (s->blockState)
3717 	{
3718 			/*
3719 			 * We are inside a transaction block and we got a ROLLBACK command
3720 			 * from the user, so tell CommitTransactionCommand to abort and
3721 			 * exit the transaction block.
3722 			 */
3723 		case TBLOCK_INPROGRESS:
3724 			s->blockState = TBLOCK_ABORT_PENDING;
3725 			break;
3726 
3727 			/*
3728 			 * We are inside a failed transaction block and we got a ROLLBACK
3729 			 * command from the user.  Abort processing is already done, so
3730 			 * CommitTransactionCommand just has to cleanup and go back to
3731 			 * idle state.
3732 			 */
3733 		case TBLOCK_ABORT:
3734 			s->blockState = TBLOCK_ABORT_END;
3735 			break;
3736 
3737 			/*
3738 			 * We are inside a subtransaction.  Mark everything up to top
3739 			 * level as exitable.
3740 			 */
3741 		case TBLOCK_SUBINPROGRESS:
3742 		case TBLOCK_SUBABORT:
3743 			while (s->parent != NULL)
3744 			{
3745 				if (s->blockState == TBLOCK_SUBINPROGRESS)
3746 					s->blockState = TBLOCK_SUBABORT_PENDING;
3747 				else if (s->blockState == TBLOCK_SUBABORT)
3748 					s->blockState = TBLOCK_SUBABORT_END;
3749 				else
3750 					elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3751 						 BlockStateAsString(s->blockState));
3752 				s = s->parent;
3753 			}
3754 			if (s->blockState == TBLOCK_INPROGRESS)
3755 				s->blockState = TBLOCK_ABORT_PENDING;
3756 			else if (s->blockState == TBLOCK_ABORT)
3757 				s->blockState = TBLOCK_ABORT_END;
3758 			else
3759 				elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3760 					 BlockStateAsString(s->blockState));
3761 			break;
3762 
3763 			/*
3764 			 * The user issued ABORT when not inside a transaction. Issue a
3765 			 * WARNING and go to abort state.  The upcoming call to
3766 			 * CommitTransactionCommand() will then put us back into the
3767 			 * default state.
3768 			 */
3769 		case TBLOCK_STARTED:
3770 			ereport(WARNING,
3771 					(errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3772 					 errmsg("there is no transaction in progress")));
3773 			s->blockState = TBLOCK_ABORT_PENDING;
3774 			break;
3775 
3776 			/*
3777 			 * The user issued an ABORT that somehow ran inside a parallel
3778 			 * worker.  We can't cope with that.
3779 			 */
3780 		case TBLOCK_PARALLEL_INPROGRESS:
3781 			ereport(FATAL,
3782 					(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3783 					 errmsg("cannot abort during a parallel operation")));
3784 			break;
3785 
3786 			/* These cases are invalid. */
3787 		case TBLOCK_DEFAULT:
3788 		case TBLOCK_BEGIN:
3789 		case TBLOCK_SUBBEGIN:
3790 		case TBLOCK_END:
3791 		case TBLOCK_SUBRELEASE:
3792 		case TBLOCK_SUBCOMMIT:
3793 		case TBLOCK_ABORT_END:
3794 		case TBLOCK_SUBABORT_END:
3795 		case TBLOCK_ABORT_PENDING:
3796 		case TBLOCK_SUBABORT_PENDING:
3797 		case TBLOCK_SUBRESTART:
3798 		case TBLOCK_SUBABORT_RESTART:
3799 		case TBLOCK_PREPARE:
3800 			elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
3801 				 BlockStateAsString(s->blockState));
3802 			break;
3803 	}
3804 }
3805 
3806 /*
3807  * DefineSavepoint
3808  *		This executes a SAVEPOINT command.
3809  */
3810 void
DefineSavepoint(char * name)3811 DefineSavepoint(char *name)
3812 {
3813 	TransactionState s = CurrentTransactionState;
3814 
3815 	/*
3816 	 * Workers synchronize transaction state at the beginning of each parallel
3817 	 * operation, so we can't account for new subtransactions after that
3818 	 * point.  (Note that this check will certainly error out if s->blockState
3819 	 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
3820 	 * below.)
3821 	 */
3822 	if (IsInParallelMode())
3823 		ereport(ERROR,
3824 				(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3825 				 errmsg("cannot define savepoints during a parallel operation")));
3826 
3827 	switch (s->blockState)
3828 	{
3829 		case TBLOCK_INPROGRESS:
3830 		case TBLOCK_SUBINPROGRESS:
3831 			/* Normal subtransaction start */
3832 			PushTransaction();
3833 			s = CurrentTransactionState;	/* changed by push */
3834 
3835 			/*
3836 			 * Savepoint names, like the TransactionState block itself, live
3837 			 * in TopTransactionContext.
3838 			 */
3839 			if (name)
3840 				s->name = MemoryContextStrdup(TopTransactionContext, name);
3841 			break;
3842 
3843 			/* These cases are invalid. */
3844 		case TBLOCK_DEFAULT:
3845 		case TBLOCK_STARTED:
3846 		case TBLOCK_BEGIN:
3847 		case TBLOCK_PARALLEL_INPROGRESS:
3848 		case TBLOCK_SUBBEGIN:
3849 		case TBLOCK_END:
3850 		case TBLOCK_SUBRELEASE:
3851 		case TBLOCK_SUBCOMMIT:
3852 		case TBLOCK_ABORT:
3853 		case TBLOCK_SUBABORT:
3854 		case TBLOCK_ABORT_END:
3855 		case TBLOCK_SUBABORT_END:
3856 		case TBLOCK_ABORT_PENDING:
3857 		case TBLOCK_SUBABORT_PENDING:
3858 		case TBLOCK_SUBRESTART:
3859 		case TBLOCK_SUBABORT_RESTART:
3860 		case TBLOCK_PREPARE:
3861 			elog(FATAL, "DefineSavepoint: unexpected state %s",
3862 				 BlockStateAsString(s->blockState));
3863 			break;
3864 	}
3865 }
3866 
3867 /*
3868  * ReleaseSavepoint
3869  *		This executes a RELEASE command.
3870  *
3871  * As above, we don't actually do anything here except change blockState.
3872  */
3873 void
ReleaseSavepoint(List * options)3874 ReleaseSavepoint(List *options)
3875 {
3876 	TransactionState s = CurrentTransactionState;
3877 	TransactionState target,
3878 				xact;
3879 	ListCell   *cell;
3880 	char	   *name = NULL;
3881 
3882 	/*
3883 	 * Workers synchronize transaction state at the beginning of each parallel
3884 	 * operation, so we can't account for transaction state change after that
3885 	 * point.  (Note that this check will certainly error out if s->blockState
3886 	 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
3887 	 * below.)
3888 	 */
3889 	if (IsInParallelMode())
3890 		ereport(ERROR,
3891 				(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3892 				 errmsg("cannot release savepoints during a parallel operation")));
3893 
3894 	switch (s->blockState)
3895 	{
3896 			/*
3897 			 * We can't rollback to a savepoint if there is no savepoint
3898 			 * defined.
3899 			 */
3900 		case TBLOCK_INPROGRESS:
3901 			ereport(ERROR,
3902 					(errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3903 					 errmsg("no such savepoint")));
3904 			break;
3905 
3906 			/*
3907 			 * We are in a non-aborted subtransaction.  This is the only valid
3908 			 * case.
3909 			 */
3910 		case TBLOCK_SUBINPROGRESS:
3911 			break;
3912 
3913 			/* These cases are invalid. */
3914 		case TBLOCK_DEFAULT:
3915 		case TBLOCK_STARTED:
3916 		case TBLOCK_BEGIN:
3917 		case TBLOCK_PARALLEL_INPROGRESS:
3918 		case TBLOCK_SUBBEGIN:
3919 		case TBLOCK_END:
3920 		case TBLOCK_SUBRELEASE:
3921 		case TBLOCK_SUBCOMMIT:
3922 		case TBLOCK_ABORT:
3923 		case TBLOCK_SUBABORT:
3924 		case TBLOCK_ABORT_END:
3925 		case TBLOCK_SUBABORT_END:
3926 		case TBLOCK_ABORT_PENDING:
3927 		case TBLOCK_SUBABORT_PENDING:
3928 		case TBLOCK_SUBRESTART:
3929 		case TBLOCK_SUBABORT_RESTART:
3930 		case TBLOCK_PREPARE:
3931 			elog(FATAL, "ReleaseSavepoint: unexpected state %s",
3932 				 BlockStateAsString(s->blockState));
3933 			break;
3934 	}
3935 
3936 	foreach(cell, options)
3937 	{
3938 		DefElem    *elem = lfirst(cell);
3939 
3940 		if (strcmp(elem->defname, "savepoint_name") == 0)
3941 			name = strVal(elem->arg);
3942 	}
3943 
3944 	Assert(PointerIsValid(name));
3945 
3946 	for (target = s; PointerIsValid(target); target = target->parent)
3947 	{
3948 		if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
3949 			break;
3950 	}
3951 
3952 	if (!PointerIsValid(target))
3953 		ereport(ERROR,
3954 				(errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3955 				 errmsg("no such savepoint")));
3956 
3957 	/* disallow crossing savepoint level boundaries */
3958 	if (target->savepointLevel != s->savepointLevel)
3959 		ereport(ERROR,
3960 				(errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
3961 				 errmsg("no such savepoint")));
3962 
3963 	/*
3964 	 * Mark "commit pending" all subtransactions up to the target
3965 	 * subtransaction.  The actual commits will happen when control gets to
3966 	 * CommitTransactionCommand.
3967 	 */
3968 	xact = CurrentTransactionState;
3969 	for (;;)
3970 	{
3971 		Assert(xact->blockState == TBLOCK_SUBINPROGRESS);
3972 		xact->blockState = TBLOCK_SUBRELEASE;
3973 		if (xact == target)
3974 			break;
3975 		xact = xact->parent;
3976 		Assert(PointerIsValid(xact));
3977 	}
3978 }
3979 
3980 /*
3981  * RollbackToSavepoint
3982  *		This executes a ROLLBACK TO <savepoint> command.
3983  *
3984  * As above, we don't actually do anything here except change blockState.
3985  */
3986 void
RollbackToSavepoint(List * options)3987 RollbackToSavepoint(List *options)
3988 {
3989 	TransactionState s = CurrentTransactionState;
3990 	TransactionState target,
3991 				xact;
3992 	ListCell   *cell;
3993 	char	   *name = NULL;
3994 
3995 	/*
3996 	 * Workers synchronize transaction state at the beginning of each parallel
3997 	 * operation, so we can't account for transaction state change after that
3998 	 * point.  (Note that this check will certainly error out if s->blockState
3999 	 * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4000 	 * below.)
4001 	 */
4002 	if (IsInParallelMode())
4003 		ereport(ERROR,
4004 				(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4005 				 errmsg("cannot rollback to savepoints during a parallel operation")));
4006 
4007 	switch (s->blockState)
4008 	{
4009 			/*
4010 			 * We can't rollback to a savepoint if there is no savepoint
4011 			 * defined.
4012 			 */
4013 		case TBLOCK_INPROGRESS:
4014 		case TBLOCK_ABORT:
4015 			ereport(ERROR,
4016 					(errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4017 					 errmsg("no such savepoint")));
4018 			break;
4019 
4020 			/*
4021 			 * There is at least one savepoint, so proceed.
4022 			 */
4023 		case TBLOCK_SUBINPROGRESS:
4024 		case TBLOCK_SUBABORT:
4025 			break;
4026 
4027 			/* These cases are invalid. */
4028 		case TBLOCK_DEFAULT:
4029 		case TBLOCK_STARTED:
4030 		case TBLOCK_BEGIN:
4031 		case TBLOCK_PARALLEL_INPROGRESS:
4032 		case TBLOCK_SUBBEGIN:
4033 		case TBLOCK_END:
4034 		case TBLOCK_SUBRELEASE:
4035 		case TBLOCK_SUBCOMMIT:
4036 		case TBLOCK_ABORT_END:
4037 		case TBLOCK_SUBABORT_END:
4038 		case TBLOCK_ABORT_PENDING:
4039 		case TBLOCK_SUBABORT_PENDING:
4040 		case TBLOCK_SUBRESTART:
4041 		case TBLOCK_SUBABORT_RESTART:
4042 		case TBLOCK_PREPARE:
4043 			elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4044 				 BlockStateAsString(s->blockState));
4045 			break;
4046 	}
4047 
4048 	foreach(cell, options)
4049 	{
4050 		DefElem    *elem = lfirst(cell);
4051 
4052 		if (strcmp(elem->defname, "savepoint_name") == 0)
4053 			name = strVal(elem->arg);
4054 	}
4055 
4056 	Assert(PointerIsValid(name));
4057 
4058 	for (target = s; PointerIsValid(target); target = target->parent)
4059 	{
4060 		if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4061 			break;
4062 	}
4063 
4064 	if (!PointerIsValid(target))
4065 		ereport(ERROR,
4066 				(errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4067 				 errmsg("no such savepoint")));
4068 
4069 	/* disallow crossing savepoint level boundaries */
4070 	if (target->savepointLevel != s->savepointLevel)
4071 		ereport(ERROR,
4072 				(errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4073 				 errmsg("no such savepoint")));
4074 
4075 	/*
4076 	 * Mark "abort pending" all subtransactions up to the target
4077 	 * subtransaction.  The actual aborts will happen when control gets to
4078 	 * CommitTransactionCommand.
4079 	 */
4080 	xact = CurrentTransactionState;
4081 	for (;;)
4082 	{
4083 		if (xact == target)
4084 			break;
4085 		if (xact->blockState == TBLOCK_SUBINPROGRESS)
4086 			xact->blockState = TBLOCK_SUBABORT_PENDING;
4087 		else if (xact->blockState == TBLOCK_SUBABORT)
4088 			xact->blockState = TBLOCK_SUBABORT_END;
4089 		else
4090 			elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4091 				 BlockStateAsString(xact->blockState));
4092 		xact = xact->parent;
4093 		Assert(PointerIsValid(xact));
4094 	}
4095 
4096 	/* And mark the target as "restart pending" */
4097 	if (xact->blockState == TBLOCK_SUBINPROGRESS)
4098 		xact->blockState = TBLOCK_SUBRESTART;
4099 	else if (xact->blockState == TBLOCK_SUBABORT)
4100 		xact->blockState = TBLOCK_SUBABORT_RESTART;
4101 	else
4102 		elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4103 			 BlockStateAsString(xact->blockState));
4104 }
4105 
4106 /*
4107  * BeginInternalSubTransaction
4108  *		This is the same as DefineSavepoint except it allows TBLOCK_STARTED,
4109  *		TBLOCK_END, and TBLOCK_PREPARE states, and therefore it can safely be
4110  *		used in functions that might be called when not inside a BEGIN block
4111  *		or when running deferred triggers at COMMIT/PREPARE time.  Also, it
4112  *		automatically does CommitTransactionCommand/StartTransactionCommand
4113  *		instead of expecting the caller to do it.
4114  */
4115 void
BeginInternalSubTransaction(char * name)4116 BeginInternalSubTransaction(char *name)
4117 {
4118 	TransactionState s = CurrentTransactionState;
4119 
4120 	/*
4121 	 * Workers synchronize transaction state at the beginning of each parallel
4122 	 * operation, so we can't account for new subtransactions after that
4123 	 * point. We might be able to make an exception for the type of
4124 	 * subtransaction established by this function, which is typically used in
4125 	 * contexts where we're going to release or roll back the subtransaction
4126 	 * before proceeding further, so that no enduring change to the
4127 	 * transaction state occurs. For now, however, we prohibit this case along
4128 	 * with all the others.
4129 	 */
4130 	if (IsInParallelMode())
4131 		ereport(ERROR,
4132 				(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4133 				 errmsg("cannot start subtransactions during a parallel operation")));
4134 
4135 	switch (s->blockState)
4136 	{
4137 		case TBLOCK_STARTED:
4138 		case TBLOCK_INPROGRESS:
4139 		case TBLOCK_END:
4140 		case TBLOCK_PREPARE:
4141 		case TBLOCK_SUBINPROGRESS:
4142 			/* Normal subtransaction start */
4143 			PushTransaction();
4144 			s = CurrentTransactionState;	/* changed by push */
4145 
4146 			/*
4147 			 * Savepoint names, like the TransactionState block itself, live
4148 			 * in TopTransactionContext.
4149 			 */
4150 			if (name)
4151 				s->name = MemoryContextStrdup(TopTransactionContext, name);
4152 			break;
4153 
4154 			/* These cases are invalid. */
4155 		case TBLOCK_DEFAULT:
4156 		case TBLOCK_BEGIN:
4157 		case TBLOCK_PARALLEL_INPROGRESS:
4158 		case TBLOCK_SUBBEGIN:
4159 		case TBLOCK_SUBRELEASE:
4160 		case TBLOCK_SUBCOMMIT:
4161 		case TBLOCK_ABORT:
4162 		case TBLOCK_SUBABORT:
4163 		case TBLOCK_ABORT_END:
4164 		case TBLOCK_SUBABORT_END:
4165 		case TBLOCK_ABORT_PENDING:
4166 		case TBLOCK_SUBABORT_PENDING:
4167 		case TBLOCK_SUBRESTART:
4168 		case TBLOCK_SUBABORT_RESTART:
4169 			elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4170 				 BlockStateAsString(s->blockState));
4171 			break;
4172 	}
4173 
4174 	CommitTransactionCommand();
4175 	StartTransactionCommand();
4176 }
4177 
4178 /*
4179  * ReleaseCurrentSubTransaction
4180  *
4181  * RELEASE (ie, commit) the innermost subtransaction, regardless of its
4182  * savepoint name (if any).
4183  * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4184  */
4185 void
ReleaseCurrentSubTransaction(void)4186 ReleaseCurrentSubTransaction(void)
4187 {
4188 	TransactionState s = CurrentTransactionState;
4189 
4190 	/*
4191 	 * Workers synchronize transaction state at the beginning of each parallel
4192 	 * operation, so we can't account for commit of subtransactions after that
4193 	 * point.  This should not happen anyway.  Code calling this would
4194 	 * typically have called BeginInternalSubTransaction() first, failing
4195 	 * there.
4196 	 */
4197 	if (IsInParallelMode())
4198 		ereport(ERROR,
4199 				(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4200 				 errmsg("cannot commit subtransactions during a parallel operation")));
4201 
4202 	if (s->blockState != TBLOCK_SUBINPROGRESS)
4203 		elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4204 			 BlockStateAsString(s->blockState));
4205 	Assert(s->state == TRANS_INPROGRESS);
4206 	MemoryContextSwitchTo(CurTransactionContext);
4207 	CommitSubTransaction();
4208 	s = CurrentTransactionState;	/* changed by pop */
4209 	Assert(s->state == TRANS_INPROGRESS);
4210 }
4211 
4212 /*
4213  * RollbackAndReleaseCurrentSubTransaction
4214  *
4215  * ROLLBACK and RELEASE (ie, abort) the innermost subtransaction, regardless
4216  * of its savepoint name (if any).
4217  * NB: do NOT use CommitTransactionCommand/StartTransactionCommand with this.
4218  */
4219 void
RollbackAndReleaseCurrentSubTransaction(void)4220 RollbackAndReleaseCurrentSubTransaction(void)
4221 {
4222 	TransactionState s = CurrentTransactionState;
4223 
4224 	/*
4225 	 * Unlike ReleaseCurrentSubTransaction(), this is nominally permitted
4226 	 * during parallel operations.  That's because we may be in the master,
4227 	 * recovering from an error thrown while we were in parallel mode.  We
4228 	 * won't reach here in a worker, because BeginInternalSubTransaction()
4229 	 * will have failed.
4230 	 */
4231 
4232 	switch (s->blockState)
4233 	{
4234 			/* Must be in a subtransaction */
4235 		case TBLOCK_SUBINPROGRESS:
4236 		case TBLOCK_SUBABORT:
4237 			break;
4238 
4239 			/* These cases are invalid. */
4240 		case TBLOCK_DEFAULT:
4241 		case TBLOCK_STARTED:
4242 		case TBLOCK_BEGIN:
4243 		case TBLOCK_PARALLEL_INPROGRESS:
4244 		case TBLOCK_SUBBEGIN:
4245 		case TBLOCK_INPROGRESS:
4246 		case TBLOCK_END:
4247 		case TBLOCK_SUBRELEASE:
4248 		case TBLOCK_SUBCOMMIT:
4249 		case TBLOCK_ABORT:
4250 		case TBLOCK_ABORT_END:
4251 		case TBLOCK_SUBABORT_END:
4252 		case TBLOCK_ABORT_PENDING:
4253 		case TBLOCK_SUBABORT_PENDING:
4254 		case TBLOCK_SUBRESTART:
4255 		case TBLOCK_SUBABORT_RESTART:
4256 		case TBLOCK_PREPARE:
4257 			elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4258 				 BlockStateAsString(s->blockState));
4259 			break;
4260 	}
4261 
4262 	/*
4263 	 * Abort the current subtransaction, if needed.
4264 	 */
4265 	if (s->blockState == TBLOCK_SUBINPROGRESS)
4266 		AbortSubTransaction();
4267 
4268 	/* And clean it up, too */
4269 	CleanupSubTransaction();
4270 
4271 	s = CurrentTransactionState;	/* changed by pop */
4272 	AssertState(s->blockState == TBLOCK_SUBINPROGRESS ||
4273 				s->blockState == TBLOCK_INPROGRESS ||
4274 				s->blockState == TBLOCK_STARTED);
4275 }
4276 
4277 /*
4278  *	AbortOutOfAnyTransaction
4279  *
4280  *	This routine is provided for error recovery purposes.  It aborts any
4281  *	active transaction or transaction block, leaving the system in a known
4282  *	idle state.
4283  */
4284 void
AbortOutOfAnyTransaction(void)4285 AbortOutOfAnyTransaction(void)
4286 {
4287 	TransactionState s = CurrentTransactionState;
4288 
4289 	/* Ensure we're not running in a doomed memory context */
4290 	AtAbort_Memory();
4291 
4292 	/*
4293 	 * Get out of any transaction or nested transaction
4294 	 */
4295 	do
4296 	{
4297 		switch (s->blockState)
4298 		{
4299 			case TBLOCK_DEFAULT:
4300 				if (s->state == TRANS_DEFAULT)
4301 				{
4302 					/* Not in a transaction, do nothing */
4303 				}
4304 				else
4305 				{
4306 					/*
4307 					 * We can get here after an error during transaction start
4308 					 * (state will be TRANS_START).  Need to clean up the
4309 					 * incompletely started transaction.  First, adjust the
4310 					 * low-level state to suppress warning message from
4311 					 * AbortTransaction.
4312 					 */
4313 					if (s->state == TRANS_START)
4314 						s->state = TRANS_INPROGRESS;
4315 					AbortTransaction();
4316 					CleanupTransaction();
4317 				}
4318 				break;
4319 			case TBLOCK_STARTED:
4320 			case TBLOCK_BEGIN:
4321 			case TBLOCK_INPROGRESS:
4322 			case TBLOCK_PARALLEL_INPROGRESS:
4323 			case TBLOCK_END:
4324 			case TBLOCK_ABORT_PENDING:
4325 			case TBLOCK_PREPARE:
4326 				/* In a transaction, so clean up */
4327 				AbortTransaction();
4328 				CleanupTransaction();
4329 				s->blockState = TBLOCK_DEFAULT;
4330 				break;
4331 			case TBLOCK_ABORT:
4332 			case TBLOCK_ABORT_END:
4333 
4334 				/*
4335 				 * AbortTransaction is already done, still need Cleanup.
4336 				 * However, if we failed partway through running ROLLBACK,
4337 				 * there will be an active portal running that command, which
4338 				 * we need to shut down before doing CleanupTransaction.
4339 				 */
4340 				AtAbort_Portals();
4341 				CleanupTransaction();
4342 				s->blockState = TBLOCK_DEFAULT;
4343 				break;
4344 
4345 				/*
4346 				 * In a subtransaction, so clean it up and abort parent too
4347 				 */
4348 			case TBLOCK_SUBBEGIN:
4349 			case TBLOCK_SUBINPROGRESS:
4350 			case TBLOCK_SUBRELEASE:
4351 			case TBLOCK_SUBCOMMIT:
4352 			case TBLOCK_SUBABORT_PENDING:
4353 			case TBLOCK_SUBRESTART:
4354 				AbortSubTransaction();
4355 				CleanupSubTransaction();
4356 				s = CurrentTransactionState;	/* changed by pop */
4357 				break;
4358 
4359 			case TBLOCK_SUBABORT:
4360 			case TBLOCK_SUBABORT_END:
4361 			case TBLOCK_SUBABORT_RESTART:
4362 				/* As above, but AbortSubTransaction already done */
4363 				if (s->curTransactionOwner)
4364 				{
4365 					/* As in TBLOCK_ABORT, might have a live portal to zap */
4366 					AtSubAbort_Portals(s->subTransactionId,
4367 									   s->parent->subTransactionId,
4368 									   s->curTransactionOwner,
4369 									   s->parent->curTransactionOwner);
4370 				}
4371 				CleanupSubTransaction();
4372 				s = CurrentTransactionState;	/* changed by pop */
4373 				break;
4374 		}
4375 	} while (s->blockState != TBLOCK_DEFAULT);
4376 
4377 	/* Should be out of all subxacts now */
4378 	Assert(s->parent == NULL);
4379 
4380 	/* If we didn't actually have anything to do, revert to TopMemoryContext */
4381 	AtCleanup_Memory();
4382 }
4383 
4384 /*
4385  * IsTransactionBlock --- are we within a transaction block?
4386  */
4387 bool
IsTransactionBlock(void)4388 IsTransactionBlock(void)
4389 {
4390 	TransactionState s = CurrentTransactionState;
4391 
4392 	if (s->blockState == TBLOCK_DEFAULT || s->blockState == TBLOCK_STARTED)
4393 		return false;
4394 
4395 	return true;
4396 }
4397 
4398 /*
4399  * IsTransactionOrTransactionBlock --- are we within either a transaction
4400  * or a transaction block?	(The backend is only really "idle" when this
4401  * returns false.)
4402  *
4403  * This should match up with IsTransactionBlock and IsTransactionState.
4404  */
4405 bool
IsTransactionOrTransactionBlock(void)4406 IsTransactionOrTransactionBlock(void)
4407 {
4408 	TransactionState s = CurrentTransactionState;
4409 
4410 	if (s->blockState == TBLOCK_DEFAULT)
4411 		return false;
4412 
4413 	return true;
4414 }
4415 
4416 /*
4417  * TransactionBlockStatusCode - return status code to send in ReadyForQuery
4418  */
4419 char
TransactionBlockStatusCode(void)4420 TransactionBlockStatusCode(void)
4421 {
4422 	TransactionState s = CurrentTransactionState;
4423 
4424 	switch (s->blockState)
4425 	{
4426 		case TBLOCK_DEFAULT:
4427 		case TBLOCK_STARTED:
4428 			return 'I';			/* idle --- not in transaction */
4429 		case TBLOCK_BEGIN:
4430 		case TBLOCK_SUBBEGIN:
4431 		case TBLOCK_INPROGRESS:
4432 		case TBLOCK_PARALLEL_INPROGRESS:
4433 		case TBLOCK_SUBINPROGRESS:
4434 		case TBLOCK_END:
4435 		case TBLOCK_SUBRELEASE:
4436 		case TBLOCK_SUBCOMMIT:
4437 		case TBLOCK_PREPARE:
4438 			return 'T';			/* in transaction */
4439 		case TBLOCK_ABORT:
4440 		case TBLOCK_SUBABORT:
4441 		case TBLOCK_ABORT_END:
4442 		case TBLOCK_SUBABORT_END:
4443 		case TBLOCK_ABORT_PENDING:
4444 		case TBLOCK_SUBABORT_PENDING:
4445 		case TBLOCK_SUBRESTART:
4446 		case TBLOCK_SUBABORT_RESTART:
4447 			return 'E';			/* in failed transaction */
4448 	}
4449 
4450 	/* should never get here */
4451 	elog(FATAL, "invalid transaction block state: %s",
4452 		 BlockStateAsString(s->blockState));
4453 	return 0;					/* keep compiler quiet */
4454 }
4455 
4456 /*
4457  * IsSubTransaction
4458  */
4459 bool
IsSubTransaction(void)4460 IsSubTransaction(void)
4461 {
4462 	TransactionState s = CurrentTransactionState;
4463 
4464 	if (s->nestingLevel >= 2)
4465 		return true;
4466 
4467 	return false;
4468 }
4469 
4470 /*
4471  * StartSubTransaction
4472  *
4473  * If you're wondering why this is separate from PushTransaction: it's because
4474  * we can't conveniently do this stuff right inside DefineSavepoint.  The
4475  * SAVEPOINT utility command will be executed inside a Portal, and if we
4476  * muck with CurrentMemoryContext or CurrentResourceOwner then exit from
4477  * the Portal will undo those settings.  So we make DefineSavepoint just
4478  * push a dummy transaction block, and when control returns to the main
4479  * idle loop, CommitTransactionCommand will be called, and we'll come here
4480  * to finish starting the subtransaction.
4481  */
4482 static void
StartSubTransaction(void)4483 StartSubTransaction(void)
4484 {
4485 	TransactionState s = CurrentTransactionState;
4486 
4487 	if (s->state != TRANS_DEFAULT)
4488 		elog(WARNING, "StartSubTransaction while in %s state",
4489 			 TransStateAsString(s->state));
4490 
4491 	s->state = TRANS_START;
4492 
4493 	/*
4494 	 * Initialize subsystems for new subtransaction
4495 	 *
4496 	 * must initialize resource-management stuff first
4497 	 */
4498 	AtSubStart_Memory();
4499 	AtSubStart_ResourceOwner();
4500 	AtSubStart_Notify();
4501 	AfterTriggerBeginSubXact();
4502 
4503 	s->state = TRANS_INPROGRESS;
4504 
4505 	/*
4506 	 * Call start-of-subxact callbacks
4507 	 */
4508 	CallSubXactCallbacks(SUBXACT_EVENT_START_SUB, s->subTransactionId,
4509 						 s->parent->subTransactionId);
4510 
4511 	ShowTransactionState("StartSubTransaction");
4512 }
4513 
4514 /*
4515  * CommitSubTransaction
4516  *
4517  *	The caller has to make sure to always reassign CurrentTransactionState
4518  *	if it has a local pointer to it after calling this function.
4519  */
4520 static void
CommitSubTransaction(void)4521 CommitSubTransaction(void)
4522 {
4523 	TransactionState s = CurrentTransactionState;
4524 
4525 	ShowTransactionState("CommitSubTransaction");
4526 
4527 	if (s->state != TRANS_INPROGRESS)
4528 		elog(WARNING, "CommitSubTransaction while in %s state",
4529 			 TransStateAsString(s->state));
4530 
4531 	/* Pre-commit processing goes here */
4532 
4533 	CallSubXactCallbacks(SUBXACT_EVENT_PRE_COMMIT_SUB, s->subTransactionId,
4534 						 s->parent->subTransactionId);
4535 
4536 	/* If in parallel mode, clean up workers and exit parallel mode. */
4537 	if (IsInParallelMode())
4538 	{
4539 		AtEOSubXact_Parallel(true, s->subTransactionId);
4540 		s->parallelModeLevel = 0;
4541 	}
4542 
4543 	/* Do the actual "commit", such as it is */
4544 	s->state = TRANS_COMMIT;
4545 
4546 	/* Must CCI to ensure commands of subtransaction are seen as done */
4547 	CommandCounterIncrement();
4548 
4549 	/*
4550 	 * Prior to 8.4 we marked subcommit in clog at this point.  We now only
4551 	 * perform that step, if required, as part of the atomic update of the
4552 	 * whole transaction tree at top level commit or abort.
4553 	 */
4554 
4555 	/* Post-commit cleanup */
4556 	if (TransactionIdIsValid(s->transactionId))
4557 		AtSubCommit_childXids();
4558 	AfterTriggerEndSubXact(true);
4559 	AtSubCommit_Portals(s->subTransactionId,
4560 						s->parent->subTransactionId,
4561 						s->parent->curTransactionOwner);
4562 	AtEOSubXact_LargeObject(true, s->subTransactionId,
4563 							s->parent->subTransactionId);
4564 	AtSubCommit_Notify();
4565 
4566 	CallSubXactCallbacks(SUBXACT_EVENT_COMMIT_SUB, s->subTransactionId,
4567 						 s->parent->subTransactionId);
4568 
4569 	ResourceOwnerRelease(s->curTransactionOwner,
4570 						 RESOURCE_RELEASE_BEFORE_LOCKS,
4571 						 true, false);
4572 	AtEOSubXact_RelationCache(true, s->subTransactionId,
4573 							  s->parent->subTransactionId);
4574 	AtEOSubXact_Inval(true);
4575 	AtSubCommit_smgr();
4576 
4577 	/*
4578 	 * The only lock we actually release here is the subtransaction XID lock.
4579 	 */
4580 	CurrentResourceOwner = s->curTransactionOwner;
4581 	if (TransactionIdIsValid(s->transactionId))
4582 		XactLockTableDelete(s->transactionId);
4583 
4584 	/*
4585 	 * Other locks should get transferred to their parent resource owner.
4586 	 */
4587 	ResourceOwnerRelease(s->curTransactionOwner,
4588 						 RESOURCE_RELEASE_LOCKS,
4589 						 true, false);
4590 	ResourceOwnerRelease(s->curTransactionOwner,
4591 						 RESOURCE_RELEASE_AFTER_LOCKS,
4592 						 true, false);
4593 
4594 	AtEOXact_GUC(true, s->gucNestLevel);
4595 	AtEOSubXact_SPI(true, s->subTransactionId);
4596 	AtEOSubXact_on_commit_actions(true, s->subTransactionId,
4597 								  s->parent->subTransactionId);
4598 	AtEOSubXact_Namespace(true, s->subTransactionId,
4599 						  s->parent->subTransactionId);
4600 	AtEOSubXact_Files(true, s->subTransactionId,
4601 					  s->parent->subTransactionId);
4602 	AtEOSubXact_HashTables(true, s->nestingLevel);
4603 	AtEOSubXact_PgStat(true, s->nestingLevel);
4604 	AtSubCommit_Snapshot(s->nestingLevel);
4605 	AtEOSubXact_ApplyLauncher(true, s->nestingLevel);
4606 
4607 	/*
4608 	 * We need to restore the upper transaction's read-only state, in case the
4609 	 * upper is read-write while the child is read-only; GUC will incorrectly
4610 	 * think it should leave the child state in place.
4611 	 */
4612 	XactReadOnly = s->prevXactReadOnly;
4613 
4614 	CurrentResourceOwner = s->parent->curTransactionOwner;
4615 	CurTransactionResourceOwner = s->parent->curTransactionOwner;
4616 	ResourceOwnerDelete(s->curTransactionOwner);
4617 	s->curTransactionOwner = NULL;
4618 
4619 	AtSubCommit_Memory();
4620 
4621 	s->state = TRANS_DEFAULT;
4622 
4623 	PopTransaction();
4624 }
4625 
4626 /*
4627  * AbortSubTransaction
4628  */
4629 static void
AbortSubTransaction(void)4630 AbortSubTransaction(void)
4631 {
4632 	TransactionState s = CurrentTransactionState;
4633 
4634 	/* Prevent cancel/die interrupt while cleaning up */
4635 	HOLD_INTERRUPTS();
4636 
4637 	/* Make sure we have a valid memory context and resource owner */
4638 	AtSubAbort_Memory();
4639 	AtSubAbort_ResourceOwner();
4640 
4641 	/*
4642 	 * Release any LW locks we might be holding as quickly as possible.
4643 	 * (Regular locks, however, must be held till we finish aborting.)
4644 	 * Releasing LW locks is critical since we might try to grab them again
4645 	 * while cleaning up!
4646 	 *
4647 	 * FIXME This may be incorrect --- Are there some locks we should keep?
4648 	 * Buffer locks, for example?  I don't think so but I'm not sure.
4649 	 */
4650 	LWLockReleaseAll();
4651 
4652 	pgstat_report_wait_end();
4653 	pgstat_progress_end_command();
4654 	AbortBufferIO();
4655 	UnlockBuffers();
4656 
4657 	/* Reset WAL record construction state */
4658 	XLogResetInsertion();
4659 
4660 	/* Cancel condition variable sleep */
4661 	ConditionVariableCancelSleep();
4662 
4663 	/*
4664 	 * Also clean up any open wait for lock, since the lock manager will choke
4665 	 * if we try to wait for another lock before doing this.
4666 	 */
4667 	LockErrorCleanup();
4668 
4669 	/*
4670 	 * If any timeout events are still active, make sure the timeout interrupt
4671 	 * is scheduled.  This covers possible loss of a timeout interrupt due to
4672 	 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
4673 	 * We delay this till after LockErrorCleanup so that we don't uselessly
4674 	 * reschedule lock or deadlock check timeouts.
4675 	 */
4676 	reschedule_timeouts();
4677 
4678 	/*
4679 	 * Re-enable signals, in case we got here by longjmp'ing out of a signal
4680 	 * handler.  We do this fairly early in the sequence so that the timeout
4681 	 * infrastructure will be functional if needed while aborting.
4682 	 */
4683 	PG_SETMASK(&UnBlockSig);
4684 
4685 	/*
4686 	 * check the current transaction state
4687 	 */
4688 	ShowTransactionState("AbortSubTransaction");
4689 
4690 	if (s->state != TRANS_INPROGRESS)
4691 		elog(WARNING, "AbortSubTransaction while in %s state",
4692 			 TransStateAsString(s->state));
4693 
4694 	s->state = TRANS_ABORT;
4695 
4696 	/*
4697 	 * Reset user ID which might have been changed transiently.  (See notes in
4698 	 * AbortTransaction.)
4699 	 */
4700 	SetUserIdAndSecContext(s->prevUser, s->prevSecContext);
4701 
4702 	/* Forget about any active REINDEX. */
4703 	ResetReindexState(s->nestingLevel);
4704 
4705 	/*
4706 	 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
4707 	 * exports are not supported in subtransactions.
4708 	 */
4709 
4710 	/* Exit from parallel mode, if necessary. */
4711 	if (IsInParallelMode())
4712 	{
4713 		AtEOSubXact_Parallel(false, s->subTransactionId);
4714 		s->parallelModeLevel = 0;
4715 	}
4716 
4717 	/*
4718 	 * We can skip all this stuff if the subxact failed before creating a
4719 	 * ResourceOwner...
4720 	 */
4721 	if (s->curTransactionOwner)
4722 	{
4723 		AfterTriggerEndSubXact(false);
4724 		AtSubAbort_Portals(s->subTransactionId,
4725 						   s->parent->subTransactionId,
4726 						   s->curTransactionOwner,
4727 						   s->parent->curTransactionOwner);
4728 		AtEOSubXact_LargeObject(false, s->subTransactionId,
4729 								s->parent->subTransactionId);
4730 		AtSubAbort_Notify();
4731 
4732 		/* Advertise the fact that we aborted in pg_xact. */
4733 		(void) RecordTransactionAbort(true);
4734 
4735 		/* Post-abort cleanup */
4736 		if (TransactionIdIsValid(s->transactionId))
4737 			AtSubAbort_childXids();
4738 
4739 		CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId,
4740 							 s->parent->subTransactionId);
4741 
4742 		ResourceOwnerRelease(s->curTransactionOwner,
4743 							 RESOURCE_RELEASE_BEFORE_LOCKS,
4744 							 false, false);
4745 		AtEOSubXact_RelationCache(false, s->subTransactionId,
4746 								  s->parent->subTransactionId);
4747 		AtEOSubXact_Inval(false);
4748 		ResourceOwnerRelease(s->curTransactionOwner,
4749 							 RESOURCE_RELEASE_LOCKS,
4750 							 false, false);
4751 		ResourceOwnerRelease(s->curTransactionOwner,
4752 							 RESOURCE_RELEASE_AFTER_LOCKS,
4753 							 false, false);
4754 		AtSubAbort_smgr();
4755 
4756 		AtEOXact_GUC(false, s->gucNestLevel);
4757 		AtEOSubXact_SPI(false, s->subTransactionId);
4758 		AtEOSubXact_on_commit_actions(false, s->subTransactionId,
4759 									  s->parent->subTransactionId);
4760 		AtEOSubXact_Namespace(false, s->subTransactionId,
4761 							  s->parent->subTransactionId);
4762 		AtEOSubXact_Files(false, s->subTransactionId,
4763 						  s->parent->subTransactionId);
4764 		AtEOSubXact_HashTables(false, s->nestingLevel);
4765 		AtEOSubXact_PgStat(false, s->nestingLevel);
4766 		AtSubAbort_Snapshot(s->nestingLevel);
4767 		AtEOSubXact_ApplyLauncher(false, s->nestingLevel);
4768 	}
4769 
4770 	/*
4771 	 * Restore the upper transaction's read-only state, too.  This should be
4772 	 * redundant with GUC's cleanup but we may as well do it for consistency
4773 	 * with the commit case.
4774 	 */
4775 	XactReadOnly = s->prevXactReadOnly;
4776 
4777 	RESUME_INTERRUPTS();
4778 }
4779 
4780 /*
4781  * CleanupSubTransaction
4782  *
4783  *	The caller has to make sure to always reassign CurrentTransactionState
4784  *	if it has a local pointer to it after calling this function.
4785  */
4786 static void
CleanupSubTransaction(void)4787 CleanupSubTransaction(void)
4788 {
4789 	TransactionState s = CurrentTransactionState;
4790 
4791 	ShowTransactionState("CleanupSubTransaction");
4792 
4793 	if (s->state != TRANS_ABORT)
4794 		elog(WARNING, "CleanupSubTransaction while in %s state",
4795 			 TransStateAsString(s->state));
4796 
4797 	AtSubCleanup_Portals(s->subTransactionId);
4798 
4799 	CurrentResourceOwner = s->parent->curTransactionOwner;
4800 	CurTransactionResourceOwner = s->parent->curTransactionOwner;
4801 	if (s->curTransactionOwner)
4802 		ResourceOwnerDelete(s->curTransactionOwner);
4803 	s->curTransactionOwner = NULL;
4804 
4805 	AtSubCleanup_Memory();
4806 
4807 	s->state = TRANS_DEFAULT;
4808 
4809 	PopTransaction();
4810 }
4811 
4812 /*
4813  * PushTransaction
4814  *		Create transaction state stack entry for a subtransaction
4815  *
4816  *	The caller has to make sure to always reassign CurrentTransactionState
4817  *	if it has a local pointer to it after calling this function.
4818  */
4819 static void
PushTransaction(void)4820 PushTransaction(void)
4821 {
4822 	TransactionState p = CurrentTransactionState;
4823 	TransactionState s;
4824 
4825 	/*
4826 	 * We keep subtransaction state nodes in TopTransactionContext.
4827 	 */
4828 	s = (TransactionState)
4829 		MemoryContextAllocZero(TopTransactionContext,
4830 							   sizeof(TransactionStateData));
4831 
4832 	/*
4833 	 * Assign a subtransaction ID, watching out for counter wraparound.
4834 	 */
4835 	currentSubTransactionId += 1;
4836 	if (currentSubTransactionId == InvalidSubTransactionId)
4837 	{
4838 		currentSubTransactionId -= 1;
4839 		pfree(s);
4840 		ereport(ERROR,
4841 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
4842 				 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
4843 	}
4844 
4845 	/*
4846 	 * We can now stack a minimally valid subtransaction without fear of
4847 	 * failure.
4848 	 */
4849 	s->transactionId = InvalidTransactionId;	/* until assigned */
4850 	s->subTransactionId = currentSubTransactionId;
4851 	s->parent = p;
4852 	s->nestingLevel = p->nestingLevel + 1;
4853 	s->gucNestLevel = NewGUCNestLevel();
4854 	s->savepointLevel = p->savepointLevel;
4855 	s->state = TRANS_DEFAULT;
4856 	s->blockState = TBLOCK_SUBBEGIN;
4857 	GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);
4858 	s->prevXactReadOnly = XactReadOnly;
4859 	s->parallelModeLevel = 0;
4860 
4861 	CurrentTransactionState = s;
4862 
4863 	/*
4864 	 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
4865 	 * with the subtransaction from here on out; in particular they should not
4866 	 * assume that it necessarily has a transaction context, resource owner,
4867 	 * or XID.
4868 	 */
4869 }
4870 
4871 /*
4872  * PopTransaction
4873  *		Pop back to parent transaction state
4874  *
4875  *	The caller has to make sure to always reassign CurrentTransactionState
4876  *	if it has a local pointer to it after calling this function.
4877  */
4878 static void
PopTransaction(void)4879 PopTransaction(void)
4880 {
4881 	TransactionState s = CurrentTransactionState;
4882 
4883 	if (s->state != TRANS_DEFAULT)
4884 		elog(WARNING, "PopTransaction while in %s state",
4885 			 TransStateAsString(s->state));
4886 
4887 	if (s->parent == NULL)
4888 		elog(FATAL, "PopTransaction with no parent");
4889 
4890 	CurrentTransactionState = s->parent;
4891 
4892 	/* Let's just make sure CurTransactionContext is good */
4893 	CurTransactionContext = s->parent->curTransactionContext;
4894 	MemoryContextSwitchTo(CurTransactionContext);
4895 
4896 	/* Ditto for ResourceOwner links */
4897 	CurTransactionResourceOwner = s->parent->curTransactionOwner;
4898 	CurrentResourceOwner = s->parent->curTransactionOwner;
4899 
4900 	/* Free the old child structure */
4901 	if (s->name)
4902 		pfree(s->name);
4903 	pfree(s);
4904 }
4905 
4906 /*
4907  * EstimateTransactionStateSpace
4908  *		Estimate the amount of space that will be needed by
4909  *		SerializeTransactionState.  It would be OK to overestimate slightly,
4910  *		but it's simple for us to work out the precise value, so we do.
4911  */
4912 Size
EstimateTransactionStateSpace(void)4913 EstimateTransactionStateSpace(void)
4914 {
4915 	TransactionState s;
4916 	Size		nxids = 6;		/* iso level, deferrable, top & current XID,
4917 								 * command counter, XID count */
4918 
4919 	for (s = CurrentTransactionState; s != NULL; s = s->parent)
4920 	{
4921 		if (TransactionIdIsValid(s->transactionId))
4922 			nxids = add_size(nxids, 1);
4923 		nxids = add_size(nxids, s->nChildXids);
4924 	}
4925 
4926 	nxids = add_size(nxids, nParallelCurrentXids);
4927 	return mul_size(nxids, sizeof(TransactionId));
4928 }
4929 
4930 /*
4931  * SerializeTransactionState
4932  *		Write out relevant details of our transaction state that will be
4933  *		needed by a parallel worker.
4934  *
4935  * We need to save and restore XactDeferrable, XactIsoLevel, and the XIDs
4936  * associated with this transaction.  The first eight bytes of the result
4937  * contain XactDeferrable and XactIsoLevel; the next twelve bytes contain the
4938  * XID of the top-level transaction, the XID of the current transaction
4939  * (or, in each case, InvalidTransactionId if none), and the current command
4940  * counter.  After that, the next 4 bytes contain a count of how many
4941  * additional XIDs follow; this is followed by all of those XIDs one after
4942  * another.  We emit the XIDs in sorted order for the convenience of the
4943  * receiving process.
4944  */
4945 void
SerializeTransactionState(Size maxsize,char * start_address)4946 SerializeTransactionState(Size maxsize, char *start_address)
4947 {
4948 	TransactionState s;
4949 	Size		nxids = 0;
4950 	Size		i = 0;
4951 	Size		c = 0;
4952 	TransactionId *workspace;
4953 	TransactionId *result = (TransactionId *) start_address;
4954 
4955 	result[c++] = (TransactionId) XactIsoLevel;
4956 	result[c++] = (TransactionId) XactDeferrable;
4957 	result[c++] = XactTopTransactionId;
4958 	result[c++] = CurrentTransactionState->transactionId;
4959 	result[c++] = (TransactionId) currentCommandId;
4960 	Assert(maxsize >= c * sizeof(TransactionId));
4961 
4962 	/*
4963 	 * If we're running in a parallel worker and launching a parallel worker
4964 	 * of our own, we can just pass along the information that was passed to
4965 	 * us.
4966 	 */
4967 	if (nParallelCurrentXids > 0)
4968 	{
4969 		result[c++] = nParallelCurrentXids;
4970 		Assert(maxsize >= (nParallelCurrentXids + c) * sizeof(TransactionId));
4971 		memcpy(&result[c], ParallelCurrentXids,
4972 			   nParallelCurrentXids * sizeof(TransactionId));
4973 		return;
4974 	}
4975 
4976 	/*
4977 	 * OK, we need to generate a sorted list of XIDs that our workers should
4978 	 * view as current.  First, figure out how many there are.
4979 	 */
4980 	for (s = CurrentTransactionState; s != NULL; s = s->parent)
4981 	{
4982 		if (TransactionIdIsValid(s->transactionId))
4983 			nxids = add_size(nxids, 1);
4984 		nxids = add_size(nxids, s->nChildXids);
4985 	}
4986 	Assert((c + 1 + nxids) * sizeof(TransactionId) <= maxsize);
4987 
4988 	/* Copy them to our scratch space. */
4989 	workspace = palloc(nxids * sizeof(TransactionId));
4990 	for (s = CurrentTransactionState; s != NULL; s = s->parent)
4991 	{
4992 		if (TransactionIdIsValid(s->transactionId))
4993 			workspace[i++] = s->transactionId;
4994 		memcpy(&workspace[i], s->childXids,
4995 			   s->nChildXids * sizeof(TransactionId));
4996 		i += s->nChildXids;
4997 	}
4998 	Assert(i == nxids);
4999 
5000 	/* Sort them. */
5001 	qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5002 
5003 	/* Copy data into output area. */
5004 	result[c++] = (TransactionId) nxids;
5005 	memcpy(&result[c], workspace, nxids * sizeof(TransactionId));
5006 }
5007 
5008 /*
5009  * StartParallelWorkerTransaction
5010  *		Start a parallel worker transaction, restoring the relevant
5011  *		transaction state serialized by SerializeTransactionState.
5012  */
5013 void
StartParallelWorkerTransaction(char * tstatespace)5014 StartParallelWorkerTransaction(char *tstatespace)
5015 {
5016 	TransactionId *tstate = (TransactionId *) tstatespace;
5017 
5018 	Assert(CurrentTransactionState->blockState == TBLOCK_DEFAULT);
5019 	StartTransaction();
5020 
5021 	XactIsoLevel = (int) tstate[0];
5022 	XactDeferrable = (bool) tstate[1];
5023 	XactTopTransactionId = tstate[2];
5024 	CurrentTransactionState->transactionId = tstate[3];
5025 	currentCommandId = tstate[4];
5026 	nParallelCurrentXids = (int) tstate[5];
5027 	ParallelCurrentXids = &tstate[6];
5028 
5029 	CurrentTransactionState->blockState = TBLOCK_PARALLEL_INPROGRESS;
5030 }
5031 
5032 /*
5033  * EndParallelWorkerTransaction
5034  *		End a parallel worker transaction.
5035  */
5036 void
EndParallelWorkerTransaction(void)5037 EndParallelWorkerTransaction(void)
5038 {
5039 	Assert(CurrentTransactionState->blockState == TBLOCK_PARALLEL_INPROGRESS);
5040 	CommitTransaction();
5041 	CurrentTransactionState->blockState = TBLOCK_DEFAULT;
5042 }
5043 
5044 /*
5045  * ShowTransactionState
5046  *		Debug support
5047  */
5048 static void
ShowTransactionState(const char * str)5049 ShowTransactionState(const char *str)
5050 {
5051 	/* skip work if message will definitely not be printed */
5052 	if (log_min_messages <= DEBUG5 || client_min_messages <= DEBUG5)
5053 		ShowTransactionStateRec(str, CurrentTransactionState);
5054 }
5055 
5056 /*
5057  * ShowTransactionStateRec
5058  *		Recursive subroutine for ShowTransactionState
5059  */
5060 static void
ShowTransactionStateRec(const char * str,TransactionState s)5061 ShowTransactionStateRec(const char *str, TransactionState s)
5062 {
5063 	StringInfoData buf;
5064 
5065 	initStringInfo(&buf);
5066 
5067 	if (s->nChildXids > 0)
5068 	{
5069 		int			i;
5070 
5071 		appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5072 		for (i = 1; i < s->nChildXids; i++)
5073 			appendStringInfo(&buf, " %u", s->childXids[i]);
5074 	}
5075 
5076 	if (s->parent)
5077 		ShowTransactionStateRec(str, s->parent);
5078 
5079 	/* use ereport to suppress computation if msg will not be printed */
5080 	ereport(DEBUG5,
5081 			(errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5082 							 str, s->nestingLevel,
5083 							 PointerIsValid(s->name) ? s->name : "unnamed",
5084 							 BlockStateAsString(s->blockState),
5085 							 TransStateAsString(s->state),
5086 							 (unsigned int) s->transactionId,
5087 							 (unsigned int) s->subTransactionId,
5088 							 (unsigned int) currentCommandId,
5089 							 currentCommandIdUsed ? " (used)" : "",
5090 							 buf.data)));
5091 
5092 	pfree(buf.data);
5093 }
5094 
5095 /*
5096  * BlockStateAsString
5097  *		Debug support
5098  */
5099 static const char *
BlockStateAsString(TBlockState blockState)5100 BlockStateAsString(TBlockState blockState)
5101 {
5102 	switch (blockState)
5103 	{
5104 		case TBLOCK_DEFAULT:
5105 			return "DEFAULT";
5106 		case TBLOCK_STARTED:
5107 			return "STARTED";
5108 		case TBLOCK_BEGIN:
5109 			return "BEGIN";
5110 		case TBLOCK_INPROGRESS:
5111 			return "INPROGRESS";
5112 		case TBLOCK_PARALLEL_INPROGRESS:
5113 			return "PARALLEL_INPROGRESS";
5114 		case TBLOCK_END:
5115 			return "END";
5116 		case TBLOCK_ABORT:
5117 			return "ABORT";
5118 		case TBLOCK_ABORT_END:
5119 			return "ABORT END";
5120 		case TBLOCK_ABORT_PENDING:
5121 			return "ABORT PEND";
5122 		case TBLOCK_PREPARE:
5123 			return "PREPARE";
5124 		case TBLOCK_SUBBEGIN:
5125 			return "SUB BEGIN";
5126 		case TBLOCK_SUBINPROGRESS:
5127 			return "SUB INPROGRS";
5128 		case TBLOCK_SUBRELEASE:
5129 			return "SUB RELEASE";
5130 		case TBLOCK_SUBCOMMIT:
5131 			return "SUB COMMIT";
5132 		case TBLOCK_SUBABORT:
5133 			return "SUB ABORT";
5134 		case TBLOCK_SUBABORT_END:
5135 			return "SUB ABORT END";
5136 		case TBLOCK_SUBABORT_PENDING:
5137 			return "SUB ABRT PEND";
5138 		case TBLOCK_SUBRESTART:
5139 			return "SUB RESTART";
5140 		case TBLOCK_SUBABORT_RESTART:
5141 			return "SUB AB RESTRT";
5142 	}
5143 	return "UNRECOGNIZED";
5144 }
5145 
5146 /*
5147  * TransStateAsString
5148  *		Debug support
5149  */
5150 static const char *
TransStateAsString(TransState state)5151 TransStateAsString(TransState state)
5152 {
5153 	switch (state)
5154 	{
5155 		case TRANS_DEFAULT:
5156 			return "DEFAULT";
5157 		case TRANS_START:
5158 			return "START";
5159 		case TRANS_INPROGRESS:
5160 			return "INPROGR";
5161 		case TRANS_COMMIT:
5162 			return "COMMIT";
5163 		case TRANS_ABORT:
5164 			return "ABORT";
5165 		case TRANS_PREPARE:
5166 			return "PREPARE";
5167 	}
5168 	return "UNRECOGNIZED";
5169 }
5170 
5171 /*
5172  * xactGetCommittedChildren
5173  *
5174  * Gets the list of committed children of the current transaction.  The return
5175  * value is the number of child transactions.  *ptr is set to point to an
5176  * array of TransactionIds.  The array is allocated in TopTransactionContext;
5177  * the caller should *not* pfree() it (this is a change from pre-8.4 code!).
5178  * If there are no subxacts, *ptr is set to NULL.
5179  */
5180 int
xactGetCommittedChildren(TransactionId ** ptr)5181 xactGetCommittedChildren(TransactionId **ptr)
5182 {
5183 	TransactionState s = CurrentTransactionState;
5184 
5185 	if (s->nChildXids == 0)
5186 		*ptr = NULL;
5187 	else
5188 		*ptr = s->childXids;
5189 
5190 	return s->nChildXids;
5191 }
5192 
5193 /*
5194  *	XLOG support routines
5195  */
5196 
5197 
5198 /*
5199  * Log the commit record for a plain or twophase transaction commit.
5200  *
5201  * A 2pc commit will be emitted when twophase_xid is valid, a plain one
5202  * otherwise.
5203  */
5204 XLogRecPtr
XactLogCommitRecord(TimestampTz commit_time,int nsubxacts,TransactionId * subxacts,int nrels,RelFileNode * rels,int nmsgs,SharedInvalidationMessage * msgs,bool relcacheInval,bool forceSync,int xactflags,TransactionId twophase_xid)5205 XactLogCommitRecord(TimestampTz commit_time,
5206 					int nsubxacts, TransactionId *subxacts,
5207 					int nrels, RelFileNode *rels,
5208 					int nmsgs, SharedInvalidationMessage *msgs,
5209 					bool relcacheInval, bool forceSync,
5210 					int xactflags, TransactionId twophase_xid)
5211 {
5212 	xl_xact_commit xlrec;
5213 	xl_xact_xinfo xl_xinfo;
5214 	xl_xact_dbinfo xl_dbinfo;
5215 	xl_xact_subxacts xl_subxacts;
5216 	xl_xact_relfilenodes xl_relfilenodes;
5217 	xl_xact_invals xl_invals;
5218 	xl_xact_twophase xl_twophase;
5219 	xl_xact_origin xl_origin;
5220 
5221 	uint8		info;
5222 
5223 	Assert(CritSectionCount > 0);
5224 
5225 	xl_xinfo.xinfo = 0;
5226 
5227 	/* decide between a plain and 2pc commit */
5228 	if (!TransactionIdIsValid(twophase_xid))
5229 		info = XLOG_XACT_COMMIT;
5230 	else
5231 		info = XLOG_XACT_COMMIT_PREPARED;
5232 
5233 	/* First figure out and collect all the information needed */
5234 
5235 	xlrec.xact_time = commit_time;
5236 
5237 	if (relcacheInval)
5238 		xl_xinfo.xinfo |= XACT_COMPLETION_UPDATE_RELCACHE_FILE;
5239 	if (forceSyncCommit)
5240 		xl_xinfo.xinfo |= XACT_COMPLETION_FORCE_SYNC_COMMIT;
5241 	if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5242 		xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5243 
5244 	/*
5245 	 * Check if the caller would like to ask standbys for immediate feedback
5246 	 * once this commit is applied.
5247 	 */
5248 	if (synchronous_commit >= SYNCHRONOUS_COMMIT_REMOTE_APPLY)
5249 		xl_xinfo.xinfo |= XACT_COMPLETION_APPLY_FEEDBACK;
5250 
5251 	/*
5252 	 * Relcache invalidations requires information about the current database
5253 	 * and so does logical decoding.
5254 	 */
5255 	if (nmsgs > 0 || XLogLogicalInfoActive())
5256 	{
5257 		xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5258 		xl_dbinfo.dbId = MyDatabaseId;
5259 		xl_dbinfo.tsId = MyDatabaseTableSpace;
5260 	}
5261 
5262 	if (nsubxacts > 0)
5263 	{
5264 		xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5265 		xl_subxacts.nsubxacts = nsubxacts;
5266 	}
5267 
5268 	if (nrels > 0)
5269 	{
5270 		xl_xinfo.xinfo |= XACT_XINFO_HAS_RELFILENODES;
5271 		xl_relfilenodes.nrels = nrels;
5272 	}
5273 
5274 	if (nmsgs > 0)
5275 	{
5276 		xl_xinfo.xinfo |= XACT_XINFO_HAS_INVALS;
5277 		xl_invals.nmsgs = nmsgs;
5278 	}
5279 
5280 	if (TransactionIdIsValid(twophase_xid))
5281 	{
5282 		xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5283 		xl_twophase.xid = twophase_xid;
5284 	}
5285 
5286 	/* dump transaction origin information */
5287 	if (replorigin_session_origin != InvalidRepOriginId)
5288 	{
5289 		xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
5290 
5291 		xl_origin.origin_lsn = replorigin_session_origin_lsn;
5292 		xl_origin.origin_timestamp = replorigin_session_origin_timestamp;
5293 	}
5294 
5295 	if (xl_xinfo.xinfo != 0)
5296 		info |= XLOG_XACT_HAS_INFO;
5297 
5298 	/* Then include all the collected data into the commit record. */
5299 
5300 	XLogBeginInsert();
5301 
5302 	XLogRegisterData((char *) (&xlrec), sizeof(xl_xact_commit));
5303 
5304 	if (xl_xinfo.xinfo != 0)
5305 		XLogRegisterData((char *) (&xl_xinfo.xinfo), sizeof(xl_xinfo.xinfo));
5306 
5307 	if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5308 		XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
5309 
5310 	if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5311 	{
5312 		XLogRegisterData((char *) (&xl_subxacts),
5313 						 MinSizeOfXactSubxacts);
5314 		XLogRegisterData((char *) subxacts,
5315 						 nsubxacts * sizeof(TransactionId));
5316 	}
5317 
5318 	if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILENODES)
5319 	{
5320 		XLogRegisterData((char *) (&xl_relfilenodes),
5321 						 MinSizeOfXactRelfilenodes);
5322 		XLogRegisterData((char *) rels,
5323 						 nrels * sizeof(RelFileNode));
5324 	}
5325 
5326 	if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
5327 	{
5328 		XLogRegisterData((char *) (&xl_invals), MinSizeOfXactInvals);
5329 		XLogRegisterData((char *) msgs,
5330 						 nmsgs * sizeof(SharedInvalidationMessage));
5331 	}
5332 
5333 	if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5334 		XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
5335 
5336 	if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5337 		XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
5338 
5339 	/* we allow filtering by xacts */
5340 	XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
5341 
5342 	return XLogInsert(RM_XACT_ID, info);
5343 }
5344 
5345 /*
5346  * Log the commit record for a plain or twophase transaction abort.
5347  *
5348  * A 2pc abort will be emitted when twophase_xid is valid, a plain one
5349  * otherwise.
5350  */
5351 XLogRecPtr
XactLogAbortRecord(TimestampTz abort_time,int nsubxacts,TransactionId * subxacts,int nrels,RelFileNode * rels,int xactflags,TransactionId twophase_xid)5352 XactLogAbortRecord(TimestampTz abort_time,
5353 				   int nsubxacts, TransactionId *subxacts,
5354 				   int nrels, RelFileNode *rels,
5355 				   int xactflags, TransactionId twophase_xid)
5356 {
5357 	xl_xact_abort xlrec;
5358 	xl_xact_xinfo xl_xinfo;
5359 	xl_xact_subxacts xl_subxacts;
5360 	xl_xact_relfilenodes xl_relfilenodes;
5361 	xl_xact_twophase xl_twophase;
5362 
5363 	uint8		info;
5364 
5365 	Assert(CritSectionCount > 0);
5366 
5367 	xl_xinfo.xinfo = 0;
5368 
5369 	/* decide between a plain and 2pc abort */
5370 	if (!TransactionIdIsValid(twophase_xid))
5371 		info = XLOG_XACT_ABORT;
5372 	else
5373 		info = XLOG_XACT_ABORT_PREPARED;
5374 
5375 
5376 	/* First figure out and collect all the information needed */
5377 
5378 	xlrec.xact_time = abort_time;
5379 
5380 	if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5381 		xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5382 
5383 	if (nsubxacts > 0)
5384 	{
5385 		xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5386 		xl_subxacts.nsubxacts = nsubxacts;
5387 	}
5388 
5389 	if (nrels > 0)
5390 	{
5391 		xl_xinfo.xinfo |= XACT_XINFO_HAS_RELFILENODES;
5392 		xl_relfilenodes.nrels = nrels;
5393 	}
5394 
5395 	if (TransactionIdIsValid(twophase_xid))
5396 	{
5397 		xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5398 		xl_twophase.xid = twophase_xid;
5399 	}
5400 
5401 	if (xl_xinfo.xinfo != 0)
5402 		info |= XLOG_XACT_HAS_INFO;
5403 
5404 	/* Then include all the collected data into the abort record. */
5405 
5406 	XLogBeginInsert();
5407 
5408 	XLogRegisterData((char *) (&xlrec), MinSizeOfXactAbort);
5409 
5410 	if (xl_xinfo.xinfo != 0)
5411 		XLogRegisterData((char *) (&xl_xinfo), sizeof(xl_xinfo));
5412 
5413 	if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5414 	{
5415 		XLogRegisterData((char *) (&xl_subxacts),
5416 						 MinSizeOfXactSubxacts);
5417 		XLogRegisterData((char *) subxacts,
5418 						 nsubxacts * sizeof(TransactionId));
5419 	}
5420 
5421 	if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILENODES)
5422 	{
5423 		XLogRegisterData((char *) (&xl_relfilenodes),
5424 						 MinSizeOfXactRelfilenodes);
5425 		XLogRegisterData((char *) rels,
5426 						 nrels * sizeof(RelFileNode));
5427 	}
5428 
5429 	if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5430 		XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
5431 
5432 	return XLogInsert(RM_XACT_ID, info);
5433 }
5434 
5435 /*
5436  * Before 9.0 this was a fairly short function, but now it performs many
5437  * actions for which the order of execution is critical.
5438  */
5439 static void
xact_redo_commit(xl_xact_parsed_commit * parsed,TransactionId xid,XLogRecPtr lsn,RepOriginId origin_id)5440 xact_redo_commit(xl_xact_parsed_commit *parsed,
5441 				 TransactionId xid,
5442 				 XLogRecPtr lsn,
5443 				 RepOriginId origin_id)
5444 {
5445 	TransactionId max_xid;
5446 	TimestampTz commit_time;
5447 
5448 	Assert(TransactionIdIsValid(xid));
5449 
5450 	max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
5451 
5452 	/*
5453 	 * Make sure nextXid is beyond any XID mentioned in the record.
5454 	 *
5455 	 * We don't expect anyone else to modify nextXid, hence we don't need to
5456 	 * hold a lock while checking this. We still acquire the lock to modify
5457 	 * it, though.
5458 	 */
5459 	if (TransactionIdFollowsOrEquals(max_xid,
5460 									 ShmemVariableCache->nextXid))
5461 	{
5462 		LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
5463 		ShmemVariableCache->nextXid = max_xid;
5464 		TransactionIdAdvance(ShmemVariableCache->nextXid);
5465 		LWLockRelease(XidGenLock);
5466 	}
5467 
5468 	Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) ==
5469 		   (origin_id == InvalidRepOriginId));
5470 
5471 	if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
5472 		commit_time = parsed->origin_timestamp;
5473 	else
5474 		commit_time = parsed->xact_time;
5475 
5476 	/* Set the transaction commit timestamp and metadata */
5477 	TransactionTreeSetCommitTsData(xid, parsed->nsubxacts, parsed->subxacts,
5478 								   commit_time, origin_id, false);
5479 
5480 	if (standbyState == STANDBY_DISABLED)
5481 	{
5482 		/*
5483 		 * Mark the transaction committed in pg_xact.
5484 		 */
5485 		TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
5486 	}
5487 	else
5488 	{
5489 		/*
5490 		 * If a transaction completion record arrives that has as-yet
5491 		 * unobserved subtransactions then this will not have been fully
5492 		 * handled by the call to RecordKnownAssignedTransactionIds() in the
5493 		 * main recovery loop in xlog.c. So we need to do bookkeeping again to
5494 		 * cover that case. This is confusing and it is easy to think this
5495 		 * call is irrelevant, which has happened three times in development
5496 		 * already. Leave it in.
5497 		 */
5498 		RecordKnownAssignedTransactionIds(max_xid);
5499 
5500 		/*
5501 		 * Mark the transaction committed in pg_xact. We use async commit
5502 		 * protocol during recovery to provide information on database
5503 		 * consistency for when users try to set hint bits. It is important
5504 		 * that we do not set hint bits until the minRecoveryPoint is past
5505 		 * this commit record. This ensures that if we crash we don't see hint
5506 		 * bits set on changes made by transactions that haven't yet
5507 		 * recovered. It's unlikely but it's good to be safe.
5508 		 */
5509 		TransactionIdAsyncCommitTree(
5510 									 xid, parsed->nsubxacts, parsed->subxacts, lsn);
5511 
5512 		/*
5513 		 * We must mark clog before we update the ProcArray.
5514 		 */
5515 		ExpireTreeKnownAssignedTransactionIds(
5516 											  xid, parsed->nsubxacts, parsed->subxacts, max_xid);
5517 
5518 		/*
5519 		 * Send any cache invalidations attached to the commit. We must
5520 		 * maintain the same order of invalidation then release locks as
5521 		 * occurs in CommitTransaction().
5522 		 */
5523 		ProcessCommittedInvalidationMessages(
5524 											 parsed->msgs, parsed->nmsgs,
5525 											 XactCompletionRelcacheInitFileInval(parsed->xinfo),
5526 											 parsed->dbId, parsed->tsId);
5527 
5528 		/*
5529 		 * Release locks, if any. We do this for both two phase and normal one
5530 		 * phase transactions. In effect we are ignoring the prepare phase and
5531 		 * just going straight to lock release. At commit we release all locks
5532 		 * via their top-level xid only, so no need to provide subxact list,
5533 		 * which will save time when replaying commits.
5534 		 */
5535 		if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
5536 			StandbyReleaseLockTree(xid, 0, NULL);
5537 	}
5538 
5539 	if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
5540 	{
5541 		/* recover apply progress */
5542 		replorigin_advance(origin_id, parsed->origin_lsn, lsn,
5543 						   false /* backward */ , false /* WAL */ );
5544 	}
5545 
5546 	/* Make sure files supposed to be dropped are dropped */
5547 	if (parsed->nrels > 0)
5548 	{
5549 		/*
5550 		 * First update minimum recovery point to cover this WAL record. Once
5551 		 * a relation is deleted, there's no going back. The buffer manager
5552 		 * enforces the WAL-first rule for normal updates to relation files,
5553 		 * so that the minimum recovery point is always updated before the
5554 		 * corresponding change in the data file is flushed to disk, but we
5555 		 * have to do the same here since we're bypassing the buffer manager.
5556 		 *
5557 		 * Doing this before deleting the files means that if a deletion fails
5558 		 * for some reason, you cannot start up the system even after restart,
5559 		 * until you fix the underlying situation so that the deletion will
5560 		 * succeed. Alternatively, we could update the minimum recovery point
5561 		 * after deletion, but that would leave a small window where the
5562 		 * WAL-first rule would be violated.
5563 		 */
5564 		XLogFlush(lsn);
5565 
5566 		/* Make sure files supposed to be dropped are dropped */
5567 		DropRelationFiles(parsed->xnodes, parsed->nrels, true);
5568 	}
5569 
5570 	/*
5571 	 * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
5572 	 * in normal operation. For example, in CREATE DATABASE, we copy all files
5573 	 * from the template database, and then commit the transaction. If we
5574 	 * crash after all the files have been copied but before the commit, you
5575 	 * have files in the data directory without an entry in pg_database. To
5576 	 * minimize the window for that, we use ForceSyncCommit() to rush the
5577 	 * commit record to disk as quick as possible. We have the same window
5578 	 * during recovery, and forcing an XLogFlush() (which updates
5579 	 * minRecoveryPoint during recovery) helps to reduce that problem window,
5580 	 * for any user that requested ForceSyncCommit().
5581 	 */
5582 	if (XactCompletionForceSyncCommit(parsed->xinfo))
5583 		XLogFlush(lsn);
5584 
5585 	/*
5586 	 * If asked by the primary (because someone is waiting for a synchronous
5587 	 * commit = remote_apply), we will need to ask walreceiver to send a reply
5588 	 * immediately.
5589 	 */
5590 	if (XactCompletionApplyFeedback(parsed->xinfo))
5591 		XLogRequestWalReceiverReply();
5592 }
5593 
5594 /*
5595  * Be careful with the order of execution, as with xact_redo_commit().
5596  * The two functions are similar but differ in key places.
5597  *
5598  * Note also that an abort can be for a subtransaction and its children,
5599  * not just for a top level abort. That means we have to consider
5600  * topxid != xid, whereas in commit we would find topxid == xid always
5601  * because subtransaction commit is never WAL logged.
5602  */
5603 static void
xact_redo_abort(xl_xact_parsed_abort * parsed,TransactionId xid,XLogRecPtr lsn)5604 xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid,
5605 				XLogRecPtr lsn)
5606 {
5607 	TransactionId max_xid;
5608 
5609 	Assert(TransactionIdIsValid(xid));
5610 
5611 	/*
5612 	 * Make sure nextXid is beyond any XID mentioned in the record.
5613 	 *
5614 	 * We don't expect anyone else to modify nextXid, hence we don't need to
5615 	 * hold a lock while checking this. We still acquire the lock to modify
5616 	 * it, though.
5617 	 */
5618 	max_xid = TransactionIdLatest(xid,
5619 								  parsed->nsubxacts,
5620 								  parsed->subxacts);
5621 
5622 	if (TransactionIdFollowsOrEquals(max_xid,
5623 									 ShmemVariableCache->nextXid))
5624 	{
5625 		LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
5626 		ShmemVariableCache->nextXid = max_xid;
5627 		TransactionIdAdvance(ShmemVariableCache->nextXid);
5628 		LWLockRelease(XidGenLock);
5629 	}
5630 
5631 	if (standbyState == STANDBY_DISABLED)
5632 	{
5633 		/* Mark the transaction aborted in pg_xact, no need for async stuff */
5634 		TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
5635 	}
5636 	else
5637 	{
5638 		/*
5639 		 * If a transaction completion record arrives that has as-yet
5640 		 * unobserved subtransactions then this will not have been fully
5641 		 * handled by the call to RecordKnownAssignedTransactionIds() in the
5642 		 * main recovery loop in xlog.c. So we need to do bookkeeping again to
5643 		 * cover that case. This is confusing and it is easy to think this
5644 		 * call is irrelevant, which has happened three times in development
5645 		 * already. Leave it in.
5646 		 */
5647 		RecordKnownAssignedTransactionIds(max_xid);
5648 
5649 		/* Mark the transaction aborted in pg_xact, no need for async stuff */
5650 		TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
5651 
5652 		/*
5653 		 * We must update the ProcArray after we have marked clog.
5654 		 */
5655 		ExpireTreeKnownAssignedTransactionIds(
5656 											  xid, parsed->nsubxacts, parsed->subxacts, max_xid);
5657 
5658 		/*
5659 		 * There are no invalidation messages to send or undo.
5660 		 */
5661 
5662 		/*
5663 		 * Release locks, if any. There are no invalidations to send.
5664 		 */
5665 		if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
5666 			StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
5667 	}
5668 
5669 	/* Make sure files supposed to be dropped are dropped */
5670 	if (parsed->nrels > 0)
5671 	{
5672 		/*
5673 		 * See comments about update of minimum recovery point on truncation,
5674 		 * in xact_redo_commit().
5675 		 */
5676 		XLogFlush(lsn);
5677 
5678 		DropRelationFiles(parsed->xnodes, parsed->nrels, true);
5679 	}
5680 }
5681 
5682 void
xact_redo(XLogReaderState * record)5683 xact_redo(XLogReaderState *record)
5684 {
5685 	uint8		info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
5686 
5687 	/* Backup blocks are not used in xact records */
5688 	Assert(!XLogRecHasAnyBlockRefs(record));
5689 
5690 	if (info == XLOG_XACT_COMMIT)
5691 	{
5692 		xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
5693 		xl_xact_parsed_commit parsed;
5694 
5695 		ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
5696 		xact_redo_commit(&parsed, XLogRecGetXid(record),
5697 						 record->EndRecPtr, XLogRecGetOrigin(record));
5698 	}
5699 	else if (info == XLOG_XACT_COMMIT_PREPARED)
5700 	{
5701 		xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
5702 		xl_xact_parsed_commit parsed;
5703 
5704 		ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
5705 		xact_redo_commit(&parsed, parsed.twophase_xid,
5706 						 record->EndRecPtr, XLogRecGetOrigin(record));
5707 
5708 		/* Delete TwoPhaseState gxact entry and/or 2PC file. */
5709 		LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5710 		PrepareRedoRemove(parsed.twophase_xid, false);
5711 		LWLockRelease(TwoPhaseStateLock);
5712 	}
5713 	else if (info == XLOG_XACT_ABORT)
5714 	{
5715 		xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
5716 		xl_xact_parsed_abort parsed;
5717 
5718 		ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
5719 		xact_redo_abort(&parsed, XLogRecGetXid(record), record->EndRecPtr);
5720 	}
5721 	else if (info == XLOG_XACT_ABORT_PREPARED)
5722 	{
5723 		xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
5724 		xl_xact_parsed_abort parsed;
5725 
5726 		ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
5727 		xact_redo_abort(&parsed, parsed.twophase_xid, record->EndRecPtr);
5728 
5729 		/* Delete TwoPhaseState gxact entry and/or 2PC file. */
5730 		LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5731 		PrepareRedoRemove(parsed.twophase_xid, false);
5732 		LWLockRelease(TwoPhaseStateLock);
5733 	}
5734 	else if (info == XLOG_XACT_PREPARE)
5735 	{
5736 		/*
5737 		 * Store xid and start/end pointers of the WAL record in TwoPhaseState
5738 		 * gxact entry.
5739 		 */
5740 		LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
5741 		PrepareRedoAdd(XLogRecGetData(record),
5742 					   record->ReadRecPtr,
5743 					   record->EndRecPtr);
5744 		LWLockRelease(TwoPhaseStateLock);
5745 	}
5746 	else if (info == XLOG_XACT_ASSIGNMENT)
5747 	{
5748 		xl_xact_assignment *xlrec = (xl_xact_assignment *) XLogRecGetData(record);
5749 
5750 		if (standbyState >= STANDBY_INITIALIZED)
5751 			ProcArrayApplyXidAssignment(xlrec->xtop,
5752 										xlrec->nsubxacts, xlrec->xsub);
5753 	}
5754 	else
5755 		elog(PANIC, "xact_redo: unknown op code %u", info);
5756 }
5757