From 90572de36af5ae76a3f2cc0e5653c2707549ac5d Mon Sep 17 00:00:00 2001 From: Yufeng He <40085740+he-yufeng@users.noreply.github.com> Date: Wed, 15 Jul 2026 12:39:04 +0800 Subject: [PATCH] [Store] Serialize ssd_total_capacity_bytes in local disk snapshot After a master restart with snapshot restore, the SSD total capacity in metrics dropped to 0 (used bytes stayed correct) until the client restarted and re-ran FileStorage::Init (#2783). SegmentSerializer packed a LocalDiskSegment as [enable_offloading, count, key/task pairs...] and never included ssd_total_capacity_bytes, so the restored segment kept its default 0. Append ssd_total_capacity_bytes to the packed array and read it back when present. Snapshots written before this change lack the trailing field and deserialize unchanged (capacity stays 0 until the client re-reports it), so the format bump is backward compatible. Signed-off-by: Yufeng He <40085740+he-yufeng@users.noreply.github.com> --- mooncake-store/src/segment.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/mooncake-store/src/segment.cpp b/mooncake-store/src/segment.cpp index ca0de3db9d..7009b8965d 100644 --- a/mooncake-store/src/segment.cpp +++ b/mooncake-store/src/segment.cpp @@ -680,7 +680,9 @@ SegmentSerializer::Serialize() { } std::sort(sorted_keys.begin(), sorted_keys.end()); - packer.pack_array(2 + sorted_keys.size() * 2); + // Trailing ssd_total_capacity_bytes so a restored master keeps the + // client-reported SSD capacity across a snapshot restore (#2783). + packer.pack_array(2 + sorted_keys.size() * 2 + 1); packer.pack(segment->enable_offloading); packer.pack(static_cast(sorted_keys.size())); @@ -692,6 +694,7 @@ SegmentSerializer::Serialize() { packer.pack(task.key); packer.pack(task.size); } + packer.pack(segment->ssd_total_capacity_bytes); } // Compress entire data @@ -1089,6 +1092,17 @@ tl::expected SegmentSerializer::Deserialize( } } + // ssd_total_capacity_bytes is appended after the offloading + // objects. Pre-#2783 snapshots omit it, so read it only when + // present; otherwise it keeps the default 0 until the client + // re-reports capacity. + size_t capacity_idx = 2 + count * 2; + if (client_value.via.array.size > capacity_idx && + IsMsgpackInteger(client_value.via.array.ptr[capacity_idx])) { + segment->ssd_total_capacity_bytes = + client_value.via.array.ptr[capacity_idx].as(); + } + segment_manager_->client_local_disk_segment_[client_id] = std::move(segment); }