From c7d3bd105c40e3ddf9c8e9c8e35647c7e0c42aeb Mon Sep 17 00:00:00 2001 From: John Spray Date: Thu, 21 Nov 2024 10:14:55 +0000 Subject: [PATCH] pageserver: permit reads behind GC cutoff while in LSN lease grace period --- pageserver/src/page_service.rs | 5 ++++- pageserver/src/tenant/timeline.rs | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pageserver/src/page_service.rs b/pageserver/src/page_service.rs index a429dff1fd..1248529b66 100644 --- a/pageserver/src/page_service.rs +++ b/pageserver/src/page_service.rs @@ -1068,7 +1068,7 @@ impl PageServerHandler { )); } - if request_lsn < **latest_gc_cutoff_lsn { + if request_lsn < **latest_gc_cutoff_lsn && !timeline.is_gc_blocked_by_lsn_lease_deadline() { let gc_info = &timeline.gc_info.read().unwrap(); if !gc_info.leases.contains_key(&request_lsn) { // The requested LSN is below gc cutoff and is not guarded by a lease. @@ -1078,6 +1078,9 @@ impl PageServerHandler { return Err(if request_lsn == Lsn::INVALID { PageStreamError::BadRequest("invalid LSN(0) in request".into()) } else { + // Although we might still have this data, we return an error to more readily + // detect client misbehavior: clients should only read from recent LSNs on their + // timeline, or from locations holding an LSN lease. PageStreamError::BadRequest(format!( "tried to request a page version that was garbage collected. requested at {} gc cutoff {}", request_lsn, **latest_gc_cutoff_lsn diff --git a/pageserver/src/tenant/timeline.rs b/pageserver/src/tenant/timeline.rs index 95864af4d0..0c7f3204f6 100644 --- a/pageserver/src/tenant/timeline.rs +++ b/pageserver/src/tenant/timeline.rs @@ -2085,6 +2085,11 @@ impl Timeline { .unwrap_or(self.conf.default_tenant_conf.lsn_lease_length_for_ts) } + pub(crate) fn is_gc_blocked_by_lsn_lease_deadline(&self) -> bool { + let tenant_conf = self.tenant_conf.load(); + tenant_conf.is_gc_blocked_by_lsn_lease_deadline() + } + pub(crate) fn get_lazy_slru_download(&self) -> bool { let tenant_conf = self.tenant_conf.load(); tenant_conf