Hive
perf(server): back flaky-alert default-branch validation with a marker MV
GitHub issue · Closed
Follow-up from the ClickHouse CPU investigation. Fixes the #1 CPU-consuming query (the flaky-alert default-branch validation gate). Independent of the OOM/memory fix (already shipped in #11623).
What
Adds test_case_runs_validated_on_branch — a ReplacingMergeTree fed by a new materialized view holding one marker row per (project_id, git_branch, test_case_id) that has ever had a successful, non-flaky run. The flaky-alert validation gate now reads that small table via a primary-key point lookup instead of scanning the raw test_case_runs table.
Why
During the ClickHouse CPU investigation, the top single query by CPU (last 10 min: 704 core-seconds) was:
SELECT DISTINCT test_case_id FROM test_case_runs
WHERE project_id = ? AND test_case_id IN (…≤2000…)
AND git_branch = <default> AND status = 'success' AND is_flaky = false
This is Tests.test_case_ids_with_successful_default_branch_run/3, called from AlertEvaluationWorker.reject_unvalidated_test_cases/2 to filter a flaky alert’s triggered test cases down to those proven on the default branch (so brand-new/PR-only tests aren’t auto-quarantined). It scanned raw test_case_runs for the whole triggered set on every evaluation.
Measured behavior on a busy project: it read millions of rows per evaluation and its per-call latency went from ~100 ms (idle cluster) to ~1.5 s under contention, making it a top contributor to the CPU-saturation feedback loop we saw (queries slowing 5–13×, concurrency 1.1→11.3).
How the fix works
- New MV
test_case_runs_validated_on_branch_mvpre-appliesstatus = 'success' AND is_flaky = falseand groups to distinct(project_id, git_branch, test_case_id), writing marker rows into theReplacingMergeTree. - The validation query drops the
status/is_flakyfilters and reads the marker table keyed on(project_id, git_branch, test_case_id)— a bounded point lookup per test case instead of a per-test-case run scan. - One-time partition-chunked backfill (throttled,
max_memory_usage-capped,TABLE_IS_READ_ONLY/MEMORY_LIMIT_EXCEEDEDretry), matching the existing per-case aggregate migrations.
Correctness
Semantics are identical: a marker exists iff a (project, branch, test case) had a successful, non-flaky run — exactly the predicate the old raw query used. The existing tests_test.exs test (validated / PR-only / failing-on-main / flaky-success-on-main) now exercises the MV path end-to-end and asserts only the truly-validated id is returned.
Trade-off / note
This adds one more MV firing on test_case_runs inserts. It’s lightweight (distinct-key marker, no array state) and insert-path CPU was already negligible in the investigation (~34 core-s vs 704 for the query it replaces), so this is a large net CPU win. A separate follow-up will trim the unused reliability success buckets (250/500/750) added in #11623 to cut merge write-amplification.
Validation
mix format+Code.string_to_quoted!on changed files.- Existing
tests_test.exstest_case_ids_with_successful_default_branch_run/3describe block covers all four cases; it runs against ClickHouse in CI with the new MV migrated in.
How to test locally
mix ecto.migrate(ingest repo) to create the MV + backfill.mix test test/tuist/tests_test.exs -o "test_case_ids_with_successful_default_branch_run"(or run the describe block) — inserts runs across branches/statuses and asserts only the default-branch success/non-flaky test case validates.
Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.
Start a Flight and preserve its objective, outcome, and session here.
No GitHub comments yet.