From 92b3bda408cf8dfb1136d07ec6d69d5586fc66e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arpad=20M=C3=BCller?= Date: Thu, 31 Oct 2024 21:52:29 +0100 Subject: [PATCH 1/5] Add tenant config option to allow timeline_offloading --- pageserver/src/tenant.rs | 4 +++- pageserver/src/tenant/config.rs | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pageserver/src/tenant.rs b/pageserver/src/tenant.rs index 68f8f7e13c72..e58ca5d2fd7a 100644 --- a/pageserver/src/tenant.rs +++ b/pageserver/src/tenant.rs @@ -2499,8 +2499,10 @@ impl Tenant { .iter() .any(|(_id, tl)| tl.get_ancestor_timeline_id() == Some(*timeline_id)) }; + let config_allows_offload = self.conf.timeline_offloading + || self.tenant_conf.load().tenant_conf.timeline_offloading; let can_offload = - can_offload && has_no_unoffloaded_children && self.conf.timeline_offloading; + can_offload && has_no_unoffloaded_children && config_allows_offload; if (is_active, can_offload) == (false, false) { None } else { diff --git a/pageserver/src/tenant/config.rs b/pageserver/src/tenant/config.rs index ce686c89ef61..b070eb34a21c 100644 --- a/pageserver/src/tenant/config.rs +++ b/pageserver/src/tenant/config.rs @@ -349,6 +349,10 @@ pub struct TenantConfOpt { #[serde(with = "humantime_serde")] #[serde(default)] pub lsn_lease_length_for_ts: Option, + + #[serde(skip_serializing_if = "std::ops::Not::not")] + #[serde(default)] + pub timeline_offloading: bool, } impl TenantConfOpt { From da9cb14bae8b3380e65da24158276cf169f49392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arpad=20M=C3=BCller?= Date: Thu, 31 Oct 2024 22:06:42 +0100 Subject: [PATCH 2/5] Proper config flag now --- libs/pageserver_api/src/config.rs | 5 +++++ pageserver/src/tenant.rs | 3 ++- pageserver/src/tenant/config.rs | 5 +++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libs/pageserver_api/src/config.rs b/libs/pageserver_api/src/config.rs index 6b2d6cf62568..00cc426c3c3f 100644 --- a/libs/pageserver_api/src/config.rs +++ b/libs/pageserver_api/src/config.rs @@ -259,6 +259,10 @@ pub struct TenantConfigToml { /// Layers needed to reconstruct pages at LSN will not be GC-ed during this interval. #[serde(with = "humantime_serde")] pub lsn_lease_length_for_ts: Duration, + + /// Enable auto-offloading of timelines. + /// (either this flag or the pageserver-global one need to be set) + pub timeline_offloading: bool, } pub mod defaults { @@ -471,6 +475,7 @@ impl Default for TenantConfigToml { image_layer_creation_check_threshold: DEFAULT_IMAGE_LAYER_CREATION_CHECK_THRESHOLD, lsn_lease_length: LsnLease::DEFAULT_LENGTH, lsn_lease_length_for_ts: LsnLease::DEFAULT_LENGTH_FOR_TS, + timeline_offloading: false, } } } diff --git a/pageserver/src/tenant.rs b/pageserver/src/tenant.rs index e58ca5d2fd7a..b8ad821a011a 100644 --- a/pageserver/src/tenant.rs +++ b/pageserver/src/tenant.rs @@ -2500,7 +2500,7 @@ impl Tenant { .any(|(_id, tl)| tl.get_ancestor_timeline_id() == Some(*timeline_id)) }; let config_allows_offload = self.conf.timeline_offloading - || self.tenant_conf.load().tenant_conf.timeline_offloading; + || self.tenant_conf.load().tenant_conf.timeline_offloading.unwrap_or_default(); let can_offload = can_offload && has_no_unoffloaded_children && config_allows_offload; if (is_active, can_offload) == (false, false) { @@ -4904,6 +4904,7 @@ pub(crate) mod harness { ), lsn_lease_length: Some(tenant_conf.lsn_lease_length), lsn_lease_length_for_ts: Some(tenant_conf.lsn_lease_length_for_ts), + timeline_offloading: Some(tenant_conf.timeline_offloading), } } } diff --git a/pageserver/src/tenant/config.rs b/pageserver/src/tenant/config.rs index b070eb34a21c..2c7458fe8c23 100644 --- a/pageserver/src/tenant/config.rs +++ b/pageserver/src/tenant/config.rs @@ -350,9 +350,9 @@ pub struct TenantConfOpt { #[serde(default)] pub lsn_lease_length_for_ts: Option, - #[serde(skip_serializing_if = "std::ops::Not::not")] + #[serde(skip_serializing_if = "Option::is_none")] #[serde(default)] - pub timeline_offloading: bool, + pub timeline_offloading: Option, } impl TenantConfOpt { @@ -415,6 +415,7 @@ impl TenantConfOpt { lsn_lease_length_for_ts: self .lsn_lease_length_for_ts .unwrap_or(global_conf.lsn_lease_length_for_ts), + timeline_offloading: self.lazy_slru_download.unwrap_or(global_conf.timeline_offloading), } } } From 8cc4c5f395cad99284c055ca6f7562182b3ca750 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arpad=20M=C3=BCller?= Date: Thu, 31 Oct 2024 22:37:46 +0100 Subject: [PATCH 3/5] cargo fmt --- pageserver/src/tenant.rs | 7 ++++++- pageserver/src/tenant/config.rs | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pageserver/src/tenant.rs b/pageserver/src/tenant.rs index b8ad821a011a..d45c99a41b24 100644 --- a/pageserver/src/tenant.rs +++ b/pageserver/src/tenant.rs @@ -2500,7 +2500,12 @@ impl Tenant { .any(|(_id, tl)| tl.get_ancestor_timeline_id() == Some(*timeline_id)) }; let config_allows_offload = self.conf.timeline_offloading - || self.tenant_conf.load().tenant_conf.timeline_offloading.unwrap_or_default(); + || self + .tenant_conf + .load() + .tenant_conf + .timeline_offloading + .unwrap_or_default(); let can_offload = can_offload && has_no_unoffloaded_children && config_allows_offload; if (is_active, can_offload) == (false, false) { diff --git a/pageserver/src/tenant/config.rs b/pageserver/src/tenant/config.rs index 2c7458fe8c23..4c26f5e22f54 100644 --- a/pageserver/src/tenant/config.rs +++ b/pageserver/src/tenant/config.rs @@ -415,7 +415,9 @@ impl TenantConfOpt { lsn_lease_length_for_ts: self .lsn_lease_length_for_ts .unwrap_or(global_conf.lsn_lease_length_for_ts), - timeline_offloading: self.lazy_slru_download.unwrap_or(global_conf.timeline_offloading), + timeline_offloading: self + .lazy_slru_download + .unwrap_or(global_conf.timeline_offloading), } } } From 46882f07104851faa16221ed7462b56ca6ae7cb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arpad=20M=C3=BCller?= Date: Fri, 1 Nov 2024 04:05:05 +0100 Subject: [PATCH 4/5] Add to fully_custom_config --- test_runner/regress/test_attach_tenant_config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test_runner/regress/test_attach_tenant_config.py b/test_runner/regress/test_attach_tenant_config.py index 83d003a5cc88..a5e51f7feae1 100644 --- a/test_runner/regress/test_attach_tenant_config.py +++ b/test_runner/regress/test_attach_tenant_config.py @@ -174,6 +174,7 @@ def test_fully_custom_config(positive_env: NeonEnv): "image_layer_creation_check_threshold": 1, "lsn_lease_length": "1m", "lsn_lease_length_for_ts": "5s", + "timeline_offloading": True, } ps_http = env.pageserver.http_client() From 643a7f8ccc25c6deca27941a003570e59e87f667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arpad=20M=C3=BCller?= Date: Mon, 4 Nov 2024 16:51:27 +0100 Subject: [PATCH 5/5] Also add to models::TenantConfig --- control_plane/src/pageserver.rs | 10 ++++++++++ libs/pageserver_api/src/models.rs | 1 + pageserver/src/tenant/config.rs | 1 + 3 files changed, 12 insertions(+) diff --git a/control_plane/src/pageserver.rs b/control_plane/src/pageserver.rs index 8df0a714ec6a..db54965eb525 100644 --- a/control_plane/src/pageserver.rs +++ b/control_plane/src/pageserver.rs @@ -403,6 +403,11 @@ impl PageServerNode { lsn_lease_length_for_ts: settings .remove("lsn_lease_length_for_ts") .map(|x| x.to_string()), + timeline_offloading: settings + .remove("timeline_offloading") + .map(|x| x.parse::()) + .transpose() + .context("Failed to parse 'timeline_offloading' as bool")?, }; if !settings.is_empty() { bail!("Unrecognized tenant settings: {settings:?}") @@ -498,6 +503,11 @@ impl PageServerNode { lsn_lease_length_for_ts: settings .remove("lsn_lease_length_for_ts") .map(|x| x.to_string()), + timeline_offloading: settings + .remove("timeline_offloading") + .map(|x| x.parse::()) + .transpose() + .context("Failed to parse 'timeline_offloading' as bool")?, } }; diff --git a/libs/pageserver_api/src/models.rs b/libs/pageserver_api/src/models.rs index 0a4992aea42e..0dfa1ba817ca 100644 --- a/libs/pageserver_api/src/models.rs +++ b/libs/pageserver_api/src/models.rs @@ -310,6 +310,7 @@ pub struct TenantConfig { pub image_layer_creation_check_threshold: Option, pub lsn_lease_length: Option, pub lsn_lease_length_for_ts: Option, + pub timeline_offloading: Option, } /// The policy for the aux file storage. diff --git a/pageserver/src/tenant/config.rs b/pageserver/src/tenant/config.rs index 4c26f5e22f54..4d6176bfd9d3 100644 --- a/pageserver/src/tenant/config.rs +++ b/pageserver/src/tenant/config.rs @@ -471,6 +471,7 @@ impl From for models::TenantConfig { image_layer_creation_check_threshold: value.image_layer_creation_check_threshold, lsn_lease_length: value.lsn_lease_length.map(humantime), lsn_lease_length_for_ts: value.lsn_lease_length_for_ts.map(humantime), + timeline_offloading: value.timeline_offloading, } } }