PostgreSQL Source Code  git master
snapmgr.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * snapmgr.c
4  * PostgreSQL snapshot manager
5  *
6  * We keep track of snapshots in two ways: those "registered" by resowner.c,
7  * and the "active snapshot" stack. All snapshots in either of them live in
8  * persistent memory. When a snapshot is no longer in any of these lists
9  * (tracked by separate refcounts on each snapshot), its memory can be freed.
10  *
11  * The FirstXactSnapshot, if any, is treated a bit specially: we increment its
12  * regd_count and list it in RegisteredSnapshots, but this reference is not
13  * tracked by a resource owner. We used to use the TopTransactionResourceOwner
14  * to track this snapshot reference, but that introduces logical circularity
15  * and thus makes it impossible to clean up in a sane fashion. It's better to
16  * handle this reference as an internally-tracked registration, so that this
17  * module is entirely lower-level than ResourceOwners.
18  *
19  * Likewise, any snapshots that have been exported by pg_export_snapshot
20  * have regd_count = 1 and are listed in RegisteredSnapshots, but are not
21  * tracked by any resource owner.
22  *
23  * Likewise, the CatalogSnapshot is listed in RegisteredSnapshots when it
24  * is valid, but is not tracked by any resource owner.
25  *
26  * The same is true for historic snapshots used during logical decoding,
27  * their lifetime is managed separately (as they live longer than one xact.c
28  * transaction).
29  *
30  * These arrangements let us reset MyProc->xmin when there are no snapshots
31  * referenced by this transaction, and advance it when the one with oldest
32  * Xmin is no longer referenced. For simplicity however, only registered
33  * snapshots not active snapshots participate in tracking which one is oldest;
34  * we don't try to change MyProc->xmin except when the active-snapshot
35  * stack is empty.
36  *
37  *
38  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
39  * Portions Copyright (c) 1994, Regents of the University of California
40  *
41  * IDENTIFICATION
42  * src/backend/utils/time/snapmgr.c
43  *
44  *-------------------------------------------------------------------------
45  */
46 #include "postgres.h"
47 
48 #include <sys/stat.h>
49 #include <unistd.h>
50 
51 #include "access/subtrans.h"
52 #include "access/transam.h"
53 #include "access/xact.h"
54 #include "access/xlog.h"
55 #include "catalog/catalog.h"
56 #include "datatype/timestamp.h"
57 #include "lib/pairingheap.h"
58 #include "miscadmin.h"
59 #include "port/pg_lfind.h"
60 #include "storage/fd.h"
61 #include "storage/predicate.h"
62 #include "storage/proc.h"
63 #include "storage/procarray.h"
64 #include "storage/sinval.h"
65 #include "storage/sinvaladt.h"
66 #include "storage/spin.h"
67 #include "utils/builtins.h"
68 #include "utils/memutils.h"
69 #include "utils/rel.h"
70 #include "utils/resowner.h"
71 #include "utils/snapmgr.h"
72 #include "utils/syscache.h"
73 #include "utils/timestamp.h"
74 
75 
76 /*
77  * CurrentSnapshot points to the only snapshot taken in transaction-snapshot
78  * mode, and to the latest one taken in a read-committed transaction.
79  * SecondarySnapshot is a snapshot that's always up-to-date as of the current
80  * instant, even in transaction-snapshot mode. It should only be used for
81  * special-purpose code (say, RI checking.) CatalogSnapshot points to an
82  * MVCC snapshot intended to be used for catalog scans; we must invalidate it
83  * whenever a system catalog change occurs.
84  *
85  * These SnapshotData structs are static to simplify memory allocation
86  * (see the hack in GetSnapshotData to avoid repeated malloc/free).
87  */
93 
94 /* Pointers to valid snapshots */
95 static Snapshot CurrentSnapshot = NULL;
97 static Snapshot CatalogSnapshot = NULL;
98 static Snapshot HistoricSnapshot = NULL;
99 
100 /*
101  * These are updated by GetSnapshotData. We initialize them this way
102  * for the convenience of TransactionIdIsInProgress: even in bootstrap
103  * mode, we don't want it to say that BootstrapTransactionId is in progress.
104  */
107 
108 /* (table, ctid) => (cmin, cmax) mapping during timetravel */
109 static HTAB *tuplecid_data = NULL;
110 
111 /*
112  * Elements of the active snapshot stack.
113  *
114  * Each element here accounts for exactly one active_count on SnapshotData.
115  *
116  * NB: the code assumes that elements in this list are in non-increasing
117  * order of as_level; also, the list must be NULL-terminated.
118  */
119 typedef struct ActiveSnapshotElt
120 {
122  int as_level;
125 
126 /* Top of the stack of active snapshots */
128 
129 /* Bottom of the stack of active snapshots */
131 
132 /*
133  * Currently registered Snapshots. Ordered in a heap by xmin, so that we can
134  * quickly find the one with lowest xmin, to advance our MyProc->xmin.
135  */
136 static int xmin_cmp(const pairingheap_node *a, const pairingheap_node *b,
137  void *arg);
138 
139 static pairingheap RegisteredSnapshots = {&xmin_cmp, NULL, NULL};
140 
141 /* first GetTransactionSnapshot call in a transaction? */
142 bool FirstSnapshotSet = false;
143 
144 /*
145  * Remember the serializable transaction snapshot, if any. We cannot trust
146  * FirstSnapshotSet in combination with IsolationUsesXactSnapshot(), because
147  * GUC may be reset before us, changing the value of IsolationUsesXactSnapshot.
148  */
150 
151 /* Define pathname of exported-snapshot files */
152 #define SNAPSHOT_EXPORT_DIR "pg_snapshots"
153 
154 /* Structure holding info about exported snapshot. */
155 typedef struct ExportedSnapshot
156 {
157  char *snapfile;
160 
161 /* Current xact's exported snapshots (a list of ExportedSnapshot structs) */
163 
164 /* Prototypes for local functions */
165 static Snapshot CopySnapshot(Snapshot snapshot);
166 static void UnregisterSnapshotNoOwner(Snapshot snapshot);
167 static void FreeSnapshot(Snapshot snapshot);
168 static void SnapshotResetXmin(void);
169 
170 /* ResourceOwner callbacks to track snapshot references */
171 static void ResOwnerReleaseSnapshot(Datum res);
172 
174 {
175  .name = "snapshot reference",
176  .release_phase = RESOURCE_RELEASE_AFTER_LOCKS,
177  .release_priority = RELEASE_PRIO_SNAPSHOT_REFS,
178  .ReleaseResource = ResOwnerReleaseSnapshot,
179  .DebugPrint = NULL /* the default message is fine */
180 };
181 
182 /* Convenience wrappers over ResourceOwnerRemember/Forget */
183 static inline void
185 {
187 }
188 static inline void
190 {
192 }
193 
194 /*
195  * Snapshot fields to be serialized.
196  *
197  * Only these fields need to be sent to the cooperating backend; the
198  * remaining ones can (and must) be set by the receiver upon restore.
199  */
201 {
212 
213 /*
214  * GetTransactionSnapshot
215  * Get the appropriate snapshot for a new query in a transaction.
216  *
217  * Note that the return value may point at static storage that will be modified
218  * by future calls and by CommandCounterIncrement(). Callers should call
219  * RegisterSnapshot or PushActiveSnapshot on the returned snap if it is to be
220  * used very long.
221  */
222 Snapshot
224 {
225  /*
226  * Return historic snapshot if doing logical decoding. We'll never need a
227  * non-historic transaction snapshot in this (sub-)transaction, so there's
228  * no need to be careful to set one up for later calls to
229  * GetTransactionSnapshot().
230  */
232  {
234  return HistoricSnapshot;
235  }
236 
237  /* First call in transaction? */
238  if (!FirstSnapshotSet)
239  {
240  /*
241  * Don't allow catalog snapshot to be older than xact snapshot. Must
242  * do this first to allow the empty-heap Assert to succeed.
243  */
245 
247  Assert(FirstXactSnapshot == NULL);
248 
249  if (IsInParallelMode())
250  elog(ERROR,
251  "cannot take query snapshot during a parallel operation");
252 
253  /*
254  * In transaction-snapshot mode, the first snapshot must live until
255  * end of xact regardless of what the caller does with it, so we must
256  * make a copy of it rather than returning CurrentSnapshotData
257  * directly. Furthermore, if we're running in serializable mode,
258  * predicate.c needs to wrap the snapshot fetch in its own processing.
259  */
261  {
262  /* First, create the snapshot in CurrentSnapshotData */
265  else
267  /* Make a saved copy */
270  /* Mark it as "registered" in FirstXactSnapshot */
273  }
274  else
276 
277  FirstSnapshotSet = true;
278  return CurrentSnapshot;
279  }
280 
282  return CurrentSnapshot;
283 
284  /* Don't allow catalog snapshot to be older than xact snapshot. */
286 
288 
289  return CurrentSnapshot;
290 }
291 
292 /*
293  * GetLatestSnapshot
294  * Get a snapshot that is up-to-date as of the current instant,
295  * even if we are executing in transaction-snapshot mode.
296  */
297 Snapshot
299 {
300  /*
301  * We might be able to relax this, but nothing that could otherwise work
302  * needs it.
303  */
304  if (IsInParallelMode())
305  elog(ERROR,
306  "cannot update SecondarySnapshot during a parallel operation");
307 
308  /*
309  * So far there are no cases requiring support for GetLatestSnapshot()
310  * during logical decoding, but it wouldn't be hard to add if required.
311  */
313 
314  /* If first call in transaction, go ahead and set the xact snapshot */
315  if (!FirstSnapshotSet)
316  return GetTransactionSnapshot();
317 
319 
320  return SecondarySnapshot;
321 }
322 
323 /*
324  * GetOldestSnapshot
325  *
326  * Get the transaction's oldest known snapshot, as judged by the LSN.
327  * Will return NULL if there are no active or registered snapshots.
328  */
329 Snapshot
331 {
332  Snapshot OldestRegisteredSnapshot = NULL;
333  XLogRecPtr RegisteredLSN = InvalidXLogRecPtr;
334 
336  {
337  OldestRegisteredSnapshot = pairingheap_container(SnapshotData, ph_node,
339  RegisteredLSN = OldestRegisteredSnapshot->lsn;
340  }
341 
342  if (OldestActiveSnapshot != NULL)
343  {
345 
346  if (XLogRecPtrIsInvalid(RegisteredLSN) || RegisteredLSN > ActiveLSN)
348  }
349 
350  return OldestRegisteredSnapshot;
351 }
352 
353 /*
354  * GetCatalogSnapshot
355  * Get a snapshot that is sufficiently up-to-date for scan of the
356  * system catalog with the specified OID.
357  */
358 Snapshot
360 {
361  /*
362  * Return historic snapshot while we're doing logical decoding, so we can
363  * see the appropriate state of the catalog.
364  *
365  * This is the primary reason for needing to reset the system caches after
366  * finishing decoding.
367  */
369  return HistoricSnapshot;
370 
371  return GetNonHistoricCatalogSnapshot(relid);
372 }
373 
374 /*
375  * GetNonHistoricCatalogSnapshot
376  * Get a snapshot that is sufficiently up-to-date for scan of the system
377  * catalog with the specified OID, even while historic snapshots are set
378  * up.
379  */
380 Snapshot
382 {
383  /*
384  * If the caller is trying to scan a relation that has no syscache, no
385  * catcache invalidations will be sent when it is updated. For a few key
386  * relations, snapshot invalidations are sent instead. If we're trying to
387  * scan a relation for which neither catcache nor snapshot invalidations
388  * are sent, we must refresh the snapshot every time.
389  */
390  if (CatalogSnapshot &&
392  !RelationHasSysCache(relid))
394 
395  if (CatalogSnapshot == NULL)
396  {
397  /* Get new snapshot. */
399 
400  /*
401  * Make sure the catalog snapshot will be accounted for in decisions
402  * about advancing PGPROC->xmin. We could apply RegisterSnapshot, but
403  * that would result in making a physical copy, which is overkill; and
404  * it would also create a dependency on some resource owner, which we
405  * do not want for reasons explained at the head of this file. Instead
406  * just shove the CatalogSnapshot into the pairing heap manually. This
407  * has to be reversed in InvalidateCatalogSnapshot, of course.
408  *
409  * NB: it had better be impossible for this to throw error, since the
410  * CatalogSnapshot pointer is already valid.
411  */
413  }
414 
415  return CatalogSnapshot;
416 }
417 
418 /*
419  * InvalidateCatalogSnapshot
420  * Mark the current catalog snapshot, if any, as invalid
421  *
422  * We could change this API to allow the caller to provide more fine-grained
423  * invalidation details, so that a change to relation A wouldn't prevent us
424  * from using our cached snapshot to scan relation B, but so far there's no
425  * evidence that the CPU cycles we spent tracking such fine details would be
426  * well-spent.
427  */
428 void
430 {
431  if (CatalogSnapshot)
432  {
434  CatalogSnapshot = NULL;
436  }
437 }
438 
439 /*
440  * InvalidateCatalogSnapshotConditionally
441  * Drop catalog snapshot if it's the only one we have
442  *
443  * This is called when we are about to wait for client input, so we don't
444  * want to continue holding the catalog snapshot if it might mean that the
445  * global xmin horizon can't advance. However, if there are other snapshots
446  * still active or registered, the catalog snapshot isn't likely to be the
447  * oldest one, so we might as well keep it.
448  */
449 void
451 {
452  if (CatalogSnapshot &&
453  ActiveSnapshot == NULL &&
456 }
457 
458 /*
459  * SnapshotSetCommandId
460  * Propagate CommandCounterIncrement into the static snapshots, if set
461  */
462 void
464 {
465  if (!FirstSnapshotSet)
466  return;
467 
468  if (CurrentSnapshot)
469  CurrentSnapshot->curcid = curcid;
470  if (SecondarySnapshot)
471  SecondarySnapshot->curcid = curcid;
472  /* Should we do the same with CatalogSnapshot? */
473 }
474 
475 /*
476  * SetTransactionSnapshot
477  * Set the transaction's snapshot from an imported MVCC snapshot.
478  *
479  * Note that this is very closely tied to GetTransactionSnapshot --- it
480  * must take care of all the same considerations as the first-snapshot case
481  * in GetTransactionSnapshot.
482  */
483 static void
485  int sourcepid, PGPROC *sourceproc)
486 {
487  /* Caller should have checked this already */
489 
490  /* Better do this to ensure following Assert succeeds. */
492 
494  Assert(FirstXactSnapshot == NULL);
496 
497  /*
498  * Even though we are not going to use the snapshot it computes, we must
499  * call GetSnapshotData, for two reasons: (1) to be sure that
500  * CurrentSnapshotData's XID arrays have been allocated, and (2) to update
501  * the state for GlobalVis*.
502  */
504 
505  /*
506  * Now copy appropriate fields from the source snapshot.
507  */
508  CurrentSnapshot->xmin = sourcesnap->xmin;
509  CurrentSnapshot->xmax = sourcesnap->xmax;
510  CurrentSnapshot->xcnt = sourcesnap->xcnt;
511  Assert(sourcesnap->xcnt <= GetMaxSnapshotXidCount());
512  if (sourcesnap->xcnt > 0)
513  memcpy(CurrentSnapshot->xip, sourcesnap->xip,
514  sourcesnap->xcnt * sizeof(TransactionId));
515  CurrentSnapshot->subxcnt = sourcesnap->subxcnt;
516  Assert(sourcesnap->subxcnt <= GetMaxSnapshotSubxidCount());
517  if (sourcesnap->subxcnt > 0)
518  memcpy(CurrentSnapshot->subxip, sourcesnap->subxip,
519  sourcesnap->subxcnt * sizeof(TransactionId));
522  /* NB: curcid should NOT be copied, it's a local matter */
523 
525 
526  /*
527  * Now we have to fix what GetSnapshotData did with MyProc->xmin and
528  * TransactionXmin. There is a race condition: to make sure we are not
529  * causing the global xmin to go backwards, we have to test that the
530  * source transaction is still running, and that has to be done
531  * atomically. So let procarray.c do it.
532  *
533  * Note: in serializable mode, predicate.c will do this a second time. It
534  * doesn't seem worth contorting the logic here to avoid two calls,
535  * especially since it's not clear that predicate.c *must* do this.
536  */
537  if (sourceproc != NULL)
538  {
540  ereport(ERROR,
541  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
542  errmsg("could not import the requested snapshot"),
543  errdetail("The source transaction is not running anymore.")));
544  }
545  else if (!ProcArrayInstallImportedXmin(CurrentSnapshot->xmin, sourcevxid))
546  ereport(ERROR,
547  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
548  errmsg("could not import the requested snapshot"),
549  errdetail("The source process with PID %d is not running anymore.",
550  sourcepid)));
551 
552  /*
553  * In transaction-snapshot mode, the first snapshot must live until end of
554  * xact, so we must make a copy of it. Furthermore, if we're running in
555  * serializable mode, predicate.c needs to do its own processing.
556  */
558  {
561  sourcepid);
562  /* Make a saved copy */
565  /* Mark it as "registered" in FirstXactSnapshot */
568  }
569 
570  FirstSnapshotSet = true;
571 }
572 
573 /*
574  * CopySnapshot
575  * Copy the given snapshot.
576  *
577  * The copy is palloc'd in TopTransactionContext and has initial refcounts set
578  * to 0. The returned snapshot has the copied flag set.
579  */
580 static Snapshot
582 {
583  Snapshot newsnap;
584  Size subxipoff;
585  Size size;
586 
587  Assert(snapshot != InvalidSnapshot);
588 
589  /* We allocate any XID arrays needed in the same palloc block. */
590  size = subxipoff = sizeof(SnapshotData) +
591  snapshot->xcnt * sizeof(TransactionId);
592  if (snapshot->subxcnt > 0)
593  size += snapshot->subxcnt * sizeof(TransactionId);
594 
596  memcpy(newsnap, snapshot, sizeof(SnapshotData));
597 
598  newsnap->regd_count = 0;
599  newsnap->active_count = 0;
600  newsnap->copied = true;
601  newsnap->snapXactCompletionCount = 0;
602 
603  /* setup XID array */
604  if (snapshot->xcnt > 0)
605  {
606  newsnap->xip = (TransactionId *) (newsnap + 1);
607  memcpy(newsnap->xip, snapshot->xip,
608  snapshot->xcnt * sizeof(TransactionId));
609  }
610  else
611  newsnap->xip = NULL;
612 
613  /*
614  * Setup subXID array. Don't bother to copy it if it had overflowed,
615  * though, because it's not used anywhere in that case. Except if it's a
616  * snapshot taken during recovery; all the top-level XIDs are in subxip as
617  * well in that case, so we mustn't lose them.
618  */
619  if (snapshot->subxcnt > 0 &&
620  (!snapshot->suboverflowed || snapshot->takenDuringRecovery))
621  {
622  newsnap->subxip = (TransactionId *) ((char *) newsnap + subxipoff);
623  memcpy(newsnap->subxip, snapshot->subxip,
624  snapshot->subxcnt * sizeof(TransactionId));
625  }
626  else
627  newsnap->subxip = NULL;
628 
629  return newsnap;
630 }
631 
632 /*
633  * FreeSnapshot
634  * Free the memory associated with a snapshot.
635  */
636 static void
638 {
639  Assert(snapshot->regd_count == 0);
640  Assert(snapshot->active_count == 0);
641  Assert(snapshot->copied);
642 
643  pfree(snapshot);
644 }
645 
646 /*
647  * PushActiveSnapshot
648  * Set the given snapshot as the current active snapshot
649  *
650  * If the passed snapshot is a statically-allocated one, or it is possibly
651  * subject to a future command counter update, create a new long-lived copy
652  * with active refcount=1. Otherwise, only increment the refcount.
653  */
654 void
656 {
658 }
659 
660 /*
661  * PushActiveSnapshotWithLevel
662  * Set the given snapshot as the current active snapshot
663  *
664  * Same as PushActiveSnapshot except that caller can specify the
665  * transaction nesting level that "owns" the snapshot. This level
666  * must not be deeper than the current top of the snapshot stack.
667  */
668 void
669 PushActiveSnapshotWithLevel(Snapshot snapshot, int snap_level)
670 {
671  ActiveSnapshotElt *newactive;
672 
673  Assert(snapshot != InvalidSnapshot);
674  Assert(ActiveSnapshot == NULL || snap_level >= ActiveSnapshot->as_level);
675 
677 
678  /*
679  * Checking SecondarySnapshot is probably useless here, but it seems
680  * better to be sure.
681  */
682  if (snapshot == CurrentSnapshot || snapshot == SecondarySnapshot ||
683  !snapshot->copied)
684  newactive->as_snap = CopySnapshot(snapshot);
685  else
686  newactive->as_snap = snapshot;
687 
688  newactive->as_next = ActiveSnapshot;
689  newactive->as_level = snap_level;
690 
691  newactive->as_snap->active_count++;
692 
693  ActiveSnapshot = newactive;
694  if (OldestActiveSnapshot == NULL)
696 }
697 
698 /*
699  * PushCopiedSnapshot
700  * As above, except forcibly copy the presented snapshot.
701  *
702  * This should be used when the ActiveSnapshot has to be modifiable, for
703  * example if the caller intends to call UpdateActiveSnapshotCommandId.
704  * The new snapshot will be released when popped from the stack.
705  */
706 void
708 {
709  PushActiveSnapshot(CopySnapshot(snapshot));
710 }
711 
712 /*
713  * UpdateActiveSnapshotCommandId
714  *
715  * Update the current CID of the active snapshot. This can only be applied
716  * to a snapshot that is not referenced elsewhere.
717  */
718 void
720 {
721  CommandId save_curcid,
722  curcid;
723 
724  Assert(ActiveSnapshot != NULL);
727 
728  /*
729  * Don't allow modification of the active snapshot during parallel
730  * operation. We share the snapshot to worker backends at the beginning
731  * of parallel operation, so any change to the snapshot can lead to
732  * inconsistencies. We have other defenses against
733  * CommandCounterIncrement, but there are a few places that call this
734  * directly, so we put an additional guard here.
735  */
736  save_curcid = ActiveSnapshot->as_snap->curcid;
737  curcid = GetCurrentCommandId(false);
738  if (IsInParallelMode() && save_curcid != curcid)
739  elog(ERROR, "cannot modify commandid in active snapshot during a parallel operation");
740  ActiveSnapshot->as_snap->curcid = curcid;
741 }
742 
743 /*
744  * PopActiveSnapshot
745  *
746  * Remove the topmost snapshot from the active snapshot stack, decrementing the
747  * reference count, and free it if this was the last reference.
748  */
749 void
751 {
752  ActiveSnapshotElt *newstack;
753 
754  newstack = ActiveSnapshot->as_next;
755 
757 
759 
760  if (ActiveSnapshot->as_snap->active_count == 0 &&
763 
765  ActiveSnapshot = newstack;
766  if (ActiveSnapshot == NULL)
767  OldestActiveSnapshot = NULL;
768 
770 }
771 
772 /*
773  * GetActiveSnapshot
774  * Return the topmost snapshot in the Active stack.
775  */
776 Snapshot
778 {
779  Assert(ActiveSnapshot != NULL);
780 
781  return ActiveSnapshot->as_snap;
782 }
783 
784 /*
785  * ActiveSnapshotSet
786  * Return whether there is at least one snapshot in the Active stack
787  */
788 bool
790 {
791  return ActiveSnapshot != NULL;
792 }
793 
794 /*
795  * RegisterSnapshot
796  * Register a snapshot as being in use by the current resource owner
797  *
798  * If InvalidSnapshot is passed, it is not registered.
799  */
800 Snapshot
802 {
803  if (snapshot == InvalidSnapshot)
804  return InvalidSnapshot;
805 
807 }
808 
809 /*
810  * RegisterSnapshotOnOwner
811  * As above, but use the specified resource owner
812  */
813 Snapshot
815 {
816  Snapshot snap;
817 
818  if (snapshot == InvalidSnapshot)
819  return InvalidSnapshot;
820 
821  /* Static snapshot? Create a persistent copy */
822  snap = snapshot->copied ? snapshot : CopySnapshot(snapshot);
823 
824  /* and tell resowner.c about it */
825  ResourceOwnerEnlarge(owner);
826  snap->regd_count++;
827  ResourceOwnerRememberSnapshot(owner, snap);
828 
829  if (snap->regd_count == 1)
831 
832  return snap;
833 }
834 
835 /*
836  * UnregisterSnapshot
837  *
838  * Decrement the reference count of a snapshot, remove the corresponding
839  * reference from CurrentResourceOwner, and free the snapshot if no more
840  * references remain.
841  */
842 void
844 {
845  if (snapshot == NULL)
846  return;
847 
849 }
850 
851 /*
852  * UnregisterSnapshotFromOwner
853  * As above, but use the specified resource owner
854  */
855 void
857 {
858  if (snapshot == NULL)
859  return;
860 
861  ResourceOwnerForgetSnapshot(owner, snapshot);
862  UnregisterSnapshotNoOwner(snapshot);
863 }
864 
865 static void
867 {
868  Assert(snapshot->regd_count > 0);
870 
871  snapshot->regd_count--;
872  if (snapshot->regd_count == 0)
874 
875  if (snapshot->regd_count == 0 && snapshot->active_count == 0)
876  {
877  FreeSnapshot(snapshot);
879  }
880 }
881 
882 /*
883  * Comparison function for RegisteredSnapshots heap. Snapshots are ordered
884  * by xmin, so that the snapshot with smallest xmin is at the top.
885  */
886 static int
888 {
889  const SnapshotData *asnap = pairingheap_const_container(SnapshotData, ph_node, a);
890  const SnapshotData *bsnap = pairingheap_const_container(SnapshotData, ph_node, b);
891 
892  if (TransactionIdPrecedes(asnap->xmin, bsnap->xmin))
893  return 1;
894  else if (TransactionIdFollows(asnap->xmin, bsnap->xmin))
895  return -1;
896  else
897  return 0;
898 }
899 
900 /*
901  * SnapshotResetXmin
902  *
903  * If there are no more snapshots, we can reset our PGPROC->xmin to
904  * InvalidTransactionId. Note we can do this without locking because we assume
905  * that storing an Xid is atomic.
906  *
907  * Even if there are some remaining snapshots, we may be able to advance our
908  * PGPROC->xmin to some degree. This typically happens when a portal is
909  * dropped. For efficiency, we only consider recomputing PGPROC->xmin when
910  * the active snapshot stack is empty; this allows us not to need to track
911  * which active snapshot is oldest.
912  *
913  * Note: it's tempting to use GetOldestSnapshot() here so that we can include
914  * active snapshots in the calculation. However, that compares by LSN not
915  * xmin so it's not entirely clear that it's the same thing. Also, we'd be
916  * critically dependent on the assumption that the bottommost active snapshot
917  * stack entry has the oldest xmin. (Current uses of GetOldestSnapshot() are
918  * not actually critical, but this would be.)
919  */
920 static void
922 {
923  Snapshot minSnapshot;
924 
925  if (ActiveSnapshot != NULL)
926  return;
927 
929  {
931  return;
932  }
933 
934  minSnapshot = pairingheap_container(SnapshotData, ph_node,
936 
937  if (TransactionIdPrecedes(MyProc->xmin, minSnapshot->xmin))
938  MyProc->xmin = minSnapshot->xmin;
939 }
940 
941 /*
942  * AtSubCommit_Snapshot
943  */
944 void
946 {
947  ActiveSnapshotElt *active;
948 
949  /*
950  * Relabel the active snapshots set in this subtransaction as though they
951  * are owned by the parent subxact.
952  */
953  for (active = ActiveSnapshot; active != NULL; active = active->as_next)
954  {
955  if (active->as_level < level)
956  break;
957  active->as_level = level - 1;
958  }
959 }
960 
961 /*
962  * AtSubAbort_Snapshot
963  * Clean up snapshots after a subtransaction abort
964  */
965 void
967 {
968  /* Forget the active snapshots set by this subtransaction */
969  while (ActiveSnapshot && ActiveSnapshot->as_level >= level)
970  {
972 
974 
975  /*
976  * Decrement the snapshot's active count. If it's still registered or
977  * marked as active by an outer subtransaction, we can't free it yet.
978  */
981 
982  if (ActiveSnapshot->as_snap->active_count == 0 &&
985 
986  /* and free the stack element */
988 
990  if (ActiveSnapshot == NULL)
991  OldestActiveSnapshot = NULL;
992  }
993 
995 }
996 
997 /*
998  * AtEOXact_Snapshot
999  * Snapshot manager's cleanup function for end of transaction
1000  */
1001 void
1002 AtEOXact_Snapshot(bool isCommit, bool resetXmin)
1003 {
1004  /*
1005  * In transaction-snapshot mode we must release our privately-managed
1006  * reference to the transaction snapshot. We must remove it from
1007  * RegisteredSnapshots to keep the check below happy. But we don't bother
1008  * to do FreeSnapshot, for two reasons: the memory will go away with
1009  * TopTransactionContext anyway, and if someone has left the snapshot
1010  * stacked as active, we don't want the code below to be chasing through a
1011  * dangling pointer.
1012  */
1013  if (FirstXactSnapshot != NULL)
1014  {
1018  }
1019  FirstXactSnapshot = NULL;
1020 
1021  /*
1022  * If we exported any snapshots, clean them up.
1023  */
1024  if (exportedSnapshots != NIL)
1025  {
1026  ListCell *lc;
1027 
1028  /*
1029  * Get rid of the files. Unlink failure is only a WARNING because (1)
1030  * it's too late to abort the transaction, and (2) leaving a leaked
1031  * file around has little real consequence anyway.
1032  *
1033  * We also need to remove the snapshots from RegisteredSnapshots to
1034  * prevent a warning below.
1035  *
1036  * As with the FirstXactSnapshot, we don't need to free resources of
1037  * the snapshot itself as it will go away with the memory context.
1038  */
1039  foreach(lc, exportedSnapshots)
1040  {
1041  ExportedSnapshot *esnap = (ExportedSnapshot *) lfirst(lc);
1042 
1043  if (unlink(esnap->snapfile))
1044  elog(WARNING, "could not unlink file \"%s\": %m",
1045  esnap->snapfile);
1046 
1048  &esnap->snapshot->ph_node);
1049  }
1050 
1052  }
1053 
1054  /* Drop catalog snapshot if any */
1056 
1057  /* On commit, complain about leftover snapshots */
1058  if (isCommit)
1059  {
1060  ActiveSnapshotElt *active;
1061 
1063  elog(WARNING, "registered snapshots seem to remain after cleanup");
1064 
1065  /* complain about unpopped active snapshots */
1066  for (active = ActiveSnapshot; active != NULL; active = active->as_next)
1067  elog(WARNING, "snapshot %p still active", active);
1068  }
1069 
1070  /*
1071  * And reset our state. We don't need to free the memory explicitly --
1072  * it'll go away with TopTransactionContext.
1073  */
1074  ActiveSnapshot = NULL;
1075  OldestActiveSnapshot = NULL;
1077 
1078  CurrentSnapshot = NULL;
1079  SecondarySnapshot = NULL;
1080 
1081  FirstSnapshotSet = false;
1082 
1083  /*
1084  * During normal commit processing, we call ProcArrayEndTransaction() to
1085  * reset the MyProc->xmin. That call happens prior to the call to
1086  * AtEOXact_Snapshot(), so we need not touch xmin here at all.
1087  */
1088  if (resetXmin)
1090 
1091  Assert(resetXmin || MyProc->xmin == 0);
1092 }
1093 
1094 
1095 /*
1096  * ExportSnapshot
1097  * Export the snapshot to a file so that other backends can import it.
1098  * Returns the token (the file name) that can be used to import this
1099  * snapshot.
1100  */
1101 char *
1103 {
1104  TransactionId topXid;
1105  TransactionId *children;
1106  ExportedSnapshot *esnap;
1107  int nchildren;
1108  int addTopXid;
1110  FILE *f;
1111  int i;
1112  MemoryContext oldcxt;
1113  char path[MAXPGPATH];
1114  char pathtmp[MAXPGPATH];
1115 
1116  /*
1117  * It's tempting to call RequireTransactionBlock here, since it's not very
1118  * useful to export a snapshot that will disappear immediately afterwards.
1119  * However, we haven't got enough information to do that, since we don't
1120  * know if we're at top level or not. For example, we could be inside a
1121  * plpgsql function that is going to fire off other transactions via
1122  * dblink. Rather than disallow perfectly legitimate usages, don't make a
1123  * check.
1124  *
1125  * Also note that we don't make any restriction on the transaction's
1126  * isolation level; however, importers must check the level if they are
1127  * serializable.
1128  */
1129 
1130  /*
1131  * Get our transaction ID if there is one, to include in the snapshot.
1132  */
1133  topXid = GetTopTransactionIdIfAny();
1134 
1135  /*
1136  * We cannot export a snapshot from a subtransaction because there's no
1137  * easy way for importers to verify that the same subtransaction is still
1138  * running.
1139  */
1140  if (IsSubTransaction())
1141  ereport(ERROR,
1142  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
1143  errmsg("cannot export a snapshot from a subtransaction")));
1144 
1145  /*
1146  * We do however allow previous committed subtransactions to exist.
1147  * Importers of the snapshot must see them as still running, so get their
1148  * XIDs to add them to the snapshot.
1149  */
1150  nchildren = xactGetCommittedChildren(&children);
1151 
1152  /*
1153  * Generate file path for the snapshot. We start numbering of snapshots
1154  * inside the transaction from 1.
1155  */
1156  snprintf(path, sizeof(path), SNAPSHOT_EXPORT_DIR "/%08X-%08X-%d",
1158 
1159  /*
1160  * Copy the snapshot into TopTransactionContext, add it to the
1161  * exportedSnapshots list, and mark it pseudo-registered. We do this to
1162  * ensure that the snapshot's xmin is honored for the rest of the
1163  * transaction.
1164  */
1165  snapshot = CopySnapshot(snapshot);
1166 
1168  esnap = (ExportedSnapshot *) palloc(sizeof(ExportedSnapshot));
1169  esnap->snapfile = pstrdup(path);
1170  esnap->snapshot = snapshot;
1172  MemoryContextSwitchTo(oldcxt);
1173 
1174  snapshot->regd_count++;
1176 
1177  /*
1178  * Fill buf with a text serialization of the snapshot, plus identification
1179  * data about this transaction. The format expected by ImportSnapshot is
1180  * pretty rigid: each line must be fieldname:value.
1181  */
1182  initStringInfo(&buf);
1183 
1184  appendStringInfo(&buf, "vxid:%d/%u\n", MyProc->backendId, MyProc->lxid);
1185  appendStringInfo(&buf, "pid:%d\n", MyProcPid);
1186  appendStringInfo(&buf, "dbid:%u\n", MyDatabaseId);
1187  appendStringInfo(&buf, "iso:%d\n", XactIsoLevel);
1188  appendStringInfo(&buf, "ro:%d\n", XactReadOnly);
1189 
1190  appendStringInfo(&buf, "xmin:%u\n", snapshot->xmin);
1191  appendStringInfo(&buf, "xmax:%u\n", snapshot->xmax);
1192 
1193  /*
1194  * We must include our own top transaction ID in the top-xid data, since
1195  * by definition we will still be running when the importing transaction
1196  * adopts the snapshot, but GetSnapshotData never includes our own XID in
1197  * the snapshot. (There must, therefore, be enough room to add it.)
1198  *
1199  * However, it could be that our topXid is after the xmax, in which case
1200  * we shouldn't include it because xip[] members are expected to be before
1201  * xmax. (We need not make the same check for subxip[] members, see
1202  * snapshot.h.)
1203  */
1204  addTopXid = (TransactionIdIsValid(topXid) &&
1205  TransactionIdPrecedes(topXid, snapshot->xmax)) ? 1 : 0;
1206  appendStringInfo(&buf, "xcnt:%d\n", snapshot->xcnt + addTopXid);
1207  for (i = 0; i < snapshot->xcnt; i++)
1208  appendStringInfo(&buf, "xip:%u\n", snapshot->xip[i]);
1209  if (addTopXid)
1210  appendStringInfo(&buf, "xip:%u\n", topXid);
1211 
1212  /*
1213  * Similarly, we add our subcommitted child XIDs to the subxid data. Here,
1214  * we have to cope with possible overflow.
1215  */
1216  if (snapshot->suboverflowed ||
1217  snapshot->subxcnt + nchildren > GetMaxSnapshotSubxidCount())
1218  appendStringInfoString(&buf, "sof:1\n");
1219  else
1220  {
1221  appendStringInfoString(&buf, "sof:0\n");
1222  appendStringInfo(&buf, "sxcnt:%d\n", snapshot->subxcnt + nchildren);
1223  for (i = 0; i < snapshot->subxcnt; i++)
1224  appendStringInfo(&buf, "sxp:%u\n", snapshot->subxip[i]);
1225  for (i = 0; i < nchildren; i++)
1226  appendStringInfo(&buf, "sxp:%u\n", children[i]);
1227  }
1228  appendStringInfo(&buf, "rec:%u\n", snapshot->takenDuringRecovery);
1229 
1230  /*
1231  * Now write the text representation into a file. We first write to a
1232  * ".tmp" filename, and rename to final filename if no error. This
1233  * ensures that no other backend can read an incomplete file
1234  * (ImportSnapshot won't allow it because of its valid-characters check).
1235  */
1236  snprintf(pathtmp, sizeof(pathtmp), "%s.tmp", path);
1237  if (!(f = AllocateFile(pathtmp, PG_BINARY_W)))
1238  ereport(ERROR,
1240  errmsg("could not create file \"%s\": %m", pathtmp)));
1241 
1242  if (fwrite(buf.data, buf.len, 1, f) != 1)
1243  ereport(ERROR,
1245  errmsg("could not write to file \"%s\": %m", pathtmp)));
1246 
1247  /* no fsync() since file need not survive a system crash */
1248 
1249  if (FreeFile(f))
1250  ereport(ERROR,
1252  errmsg("could not write to file \"%s\": %m", pathtmp)));
1253 
1254  /*
1255  * Now that we have written everything into a .tmp file, rename the file
1256  * to remove the .tmp suffix.
1257  */
1258  if (rename(pathtmp, path) < 0)
1259  ereport(ERROR,
1261  errmsg("could not rename file \"%s\" to \"%s\": %m",
1262  pathtmp, path)));
1263 
1264  /*
1265  * The basename of the file is what we return from pg_export_snapshot().
1266  * It's already in path in a textual format and we know that the path
1267  * starts with SNAPSHOT_EXPORT_DIR. Skip over the prefix and the slash
1268  * and pstrdup it so as not to return the address of a local variable.
1269  */
1270  return pstrdup(path + strlen(SNAPSHOT_EXPORT_DIR) + 1);
1271 }
1272 
1273 /*
1274  * pg_export_snapshot
1275  * SQL-callable wrapper for ExportSnapshot.
1276  */
1277 Datum
1279 {
1280  char *snapshotName;
1281 
1282  snapshotName = ExportSnapshot(GetActiveSnapshot());
1283  PG_RETURN_TEXT_P(cstring_to_text(snapshotName));
1284 }
1285 
1286 
1287 /*
1288  * Parsing subroutines for ImportSnapshot: parse a line with the given
1289  * prefix followed by a value, and advance *s to the next line. The
1290  * filename is provided for use in error messages.
1291  */
1292 static int
1293 parseIntFromText(const char *prefix, char **s, const char *filename)
1294 {
1295  char *ptr = *s;
1296  int prefixlen = strlen(prefix);
1297  int val;
1298 
1299  if (strncmp(ptr, prefix, prefixlen) != 0)
1300  ereport(ERROR,
1301  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1302  errmsg("invalid snapshot data in file \"%s\"", filename)));
1303  ptr += prefixlen;
1304  if (sscanf(ptr, "%d", &val) != 1)
1305  ereport(ERROR,
1306  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1307  errmsg("invalid snapshot data in file \"%s\"", filename)));
1308  ptr = strchr(ptr, '\n');
1309  if (!ptr)
1310  ereport(ERROR,
1311  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1312  errmsg("invalid snapshot data in file \"%s\"", filename)));
1313  *s = ptr + 1;
1314  return val;
1315 }
1316 
1317 static TransactionId
1318 parseXidFromText(const char *prefix, char **s, const char *filename)
1319 {
1320  char *ptr = *s;
1321  int prefixlen = strlen(prefix);
1323 
1324  if (strncmp(ptr, prefix, prefixlen) != 0)
1325  ereport(ERROR,
1326  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1327  errmsg("invalid snapshot data in file \"%s\"", filename)));
1328  ptr += prefixlen;
1329  if (sscanf(ptr, "%u", &val) != 1)
1330  ereport(ERROR,
1331  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1332  errmsg("invalid snapshot data in file \"%s\"", filename)));
1333  ptr = strchr(ptr, '\n');
1334  if (!ptr)
1335  ereport(ERROR,
1336  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1337  errmsg("invalid snapshot data in file \"%s\"", filename)));
1338  *s = ptr + 1;
1339  return val;
1340 }
1341 
1342 static void
1343 parseVxidFromText(const char *prefix, char **s, const char *filename,
1344  VirtualTransactionId *vxid)
1345 {
1346  char *ptr = *s;
1347  int prefixlen = strlen(prefix);
1348 
1349  if (strncmp(ptr, prefix, prefixlen) != 0)
1350  ereport(ERROR,
1351  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1352  errmsg("invalid snapshot data in file \"%s\"", filename)));
1353  ptr += prefixlen;
1354  if (sscanf(ptr, "%d/%u", &vxid->backendId, &vxid->localTransactionId) != 2)
1355  ereport(ERROR,
1356  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1357  errmsg("invalid snapshot data in file \"%s\"", filename)));
1358  ptr = strchr(ptr, '\n');
1359  if (!ptr)
1360  ereport(ERROR,
1361  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1362  errmsg("invalid snapshot data in file \"%s\"", filename)));
1363  *s = ptr + 1;
1364 }
1365 
1366 /*
1367  * ImportSnapshot
1368  * Import a previously exported snapshot. The argument should be a
1369  * filename in SNAPSHOT_EXPORT_DIR. Load the snapshot from that file.
1370  * This is called by "SET TRANSACTION SNAPSHOT 'foo'".
1371  */
1372 void
1373 ImportSnapshot(const char *idstr)
1374 {
1375  char path[MAXPGPATH];
1376  FILE *f;
1377  struct stat stat_buf;
1378  char *filebuf;
1379  int xcnt;
1380  int i;
1381  VirtualTransactionId src_vxid;
1382  int src_pid;
1383  Oid src_dbid;
1384  int src_isolevel;
1385  bool src_readonly;
1386  SnapshotData snapshot;
1387 
1388  /*
1389  * Must be at top level of a fresh transaction. Note in particular that
1390  * we check we haven't acquired an XID --- if we have, it's conceivable
1391  * that the snapshot would show it as not running, making for very screwy
1392  * behavior.
1393  */
1394  if (FirstSnapshotSet ||
1396  IsSubTransaction())
1397  ereport(ERROR,
1398  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
1399  errmsg("SET TRANSACTION SNAPSHOT must be called before any query")));
1400 
1401  /*
1402  * If we are in read committed mode then the next query would execute with
1403  * a new snapshot thus making this function call quite useless.
1404  */
1406  ereport(ERROR,
1407  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1408  errmsg("a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ")));
1409 
1410  /*
1411  * Verify the identifier: only 0-9, A-F and hyphens are allowed. We do
1412  * this mainly to prevent reading arbitrary files.
1413  */
1414  if (strspn(idstr, "0123456789ABCDEF-") != strlen(idstr))
1415  ereport(ERROR,
1416  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1417  errmsg("invalid snapshot identifier: \"%s\"", idstr)));
1418 
1419  /* OK, read the file */
1420  snprintf(path, MAXPGPATH, SNAPSHOT_EXPORT_DIR "/%s", idstr);
1421 
1422  f = AllocateFile(path, PG_BINARY_R);
1423  if (!f)
1424  {
1425  /*
1426  * If file is missing while identifier has a correct format, avoid
1427  * system errors.
1428  */
1429  if (errno == ENOENT)
1430  ereport(ERROR,
1431  (errcode(ERRCODE_UNDEFINED_OBJECT),
1432  errmsg("snapshot \"%s\" does not exist", idstr)));
1433  else
1434  ereport(ERROR,
1436  errmsg("could not open file \"%s\" for reading: %m",
1437  path)));
1438  }
1439 
1440  /* get the size of the file so that we know how much memory we need */
1441  if (fstat(fileno(f), &stat_buf))
1442  elog(ERROR, "could not stat file \"%s\": %m", path);
1443 
1444  /* and read the file into a palloc'd string */
1445  filebuf = (char *) palloc(stat_buf.st_size + 1);
1446  if (fread(filebuf, stat_buf.st_size, 1, f) != 1)
1447  elog(ERROR, "could not read file \"%s\": %m", path);
1448 
1449  filebuf[stat_buf.st_size] = '\0';
1450 
1451  FreeFile(f);
1452 
1453  /*
1454  * Construct a snapshot struct by parsing the file content.
1455  */
1456  memset(&snapshot, 0, sizeof(snapshot));
1457 
1458  parseVxidFromText("vxid:", &filebuf, path, &src_vxid);
1459  src_pid = parseIntFromText("pid:", &filebuf, path);
1460  /* we abuse parseXidFromText a bit here ... */
1461  src_dbid = parseXidFromText("dbid:", &filebuf, path);
1462  src_isolevel = parseIntFromText("iso:", &filebuf, path);
1463  src_readonly = parseIntFromText("ro:", &filebuf, path);
1464 
1465  snapshot.snapshot_type = SNAPSHOT_MVCC;
1466 
1467  snapshot.xmin = parseXidFromText("xmin:", &filebuf, path);
1468  snapshot.xmax = parseXidFromText("xmax:", &filebuf, path);
1469 
1470  snapshot.xcnt = xcnt = parseIntFromText("xcnt:", &filebuf, path);
1471 
1472  /* sanity-check the xid count before palloc */
1473  if (xcnt < 0 || xcnt > GetMaxSnapshotXidCount())
1474  ereport(ERROR,
1475  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1476  errmsg("invalid snapshot data in file \"%s\"", path)));
1477 
1478  snapshot.xip = (TransactionId *) palloc(xcnt * sizeof(TransactionId));
1479  for (i = 0; i < xcnt; i++)
1480  snapshot.xip[i] = parseXidFromText("xip:", &filebuf, path);
1481 
1482  snapshot.suboverflowed = parseIntFromText("sof:", &filebuf, path);
1483 
1484  if (!snapshot.suboverflowed)
1485  {
1486  snapshot.subxcnt = xcnt = parseIntFromText("sxcnt:", &filebuf, path);
1487 
1488  /* sanity-check the xid count before palloc */
1489  if (xcnt < 0 || xcnt > GetMaxSnapshotSubxidCount())
1490  ereport(ERROR,
1491  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1492  errmsg("invalid snapshot data in file \"%s\"", path)));
1493 
1494  snapshot.subxip = (TransactionId *) palloc(xcnt * sizeof(TransactionId));
1495  for (i = 0; i < xcnt; i++)
1496  snapshot.subxip[i] = parseXidFromText("sxp:", &filebuf, path);
1497  }
1498  else
1499  {
1500  snapshot.subxcnt = 0;
1501  snapshot.subxip = NULL;
1502  }
1503 
1504  snapshot.takenDuringRecovery = parseIntFromText("rec:", &filebuf, path);
1505 
1506  /*
1507  * Do some additional sanity checking, just to protect ourselves. We
1508  * don't trouble to check the array elements, just the most critical
1509  * fields.
1510  */
1511  if (!VirtualTransactionIdIsValid(src_vxid) ||
1512  !OidIsValid(src_dbid) ||
1513  !TransactionIdIsNormal(snapshot.xmin) ||
1514  !TransactionIdIsNormal(snapshot.xmax))
1515  ereport(ERROR,
1516  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1517  errmsg("invalid snapshot data in file \"%s\"", path)));
1518 
1519  /*
1520  * If we're serializable, the source transaction must be too, otherwise
1521  * predicate.c has problems (SxactGlobalXmin could go backwards). Also, a
1522  * non-read-only transaction can't adopt a snapshot from a read-only
1523  * transaction, as predicate.c handles the cases very differently.
1524  */
1526  {
1527  if (src_isolevel != XACT_SERIALIZABLE)
1528  ereport(ERROR,
1529  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1530  errmsg("a serializable transaction cannot import a snapshot from a non-serializable transaction")));
1531  if (src_readonly && !XactReadOnly)
1532  ereport(ERROR,
1533  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1534  errmsg("a non-read-only serializable transaction cannot import a snapshot from a read-only transaction")));
1535  }
1536 
1537  /*
1538  * We cannot import a snapshot that was taken in a different database,
1539  * because vacuum calculates OldestXmin on a per-database basis; so the
1540  * source transaction's xmin doesn't protect us from data loss. This
1541  * restriction could be removed if the source transaction were to mark its
1542  * xmin as being globally applicable. But that would require some
1543  * additional syntax, since that has to be known when the snapshot is
1544  * initially taken. (See pgsql-hackers discussion of 2011-10-21.)
1545  */
1546  if (src_dbid != MyDatabaseId)
1547  ereport(ERROR,
1548  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1549  errmsg("cannot import a snapshot from a different database")));
1550 
1551  /* OK, install the snapshot */
1552  SetTransactionSnapshot(&snapshot, &src_vxid, src_pid, NULL);
1553 }
1554 
1555 /*
1556  * XactHasExportedSnapshots
1557  * Test whether current transaction has exported any snapshots.
1558  */
1559 bool
1561 {
1562  return (exportedSnapshots != NIL);
1563 }
1564 
1565 /*
1566  * DeleteAllExportedSnapshotFiles
1567  * Clean up any files that have been left behind by a crashed backend
1568  * that had exported snapshots before it died.
1569  *
1570  * This should be called during database startup or crash recovery.
1571  */
1572 void
1574 {
1575  char buf[MAXPGPATH + sizeof(SNAPSHOT_EXPORT_DIR)];
1576  DIR *s_dir;
1577  struct dirent *s_de;
1578 
1579  /*
1580  * Problems in reading the directory, or unlinking files, are reported at
1581  * LOG level. Since we're running in the startup process, ERROR level
1582  * would prevent database start, and it's not important enough for that.
1583  */
1585 
1586  while ((s_de = ReadDirExtended(s_dir, SNAPSHOT_EXPORT_DIR, LOG)) != NULL)
1587  {
1588  if (strcmp(s_de->d_name, ".") == 0 ||
1589  strcmp(s_de->d_name, "..") == 0)
1590  continue;
1591 
1592  snprintf(buf, sizeof(buf), SNAPSHOT_EXPORT_DIR "/%s", s_de->d_name);
1593 
1594  if (unlink(buf) != 0)
1595  ereport(LOG,
1597  errmsg("could not remove file \"%s\": %m", buf)));
1598  }
1599 
1600  FreeDir(s_dir);
1601 }
1602 
1603 /*
1604  * ThereAreNoPriorRegisteredSnapshots
1605  * Is the registered snapshot count less than or equal to one?
1606  *
1607  * Don't use this to settle important decisions. While zero registrations and
1608  * no ActiveSnapshot would confirm a certain idleness, the system makes no
1609  * guarantees about the significance of one registered snapshot.
1610  */
1611 bool
1613 {
1616  return true;
1617 
1618  return false;
1619 }
1620 
1621 /*
1622  * HaveRegisteredOrActiveSnapshot
1623  * Is there any registered or active snapshot?
1624  *
1625  * NB: Unless pushed or active, the cached catalog snapshot will not cause
1626  * this function to return true. That allows this function to be used in
1627  * checks enforcing a longer-lived snapshot.
1628  */
1629 bool
1631 {
1632  if (ActiveSnapshot != NULL)
1633  return true;
1634 
1635  /*
1636  * The catalog snapshot is in RegisteredSnapshots when valid, but can be
1637  * removed at any time due to invalidation processing. If explicitly
1638  * registered more than one snapshot has to be in RegisteredSnapshots.
1639  */
1640  if (CatalogSnapshot != NULL &&
1642  return false;
1643 
1645 }
1646 
1647 
1648 /*
1649  * Setup a snapshot that replaces normal catalog snapshots that allows catalog
1650  * access to behave just like it did at a certain point in the past.
1651  *
1652  * Needed for logical decoding.
1653  */
1654 void
1655 SetupHistoricSnapshot(Snapshot historic_snapshot, HTAB *tuplecids)
1656 {
1657  Assert(historic_snapshot != NULL);
1658 
1659  /* setup the timetravel snapshot */
1660  HistoricSnapshot = historic_snapshot;
1661 
1662  /* setup (cmin, cmax) lookup hash */
1663  tuplecid_data = tuplecids;
1664 }
1665 
1666 
1667 /*
1668  * Make catalog snapshots behave normally again.
1669  */
1670 void
1672 {
1673  HistoricSnapshot = NULL;
1674  tuplecid_data = NULL;
1675 }
1676 
1677 bool
1679 {
1680  return HistoricSnapshot != NULL;
1681 }
1682 
1683 HTAB *
1685 {
1687  return tuplecid_data;
1688 }
1689 
1690 /*
1691  * EstimateSnapshotSpace
1692  * Returns the size needed to store the given snapshot.
1693  *
1694  * We are exporting only required fields from the Snapshot, stored in
1695  * SerializedSnapshotData.
1696  */
1697 Size
1699 {
1700  Size size;
1701 
1702  Assert(snapshot != InvalidSnapshot);
1703  Assert(snapshot->snapshot_type == SNAPSHOT_MVCC);
1704 
1705  /* We allocate any XID arrays needed in the same palloc block. */
1706  size = add_size(sizeof(SerializedSnapshotData),
1707  mul_size(snapshot->xcnt, sizeof(TransactionId)));
1708  if (snapshot->subxcnt > 0 &&
1709  (!snapshot->suboverflowed || snapshot->takenDuringRecovery))
1710  size = add_size(size,
1711  mul_size(snapshot->subxcnt, sizeof(TransactionId)));
1712 
1713  return size;
1714 }
1715 
1716 /*
1717  * SerializeSnapshot
1718  * Dumps the serialized snapshot (extracted from given snapshot) onto the
1719  * memory location at start_address.
1720  */
1721 void
1722 SerializeSnapshot(Snapshot snapshot, char *start_address)
1723 {
1724  SerializedSnapshotData serialized_snapshot;
1725 
1726  Assert(snapshot->subxcnt >= 0);
1727 
1728  /* Copy all required fields */
1729  serialized_snapshot.xmin = snapshot->xmin;
1730  serialized_snapshot.xmax = snapshot->xmax;
1731  serialized_snapshot.xcnt = snapshot->xcnt;
1732  serialized_snapshot.subxcnt = snapshot->subxcnt;
1733  serialized_snapshot.suboverflowed = snapshot->suboverflowed;
1734  serialized_snapshot.takenDuringRecovery = snapshot->takenDuringRecovery;
1735  serialized_snapshot.curcid = snapshot->curcid;
1736  serialized_snapshot.whenTaken = snapshot->whenTaken;
1737  serialized_snapshot.lsn = snapshot->lsn;
1738 
1739  /*
1740  * Ignore the SubXID array if it has overflowed, unless the snapshot was
1741  * taken during recovery - in that case, top-level XIDs are in subxip as
1742  * well, and we mustn't lose them.
1743  */
1744  if (serialized_snapshot.suboverflowed && !snapshot->takenDuringRecovery)
1745  serialized_snapshot.subxcnt = 0;
1746 
1747  /* Copy struct to possibly-unaligned buffer */
1748  memcpy(start_address,
1749  &serialized_snapshot, sizeof(SerializedSnapshotData));
1750 
1751  /* Copy XID array */
1752  if (snapshot->xcnt > 0)
1753  memcpy((TransactionId *) (start_address +
1754  sizeof(SerializedSnapshotData)),
1755  snapshot->xip, snapshot->xcnt * sizeof(TransactionId));
1756 
1757  /*
1758  * Copy SubXID array. Don't bother to copy it if it had overflowed,
1759  * though, because it's not used anywhere in that case. Except if it's a
1760  * snapshot taken during recovery; all the top-level XIDs are in subxip as
1761  * well in that case, so we mustn't lose them.
1762  */
1763  if (serialized_snapshot.subxcnt > 0)
1764  {
1765  Size subxipoff = sizeof(SerializedSnapshotData) +
1766  snapshot->xcnt * sizeof(TransactionId);
1767 
1768  memcpy((TransactionId *) (start_address + subxipoff),
1769  snapshot->subxip, snapshot->subxcnt * sizeof(TransactionId));
1770  }
1771 }
1772 
1773 /*
1774  * RestoreSnapshot
1775  * Restore a serialized snapshot from the specified address.
1776  *
1777  * The copy is palloc'd in TopTransactionContext and has initial refcounts set
1778  * to 0. The returned snapshot has the copied flag set.
1779  */
1780 Snapshot
1781 RestoreSnapshot(char *start_address)
1782 {
1783  SerializedSnapshotData serialized_snapshot;
1784  Size size;
1785  Snapshot snapshot;
1786  TransactionId *serialized_xids;
1787 
1788  memcpy(&serialized_snapshot, start_address,
1789  sizeof(SerializedSnapshotData));
1790  serialized_xids = (TransactionId *)
1791  (start_address + sizeof(SerializedSnapshotData));
1792 
1793  /* We allocate any XID arrays needed in the same palloc block. */
1794  size = sizeof(SnapshotData)
1795  + serialized_snapshot.xcnt * sizeof(TransactionId)
1796  + serialized_snapshot.subxcnt * sizeof(TransactionId);
1797 
1798  /* Copy all required fields */
1800  snapshot->snapshot_type = SNAPSHOT_MVCC;
1801  snapshot->xmin = serialized_snapshot.xmin;
1802  snapshot->xmax = serialized_snapshot.xmax;
1803  snapshot->xip = NULL;
1804  snapshot->xcnt = serialized_snapshot.xcnt;
1805  snapshot->subxip = NULL;
1806  snapshot->subxcnt = serialized_snapshot.subxcnt;
1807  snapshot->suboverflowed = serialized_snapshot.suboverflowed;
1808  snapshot->takenDuringRecovery = serialized_snapshot.takenDuringRecovery;
1809  snapshot->curcid = serialized_snapshot.curcid;
1810  snapshot->whenTaken = serialized_snapshot.whenTaken;
1811  snapshot->lsn = serialized_snapshot.lsn;
1812  snapshot->snapXactCompletionCount = 0;
1813 
1814  /* Copy XIDs, if present. */
1815  if (serialized_snapshot.xcnt > 0)
1816  {
1817  snapshot->xip = (TransactionId *) (snapshot + 1);
1818  memcpy(snapshot->xip, serialized_xids,
1819  serialized_snapshot.xcnt * sizeof(TransactionId));
1820  }
1821 
1822  /* Copy SubXIDs, if present. */
1823  if (serialized_snapshot.subxcnt > 0)
1824  {
1825  snapshot->subxip = ((TransactionId *) (snapshot + 1)) +
1826  serialized_snapshot.xcnt;
1827  memcpy(snapshot->subxip, serialized_xids + serialized_snapshot.xcnt,
1828  serialized_snapshot.subxcnt * sizeof(TransactionId));
1829  }
1830 
1831  /* Set the copied flag so that the caller will set refcounts correctly. */
1832  snapshot->regd_count = 0;
1833  snapshot->active_count = 0;
1834  snapshot->copied = true;
1835 
1836  return snapshot;
1837 }
1838 
1839 /*
1840  * Install a restored snapshot as the transaction snapshot.
1841  *
1842  * The second argument is of type void * so that snapmgr.h need not include
1843  * the declaration for PGPROC.
1844  */
1845 void
1846 RestoreTransactionSnapshot(Snapshot snapshot, void *source_pgproc)
1847 {
1848  SetTransactionSnapshot(snapshot, NULL, InvalidPid, source_pgproc);
1849 }
1850 
1851 /*
1852  * XidInMVCCSnapshot
1853  * Is the given XID still-in-progress according to the snapshot?
1854  *
1855  * Note: GetSnapshotData never stores either top xid or subxids of our own
1856  * backend into a snapshot, so these xids will not be reported as "running"
1857  * by this function. This is OK for current uses, because we always check
1858  * TransactionIdIsCurrentTransactionId first, except when it's known the
1859  * XID could not be ours anyway.
1860  */
1861 bool
1863 {
1864  /*
1865  * Make a quick range check to eliminate most XIDs without looking at the
1866  * xip arrays. Note that this is OK even if we convert a subxact XID to
1867  * its parent below, because a subxact with XID < xmin has surely also got
1868  * a parent with XID < xmin, while one with XID >= xmax must belong to a
1869  * parent that was not yet committed at the time of this snapshot.
1870  */
1871 
1872  /* Any xid < xmin is not in-progress */
1873  if (TransactionIdPrecedes(xid, snapshot->xmin))
1874  return false;
1875  /* Any xid >= xmax is in-progress */
1876  if (TransactionIdFollowsOrEquals(xid, snapshot->xmax))
1877  return true;
1878 
1879  /*
1880  * Snapshot information is stored slightly differently in snapshots taken
1881  * during recovery.
1882  */
1883  if (!snapshot->takenDuringRecovery)
1884  {
1885  /*
1886  * If the snapshot contains full subxact data, the fastest way to
1887  * check things is just to compare the given XID against both subxact
1888  * XIDs and top-level XIDs. If the snapshot overflowed, we have to
1889  * use pg_subtrans to convert a subxact XID to its parent XID, but
1890  * then we need only look at top-level XIDs not subxacts.
1891  */
1892  if (!snapshot->suboverflowed)
1893  {
1894  /* we have full data, so search subxip */
1895  if (pg_lfind32(xid, snapshot->subxip, snapshot->subxcnt))
1896  return true;
1897 
1898  /* not there, fall through to search xip[] */
1899  }
1900  else
1901  {
1902  /*
1903  * Snapshot overflowed, so convert xid to top-level. This is safe
1904  * because we eliminated too-old XIDs above.
1905  */
1906  xid = SubTransGetTopmostTransaction(xid);
1907 
1908  /*
1909  * If xid was indeed a subxact, we might now have an xid < xmin,
1910  * so recheck to avoid an array scan. No point in rechecking
1911  * xmax.
1912  */
1913  if (TransactionIdPrecedes(xid, snapshot->xmin))
1914  return false;
1915  }
1916 
1917  if (pg_lfind32(xid, snapshot->xip, snapshot->xcnt))
1918  return true;
1919  }
1920  else
1921  {
1922  /*
1923  * In recovery we store all xids in the subxip array because it is by
1924  * far the bigger array, and we mostly don't know which xids are
1925  * top-level and which are subxacts. The xip array is empty.
1926  *
1927  * We start by searching subtrans, if we overflowed.
1928  */
1929  if (snapshot->suboverflowed)
1930  {
1931  /*
1932  * Snapshot overflowed, so convert xid to top-level. This is safe
1933  * because we eliminated too-old XIDs above.
1934  */
1935  xid = SubTransGetTopmostTransaction(xid);
1936 
1937  /*
1938  * If xid was indeed a subxact, we might now have an xid < xmin,
1939  * so recheck to avoid an array scan. No point in rechecking
1940  * xmax.
1941  */
1942  if (TransactionIdPrecedes(xid, snapshot->xmin))
1943  return false;
1944  }
1945 
1946  /*
1947  * We now have either a top-level xid higher than xmin or an
1948  * indeterminate xid. We don't know whether it's top level or subxact
1949  * but it doesn't matter. If it's present, the xid is visible.
1950  */
1951  if (pg_lfind32(xid, snapshot->subxip, snapshot->subxcnt))
1952  return true;
1953  }
1954 
1955  return false;
1956 }
1957 
1958 /* ResourceOwner callbacks */
1959 
1960 static void
1962 {
1964 }
static int32 next
Definition: blutils.c:221
unsigned int uint32
Definition: c.h:495
#define PG_BINARY_R
Definition: c.h:1264
signed int int32
Definition: c.h:483
#define PG_BINARY_W
Definition: c.h:1265
uint32 CommandId
Definition: c.h:655
uint32 TransactionId
Definition: c.h:641
#define OidIsValid(objectId)
Definition: c.h:764
size_t Size
Definition: c.h:594
int64 TimestampTz
Definition: timestamp.h:39
int errcode_for_file_access(void)
Definition: elog.c:883
int errdetail(const char *fmt,...)
Definition: elog.c:1208
int errcode(int sqlerrcode)
Definition: elog.c:860
int errmsg(const char *fmt,...)
Definition: elog.c:1075
#define LOG
Definition: elog.h:31
#define WARNING
Definition: elog.h:36
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
int FreeDir(DIR *dir)
Definition: fd.c:2961
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2583
int FreeFile(FILE *file)
Definition: fd.c:2781
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2924
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2843
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
int MyProcPid
Definition: globals.c:45
Oid MyDatabaseId
Definition: globals.c:90
long val
Definition: informix.c:664
int b
Definition: isn.c:70
int a
Definition: isn.c:69
int i
Definition: isn.c:73
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
Definition: list.c:339
#define VirtualTransactionIdIsValid(vxid)
Definition: lock.h:67
MemoryContext TopTransactionContext
Definition: mcxt.c:146
char * pstrdup(const char *in)
Definition: mcxt.c:1619
void pfree(void *pointer)
Definition: mcxt.c:1431
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1034
void * palloc(Size size)
Definition: mcxt.c:1201
#define InvalidPid
Definition: miscadmin.h:32
void pairingheap_remove(pairingheap *heap, pairingheap_node *node)
Definition: pairingheap.c:170
void pairingheap_add(pairingheap *heap, pairingheap_node *node)
Definition: pairingheap.c:112
pairingheap_node * pairingheap_first(pairingheap *heap)
Definition: pairingheap.c:130
#define pairingheap_is_empty(h)
Definition: pairingheap.h:96
#define pairingheap_is_singular(h)
Definition: pairingheap.h:99
#define pairingheap_container(type, membername, ptr)
Definition: pairingheap.h:43
#define pairingheap_const_container(type, membername, ptr)
Definition: pairingheap.h:51
#define pairingheap_reset(h)
Definition: pairingheap.h:93
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
void * arg
#define MAXPGPATH
static char * filename
Definition: pg_dumpall.c:121
static bool pg_lfind32(uint32 key, uint32 *base, uint32 nelem)
Definition: pg_lfind.h:90
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
static char * buf
Definition: pg_test_fsync.c:73
#define snprintf
Definition: port.h:238
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
uintptr_t Datum
Definition: postgres.h:64
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
unsigned int Oid
Definition: postgres_ext.h:31
void SetSerializableTransactionSnapshot(Snapshot snapshot, VirtualTransactionId *sourcevxid, int sourcepid)
Definition: predicate.c:1692
Snapshot GetSerializableTransactionSnapshot(Snapshot snapshot)
Definition: predicate.c:1652
int GetMaxSnapshotSubxidCount(void)
Definition: procarray.c:2069
Snapshot GetSnapshotData(Snapshot snapshot)
Definition: procarray.c:2166
int GetMaxSnapshotXidCount(void)
Definition: procarray.c:2058
bool ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc)
Definition: procarray.c:2604
bool ProcArrayInstallImportedXmin(TransactionId xmin, VirtualTransactionId *sourcevxid)
Definition: procarray.c:2525
ResourceOwner CurrentResourceOwner
Definition: resowner.c:165
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:554
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:514
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition: resowner.c:442
#define RELEASE_PRIO_SNAPSHOT_REFS
Definition: resowner.h:75
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition: resowner.h:56
Size add_size(Size s1, Size s2)
Definition: shmem.c:494
Size mul_size(Size s1, Size s2)
Definition: shmem.c:511
static Snapshot HistoricSnapshot
Definition: snapmgr.c:98
static Snapshot FirstXactSnapshot
Definition: snapmgr.c:149
TransactionId RecentXmin
Definition: snapmgr.c:106
SnapshotData CatalogSnapshotData
Definition: snapmgr.c:90
void UnregisterSnapshotFromOwner(Snapshot snapshot, ResourceOwner owner)
Definition: snapmgr.c:856
static void SetTransactionSnapshot(Snapshot sourcesnap, VirtualTransactionId *sourcevxid, int sourcepid, PGPROC *sourceproc)
Definition: snapmgr.c:484
void AtSubAbort_Snapshot(int level)
Definition: snapmgr.c:966
void SerializeSnapshot(Snapshot snapshot, char *start_address)
Definition: snapmgr.c:1722
SnapshotData SnapshotSelfData
Definition: snapmgr.c:91
void AtEOXact_Snapshot(bool isCommit, bool resetXmin)
Definition: snapmgr.c:1002
struct ActiveSnapshotElt ActiveSnapshotElt
static Snapshot CurrentSnapshot
Definition: snapmgr.c:95
static Snapshot SecondarySnapshot
Definition: snapmgr.c:96
bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot)
Definition: snapmgr.c:1862
static List * exportedSnapshots
Definition: snapmgr.c:162
static pairingheap RegisteredSnapshots
Definition: snapmgr.c:139
bool FirstSnapshotSet
Definition: snapmgr.c:142
static void UnregisterSnapshotNoOwner(Snapshot snapshot)
Definition: snapmgr.c:866
Snapshot GetTransactionSnapshot(void)
Definition: snapmgr.c:223
Snapshot GetLatestSnapshot(void)
Definition: snapmgr.c:298
void TeardownHistoricSnapshot(bool is_error)
Definition: snapmgr.c:1671
Snapshot GetCatalogSnapshot(Oid relid)
Definition: snapmgr.c:359
void UnregisterSnapshot(Snapshot snapshot)
Definition: snapmgr.c:843
void PushActiveSnapshot(Snapshot snapshot)
Definition: snapmgr.c:655
static Snapshot CopySnapshot(Snapshot snapshot)
Definition: snapmgr.c:581
static ActiveSnapshotElt * OldestActiveSnapshot
Definition: snapmgr.c:130
Snapshot RestoreSnapshot(char *start_address)
Definition: snapmgr.c:1781
HTAB * HistoricSnapshotGetTupleCids(void)
Definition: snapmgr.c:1684
void AtSubCommit_Snapshot(int level)
Definition: snapmgr.c:945
static void ResourceOwnerRememberSnapshot(ResourceOwner owner, Snapshot snap)
Definition: snapmgr.c:184
void UpdateActiveSnapshotCommandId(void)
Definition: snapmgr.c:719
static void SnapshotResetXmin(void)
Definition: snapmgr.c:921
static int parseIntFromText(const char *prefix, char **s, const char *filename)
Definition: snapmgr.c:1293
static SnapshotData SecondarySnapshotData
Definition: snapmgr.c:89
char * ExportSnapshot(Snapshot snapshot)
Definition: snapmgr.c:1102
static int xmin_cmp(const pairingheap_node *a, const pairingheap_node *b, void *arg)
Definition: snapmgr.c:887
TransactionId TransactionXmin
Definition: snapmgr.c:105
SnapshotData SnapshotAnyData
Definition: snapmgr.c:92
bool HistoricSnapshotActive(void)
Definition: snapmgr.c:1678
void ImportSnapshot(const char *idstr)
Definition: snapmgr.c:1373
bool ActiveSnapshotSet(void)
Definition: snapmgr.c:789
Snapshot RegisterSnapshot(Snapshot snapshot)
Definition: snapmgr.c:801
bool XactHasExportedSnapshots(void)
Definition: snapmgr.c:1560
static const ResourceOwnerDesc snapshot_resowner_desc
Definition: snapmgr.c:173
void DeleteAllExportedSnapshotFiles(void)
Definition: snapmgr.c:1573
static void parseVxidFromText(const char *prefix, char **s, const char *filename, VirtualTransactionId *vxid)
Definition: snapmgr.c:1343
static void FreeSnapshot(Snapshot snapshot)
Definition: snapmgr.c:637
#define SNAPSHOT_EXPORT_DIR
Definition: snapmgr.c:152
bool HaveRegisteredOrActiveSnapshot(void)
Definition: snapmgr.c:1630
void InvalidateCatalogSnapshotConditionally(void)
Definition: snapmgr.c:450
static SnapshotData CurrentSnapshotData
Definition: snapmgr.c:88
static void ResourceOwnerForgetSnapshot(ResourceOwner owner, Snapshot snap)
Definition: snapmgr.c:189
bool ThereAreNoPriorRegisteredSnapshots(void)
Definition: snapmgr.c:1612
void RestoreTransactionSnapshot(Snapshot snapshot, void *source_pgproc)
Definition: snapmgr.c:1846
void SnapshotSetCommandId(CommandId curcid)
Definition: snapmgr.c:463
struct SerializedSnapshotData SerializedSnapshotData
void PopActiveSnapshot(void)
Definition: snapmgr.c:750
void PushCopiedSnapshot(Snapshot snapshot)
Definition: snapmgr.c:707
Size EstimateSnapshotSpace(Snapshot snapshot)
Definition: snapmgr.c:1698
static ActiveSnapshotElt * ActiveSnapshot
Definition: snapmgr.c:127
void SetupHistoricSnapshot(Snapshot historic_snapshot, HTAB *tuplecids)
Definition: snapmgr.c:1655
static HTAB * tuplecid_data
Definition: snapmgr.c:109
Snapshot RegisterSnapshotOnOwner(Snapshot snapshot, ResourceOwner owner)
Definition: snapmgr.c:814
static TransactionId parseXidFromText(const char *prefix, char **s, const char *filename)
Definition: snapmgr.c:1318
void InvalidateCatalogSnapshot(void)
Definition: snapmgr.c:429
void PushActiveSnapshotWithLevel(Snapshot snapshot, int snap_level)
Definition: snapmgr.c:669
Snapshot GetNonHistoricCatalogSnapshot(Oid relid)
Definition: snapmgr.c:381
struct ExportedSnapshot ExportedSnapshot
Snapshot GetOldestSnapshot(void)
Definition: snapmgr.c:330
static Snapshot CatalogSnapshot
Definition: snapmgr.c:97
Snapshot GetActiveSnapshot(void)
Definition: snapmgr.c:777
Datum pg_export_snapshot(PG_FUNCTION_ARGS)
Definition: snapmgr.c:1278
static void ResOwnerReleaseSnapshot(Datum res)
Definition: snapmgr.c:1961
struct SnapshotData * Snapshot
Definition: snapshot.h:121
struct SnapshotData SnapshotData
@ SNAPSHOT_SELF
Definition: snapshot.h:64
@ SNAPSHOT_MVCC
Definition: snapshot.h:50
@ SNAPSHOT_ANY
Definition: snapshot.h:69
#define InvalidSnapshot
Definition: snapshot.h:123
PGPROC * MyProc
Definition: proc.c:68
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:182
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
struct ActiveSnapshotElt * as_next
Definition: snapmgr.c:123
Snapshot as_snap
Definition: snapmgr.c:121
Definition: dirent.c:26
char * snapfile
Definition: snapmgr.c:157
Snapshot snapshot
Definition: snapmgr.c:158
Definition: dynahash.c:220
Definition: pg_list.h:54
Definition: proc.h:162
TransactionId xmin
Definition: proc.h:178
LocalTransactionId lxid
Definition: proc.h:183
BackendId backendId
Definition: proc.h:192
const char * name
Definition: resowner.h:93
TransactionId xmax
Definition: snapmgr.c:203
TimestampTz whenTaken
Definition: snapmgr.c:209
TransactionId xmin
Definition: snapmgr.c:202
TransactionId xmin
Definition: snapshot.h:157
int32 subxcnt
Definition: snapshot.h:181
bool copied
Definition: snapshot.h:185
uint32 regd_count
Definition: snapshot.h:205
uint32 active_count
Definition: snapshot.h:204
CommandId curcid
Definition: snapshot.h:187
pairingheap_node ph_node
Definition: snapshot.h:206
TimestampTz whenTaken
Definition: snapshot.h:208
uint32 xcnt
Definition: snapshot.h:169
TransactionId * subxip
Definition: snapshot.h:180
uint64 snapXactCompletionCount
Definition: snapshot.h:216
TransactionId xmax
Definition: snapshot.h:158
XLogRecPtr lsn
Definition: snapshot.h:209
SnapshotType snapshot_type
Definition: snapshot.h:144
TransactionId * xip
Definition: snapshot.h:168
bool suboverflowed
Definition: snapshot.h:182
bool takenDuringRecovery
Definition: snapshot.h:184
LocalTransactionId localTransactionId
Definition: lock.h:62
BackendId backendId
Definition: lock.h:61
Definition: dirent.h:10
char d_name[MAX_PATH]
Definition: dirent.h:15
__int64 st_size
Definition: win32_port.h:273
TransactionId SubTransGetTopmostTransaction(TransactionId xid)
Definition: subtrans.c:159
bool RelationHasSysCache(Oid relid)
Definition: syscache.c:625
bool RelationInvalidatesSnapshotsOnly(Oid relid)
Definition: syscache.c:602
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:280
bool TransactionIdFollows(TransactionId id1, TransactionId id2)
Definition: transam.c:314
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:329
#define InvalidTransactionId
Definition: transam.h:31
#define FirstNormalTransactionId
Definition: transam.h:34
#define TransactionIdIsValid(xid)
Definition: transam.h:41
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
text * cstring_to_text(const char *s)
Definition: varlena.c:184
#define fstat
Definition: win32_port.h:283
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:914
bool XactReadOnly
Definition: xact.c:82
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:432
int XactIsoLevel
Definition: xact.c:79
bool IsSubTransaction(void)
Definition: xact.c:4905
bool IsInParallelMode(void)
Definition: xact.c:1069
int xactGetCommittedChildren(TransactionId **ptr)
Definition: xact.c:5643
CommandId GetCurrentCommandId(bool used)
Definition: xact.c:818
#define XACT_SERIALIZABLE
Definition: xact.h:39
#define IsolationUsesXactSnapshot()
Definition: xact.h:51
#define IsolationIsSerializable()
Definition: xact.h:52
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28