Skip to content

Commit 95392bc

Browse files
kafka: route a partition with a non-empty archival manifest to tiered storage
Add a structural IO gate as the highest-priority branch of make_partition_proxy: a partition whose archival STM holds a non-empty manifest is served via replicated_partition (local log + cloud manifest), regardless of the cloud_topic_enabled() config flag. This keys on partition-raft state, so it is robust to the unordered propagation of the storage-mode flip that triggers a tiered->cloud migration. A native cloud topic carries an empty archival manifest and so falls through to the cloud-topic path; cutover empties the manifest, returning a migrated partition to the cloud-topic path where it reads its imported extents. replicated_partition already serves the whole partition during migration, so no composite proxy or per-fetch boundary is needed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 7d953fa commit 95392bc

1 file changed

Lines changed: 23 additions & 0 deletions

File tree

src/v/kafka/data/partition_proxy.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,29 @@ partition_proxy make_with_impl(Args&&... args) {
2828

2929
partition_proxy
3030
make_partition_proxy(const ss::lw_shared_ptr<cluster::partition>& partition) {
31+
// Structural IO gate: a partition that still holds tiered-storage data is
32+
// served as tiered storage -- a plain tiered partition, or a partition mid
33+
// tiered->cloud migration whose data still lives in tiered storage. This
34+
// keys on partition-raft state (the manifest), not the cloud_topic_enabled()
35+
// config flag, so it is robust to the unordered controller propagation of
36+
// the storage-mode flip. replicated_partition serves the whole partition
37+
// (local log + cloud manifest). Cutover (reset_metadata) clears both the
38+
// live manifest and the archive, after which the partition falls through to
39+
// the cloud-topic path below (reading its imported extents).
40+
//
41+
// "Still holds tiered data" must include the archive: spillover offloads the
42+
// oldest segments out of the live STM manifest into archive (spillover)
43+
// sub-manifests, and retention/GC runs on a migrating partition (the
44+
// archiver is not dormant until cutover). So the live manifest can reach 0
45+
// while data remains in the archive; keying only on it would misread a
46+
// spilled, still-migrating partition as cut over and route it to the
47+
// cloud-topic path before its extents were imported. holds_archived_data()
48+
// consults both the live manifest and the archive.
49+
const auto& archival_stm = partition->archival_meta_stm();
50+
if (archival_stm && archival_stm->holds_archived_data()) {
51+
return make_with_impl<replicated_partition>(partition);
52+
}
53+
3154
auto is_ct = partition->get_ntp_config().cloud_topic_enabled();
3255
auto is_rr = partition->is_read_replica_mode_enabled();
3356
if (is_ct) {

0 commit comments

Comments
 (0)