Skip to content

Commit 90dff8a

Browse files
xzhangxian1008ti-chi-bot
authored andcommitted
executor: replace Call with CallWithRecover in the close of hash join v1 (pingcap#61868)
close pingcap#60926
1 parent 54e6268 commit 90dff8a

File tree

4 files changed

+54
-4
lines changed

4 files changed

+54
-4
lines changed

pkg/executor/join/hash_join_v1.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ import (
4545
"github.com/pingcap/tidb/pkg/util/memory"
4646
)
4747

48+
// IsChildCloseCalledForTest is used for test
49+
var IsChildCloseCalledForTest = false
50+
4851
var (
4952
_ exec.Executor = &HashJoinV1Exec{}
5053
_ exec.Executor = &NestedLoopApplyExec{}
@@ -114,7 +117,7 @@ type HashJoinV1Exec struct {
114117
}
115118

116119
// Close implements the Executor Close interface.
117-
func (e *HashJoinV1Exec) Close() error {
120+
func (e *HashJoinV1Exec) Close() (err error) {
118121
if e.closeCh != nil {
119122
close(e.closeCh)
120123
}
@@ -138,7 +141,11 @@ func (e *HashJoinV1Exec) Close() error {
138141
channel.Clear(e.ProbeWorkers[i].joinChkResourceCh)
139142
}
140143
e.ProbeSideTupleFetcher.probeChkResourceCh = nil
141-
terror.Call(e.RowContainer.Close)
144+
util.WithRecovery(func() { err = e.RowContainer.Close() }, func(r any) {
145+
if r != nil {
146+
err = errors.Errorf("%v", r)
147+
}
148+
})
142149
e.HashJoinCtxV1.SessCtx.GetSessionVars().MemTracker.UnbindActionFromHardLimit(e.RowContainer.ActionSpill())
143150
e.waiterWg.Wait()
144151
}
@@ -159,7 +166,12 @@ func (e *HashJoinV1Exec) Close() error {
159166
if e.stats != nil {
160167
defer e.Ctx().GetSessionVars().StmtCtx.RuntimeStatsColl.RegisterStats(e.ID(), e.stats)
161168
}
162-
err := e.BaseExecutor.Close()
169+
170+
IsChildCloseCalledForTest = true
171+
childErr := e.BaseExecutor.Close()
172+
if childErr != nil {
173+
return childErr
174+
}
163175
return err
164176
}
165177

pkg/executor/join/hash_table_v1.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"unsafe"
2323

2424
"github.com/pingcap/errors"
25+
"github.com/pingcap/failpoint"
2526
"github.com/pingcap/tidb/pkg/sessionctx"
2627
"github.com/pingcap/tidb/pkg/sessionctx/stmtctx"
2728
"github.com/pingcap/tidb/pkg/types"
@@ -535,6 +536,8 @@ func (c *hashRowContainer) Len() uint64 {
535536
}
536537

537538
func (c *hashRowContainer) Close() error {
539+
failpoint.Inject("issue60923", nil)
540+
538541
defer c.memTracker.Detach()
539542
c.chkBuf = nil
540543
return c.rowContainer.Close()

pkg/executor/test/issuetest/BUILD.bazel

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ go_test(
88
"main_test.go",
99
],
1010
flaky = True,
11-
shard_count = 24,
11+
shard_count = 25,
1212
deps = [
1313
"//pkg/autoid_service",
1414
"//pkg/config",
@@ -21,6 +21,7 @@ go_test(
2121
"//pkg/parser/mysql",
2222
"//pkg/session/types",
2323
"//pkg/testkit",
24+
"//pkg/testkit/testfailpoint",
2425
"//pkg/util",
2526
"//pkg/util/dbterror/exeerrors",
2627
"//pkg/util/memory",

pkg/executor/test/issuetest/executor_issue_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package issuetest_test
1616

1717
import (
18+
"context"
1819
"fmt"
1920
"math/rand"
2021
"strings"
@@ -32,6 +33,7 @@ import (
3233
"github.com/pingcap/tidb/pkg/parser/mysql"
3334
sessiontypes "github.com/pingcap/tidb/pkg/session/types"
3435
"github.com/pingcap/tidb/pkg/testkit"
36+
"github.com/pingcap/tidb/pkg/testkit/testfailpoint"
3537
"github.com/pingcap/tidb/pkg/util"
3638
"github.com/pingcap/tidb/pkg/util/dbterror/exeerrors"
3739
"github.com/pingcap/tidb/pkg/util/memory"
@@ -772,3 +774,35 @@ func TestIssue55881(t *testing.T) {
772774
"(select max(value) from (select * from cte union all select * from cte union all select * from aaa where aaa.id > bbb.id)) from bbb;")
773775
}
774776
}
777+
778+
func TestIssue60923(t *testing.T) {
779+
store := testkit.CreateMockStore(t)
780+
tk := testkit.NewTestKit(t, store)
781+
782+
tk.MustExec("use test")
783+
tk.MustExec("drop table if exists t1")
784+
tk.MustExec("drop table if exists t2")
785+
tk.MustExec("create table t1 (col0 int, col1 int);")
786+
tk.MustExec("create table t2 (col0 int, col1 int);")
787+
tk.MustExec("insert into t1 values (0, 10), (1, 10), (2, 10), (3, 10), (4, 10), (5, 10), (6, 10), (7, 10), (8, 10), (9, 10), (10, 10);")
788+
tk.MustExec("insert into t2 values (0, 5), (0, 5), (1, 5), (2, 5), (2, 5), (3, 5), (4, 5), (5, 5), (5, 5), (6, 5), (7, 5), (8, 5), (8, 5), (9, 5), (9, 5), (10, 5);")
789+
790+
testfailpoint.Enable(t, "github.com/pingcap/tidb/pkg/executor/join/issue60923", "panic")
791+
tk.MustExec("set tidb_hash_join_version=legacy")
792+
793+
ctx := context.Background()
794+
join.IsChildCloseCalledForTest = false
795+
rs, _ := tk.ExecWithContext(context.Background(), "select * from t1 join (select col0, sum(col1) from t2 group by col0) as r on t1.col0 = r.col0;")
796+
req := rs.NewChunk(nil)
797+
for {
798+
err := rs.Next(ctx, req)
799+
require.NoError(t, err)
800+
if req.NumRows() == 0 {
801+
break
802+
}
803+
}
804+
if rs != nil {
805+
require.Error(t, rs.Close())
806+
}
807+
require.True(t, join.IsChildCloseCalledForTest)
808+
}

0 commit comments

Comments
 (0)