From 0a2797358484fe3fb712dd20bd81342b2f882c20 Mon Sep 17 00:00:00 2001 From: John Spray Date: Thu, 17 Apr 2025 14:29:16 +0100 Subject: [PATCH] pageserver: rename `Tenant` to `TenantShard` (#11589) ## Problem `Tenant` isn't really a whole tenant: it's just one shard of a tenant. ## Summary of changes - Automated rename of Tenant to TenantShard - Followup commit to change references in comments --- pageserver/src/config.rs | 10 +- pageserver/src/consumption_metrics.rs | 4 +- pageserver/src/consumption_metrics/metrics.rs | 12 +- pageserver/src/http/routes.rs | 4 +- pageserver/src/metrics.rs | 2 +- pageserver/src/page_service.rs | 2 +- pageserver/src/tenant.rs | 112 +++++++++--------- pageserver/src/tenant/mgr.rs | 65 +++++----- .../src/tenant/remote_timeline_client.rs | 8 +- .../tenant/remote_timeline_client/download.rs | 2 +- .../src/tenant/secondary/heatmap_uploader.rs | 8 +- pageserver/src/tenant/secondary/scheduler.rs | 2 +- pageserver/src/tenant/size.rs | 4 +- .../src/tenant/storage_layer/delta_layer.rs | 4 +- .../src/tenant/storage_layer/image_layer.rs | 4 +- pageserver/src/tenant/tasks.rs | 12 +- pageserver/src/tenant/timeline.rs | 24 ++-- pageserver/src/tenant/timeline/delete.rs | 16 +-- .../src/tenant/timeline/detach_ancestor.rs | 18 +-- .../src/tenant/timeline/eviction_task.rs | 16 +-- pageserver/src/tenant/timeline/offload.rs | 6 +- pageserver/src/tenant/timeline/uninit.rs | 20 ++-- 22 files changed, 184 insertions(+), 171 deletions(-) diff --git a/pageserver/src/config.rs b/pageserver/src/config.rs index 26ae6af70e..c12ac32b7e 100644 --- a/pageserver/src/config.rs +++ b/pageserver/src/config.rs @@ -118,13 +118,13 @@ pub struct PageServerConf { /// A lower value implicitly deprioritizes loading such tenants, vs. other work in the system. pub concurrent_tenant_warmup: ConfigurableSemaphore, - /// Number of concurrent [`Tenant::gather_size_inputs`](crate::tenant::Tenant::gather_size_inputs) allowed. + /// Number of concurrent [`TenantShard::gather_size_inputs`](crate::tenant::TenantShard::gather_size_inputs) allowed. pub concurrent_tenant_size_logical_size_queries: ConfigurableSemaphore, - /// Limit of concurrent [`Tenant::gather_size_inputs`] issued by module `eviction_task`. + /// Limit of concurrent [`TenantShard::gather_size_inputs`] issued by module `eviction_task`. /// The number of permits is the same as `concurrent_tenant_size_logical_size_queries`. /// See the comment in `eviction_task` for details. /// - /// [`Tenant::gather_size_inputs`]: crate::tenant::Tenant::gather_size_inputs + /// [`TenantShard::gather_size_inputs`]: crate::tenant::TenantShard::gather_size_inputs pub eviction_task_immitated_concurrent_logical_size_queries: ConfigurableSemaphore, // How often to collect metrics and send them to the metrics endpoint. @@ -588,10 +588,10 @@ impl ConfigurableSemaphore { /// Initializse using a non-zero amount of permits. /// /// Require a non-zero initial permits, because using permits == 0 is a crude way to disable a - /// feature such as [`Tenant::gather_size_inputs`]. Otherwise any semaphore using future will + /// feature such as [`TenantShard::gather_size_inputs`]. Otherwise any semaphore using future will /// behave like [`futures::future::pending`], just waiting until new permits are added. /// - /// [`Tenant::gather_size_inputs`]: crate::tenant::Tenant::gather_size_inputs + /// [`TenantShard::gather_size_inputs`]: crate::tenant::TenantShard::gather_size_inputs pub fn new(initial_permits: NonZeroUsize) -> Self { ConfigurableSemaphore { initial_permits, diff --git a/pageserver/src/consumption_metrics.rs b/pageserver/src/consumption_metrics.rs index 0231190e69..3ca82528cf 100644 --- a/pageserver/src/consumption_metrics.rs +++ b/pageserver/src/consumption_metrics.rs @@ -24,7 +24,7 @@ use crate::task_mgr::{self, BACKGROUND_RUNTIME, TaskKind}; use crate::tenant::mgr::TenantManager; use crate::tenant::size::CalculateSyntheticSizeError; use crate::tenant::tasks::BackgroundLoopKind; -use crate::tenant::{LogicalSizeCalculationCause, Tenant}; +use crate::tenant::{LogicalSizeCalculationCause, TenantShard}; mod disk_cache; mod metrics; @@ -428,7 +428,7 @@ async fn calculate_synthetic_size_worker( } } -async fn calculate_and_log(tenant: &Tenant, cancel: &CancellationToken, ctx: &RequestContext) { +async fn calculate_and_log(tenant: &TenantShard, cancel: &CancellationToken, ctx: &RequestContext) { const CAUSE: LogicalSizeCalculationCause = LogicalSizeCalculationCause::ConsumptionMetricsSyntheticSize; diff --git a/pageserver/src/consumption_metrics/metrics.rs b/pageserver/src/consumption_metrics/metrics.rs index 71910011ea..a4bfe74e30 100644 --- a/pageserver/src/consumption_metrics/metrics.rs +++ b/pageserver/src/consumption_metrics/metrics.rs @@ -175,9 +175,9 @@ impl MetricsKey { .absolute_values() } - /// [`Tenant::remote_size`] + /// [`TenantShard::remote_size`] /// - /// [`Tenant::remote_size`]: crate::tenant::Tenant::remote_size + /// [`TenantShard::remote_size`]: crate::tenant::TenantShard::remote_size const fn remote_storage_size(tenant_id: TenantId) -> AbsoluteValueFactory { MetricsKey { tenant_id, @@ -199,9 +199,9 @@ impl MetricsKey { .absolute_values() } - /// [`Tenant::cached_synthetic_size`] as refreshed by [`calculate_synthetic_size_worker`]. + /// [`TenantShard::cached_synthetic_size`] as refreshed by [`calculate_synthetic_size_worker`]. /// - /// [`Tenant::cached_synthetic_size`]: crate::tenant::Tenant::cached_synthetic_size + /// [`TenantShard::cached_synthetic_size`]: crate::tenant::TenantShard::cached_synthetic_size /// [`calculate_synthetic_size_worker`]: super::calculate_synthetic_size_worker const fn synthetic_size(tenant_id: TenantId) -> AbsoluteValueFactory { MetricsKey { @@ -254,7 +254,7 @@ pub(super) async fn collect_all_metrics( async fn collect(tenants: S, cache: &Cache, ctx: &RequestContext) -> Vec where - S: futures::stream::Stream)>, + S: futures::stream::Stream)>, { let mut current_metrics: Vec = Vec::new(); @@ -308,7 +308,7 @@ impl TenantSnapshot { /// /// `resident_size` is calculated of the timelines we had access to for other metrics, so we /// cannot just list timelines here. - fn collect(t: &Arc, resident_size: u64) -> Self { + fn collect(t: &Arc, resident_size: u64) -> Self { TenantSnapshot { resident_size, remote_size: t.remote_size(), diff --git a/pageserver/src/http/routes.rs b/pageserver/src/http/routes.rs index bbc4bfae1b..8b6500b020 100644 --- a/pageserver/src/http/routes.rs +++ b/pageserver/src/http/routes.rs @@ -1873,7 +1873,7 @@ async fn update_tenant_config_handler( &ShardParameters::default(), ); - crate::tenant::Tenant::persist_tenant_config(state.conf, &tenant_shard_id, &location_conf) + crate::tenant::TenantShard::persist_tenant_config(state.conf, &tenant_shard_id, &location_conf) .await .map_err(|e| ApiError::InternalServerError(anyhow::anyhow!(e)))?; @@ -1917,7 +1917,7 @@ async fn patch_tenant_config_handler( &ShardParameters::default(), ); - crate::tenant::Tenant::persist_tenant_config(state.conf, &tenant_shard_id, &location_conf) + crate::tenant::TenantShard::persist_tenant_config(state.conf, &tenant_shard_id, &location_conf) .await .map_err(|e| ApiError::InternalServerError(anyhow::anyhow!(e)))?; diff --git a/pageserver/src/metrics.rs b/pageserver/src/metrics.rs index 2a779b0daa..ce229bbbec 100644 --- a/pageserver/src/metrics.rs +++ b/pageserver/src/metrics.rs @@ -1086,7 +1086,7 @@ pub(crate) static TIMELINE_EPHEMERAL_BYTES: Lazy = Lazy::new(|| { .expect("Failed to register metric") }); -/// Metrics related to the lifecycle of a [`crate::tenant::Tenant`] object: things +/// Metrics related to the lifecycle of a [`crate::tenant::TenantShard`] object: things /// like how long it took to load. /// /// Note that these are process-global metrics, _not_ per-tenant metrics. Per-tenant diff --git a/pageserver/src/page_service.rs b/pageserver/src/page_service.rs index 560ac75f4a..d1a210a786 100644 --- a/pageserver/src/page_service.rs +++ b/pageserver/src/page_service.rs @@ -76,7 +76,7 @@ use crate::tenant::timeline::{self, WaitLsnError}; use crate::tenant::{GetTimelineError, PageReconstructError, Timeline}; use crate::{basebackup, timed_after_cancellation}; -/// How long we may wait for a [`crate::tenant::mgr::TenantSlot::InProgress`]` and/or a [`crate::tenant::Tenant`] which +/// How long we may wait for a [`crate::tenant::mgr::TenantSlot::InProgress`]` and/or a [`crate::tenant::TenantShard`] which /// is not yet in state [`TenantState::Active`]. /// /// NB: this is a different value than [`crate::http::routes::ACTIVE_TENANT_TIMEOUT`]. diff --git a/pageserver/src/tenant.rs b/pageserver/src/tenant.rs index 0ba70f45b2..997fc24052 100644 --- a/pageserver/src/tenant.rs +++ b/pageserver/src/tenant.rs @@ -158,7 +158,7 @@ pub struct TenantSharedResources { pub l0_flush_global_state: L0FlushGlobalState, } -/// A [`Tenant`] is really an _attached_ tenant. The configuration +/// A [`TenantShard`] is really an _attached_ tenant. The configuration /// for an attached tenant is a subset of the [`LocationConf`], represented /// in this struct. #[derive(Clone)] @@ -245,7 +245,7 @@ pub(crate) enum SpawnMode { /// /// Tenant consists of multiple timelines. Keep them in a hash table. /// -pub struct Tenant { +pub struct TenantShard { // Global pageserver config parameters pub conf: &'static PageServerConf, @@ -267,7 +267,7 @@ pub struct Tenant { shard_identity: ShardIdentity, /// The remote storage generation, used to protect S3 objects from split-brain. - /// Does not change over the lifetime of the [`Tenant`] object. + /// Does not change over the lifetime of the [`TenantShard`] object. /// /// This duplicates the generation stored in LocationConf, but that structure is mutable: /// this copy enforces the invariant that generatio doesn't change during a Tenant's lifetime. @@ -309,7 +309,7 @@ pub struct Tenant { // Access to global deletion queue for when this tenant wants to schedule a deletion deletion_queue_client: DeletionQueueClient, - /// Cached logical sizes updated updated on each [`Tenant::gather_size_inputs`]. + /// Cached logical sizes updated updated on each [`TenantShard::gather_size_inputs`]. cached_logical_sizes: tokio::sync::Mutex>, cached_synthetic_tenant_size: Arc, @@ -337,12 +337,12 @@ pub struct Tenant { // Timelines' cancellation token. pub(crate) cancel: CancellationToken, - // Users of the Tenant such as the page service must take this Gate to avoid - // trying to use a Tenant which is shutting down. + // Users of the TenantShard such as the page service must take this Gate to avoid + // trying to use a TenantShard which is shutting down. pub(crate) gate: Gate, /// Throttle applied at the top of [`Timeline::get`]. - /// All [`Tenant::timelines`] of a given [`Tenant`] instance share the same [`throttle::Throttle`] instance. + /// All [`TenantShard::timelines`] of a given [`TenantShard`] instance share the same [`throttle::Throttle`] instance. pub(crate) pagestream_throttle: Arc, pub(crate) pagestream_throttle_metrics: Arc, @@ -362,7 +362,7 @@ pub struct Tenant { l0_flush_global_state: L0FlushGlobalState, } -impl std::fmt::Debug for Tenant { +impl std::fmt::Debug for TenantShard { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{} ({})", self.tenant_shard_id, self.current_state()) } @@ -841,7 +841,7 @@ impl Debug for SetStoppingError { } } -/// Arguments to [`Tenant::create_timeline`]. +/// Arguments to [`TenantShard::create_timeline`]. /// /// Not usable as an idempotency key for timeline creation because if [`CreateTimelineParamsBranch::ancestor_start_lsn`] /// is `None`, the result of the timeline create call is not deterministic. @@ -876,7 +876,7 @@ pub(crate) struct CreateTimelineParamsImportPgdata { pub(crate) idempotency_key: import_pgdata::index_part_format::IdempotencyKey, } -/// What is used to determine idempotency of a [`Tenant::create_timeline`] call in [`Tenant::start_creating_timeline`] in [`Tenant::start_creating_timeline`]. +/// What is used to determine idempotency of a [`TenantShard::create_timeline`] call in [`TenantShard::start_creating_timeline`] in [`TenantShard::start_creating_timeline`]. /// /// Each [`Timeline`] object holds [`Self`] as an immutable property in [`Timeline::create_idempotency`]. /// @@ -914,7 +914,7 @@ pub(crate) struct CreatingTimelineIdempotencyImportPgdata { idempotency_key: import_pgdata::index_part_format::IdempotencyKey, } -/// What is returned by [`Tenant::start_creating_timeline`]. +/// What is returned by [`TenantShard::start_creating_timeline`]. #[must_use] enum StartCreatingTimelineResult { CreateGuard(TimelineCreateGuard), @@ -943,13 +943,13 @@ struct TimelineInitAndSyncNeedsSpawnImportPgdata { guard: TimelineCreateGuard, } -/// What is returned by [`Tenant::create_timeline`]. +/// What is returned by [`TenantShard::create_timeline`]. enum CreateTimelineResult { Created(Arc), Idempotent(Arc), - /// IMPORTANT: This [`Arc`] object is not in [`Tenant::timelines`] when + /// IMPORTANT: This [`Arc`] object is not in [`TenantShard::timelines`] when /// we return this result, nor will this concrete object ever be added there. - /// Cf method comment on [`Tenant::create_timeline_import_pgdata`]. + /// Cf method comment on [`TenantShard::create_timeline_import_pgdata`]. ImportSpawned(Arc), } @@ -1082,7 +1082,7 @@ pub(crate) enum LoadConfigError { NotFound(Utf8PathBuf), } -impl Tenant { +impl TenantShard { /// Yet another helper for timeline initialization. /// /// - Initializes the Timeline struct and inserts it into the tenant's hash map @@ -1303,7 +1303,7 @@ impl Tenant { init_order: Option, mode: SpawnMode, ctx: &RequestContext, - ) -> Result, GlobalShutDown> { + ) -> Result, GlobalShutDown> { let wal_redo_manager = WalRedoManager::new(PostgresRedoManager::new(conf, tenant_shard_id))?; @@ -1317,7 +1317,7 @@ impl Tenant { let attach_mode = attached_conf.location.attach_mode; let generation = attached_conf.location.generation; - let tenant = Arc::new(Tenant::new( + let tenant = Arc::new(TenantShard::new( TenantState::Attaching, conf, attached_conf, @@ -1334,7 +1334,7 @@ impl Tenant { let attach_gate_guard = tenant .gate .enter() - .expect("We just created the Tenant: nothing else can have shut it down yet"); + .expect("We just created the TenantShard: nothing else can have shut it down yet"); // Do all the hard work in the background let tenant_clone = Arc::clone(&tenant); @@ -1362,7 +1362,7 @@ impl Tenant { } } - fn make_broken_or_stopping(t: &Tenant, err: anyhow::Error) { + fn make_broken_or_stopping(t: &TenantShard, err: anyhow::Error) { t.state.send_modify(|state| match state { // TODO: the old code alluded to DeleteTenantFlow sometimes setting // TenantState::Stopping before we get here, but this may be outdated. @@ -1627,7 +1627,7 @@ impl Tenant { /// No background tasks are started as part of this routine. /// async fn attach( - self: &Arc, + self: &Arc, preload: Option, ctx: &RequestContext, ) -> anyhow::Result<()> { @@ -1957,7 +1957,7 @@ impl Tenant { } async fn load_timelines_metadata( - self: &Arc, + self: &Arc, timeline_ids: HashSet, remote_storage: &GenericRemoteStorage, heatmap: Option<(HeatMapTenant, std::time::Instant)>, @@ -2028,7 +2028,7 @@ impl Tenant { } fn load_timeline_metadata( - self: &Arc, + self: &Arc, timeline_id: TimelineId, remote_storage: GenericRemoteStorage, previous_heatmap: Option, @@ -2429,14 +2429,14 @@ impl Tenant { /// This is used by tests & import-from-basebackup. /// /// The returned [`UninitializedTimeline`] contains no data nor metadata and it is in - /// a state that will fail [`Tenant::load_remote_timeline`] because `disk_consistent_lsn=Lsn(0)`. + /// a state that will fail [`TenantShard::load_remote_timeline`] because `disk_consistent_lsn=Lsn(0)`. /// /// The caller is responsible for getting the timeline into a state that will be accepted - /// by [`Tenant::load_remote_timeline`] / [`Tenant::attach`]. + /// by [`TenantShard::load_remote_timeline`] / [`TenantShard::attach`]. /// Then they may call [`UninitializedTimeline::finish_creation`] to add the timeline - /// to the [`Tenant::timelines`]. + /// to the [`TenantShard::timelines`]. /// - /// Tests should use `Tenant::create_test_timeline` to set up the minimum required metadata keys. + /// Tests should use `TenantShard::create_test_timeline` to set up the minimum required metadata keys. pub(crate) async fn create_empty_timeline( self: &Arc, new_timeline_id: TimelineId, @@ -2584,7 +2584,7 @@ impl Tenant { /// the same timeline ID already exists, returns CreateTimelineError::AlreadyExists. #[allow(clippy::too_many_arguments)] pub(crate) async fn create_timeline( - self: &Arc, + self: &Arc, params: CreateTimelineParams, broker_client: storage_broker::BrokerClientChannel, ctx: &RequestContext, @@ -2751,13 +2751,13 @@ impl Tenant { Ok(activated_timeline) } - /// The returned [`Arc`] is NOT in the [`Tenant::timelines`] map until the import + /// The returned [`Arc`] is NOT in the [`TenantShard::timelines`] map until the import /// completes in the background. A DIFFERENT [`Arc`] will be inserted into the - /// [`Tenant::timelines`] map when the import completes. + /// [`TenantShard::timelines`] map when the import completes. /// We only return an [`Arc`] here so the API handler can create a [`pageserver_api::models::TimelineInfo`] /// for the response. async fn create_timeline_import_pgdata( - self: &Arc, + self: &Arc, params: CreateTimelineParamsImportPgdata, activate: ActivateTimelineArgs, ctx: &RequestContext, @@ -2854,7 +2854,7 @@ impl Tenant { #[instrument(skip_all, fields(tenant_id=%self.tenant_shard_id.tenant_id, shard_id=%self.tenant_shard_id.shard_slug(), timeline_id=%timeline.timeline_id))] async fn create_timeline_import_pgdata_task( - self: Arc, + self: Arc, timeline: Arc, index_part: import_pgdata::index_part_format::Root, activate: ActivateTimelineArgs, @@ -2882,7 +2882,7 @@ impl Tenant { } async fn create_timeline_import_pgdata_task_impl( - self: Arc, + self: Arc, timeline: Arc, index_part: import_pgdata::index_part_format::Root, activate: ActivateTimelineArgs, @@ -2899,10 +2899,10 @@ impl Tenant { // Reload timeline from remote. // This proves that the remote state is attachable, and it reuses the code. // - // TODO: think about whether this is safe to do with concurrent Tenant::shutdown. + // TODO: think about whether this is safe to do with concurrent TenantShard::shutdown. // timeline_create_guard hols the tenant gate open, so, shutdown cannot _complete_ until we exit. - // But our activate() call might launch new background tasks after Tenant::shutdown - // already went past shutting down the Tenant::timelines, which this timeline here is no part of. + // But our activate() call might launch new background tasks after TenantShard::shutdown + // already went past shutting down the TenantShard::timelines, which this timeline here is no part of. // I think the same problem exists with the bootstrap & branch mgmt API tasks (tenant shutting // down while bootstrapping/branching + activating), but, the race condition is much more likely // to manifest because of the long runtime of this import task. @@ -2917,7 +2917,7 @@ impl Tenant { // }; let timeline_id = timeline.timeline_id; - // load from object storage like Tenant::attach does + // load from object storage like TenantShard::attach does let resources = self.build_timeline_resources(timeline_id); let index_part = resources .remote_client @@ -3938,7 +3938,7 @@ enum ActivateTimelineArgs { No, } -impl Tenant { +impl TenantShard { pub fn tenant_specific_overrides(&self) -> pageserver_api::models::TenantConfig { self.tenant_conf.load().tenant_conf.clone() } @@ -4096,7 +4096,7 @@ impl Tenant { update: F, ) -> anyhow::Result { // Use read-copy-update in order to avoid overwriting the location config - // state if this races with [`Tenant::set_new_location_config`]. Note that + // state if this races with [`TenantShard::set_new_location_config`]. Note that // this race is not possible if both request types come from the storage // controller (as they should!) because an exclusive op lock is required // on the storage controller side. @@ -4219,7 +4219,7 @@ impl Tenant { Ok((timeline, timeline_ctx)) } - /// [`Tenant::shutdown`] must be called before dropping the returned [`Tenant`] object + /// [`TenantShard::shutdown`] must be called before dropping the returned [`TenantShard`] object /// to ensure proper cleanup of background tasks and metrics. // // Allow too_many_arguments because a constructor's argument list naturally grows with the @@ -4235,7 +4235,7 @@ impl Tenant { remote_storage: GenericRemoteStorage, deletion_queue_client: DeletionQueueClient, l0_flush_global_state: L0FlushGlobalState, - ) -> Tenant { + ) -> TenantShard { debug_assert!( !attached_conf.location.generation.is_none() || conf.control_plane_api.is_none() ); @@ -4295,7 +4295,7 @@ impl Tenant { } }); - Tenant { + TenantShard { tenant_shard_id, shard_identity, generation: attached_conf.location.generation, @@ -4330,7 +4330,7 @@ impl Tenant { cancel: CancellationToken::default(), gate: Gate::default(), pagestream_throttle: Arc::new(throttle::Throttle::new( - Tenant::get_pagestream_throttle_config(conf, &attached_conf.tenant_conf), + TenantShard::get_pagestream_throttle_config(conf, &attached_conf.tenant_conf), )), pagestream_throttle_metrics: Arc::new( crate::metrics::tenant_throttling::Pagestream::new(&tenant_shard_id), @@ -4466,11 +4466,11 @@ impl Tenant { // Perform GC for each timeline. // - // Note that we don't hold the `Tenant::gc_cs` lock here because we don't want to delay the + // Note that we don't hold the `TenantShard::gc_cs` lock here because we don't want to delay the // branch creation task, which requires the GC lock. A GC iteration can run concurrently // with branch creation. // - // See comments in [`Tenant::branch_timeline`] for more information about why branch + // See comments in [`TenantShard::branch_timeline`] for more information about why branch // creation task can run concurrently with timeline's GC iteration. for timeline in gc_timelines { if cancel.is_cancelled() { @@ -4500,7 +4500,7 @@ impl Tenant { /// Refreshes the Timeline::gc_info for all timelines, returning the /// vector of timelines which have [`Timeline::get_last_record_lsn`] past - /// [`Tenant::get_gc_horizon`]. + /// [`TenantShard::get_gc_horizon`]. /// /// This is usually executed as part of periodic gc, but can now be triggered more often. pub(crate) async fn refresh_gc_info( @@ -5499,7 +5499,7 @@ impl Tenant { } } - // The flushes we did above were just writes, but the Tenant might have had + // The flushes we did above were just writes, but the TenantShard might have had // pending deletions as well from recent compaction/gc: we want to flush those // as well. This requires flushing the global delete queue. This is cheap // because it's typically a no-op. @@ -5517,7 +5517,7 @@ impl Tenant { /// How much local storage would this tenant like to have? It can cope with /// less than this (via eviction and on-demand downloads), but this function enables - /// the Tenant to advertise how much storage it would prefer to have to provide fast I/O + /// the TenantShard to advertise how much storage it would prefer to have to provide fast I/O /// by keeping important things on local disk. /// /// This is a heuristic, not a guarantee: tenants that are long-idle will actually use less @@ -5540,11 +5540,11 @@ impl Tenant { /// manifest in `Self::remote_tenant_manifest`. /// /// TODO: instead of requiring callers to remember to call `maybe_upload_tenant_manifest` after - /// changing any `Tenant` state that's included in the manifest, consider making the manifest + /// changing any `TenantShard` state that's included in the manifest, consider making the manifest /// the authoritative source of data with an API that automatically uploads on changes. Revisit /// this when the manifest is more widely used and we have a better idea of the data model. pub(crate) async fn maybe_upload_tenant_manifest(&self) -> Result<(), TenantManifestError> { - // Multiple tasks may call this function concurrently after mutating the Tenant runtime + // Multiple tasks may call this function concurrently after mutating the TenantShard runtime // state, affecting the manifest generated by `build_tenant_manifest`. We use an async mutex // to serialize these callers. `eq_ignoring_version` acts as a slightly inefficient but // simple coalescing mechanism. @@ -5812,7 +5812,7 @@ pub(crate) mod harness { info_span!("TenantHarness", tenant_id=%self.tenant_shard_id.tenant_id, shard_id=%self.tenant_shard_id.shard_slug()) } - pub(crate) async fn load(&self) -> (Arc, RequestContext) { + pub(crate) async fn load(&self) -> (Arc, RequestContext) { let ctx = RequestContext::new(TaskKind::UnitTest, DownloadBehavior::Error) .with_scope_unit_test(); ( @@ -5827,10 +5827,10 @@ pub(crate) mod harness { pub(crate) async fn do_try_load( &self, ctx: &RequestContext, - ) -> anyhow::Result> { + ) -> anyhow::Result> { let walredo_mgr = Arc::new(WalRedoManager::from(TestRedoManager)); - let tenant = Arc::new(Tenant::new( + let tenant = Arc::new(TenantShard::new( TenantState::Attaching, self.conf, AttachedTenantConf::try_from(LocationConf::attached_single( @@ -6046,7 +6046,7 @@ mod tests { #[cfg(feature = "testing")] #[allow(clippy::too_many_arguments)] async fn randomize_timeline( - tenant: &Arc, + tenant: &Arc, new_timeline_id: TimelineId, pg_version: u32, spec: TestTimelineSpecification, @@ -6936,7 +6936,7 @@ mod tests { } async fn bulk_insert_compact_gc( - tenant: &Tenant, + tenant: &TenantShard, timeline: &Arc, ctx: &RequestContext, lsn: Lsn, @@ -6948,7 +6948,7 @@ mod tests { } async fn bulk_insert_maybe_compact_gc( - tenant: &Tenant, + tenant: &TenantShard, timeline: &Arc, ctx: &RequestContext, mut lsn: Lsn, @@ -7858,7 +7858,7 @@ mod tests { let (tline, _ctx) = tenant .create_empty_timeline(TIMELINE_ID, Lsn(0), DEFAULT_PG_VERSION, &ctx) .await?; - // Leave the timeline ID in [`Tenant::timelines_creating`] to exclude attempting to create it again + // Leave the timeline ID in [`TenantShard::timelines_creating`] to exclude attempting to create it again let raw_tline = tline.raw_timeline().unwrap(); raw_tline .shutdown(super::timeline::ShutdownMode::Hard) diff --git a/pageserver/src/tenant/mgr.rs b/pageserver/src/tenant/mgr.rs index ac81b8e3d7..2ae7e1e875 100644 --- a/pageserver/src/tenant/mgr.rs +++ b/pageserver/src/tenant/mgr.rs @@ -52,7 +52,9 @@ use crate::tenant::config::{ use crate::tenant::span::debug_assert_current_span_has_tenant_id; use crate::tenant::storage_layer::inmemory_layer; use crate::tenant::timeline::ShutdownMode; -use crate::tenant::{AttachedTenantConf, GcError, LoadConfigError, SpawnMode, Tenant, TenantState}; +use crate::tenant::{ + AttachedTenantConf, GcError, LoadConfigError, SpawnMode, TenantShard, TenantState, +}; use crate::virtual_file::MaybeFatalIo; use crate::{InitializationOrder, TEMP_FILE_SUFFIX}; @@ -67,7 +69,7 @@ use crate::{InitializationOrder, TEMP_FILE_SUFFIX}; /// having a properly acquired generation (Secondary doesn't need a generation) #[derive(Clone)] pub(crate) enum TenantSlot { - Attached(Arc), + Attached(Arc), Secondary(Arc), /// In this state, other administrative operations acting on the TenantId should /// block, or return a retry indicator equivalent to HTTP 503. @@ -86,7 +88,7 @@ impl std::fmt::Debug for TenantSlot { impl TenantSlot { /// Return the `Tenant` in this slot if attached, else None - fn get_attached(&self) -> Option<&Arc> { + fn get_attached(&self) -> Option<&Arc> { match self { Self::Attached(t) => Some(t), Self::Secondary(_) => None, @@ -164,7 +166,7 @@ impl TenantStartupMode { /// Result type for looking up a TenantId to a specific shard pub(crate) enum ShardResolveResult { NotFound, - Found(Arc), + Found(Arc), // Wait for this barrrier, then query again InProgress(utils::completion::Barrier), } @@ -173,7 +175,7 @@ impl TenantsMap { /// Convenience function for typical usage, where we want to get a `Tenant` object, for /// working with attached tenants. If the TenantId is in the map but in Secondary state, /// None is returned. - pub(crate) fn get(&self, tenant_shard_id: &TenantShardId) -> Option<&Arc> { + pub(crate) fn get(&self, tenant_shard_id: &TenantShardId) -> Option<&Arc> { match self { TenantsMap::Initializing => None, TenantsMap::Open(m) | TenantsMap::ShuttingDown(m) => { @@ -410,7 +412,7 @@ fn load_tenant_config( return None; } - Some(Tenant::load_tenant_config(conf, &tenant_shard_id)) + Some(TenantShard::load_tenant_config(conf, &tenant_shard_id)) } /// Initial stage of load: walk the local tenants directory, clean up any temp files, @@ -606,7 +608,8 @@ pub async fn init_tenant_mgr( // Presence of a generation number implies attachment: attach the tenant // if it wasn't already, and apply the generation number. config_write_futs.push(async move { - let r = Tenant::persist_tenant_config(conf, &tenant_shard_id, &location_conf).await; + let r = + TenantShard::persist_tenant_config(conf, &tenant_shard_id, &location_conf).await; (tenant_shard_id, location_conf, r) }); } @@ -694,7 +697,7 @@ fn tenant_spawn( init_order: Option, mode: SpawnMode, ctx: &RequestContext, -) -> Result, GlobalShutDown> { +) -> Result, GlobalShutDown> { // All these conditions should have been satisfied by our caller: the tenant dir exists, is a well formed // path, and contains a configuration file. Assertions that do synchronous I/O are limited to debug mode // to avoid impacting prod runtime performance. @@ -706,7 +709,7 @@ fn tenant_spawn( .unwrap() ); - Tenant::spawn( + TenantShard::spawn( conf, tenant_shard_id, resources, @@ -883,12 +886,12 @@ impl TenantManager { /// Gets the attached tenant from the in-memory data, erroring if it's absent, in secondary mode, or currently /// undergoing a state change (i.e. slot is InProgress). /// - /// The return Tenant is not guaranteed to be active: check its status after obtaing it, or - /// use [`Tenant::wait_to_become_active`] before using it if you will do I/O on it. + /// The return TenantShard is not guaranteed to be active: check its status after obtaing it, or + /// use [`TenantShard::wait_to_become_active`] before using it if you will do I/O on it. pub(crate) fn get_attached_tenant_shard( &self, tenant_shard_id: TenantShardId, - ) -> Result, GetTenantError> { + ) -> Result, GetTenantError> { let locked = self.tenants.read().unwrap(); let peek_slot = tenant_map_peek_slot(&locked, &tenant_shard_id, TenantSlotPeekMode::Read)?; @@ -937,12 +940,12 @@ impl TenantManager { flush: Option, mut spawn_mode: SpawnMode, ctx: &RequestContext, - ) -> Result>, UpsertLocationError> { + ) -> Result>, UpsertLocationError> { debug_assert_current_span_has_tenant_id(); info!("configuring tenant location to state {new_location_config:?}"); enum FastPathModified { - Attached(Arc), + Attached(Arc), Secondary(Arc), } @@ -999,9 +1002,13 @@ impl TenantManager { // phase of writing config and/or waiting for flush, before returning. match fast_path_taken { Some(FastPathModified::Attached(tenant)) => { - Tenant::persist_tenant_config(self.conf, &tenant_shard_id, &new_location_config) - .await - .fatal_err("write tenant shard config"); + TenantShard::persist_tenant_config( + self.conf, + &tenant_shard_id, + &new_location_config, + ) + .await + .fatal_err("write tenant shard config"); // Transition to AttachedStale means we may well hold a valid generation // still, and have been requested to go stale as part of a migration. If @@ -1030,9 +1037,13 @@ impl TenantManager { return Ok(Some(tenant)); } Some(FastPathModified::Secondary(_secondary_tenant)) => { - Tenant::persist_tenant_config(self.conf, &tenant_shard_id, &new_location_config) - .await - .fatal_err("write tenant shard config"); + TenantShard::persist_tenant_config( + self.conf, + &tenant_shard_id, + &new_location_config, + ) + .await + .fatal_err("write tenant shard config"); return Ok(None); } @@ -1122,7 +1133,7 @@ impl TenantManager { // Before activating either secondary or attached mode, persist the // configuration, so that on restart we will re-attach (or re-start // secondary) on the tenant. - Tenant::persist_tenant_config(self.conf, &tenant_shard_id, &new_location_config) + TenantShard::persist_tenant_config(self.conf, &tenant_shard_id, &new_location_config) .await .fatal_err("write tenant shard config"); @@ -1262,7 +1273,7 @@ impl TenantManager { let tenant_path = self.conf.tenant_path(&tenant_shard_id); let timelines_path = self.conf.timelines_path(&tenant_shard_id); - let config = Tenant::load_tenant_config(self.conf, &tenant_shard_id)?; + let config = TenantShard::load_tenant_config(self.conf, &tenant_shard_id)?; if drop_cache { tracing::info!("Dropping local file cache"); @@ -1297,7 +1308,7 @@ impl TenantManager { Ok(()) } - pub(crate) fn get_attached_active_tenant_shards(&self) -> Vec> { + pub(crate) fn get_attached_active_tenant_shards(&self) -> Vec> { let locked = self.tenants.read().unwrap(); match &*locked { TenantsMap::Initializing => Vec::new(), @@ -1446,7 +1457,7 @@ impl TenantManager { #[instrument(skip_all, fields(tenant_id=%tenant.get_tenant_shard_id().tenant_id, shard_id=%tenant.get_tenant_shard_id().shard_slug(), new_shard_count=%new_shard_count.literal()))] pub(crate) async fn shard_split( &self, - tenant: Arc, + tenant: Arc, new_shard_count: ShardCount, new_stripe_size: Option, ctx: &RequestContext, @@ -1476,7 +1487,7 @@ impl TenantManager { pub(crate) async fn do_shard_split( &self, - tenant: Arc, + tenant: Arc, new_shard_count: ShardCount, new_stripe_size: Option, ctx: &RequestContext, @@ -1703,7 +1714,7 @@ impl TenantManager { /// For each resident layer in the parent shard, we will hard link it into all of the child shards. async fn shard_split_hardlink( &self, - parent_shard: &Tenant, + parent_shard: &TenantShard, child_shards: Vec, ) -> anyhow::Result<()> { debug_assert_current_span_has_tenant_id(); @@ -1988,7 +1999,7 @@ impl TenantManager { } let tenant_path = self.conf.tenant_path(&tenant_shard_id); - let config = Tenant::load_tenant_config(self.conf, &tenant_shard_id) + let config = TenantShard::load_tenant_config(self.conf, &tenant_shard_id) .map_err(|e| Error::DetachReparent(e.into()))?; let shard_identity = config.shard; diff --git a/pageserver/src/tenant/remote_timeline_client.rs b/pageserver/src/tenant/remote_timeline_client.rs index 10a13ef1a2..ea29f51956 100644 --- a/pageserver/src/tenant/remote_timeline_client.rs +++ b/pageserver/src/tenant/remote_timeline_client.rs @@ -133,7 +133,7 @@ //! - Initiate upload queue with that [`IndexPart`]. //! - Reschedule all lost operations by comparing the local filesystem state //! and remote state as per [`IndexPart`]. This is done in -//! [`Tenant::timeline_init_and_sync`]. +//! [`TenantShard::timeline_init_and_sync`]. //! //! Note that if we crash during file deletion between the index update //! that removes the file from the list of files, and deleting the remote file, @@ -171,7 +171,7 @@ //! If no remote storage configuration is provided, the [`RemoteTimelineClient`] is //! not created and the uploads are skipped. //! -//! [`Tenant::timeline_init_and_sync`]: super::Tenant::timeline_init_and_sync +//! [`TenantShard::timeline_init_and_sync`]: super::TenantShard::timeline_init_and_sync //! [`Timeline::load_layer_map`]: super::Timeline::load_layer_map pub(crate) mod download; @@ -2743,7 +2743,7 @@ mod tests { use crate::tenant::config::AttachmentMode; use crate::tenant::harness::{TIMELINE_ID, TenantHarness}; use crate::tenant::storage_layer::layer::local_layer_path; - use crate::tenant::{Tenant, Timeline}; + use crate::tenant::{TenantShard, Timeline}; pub(super) fn dummy_contents(name: &str) -> Vec { format!("contents for {name}").into() @@ -2796,7 +2796,7 @@ mod tests { struct TestSetup { harness: TenantHarness, - tenant: Arc, + tenant: Arc, timeline: Arc, tenant_ctx: RequestContext, } diff --git a/pageserver/src/tenant/remote_timeline_client/download.rs b/pageserver/src/tenant/remote_timeline_client/download.rs index 8b399996d5..70f77ef9e8 100644 --- a/pageserver/src/tenant/remote_timeline_client/download.rs +++ b/pageserver/src/tenant/remote_timeline_client/download.rs @@ -452,7 +452,7 @@ async fn do_download_index_part( /// generation (normal case when migrating/restarting). Only if both of these return 404 do we fall back /// to listing objects. /// -/// * `my_generation`: the value of `[crate::tenant::Tenant::generation]` +/// * `my_generation`: the value of `[crate::tenant::TenantShard::generation]` /// * `what`: for logging, what object are we downloading /// * `prefix`: when listing objects, use this prefix (i.e. the part of the object path before the generation) /// * `do_download`: a GET of the object in a particular generation, which should **retry indefinitely** unless diff --git a/pageserver/src/tenant/secondary/heatmap_uploader.rs b/pageserver/src/tenant/secondary/heatmap_uploader.rs index 3375714a66..46bc0ef235 100644 --- a/pageserver/src/tenant/secondary/heatmap_uploader.rs +++ b/pageserver/src/tenant/secondary/heatmap_uploader.rs @@ -21,7 +21,7 @@ use super::scheduler::{ use super::{CommandRequest, SecondaryTenantError, UploadCommand}; use crate::TEMP_FILE_SUFFIX; use crate::metrics::SECONDARY_MODE; -use crate::tenant::Tenant; +use crate::tenant::TenantShard; use crate::tenant::config::AttachmentMode; use crate::tenant::mgr::{GetTenantError, TenantManager}; use crate::tenant::remote_timeline_client::remote_heatmap_path; @@ -74,7 +74,7 @@ impl RunningJob for WriteInProgress { } struct UploadPending { - tenant: Arc, + tenant: Arc, last_upload: Option, target_time: Option, period: Option, @@ -106,7 +106,7 @@ impl scheduler::Completion for WriteComplete { struct UploaderTenantState { // This Weak only exists to enable culling idle instances of this type // when the Tenant has been deallocated. - tenant: Weak, + tenant: Weak, /// Digest of the serialized heatmap that we last successfully uploaded last_upload_state: Option, @@ -357,7 +357,7 @@ struct LastUploadState { /// of the object we would have uploaded. async fn upload_tenant_heatmap( remote_storage: GenericRemoteStorage, - tenant: &Arc, + tenant: &Arc, last_upload: Option, ) -> Result { debug_assert_current_span_has_tenant_id(); diff --git a/pageserver/src/tenant/secondary/scheduler.rs b/pageserver/src/tenant/secondary/scheduler.rs index f948f9114f..62ca527bbc 100644 --- a/pageserver/src/tenant/secondary/scheduler.rs +++ b/pageserver/src/tenant/secondary/scheduler.rs @@ -360,7 +360,7 @@ where /// Periodic execution phase: inspect all attached tenants and schedule any work they require. /// - /// The type in `tenants` should be a tenant-like structure, e.g. [`crate::tenant::Tenant`] or [`crate::tenant::secondary::SecondaryTenant`] + /// The type in `tenants` should be a tenant-like structure, e.g. [`crate::tenant::TenantShard`] or [`crate::tenant::secondary::SecondaryTenant`] /// /// This function resets the pending list: it is assumed that the caller may change their mind about /// which tenants need work between calls to schedule_iteration. diff --git a/pageserver/src/tenant/size.rs b/pageserver/src/tenant/size.rs index c7ac50ca6a..bf5d9bc87a 100644 --- a/pageserver/src/tenant/size.rs +++ b/pageserver/src/tenant/size.rs @@ -12,7 +12,7 @@ use tracing::*; use utils::id::TimelineId; use utils::lsn::Lsn; -use super::{GcError, LogicalSizeCalculationCause, Tenant}; +use super::{GcError, LogicalSizeCalculationCause, TenantShard}; use crate::context::RequestContext; use crate::pgdatadir_mapping::CalculateLogicalSizeError; use crate::tenant::{MaybeOffloaded, Timeline}; @@ -156,7 +156,7 @@ pub struct TimelineInputs { /// initdb_lsn branchpoints* next_pitr_cutoff latest /// ``` pub(super) async fn gather_inputs( - tenant: &Tenant, + tenant: &TenantShard, limit: &Arc, max_retention_period: Option, logical_size_cache: &mut HashMap<(TimelineId, Lsn), u64>, diff --git a/pageserver/src/tenant/storage_layer/delta_layer.rs b/pageserver/src/tenant/storage_layer/delta_layer.rs index 4417b8aa51..0654342a25 100644 --- a/pageserver/src/tenant/storage_layer/delta_layer.rs +++ b/pageserver/src/tenant/storage_layer/delta_layer.rs @@ -1620,7 +1620,7 @@ pub(crate) mod test { use crate::tenant::harness::{TIMELINE_ID, TenantHarness}; use crate::tenant::storage_layer::{Layer, ResidentLayer}; use crate::tenant::vectored_blob_io::StreamingVectoredReadPlanner; - use crate::tenant::{Tenant, Timeline}; + use crate::tenant::{TenantShard, Timeline}; /// Construct an index for a fictional delta layer and and then /// traverse in order to plan vectored reads for a query. Finally, @@ -2209,7 +2209,7 @@ pub(crate) mod test { } pub(crate) async fn produce_delta_layer( - tenant: &Tenant, + tenant: &TenantShard, tline: &Arc, mut deltas: Vec<(Key, Lsn, Value)>, ctx: &RequestContext, diff --git a/pageserver/src/tenant/storage_layer/image_layer.rs b/pageserver/src/tenant/storage_layer/image_layer.rs index c2de20b5b3..8ee4cdee66 100644 --- a/pageserver/src/tenant/storage_layer/image_layer.rs +++ b/pageserver/src/tenant/storage_layer/image_layer.rs @@ -1228,7 +1228,7 @@ mod test { use crate::tenant::harness::{TIMELINE_ID, TenantHarness}; use crate::tenant::storage_layer::{Layer, ResidentLayer}; use crate::tenant::vectored_blob_io::StreamingVectoredReadPlanner; - use crate::tenant::{Tenant, Timeline}; + use crate::tenant::{TenantShard, Timeline}; #[tokio::test] async fn image_layer_rewrite() { @@ -1410,7 +1410,7 @@ mod test { } async fn produce_image_layer( - tenant: &Tenant, + tenant: &TenantShard, tline: &Arc, mut images: Vec<(Key, Bytes)>, lsn: Lsn, diff --git a/pageserver/src/tenant/tasks.rs b/pageserver/src/tenant/tasks.rs index 54588e788c..1112a5330b 100644 --- a/pageserver/src/tenant/tasks.rs +++ b/pageserver/src/tenant/tasks.rs @@ -24,7 +24,7 @@ use crate::task_mgr::{self, BACKGROUND_RUNTIME, TOKIO_WORKER_THREADS, TaskKind}; use crate::tenant::throttle::Stats; use crate::tenant::timeline::CompactionError; use crate::tenant::timeline::compaction::CompactionOutcome; -use crate::tenant::{Tenant, TenantState}; +use crate::tenant::{TenantShard, TenantState}; /// Semaphore limiting concurrent background tasks (across all tenants). /// @@ -117,7 +117,7 @@ pub(crate) async fn acquire_concurrency_permit( } /// Start per tenant background loops: compaction, GC, and ingest housekeeping. -pub fn start_background_loops(tenant: &Arc, can_start: Option<&Barrier>) { +pub fn start_background_loops(tenant: &Arc, can_start: Option<&Barrier>) { let tenant_shard_id = tenant.tenant_shard_id; task_mgr::spawn( @@ -198,7 +198,7 @@ pub fn start_background_loops(tenant: &Arc, can_start: Option<&Barrier>) } /// Compaction task's main loop. -async fn compaction_loop(tenant: Arc, cancel: CancellationToken) { +async fn compaction_loop(tenant: Arc, cancel: CancellationToken) { const BASE_BACKOFF_SECS: f64 = 1.0; const MAX_BACKOFF_SECS: f64 = 300.0; const RECHECK_CONFIG_INTERVAL: Duration = Duration::from_secs(10); @@ -348,7 +348,7 @@ pub(crate) fn log_compaction_error( } /// GC task's main loop. -async fn gc_loop(tenant: Arc, cancel: CancellationToken) { +async fn gc_loop(tenant: Arc, cancel: CancellationToken) { const MAX_BACKOFF_SECS: f64 = 300.0; let mut error_run = 0; // consecutive errors @@ -432,7 +432,7 @@ async fn gc_loop(tenant: Arc, cancel: CancellationToken) { } /// Tenant housekeeping's main loop. -async fn tenant_housekeeping_loop(tenant: Arc, cancel: CancellationToken) { +async fn tenant_housekeeping_loop(tenant: Arc, cancel: CancellationToken) { let mut last_throttle_flag_reset_at = Instant::now(); loop { if wait_for_active_tenant(&tenant, &cancel).await.is_break() { @@ -483,7 +483,7 @@ async fn tenant_housekeeping_loop(tenant: Arc, cancel: CancellationToken /// Waits until the tenant becomes active, or returns `ControlFlow::Break()` to shut down. async fn wait_for_active_tenant( - tenant: &Arc, + tenant: &Arc, cancel: &CancellationToken, ) -> ControlFlow<()> { if tenant.current_state() == TenantState::Active { diff --git a/pageserver/src/tenant/timeline.rs b/pageserver/src/tenant/timeline.rs index bc54c85119..5b126d516b 100644 --- a/pageserver/src/tenant/timeline.rs +++ b/pageserver/src/tenant/timeline.rs @@ -412,7 +412,7 @@ pub struct Timeline { /// Timeline deletion will acquire both compaction and gc locks in whatever order. gc_lock: tokio::sync::Mutex<()>, - /// Cloned from [`super::Tenant::pagestream_throttle`] on construction. + /// Cloned from [`super::TenantShard::pagestream_throttle`] on construction. pub(crate) pagestream_throttle: Arc, /// Size estimator for aux file v2 @@ -2065,7 +2065,7 @@ impl Timeline { pub(crate) fn activate( self: &Arc, - parent: Arc, + parent: Arc, broker_client: BrokerClientChannel, background_jobs_can_start: Option<&completion::Barrier>, ctx: &RequestContext, @@ -3325,7 +3325,7 @@ impl Timeline { // (1) and (4) // TODO: this is basically a no-op now, should we remove it? self.remote_client.schedule_barrier()?; - // Tenant::create_timeline will wait for these uploads to happen before returning, or + // TenantShard::create_timeline will wait for these uploads to happen before returning, or // on retry. // Now that we have the full layer map, we may calculate the visibility of layers within it (a global scan) @@ -5754,7 +5754,7 @@ impl Timeline { /// from our ancestor to be branches of this timeline. pub(crate) async fn prepare_to_detach_from_ancestor( self: &Arc, - tenant: &crate::tenant::Tenant, + tenant: &crate::tenant::TenantShard, options: detach_ancestor::Options, behavior: DetachBehavior, ctx: &RequestContext, @@ -5773,7 +5773,7 @@ impl Timeline { /// resetting the tenant. pub(crate) async fn detach_from_ancestor_and_reparent( self: &Arc, - tenant: &crate::tenant::Tenant, + tenant: &crate::tenant::TenantShard, prepared: detach_ancestor::PreparedTimelineDetach, ancestor_timeline_id: TimelineId, ancestor_lsn: Lsn, @@ -5797,7 +5797,7 @@ impl Timeline { /// The tenant must've been reset if ancestry was modified previously (in tenant manager). pub(crate) async fn complete_detaching_timeline_ancestor( self: &Arc, - tenant: &crate::tenant::Tenant, + tenant: &crate::tenant::TenantShard, attempt: detach_ancestor::Attempt, ctx: &RequestContext, ) -> Result<(), detach_ancestor::Error> { @@ -6859,14 +6859,14 @@ impl Timeline { /// Persistently blocks gc for `Manual` reason. /// /// Returns true if no such block existed before, false otherwise. - pub(crate) async fn block_gc(&self, tenant: &super::Tenant) -> anyhow::Result { + pub(crate) async fn block_gc(&self, tenant: &super::TenantShard) -> anyhow::Result { use crate::tenant::remote_timeline_client::index::GcBlockingReason; assert_eq!(self.tenant_shard_id, tenant.tenant_shard_id); tenant.gc_block.insert(self, GcBlockingReason::Manual).await } /// Persistently unblocks gc for `Manual` reason. - pub(crate) async fn unblock_gc(&self, tenant: &super::Tenant) -> anyhow::Result<()> { + pub(crate) async fn unblock_gc(&self, tenant: &super::TenantShard) -> anyhow::Result<()> { use crate::tenant::remote_timeline_client::index::GcBlockingReason; assert_eq!(self.tenant_shard_id, tenant.tenant_shard_id); tenant.gc_block.remove(self, GcBlockingReason::Manual).await @@ -6884,8 +6884,8 @@ impl Timeline { /// Force create an image layer and place it into the layer map. /// - /// DO NOT use this function directly. Use [`Tenant::branch_timeline_test_with_layers`] - /// or [`Tenant::create_test_timeline_with_layers`] to ensure all these layers are + /// DO NOT use this function directly. Use [`TenantShard::branch_timeline_test_with_layers`] + /// or [`TenantShard::create_test_timeline_with_layers`] to ensure all these layers are /// placed into the layer map in one run AND be validated. #[cfg(test)] pub(super) async fn force_create_image_layer( @@ -6941,8 +6941,8 @@ impl Timeline { /// Force create a delta layer and place it into the layer map. /// - /// DO NOT use this function directly. Use [`Tenant::branch_timeline_test_with_layers`] - /// or [`Tenant::create_test_timeline_with_layers`] to ensure all these layers are + /// DO NOT use this function directly. Use [`TenantShard::branch_timeline_test_with_layers`] + /// or [`TenantShard::create_test_timeline_with_layers`] to ensure all these layers are /// placed into the layer map in one run AND be validated. #[cfg(test)] pub(super) async fn force_create_delta_layer( diff --git a/pageserver/src/tenant/timeline/delete.rs b/pageserver/src/tenant/timeline/delete.rs index 64fcf1fe0d..1d4dd05e34 100644 --- a/pageserver/src/tenant/timeline/delete.rs +++ b/pageserver/src/tenant/timeline/delete.rs @@ -18,8 +18,8 @@ use crate::tenant::remote_timeline_client::{ PersistIndexPartWithDeletedFlagError, RemoteTimelineClient, }; use crate::tenant::{ - CreateTimelineCause, DeleteTimelineError, MaybeDeletedIndexPart, Tenant, TenantManifestError, - Timeline, TimelineOrOffloaded, + CreateTimelineCause, DeleteTimelineError, MaybeDeletedIndexPart, TenantManifestError, + TenantShard, Timeline, TimelineOrOffloaded, }; use crate::virtual_file::MaybeFatalIo; @@ -113,7 +113,7 @@ pub(super) async fn delete_local_timeline_directory( /// It is important that this gets called when DeletionGuard is being held. /// For more context see comments in [`make_timeline_delete_guard`] async fn remove_maybe_offloaded_timeline_from_tenant( - tenant: &Tenant, + tenant: &TenantShard, timeline: &TimelineOrOffloaded, _: &DeletionGuard, // using it as a witness ) -> anyhow::Result<()> { @@ -192,7 +192,7 @@ impl DeleteTimelineFlow { // error out if some of the shutdown tasks have already been completed! #[instrument(skip_all)] pub async fn run( - tenant: &Arc, + tenant: &Arc, timeline_id: TimelineId, ) -> Result<(), DeleteTimelineError> { super::debug_assert_current_span_has_tenant_and_timeline_id(); @@ -288,7 +288,7 @@ impl DeleteTimelineFlow { /// Shortcut to create Timeline in stopping state and spawn deletion task. #[instrument(skip_all, fields(%timeline_id))] pub(crate) async fn resume_deletion( - tenant: Arc, + tenant: Arc, timeline_id: TimelineId, local_metadata: &TimelineMetadata, remote_client: RemoteTimelineClient, @@ -338,7 +338,7 @@ impl DeleteTimelineFlow { fn schedule_background( guard: DeletionGuard, conf: &'static PageServerConf, - tenant: Arc, + tenant: Arc, timeline: TimelineOrOffloaded, remote_client: Arc, ) { @@ -381,7 +381,7 @@ impl DeleteTimelineFlow { async fn background( mut guard: DeletionGuard, conf: &PageServerConf, - tenant: &Tenant, + tenant: &TenantShard, timeline: &TimelineOrOffloaded, remote_client: Arc, ) -> Result<(), DeleteTimelineError> { @@ -435,7 +435,7 @@ pub(super) enum TimelineDeleteGuardKind { } pub(super) fn make_timeline_delete_guard( - tenant: &Tenant, + tenant: &TenantShard, timeline_id: TimelineId, guard_kind: TimelineDeleteGuardKind, ) -> Result<(TimelineOrOffloaded, DeletionGuard), DeleteTimelineError> { diff --git a/pageserver/src/tenant/timeline/detach_ancestor.rs b/pageserver/src/tenant/timeline/detach_ancestor.rs index a841cc55f0..8e95c3a8ff 100644 --- a/pageserver/src/tenant/timeline/detach_ancestor.rs +++ b/pageserver/src/tenant/timeline/detach_ancestor.rs @@ -23,7 +23,7 @@ use super::layer_manager::LayerManager; use super::{FlushLayerError, Timeline}; use crate::context::{DownloadBehavior, RequestContext}; use crate::task_mgr::TaskKind; -use crate::tenant::Tenant; +use crate::tenant::TenantShard; use crate::tenant::remote_timeline_client::index::GcBlockingReason::DetachAncestor; use crate::tenant::storage_layer::layer::local_layer_path; use crate::tenant::storage_layer::{ @@ -265,7 +265,7 @@ async fn generate_tombstone_image_layer( /// See [`Timeline::prepare_to_detach_from_ancestor`] pub(super) async fn prepare( detached: &Arc, - tenant: &Tenant, + tenant: &TenantShard, behavior: DetachBehavior, options: Options, ctx: &RequestContext, @@ -590,7 +590,7 @@ pub(super) async fn prepare( async fn start_new_attempt( detached: &Timeline, - tenant: &Tenant, + tenant: &TenantShard, ancestor_timeline_id: TimelineId, ancestor_lsn: Lsn, ) -> Result { @@ -611,7 +611,7 @@ async fn start_new_attempt( async fn continue_with_blocked_gc( detached: &Timeline, - tenant: &Tenant, + tenant: &TenantShard, ancestor_timeline_id: TimelineId, ancestor_lsn: Lsn, ) -> Result { @@ -622,7 +622,7 @@ async fn continue_with_blocked_gc( fn obtain_exclusive_attempt( detached: &Timeline, - tenant: &Tenant, + tenant: &TenantShard, ancestor_timeline_id: TimelineId, ancestor_lsn: Lsn, ) -> Result { @@ -655,7 +655,7 @@ fn obtain_exclusive_attempt( fn reparented_direct_children( detached: &Arc, - tenant: &Tenant, + tenant: &TenantShard, ) -> Result, Error> { let mut all_direct_children = tenant .timelines @@ -950,7 +950,7 @@ impl DetachingAndReparenting { /// See [`Timeline::detach_from_ancestor_and_reparent`]. pub(super) async fn detach_and_reparent( detached: &Arc, - tenant: &Tenant, + tenant: &TenantShard, prepared: PreparedTimelineDetach, ancestor_timeline_id: TimelineId, ancestor_lsn: Lsn, @@ -1184,7 +1184,7 @@ pub(super) async fn detach_and_reparent( pub(super) async fn complete( detached: &Arc, - tenant: &Tenant, + tenant: &TenantShard, mut attempt: Attempt, _ctx: &RequestContext, ) -> Result<(), Error> { @@ -1258,7 +1258,7 @@ where } fn check_no_archived_children_of_ancestor( - tenant: &Tenant, + tenant: &TenantShard, detached: &Arc, ancestor: &Arc, ancestor_lsn: Lsn, diff --git a/pageserver/src/tenant/timeline/eviction_task.rs b/pageserver/src/tenant/timeline/eviction_task.rs index 397e8e8978..b1b0d32c9b 100644 --- a/pageserver/src/tenant/timeline/eviction_task.rs +++ b/pageserver/src/tenant/timeline/eviction_task.rs @@ -33,7 +33,7 @@ use crate::tenant::size::CalculateSyntheticSizeError; use crate::tenant::storage_layer::LayerVisibilityHint; use crate::tenant::tasks::{BackgroundLoopKind, BackgroundLoopSemaphorePermit, sleep_random}; use crate::tenant::timeline::EvictionError; -use crate::tenant::{LogicalSizeCalculationCause, Tenant}; +use crate::tenant::{LogicalSizeCalculationCause, TenantShard}; #[derive(Default)] pub struct EvictionTaskTimelineState { @@ -48,7 +48,7 @@ pub struct EvictionTaskTenantState { impl Timeline { pub(super) fn launch_eviction_task( self: &Arc, - parent: Arc, + parent: Arc, background_tasks_can_start: Option<&completion::Barrier>, ) { let self_clone = Arc::clone(self); @@ -75,7 +75,7 @@ impl Timeline { } #[instrument(skip_all, fields(tenant_id = %self.tenant_shard_id.tenant_id, shard_id = %self.tenant_shard_id.shard_slug(), timeline_id = %self.timeline_id))] - async fn eviction_task(self: Arc, tenant: Arc) { + async fn eviction_task(self: Arc, tenant: Arc) { // acquire the gate guard only once within a useful span let Ok(guard) = self.gate.enter() else { return; @@ -118,7 +118,7 @@ impl Timeline { #[instrument(skip_all, fields(policy_kind = policy.discriminant_str()))] async fn eviction_iteration( self: &Arc, - tenant: &Tenant, + tenant: &TenantShard, policy: &EvictionPolicy, cancel: &CancellationToken, gate: &GateGuard, @@ -175,7 +175,7 @@ impl Timeline { async fn eviction_iteration_threshold( self: &Arc, - tenant: &Tenant, + tenant: &TenantShard, p: &EvictionPolicyLayerAccessThreshold, cancel: &CancellationToken, gate: &GateGuard, @@ -309,7 +309,7 @@ impl Timeline { /// disk usage based eviction task. async fn imitiate_only( self: &Arc, - tenant: &Tenant, + tenant: &TenantShard, p: &EvictionPolicyLayerAccessThreshold, cancel: &CancellationToken, gate: &GateGuard, @@ -363,7 +363,7 @@ impl Timeline { #[instrument(skip_all)] async fn imitate_layer_accesses( &self, - tenant: &Tenant, + tenant: &TenantShard, p: &EvictionPolicyLayerAccessThreshold, cancel: &CancellationToken, gate: &GateGuard, @@ -499,7 +499,7 @@ impl Timeline { #[instrument(skip_all)] async fn imitate_synthetic_size_calculation_worker( &self, - tenant: &Tenant, + tenant: &TenantShard, cancel: &CancellationToken, ctx: &RequestContext, ) { diff --git a/pageserver/src/tenant/timeline/offload.rs b/pageserver/src/tenant/timeline/offload.rs index f46f1676c9..5920315917 100644 --- a/pageserver/src/tenant/timeline/offload.rs +++ b/pageserver/src/tenant/timeline/offload.rs @@ -8,7 +8,7 @@ use crate::span::debug_assert_current_span_has_tenant_and_timeline_id; use crate::tenant::remote_timeline_client::ShutdownIfArchivedError; use crate::tenant::timeline::delete::{TimelineDeleteGuardKind, make_timeline_delete_guard}; use crate::tenant::{ - DeleteTimelineError, OffloadedTimeline, Tenant, TenantManifestError, TimelineOrOffloaded, + DeleteTimelineError, OffloadedTimeline, TenantManifestError, TenantShard, TimelineOrOffloaded, }; #[derive(thiserror::Error, Debug)] @@ -33,7 +33,7 @@ impl From for OffloadError { } pub(crate) async fn offload_timeline( - tenant: &Tenant, + tenant: &TenantShard, timeline: &Arc, ) -> Result<(), OffloadError> { debug_assert_current_span_has_tenant_and_timeline_id(); @@ -123,7 +123,7 @@ pub(crate) async fn offload_timeline( /// /// Returns the strong count of the timeline `Arc` fn remove_timeline_from_tenant( - tenant: &Tenant, + tenant: &TenantShard, timeline: &Timeline, _: &DeletionGuard, // using it as a witness ) -> usize { diff --git a/pageserver/src/tenant/timeline/uninit.rs b/pageserver/src/tenant/timeline/uninit.rs index f66c0ffa0f..beebf35462 100644 --- a/pageserver/src/tenant/timeline/uninit.rs +++ b/pageserver/src/tenant/timeline/uninit.rs @@ -15,17 +15,19 @@ use super::Timeline; use crate::context::RequestContext; use crate::import_datadir; use crate::span::debug_assert_current_span_has_tenant_and_timeline_id; -use crate::tenant::{CreateTimelineError, CreateTimelineIdempotency, Tenant, TimelineOrOffloaded}; +use crate::tenant::{ + CreateTimelineError, CreateTimelineIdempotency, TenantShard, TimelineOrOffloaded, +}; /// A timeline with some of its files on disk, being initialized. /// This struct ensures the atomicity of the timeline init: it's either properly created and inserted into pageserver's memory, or /// its local files are removed. If we crash while this class exists, then the timeline's local -/// state is cleaned up during [`Tenant::clean_up_timelines`], because the timeline's content isn't in remote storage. +/// state is cleaned up during [`TenantShard::clean_up_timelines`], because the timeline's content isn't in remote storage. /// /// The caller is responsible for proper timeline data filling before the final init. #[must_use] pub struct UninitializedTimeline<'t> { - pub(crate) owning_tenant: &'t Tenant, + pub(crate) owning_tenant: &'t TenantShard, timeline_id: TimelineId, raw_timeline: Option<(Arc, TimelineCreateGuard)>, /// Whether we spawned the inner Timeline's tasks such that we must later shut it down @@ -35,7 +37,7 @@ pub struct UninitializedTimeline<'t> { impl<'t> UninitializedTimeline<'t> { pub(crate) fn new( - owning_tenant: &'t Tenant, + owning_tenant: &'t TenantShard, timeline_id: TimelineId, raw_timeline: Option<(Arc, TimelineCreateGuard)>, ) -> Self { @@ -156,7 +158,7 @@ impl<'t> UninitializedTimeline<'t> { /// Prepares timeline data by loading it from the basebackup archive. pub(crate) async fn import_basebackup_from_tar( mut self, - tenant: Arc, + tenant: Arc, copyin_read: &mut (impl tokio::io::AsyncRead + Send + Sync + Unpin), base_lsn: Lsn, broker_client: storage_broker::BrokerClientChannel, @@ -227,17 +229,17 @@ pub(crate) fn cleanup_timeline_directory(create_guard: TimelineCreateGuard) { error!("Failed to clean up uninitialized timeline directory {timeline_path:?}: {e:?}") } } - // Having cleaned up, we can release this TimelineId in `[Tenant::timelines_creating]` to allow other + // Having cleaned up, we can release this TimelineId in `[TenantShard::timelines_creating]` to allow other // timeline creation attempts under this TimelineId to proceed drop(create_guard); } /// A guard for timeline creations in process: as long as this object exists, the timeline ID -/// is kept in `[Tenant::timelines_creating]` to exclude concurrent attempts to create the same timeline. +/// is kept in `[TenantShard::timelines_creating]` to exclude concurrent attempts to create the same timeline. #[must_use] pub(crate) struct TimelineCreateGuard { pub(crate) _tenant_gate_guard: GateGuard, - pub(crate) owning_tenant: Arc, + pub(crate) owning_tenant: Arc, pub(crate) timeline_id: TimelineId, pub(crate) timeline_path: Utf8PathBuf, pub(crate) idempotency: CreateTimelineIdempotency, @@ -263,7 +265,7 @@ pub(crate) enum TimelineExclusionError { impl TimelineCreateGuard { pub(crate) fn new( - owning_tenant: &Arc, + owning_tenant: &Arc, timeline_id: TimelineId, timeline_path: Utf8PathBuf, idempotency: CreateTimelineIdempotency,