Repository navigation
The Viewer's Job History reads each server's newest runs through an index (#4477) - #4493
Merged
Merged
Conversation
…-history index (#4469, #4477) The startup watermark read looks up each collector's newest collection_log row through a new index instead of scanning the newest chunks: idx_collection_log_watermark on collection_log (server_id, collector_name, collection_time DESC), plus a per-collector unnest()/LATERAL LIMIT 1 lookup replacing the GROUP BY. Also adds idx_job_history_server_run on job_history (server_id, run_datetime DESC, instance_id DESC) for the Viewer's Job History read. Refs #4469 Refs #4477
…rm, the top-rung pins (#4469) StorageVersion.SchemaVersion moves to 150. The Viewer schema probe gains a V150 sentinel (both idx_collection_log_watermark and idx_job_history_server_run present) and its newest-first arm above V149's, so a fully-migrated store maps to exactly 150 instead of falling through to V149 and showing a spurious upgrade banner. QueryStoreLivenessHotTouchLiveTests' 'I am the top rung' facts move to a new CollectionLogWatermarkAndJobHistoryIndexesRungTests class; V149's and V148's own facts are rewritten to assert what stays true forever (registered, ladder-dense, gated below the current top's arm) rather than 'is exactly the top'. Refs #4469, #4477
…ory-indexes' into fix/4477-job-history-per-server-topn
…rvers registry (#4477) Correctness fix on top of the per-server LATERAL: the driving set for the per-server top-N is now every server_id with a job_history row inside the window, not the servers registry. A server removed from the registry after its history was collected still surfaces (raw collected name, matching the old LEFT JOIN's COALESCE fallback). Adds live equivalence, plan-shape and mutation pins.
…equivalence pin The two rows meant to land on the same run_datetime_utc instant did not: their raw run_datetime values were only 6 minutes apart while their server offsets differ by 360 minutes, so they never actually tied, and their instance_id values were assigned in the wrong order for the instance_id DESC tie-break the assertion expects. Widened the raw gap to 360 minutes and swapped the instance_id values so the fixture produces the tie it claims to.
…-pass key-then-row read (#4477) job_stats now scans job_history once for the whole fleet, restricted to the (server_id, job_id) pairs base already kept via a semi-join, instead of a per-server LATERAL that re-scanned each server's whole success-row window. top_by_server now runs a key-only, index-only pass first (run_datetime, instance_id -- the two columns idx_job_history_server_run carries) to find the fleet-wide n-th cutoff, then a second pass that fetches full rows only at or past that cutoff. Same tie-break, same LIMIT, same result set.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #4477.
Why
The Viewer's Job History (
ViewerDataService.BuildJobHistorySql) shows the newest 2,000 job runs across the fleet (or one server) in the chosen window.job_historyrow collected in the window plus a day of clock-skew allowance, applies each server's UTC offset, sorts them all, and keeps 2,000.job_statsre-scans the same window for the long-running check.What changes
idx_job_history_server_run (server_id, run_datetime DESC, instance_id DESC)as a per-serverLATERAL … ORDER BY run_datetime DESC, instance_id DESC LIMIT n, then merge with today's exact order and tie-break (run_datetime_utc DESC, instance_id DESC).run_datetime − offset" per server is "newest byrun_datetime", and the merged top-n is the same set.serversregistry. A server whose registry entry was removed still shows its history under its collected name, as the oldLEFT JOIN serversdid.job_stats(the average successful duration and last success, for the long-running flag) is computed only for the (server, job) pairs in the result.Measurements
Measured on a local PostgreSQL 18 + TimescaleDB 2.30 store planted like a busy fleet: 43 servers × 72 hours, 2,015,496
job_historyrows, the two oldest daily chunks compressed, afterVACUUM ANALYZE. The parameters are the Viewer's defaults: the last 24 hours, all servers, the 2,000-row cap.EXPLAIN (ANALYZE, BUFFERS), run warm in both orders, and once after a container restart. The restart empties shared_buffers but not the OS page cache, so compare the "read" counts rather than the cold milliseconds.The per-server read touches more pages in total: each of the 43 servers' index descents fetches up to the row cap before the fleet-wide merge. Nearly all of those pages are already in memory. It reads about 5× fewer blocks from outside shared_buffers, and it's about 47% faster warm. The same measurement on a production-sized store is planned after the next install, as a confirmation.
Test plan
JobHistoryPerServerTopNLiveTests(live TimescaleDB rig):NewSql_MatchesOldSql_ExactlyAcrossOffsetsTiesAndTheCapBoundary: 5 servers (offsets +60 / −300 / 0 / noserver_propertiesrow / deregistered), 3 days of runs with retries and failures, a cross-server tie onrun_datetime_utc, a same-server tie onrun_datetime, and a cap that cuts the plant. It matchesdev's SQL row for row, fleet-wide and scoped, in both orders.DeregisteredServersRow_StillSurfaces_LikeTheOldLeftJoin: a server removed fromserversstill returns its rows under its collected name.ScopedRead_UsesTheIndex_WithNoExtraSort: the scoped read usesidx_job_history_server_runwith no sort onrun_datetime. The same assertion againstdev's SQL on the same rig FAILS (noLATERAL).instance_id DESCtie-break dropped from the fleet merge → the equivalence pin RED (a wrong server at row 19);JobHistoryGroupedStatsMatchWindowFunctionLiveTests,CollectionLogWatermarkAndJobHistoryIndexesRungTests,JobHistoryCapLabelTests,JobHistoryIdentityEpochTestsandDocCommentHygieneTests.Darling.Testsbuilds with 0 warnings.CHANGELOG
SECTION: Changed
ENTRY:
REF:
[The Viewer's Job History reads each server's newest runs through an index (#4477) #4493]: The Viewer's Job History reads each server's newest runs through an index (#4477) #4493