Skip to main content

Module pager_cache

Module pager_cache 

Source
Expand description

Process-wide SQLite page cache shared by every connection. Process-wide SQLite page cache, installed through SQLITE_CONFIG_PCACHE2.

SQLite’s default page cache gives every connection its own cache_size budget, so a process with many databases holds up to the sum of all of them while a busy database is capped at its own share. This cache replaces SQLite’s page cache for every connection in the process: one byte budget covers the pages of every purgeable cache, so a busy database takes pages from idle ones and the process total stays bounded.

The cache follows SQLite’s page cache contract:

  • A page returned by xFetch is pinned and stays at its address until xUnpin.
  • An unpinned page of a purgeable cache may be discarded at any time, because its pager keeps no reference to it (SQLite never unpins a dirty page). Discarding one from another connection’s cache is therefore safe.
  • A non-purgeable cache (an in-memory or temporary database, which temp_store = MEMORY makes of every temporary b-tree) keeps every page until xUnpin with discard, xTruncate or xDestroy, because those pages are the database itself. Its pages are counted apart and never charged to the budget, so one connection’s large sort or VACUUM cannot push every other connection’s pages out.
  • xFetch with createFlag 1 may refuse when the budget is full of pinned pages, which tells the pager to spill; with createFlag 2 it allocates past the budget rather than fail, and the overshoot is returned when pages are unpinned. Purgeable bytes can therefore exceed the budget by the pages SQLite still pins after a refusal it cannot spill around: pages held by open cursors, and dirty pages when no spill is possible.
  • A new page, including its extra area, starts zeroed, because SQLite’s pager reads its header from the extra area to tell a new page from a recycled one.

Every page access takes only the lock of the shard that owns its connection’s cache, so connections on different shards never wait for each other. Each shard keeps its own least recently used order; eviction walks the shards from a rotating cursor, which approximates one process-wide order without a global lock. Pages are allocated and freed outside every lock. Every call on one connection’s cache runs under that connection’s database mutex, or the shared b-tree’s mutex in shared-cache mode, so a miss can drop the shard lock while it allocates without racing another call on the same cache. A miss still checks the key again when it re-locks, so a page it finds there is returned instead of overwritten.

Structs§

PagerCache
Every page of every connection’s cache.

Functions§

attach_metrics
Reports the installed cache’s gauges through metrics, unless another pool already attached its metrics. The cache is process-wide, so whichever pool carries metrics reports it, regardless of which pool installed it.
install
Installs the process-wide page cache with capacity_bytes, once per process.
installed
The installed cache, if any, for tests and metrics.