We were unable to construct the commit group for this pull request: None of the pull request's commits have been successfully processed as yet.

Trim `test_max_bytes_ratio_before_external_distinct` to fit the client timeout #121096

Open
groeneai opened 10:04pm on September 19, 2026 wants to merge 0 commits into clickhouse/clickhouse master from
trim-external-distinct-ratio-test

Pull Request Overview

  • Opened on September 19, 2026
  • Status Open
  • Commit count 0

Total Delta

0 Total Diff Delta

Open Days

Open 0 weekdays

Test Delta

0 Diff Delta in Test Files
Breakdown by Phase

How long has this pull request spent in each phase of its lifecycle?

Data pending calculation for pull request

Author avatar

Trim `test_max_bytes_ratio_before_external_distinct` to fit the client timeout

Related: https://github.com/ClickHouse/ClickHouse/pull/116569
Related: https://github.com/ClickHouse/ClickHouse/pull/104965

Changelog category (leave one):


  • CI Fix or Improvement (changelog entry is not required)

Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):

Sized test_max_bytes_ratio_before_external_distinct to fit the integration harness's 600 second per-query timeout.

Description

test_max_bytes_ratio_before_external_distinct[server] and [user] time out at the harness's hard 600 second per-query cap on Integration tests (amd_asan_ubsan, db disk, 1/8): over 30 days it ran [server] 1031 times at a median of 572s, 260 of them at or above 595s, while sort and group_by in the same file have 0 runs over 540s. The cap is DEFAULT_QUERY_TIMEOUT in helpers/client.py, applied unconditionally, so the test cannot raise it; the timeout= kwarg only arms an additional, earlier timer.

Not a release-build regression: on arm_binary this test takes 36s against 41s for its sort sibling; the 15.6x sanitizer factor comes from a single-threaded comparison-based spill path, on builds that are not shipped. long_run, the other remedy, would delete the coverage (pytest.ini carries addopts = -m 'not long_run and not e2e' and no job selects the marker). The merged sibling test_external_distinct_disk_limits covers this feature at 16k to 262k rows.

The test asserts a memory-limit behaviour by consuming memory up to the node's limit, so its runtime has a floor set by that limit, and shrinking the workload alone would break the oracle: the unspilled peak must still exceed the limit for the ratio=0 half to be rejected. So limit and workload come down together, on a dedicated instance pair, leaving group_by and sort on their untouched 10Gi configs: 7M keys of exactly 800 bytes against 4Gi, sized for RSS headroom rather than minimality.

Each param asserts which tracker rejected it, (total) or User at maximum: 4.00 GiB; both pass on address,undefined and non-sanitizer builds, and swapping the expected texts reddens both. The spilling half asserts that it spilled, so the trim strengthens that arm. The spilling query drops from 411s to 42s and the file from about 1850s to 1031s; the two added idle instances cost 1.5s of startup.

Report: https://s3.amazonaws.com/clickhouse-test-reports/praktika.html?PR=104965&sha=81348dcffea1f5d0c73f4894d63a28a718bcbdfa&name_0=PR&name_1=Integration%20tests%20(amd_asan_ubsan%2C%20db%20disk%2C%201%2F8)

30 days of per-param timings on the failing job, and the query

```sql
SELECT
splitByString('::', test_name)[2] AS param,
count() AS runs,
round(quantile(0.5)(test_duration_ms)/1000) AS p50_s,
round(quantile(0.9)(test_duration_ms)/1000) AS p90_s,
round(max(test_duration_ms)/1000) AS max_s,
countIf(test_duration_ms > 540000) AS over_540s,
countIf(test_duration_ms >= 595000) AS over_595s,
countIf(test_status IN ('FAIL', 'ERROR')) AS failures
FROM checks
WHERE check_start_time > now() - INTERVAL 30 DAY
AND check_name = 'Integration tests (amd_asan_ubsan, db disk, 1/8)'
AND test_name LIKE 'test_max_bytes_ratio_before_external_order_group_by_for_server/test.py::%'
GROUP BY param
ORDER BY p50_s DESC
```

```
โ”Œโ”€paramโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€runsโ”€โ”ฌโ”€p50_sโ”€โ”ฌโ”€p90_sโ”€โ”ฌโ”€max_sโ”€โ”ฌโ”€over_540sโ”€โ”ฌโ”€over_595sโ”€โ”ฌโ”€failuresโ”€โ”
โ”‚ test_max_bytes_ratio_before_external_distinct[server] โ”‚ 1031 โ”‚ 572 โ”‚ 608 โ”‚ 656 โ”‚ 801 โ”‚ 260 โ”‚ 3 โ”‚
โ”‚ test_max_bytes_ratio_before_external_distinct[user] โ”‚ 1031 โ”‚ 547 โ”‚ 582 โ”‚ 649 โ”‚ 571 โ”‚ 23 โ”‚ 1 โ”‚
โ”‚ test_max_bytes_ratio_before_external_sort[server] โ”‚ 1660 โ”‚ 275 โ”‚ 313 โ”‚ 399 โ”‚ 0 โ”‚ 0 โ”‚ 2 โ”‚
โ”‚ test_max_bytes_ratio_before_external_sort[user] โ”‚ 1660 โ”‚ 265 โ”‚ 286 โ”‚ 387 โ”‚ 0 โ”‚ 0 โ”‚ 2 โ”‚
โ”‚ test_max_bytes_ratio_before_external_group_by[user] โ”‚ 1660 โ”‚ 236 โ”‚ 271 โ”‚ 512 โ”‚ 0 โ”‚ 0 โ”‚ 2 โ”‚
โ”‚ test_max_bytes_ratio_before_external_group_by[server] โ”‚ 1660 โ”‚ 228 โ”‚ 245 โ”‚ 482 โ”‚ 0 โ”‚ 0 โ”‚ 2 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```


Workflow [PR]
Sync PR [sync-upstream/pr/121096]
<!-- CI automatic block end :ci_links: -->

Comments Threads Pending Resolution

Resolved Comment Threads

No resolved comments have been left on this PR.