mirror of
https://github.com/hanzoai/datastore.git
synced 2026-09-26 13:55:07 +00:00
Replace the QueryFuzzer name-based guard (and its gtest) with a max constraint on sleep_in_send_data_ms, sleep_in_send_tables_status_ms and sleep_after_receiving_query_ms in limit-recursion-settings.xml, alongside the existing max_threads cap and for the same reason: the fuzzer scales a test's small value into a multi-minute TCPHandler sleep_for (uninterruptible by cancellation) that trips the 90s hung-check. The profile is installed by both the AST fuzzer and the stress test, so the cap applies wherever the fuzzer runs. Legit stateless uses are <= 100ms; a fuzzed value is clamped to 1s and cannot trip the hung-check. Co-Authored-By: Claude Opus 4.8 <[email protected]>
81 lines
3.9 KiB
XML
81 lines
3.9 KiB
XML
<clickhouse>
|
|
<profiles>
|
|
<default>
|
|
<constraints>
|
|
<!--
|
|
Prevent pathologically slow/hung queries built from deeply nested
|
|
expressions (e.g. `SELECT formatQuery($$SELECT [[[[...20000...]]]]$$)`).
|
|
Bound the parser/AST depth and size settings to [1, default] so neither
|
|
the query fuzzer nor a test can raise them to values that build huge,
|
|
slow-to-parse/format queries. The `<min>1</min>` matters: for all of these
|
|
a value of `0` means "unlimited" and disables the guard, so a `<max>` alone
|
|
would still let `SET ... = 0` remove the safeguard. Lowering to any value
|
|
>= 1 is still allowed.
|
|
|
|
Installed by both the AST fuzzer and the stress test, since the stress
|
|
test ignores `no-*` build tags and runs the fuzzer over every query.
|
|
|
|
`max_parser_backtracks` is additionally pinned on the client command line
|
|
(run-fuzzer.sh, stress.py): its pre-24.3 default is 0, so a client
|
|
`compatibility=...` reverts it to 0 and sends that to the server, which a
|
|
value in this profile cannot prevent (the client value wins).
|
|
-->
|
|
<max_ast_depth>
|
|
<min>1</min>
|
|
<max>1000</max>
|
|
</max_ast_depth>
|
|
<max_parser_depth>
|
|
<min>1</min>
|
|
<max>1000</max>
|
|
</max_parser_depth>
|
|
<max_parser_backtracks>
|
|
<min>1</min>
|
|
<max>1000000</max>
|
|
</max_parser_backtracks>
|
|
<max_ast_elements>
|
|
<min>1</min>
|
|
<max>50000</max>
|
|
</max_ast_elements>
|
|
<max_expanded_ast_elements>
|
|
<min>1</min>
|
|
<max>500000</max>
|
|
</max_expanded_ast_elements>
|
|
|
|
<!--
|
|
A fuzzed huge max_threads (e.g. 65535) makes one query request more
|
|
pipeline threads than the global pool (max_thread_pool_size=10000),
|
|
saturating it (CANNOT_SCHEDULE_TASK), which starves the server-liveness
|
|
probe and delays query cancellation. Cap it. Lives here so every
|
|
ast_fuzzer_runs user (dedicated AST fuzzer and stress test) gets it.
|
|
-->
|
|
<max_threads>
|
|
<max>128</max>
|
|
</max_threads>
|
|
|
|
<!--
|
|
Test-only fault-injection delays. TCPHandler runs them via
|
|
std::this_thread::sleep_for, which does not observe query cancellation, so a
|
|
fuzzed multi-minute value keeps the connection thread blocked past the 90s
|
|
hung-check window on a cancelled query. Cap them: legit stateless uses are
|
|
<= 100ms, and clamping a fuzzed value to 1s cannot trip the hung check.
|
|
-->
|
|
<sleep_in_send_data_ms>
|
|
<max>1000</max>
|
|
</sleep_in_send_data_ms>
|
|
<sleep_in_send_tables_status_ms>
|
|
<max>1000</max>
|
|
</sleep_in_send_tables_status_ms>
|
|
<sleep_after_receiving_query_ms>
|
|
<max>1000</max>
|
|
</sleep_after_receiving_query_ms>
|
|
</constraints>
|
|
|
|
<!-- Server-side backstop: keeps max_parser_backtracks `changed` so a server-side
|
|
`SET compatibility=...` can't revert it to 0. The client-option compatibility
|
|
path is handled by the command-line pin in run-fuzzer.sh / stress.py, which
|
|
overrides this value anyway. -->
|
|
<max_parser_backtracks>1000000</max_parser_backtracks>
|
|
</default>
|
|
</profiles>
|
|
</clickhouse>
|