Per design §3.2 line 704, tail corruption in a non-last WAL segment is
middle corruption, which must hard-fail recovery instead of being
silently truncated. The previous code in wal/recovery.go always returned
TailCorruptionError for CollectingFragments state or parse errors,
regardless of segment position. Recover then always truncated
segments[last], which could corrupt a valid last segment when the actual
corruption was in a middle segment.
Oracle bg_ef425776 flagged an additional failure mode: "wal/recover.go
总是对 segments[len(segments)-1] 调用截断,但 RecoverFromSegments 的
TailCorruptionError 可能来自非尾段".
Changes:
- wal/record_parser.go: add SegmentPath field to TailCorruptionError for
diagnostics and defensive truncation target identification.
- wal/recovery.go:
- ReplaySegmentFile now takes isLastSegment bool parameter.
- When parse error or CollectingFragments occurs in non-last segment,
return hard error. Uses %v (NOT %w) so IsTailCorruption returns false
— otherwise errors.As would still find underlying TailCorruptionError
through the %w chain and Recover would treat it as truncatable.
- When in last segment, return TailCorruptionError with SegmentPath set.
- RecoverFromSegments passes isLastSegment based on iteration index.
- wal/recover.go:
- Use tce.SegmentPath as authoritative truncation target (defensive
fallback to segments[last] if missing). After C4 fix, TailCorruptionError
is only returned for last segment, so this is always segments[last]
in practice.
Tests:
- wal/recovery_test.go: 4 unit tests for ReplaySegmentFile covering
last/non-last × CollectingFragments/parse-error matrix. Existing direct
ReplaySegmentFile calls updated to pass isLastSegment=true.
- wal/recover_test.go: 4 integration tests covering middle-segment
CollectingFragments corruption (must hard-fail), middle-segment CRC
corruption (must hard-fail), last-segment corruption in single-segment
WAL (must truncate), last-segment corruption in multi-segment WAL
(must truncate only last segment).
Verified: each new test fails on pre-fix code (non-last corruption
silently truncated valid last segment) and passes after the fix. Full
suite green including go test -race ./... .
Audit context: docs/audit-3.2.md C4 (Oracle-verified bg_ef425776).