From 0ed98977bab44901d02ed091bcf350bce5940279 Mon Sep 17 00:00:00 2001 From: John Spray Date: Tue, 15 Oct 2024 15:17:29 +0000 Subject: [PATCH] pageserver: work around #9185 in layer visibility calculation --- .../src/tenant/storage_layer/inmemory_layer.rs | 4 ++++ pageserver/src/tenant/timeline/compaction.rs | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/pageserver/src/tenant/storage_layer/inmemory_layer.rs b/pageserver/src/tenant/storage_layer/inmemory_layer.rs index e487bee1f2..a19a2a86b9 100644 --- a/pageserver/src/tenant/storage_layer/inmemory_layer.rs +++ b/pageserver/src/tenant/storage_layer/inmemory_layer.rs @@ -392,6 +392,10 @@ impl InMemoryLayer { self.end_lsn.get().copied().unwrap_or(Lsn::MAX) } + pub(crate) fn start_lsn(&self) -> Lsn { + self.start_lsn + } + pub(crate) fn get_lsn_range(&self) -> Range { self.start_lsn..self.end_lsn_or_max() } diff --git a/pageserver/src/tenant/timeline/compaction.rs b/pageserver/src/tenant/timeline/compaction.rs index 8b9ace1e5b..82a418313c 100644 --- a/pageserver/src/tenant/timeline/compaction.rs +++ b/pageserver/src/tenant/timeline/compaction.rs @@ -646,6 +646,21 @@ impl Timeline { readable_points.push(*child_lsn); } readable_points.push(head_lsn); + + // The Timeline get page process will walk all InMemoryLayers before it starts walking historic + // layers. That means it might fail to see image layers that overlap with the LSN range of + // InMemoryLayers, so there is a de-facto read point at the start_lsn of the oldest InMemoryLayer. + // + // This behavior in the getpage path is considered a but, and including InMemoryLayer's start_lsn here + // is a workaround. See https://github.com/neondatabase/neon/issues/9185 + if let Some(oldest_inmemory_layer) = layer_map.frozen_layers.front() { + readable_points.push(oldest_inmemory_layer.start_lsn()) + } else if let Some(open_layer) = layer_map.open_layer.as_ref() { + readable_points.push(open_layer.start_lsn()); + } + + readable_points.sort(); + readable_points };