pg_stat_log v0.2
Performance-focused release of pg_stat_log. The entry storage was rewritten as an index-based chaining hash table, making the logging hot path O(1) expected even when the table is completely full.
Highlights
- O(1) lookups at any load factor. The entries array was previously an open-addressing hash table sized exactly to
max_entries, so it could reach 100% load. Once full, a message with an untracked signature found no empty slot to terminate the probe and scanned allmax_entriesslots before being dropped — an O(N) walk under the exclusive LWLock, exactly during the diverse log storms the extension is meant to observe. Entries are now stored in a separate-chaining hash table linked by array indices, so lookups, inserts, and drops walk a single bucket chain whose average length is the load factor — O(1) expected even at saturation.
Changes
- Replace the per-slot
usedflag with anint32 nextchain link (slot size unchanged) and append a bucket-heads array after the entries in the same flat stats block. - Chain links are array indices, not pointers, so the block remains snapshot-safe (
memcpy) and persistence-safe (verbatimfwrite/fread), as required by the fixed-amount Custom Cumulative Stats API. - Memory cost: one
int32per entry for the bucket-heads array (~1.15x the raw entry data; still a hard cap fixed at startup). - Behavior is unchanged: already-tracked signatures keep counting after saturation, and only genuinely new signatures are dropped (counted in
n_dropped).
Documentation
- New README section "Design notes: why a custom hash table" explaining why PostgreSQL's standard hash tables (dynahash, simplehash, dshash) cannot be used under the fixed-amount custom stats constraints, with a matching summary in the
PgStatLogstruct comment.
Tests
- New TAP check verifying that an already-tracked signature continues to increment when the table is full.
Upgrade notes
- No SQL-level changes — the extension script is unchanged, so no
ALTER EXTENSION ... UPDATEis needed. Install the new shared library and restart the server. - The shared stats block layout changed, so counters persisted by 0.1 are discarded on the first startup with 0.2 (statistics start fresh, as after a crash recovery).
Requirements
- PostgreSQL 18 or later
- Must be loaded via
shared_preload_libraries