Coverage Report

Created: 2026-08-13 07:12

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