planner/core/issuetest/planner_issue is flaky: assertion reads the current statements_summary window under a 1s refresh interval
- Dominant language
- Go
- Stars
- 40.5k
- Forks
- 6.2k
- PR merge metrics
- PR metrics pending
Description
## Bug Report
The integration test `planner/core/issuetest/planner_issue` is flaky. It asserts on the *current* window of `information_schema.cluster_statements_summary` while the test itself sets `tidb_stmt_summary_refresh_interval = 1`, so the row it checks disappears whenever a one-second window boundary is crossed before the assertion runs. It fails intermittently on loaded CI machines and passes on fast ones.
Observed in `idc-jenkins-ci-tidb/check_dev` build [6510](https://prow.tidb.net/jenkins/job/pingcap/job/tidb/job/ghpr_check/6510/display/redirect) (found while running CI for #70436, whose diff does not touch the planner or statement summary).
### 1. Minimal reproduce step (Required)
```bash
cd tests/integrationtest && ./run-tests.sh -t planner/core/issuetest/planner_issue
```
The failing assertion is `tests/integrationtest/t/planner/core/issuetest/planner_issue.test:881`:
```sql
select count(*) as truncated_count
from information_schema.cluster_statements_summary
where digest_text like 'select%long_column_name_just_fill_out_the_plan_and_sql_digest_text%'
and (digest_text like '%(len:%' or query_sample_text like '%(len:%');
```
It is timing dependent: it fails whenever at least one second elapses between the long `SELECT` at line 804 and this assertion, which is what happens when the machine is loaded. Per the analysis below, adding a one-second delay just before the assertion (after `show global bindings;` on line 878) should turn the race into a deterministic failure:
```sql
select sleep(1);
```
### 2. What did you expect to see? (Required)
```text
truncated_count
1
```
### 3. What did you see instead (Required)
```text
truncated_count
0
```
CI log excerpt
```text
ERRO[0335] 1 tests failed
run test [planner/core/issuetest/planner_issue] err: sql:select count(*) as truncated_count
from information_schema.cluster_statements_summary
where digest_text like 'select%long_column_name_just_fill_out_the_plan_and_sql_digest_text%'
and (digest_text like '%(len:%' or query_sample_text like '%(len:%');: failed to run query
around line 884,
we need(267):
...
truncated_count
1
but got(267):
...
truncated_count
0
make: *** [Makefile:188: integrationtest] Error 1
```
### Analysis
The test sets a one-second summary window at `planner_issue.test:708`:
```sql
set global tidb_stmt_summary_refresh_interval = 1;
```
`cluster_statements_summary` only exposes the current window. `getStmtByDigestRow` drops any element whose `beginTime` predates the current window begin:
https://github.com/pingcap/tidb/blob/31c9768698c5b15ef3a277a7db38b995db82ce87/pkg/util/stmtsummary/reader.go#L164-L179
`beginTimeForCurInterval` is advanced by `AddStatement` and is aligned to the interval boundary:
https://github.com/pingcap/tidb/blob/31c9768698c5b15ef3a277a7db38b995db82ce87/pkg/util/stmtsummary/statement_summary.go#L413-L418
So with a one-second interval, the long `SELECT` recorded in second `T` stops being visible in `cluster_statements_summary` as soon as any later statement in the test — the union query at line 866, the failing `create global binding from history` at line 877, or `show global bindings` at line 878 — is recorded in a later second. The row moves to `cluster_statements_summary_history`, the assertion counts 0, and the test fails.
Two details worth noting:
- The earlier check of the same shape at line 866 unions the current view with `cluster_statements_summary_history`, so it is not affected by the rotation. Only line 881 reads the current view alone.
- The first block of the test (line 788) asserts `truncated_count = 0`, which stays green even when the row has already rotated out, so the window rotation only shows up in the second block.
### Suggested fix
Either of:
1. Make the assertion at line 881 union with `cluster_statements_summary_history`, matching what line 866 already does.
2. Drop `set global tidb_stmt_summary_refresh_interval = 1` (or set it to a large value). The test clears state by toggling `tidb_enable_stmt_summary` off and on (lines 800-801), so it does not need a one-second rotation to get a clean window.
Option 1 keeps the current window semantics under test; option 2 removes the timing dependency entirely.
### 4. What is your TiDB version? (Required)
```text
master, base SHA 31c9768698c5b15ef3a277a7db38b995db82ce87
```
Contributor guide
Research direction
Start with tests/integrationtest/t/planner/core/issuetest/planner_issue.test around lines 866-881 and compare the history-union assertion with the flaky current-window query. Run ./run-tests.sh -t planner/core/issuetest/planner_issue, then verify the test reliably reports truncated_count as 1 under the documented one-second refresh interval.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, sql
- Domain
- databases, testing-qa
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100