Files
qbit-db-performance/CHANGELOG.md
james.maesandClaude Opus 5.5 c49b479620 fix(alerts): page spike history instead of holding 7 days of query snapshots
SnapshotEvaluator.spikes loaded RuleContext.window("query_snapshot", 7)
as QRecords on every snapshot evaluation (every collection interval on
the worker). kof22 writes ~33,000 query snapshots a day, so by day 7 that
is ~230,000 records per evaluation.

history() now reads the window in BATCH_SIZE keyset pages (only OK and
PARTIAL snapshots, as before) and keeps per statement only the current
interval time, the latest capture time and earlier interval times in a
primitive double array. Median, twelve-sample baseline and the one-hour
absence rule are unchanged (SnapshotEvaluatorTest still passes).

SpikeHistoryBoundedTest counts every query snapshot QQQ materializes:
2,500 samples never exceed one 1,000-row page, failed snapshots and
samples outside the window are excluded, the current interval is found.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 15:24:44 -05:00

3.6 KiB

Changelog

All notable changes are documented here. This project follows Keep a Changelog and semantic versioning.

[Unreleased]

Fixed

  • Query-spike alerts no longer hold seven days of query snapshots as records on every snapshot evaluation (~230,000 rows at kof22's rate). SnapshotEvaluator reads the window in 1,000-row keyset pages and keeps only each statement's current interval time, latest capture time and earlier interval times as primitive doubles; the spike rule (twelve prior samples, median, absence after an hour) is unchanged.
  • The Attribution home panel no longer loads a day of attribution detail into the heap. It sums statements and time per unit and table in the database (at most 5,000 groups), so a render holds about a thousand aggregate rows instead of the roughly 570,000 detail rows (540 MB in PostgreSQL) that ran the kof22 web pod out of memory on 2026-10-16. The daily attribution rollup reads the day in 1,000-row keyset pages (DbPerfStore.forEachPage), so worker memory is bounded by distinct dimension keys, not by the day's row count. The hourly analysis (dbPerfAnalyze) reads attribution the same way: RuleContext.window("attribution", ...) returns database sums per unit, table and operation instead of every detail row (it filled the kof22 worker heap to ~1.8 GB every hour).
  • Collection no longer stops at RUNNING on large production statement sets: list folding in the SQL normalizer is a linear token scan (the nested-repetition regular expressions overflowed the stack on 60 KB statements with long IN/VALUES lists). Any failure, including an Error, now closes the run as FAILED with the exception class, logs it at ERROR (class and frame only, never SQL text) and raises the collection alert; runs left RUNNING by a crash are closed as FAILED after three intervals.
  • Only one runtime attributes per JVM: starting attribution on a newer instance (a hot swap, or repeated server starts in tests) stops the previous one, so old instances are never pinned by a forgotten listener and flusher.
  • Each table has its own icon (the app icon is now storage), so nav entries are distinguishable and do not repeat icons used elsewhere.
  • Home tables keep at most four columns with plain headers (readable at every width): secondary facts such as calls and mean time, the session's query text, and a unit's kind and top table move into a second line of the first cell.

Added

  • QQQ attribution and N+1 detection: a core statement execution listener (QQQ 4.1.0-RC.13) aggregates database time per route, scheduled job, process, table and statement shape in bounded memory, records repeated statement shapes per unit of work, and each pod flushes one batched insert per table every attribution_flush_seconds. Hosts without QQQ's application launcher call DbPerfRuntime.of(instance).startAttribution() after startup.

  • Secured database-performance tables, PostgreSQL statistics snapshots, daily rollups and configurable retention.

  • Audited PLAN/GENERIC and read-only ANALYZE query viewer with SQL validation, timeout, rollback and transient parameter handling.

  • Query plan statement action with readable plan text, cost, SQL Workbench link and a sanitized assistant prompt.

  • UI API extension 1.0.0 with overview, live activity, explain and statement lookup, plus its committed OpenAPI contract.

  • Eight full-width typed home panels with pagination, record links, guided empty states and permission-gated live activity.

  • Maven-versioned QBIT help bundle, complete metadata coverage checks, rule threshold guidance and adoption documentation.

  • PostgreSQL security acceptance tests and H2 API/widget fixtures.