Dont allocate fresh page1 if it's in the WAL

This commit is contained in:
Jussi Saurio
2025-06-17 13:53:54 +03:00
committed by Diego Reis
parent dc13d88900
commit acafe71d9e
4 changed files with 17 additions and 20 deletions

View File

@@ -202,12 +202,14 @@ impl Database {
shared_wal,
buffer_pool.clone(),
)));
let is_empty = false;
let pager = Rc::new(Pager::new(
self.db_file.clone(),
wal,
self.io.clone(),
Arc::new(RwLock::new(DumbLruPageCache::default())),
buffer_pool,
is_empty,
)?);
let header = pager.db_header()?;
@@ -230,12 +232,14 @@ impl Database {
})
} else {
let dummy_wal = Rc::new(RefCell::new(DummyWAL {}));
let is_empty = true;
let mut pager = Pager::new(
self.db_file.clone(),
dummy_wal,
self.io.clone(),
Arc::new(RwLock::new(DumbLruPageCache::default())),
buffer_pool.clone(),
is_empty,
)?;
let header = pager.db_header()?;
let wal_path = format!("{}-wal", self.path);

View File

@@ -6868,7 +6868,7 @@ mod tests {
let wal = Rc::new(RefCell::new(wal_file));
let page_cache = Arc::new(parking_lot::RwLock::new(DumbLruPageCache::new(2000)));
let pager = { Pager::new(db_file, wal, io, page_cache, buffer_pool).unwrap() };
let pager = { Pager::new(db_file, wal, io, page_cache, buffer_pool, true).unwrap() };
let pager = Rc::new(pager);
// FIXME: handle page cache is full
pager.allocate_page1().unwrap();
@@ -7390,6 +7390,7 @@ mod tests {
io,
Arc::new(parking_lot::RwLock::new(DumbLruPageCache::new(10))),
buffer_pool,
true,
)
.unwrap(),
);

View File

@@ -14,7 +14,7 @@ use parking_lot::RwLock;
use std::cell::{RefCell, UnsafeCell};
use std::collections::HashSet;
use std::rc::Rc;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Arc;
use tracing::{trace, Level};
@@ -214,8 +214,8 @@ pub struct Pager {
checkpoint_inflight: Rc<RefCell<usize>>,
syncing: Rc<RefCell<bool>>,
auto_vacuum_mode: RefCell<AutoVacuumMode>,
/// Number of pages in the database file.
pub npages: AtomicUsize,
/// Is the db empty? This is signified by 0-sized database and nonexistent WAL.
pub is_empty: AtomicBool,
}
#[derive(Debug, Copy, Clone)]
@@ -249,17 +249,8 @@ impl Pager {
io: Arc<dyn crate::io::IO>,
page_cache: Arc<RwLock<DumbLruPageCache>>,
buffer_pool: Rc<BufferPool>,
is_empty: bool,
) -> Result<Self> {
let npages = if db_file.size().unwrap() > 0 {
let db_header = Pager::begin_open(db_file.clone()).unwrap();
// ensure db header is there
io.run_once().unwrap();
let size = db_header.lock().database_size;
size as usize
} else {
0
};
Ok(Self {
db_file,
wal,
@@ -275,7 +266,7 @@ impl Pager {
checkpoint_inflight: Rc::new(RefCell::new(0)),
buffer_pool,
auto_vacuum_mode: RefCell::new(AutoVacuumMode::None),
npages: AtomicUsize::new(npages),
is_empty: AtomicBool::new(is_empty),
})
}
@@ -284,7 +275,7 @@ impl Pager {
}
pub fn db_header(&self) -> Result<DatabaseHeader> {
if self.npages.load(Ordering::SeqCst) == 0 {
if self.is_empty.load(Ordering::SeqCst) {
return Ok(DatabaseHeader::default());
}
@@ -1007,7 +998,7 @@ impl Pager {
pub fn allocate_page1(&self) -> Result<PageRef> {
let default_header = DatabaseHeader::default();
self.npages.fetch_add(1, Ordering::SeqCst);
self.is_empty.store(false, Ordering::SeqCst);
let page = allocate_page(1, &self.buffer_pool, 0);
let page1 = Arc::new(BTreePageInner {
@@ -1046,7 +1037,7 @@ impl Pager {
pub fn allocate_page(&self) -> Result<PageRef> {
let mut header = self.db_header()?;
header.database_size += 1;
self.npages.fetch_add(1, Ordering::SeqCst);
self.is_empty.store(false, Ordering::SeqCst);
tracing::debug!("allocate_page(database_size={})", header.database_size);
@@ -1426,7 +1417,7 @@ mod ptrmap_tests {
buffer_pool.clone(),
)));
let pager = Pager::new(db_file, wal, io, page_cache, buffer_pool).unwrap();
let pager = Pager::new(db_file, wal, io, page_cache, buffer_pool, true).unwrap();
pager.set_auto_vacuum_mode(AutoVacuumMode::Full);
// Allocate all the pages as btree root pages

View File

@@ -1685,7 +1685,7 @@ pub fn op_transaction(
}
// We allocate the first page lazily in the *first* write transaction
if conn.pager.npages.load(Ordering::SeqCst) == 0 {
if conn.pager.is_empty.load(Ordering::SeqCst) {
conn.pager.allocate_page1()?;
}
}
@@ -5221,6 +5221,7 @@ pub fn op_open_ephemeral(
io,
page_cache,
buffer_pool.clone(),
true,
)?);
let header = pager.db_header()?;