demo that this solution creates too many leases

This commit is contained in:
Christian Schwarz
2025-07-17 07:14:11 +00:00
parent bd06bc54b6
commit e850cc94b5
3 changed files with 47 additions and 2 deletions

View File

@@ -2181,8 +2181,29 @@ async fn handle_tenant_break(
json_response(StatusCode::OK, ())
}
async fn get_lsn_leases_handler(
mut request: Request<Body>,
_cancel: CancellationToken,
) -> Result<Response<Body>, ApiError> {
let tenant_shard_id: TenantShardId = parse_request_param(&request, "tenant_shard_id")?;
let timeline_id: TimelineId = parse_request_param(&request, "timeline_id")?;
check_permission(&request, Some(tenant_shard_id.tenant_id))?;
let ctx = RequestContext::new(TaskKind::MgmtRequest, DownloadBehavior::Download);
let state = get_state(&request);
let timeline =
active_timeline_of_active_tenant(&state.tenant_manager, tenant_shard_id, timeline_id)
.await?;
let leases = timeline.gc_info.read().unwrap().leases.clone();
json_response(StatusCode::OK, leases)
}
// Obtains an lsn lease on the given timeline.
async fn lsn_lease_handler(
async fn post_lsn_lease_handler(
mut request: Request<Body>,
_cancel: CancellationToken,
) -> Result<Response<Body>, ApiError> {
@@ -4002,9 +4023,14 @@ pub fn make_router(
"/v1/tenant/:tenant_shard_id/timeline/:timeline_id/patch_index_part",
|r| api_handler(r, timeline_patch_index_part_handler),
)
.get(
"/v1/tenant/:tenant_shard_id/timeline/:timeline_id/lsn_lease",
|r| api_handler(r, get_lsn_leases_handler)
)
.post(
"/v1/tenant/:tenant_shard_id/timeline/:timeline_id/lsn_lease",
|r| api_handler(r, lsn_lease_handler),
|r| api_handler(r, post_lsn_lease_handler),
)
.put(
"/v1/tenant/:tenant_shard_id/timeline/:timeline_id/do_gc",

View File

@@ -839,6 +839,17 @@ class PageserverHttpClient(requests.Session, MetricsGetter):
res_json = res.json()
return res_json
def timeline_lsn_lease_dump(
self, tenant_shard_id: TenantShardId, timeline_id: TimelineId
):
res = self.get(
f"http://localhost:{self.port}/v1/tenant/{tenant_shard_id}/timeline/{timeline_id}/lsn_lease",
)
self.verbose_error(res)
res_json = res.json()
return res_json
def timeline_lsn_lease(
self, tenant_id: TenantId | TenantShardId, timeline_id: TimelineId, lsn: Lsn
):

View File

@@ -200,6 +200,14 @@ def test_hot_standby_gc(neon_env_builder: NeonEnvBuilder, pause_apply: bool):
res = s_cur.fetchone()
assert res == (10000,)
for tenant_shard_id, pageserver in shards:
client = pageserver.http_client()
leases = client.timeline_lsn_lease_dump(tenant_shard_id, timeline_id)
leases_sorted = sorted(list(leases.items()))
log.info(f"lease state {tenant_shard_id=} {len(leases_sorted)} leases")
for lease in leases_sorted:
log.info(f"{lease=}")
assert len(leases) == 1
def run_pgbench(connstr: str, pg_bin: PgBin):
log.info(f"Start a pgbench workload on pg {connstr}")