From 8996e82d84dad9e1f0cd574f786c11960f842adf Mon Sep 17 00:00:00 2001 From: bang <3656828039@qq.com> Date: Tue, 12 May 2026 00:55:03 +0800 Subject: [PATCH] =?UTF-8?q?fix(storage):=20Delete=20=E5=86=99=E5=85=A5=20W?= =?UTF-8?q?AL=20tombstone=20=E7=A1=AE=E4=BF=9D=E5=B4=A9=E6=BA=83=E6=81=A2?= =?UTF-8?q?=E5=A4=8D=E6=97=B6=E8=83=BD=E9=87=8D=E6=94=BE=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Delete 之前未写 WAL,崩溃恢复时会丢失已删除的 key。 修复: 在删除前先写 WAL(nil value = tombstone), 恢复时遇到 nil value 则执行 delete 而非 insert,保持与 Put 一致的错误处理流程。 --- storage/zstorage/memtable.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/storage/zstorage/memtable.go b/storage/zstorage/memtable.go index 290a16a..61a8838 100644 --- a/storage/zstorage/memtable.go +++ b/storage/zstorage/memtable.go @@ -227,6 +227,12 @@ func (m *MemTable) Delete(key []byte) error { return errors.New("NO DATA IN MEMTABLE") } + // 先写 WAL tombstone(value 为 nil 表示删除标记),确保崩溃恢复时能重放删除 + if err := m.wal.Write(istorage.LogEntry{Key: key, Value: nil}); err != nil { + fmt.Println("Error writing delete to WAL:", err) + return err + } + if !m.active.delete(key) { fmt.Println("the key does not exist") return errors.New("KEY NOT FOUND") @@ -281,8 +287,11 @@ func (m *MemTable) recoverFromWAL() { fmt.Printf("[INFO] Recovering %d entries from WAL...\n", len(entries)) for _, entry := range entries { - // 直接插入 active 表,不写入 WAL(避免重复写入) - m.active.insert(entry.Key, entry.Value) + if entry.Value == nil { + m.active.delete(entry.Key) + } else { + m.active.insert(entry.Key, entry.Value) + } } fmt.Printf("[INFO] WAL recovery completed, memtable size: %d\n", m.active.size)