pageserver, tests: prepare test_basebackup_cache for --timelines-onto-safekeepers (#12143)

## Problem
- `test_basebackup_cache` fails in
https://github.com/neondatabase/neon/pull/11712 because after the
timelines on safekeepers are managed by storage controller, they do
contain proper start_lsn and the compute_ctl tool sends the first
basebackup request with this LSN.
- `Failed to prepare basebackup` log messages during timeline
initialization, because the timeline is not yet in the global timeline
map.

- Relates to https://github.com/neondatabase/cloud/issues/29353

## Summary of changes
- Account for `timeline_onto_safekeepers` storcon's option in the test.
- Do not trigger basebackup prepare during the timeline initialization.
This commit is contained in:
Dmitrii Kovalkov
2025-06-05 16:04:37 +04:00
committed by GitHub
parent 038e967daf
commit f7ec7668a2
2 changed files with 31 additions and 9 deletions

View File

@@ -2506,6 +2506,13 @@ impl Timeline {
// Preparing basebackup doesn't make sense for shards other than shard zero.
return;
}
if !self.is_active() {
// May happen during initial timeline creation.
// Such timeline is not in the global timeline map yet,
// so basebackup cache will not be able to find it.
// TODO(diko): We can prepare such timelines in finish_creation().
return;
}
let res = self
.basebackup_prepare_sender

View File

@@ -26,6 +26,10 @@ def test_basebackup_cache(neon_env_builder: NeonEnvBuilder):
ps = env.pageserver
ps_http = ps.http_client()
storcon_managed_timelines = (env.storage_controller_config or {}).get(
"timelines_onto_safekeepers", False
)
# 1. Check that we always hit the cache after compute restart.
for i in range(3):
ep.start()
@@ -33,15 +37,26 @@ def test_basebackup_cache(neon_env_builder: NeonEnvBuilder):
def check_metrics(i=i):
metrics = ps_http.get_metrics()
# Never miss.
# The first time compute_ctl sends `get_basebackup` with lsn=None, we do not cache such requests.
# All other requests should be a hit
assert (
metrics.query_one(
"pageserver_basebackup_cache_read_total", {"result": "miss"}
).value
== 0
)
if storcon_managed_timelines:
# We do not cache the initial basebackup yet,
# so the first compute startup should be a miss.
assert (
metrics.query_one(
"pageserver_basebackup_cache_read_total", {"result": "miss"}
).value
== 1
)
else:
# If the timeline is not initialized on safekeeprs,
# the compute_ctl sends `get_basebackup` with lsn=None for the first startup.
# We do not use cache for such requests, so it's niether a hit nor a miss.
assert (
metrics.query_one(
"pageserver_basebackup_cache_read_total", {"result": "miss"}
).value
== 0
)
# All but the first requests are hits.
assert (
metrics.query_one("pageserver_basebackup_cache_read_total", {"result": "hit"}).value