Skip to content

Commit 31b3440

Browse files
authored
executor: fix goroutine leak when builder panic (#52471)
close #51693
1 parent 0f23d83 commit 31b3440

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

pkg/executor/builder.go

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import (
5757
"github.com/pingcap/tidb/pkg/parser/ast"
5858
"github.com/pingcap/tidb/pkg/parser/model"
5959
"github.com/pingcap/tidb/pkg/parser/mysql"
60+
"github.com/pingcap/tidb/pkg/parser/terror"
6061
plannercore "github.com/pingcap/tidb/pkg/planner/core"
6162
plannerutil "github.com/pingcap/tidb/pkg/planner/util"
6263
"github.com/pingcap/tidb/pkg/sessionctx"
@@ -4500,11 +4501,20 @@ func (builder *dataReaderBuilder) buildProjectionForIndexJoin(
45004501
canReorderHandles bool,
45014502
memTracker *memory.Tracker,
45024503
interruptSignal *atomic.Value,
4503-
) (exec.Executor, error) {
4504-
childExec, err := builder.buildExecutorForIndexJoinInternal(ctx, v.Children()[0], lookUpContents, indexRanges, keyOff2IdxOff, cwc, canReorderHandles, memTracker, interruptSignal)
4504+
) (executor exec.Executor, err error) {
4505+
var childExec exec.Executor
4506+
childExec, err = builder.buildExecutorForIndexJoinInternal(ctx, v.Children()[0], lookUpContents, indexRanges, keyOff2IdxOff, cwc, canReorderHandles, memTracker, interruptSignal)
45054507
if err != nil {
45064508
return nil, err
45074509
}
4510+
defer func() {
4511+
if r := recover(); r != nil {
4512+
err = util.GetRecoverError(r)
4513+
}
4514+
if err != nil {
4515+
terror.Log(exec.Close(childExec))
4516+
}
4517+
}()
45084518

45094519
e := &ProjectionExec{
45104520
BaseExecutor: exec.NewBaseExecutor(builder.ctx, v.Schema(), v.ID(), childExec),
@@ -4519,9 +4529,16 @@ func (builder *dataReaderBuilder) buildProjectionForIndexJoin(
45194529
if int64(v.StatsCount()) < int64(builder.ctx.GetSessionVars().MaxChunkSize) {
45204530
e.numWorkers = 0
45214531
}
4532+
failpoint.Inject("buildProjectionForIndexJoinPanic", func(val failpoint.Value) {
4533+
if v, ok := val.(bool); ok && v {
4534+
panic("buildProjectionForIndexJoinPanic")
4535+
}
4536+
})
45224537
err = e.open(ctx)
4523-
4524-
return e, err
4538+
if err != nil {
4539+
return nil, err
4540+
}
4541+
return e, nil
45254542
}
45264543

45274544
// buildRangesForIndexJoin builds kv ranges for index join when the inner plan is index scan plan.

pkg/executor/executor_failpoint_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,3 +699,21 @@ func TestHandleForeignKeyCascadePanic(t *testing.T) {
699699
err := tk.ExecToErr("replace into t1 values (1, 2);")
700700
require.ErrorContains(t, err, "handleForeignKeyCascadeError")
701701
}
702+
703+
func TestBuildProjectionForIndexJoinPanic(t *testing.T) {
704+
// Test no goroutine leak.
705+
store := testkit.CreateMockStore(t)
706+
tk := testkit.NewTestKit(t, store)
707+
tk.MustExec("use test")
708+
tk.MustExec("drop table if exists t1, t2;")
709+
tk.MustExec("create table t1(a int, b varchar(8));")
710+
tk.MustExec("insert into t1 values(1,'1');")
711+
tk.MustExec("create table t2(a int , b varchar(8) GENERATED ALWAYS AS (c) VIRTUAL, c varchar(8), PRIMARY KEY (a));")
712+
tk.MustExec("insert into t2(a) values(1);")
713+
require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/pkg/executor/buildProjectionForIndexJoinPanic", "return(true)"))
714+
defer func() {
715+
require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/pkg/executor/buildProjectionForIndexJoinPanic"))
716+
}()
717+
err := tk.QueryToErr("select /*+ tidb_inlj(t2) */ t2.b, t1.b from t1 join t2 ON t2.a=t1.a;")
718+
require.ErrorContains(t, err, "buildProjectionForIndexJoinPanic")
719+
}

0 commit comments

Comments
 (0)