From 4ee517cea4831d9f182a7fa2429510f0846a48e3 Mon Sep 17 00:00:00 2001 From: crazycs Date: Tue, 10 Sep 2019 15:10:03 +0800 Subject: [PATCH] conn: fix lost connection when insert from select panic cause by out of memory quota (#12090) --- executor/adapter.go | 13 +++++++++++++ executor/executor_test.go | 10 ++++++++++ 2 files changed, 23 insertions(+) diff --git a/executor/adapter.go b/executor/adapter.go index 9ecc95cf725ff..71badbf70d5c6 100644 --- a/executor/adapter.go +++ b/executor/adapter.go @@ -44,6 +44,7 @@ import ( "github.com/pingcap/tidb/types" "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" @@ -257,6 +258,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 1180d68ddadc6..85909b70def01 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -4373,6 +4373,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 {