diff --git a/etcdctl/command/backup_command.go b/etcdctl/command/backup_command.go index 82d7bda33..ed2488e40 100644 --- a/etcdctl/command/backup_command.go +++ b/etcdctl/command/backup_command.go @@ -15,6 +15,7 @@ package command import ( + "fmt" "log" "os" "path" @@ -71,7 +72,12 @@ func handleBackup(c *cli.Context) { } defer w.Close() wmetadata, state, ents, err := w.ReadAll() - if err != nil { + switch err { + case nil: + case wal.ErrSnapshotNotFound: + fmt.Printf("Failed to find the match snapshot record %+v in wal %v.", walsnap, srcWAL) + fmt.Printf("etcdctl will add it back. Start auto fixing...") + default: log.Fatal(err) } var metadata etcdserverpb.Metadata diff --git a/wal/wal.go b/wal/wal.go index 61fde9349..93aff5f6c 100644 --- a/wal/wal.go +++ b/wal/wal.go @@ -203,7 +203,7 @@ func openAtIndex(dirpath string, snap walpb.Snapshot, all bool) (*WAL, error) { // ReadAll reads out all records of the current WAL. // If it cannot read out the expected snap, it will return ErrSnapshotNotFound. // If loaded snap doesn't match with the expected one, it will return -// ErrSnapshotMismatch. +// all the records and error ErrSnapshotMismatch. // TODO: detect not-last-snap error. // TODO: maybe loose the checking of match. // After ReadAll, the WAL will be ready for appending new records. @@ -256,9 +256,9 @@ func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb. state.Reset() return nil, state, nil, err } + err = nil if !match { - state.Reset() - return nil, state, nil, ErrSnapshotNotFound + err = ErrSnapshotNotFound } // close decoder, disable reading @@ -269,7 +269,7 @@ func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb. // create encoder (chain crc with the decoder), enable appending w.encoder = newEncoder(w.f, w.decoder.lastCRC()) w.decoder = nil - return metadata, state, ents, nil + return metadata, state, ents, err } // Cut closes current file written and creates a new one ready to append.