Skip to main content

fsqlite_wal/
lib.rs

1//! WAL checksum primitives, integrity helpers, and native commit protocol.
2//!
3//! Fault Matrix (`bd-966ja`) for batched append and publish paths:
4//!
5//! This matrix covers the byte-oriented append helpers in [`wal::WalFile`] and
6//! the current durable-publish helper [`group_commit::write_consolidated_frames`].
7//! It intentionally stops at WAL durability. Later SHM / snapshot-plane publish
8//! remains the caller's responsibility (see `native_commit`).
9//!
10//! | Stage | Primary APIs | Fault conditions | Surface | State after fault |
11//! | --- | --- | --- | --- | --- |
12//! | Batch shape + serialization | `prepare_frame_bytes_with_transforms_into` | Frame-count mismatch, page-size mismatch, `frame_count * frame_size` overflow, salt/checksum helper failure while constructing transforms | `WalCorrupt`, `DatabaseFull`, or helper error | WAL file and in-memory WAL counters stay unchanged; caller-owned scratch may contain partial serialized bytes |
13//! | Append-window validation | `prepared_append_window_still_current` | File size changed, generation header changed, short header read, header parse failure | `Ok(false)` for stale window; `WalCorrupt` / parse error for malformed WAL | No append occurs; caller must rebuild from the new seed or treat the WAL as corrupt |
14//! | Checksum finalization | `finalize_prepared_frame_bytes` | Prepared buffer length mismatch, `frame_count * frame_size` overflow, salt/checksum write failure | `WalCorrupt`, `DatabaseFull`, or checksum helper error | No on-disk mutation; caller buffer may have partially rewritten checksum fields |
15//! | Durable byte append | `append_finalized_prepared_frame_bytes` | Frame-count overflow, prepared buffer length mismatch, VFS `write` failure, post-write state advance overflow guard | `DatabaseFull`, `WalCorrupt`, or VFS error | Pre-write validation faults leave WAL state unchanged; a write failure happens before `advance_state_after_write`, so in-memory counters do not advance even though the on-disk tail may need replay/validation |
16//! | One-shot prepared append | `append_prepared_frame_bytes` | Any finalization fault plus any finalized-append fault | Propagated error from the lower stage | Same guarantees as the composed lower layers: no publish on finalize failure; write-path faults may leave an untrusted tail that recovery must trim or validate |
17//! | Fused batched append | `append_frames` | Test/fault-injection busy hook, page-size mismatch in any frame, batch-size overflow, salt/checksum helper failure, finalized append failure, test-only after-append injected fault | `Busy`, `WalCorrupt`, `DatabaseFull`, helper error, or injected test fault | Assembly faults leave `frame_scratch` restored and counters unchanged; an after-append injected fault is special because bytes/state may already be advanced even though the function returns `Err` |
18//! | Durable publish | `write_consolidated_frames`, direct `WalFile::sync` callers | Frame-batch byte-size overflow, any `append_frames` fault, `sync(FULL)` failure after a successful append | `Internal`, append error, or VFS sync error | If `sync` fails, WAL bytes may already be appended and `WalFile` state may already reflect them, but durability/publish is not established, so higher layers must not advertise the batch as committed |
19
20#[cfg(target_arch = "wasm32")]
21use std::path::Path;
22
23pub mod cell_delta_commit;
24pub mod cell_delta_wal;
25pub mod checkpoint;
26pub mod checkpoint_executor;
27pub mod checksum;
28#[cfg(test)]
29pub mod commit_path_histograms;
30#[cfg(any(test, feature = "fault-injection"))]
31pub mod fault_hooks;
32pub mod group_commit;
33pub mod metrics;
34pub mod native_commit;
35pub mod parallel_wal;
36pub mod per_core_buffer;
37pub mod recovery_compaction;
38pub mod recovery_fence;
39pub mod telemetry;
40pub mod wal;
41#[cfg(not(target_arch = "wasm32"))]
42pub mod wal_fec;
43pub mod wal_index;
44
45pub use cell_delta_commit::{
46    CellDeltaDescriptor, FullPageFrame, MixedCommitStats, MixedFrameSubmission,
47    build_cell_delta_frames, serialize_mixed_frames,
48};
49pub use cell_delta_wal::{
50    CELL_DELTA_CHECKSUM_SIZE, CELL_DELTA_FRAME_MARKER, CELL_DELTA_HEADER_SIZE,
51    CELL_DELTA_MAX_DATA_SIZE, CELL_DELTA_MIN_FRAME_SIZE, CellDeltaWalFrame, CellOp,
52    WalRecoverySummary, extract_page_number_from_marker, is_cell_delta_frame,
53};
54pub use checkpoint::{
55    CheckpointMode, CheckpointPlan, CheckpointPostAction, CheckpointProgress, CheckpointState,
56    plan_checkpoint,
57};
58pub use checkpoint_executor::{CheckpointExecutionResult, CheckpointTarget, execute_checkpoint};
59pub use checksum::{
60    BTREE_PAGE_TYPE_FLAGS, CRASH_MODEL_SECTOR_SIZES, ChecksumFailureKind, CrashModelContract,
61    HashTier, IntegrityCheckIssue, IntegrityCheckLevel, IntegrityCheckReport,
62    PAGE_CHECKSUM_RESERVED_BYTES, RecoveryAction, SQLITE_DB_HEADER_RESERVED_OFFSET,
63    SQLITE_DB_HEADER_SIZE, SqliteWalChecksum, WAL_FORMAT_VERSION, WAL_FRAME_HEADER_SIZE,
64    WAL_HEADER_SIZE, WAL_MAGIC_BE, WAL_MAGIC_LE, WalChainInvalidReason, WalChainValidation,
65    WalFecRepairOutcome, WalFrameHeader, WalHeader, WalRecoveryDecision, WalSalts, Xxh3Checksum128,
66    attempt_wal_fec_repair, compute_wal_frame_checksum, configure_page_checksum_reserved_bytes,
67    content_address_hash_128, crash_model_contract, crc32c_checksum, detect_torn_write_in_wal,
68    integrity_check_database_header, integrity_check_level1_page, integrity_check_level2_btree,
69    integrity_check_level3_overflow_chain, integrity_check_level4_cross_reference,
70    integrity_check_level5_schema, integrity_check_sqlite_file_level1, integrity_hash_xxh3_128,
71    is_valid_btree_page_type, merge_integrity_reports, page_checksum_reserved_bytes,
72    read_page_checksum, read_wal_frame_checksum, read_wal_frame_salts, read_wal_header_checksum,
73    read_wal_header_salts, recover_wal_frame_checksum_mismatch,
74    recovery_action_for_checksum_failure, sqlite_wal_checksum, supports_torn_write_sector_size,
75    tier_for_algorithm, validate_wal_chain, validate_wal_header_checksum, verify_page_checksum,
76    verify_wal_fec_source_hash, wal_fec_source_hash_xxh3_128, wal_frame_db_size,
77    wal_header_checksum, write_page_checksum, write_wal_frame_checksum, write_wal_frame_salts,
78    write_wal_header_checksum, write_wal_header_salts, zero_page_checksum_trailer,
79};
80pub use group_commit::{
81    ConsolidationMetrics, ConsolidationMetricsSnapshot, ConsolidationPhase, FrameSubmission,
82    GLOBAL_CONSOLIDATION_METRICS, GroupCommitConfig, GroupCommitConsolidator, PhaseHistogram,
83    PhasePercentiles, SubmitOutcome, TransactionConflictSnapshot, TransactionFrameBatch,
84    TransactionFrameBatchContext, WakeReasonCounters, WakeReasonSnapshot,
85    commit_phase_timing_enabled, commit_phase_timing_forced_enabled,
86    detailed_consolidation_metrics_enabled, set_commit_phase_timing_enabled,
87    write_consolidated_frames,
88};
89pub use metrics::{
90    GLOBAL_GROUP_COMMIT_METRICS, GLOBAL_WAL_FEC_REPAIR_METRICS, GLOBAL_WAL_METRICS,
91    GLOBAL_WAL_RECOVERY_METRICS, GroupCommitMetrics, GroupCommitMetricsSnapshot,
92    WalFecRepairCounters, WalFecRepairCountersSnapshot, WalMetrics, WalMetricsSnapshot,
93    WalRecoveryCounters, WalRecoveryCountersSnapshot,
94};
95pub use parallel_wal::{
96    FsyncPolicy, PARALLEL_WAL_COMPATIBILITY_SELECTOR, PARALLEL_WAL_FLUSH_SCENARIO_ID,
97    PARALLEL_WAL_LANE_POLICY_VERSION, PARALLEL_WAL_STAGE_SCENARIO_ID, ParallelWalBatch,
98    ParallelWalCommitCertificate, ParallelWalConfig, ParallelWalControlSurface,
99    ParallelWalCoordinator, ParallelWalDecisionAction, ParallelWalDecisionRecord,
100    ParallelWalFallbackReason, ParallelWalFrame, ParallelWalLaneBatch, ParallelWalLaneStager,
101    ParallelWalOperatingMode, ParallelWalOrderedResidue, ParallelWalShadowVerdict,
102    ParallelWalTraceRecord, SegmentHeader, SegmentRecoveryOptions, SegmentRecoveryResult,
103    cleanup_segments, default_parallel_wal_lane_count, delete_segment, list_segments,
104    max_durable_epoch, parallel_wal_coordinator_for_path, parallel_wal_fallback_reason_name,
105    parallel_wal_mode_name, parallel_wal_shadow_verdict_name, parallel_wal_should_shadow_compare,
106    read_segment, recover_and_apply_segments, recover_segments, remove_parallel_wal_coordinator,
107    resolve_parallel_wal_control_surface_from_env, segment_path, write_segment,
108};
109pub use per_core_buffer::{
110    AppendOutcome, BufferConfig, BufferState, DEFAULT_BUFFER_SLOT_COUNT, EpochConfig,
111    EpochFlushBatch, EpochOrderCoordinator, FallbackDecision, OverflowPolicy, PerCoreWalBuffer,
112    PerCoreWalBufferPool, WalRecord, thread_buffer_slot,
113};
114pub use recovery_fence::{
115    CheckpointChecksumVerdict, ExpectedPageChecksum, PidOwnedLockEntry, PidOwnedLockRegistry,
116    RECOVERY_FENCE_BACKOFF, RECOVERY_FENCE_MAX_RETRIES, RecoveryFence, RecoveryFenceGuard,
117    ensure_db_fsync_before_wal_truncate, execute_recovery_barrier, fsync_db_file_full,
118    pid_alive_os, verify_checkpoint_checksum_prefix,
119};
120pub use telemetry::{
121    NoOpWalObserver, WalTelemetryEvent, WalTelemetryObserver, WalTelemetryRingBuffer,
122    WalTelemetrySnapshot, wal_telemetry_snapshot,
123};
124pub use wal::{WalFile, WalGenerationIdentity};
125#[cfg(target_arch = "wasm32")]
126pub const DEFAULT_RAPTORQ_REPAIR_SYMBOLS: u8 = 2;
127#[cfg(target_arch = "wasm32")]
128pub const MAX_RAPTORQ_REPAIR_SYMBOLS: u8 = u8::MAX;
129#[cfg(not(target_arch = "wasm32"))]
130pub use wal_fec::{
131    DEFAULT_RAPTORQ_REPAIR_SYMBOLS, MAX_RAPTORQ_REPAIR_SYMBOLS, WAL_FEC_GROUP_META_MAGIC,
132    WAL_FEC_GROUP_META_VERSION, WalFecDecodeProof, WalFecGroupId, WalFecGroupMeta,
133    WalFecGroupMetaInit, WalFecGroupRecord, WalFecRecoveredGroup, WalFecRecoveryConfig,
134    WalFecRecoveryFallbackReason, WalFecRecoveryLog, WalFecRecoveryOutcome, WalFecRepairEvent,
135    WalFecRepairEvidenceCard, WalFecRepairEvidenceQuery, WalFecRepairMetricsSnapshot,
136    WalFecRepairPipeline, WalFecRepairPipelineConfig, WalFecRepairPipelineStats,
137    WalFecRepairSeverityBucket, WalFecRepairSeverityHistogram, WalFecRepairSource,
138    WalFecRepairWitnessTriple, WalFecRepairWorkItem, WalFecScanResult, WalFrameCandidate,
139    append_wal_fec_group, build_source_page_hashes, ensure_wal_with_fec_sidecar,
140    find_wal_fec_group, generate_wal_fec_repair_symbols, identify_damaged_commit_group,
141    persist_wal_fec_raptorq_repair_symbols, query_raptorq_repair_evidence,
142    raptorq_repair_events_snapshot, raptorq_repair_evidence_snapshot,
143    raptorq_repair_metrics_snapshot, read_wal_fec_raptorq_repair_symbols,
144    record_raptorq_recovery_log, recover_wal_fec_group_with_config,
145    recover_wal_fec_group_with_decoder, recovery_log_from_outcome, reset_raptorq_repair_telemetry,
146    scan_wal_fec, wal_fec_path_for_wal,
147};
148pub use wal_index::{
149    WAL_CKPT_INFO_BYTES, WAL_CKPT_LOCK, WAL_INDEX_HASH_MASK, WAL_INDEX_HASH_MULTIPLIER,
150    WAL_INDEX_HASH_SLOTS, WAL_INDEX_HDR_BYTES, WAL_INDEX_PAGE_ARRAY_ENTRIES, WAL_INDEX_VERSION,
151    WAL_LOCK_SLOT_COUNT, WAL_READ_LOCK_BASE, WAL_READ_MARK_COUNT, WAL_RECOVER_LOCK,
152    WAL_SHM_FIRST_HEADER_BYTES, WAL_SHM_FIRST_HEADER_U32_SLOTS, WAL_SHM_FIRST_USABLE_PAGE_ENTRIES,
153    WAL_SHM_HASH_BYTES, WAL_SHM_PAGE_ARRAY_BYTES, WAL_SHM_SEGMENT_BYTES,
154    WAL_SHM_SUBSEQUENT_USABLE_PAGE_ENTRIES, WAL_WRITE_LOCK, WalCkptInfo, WalHashLookup,
155    WalIndexHashSegment, WalIndexHdr, WalIndexSegmentKind, decode_native_u32, encode_native_u32,
156    parse_shm_header, simple_modulo_slot, usable_page_entries, wal_index_hash_slot,
157    wal_index_hdr_copies_match, write_shm_header,
158};
159
160#[cfg(target_arch = "wasm32")]
161pub fn read_wal_fec_raptorq_repair_symbols(_sidecar_path: &Path) -> fsqlite_error::Result<u8> {
162    Ok(DEFAULT_RAPTORQ_REPAIR_SYMBOLS)
163}
164
165#[cfg(target_arch = "wasm32")]
166pub fn persist_wal_fec_raptorq_repair_symbols(
167    _sidecar_path: &Path,
168    _value: u8,
169) -> fsqlite_error::Result<()> {
170    Ok(())
171}