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