mirror of
https://github.com/kvcache-ai/Mooncake.git
synced 2026-11-05 01:17:55 +00:00
[GH-ISSUE #4725] [Store] Offload completion can attach a stale LOCAL_DISK replica to a republished key #1203
Labels
No labels
ascend
auto-closed
bug
bug
CI/Build
Common
documentation
enhancement
feature request
good first issue
help wanted
high priority
MetaX
nightly-failure
pull-request
PyTorch Backend
question
RFC
Roadmap
stale
Store
Tests
Transfer Engine
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/Mooncake#1203
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @Aionw on GitHub (Oct 16, 2026).
Original GitHub issue: https://github.com/kvcache-ai/Mooncake/issues/4725
An offload completion is matched to the key, not to the publication it was queued for. The offload task carries tenant, key and size; the completion carries where it wrote. The master's only link between them is
state.offloading_task.EraseMetadataclears that marker, but a store worker that has already drained the task keeps writing its SSD copy. If the key is erased and republished before the completion arrives, the completion finds no marker.handled_existing_objectstays false, and the completion falls through toAddReplicaForRetainedClient, which attaches the LOCAL_DISK replica to whatever publication the key holds now. Nothing compares the object's size or content.A plain
Removeis enough to trigger it: the lease is already expired afterPutEnd, andRemovedoes not check for an offload task. (UpsertStart, by contrast, refuses while a worker owns the task.)Possible fixes:
Pre-existing on main. Found by @CAICAIIs in review of #4717.
@github-actions[bot] commented on GitHub (Oct 16, 2026):
Thanks for opening this issue, @Aionw!
41376987A maintainer will triage this when possible. To help us respond faster, please include:
Useful links: Documentation · Contributing guide
@WryGill commented on GitHub (Oct 16, 2026):
Hi, I'd like to work on this issue. This would be my first contribution to Mooncake, and I'd be happy to give it a try. Could you assign it to me? Thanks!
@he-yufeng commented on GitHub (Oct 16, 2026):
Welcome, @WryGill. Happy to have you pick this up, with one honest caveat up front: this lives in the master's offload-completion state machine, where the failure is a race between an erase and a late completion, so the hard part is proving the fix under concurrency rather than writing it.
A good first deliverable that does not commit us to a design: a failing regression test in
master_servicecovering Aionw's sequence (PutEnd, worker drains the offload task, Remove plus republish of the same key, then the late completion arrives and must not attach its LOCAL_DISK replica to the new publication). That pins the bug and gives whichever fix we pick a target.On the design fork Aionw listed, my lean is the refuse-or-tombstone variant for the immediate fix, since it does not change the task/completion wire shape; carrying a publication identity on the task is the cleaner long-term answer but is a protocol change worth its own discussion. @Aionw you found this in the #4717 review, so your call on which direction to take first carries the most context.
@he-yufeng commented on GitHub (Oct 17, 2026):
An update since my earlier note, because the landscape changed: #4687 (fixing #4686) is now in flight and takes the publication-identity route — every offload/promotion task gets an L4 task id, and the master registers a disk replica only from the completion of the exact task the reporting store drained, with at most one task per key. Aionw's sequence here (Remove plus republish before the late completion) is the same race as #4686's cause 1, and under #4687 the late report echoes the old task's id and is rejected rather than attached to the new publication.
So the practical guidance shifts. @WryGill, rather than building a separate refuse-or-tombstone fix that would land in the same state machine at the same time, the most valuable first contribution is still that failing regression test for Aionw's sequence in
master_service: it becomes the acceptance check proving whether #4687 closes this issue end to end, and if any gap remains it tells us exactly where. If the test passes on #4687's branch, this issue closes with it; if you would rather wait and pick it up after #4687 merges, that is fine too.@Aionw your earlier question on direction is answered by events: the wire-change route is already implemented and green on CI, pending a rebase and a second maintainer's review.
@WryGill commented on GitHub (Oct 17, 2026):
Thanks for the update! I’ll work on the regression test now, covering the Remove → republish → late offload completion sequence in
master_service. I’ll verify that it fails on main and check whether it passes on #4687’s branch, then share the results here.@WryGill commented on GitHub (Oct 19, 2026):
Hi @he-yufeng , I tested the Remove → republish → late offload completion sequence on main (
d750cdd) and #4687 (4c2bd97).All three regression cases—no new offload task, queued task, and already-taken task—reproduce the bug on main and pass on #4687. These results confirm that #4687 fixes the race described in this issue at the tested commit.
Once #4687 is merged, I can submit a follow-up PR adding these regression tests.
@he-yufeng commented on GitHub (Oct 20, 2026):
Thanks for running this down — three cases failing on main and passing on #4687 is exactly the evidence the race is covered. Agreed on the order: once #4687 lands, the regression tests go in as their own PR. When you open it, tag this issue and I'll review.