diff --git a/pageserver/src/http/routes.rs b/pageserver/src/http/routes.rs index d57bd98e95..dde9c5dd0b 100644 --- a/pageserver/src/http/routes.rs +++ b/pageserver/src/http/routes.rs @@ -2002,9 +2002,9 @@ async fn timeline_offload_handler( "timeline has attached children".into(), )); } - if !timeline.can_offload() { + if let (false, reason) = timeline.can_offload() { return Err(ApiError::PreconditionFailed( - "Timeline::can_offload() returned false".into(), + format!("Timeline::can_offload() check failed: {}", reason) .into(), )); } offload_timeline(&tenant, &timeline) diff --git a/pageserver/src/tenant.rs b/pageserver/src/tenant.rs index 34ea6dae1f..903174680e 100644 --- a/pageserver/src/tenant.rs +++ b/pageserver/src/tenant.rs @@ -2493,7 +2493,8 @@ impl Tenant { timelines_to_compact_or_offload = timelines .iter() .filter_map(|(timeline_id, timeline)| { - let (is_active, can_offload) = (timeline.is_active(), timeline.can_offload()); + let (is_active, (can_offload, _)) = + (timeline.is_active(), timeline.can_offload()); let has_no_unoffloaded_children = { !timelines .iter() diff --git a/pageserver/src/tenant/timeline.rs b/pageserver/src/tenant/timeline.rs index 60cc689c5e..56faacbaee 100644 --- a/pageserver/src/tenant/timeline.rs +++ b/pageserver/src/tenant/timeline.rs @@ -1570,12 +1570,16 @@ impl Timeline { /// /// This is neccessary but not sufficient for offloading of the timeline as it might have /// child timelines that are not offloaded yet. - pub(crate) fn can_offload(&self) -> bool { + pub(crate) fn can_offload(&self) -> (bool, &'static str) { if self.remote_client.is_archived() != Some(true) { - return false; + return (false, "the timeline is not archived"); + } + if !self.remote_client.no_pending_work() { + // if the remote client is still processing some work, we can't offload + return (false, "the upload queue is not drained yet"); } - true + (true, "ok") } /// Outermost timeline compaction operation; downloads needed layers. Returns whether we have pending diff --git a/pageserver/src/tenant/timeline/offload.rs b/pageserver/src/tenant/timeline/offload.rs index 2dc461c28d..1394843467 100644 --- a/pageserver/src/tenant/timeline/offload.rs +++ b/pageserver/src/tenant/timeline/offload.rs @@ -58,7 +58,7 @@ pub(crate) async fn offload_timeline( } // Now that the Timeline is in Stopping state, request all the related tasks to shut down. - timeline.shutdown(super::ShutdownMode::Hard).await; + timeline.shutdown(super::ShutdownMode::Flush).await; // TODO extend guard mechanism above with method // to make deletions possible while offloading is in progress