diff --git a/pageserver/src/tenant/storage_layer/layer_desc.rs b/pageserver/src/tenant/storage_layer/layer_desc.rs index 2e0b0b3e64..24feafd4a7 100644 --- a/pageserver/src/tenant/storage_layer/layer_desc.rs +++ b/pageserver/src/tenant/storage_layer/layer_desc.rs @@ -5,7 +5,7 @@ use utils::{ lsn::Lsn, }; -use crate::repository::Key; +use crate::{pgdatadir_mapping::METADATA_CUT, repository::Key}; use super::{DeltaFileName, ImageFileName, LayerFileName}; @@ -49,6 +49,20 @@ impl PersistentLayerDesc { } } + /// Does this layer consist exclusively of metadata + /// content such as dbdir & relation sizes? This is a + /// hint that the layer is likely to be small and should + /// not be a candidate for eviction under normal circumstances. + pub fn is_metadata_pages(&self) -> bool { + self.key_range.start >= METADATA_CUT + } + + /// Does this layer consist exclusively of content + /// required to serve a basebackup request? + pub fn is_basebackup_pages(&self) -> bool { + self.key_range.start >= METADATA_CUT + } + pub fn short_id(&self) -> impl Display { self.filename() } diff --git a/pageserver/src/tenant/timeline.rs b/pageserver/src/tenant/timeline.rs index 5c5308cef5..65cbfb6a22 100644 --- a/pageserver/src/tenant/timeline.rs +++ b/pageserver/src/tenant/timeline.rs @@ -4274,6 +4274,11 @@ impl Timeline { let file_size = l.file_size(); max_layer_size = max_layer_size.map_or(Some(file_size), |m| Some(m.max(file_size))); + // Don't evict small layers required to serve a basebackup + if l.is_basebackup_pages() { + continue; + } + let l = guard.get_from_desc(&l); let l = match l.keep_resident().await { diff --git a/pageserver/src/tenant/timeline/eviction_task.rs b/pageserver/src/tenant/timeline/eviction_task.rs index 84fe35b9fb..ba20052b82 100644 --- a/pageserver/src/tenant/timeline/eviction_task.rs +++ b/pageserver/src/tenant/timeline/eviction_task.rs @@ -197,6 +197,11 @@ impl Timeline { let layers = guard.layer_map(); let mut candidates = Vec::new(); for hist_layer in layers.iter_historic_layers() { + // Don't evict the small layers needed to serve a basebackup request. + if hist_layer.is_basebackup_pages() { + continue; + } + let hist_layer = guard.get_from_desc(&hist_layer); // guard against eviction while we inspect it; it might be that eviction_task and