summaryrefslogtreecommitdiff
path: root/src/backend/utils/time/snapmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/time/snapmgr.c')
-rw-r--r--src/backend/utils/time/snapmgr.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c
index e1caf01c603..4bddaed33ba 100644
--- a/src/backend/utils/time/snapmgr.c
+++ b/src/backend/utils/time/snapmgr.c
@@ -188,6 +188,9 @@ typedef struct ActiveSnapshotElt
/* Top of the stack of active snapshots */
static ActiveSnapshotElt *ActiveSnapshot = NULL;
+/* Bottom of the stack of active snapshots */
+static ActiveSnapshotElt *OldestActiveSnapshot = NULL;
+
/*
* Currently registered Snapshots. Ordered in a heap by xmin, so that we can
* quickly find the one with lowest xmin, to advance our MyPgXat->xmin.
@@ -394,6 +397,34 @@ GetLatestSnapshot(void)
}
/*
+ * GetOldestSnapshot
+ *
+ * Get the oldest known snapshot, as judged by the LSN.
+ */
+Snapshot
+GetOldestSnapshot(void)
+{
+ Snapshot OldestRegisteredSnapshot = NULL;
+ XLogRecPtr RegisteredLSN = InvalidXLogRecPtr;
+ XLogRecPtr ActiveLSN = InvalidXLogRecPtr;
+
+ if (!pairingheap_is_empty(&RegisteredSnapshots))
+ {
+ OldestRegisteredSnapshot = pairingheap_container(SnapshotData, ph_node,
+ pairingheap_first(&RegisteredSnapshots));
+ RegisteredLSN = OldestRegisteredSnapshot->lsn;
+ }
+
+ if (OldestActiveSnapshot != NULL)
+ ActiveLSN = OldestActiveSnapshot->as_snap->lsn;
+
+ if (XLogRecPtrIsInvalid(RegisteredLSN) || RegisteredLSN > ActiveLSN)
+ return OldestActiveSnapshot->as_snap;
+
+ return OldestRegisteredSnapshot;
+}
+
+/*
* GetCatalogSnapshot
* Get a snapshot that is sufficiently up-to-date for scan of the
* system catalog with the specified OID.
@@ -674,6 +705,8 @@ PushActiveSnapshot(Snapshot snap)
newactive->as_snap->active_count++;
ActiveSnapshot = newactive;
+ if (OldestActiveSnapshot == NULL)
+ OldestActiveSnapshot = ActiveSnapshot;
}
/*
@@ -744,6 +777,8 @@ PopActiveSnapshot(void)
pfree(ActiveSnapshot);
ActiveSnapshot = newstack;
+ if (ActiveSnapshot == NULL)
+ OldestActiveSnapshot = NULL;
SnapshotResetXmin();
}
@@ -953,6 +988,8 @@ AtSubAbort_Snapshot(int level)
pfree(ActiveSnapshot);
ActiveSnapshot = next;
+ if (ActiveSnapshot == NULL)
+ OldestActiveSnapshot = NULL;
}
SnapshotResetXmin();
@@ -1037,6 +1074,7 @@ AtEOXact_Snapshot(bool isCommit)
* it'll go away with TopTransactionContext.
*/
ActiveSnapshot = NULL;
+ OldestActiveSnapshot = NULL;
pairingheap_reset(&RegisteredSnapshots);
CurrentSnapshot = NULL;