Date: 2026-05-28
Time: 18:50
WriteAheadLog.iterateiterate provides raw, unfiltered access to every record stored in the WAL — including uncommitted batch operations, COMMIT markers, and CHECKPOINT records. This contrasts with replay, which filters out non-data records and skips uncommitted batches. It exists for diagnostic, inspection, or tooling scenarios where the caller needs to see the full on-disk state of the log, not just the logically committed view.
walfiles() and _fd are in a valid state).None beyond self. The method takes no arguments — it always scans the entire log from the beginning.
Returns an Iterator[WALRecord]. Each WALRecord contains:
seq_num: monotonically increasing sequence numberop_type: one of "PUT", "DELETE", "COMMIT", "CHECKPOINT", or "UNKNOWN"key / value: UTF-8 decoded stringschecksum: the CRC32 stored in the recordThe caller must handle:
COMMIT and CHECKPOINT, which replay would suppress1. Acquire lock and flush: Grabs lock, checks if there's an open file descriptor (fd), and flushes it. This ensures any writes buffered in userspace by the current process are pushed to the OS before reading. The lock is released immediately after the flush — it is not held during iteration.
2. Delegate to readallrecords: Uses yield from to lazily stream records. readallrecords iterates over every .wal file in sorted filename order, opens each read-only, and calls readrecord in a loop until EOF (None return) or CRC failure (ValueError).
flush() syscall — no fsync, so data reaches the OS page cache but isn't necessarily durable). Then opens each WAL segment file for reading during iteration.append calls can interleave with iteration. The iterator may or may not see records written after iterate() was called, depending on timing and whether those writes land in a file the iterator hasn't opened yet.readrecord raises ValueError on CRC failure. readall_records catches this and returns (stops iteration silently). The caller receives all records up to the corruption point with no indication that more data existed.OSError/IOError to the caller.readrecord returns None and iteration moves to the next file.Typical callers use iterate when they need the raw log contents rather than the committed-only view:
wal = WriteAheadLog("/tmp/wal")
for record in wal.iterate():
print(f"seq={record.seq_num} op={record.op_type} key={record.key}")
Caller obligations:
readall_records (internal): does the actual file scanning and record parsingwalfiles (internal): returns sorted segment file pathsreadrecord (module-level): binary deserialization and CRC verificationthreading.Lock: for the flush synchronizationos, struct, zlib (indirectly, through readrecord)