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