mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-20 21:14:25 +02:00
* filer.sync: keep the needle-404 clock from resetting on live volumes The give-up clock for a source chunk that cannot be produced is kept per volume so a vacuumed volume's files all inherit one wait. But a needle 404 and a volume lookup failure shared that clock, and sourceServed cleared it whenever any needle on the same volume read fine, so on a busy cluster the grace never elapsed for a single deleted needle on a healthy volume and filer.sync retried it forever (#11841). Give needle not-found answers their own per-volume clock that serving siblings does not reset. * filer.sync: an answered 404 needs no liveness probe before skipping After the missing-chunk gate gives up, onReplicateChunkError only skips the entry when a re-read of the most recently served chunk succeeds. That probe can never have been armed on a fresh sync, and its single stored file id can itself be vacuumed since — either way the entry stays pinned and the offset never advances. A needle 404 was answered by a live volume server, which is itself proof the source is serving requests, so skip on it directly. Keep the probe for the lookup-failure flavor, where no server answered and the silence can still mean a source outage. * filer.sync: skip a replayed version the source rewrote in place Supersession was decided by entry mtime alone, so a source entry whose chunks were swapped without an mtime bump — remote cache eviction and re-cache, an in-place repair — never read as superseded, and its vacuumed chunks were retried indefinitely. When a chunk is missing, compare the replayed chunk's file id against the live entry's resolved chunk set: absent means the replayed version is obsolete and its event is skipped on the first failure instead of after the give-up window. The same live-entry comparison now also decides the entry-level skip in onCorruptChunk/onReplicateChunkError. * filer.sync: give each missing needle its own grace clock A 404 is one needle's answer, but the clock was kept per volume: once the first needle's wait expired, every other needle on that volume inherited an already-elapsed clock and could be written off on its first sighting. Track the wait per file id and clear it only when that needle itself serves again, so a live volume's healthy needles neither shorten nor restart it. * filer.sync: keep the probe for filer-proxied 404s ReadPart proxied through the source filer collapses "no volume locations" into the same 404 a missing needle returns, so that answer cannot stand in for the liveness probe the way a direct volume read's can. Only treat 404 as an answered needle when the sink reads volume servers directly. * filer.sync: only a not-older live entry can supersede a replay Chunk-list comparison must respect the same ordering the mtime check does: a live entry older than the replayed version means the source was rolled back, so its differing chunks say nothing about whether the replayed data is still needed. Gate the content check on live mtime >= replayed mtime in both sourceMovedOn and sourceDroppedChunk. * filer.sync: compare chunk ids without resolving manifests resolvedChunkFileIds downloaded manifest files to expand chunk lists, so a manifest sitting on a dead volume made the supersession check itself fail and left the offset pinned behind a replica the source cannot read. File ids are immutable needle identities — the unresolved sets already compare chunk content exactly, and the check no longer performs I/O. * filer.sync: judge nested chunks by their top-level chunk A manifest child is not in the entry's chunk list even when the manifest still references it, so checking the live entry for the child id reported it dropped and returned the raw 404 — unwrapped, so the offset still pinned. Thread the entry-level chunk id down the manifest recursion and consult it for the dropped-chunk check instead. * filer.sync: let the manifest-child test exit through the gate Run the worker with a shortened grace period and assert the returned error is marked errSourceChunkMissing, instead of racing the worker still running against a restored RetryWaitTime.