cleanup API + add flag to residence status to distinguish loading from creating

This commit is contained in:
Christian Schwarz
2023-02-01 18:01:19 +01:00
committed by Christian Schwarz
parent 8ce21eb7e3
commit 0850d28059
6 changed files with 91 additions and 65 deletions

View File

@@ -256,8 +256,13 @@ pub struct LayerAccessStatFullDetails {
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
#[serde(tag = "kind")]
pub enum LayerResidenceStatus {
Resident { timestamp_millis_since_epoch: u128 },
Evicted { timestamp_millis_since_epoch: u128 },
Resident {
timestamp_millis_since_epoch: u128,
creating: bool,
},
Evicted {
timestamp_millis_since_epoch: u128,
},
}
#[derive(Debug, Clone, Serialize)]
@@ -300,7 +305,7 @@ pub enum HistoricLayerInfo {
#[serde_as(as = "DisplayFromStr")]
lsn_end: Lsn,
remote: bool,
access_stats: Option<LayerAccessStats>,
access_stats: LayerAccessStats,
},
Image {
layer_file_name: String,
@@ -311,7 +316,7 @@ pub enum HistoricLayerInfo {
#[serde_as(as = "DisplayFromStr")]
lsn_start: Lsn,
remote: bool,
access_stats: Option<LayerAccessStats>,
access_stats: LayerAccessStats,
},
}

View File

@@ -88,7 +88,7 @@ pub enum ValueReconstructResult {
Missing,
}
#[derive(Default, Debug)]
#[derive(Debug)]
pub struct LayerAccessStats(Mutex<LayerAccessStatsInner>);
#[derive(Debug, Clone)]
@@ -109,8 +109,13 @@ struct LayerAccessStatsInner {
#[derive(Debug, Clone)]
pub enum LayerResidenceStatus {
Resident { timestamp: SystemTime },
Evicted { timestamp: SystemTime },
Resident {
timestamp: SystemTime,
creating: bool,
},
Evicted {
timestamp: SystemTime,
},
}
#[derive(Clone, Copy, strum_macros::EnumString)]
@@ -147,19 +152,22 @@ impl LayerResidenceStatus {
}
}
pub fn resident() -> Self {
pub fn resident(creating: bool) -> Self {
LayerResidenceStatus::Resident {
timestamp: SystemTime::now(),
creating,
}
}
fn to_api_model(&self) -> pageserver_api::models::LayerResidenceStatus {
match self {
LayerResidenceStatus::Resident { timestamp } => {
pageserver_api::models::LayerResidenceStatus::Resident {
timestamp_millis_since_epoch: system_time_to_millis_since_epoch(timestamp),
}
}
LayerResidenceStatus::Resident {
timestamp,
creating,
} => pageserver_api::models::LayerResidenceStatus::Resident {
timestamp_millis_since_epoch: system_time_to_millis_since_epoch(timestamp),
creating: *creating,
},
LayerResidenceStatus::Evicted { timestamp } => {
pageserver_api::models::LayerResidenceStatus::Evicted {
timestamp_millis_since_epoch: system_time_to_millis_since_epoch(timestamp),
@@ -189,24 +197,44 @@ impl LayerAccessStats {
const LAST_ACCESSES_MAX_LEN: usize = 16;
const LAST_RESIDENCE_CHANGES_MAX_LEN: usize = 16;
pub(crate) fn new_for_loading_layer(residence_status: LayerResidenceStatus) -> Self {
let new = LayerAccessStats(Mutex::new(LayerAccessStatsInner::default()));
new.record_residence_change(residence_status);
new
}
pub(crate) fn new_for_new_layer_file() -> Self {
let new = LayerAccessStats(Mutex::new(LayerAccessStatsInner::default()));
new.record_residence_change(LayerResidenceStatus::resident(true));
new
}
/// Creates a clone of `self` and records `new_status` in the clone.
/// The `new_status` is not recorded in `self`
pub(crate) fn clone_for_residence_change(
&self,
new_status: LayerResidenceStatus,
) -> LayerAccessStats {
let mut clone = {
let clone = {
let inner = self.0.lock().unwrap();
inner.clone()
};
let new = LayerAccessStats(Mutex::new(clone));
new.record_residence_change(new_status);
new
}
fn record_residence_change(&self, new_status: LayerResidenceStatus) {
if LAYER_ACCESS_STATS_KILLSWITCH.load(atomic::Ordering::SeqCst) {
return;
}
let mut inner = self.0.lock().unwrap();
// make room first to avoid reallocs
while clone.last_residence_changes.len() >= Self::LAST_RESIDENCE_CHANGES_MAX_LEN {
clone.last_residence_changes.pop_back();
while inner.last_residence_changes.len() >= Self::LAST_RESIDENCE_CHANGES_MAX_LEN {
inner.last_residence_changes.pop_back();
}
clone.last_residence_changes.push_front(new_status.clone());
LayerAccessStats(Mutex::new(clone))
inner.last_residence_changes.push_front(new_status);
}
fn record_access(&self, access_kind: LayerAccessKind, task_kind: TaskKind) {

View File

@@ -57,7 +57,7 @@ use utils::{
use super::{
DeltaFileName, Layer, LayerAccessStats, LayerAccessStatsReset, LayerFileName, LayerIter,
LayerKeyIter, PathOrConf,
LayerKeyIter, LayerResidenceStatus, PathOrConf,
};
///
@@ -438,7 +438,7 @@ impl PersistentLayer for DeltaLayer {
lsn_start: lsn_range.start,
lsn_end: lsn_range.end,
remote: false,
access_stats: Some(self.access_stats.to_api_model()),
access_stats: self.access_stats.to_api_model(),
};
if let Some(reset) = reset {
@@ -582,7 +582,7 @@ impl DeltaLayer {
tenant_id: TenantId,
filename: &DeltaFileName,
file_size: u64,
existing_access_stats: Option<LayerAccessStats>,
access_stats: LayerAccessStats,
) -> DeltaLayer {
DeltaLayer {
path_or_conf: PathOrConf::Conf(conf),
@@ -591,7 +591,7 @@ impl DeltaLayer {
key_range: filename.key_range.clone(),
lsn_range: filename.lsn_range.clone(),
file_size,
access_stats: existing_access_stats.unwrap_or_default(),
access_stats,
inner: RwLock::new(DeltaLayerInner {
loaded: false,
file: None,
@@ -621,7 +621,9 @@ impl DeltaLayer {
key_range: summary.key_range,
lsn_range: summary.lsn_range,
file_size: metadata.len(),
access_stats: LayerAccessStats::default(),
access_stats: LayerAccessStats::new_for_loading_layer(LayerResidenceStatus::resident(
false,
)),
inner: RwLock::new(DeltaLayerInner {
loaded: false,
file: None,
@@ -792,7 +794,7 @@ impl DeltaLayerWriterInner {
key_range: self.key_start..key_end,
lsn_range: self.lsn_range.clone(),
file_size: metadata.len(),
access_stats: LayerAccessStats::default(),
access_stats: LayerAccessStats::new_for_new_layer_file(),
inner: RwLock::new(DeltaLayerInner {
loaded: false,
file: None,

View File

@@ -52,7 +52,7 @@ use utils::{
};
use super::filename::{ImageFileName, LayerFileName, PathOrConf};
use super::{Layer, LayerAccessStats, LayerAccessStatsReset, LayerIter};
use super::{Layer, LayerAccessStats, LayerAccessStatsReset, LayerIter, LayerResidenceStatus};
///
/// Header stored in the beginning of the file
@@ -249,7 +249,7 @@ impl PersistentLayer for ImageLayer {
key_end: key_range.end,
lsn_start: lsn_range.start,
remote: false,
access_stats: Some(self.access_stats.to_api_model()),
access_stats: self.access_stats.to_api_model(),
};
if let Some(reset) = reset {
@@ -385,7 +385,7 @@ impl ImageLayer {
tenant_id: TenantId,
filename: &ImageFileName,
file_size: u64,
existing_access_stats: Option<LayerAccessStats>,
access_stats: LayerAccessStats,
) -> ImageLayer {
ImageLayer {
path_or_conf: PathOrConf::Conf(conf),
@@ -394,7 +394,7 @@ impl ImageLayer {
key_range: filename.key_range.clone(),
lsn: filename.lsn,
file_size,
access_stats: existing_access_stats.unwrap_or_default(),
access_stats,
inner: RwLock::new(ImageLayerInner {
loaded: false,
file: None,
@@ -422,7 +422,9 @@ impl ImageLayer {
key_range: summary.key_range,
lsn: summary.lsn,
file_size: metadata.len(),
access_stats: LayerAccessStats::default(),
access_stats: LayerAccessStats::new_for_loading_layer(LayerResidenceStatus::resident(
false,
)),
inner: RwLock::new(ImageLayerInner {
file: None,
loaded: false,
@@ -582,7 +584,7 @@ impl ImageLayerWriterInner {
key_range: self.key_range.clone(),
lsn: self.lsn,
file_size: metadata.len(),
access_stats: LayerAccessStats::default(),
access_stats: LayerAccessStats::new_for_new_layer_file(),
inner: RwLock::new(ImageLayerInner {
loaded: false,
file: None,

View File

@@ -155,7 +155,7 @@ impl PersistentLayer for RemoteLayer {
lsn_start: lsn_range.start,
lsn_end: lsn_range.end,
remote: true,
access_stats: Some(self.access_stats.to_api_model()),
access_stats: self.access_stats.to_api_model(),
}
} else {
HistoricLayerInfo::Image {
@@ -164,7 +164,7 @@ impl PersistentLayer for RemoteLayer {
key_end: key_range.end,
lsn_start: lsn_range.start,
remote: true,
access_stats: Some(self.access_stats.to_api_model()),
access_stats: self.access_stats.to_api_model(),
}
}
}
@@ -180,7 +180,7 @@ impl RemoteLayer {
timelineid: TimelineId,
fname: &ImageFileName,
layer_metadata: &LayerFileMetadata,
existing_access_stats: Option<LayerAccessStats>,
access_stats: LayerAccessStats,
) -> RemoteLayer {
RemoteLayer {
tenantid,
@@ -192,7 +192,7 @@ impl RemoteLayer {
file_name: fname.to_owned().into(),
layer_metadata: layer_metadata.clone(),
ongoing_download: Arc::new(tokio::sync::Semaphore::new(1)),
access_stats: existing_access_stats.unwrap_or_default(),
access_stats,
}
}
@@ -201,8 +201,7 @@ impl RemoteLayer {
timelineid: TimelineId,
fname: &DeltaFileName,
layer_metadata: &LayerFileMetadata,
existing_access_stats: Option<LayerAccessStats>,
access_stats: LayerAccessStats,
) -> RemoteLayer {
RemoteLayer {
tenantid,
@@ -214,7 +213,7 @@ impl RemoteLayer {
file_name: fname.to_owned().into(),
layer_metadata: layer_metadata.clone(),
ongoing_download: Arc::new(tokio::sync::Semaphore::new(1)),
access_stats: existing_access_stats.unwrap_or_default(),
access_stats,
}
}
@@ -235,10 +234,8 @@ impl RemoteLayer {
self.tenantid,
&fname,
file_size,
Some(
self.access_stats
.clone_for_residence_change(LayerResidenceStatus::resident()),
),
self.access_stats
.clone_for_residence_change(LayerResidenceStatus::resident(false)),
))
} else {
let fname = ImageFileName {
@@ -251,10 +248,8 @@ impl RemoteLayer {
self.tenantid,
&fname,
file_size,
Some(
self.access_stats
.clone_for_residence_change(LayerResidenceStatus::resident()),
),
self.access_stats
.clone_for_residence_change(LayerResidenceStatus::resident(false)),
))
}
}

View File

@@ -29,8 +29,8 @@ use crate::broker_client::is_broker_client_initialized;
use crate::context::{DownloadBehavior, RequestContext};
use crate::tenant::remote_timeline_client::{self, index::LayerFileMetadata};
use crate::tenant::storage_layer::{
DeltaFileName, DeltaLayerWriter, ImageFileName, ImageLayerWriter, InMemoryLayer, LayerFileName,
RemoteLayer,
DeltaFileName, DeltaLayerWriter, ImageFileName, ImageLayerWriter, InMemoryLayer,
LayerAccessStats, LayerFileName, LayerResidenceStatus, RemoteLayer,
};
use crate::tenant::{
ephemeral_file::is_ephemeral_file,
@@ -71,9 +71,7 @@ use walreceiver::spawn_connection_manager_task;
use super::layer_map::BatchedUpdates;
use super::remote_timeline_client::index::IndexPart;
use super::remote_timeline_client::RemoteTimelineClient;
use super::storage_layer::{
DeltaLayer, ImageLayer, Layer, LayerAccessStatsReset, LayerResidenceStatus,
};
use super::storage_layer::{DeltaLayer, ImageLayer, Layer, LayerAccessStatsReset};
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
enum FlushLoopState {
@@ -879,22 +877,18 @@ impl Timeline {
self.timeline_id,
&image_name,
&layer_metadata,
Some(
local_layer
.access_stats()
.clone_for_residence_change(LayerResidenceStatus::evicted()),
),
local_layer
.access_stats()
.clone_for_residence_change(LayerResidenceStatus::evicted()),
),
LayerFileName::Delta(delta_name) => RemoteLayer::new_delta(
self.tenant_id,
self.timeline_id,
&delta_name,
&layer_metadata,
Some(
local_layer
.access_stats()
.clone_for_residence_change(LayerResidenceStatus::evicted()),
),
local_layer
.access_stats()
.clone_for_residence_change(LayerResidenceStatus::evicted()),
),
#[cfg(test)]
LayerFileName::Test(_) => unreachable!(),
@@ -1171,7 +1165,7 @@ impl Timeline {
self.tenant_id,
&imgfilename,
file_size,
None,
LayerAccessStats::new_for_loading_layer(LayerResidenceStatus::resident(false)),
);
trace!("found layer {}", layer.path().display());
@@ -1203,7 +1197,7 @@ impl Timeline {
self.tenant_id,
&deltafilename,
file_size,
None,
LayerAccessStats::new_for_loading_layer(LayerResidenceStatus::resident(false)),
);
trace!("found layer {}", layer.path().display());
@@ -1341,7 +1335,7 @@ impl Timeline {
self.timeline_id,
imgfilename,
&remote_layer_metadata,
None,
LayerAccessStats::new_for_loading_layer(LayerResidenceStatus::evicted()),
);
let remote_layer = Arc::new(remote_layer);
@@ -1366,7 +1360,7 @@ impl Timeline {
self.timeline_id,
deltafilename,
&remote_layer_metadata,
None,
LayerAccessStats::new_for_loading_layer(LayerResidenceStatus::evicted()),
);
let remote_layer = Arc::new(remote_layer);
updates.insert_historic(remote_layer);