Skip to main content

Pager

Struct Pager 

Source
pub struct Pager {
    pub db_file: Arc<dyn DatabaseStorage>,
    pub buffer_pool: Arc<BufferPool>,
    pub io: Arc<dyn IO>,
    /* private fields */
}
Expand description

The pager interface implements the persistence layer by providing access to pages of the database file, including caching, concurrency control, and transaction management.

Fields§

§db_file: Arc<dyn DatabaseStorage>

Source of the database pages.

§buffer_pool: Arc<BufferPool>

Buffer pool for temporary data storage.

§io: Arc<dyn IO>

I/O interface for input/output operations.

Implementations§

Source§

impl Pager

Source

pub fn new( db_file: Arc<dyn DatabaseStorage>, wal: Option<Arc<dyn Wal>>, io: Arc<dyn IO>, page_cache: PageCache, buffer_pool: Arc<BufferPool>, init_lock: Arc<Mutex<()>>, init_page_1: Arc<ArcSwapOption<Page>>, ) -> Result<Self>

Source

pub fn get_sync_type(&self) -> FileSyncType

Get the sync type setting. On non-Apple platforms, always returns Fsync (compile-time constant).

Source

pub fn set_sync_type(&self, _value: FileSyncType)

Set the sync type. No-op on non-Apple platforms.

Source

pub fn init_page_1(&self) -> Arc<ArcSwapOption<Page>>

Source

pub fn set_spill_enabled(&self, enabled: bool)

Set whether cache spilling is enabled.

Source

pub fn get_spill_enabled(&self) -> bool

Get whether cache spilling is enabled.

Source

pub fn open_subjournal(&self) -> Result<()>

Open the subjournal if not yet open. The subjournal is a file that is used to store the “before images” of pages for the current savepoint. If the savepoint is rolled back, the pages can be restored from the subjournal.

Currently uses MemoryIO, but should eventually be backed by temporary on-disk files.

Source

pub fn subjournal_page_if_required(&self, page: &Page) -> Result<()>

Write page to subjournal if the current savepoint does not currently contain an an entry for it. In case of a statement-level rollback, the page image can be restored from the subjournal.

A buffer of length page_size + 4 bytes is allocated and the page id is written to the beginning of the buffer. The rest of the buffer is filled with the page contents.

Source

pub fn try_use_subjournal(&self) -> Result<()>

try to “acquire” ownership on the subjournal of the connection-scoped pager if another statement owns the subjournal - return Busy error and let the caller retry attempt later

Source

pub fn stop_use_subjournal(&self)

release ownership of the subjournal caller must guarantee that Self::stop_use_subjournal is called only after successful call to the Self::try_use_subjournal

Source

pub fn subjournal_in_use(&self) -> bool

check if subjournal is in use for some statement

Source

pub fn open_savepoint(&self, db_size: u32) -> Result<()>

Source

pub fn release_savepoint(&self) -> Result<()>

Release i.e. commit the current savepoint. This basically just means removing it.

Source

pub fn open_named_savepoint( &self, name: String, db_size: u32, starts_transaction: bool, deferred_fk_violations: isize, ) -> Result<()>

Opens a named savepoint and captures rollback metadata for the current transaction state.

If starts_transaction is true, releasing this savepoint at the root depth commits the transaction.

Source

pub fn release_named_savepoint(&self, name: &str) -> Result<SavepointResult>

Releases the newest matching named savepoint and all nested savepoints opened after it.

Source

pub fn clear_savepoints(&self) -> Result<()>

Source

pub fn rollback_to_newest_savepoint(&self) -> Result<bool>

Rollback to the newest savepoint. This basically just means reading the subjournal from the start offset of the savepoint to the end of the subjournal and restoring the page images to the page cache.

Source

pub fn rollback_to_named_savepoint(&self, name: &str) -> Result<Option<isize>>

Rollback to the newest matching named savepoint while keeping the named savepoint active.

Returns deferred FK counter snapshot for the rolled-back savepoint.

Source

pub const fn get_pending_byte() -> u32

Source

pub fn pending_byte_page_id(&self) -> Option<u32>

From SQLITE: https://github.com/sqlite/sqlite/blob/7e38287da43ea3b661da3d8c1f431aa907d648c9/src/btreeInt.h#L608
The database page the [PENDING_BYTE] occupies. This page is never used.

Source

pub fn get_max_page_count(&self) -> u32

Get the maximum page count for this database

Source

pub fn set_max_page_count(&self, new_max: u32) -> Result<IOResult<u32>>

Set the maximum page count for this database Returns the new maximum page count (may be clamped to current database size)

Source

pub fn set_wal(&mut self, wal: Arc<dyn Wal>)

Source

pub fn get_auto_vacuum_mode(&self) -> AutoVacuumMode

Source

pub fn set_auto_vacuum_mode(&self, mode: AutoVacuumMode)

Source

pub fn persist_auto_vacuum_mode(&self, mode: AutoVacuumMode) -> Result<()>

Persist the auto-vacuum mode to page 1 and keep the pager cache in sync.

Source

pub fn ptrmap_get( &self, target_page_num: u32, ) -> Result<IOResult<Option<PtrmapEntry>>>

Retrieves the pointer map entry for a given database page. target_page_num (1-indexed) is the page whose entry is sought. Returns Ok(None) if the page is not supposed to have a ptrmap entry (e.g. header, or a ptrmap page itself).

Source

pub fn ptrmap_put( &self, db_page_no_to_update: u32, entry_type: PtrmapType, parent_page_no: u32, ) -> Result<IOResult<()>>

Writes or updates the pointer map entry for a given database page. db_page_no_to_update (1-indexed) is the page whose entry is to be set. entry_type and parent_page_no define the new entry.

Source

pub fn btree_create(&self, flags: &CreateBTreeFlags) -> Result<IOResult<u32>>

This method is used to allocate a new root page for a btree, both for tables and indexes FIXME: handle no room in page cache

Source

pub fn allocate_overflow_page(&self) -> Result<IOResult<PageRef>>

Allocate a new overflow page. This is done when a cell overflows and new space is needed.

Source

pub fn do_allocate_page( &self, page_type: PageType, offset: usize, _alloc_mode: BtreePageAllocMode, ) -> Result<IOResult<PageRef>>

Allocate a new page to the btree via the pager. This marks the page as dirty and writes the page header.

Source

pub fn usable_space(&self) -> usize

The “usable size” of a database page is the page size specified by the 2-byte integer at offset 16 in the header, minus the “reserved” space size recorded in the 1-byte integer at offset 20 in the header. The usable size of a page might be an odd number. However, the usable size is not allowed to be less than 480. In other words, if the page size is 512, then the reserved space size cannot exceed 32.

Source

pub fn db_initialized(&self) -> bool

Source

pub fn set_initial_page_size(&self, size: PageSize) -> Result<()>

Set the initial page size for the database. Should only be called before the database is initialized

Source

pub fn set_initial_journal_version(&self, version: Version) -> Result<()>

Set the initial journal version in page 1 before the database is initialized.

Source

pub fn get_page_size(&self) -> Option<PageSize>

Get the current page size. Returns None if not set yet.

Source

pub fn get_page_size_unchecked(&self) -> PageSize

Get the current page size, panicking if not set.

Source

pub fn set_page_size(&self, size: PageSize)

Set the page size. Used internally when page size is determined.

Source

pub fn get_reserved_space(&self) -> Option<u8>

Get the current reserved space. Returns None if not set yet.

Source

pub fn set_reserved_space(&self, space: u8)

Set the reserved space. Must fit in u8.

Get the cached schema cookie. Returns None if not set yet.

Set the schema cookie cache.

Get the schema cookie, using the cached value if available to avoid reading page 1.

Source

pub fn wal_pos(&self) -> (u32, u64)

This connection’s frozen WAL position (checkpoint_seq, max_frame) — the read mark for a reader, or the post-commit position for a writer. (u32::MAX, u64::MAX) when there is no WAL (no WAL materialization hazard). See Wal::connection_wal_pos.

Source

pub fn min_pinned_read_frame(&self) -> Option<u64>

Lowest WAL frame any active reader is pinned at, or None if none / no WAL. Used as the Passive-checkpoint version-store GC floor (includes readers pinned via begin_read_tx before they publish an MVCC transaction). See MvStore::rootpage_gc_protected.

Source

pub fn wal_backfill_frame(&self) -> Option<u64>

The WAL backfill boundary (frames at or below this are durable in the DB file). The MVCC Version-store GC floor for passive checkpoints: a materialized version may be reclaimed only once its materialization frame is backfilled here, so every snapshot can read it from the btree.

Source

pub fn begin_read_tx(&self) -> Result<()>

Source

pub fn mvcc_refresh_if_db_changed(&self)

MVCC-only: refresh connection-private WAL change counters without starting a read tx and invalidate cache if needed.

Source

pub fn maybe_allocate_page1(&self) -> Result<IOResult<()>>

Source

pub fn begin_write_tx( &self, allowed_auto_actions: WalAutoActions, ) -> Result<IOResult<()>>

allowed_auto_actions controls which automatic WAL maintenance the caller permits during this begin. The only action consulted here is WalAutoActions::Restart, which gates the WAL-header restart inside try_restart_log_before_write. Callers managing WAL state externally (sync engine) must not pass Restart because rotating the WAL header behind their back invalidates watermarks they have already published.

Source

pub fn begin_vacuum_blocking_tx(&self) -> Result<IOResult<()>>

Acquire exclusive WAL access + block new transactions (used by VACUUM).

This is a blocking alternative to normal begin_read_tx.

VACUUM runs on an existing database, so page 1 must already be allocated and a WAL must be present.

Source

pub fn commit_tx( &self, connection: &Connection, update_transaction_state: bool, ) -> Result<IOResult<()>>

commit dirty pages from current transaction in WAL mode if this is not nested statement (for nested statements, parent will do the commit) if update_transaction_state set to false, then Connection::transaction_state left unchanged if update_transaction_state set to true, then Connection::transaction_state reset to [TransactionState::None] in case when method completes without error

Source

pub fn rollback_tx(&self, connection: &Connection)

Source

pub fn end_read_tx(&self)

Source

pub fn end_write_tx(&self)

End just the write transaction on the WAL, without affecting the read lock.

Source

pub fn holds_read_lock(&self) -> bool

Returns true if this pager’s WAL currently holds a read lock.

Source

pub fn holds_write_lock(&self) -> bool

Source

pub fn rollback_attached(&self)

Rollback and clean up an attached database pager’s transaction. Unlike rollback_tx, this doesn’t modify connection-level state.

Source

pub fn read_page_no_cache( &self, page_idx: i64, frame_watermark: Option<u64>, allow_empty_read: bool, ) -> Result<(PageRef, Completion)>

Reads a page from disk (either WAL or DB file) bypassing page-cache

Source

pub fn read_page( &self, page_idx: i64, ) -> Result<IOResult<(PageRef, Option<Completion>)>>

Issue a non-blocking page read, inserting into the page cache, may spill to disk.

  • Done((page, None)): page was already in cache, no IO needed.
  • Done((page, Some(c_disk))): page was not in cache; it has been inserted into the cache and a disk-read is in flight against it. The caller must yield on c_disk before reading page contents.
  • IO(c_spill): the page cache was full and a spill is in flight. Caller must yield on c_spill and then call read_page_nonblock(idx) again. The disk read for this page has already been issued and will be reused on re-entry via pending_reads (no duplicate IO).

Re-entrancy contract: the caller may invoke this with the same page_idx arbitrarily many times. Each Some(page_idx) mapping in pending_reads corresponds to a single outstanding disk read; the entry is removed exactly when this method returns Done.

Source

pub fn cache_get(&self, page_idx: usize) -> Result<Option<PageRef>>

Source

pub fn cache_get_for_checkpoint( &self, page_idx: usize, target_frame: u64, seq: u32, ) -> Result<Option<PageRef>>

Get a page from cache only if it matches the target frame

Source

pub fn change_page_cache_size( &self, capacity: usize, ) -> Result<CacheResizeResult>

Changes the size of the page cache.

Source

pub fn add_dirty(&self, page: &Page) -> Result<()>

Source

pub fn wal_state(&self) -> Result<WalState>

Source

pub fn cacheflush(&self) -> Result<IOResult<Vec<Completion>>>

Flush all dirty pages to disk (async/re-entrant). Unlike commit_wal, this function does not commit, checkpoint nor sync the WAL/Database.

Source

pub fn commit_wal( &self, allowed_auto_actions: WalAutoActions, sync_mode: SyncMode, data_sync_retry: bool, ) -> Result<IOResult<()>>

Commit the write transaction to the WAL: write any dirty pages as WAL frames, fsync the WAL if it is dirty, and publish the commit. The WAL can be dirty without any dirty pages (frames inserted through write_frame_raw bypass dirty-page tracking), so under synchronous=FULL this fsyncs even when there is nothing to write. If the WAL size is over the checkpoint threshold, it will checkpoint the WAL to the database file and then fsync the database file.

allowed_auto_actions controls automatic WAL maintenance permitted at commit time. Only WalAutoActions::Checkpoint is consulted here — it gates the post-commit auto-checkpoint when should_checkpoint() is true.

Source

pub fn commit_wal_end(&self)

Source

pub fn wal_changed_pages_after(&self, frame_watermark: u64) -> Result<Vec<u32>>

Source

pub fn wal_get_frame( &self, frame_no: u64, frame: &mut [u8], ) -> Result<Completion>

Source

pub fn wal_insert_frame( &self, frame_no: u64, frame: &[u8], ) -> Result<WalFrameInfo>

Source

pub fn is_checkpointing(&self) -> bool

Source

pub fn clear_checkpoint_state(&self)

Reset checkpoint state machine to initial state. Use this to clean up after a failed explicit checkpoint (PRAGMA wal_checkpoint).

Source

pub fn cleanup_after_auto_checkpoint_failure(&self)

Clean up after a auto-checkpoint failure. Auto-checkpoint executed outside of the main transaction - so WAL transaction was already finalized

Source

pub fn cleanup_after_checkpoint_failure(&self)

Source

pub fn checkpoint( &self, mode: CheckpointMode, sync_mode: SyncMode, clear_page_cache: bool, ) -> Result<IOResult<CheckpointResult>>

Checkpoint the WAL to the database file (if needed). Args:

  • mode: The checkpoint mode to use (PASSIVE, FULL, RESTART, TRUNCATE)
  • sync_mode: The fsync mode to use (OFF, NORMAL, FULL)
  • clear_page_cache: Whether to clear the page cache after checkpointing
Source

pub fn vacuum_checkpoint_with_held_lock( &self, sync_mode: SyncMode, clear_page_cache: bool, ) -> Result<IOResult<CheckpointResult>>

Source

pub fn clear_page_cache(&self, clear_dirty: bool)

Invalidates entire page cache by removing all dirty and clean pages. Usually used in case of a rollback or in case we want to invalidate page cache after starting a read transaction right after new writes happened which would invalidate current page cache.

Source

pub fn checkpoint_shutdown( &self, allowed_auto_actions: WalAutoActions, sync_mode: SyncMode, ) -> Result<()>

Checkpoint in Truncate mode and delete the WAL file. This method is only to be called for shutting down the last remaining connection to a database.

sqlite3.h Usually, when a database in [WAL mode] is closed or detached from a database handle, SQLite checks if if there are other connections to the same database, and if there are no other database connection (if the connection being closed is the last open connection to the database), then SQLite performs a [checkpoint] before closing the connection and deletes the WAL file.

Source

pub fn blocking_checkpoint( &self, mode: CheckpointMode, sync_mode: SyncMode, ) -> Result<CheckpointResult>

Perform a blocking checkpoint with the specified mode. This is a convenience wrapper around checkpoint() that blocks until completion. Explicit checkpoints clear the page cache after completion.

Source

pub fn freepage_list(&self) -> u32

Source

pub fn free_page( &self, page: Option<PageRef>, page_id: usize, ) -> Result<IOResult<()>>

Source

pub fn allocate_page1(&self) -> Result<IOResult<PageRef>>

Source

pub fn allocating_page1(&self) -> bool

Source

pub fn allocate_page(&self) -> Result<IOResult<PageRef>>

Tries to reuse a page from the freelist if available. If not, allocates a new page which increases the database size.

FIXME: implement sqlite’s ‘nearby’ parameter and use AllocMode. SQLite’s allocate_page() equivalent has a parameter ‘nearby’ which is a hint about the page number we want to have for the allocated page. We should use this parameter to allocate the page in the same way as SQLite does; instead now we just either take the first available freelist page or allocate a new page.

Source

pub fn upsert_page_in_cache( &self, id: usize, page: PageRef, dirty_page_must_exist: bool, ) -> Result<(), LimboError>

Source

pub fn rollback( &self, schema_did_change: bool, connection: &Connection, is_write: bool, )

Source

pub fn with_header<T>( &self, f: impl Fn(&DatabaseHeader) -> T, ) -> Result<IOResult<T>>

Source

pub fn with_header_mut<T>( &self, f: impl Fn(&mut DatabaseHeader) -> T, ) -> Result<IOResult<T>>

Source

pub fn is_encryption_ctx_set(&self) -> bool

Source

pub fn is_encryption_enabled(&self) -> bool

Source

pub fn set_encryption_context( &self, cipher_mode: CipherMode, key: &EncryptionKey, ) -> Result<()>

Source

pub fn reset_checksum_context(&self)

Source

pub fn set_reserved_space_bytes(&self, value: u8)

Source

pub fn enable_encryption(&self, enable: bool)

Encryption is an opt-in feature. If the flag is passed, then enable the encryption on pager, which is then used to set it on the IOContext.

Auto Trait Implementations§

§

impl !Freeze for Pager

§

impl !RefUnwindSafe for Pager

§

impl !UnwindSafe for Pager

§

impl Send for Pager

§

impl Sync for Pager

§

impl Unpin for Pager

§

impl UnsafeUnpin for Pager

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more