Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public static SegmentRing openExisting(String sfDir, long maxBytesPerSegment) {
// CAUTION: only unlink when the file is genuinely
// empty past the header. If frame[0] failed CRC
// (bit-rot, partial-page-write at crash, etc.) but
// valid frames followed, scanFrames returns
// valid frames followed, the recovery scan returns
// lastGood=HEADER_SIZE and frameCount=0 -- yet
// tornTailBytes is non-zero. Treating that as
// "empty hot-spare" would silently destroy every
Expand Down Expand Up @@ -269,8 +269,9 @@ public static SegmentRing openExisting(String sfDir, long maxBytesPerSegment) {
// FSNs after recovery. A gap means a segment went missing (a
// manual deletion) or a sealed segment under-recovered -- its tail
// was cut short by a sparse/unbacked page or a mid-file media error
// (bad sector), the same class of fault scanFrames tolerates on the
// active segment but which corrupts the range on a sealed one.
// (bad sector), the same unreadable-region boundary the recovery
// scan tolerates on the active segment but which corrupts the
// range on a sealed one.
for (int i = 1, n = opened.size(); i < n; i++) {
MmapSegment prev = opened.get(i - 1);
MmapSegment curr = opened.get(i);
Expand Down
16 changes: 7 additions & 9 deletions core/src/main/java/io/questdb/client/std/FilesFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,13 @@ public interface FilesFacade {
* Stat length of the file at {@code path}, in bytes. Default delegates to
* {@link Files#length(String)}.
*
* <p>Test injection point: {@code MmapSegment.openExisting} maps the file to
* this length and scans straight out of the mapping, so a wrapping facade
* that returns a value <em>larger</em> than the real file makes the mapping
* extend past end-of-file. A read of a page beyond real EOF raises SIGBUS on
* <em>every</em> filesystem (which HotSpot translates to a catchable
* {@code InternalError} at an {@code Unsafe} intrinsic site) — the same fault
* a genuinely unbacked/sparse page raises on ZFS, but reproduced
* deterministically on ext4/xfs too. That is what lets recovery's mmap-fault
* guard be regression-tested on any CI runner rather than only on ZFS.
* <p>Test injection point: {@code MmapSegment.openExisting} treats this
* length as the file's extent and preads its recovery scan against it, so a
* wrapping facade that returns a value <em>larger</em> than the real file
* makes the scan read past end-of-file. Those reads come back short, which
* recovery must treat as the boundary of recoverable data — the same
* outcome as a file whose size metadata survived a crash its data blocks
* did not, reproduced deterministically on any filesystem and CI runner.
*/
long length(String path);

Expand Down
Loading
Loading