Skip to content

Commit 3f83ea0

Browse files
committed
tests: cover tiered_cloud capacity and idle-partition reclaim
- capacity pressure reclaims during produce - space management reclaims an idle partition Signed-off-by: Oren Leiman <oren.leiman@redpanda.com>
1 parent 3f3e811 commit 3f83ea0

1 file changed

Lines changed: 132 additions & 0 deletions

File tree

tests/rptest/tests/tiered_cloud_local_retention_test.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,138 @@ def test_local_data_grows_in_tiered_cloud(self):
299299
f"expected near {replication * self.local_target_bytes} bytes"
300300
)
301301

302+
@cluster(num_nodes=4)
303+
def test_capacity_pressure_reclaims_tiered_cloud(self):
304+
"""
305+
Cluster-wide disk pressure (the disk_space_manager capacity path)
306+
reclaims a tiered_cloud partition's local log, not just the
307+
retention.local.target path.
308+
309+
The topic sets no local target and effectively infinite retention, so
310+
only the capacity path can bound it. On a build that excludes
311+
tiered_cloud partitions from disk_space_manager the local log grows
312+
unbounded and this fails; with them admitted, the eviction policy pins
313+
_cloud_gc_offset and ctp_stm trims to it, so the footprint converges
314+
near the capacity target.
315+
"""
316+
assert self.redpanda is not None
317+
318+
# Node-wide log-data target, small enough that the produced topic must
319+
# be trimmed to meet it. disk_reservation_percent=0 and percent=100 so
320+
# the bytes target is the effective one.
321+
capacity_target = 16 * 1024 * 1024
322+
self.redpanda.set_cluster_config(
323+
{
324+
"retention_local_target_capacity_bytes": capacity_target,
325+
"retention_local_target_capacity_percent": 100,
326+
"disk_reservation_percent": 0,
327+
}
328+
)
329+
330+
# No retention.local.target.bytes: the local-target path stays inert
331+
# (only the 1-day default applies, and nothing is that old), so only
332+
# the capacity path can bound this topic. retention.bytes is
333+
# effectively unlimited, mirroring the field scenario that filled the
334+
# disk.
335+
rpk = RpkTool(self.redpanda)
336+
rpk.create_topic(
337+
topic=self.topic_name,
338+
partitions=1,
339+
replicas=3,
340+
config={
341+
TopicSpec.PROPERTY_STORAGE_MODE: (TopicSpec.STORAGE_MODE_TIERED_CLOUD),
342+
"cleanup.policy": TopicSpec.CLEANUP_DELETE,
343+
"retention.bytes": str(self.retention_bytes),
344+
"segment.bytes": str(self.segment_size),
345+
},
346+
)
347+
self._wait_for_partition_info()
348+
349+
# Produce well past the capacity target so an untrimmed build grows far
350+
# beyond it.
351+
produce_bytes = 64 * 1024 * 1024
352+
self._produce(produce_bytes)
353+
self.wait_until_reconciled(topic=self.topic_name, partition=0)
354+
355+
# The target is per node; the metric sums this topic's 3 replicas and
356+
# excludes internal logs (topic-filtered). Allow 3x the target plus
357+
# per-replica headroom for the never-evicted active segment and
358+
# trim-cycle latency. Still far below the ~3x produce an untrimmed
359+
# build retains.
360+
replication = 3
361+
ceiling = replication * (capacity_target + 4 * self.segment_size)
362+
# The topic has no local retention target and a lenient retention.bytes,
363+
# so ctp_stm's own retention never trims at this volume; only a
364+
# disk_space_manager capacity pin can drive the reclaim. Staying below
365+
# the ceiling therefore proves the capacity path engaged for a
366+
# tiered_cloud partition.
367+
self._wait_local_below(ceiling_bytes=ceiling, timeout_sec=180)
368+
369+
@cluster(num_nodes=4)
370+
def test_idle_partition_reclaims_on_pin(self):
371+
"""
372+
A tiered_cloud partition that has gone idle still reclaims when disk
373+
pressure sets _cloud_gc_offset afterwards.
374+
375+
With no produce the LRO is quiescent, so nothing signals ctp_stm's
376+
truncate loop. It wakes on its bounded poll interval, re-reads the
377+
offset disk_space_manager set, and trims to it, so an idle partition
378+
reclaims without further produce.
379+
"""
380+
assert self.redpanda is not None
381+
382+
capacity_target = 16 * 1024 * 1024
383+
replication = 3
384+
ceiling = replication * (capacity_target + 4 * self.segment_size)
385+
386+
# Capacity path effectively off: percent=100 with no bytes target lets
387+
# the backlog accumulate without pressure, so nothing trims until the
388+
# bytes target is set below.
389+
self.redpanda.set_cluster_config(
390+
{
391+
"retention_local_target_capacity_percent": 100,
392+
"disk_reservation_percent": 0,
393+
}
394+
)
395+
396+
rpk = RpkTool(self.redpanda)
397+
rpk.create_topic(
398+
topic=self.topic_name,
399+
partitions=1,
400+
replicas=3,
401+
config={
402+
TopicSpec.PROPERTY_STORAGE_MODE: (TopicSpec.STORAGE_MODE_TIERED_CLOUD),
403+
"cleanup.policy": TopicSpec.CLEANUP_DELETE,
404+
"retention.bytes": str(self.retention_bytes),
405+
"segment.bytes": str(self.segment_size),
406+
},
407+
)
408+
self._wait_for_partition_info()
409+
410+
# Fill the local log, then let reconciliation catch up so the LRO is
411+
# quiescent (nothing to drive the truncate loop). Nothing trims yet
412+
# (no pressure, lenient retention.bytes), so the footprint holds near
413+
# the produced size.
414+
self._produce(64 * 1024 * 1024)
415+
self.wait_until_reconciled(topic=self.topic_name, partition=0)
416+
417+
# Confirm the backlog is present and untrimmed before applying pressure,
418+
# so the reclaim assertion below cannot pass trivially.
419+
wait_until(
420+
lambda: self._local_partition_bytes() > ceiling,
421+
timeout_sec=60,
422+
backoff_sec=2,
423+
err_msg="backlog never reached the expected size before pressure",
424+
)
425+
426+
# Apply pressure: disk_space_manager sets _cloud_gc_offset on its next
427+
# cycle. The LRO is quiescent, so the truncate loop only observes it on
428+
# its next bounded poll, then trims to it.
429+
self.redpanda.set_cluster_config(
430+
{"retention_local_target_capacity_bytes": capacity_target}
431+
)
432+
self._wait_local_below(ceiling_bytes=ceiling, timeout_sec=120)
433+
302434
@cluster(num_nodes=4)
303435
def test_compact_topic_evicts_via_l1_floor(self):
304436
"""

0 commit comments

Comments
 (0)