LCOV - differential code coverage report
Current view: top level - pageserver/src/tenant/storage_layer - remote_layer.rs (source / functions) Coverage Total Hit UBC CBC
Current: f6946e90941b557c917ac98cd5a7e9506d180f3e.info Lines: 82.8 % 128 106 22 106
Current Date: 2023-10-19 02:04:12 Functions: 64.3 % 14 9 5 9
Baseline: c8637f37369098875162f194f92736355783b050.info
Baseline Date: 2023-10-18 20:25:20

           TLA  Line data    Source code
       1                 : //! A RemoteLayer is an in-memory placeholder for a layer file that exists
       2                 : //! in remote storage.
       3                 : //!
       4                 : use crate::config::PageServerConf;
       5                 : use crate::context::RequestContext;
       6                 : use crate::repository::Key;
       7                 : use crate::tenant::remote_timeline_client::index::LayerFileMetadata;
       8                 : use crate::tenant::storage_layer::{Layer, ValueReconstructResult, ValueReconstructState};
       9                 : use crate::tenant::timeline::layer_manager::LayerManager;
      10                 : use anyhow::{bail, Result};
      11                 : use camino::Utf8PathBuf;
      12                 : use pageserver_api::models::HistoricLayerInfo;
      13                 : use std::ops::Range;
      14                 : use std::sync::Arc;
      15                 : 
      16                 : use utils::{
      17                 :     id::{TenantId, TimelineId},
      18                 :     lsn::Lsn,
      19                 : };
      20                 : 
      21                 : use super::filename::{DeltaFileName, ImageFileName};
      22                 : use super::{
      23                 :     AsLayerDesc, DeltaLayer, ImageLayer, LayerAccessStats, LayerAccessStatsReset,
      24                 :     LayerResidenceStatus, PersistentLayer, PersistentLayerDesc,
      25                 : };
      26                 : 
      27                 : /// RemoteLayer is a not yet downloaded [`ImageLayer`] or
      28                 : /// [`DeltaLayer`].
      29                 : ///
      30                 : /// RemoteLayer might be downloaded on-demand during operations which are
      31                 : /// allowed download remote layers and during which, it gets replaced with a
      32                 : /// concrete `DeltaLayer` or `ImageLayer`.
      33                 : ///
      34                 : /// See: [`crate::context::RequestContext`] for authorization to download
      35                 : pub struct RemoteLayer {
      36                 :     pub desc: PersistentLayerDesc,
      37                 : 
      38                 :     pub layer_metadata: LayerFileMetadata,
      39                 : 
      40                 :     access_stats: LayerAccessStats,
      41                 : 
      42                 :     pub(crate) ongoing_download: Arc<tokio::sync::Semaphore>,
      43                 : 
      44                 :     /// Has `LayerMap::replace` failed for this (true) or not (false).
      45                 :     ///
      46                 :     /// Used together with [`ongoing_download`] semaphore in `Timeline::download_remote_layer`.
      47                 :     /// The field is used to mark a RemoteLayer permanently (until restart or ignore+load)
      48                 :     /// unprocessable, because a LayerMap::replace failed.
      49                 :     ///
      50                 :     /// It is very unlikely to accumulate these in the Timeline's LayerMap, but having this avoids
      51                 :     /// a possible fast loop between `Timeline::get_reconstruct_data` and
      52                 :     /// `Timeline::download_remote_layer`, which also logs.
      53                 :     ///
      54                 :     /// [`ongoing_download`]: Self::ongoing_download
      55                 :     pub(crate) download_replacement_failure: std::sync::atomic::AtomicBool,
      56                 : }
      57                 : 
      58                 : impl std::fmt::Debug for RemoteLayer {
      59 UBC           0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      60               0 :         f.debug_struct("RemoteLayer")
      61               0 :             .field("file_name", &self.desc.filename())
      62               0 :             .field("layer_metadata", &self.layer_metadata)
      63               0 :             .field("is_incremental", &self.desc.is_incremental())
      64               0 :             .finish()
      65               0 :     }
      66                 : }
      67                 : 
      68                 : #[async_trait::async_trait]
      69                 : impl Layer for RemoteLayer {
      70               0 :     async fn get_value_reconstruct_data(
      71               0 :         &self,
      72               0 :         _key: Key,
      73               0 :         _lsn_range: Range<Lsn>,
      74               0 :         _reconstruct_state: &mut ValueReconstructState,
      75               0 :         _ctx: &RequestContext,
      76               0 :     ) -> Result<ValueReconstructResult> {
      77               0 :         Err(anyhow::anyhow!("layer {self} needs to be downloaded"))
      78               0 :     }
      79                 : }
      80                 : 
      81                 : /// Boilerplate to implement the Layer trait, always use layer_desc for persistent layers.
      82                 : impl std::fmt::Display for RemoteLayer {
      83 CBC        4248 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      84            4248 :         write!(f, "{}", self.layer_desc().short_id())
      85            4248 :     }
      86                 : }
      87                 : 
      88                 : impl AsLayerDesc for RemoteLayer {
      89           21227 :     fn layer_desc(&self) -> &PersistentLayerDesc {
      90           21227 :         &self.desc
      91           21227 :     }
      92                 : }
      93                 : 
      94                 : impl PersistentLayer for RemoteLayer {
      95            1424 :     fn local_path(&self) -> Option<Utf8PathBuf> {
      96            1424 :         None
      97            1424 :     }
      98                 : 
      99 UBC           0 :     fn delete_resident_layer_file(&self) -> Result<()> {
     100               0 :         bail!("remote layer has no layer file");
     101               0 :     }
     102                 : 
     103 CBC        1442 :     fn downcast_remote_layer<'a>(self: Arc<Self>) -> Option<std::sync::Arc<RemoteLayer>> {
     104            1442 :         Some(self)
     105            1442 :     }
     106                 : 
     107            2695 :     fn is_remote_layer(&self) -> bool {
     108            2695 :         true
     109            2695 :     }
     110                 : 
     111             397 :     fn info(&self, reset: LayerAccessStatsReset) -> HistoricLayerInfo {
     112             397 :         let layer_file_name = self.layer_desc().filename().file_name();
     113             397 :         let lsn_range = self.layer_desc().lsn_range.clone();
     114             397 : 
     115             397 :         if self.desc.is_delta {
     116             394 :             HistoricLayerInfo::Delta {
     117             394 :                 layer_file_name,
     118             394 :                 layer_file_size: self.layer_metadata.file_size(),
     119             394 :                 lsn_start: lsn_range.start,
     120             394 :                 lsn_end: lsn_range.end,
     121             394 :                 remote: true,
     122             394 :                 access_stats: self.access_stats.as_api_model(reset),
     123             394 :             }
     124                 :         } else {
     125               3 :             HistoricLayerInfo::Image {
     126               3 :                 layer_file_name,
     127               3 :                 layer_file_size: self.layer_metadata.file_size(),
     128               3 :                 lsn_start: lsn_range.start,
     129               3 :                 remote: true,
     130               3 :                 access_stats: self.access_stats.as_api_model(reset),
     131               3 :             }
     132                 :         }
     133             397 :     }
     134                 : 
     135 UBC           0 :     fn access_stats(&self) -> &LayerAccessStats {
     136               0 :         &self.access_stats
     137               0 :     }
     138                 : }
     139                 : 
     140                 : impl RemoteLayer {
     141 CBC        1581 :     pub fn new_img(
     142            1581 :         tenantid: TenantId,
     143            1581 :         timelineid: TimelineId,
     144            1581 :         fname: &ImageFileName,
     145            1581 :         layer_metadata: &LayerFileMetadata,
     146            1581 :         access_stats: LayerAccessStats,
     147            1581 :     ) -> RemoteLayer {
     148            1581 :         RemoteLayer {
     149            1581 :             desc: PersistentLayerDesc::new_img(
     150            1581 :                 tenantid,
     151            1581 :                 timelineid,
     152            1581 :                 fname.key_range.clone(),
     153            1581 :                 fname.lsn,
     154            1581 :                 layer_metadata.file_size(),
     155            1581 :             ),
     156            1581 :             layer_metadata: layer_metadata.clone(),
     157            1581 :             ongoing_download: Arc::new(tokio::sync::Semaphore::new(1)),
     158            1581 :             download_replacement_failure: std::sync::atomic::AtomicBool::default(),
     159            1581 :             access_stats,
     160            1581 :         }
     161            1581 :     }
     162                 : 
     163            2742 :     pub fn new_delta(
     164            2742 :         tenantid: TenantId,
     165            2742 :         timelineid: TimelineId,
     166            2742 :         fname: &DeltaFileName,
     167            2742 :         layer_metadata: &LayerFileMetadata,
     168            2742 :         access_stats: LayerAccessStats,
     169            2742 :     ) -> RemoteLayer {
     170            2742 :         RemoteLayer {
     171            2742 :             desc: PersistentLayerDesc::new_delta(
     172            2742 :                 tenantid,
     173            2742 :                 timelineid,
     174            2742 :                 fname.key_range.clone(),
     175            2742 :                 fname.lsn_range.clone(),
     176            2742 :                 layer_metadata.file_size(),
     177            2742 :             ),
     178            2742 :             layer_metadata: layer_metadata.clone(),
     179            2742 :             ongoing_download: Arc::new(tokio::sync::Semaphore::new(1)),
     180            2742 :             download_replacement_failure: std::sync::atomic::AtomicBool::default(),
     181            2742 :             access_stats,
     182            2742 :         }
     183            2742 :     }
     184                 : 
     185                 :     /// Create a Layer struct representing this layer, after it has been downloaded.
     186            1370 :     pub(crate) fn create_downloaded_layer(
     187            1370 :         &self,
     188            1370 :         _layer_map_lock_held_witness: &LayerManager,
     189            1370 :         conf: &'static PageServerConf,
     190            1370 :         file_size: u64,
     191            1370 :     ) -> Arc<dyn PersistentLayer> {
     192            1370 :         if self.desc.is_delta {
     193             369 :             let fname = self.desc.delta_file_name();
     194             369 :             Arc::new(DeltaLayer::new(
     195             369 :                 conf,
     196             369 :                 self.desc.timeline_id,
     197             369 :                 self.desc.tenant_id,
     198             369 :                 &fname,
     199             369 :                 file_size,
     200             369 :                 self.access_stats
     201             369 :                     .clone_for_residence_change(LayerResidenceStatus::Resident),
     202             369 :             ))
     203                 :         } else {
     204            1001 :             let fname = self.desc.image_file_name();
     205            1001 :             Arc::new(ImageLayer::new(
     206            1001 :                 conf,
     207            1001 :                 self.desc.timeline_id,
     208            1001 :                 self.desc.tenant_id,
     209            1001 :                 &fname,
     210            1001 :                 file_size,
     211            1001 :                 self.access_stats
     212            1001 :                     .clone_for_residence_change(LayerResidenceStatus::Resident),
     213            1001 :             ))
     214                 :         }
     215            1370 :     }
     216                 : }
        

Generated by: LCOV version 2.1-beta