From eae68f366908a852cd662bb8e6073c3cf5600d2b Mon Sep 17 00:00:00 2001 From: PThorpe92 Date: Sat, 16 Aug 2025 11:25:04 -0400 Subject: [PATCH 1/2] Update stale in memory wal header after restarting log --- core/storage/wal.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/storage/wal.rs b/core/storage/wal.rs index 624a1156e..26c66cb76 100644 --- a/core/storage/wal.rs +++ b/core/storage/wal.rs @@ -1698,7 +1698,12 @@ impl WalFile { } } - self.last_checksum = self.get_shared().last_checksum; + let (header, cksm) = { + let shared = self.get_shared(); + (*shared.wal_header.lock(), shared.last_checksum) + }; + self.last_checksum = cksm; + self.header = header; self.max_frame = 0; self.min_frame = 0; Ok(()) From 605b3e233f88191b63bd448733f6444929ce2572 Mon Sep 17 00:00:00 2001 From: PThorpe92 Date: Sat, 16 Aug 2025 17:42:22 -0400 Subject: [PATCH 2/2] Move in memory reset logic to before truncation in wal restart --- core/storage/wal.rs | 77 +++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/core/storage/wal.rs b/core/storage/wal.rs index 26c66cb76..2d480f0d6 100644 --- a/core/storage/wal.rs +++ b/core/storage/wal.rs @@ -1650,54 +1650,25 @@ impl WalFile { } } - let handle_err = |e: &LimboError| { + let unlock = |e: Option<&LimboError>| { // release all read locks we just acquired, the caller will take care of the others - let shared = self.get_shared(); + let shared = unsafe { self.shared.get().as_mut().unwrap() }; for idx in 1..shared.read_locks.len() { shared.read_locks[idx].unlock(); } - tracing::error!( - "Failed to restart WAL header: {:?}, releasing read locks", - e - ); + if let Some(e) = e { + tracing::error!( + "Failed to restart WAL header: {:?}, releasing read locks", + e + ); + } }; // reinitialize in‑memory state self.get_shared() .restart_wal_header(&self.io, mode) .inspect_err(|e| { - handle_err(e); + unlock(Some(e)); })?; - - // For TRUNCATE mode: shrink the WAL file to 0 B - if matches!(mode, CheckpointMode::Truncate) { - let c = Completion::new_trunc(|_| { - tracing::trace!("WAL file truncated to 0 B"); - }); - let shared = self.get_shared(); - // for now at least, lets do all this IO syncronously - let c = shared.file.truncate(0, c).inspect_err(handle_err)?; - self.io.wait_for_completion(c).inspect_err(handle_err)?; - // fsync after truncation - self.io - .wait_for_completion( - shared - .file - .sync(Completion::new_sync(|_| { - tracing::trace!("WAL file synced after reset/truncation"); - })) - .inspect_err(handle_err)?, - ) - .inspect_err(handle_err)?; - } - - // release read‑locks 1..4 - { - let shared = self.get_shared(); - for idx in 1..shared.read_locks.len() { - shared.read_locks[idx].unlock(); - } - } - let (header, cksm) = { let shared = self.get_shared(); (*shared.wal_header.lock(), shared.last_checksum) @@ -1706,6 +1677,36 @@ impl WalFile { self.header = header; self.max_frame = 0; self.min_frame = 0; + + // For TRUNCATE mode: shrink the WAL file to 0 B + if matches!(mode, CheckpointMode::Truncate) { + let c = Completion::new_trunc(|_| { + tracing::trace!("WAL file truncated to 0 B"); + }); + let shared = self.get_shared(); + // for now at least, lets do all this IO syncronously + let c = shared + .file + .truncate(0, c) + .inspect_err(|e| unlock(Some(e)))?; + self.io + .wait_for_completion(c) + .inspect_err(|e| unlock(Some(e)))?; + // fsync after truncation + self.io + .wait_for_completion( + shared + .file + .sync(Completion::new_sync(|_| { + tracing::trace!("WAL file synced after reset/truncation"); + })) + .inspect_err(|e| unlock(Some(e)))?, + ) + .inspect_err(|e| unlock(Some(e)))?; + } + + // release read‑locks 1..4 + unlock(None); Ok(()) }