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