Write-Ahead Log (WAL)
Source: db/log.go, db/kv_entry.go
The Write-Ahead Log (WAL) provides crash-safe persistence. Every committed transaction is written and fsync'd to the WAL before the in-memory state is updated. On restart, PallasDB replays all committed entries to reconstruct the memtable.
Log entries
Each WAL record is a single Entry:
type EntryOp uint8
const (
EntryAdd EntryOp = 0 // set key → value
EntryDel EntryOp = 1 // delete key
EntryCommit EntryOp = 2 // transaction boundary
)
type Entry struct {
key []byte
val []byte
op EntryOp
}
Wire format
Each entry is encoded as:
[4 bytes] CRC32-IEEE checksum of everything after these 4 bytes
[4 bytes] key length (little-endian uint32)
[4 bytes] value length (little-endian uint32)
[1 byte] op (EntryAdd=0, EntryDel=1, EntryCommit=2)
[key len] key bytes
[val len] value bytes
The CRC32 checksum covers all bytes starting from the key-length field. An EntryCommit record has zero-length key and value. The maximum entry size is 64 MiB.
Transaction protocol
A single transaction writes:
EntryAdd key=k1 val=v1
EntryDel key=k2 val=nil
EntryAdd key=k3 val=v3
EntryCommit
The Commit() call:
- Writes the
EntryCommitrecord. - Calls
file.Sync()- the writes are now durable. - Advances
writer.committedto the current offset.
If the process crashes before Sync() returns, the uncommitted records are ignored on recovery because the commit marker was never persisted.
ResetTX() rolls back an uncommitted transaction by resetting the write offset to writer.committed, overwriting any partially written records on the next write.
Recovery on startup
openLog() in kv.go:
- Reads entries sequentially from offset 0.
- Accumulates
EntryAdd/EntryDelrecords in a buffer. - On
EntryCommit, records the committed count. - On EOF, bad checksum, or truncated read, stops - only committed entries survive.
- Sorts the committed entries by key (stable sort), then replays them into the memtable, deduplicating by keeping the last write per key.
Log truncation
When the memtable is compacted into an SSTable (compactLog()), the WAL is truncated to zero with file.Truncate(0). The SSTable now contains the durable representation of what was in the log.
File management
The WAL file is created via createFileSync which opens with O_CREATE | O_RDWR and calls Sync() after creation to ensure the directory entry is durable. Reads use ReadAt (positioned reads) via OffsetReader, avoiding seek races when reading and writing concurrently.