pub enum WalError {
Show 24 variants
Io(Error),
ChecksumMismatch {
lsn: u64,
expected: u32,
actual: u32,
},
CheckpointCorrupt {
path: String,
detail: String,
},
InvalidMagic {
offset: u64,
expected: u32,
actual: u32,
},
UnsupportedVersion {
version: u16,
supported: u16,
},
SegmentFormatVersion {
path: String,
version: u16,
supported: u16,
},
UnknownRequiredRecordType {
record_type: u32,
lsn: u64,
},
PayloadTooLarge {
size: usize,
max: usize,
},
Sealed,
AlignmentViolation {
context: &'static str,
required: usize,
actual: usize,
},
LockPoisoned {
context: &'static str,
},
EncryptionError {
detail: String,
},
EncryptedRecordWithoutKey {
lsn: u64,
context: &'static str,
},
DwbOffNotOpenable,
CorruptRecord {
lsn: u64,
detail: String,
},
InvalidPayload {
detail: String,
},
DirectIoUnsupported {
path: String,
},
OutOfSpace {
context: &'static str,
},
DurabilityLost {
detail: String,
},
MidFileCorruption {
path: String,
offset: u64,
resync_offset: u64,
resync_lsn: u64,
},
SegmentLsnGap {
path: String,
previous_path: String,
previous_last_lsn: u64,
expected_lsn: u64,
found_lsn: u64,
},
SegmentOverlapsPrevious {
path: String,
first_lsn: u64,
previous_path: String,
previous_last_lsn: u64,
},
RollCleanupFailed {
path: String,
roll: Box<WalError>,
cleanup: Box<WalError>,
},
ReplayBelowRetainedFloor {
from_lsn: u64,
retained_floor_lsn: u64,
earliest_segment: String,
},
}Expand description
Errors produced by the WAL subsystem.
Variants§
Io(Error)
I/O error from the underlying file operations.
ChecksumMismatch
CRC32C checksum mismatch during read/replay.
CheckpointCorrupt
Checkpoint frame is corrupt: bad version, truncated payload, or CRC mismatch.
InvalidMagic
Record header has an invalid magic number — file is corrupted or not a WAL.
UnsupportedVersion
WAL format version is not supported by this binary.
SegmentFormatVersion
A segment holds records in a WAL format version this build cannot read.
The same finding as WalError::UnsupportedVersion, reported by the
callers that know which file carries it. A reader sees one header at a
time and holds no path, and a version alone does not tell an operator
which segment to act on.
UnknownRequiredRecordType
Unknown required record type encountered during replay. Optional unknown record types are safely skipped.
PayloadTooLarge
Write payload exceeds maximum record size.
Sealed
Attempted to write to a WAL that has been closed or is in error state.
AlignmentViolation
Alignment violation — O_DIRECT requires aligned buffers and offsets.
LockPoisoned
A mutex was poisoned (another thread panicked while holding the lock).
EncryptionError
Encryption or decryption failed.
EncryptedRecordWithoutKey
A record still carries ENCRYPTED_FLAG at a point where plaintext is
required, and no key ring is available to turn it back into plaintext.
Passing the ciphertext through would hand every downstream decoder bytes it cannot parse: the lucky ones fail with a confusing framing error, the unlucky ones decode garbage into engine state. Skipping the record would silently drop a committed write. Neither is recoverable at this layer, so the only honest outcome is to refuse to replay.
DwbOffNotOpenable
DoubleWriteBuffer::open was called with DwbMode::Off. Callers
that want the DWB disabled must not call open at all.
CorruptRecord
Record payload failed structural validation (truncation, bad length
prefix, invalid UTF-8, etc.). Distinct from WalError::ChecksumMismatch
— the bytes passed CRC but the payload’s own framing is wrong.
InvalidPayload
Record payload is structurally invalid at parse time, before the surrounding LSN context is known (e.g., anchor payload decoded from a byte slice during unit-level use).
DirectIoUnsupported
The filesystem holding the WAL cannot open files with O_DIRECT.
Most overlayfs configurations, many network filesystems, and tmpfs
before Linux 6.1 reject O_DIRECT at open(2) with EINVAL. Kept
distinct from a generic WalError::Io because the operator action
is specific — relocate the data directory or opt out of direct I/O
deliberately — and because silently continuing with buffered I/O
would downgrade the WAL’s durability guarantee without anyone being
told.
OutOfSpace
The filesystem ran out of space while appending to the WAL (ENOSPC).
Distinct from a generic WalError::Io so callers can stop
acknowledging writes and surface a specific operator action instead of
retrying a write that cannot succeed.
DurabilityLost
An fsync of the WAL segment failed, so the writer is poisoned and permanently refuses further work.
A failed fsync is terminal, not transient. Linux reports a writeback
error exactly once (errseq_t) and drops the dirty pages that failed,
so the bytes the writer already handed to the page cache are gone and
no retry can put them back. Continuing to serve would let a later
sync see an empty buffer, report success, and acknowledge records
that no longer exist anywhere. The only correct move at this layer is
to stop: the segment must be re-opened from what is actually on disk.
MidFileCorruption
A WAL segment is damaged in the middle: a valid record was found after the damaged region, so it cannot be the unfsynced tail of the last write.
Stopping at the damage point and calling everything before it “the committed prefix” would silently discard the committed records that follow, so recovery refuses to proceed instead.
SegmentLsnGap
Two surviving WAL segments are not contiguous: the later segment’s declared first LSN is above the LSN that follows the end of the earlier one, so a whole segment is missing from the middle of the log.
Concatenating the two would hand recovery a record stream with a silent hole in it, so replay refuses instead. A missing prefix is legal (checkpoint truncation deletes whole segments below the checkpoint) and does not produce this error.
SegmentOverlapsPrevious
The last segment starts at or below an LSN an earlier segment already holds. An interrupted roll created it while the earlier segment stayed active. Resuming it would reissue LSNs, so the WAL refuses to open.
RollCleanupFailed
A segment roll failed, and removing the segment file it created also
failed. The next open refuses that file with SegmentOverlapsPrevious.
ReplayBelowRetainedFloor
A replay was asked for the suffix starting at from_lsn, but the WAL
no longer retains it: checkpoint truncation has already deleted every
segment below retained_floor_lsn.
Filtering the surviving records by lsn >= from_lsn would hand the
caller a shorter suffix that is indistinguishable from a complete
one — no hole, no gap between surviving segments, just fewer records
than the caller’s own bookkeeping says it must observe. A consumer that
treats that as complete advances its watermark past records it never
saw, and every effect keyed on them (change data capture, triggers,
streaming materialized views) is lost with nothing recorded anywhere.
Truncation is supposed to hold below every consumer’s watermark, so this is a broken invariant rather than an expected outcome; the error exists so a residual violation is loud instead of silent.
Trait Implementations§
Source§impl Error for WalError
impl Error for WalError
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Auto Trait Implementations§
impl !RefUnwindSafe for WalError
impl !UnwindSafe for WalError
impl Freeze for WalError
impl Send for WalError
impl Sync for WalError
impl Unpin for WalError
impl UnsafeUnpin for WalError
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out indicating that a T is niched.impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.