mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-08 15:41:15 +02:00
* shell: clean up the target copy when a merge upload fails A replicated write commits the needle to the local volume before it fans out to the other replicas, so an upload that reports failure can still have left a copy on the target. fs.mergeVolumes printed "failed to move" and carried on, so that copy stayed behind forever: the filer is never re-pointed at it, and nothing else knows it exists. One sick replica orphans roughly half the chunks of a merge, two thirds with three copies, since the entry node is picked at random from the replicas and the replica upload uses MaxAttempts 1. A volume with a single copy has no such window: the write is one local append that either succeeds or leaves nothing. Delete the needle we may have written before continuing. The source side already did exactly this, so deleteMovedSourceNeedles is renamed to deleteOrphanedNeedles and reused for both ends. Claude-Session: https://claude.ai/code/session_01XjiMGK72F4Gs3yWNJhnVjy * shell: verify the cookie before deleting a merge target needle The target cleanup deletes a needle an upload may or may not have written, and BatchDelete matches on the needle id alone. Needle ids come from one global sequence, so normally nothing else can hold that id — but a volume restored from elsewhere, or one written either side of a master sequence reset, can, and then a failed move deletes a live needle out from under its filer entry. Have the volume server verify the cookie for those. Source needles keep deleting by id: they are the ones the filer just pointed at, matching every other filer-driven delete. Claude-Session: https://claude.ai/code/session_01XjiMGK72F4Gs3yWNJhnVjy * shell: delete the target copies an abandoned manifest rewrite leaves rewriteManifestChunk moves sub-chunks one at a time and only then uploads the rewritten manifest. Every error after the first successful move — a nested rewrite failing, the marshal, the manifest upload — returned without touching the copies already written to the target volumes. The filer keeps pointing at the old manifest, so those copies orphan, one per sub-chunk moved so far. Track them alongside the sources and delete them on the way out. Nested rewrites hand theirs up so an outer failure clears the whole subtree. A failed UpdateEntry deliberately still leaks its copies: that error can also mean the filer applied the update and lost the response, and deleting there would turn a leak into data loss. Claude-Session: https://claude.ai/code/session_01XjiMGK72F4Gs3yWNJhnVjy * shell: give the plan its room back when a manifest rewrite is abandoned allocate reserves plannedSize against the chosen target for every move a multi-target source makes, and release hands it back when the move fails. Abandoning a manifest rewrite now deletes the copies that did land, so those reservations stopped matching anything on disk: the plan kept counting bytes that are gone and refused later chunks with "no target volume has room". Release them alongside the delete. Nested rewrites hand theirs up so an outer failure unwinds the whole subtree's accounting. Claude-Session: https://claude.ai/code/session_01XjiMGK72F4Gs3yWNJhnVjy