diff --git a/executor/adapter.go b/executor/adapter.go index 2908dccf0d37f..363ed3c96b93b 100644 --- a/executor/adapter.go +++ b/executor/adapter.go @@ -43,6 +43,7 @@ import ( "github.com/pingcap/tidb/store/tikv" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/logutil" + "github.com/pingcap/tidb/util/memory" "github.com/pingcap/tidb/util/sqlexec" "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -207,6 +208,18 @@ func (a *ExecStmt) RebuildPlan(ctx context.Context) (int64, error) { // like the INSERT, UPDATE statements, it executes in this function, if the Executor returns // result, execution is done after this function returns, in the returned sqlexec.RecordSet Next method. func (a *ExecStmt) Exec(ctx context.Context) (_ sqlexec.RecordSet, err error) { + defer func() { + r := recover() + if r == nil { + return + } + if str, ok := r.(string); !ok || !strings.HasPrefix(str, memory.PanicMemoryExceed) { + panic(r) + } + err = errors.Errorf("%v", r) + logutil.Logger(ctx).Error("execute sql panic", zap.String("sql", a.Text), zap.Stack("stack")) + }() + sctx := a.Ctx if _, ok := a.Plan.(*plannercore.Analyze); ok && sctx.GetSessionVars().InRestrictedSQL { oriStats, _ := sctx.GetSessionVars().GetSystemVar(variable.TiDBBuildStatsConcurrency) diff --git a/executor/executor_test.go b/executor/executor_test.go index 69fcf128d490b..e16bb22621c6b 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -4184,6 +4184,16 @@ func (s *testSuite) TestOOMPanicAction(c *C) { err := tk.QueryToErr("select sum(b) from t group by a;") c.Assert(err, NotNil) c.Assert(err.Error(), Matches, "Out Of Memory Quota!.*") + + // Test insert from select oom panic. + tk.MustExec("drop table if exists t,t1") + tk.MustExec("create table t (a bigint);") + tk.MustExec("create table t1 (a bigint);") + tk.MustExec("insert into t1 values (1),(2),(3),(4),(5);") + tk.MustExec("set @@tidb_mem_quota_query=200;") + _, err = tk.Exec("insert into t select a from t1 order by a desc;") + c.Assert(err, NotNil) + c.Assert(err.Error(), Matches, "Out Of Memory Quota!.*") } type oomCapturer struct {