Skip to content

Commit 2d755a8

Browse files
authored
executor: fix data race at the ShowExec (#39817)
close #39816, close #40295
1 parent f7c87c8 commit 2d755a8

File tree

4 files changed

+35
-3
lines changed

4 files changed

+35
-3
lines changed

executor/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ go_library(
192192
"//util/servermemorylimit",
193193
"//util/set",
194194
"//util/size",
195+
"//util/slice",
195196
"//util/sqlexec",
196197
"//util/stmtsummary",
197198
"//util/stringutil",

executor/show.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ import (
6969
"github.com/pingcap/tidb/util/memory"
7070
"github.com/pingcap/tidb/util/sem"
7171
"github.com/pingcap/tidb/util/set"
72+
"github.com/pingcap/tidb/util/slice"
7273
"github.com/pingcap/tidb/util/sqlexec"
7374
"github.com/pingcap/tidb/util/stringutil"
7475
"golang.org/x/exp/slices"
@@ -306,13 +307,14 @@ func (v *visibleChecker) Leave(in ast.Node) (out ast.Node, ok bool) {
306307
}
307308

308309
func (e *ShowExec) fetchShowBind() error {
309-
var bindRecords []*bindinfo.BindRecord
310+
var tmp []*bindinfo.BindRecord
310311
if !e.GlobalScope {
311312
handle := e.ctx.Value(bindinfo.SessionBindInfoKeyType).(*bindinfo.SessionHandle)
312-
bindRecords = handle.GetAllBindRecord()
313+
tmp = handle.GetAllBindRecord()
313314
} else {
314-
bindRecords = domain.GetDomain(e.ctx).BindHandle().GetAllBindRecord()
315+
tmp = domain.GetDomain(e.ctx).BindHandle().GetAllBindRecord()
315316
}
317+
bindRecords := slice.Copy(tmp)
316318
// Remove the invalid bindRecord.
317319
ind := 0
318320
for _, bindData := range bindRecords {

util/slice/slice.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,16 @@ func AllOf(s interface{}, p func(int) bool) bool {
3939
}
4040
return NoneOf(s, np)
4141
}
42+
43+
// Copy is a deep copy of the slice.
44+
func Copy[T any](a []*T) []*T {
45+
b := make([]*T, len(a))
46+
for i, p := range a {
47+
if p == nil {
48+
continue
49+
}
50+
v := *p
51+
b[i] = &v
52+
}
53+
return b
54+
}

util/slice/slice_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,19 @@ func TestSlice(t *testing.T) {
4343
})
4444
}
4545
}
46+
47+
func TestCopy(t *testing.T) {
48+
type T int
49+
v0, v1, v2, v3 := T(0), T(1), T(2), T(3)
50+
s := []*T{&v0, &v1, &v2, &v3, nil}
51+
e := Copy(s)
52+
require.Equal(t, len(s), len(e))
53+
for i := range s {
54+
if s[i] == nil {
55+
require.Nil(t, e[i])
56+
} else {
57+
require.Equal(t, *s[i], *e[i])
58+
require.True(t, s[i] != e[i])
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)