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 : }
|