Commit 0d7eeb3
fix: prevent nested local shuffle deadlocks (#26055)
## What type of PR is this?
- [x] BUG
- [ ] Improvement
- [ ] Documentation
- [ ] Feature
- [ ] Test and CI
- [ ] Code Refactoring
## Which issue(s) this PR fixes
Fixes #25922
## What this PR does / why we need it
The unified Shuffle implementation added bounded backpressure to shared
local Shuffle pools. Per-bucket credits fixed same-level hot-bucket
starvation, but a finite fixed-bucket pool can still deadlock when more
than one local Shuffle is duplicated into the same pull-based worker
tree.
The observed 16-worker wait-for cycle was:
1. an outer Shuffle writer filled its target bucket and waited for that
bucket's worker;
2. the target worker was blocked in an inner Shuffle waiting for every
inner writer to finish;
3. the missing inner writer was the child of the blocked outer writer,
so it could only finish if the outer writer resumed pulling.
This change prevents the cyclic topology instead of increasing or
removing the memory bound:
- keep the first fixed-bucket local Shuffle fast path;
- detect a fixed-bucket Shuffle already present in a packed operator
tree;
- materialize a second join/group Shuffle through the existing producer
scopes, bounded dispatch channels, and consumer scopes;
- preserve local Shuffle reuse when no second probe Shuffle is
introduced;
- cancel an active request before connection cleanup waits for
migration/reset or transaction rollback, so cleanup is independent of a
stuck data path.
The fallback remains bounded: its existing dispatch channel capacity is
32, and this PR does not change Shuffle ready credits or introduce an
unbounded queue. It also does not introduce a new hard query timeout.
## Regression coverage
- 16-way nested local shuffle join, on both probe and build chains;
- 16-way nested local shuffle group;
- fixed Shuffle below a non-root operator to cover recursive detection;
- single-layer local group and reusable local join fast paths remain
local;
- connection cleanup cancels before a blocked lifecycle operation and
before rollback.
The nested-join regression failed on `origin/main` by producing one
packed local scope and passes with this change by producing 16
independent bucket scopes.
## Validation
- `go test -race -count=1 -timeout=600s ./pkg/sql/compile
./pkg/frontend`
- focused new concurrency/topology tests under `-race -count=20`
- `go test -v -count=1 -timeout=600s ./pkg/sql/compile ./pkg/frontend`
- `go test -count=1 ./pkg/sql/colexec/shuffle ./pkg/sql/colexec/dispatch
./pkg/sql/colexec/merge ./pkg/sql/colexec/group`
- `go build ./pkg/sql/compile ./pkg/frontend`
- `go vet ./pkg/sql/compile ./pkg/frontend`
- `git diff --check`
---------
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>1 parent b1c11b2 commit 0d7eeb3
18 files changed
Lines changed: 1220 additions & 68 deletions
File tree
- pkg
- cnservice
- frontend
- sql/compile
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
531 | 531 | | |
532 | 532 | | |
533 | 533 | | |
534 | | - | |
| 534 | + | |
535 | 535 | | |
536 | 536 | | |
537 | 537 | | |
| |||
592 | 592 | | |
593 | 593 | | |
594 | 594 | | |
595 | | - | |
| 595 | + | |
596 | 596 | | |
597 | 597 | | |
598 | 598 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
18 | 21 | | |
19 | 22 | | |
20 | 23 | | |
21 | 24 | | |
22 | 25 | | |
23 | 26 | | |
| 27 | + | |
| 28 | + | |
24 | 29 | | |
25 | 30 | | |
26 | 31 | | |
27 | 32 | | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
28 | 36 | | |
29 | 37 | | |
30 | 38 | | |
| |||
41 | 49 | | |
42 | 50 | | |
43 | 51 | | |
| 52 | + | |
44 | 53 | | |
45 | 54 | | |
46 | | - | |
47 | 55 | | |
48 | 56 | | |
49 | 57 | | |
50 | 58 | | |
51 | 59 | | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
52 | 74 | | |
53 | 75 | | |
54 | 76 | | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
55 | 95 | | |
56 | 96 | | |
57 | | - | |
| 97 | + | |
58 | 98 | | |
59 | 99 | | |
60 | | - | |
| 100 | + | |
61 | 101 | | |
62 | 102 | | |
63 | 103 | | |
64 | 104 | | |
65 | 105 | | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
66 | 114 | | |
67 | 115 | | |
68 | | - | |
| 116 | + | |
69 | 117 | | |
70 | 118 | | |
71 | | - | |
72 | | - | |
73 | | - | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
74 | 122 | | |
75 | 123 | | |
76 | | - | |
| 124 | + | |
77 | 125 | | |
| 126 | + | |
78 | 127 | | |
79 | 128 | | |
80 | | - | |
| 129 | + | |
| 130 | + | |
81 | 131 | | |
82 | 132 | | |
83 | 133 | | |
84 | 134 | | |
85 | 135 | | |
86 | 136 | | |
87 | 137 | | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
88 | 142 | | |
89 | 143 | | |
90 | 144 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| 18 | + | |
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
| |||
107 | 108 | | |
108 | 109 | | |
109 | 110 | | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
110 | 173 | | |
111 | 174 | | |
112 | 175 | | |
| |||
0 commit comments