diff --git a/pageserver/src/tenant/layer_map.rs b/pageserver/src/tenant/layer_map.rs index 5f4814cc6b..4a1437ac9e 100644 --- a/pageserver/src/tenant/layer_map.rs +++ b/pageserver/src/tenant/layer_map.rs @@ -500,7 +500,7 @@ impl LayerMap { /// /// Helper function for BatchedUpdates::remove_historic /// - pub fn remove_historic_noflush(&mut self, layer_desc: &PersistentLayerDesc) { + pub(self) fn remove_historic_noflush(&mut self, layer_desc: &PersistentLayerDesc) { self.historic .remove(historic_layer_coverage::LayerKey::from(layer_desc)); let layer_key = layer_desc.key(); diff --git a/pageserver/src/tenant/layer_map/historic_layer_coverage.rs b/pageserver/src/tenant/layer_map/historic_layer_coverage.rs index 347490c1ba..82069bc145 100644 --- a/pageserver/src/tenant/layer_map/historic_layer_coverage.rs +++ b/pageserver/src/tenant/layer_map/historic_layer_coverage.rs @@ -413,6 +413,8 @@ fn test_persistent_overlapping() { /// See this for more on persistent and retroactive techniques: /// pub struct BufferedHistoricLayerCoverage { + rebuild_version: RebuildVersion, + /// A persistent layer map that we rebuild when we need to retroactively update historic_coverage: HistoricLayerCoverage, @@ -438,9 +440,33 @@ impl Default for BufferedHistoricLayerCoverage { } } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct RebuildVersion(u64); + +impl RebuildVersion { + fn inc(&mut self) { + self.0 + .checked_add(1) + .expect("at current clock cycles, we won't hit this"); + } +} + +impl Default for RebuildVersion { + fn default() -> Self { + RebuildVersion(1) + } +} + +impl std::fmt::Display for RebuildVersion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + impl BufferedHistoricLayerCoverage { pub fn new() -> Self { Self { + rebuild_version: RebuildVersion::default(), historic_coverage: HistoricLayerCoverage::::new(), buffer: BTreeMap::new(), layers: BTreeMap::new(), @@ -462,6 +488,8 @@ impl BufferedHistoricLayerCoverage { None => return, // No need to rebuild if buffer is empty }; + self.rebuild_version.inc(); + // Apply buffered updates to self.layers let num_updates = self.buffer.len(); self.buffer.retain(|layer_key, layer| { @@ -493,8 +521,10 @@ impl BufferedHistoricLayerCoverage { // TODO maybe only warn if ratio is at least 10 info!( + version = %self.rebuild_version, "Rebuilt layer map. Did {} insertions to process a batch of {} updates.", - num_inserted, num_updates, + num_inserted, + num_updates, ) }