Coverage Report

Created: 2025-07-03 06:49

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