diff --git a/core/storage/sqlite3_ondisk.rs b/core/storage/sqlite3_ondisk.rs index 228eb8b6c..f4206a963 100644 --- a/core/storage/sqlite3_ondisk.rs +++ b/core/storage/sqlite3_ondisk.rs @@ -1359,6 +1359,7 @@ pub fn read_entire_wal_dumb(file: &Arc) -> Result) -> Result) -> Result 0; if is_commit_record { wfs_data.max_frame.store(frame_idx, Ordering::SeqCst); - wfs_data.last_checksum = cumulative_checksum; } frame_idx += 1; current_offset += WAL_FRAME_HEADER_SIZE + page_size; } + wfs_data.last_checksum = cumulative_checksum; wfs_data.loaded.store(true, Ordering::SeqCst); }); let c = Completion::new(CompletionType::Read(ReadCompletion::new( @@ -1563,6 +1571,11 @@ pub fn begin_write_wal_frame( ); header.checksum_1 = final_checksum.0; header.checksum_2 = final_checksum.1; + tracing::trace!( + "begin_write_wal_frame(checksum=({}, {}))", + header.checksum_1, + header.checksum_2 + ); buf[16..20].copy_from_slice(&header.checksum_1.to_be_bytes()); buf[20..24].copy_from_slice(&header.checksum_2.to_be_bytes()); @@ -1599,6 +1612,7 @@ pub fn begin_write_wal_frame( } pub fn begin_write_wal_header(io: &Arc, header: &WalHeader) -> Result<()> { + tracing::trace!("begin_write_wal_header"); let buffer = { let drop_fn = Rc::new(|_buf| {}); diff --git a/core/storage/wal.rs b/core/storage/wal.rs index b6ec37190..1836022fc 100644 --- a/core/storage/wal.rs +++ b/core/storage/wal.rs @@ -977,6 +977,7 @@ impl WalFile { } let header = unsafe { shared.get().as_mut().unwrap().wal_header.lock() }; + let last_checksum = unsafe { (*shared.get()).last_checksum }; Self { io, // default to max frame in WAL, so that when we read schema we can read from WAL too if it's there. @@ -995,7 +996,7 @@ impl WalFile { sync_state: Cell::new(SyncState::NotSyncing), min_frame: 0, max_frame_read_lock_index: 0, - last_checksum: (0, 0), + last_checksum, start_pages_in_frames: 0, header: *header, } @@ -1083,6 +1084,7 @@ impl WalFileShared { let checksum = header.lock(); (checksum.checksum_1, checksum.checksum_2) }; + tracing::debug!("new_shared(header={:?})", header); let shared = WalFileShared { wal_header: header, min_frame: AtomicU64::new(0), diff --git a/tests/integration/query_processing/test_write_path.rs b/tests/integration/query_processing/test_write_path.rs index ee726caa3..6d7e831ad 100644 --- a/tests/integration/query_processing/test_write_path.rs +++ b/tests/integration/query_processing/test_write_path.rs @@ -734,6 +734,34 @@ fn test_wal_bad_frame() -> anyhow::Result<()> { Ok(()) } +#[test] +fn test_read_wal_dumb_no_frames() -> anyhow::Result<()> { + maybe_setup_tracing(); + let _ = env_logger::try_init(); + let db_path = { + let tmp_db = TempDatabase::new_empty(false); + let conn = tmp_db.connect_limbo(); + conn.close()?; + let db_path = tmp_db.path.clone(); + db_path + }; + // Second connection must recover from the WAL file. Last checksum should be filled correctly. + { + let tmp_db = TempDatabase::new_with_existent(&db_path, false); + let conn = tmp_db.connect_limbo(); + conn.execute("CREATE TABLE t0(x)")?; + conn.close()?; + } + { + let tmp_db = TempDatabase::new_with_existent(&db_path, false); + let conn = tmp_db.connect_limbo(); + conn.execute("INSERT INTO t0(x) VALUES (1)")?; + conn.close()?; + } + + Ok(()) +} + fn run_query(tmp_db: &TempDatabase, conn: &Arc, query: &str) -> anyhow::Result<()> { run_query_core(tmp_db, conn, query, None::) }