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