Repository navigation
Count pump records in a flat rmgr by route array - #263
Conversation
|
Compared 16-rmgr chunks with flat counters from this PR. Chunking saves memory when observed rmgr IDs cluster, with a small recurring update cost. Prototype: Archived workload: 4,096 prepared records cycling rmgr IDs
Against inline array, chunking saves 5,632 bytes (91.5%), costs 15.6% per increment (+0.13 ns), and enumerates 17.1× faster. Despite faster checksum enumeration, metric-map construction remains roughly unchanged in this harness. Two populated chunks would use 904 bytes. Additional distributions, same prepared-record count and observation count:
Storage includes Method: extracted counter implementations from base Control caveat: archived original binaries rerun at their original 10,240,000 observations give BTreeMap 6.84 [6.64, 7.12] and PR array 0.75 [0.69, 0.79] ns/record, consistent with existing PR measurements. Standalone BTreeMap timing differs materially, so treat absolute timings as harness-specific and do not use its ratios to revise published PR speedup. Flat/chunk comparisons above use identical harness. No end-to-end replication claim. Choose chunking for lower per-session storage, especially with one or two populated chunks. Choose inline array for lowest update cost and no counter allocations. |
|
Follow-up using actual WAL rather than synthetic rmgr selection: ordinary OLTP stayed in one 16-ID chunk; second chunk depended on features producing IDs 16–21. No evidence here supports assuming two chunks for ordinary workloads. Inspected retained WAL on running PostgreSQL 17.11, then generated workloads in an isolated database with
Existing schema survey across 28 databases found 12,933 Btree indexes, 617 GIN, 15 GiST, and one BRIN; no SPGiST or bloom indexes. Existing BRIN table had zero recorded inserts/updates/deletes, consistent with its absence from retained WAL sample. This development cluster is not a production prevalence sample. Intervals above are counted independently. One sink observing full experiment would retain second chunk from BRIN creation onward. One high-ID record suffices to allocate second chunk for remaining sink lifetime. Physical WAL spans all databases, so BRIN/SPGiST or another high-ID producer in any database matters. For reference, existing fixtures also split: Implication for chunk size: 16 IDs uses 520 bytes for ordinary low-ID traffic; 32 IDs uses 840 bytes. When any built-in ID 16–21 appears, 16 IDs uses 904 bytes versus 840 for 32 IDs. All sizes include Experiment database and its extensions were removed after recording results. Existing application tables and server settings were unchanged. |
c96afaa to
a7f6b51
Compare
MetricsRecordSink bumped a BTreeMap entry for every WAL record on the pump thread, 2.7% of its cycles on the lifecycle benchmark. Rmgr ids fit in a byte and routes in three slots, so a 6 KiB array indexes the counter directly; readers iterate the nonzero cells in the same order the map gave. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
a7f6b51 to
6e4955e
Compare
Pump metrics update a BTreeMap for every WAL record. Index counters by rmgr and route in a fixed array, preserving snapshot order and existing metric values.
Extracted from original #228 and based directly on
main. Contains no changes from #226 or other extracted PRs.Validation:
cargo fmt --all -- --check,cargo clippy --workspace --all-targets --locked -- -D warnings, andcargo test --locked --lib source::wal_stream(29 passed). Rebuild crate for each isolated diff.Measured impact (2026-10-22)
Compared
c96afaaa5298862d99193fe8c97c3d7d51bf03a1against shared parent151fd47cbd75ec7b9bc63ffe7040f049e702ecd0, with each PR built separately.Workload: 10,240,000 calls to production
MetricsRecordSink::observe, cycling 4,096 prepared records across eight rmgr IDs and three routes. Check exact total; consume summary after timing. Measures counter updates only; array initialization and snapshot enumeration remain outside timing. No end-to-end replication speedup established.AMD Ryzen 7 7840U; rustc 1.99.1; locked dependencies; optimized release builds; mimalloc 0.1.52. Seven trials per revision, alternating base/PR order, pinned to CPUs 2,4,6 (three physical cores). Values show median [min, max]; negative time changes mean less work or waiting. Local component measurements, without PostgreSQL or ClickHouse services.