You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Master cannot restart. Raft apply stops fatally while replaying a committed Mkdir journal entry:
refusing duplicate inode allocation during follower replay:
inode_id=208477849, last_inode_id=208677538, journal=Mkdir(...)
The guard in JournalLoader rejects any follower-replay allocation whose inode_id <= last_inode_id. In this incident the allocated id is 199,689 smaller than the current high-water mark, so this is not a near-miss of the next id. After the error, raft_node.rs stops the node and master stays down.
This looks like a restart/replay availability failure. Either:
An older/duplicate Mkdir is still present in the Raft log after last_inode_id has already advanced (snapshot restore, overlapping log, or a previously allocated id being replayed), and the fail-fast check treats that as fatal; or
Run a master cluster under a Spark / Hive warehouse workload that creates many staging directories (.spark-staging-* / _temporary/attempt_*).
Restart master (or let a follower replay committed logs after snapshot restore / role change).
Apply hits a committed Mkdir whose dir.id is already <= last_inode_id.
Raft apply returns the duplicate-allocation error and the raft node stops.
We do not yet have a minimal standalone repro. The production log below is enough to identify the invariant and the restart failure.
Expected behavior
Master restart must not stay down solely because a replayed create carries an inode id that is already covered by last_inode_id / the restored tree, if that entry is historical or already applied.
If the log really contains a duplicate allocation assigned to a different namespace object, fail with a clear corruption message and a documented recovery path. Do not leave the process in a loop of crash-on-replay.
Confirm whether the Mkdir inode already exists in the restored tree / snapshot under the same path (safe skip) vs a different path (true duplicate).
Check snapshot compact vs remaining Raft log overlap: restore sets last_inode_id to the tree max, then replay of older create entries will always trip inode_id <= last_inode_id.
Explain parent_id: -1 on this MkdirEntry.
If the check stays fail-fast, add a recovery path so master can start after snapshot+log overlap without disabling all replay errors.
Add a regression that restores a snapshot (high last_inode_id) and then replays an older committed Mkdir that is already in the tree; restart must succeed.
Describe the bug
Master cannot restart. Raft apply stops fatally while replaying a committed
Mkdirjournal entry:The guard in
JournalLoaderrejects any follower-replay allocation whoseinode_id <= last_inode_id. In this incident the allocated id is 199,689 smaller than the current high-water mark, so this is not a near-miss of the next id. After the error,raft_node.rsstops the node and master stays down.This looks like a restart/replay availability failure. Either:
Mkdiris still present in the Raft log afterlast_inode_idhas already advanced (snapshot restore, overlapping log, or a previously allocated id being replayed), and the fail-fast check treats that as fatal; orEither way, a master that already has the metadata on disk cannot come back.
Relevant code:
curvine-master/src/master/journal/journal_loader.rs(follower replay duplicate-inode check, currently around line 273)curvine-master/src/master/journal/entry.rs(JournalEntry::allocated_inode_id()forMkdir/CreateFile/Symlink)crates/metadata/curvine-raft/src/raft/raft_node.rs(fatal apply →raft node stop)fix(raft): fence leader promotion after metadata apply)To Reproduce
.spark-staging-*/_temporary/attempt_*).Mkdirwhosedir.idis already<= last_inode_id.We do not yet have a minimal standalone repro. The production log below is enough to identify the invariant and the restart failure.
Expected behavior
last_inode_id/ the restored tree, if that entry is historical or already applied.inode_id/last_inode_idremain monotonic at cluster scope. A committed log should never assign the same inode id to two different objects (related to [BUG]: Master can reuse op_id/inode_id after leader change when FSM apply lags committed log #957).Screenshots
N/A. Production error log:
OS Version (please complete the following information):
*.db/.../.spark-staging-*/_temporary/...)journal_loader.rsfollower-replay guard from fix(raft): fence leader promotion after metadata apply #1557Additional context
Observed anomalies in the failing entry:
inode_id=208477849vslast_inode_id=208677538(inode_id << last_inode_id)parent_id: -1on theMkdirinode (unexpected for a nested Spark staging path)rpc_id: 0ignore_reply_errorcan log-and-skip this error, but it defaults tofalse, so production restart still dies.Related:
op_id/inode_idafter leader change when FSM apply lags committed logfollower_replay_rejects_duplicate_allocated_inode_idSuggested investigation:
Mkdirinode already exists in the restored tree / snapshot under the same path (safe skip) vs a different path (true duplicate).last_inode_idto the tree max, then replay of older create entries will always tripinode_id <= last_inode_id.parent_id: -1on thisMkdirEntry.last_inode_id) and then replays an older committedMkdirthat is already in the tree; restart must succeed.