Skip to content

Commit be0ea47

Browse files
wjhuang2016ti-chi-bot
authored andcommitted
This is an automated cherry-pick of pingcap#57964
Signed-off-by: ti-chi-bot <[email protected]>
1 parent 1e2bb37 commit be0ea47

File tree

3 files changed

+129
-9
lines changed

3 files changed

+129
-9
lines changed

pkg/ddl/tests/metadatalock/BUILD.bazel

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ go_test(
88
"mdl_test.go",
99
],
1010
flaky = True,
11-
shard_count = 36,
11+
shard_count = 37,
1212
deps = [
1313
"//pkg/config",
1414
"//pkg/ddl",
1515
"//pkg/ddl/ingest/testutil",
1616
"//pkg/errno",
17+
"//pkg/meta/model",
1718
"//pkg/server",
1819
"//pkg/testkit",
1920
"//pkg/testkit/testsetup",

pkg/ddl/tests/metadatalock/mdl_test.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,20 @@
1515
package metadatalocktest
1616

1717
import (
18+
"context"
1819
"fmt"
1920
"sync"
2021
"testing"
2122
"time"
2223

2324
"github.com/pingcap/failpoint"
25+
<<<<<<< HEAD
26+
=======
27+
"github.com/pingcap/tidb/pkg/ddl"
28+
>>>>>>> 6b17068d75f (planner: fix incorrectly using the schema for plan cache (#57964))
2429
ingesttestutil "github.com/pingcap/tidb/pkg/ddl/ingest/testutil"
2530
mysql "github.com/pingcap/tidb/pkg/errno"
31+
"github.com/pingcap/tidb/pkg/meta/model"
2632
"github.com/pingcap/tidb/pkg/server"
2733
"github.com/pingcap/tidb/pkg/testkit"
2834
"github.com/stretchr/testify/require"
@@ -997,6 +1003,103 @@ func TestMDLPreparePlanCacheExecute2(t *testing.T) {
9971003
tk.MustExec("admin check table t")
9981004
}
9991005

1006+
// TestMDLPreparePlanCacheExecuteInsert makes sure the insert statement handle the schema correctly in plan cache.
1007+
func TestMDLPreparePlanCacheExecuteInsert(t *testing.T) {
1008+
store, dom := testkit.CreateMockStoreAndDomain(t)
1009+
defer ingesttestutil.InjectMockBackendMgr(t, store)()
1010+
1011+
sv := server.CreateMockServer(t, store)
1012+
1013+
sv.SetDomain(dom)
1014+
dom.InfoSyncer().SetSessionManager(sv)
1015+
defer sv.Close()
1016+
1017+
conn1 := server.CreateMockConn(t, sv)
1018+
tk := testkit.NewTestKitWithSession(t, store, conn1.Context().Session)
1019+
conn2 := server.CreateMockConn(t, sv)
1020+
tkDDL := testkit.NewTestKitWithSession(t, store, conn2.Context().Session)
1021+
conn3 := server.CreateMockConn(t, sv)
1022+
tk3 := testkit.NewTestKitWithSession(t, store, conn3.Context().Session)
1023+
tk.MustExec("use test")
1024+
tk.MustExec("set global tidb_enable_metadata_lock=1")
1025+
tk.MustExec("create table t(a int primary key, b int);")
1026+
tk.MustExec("create table t2(a int);")
1027+
tk.MustExec("insert into t values(1, 1), (2, 2), (3, 3), (4, 4);")
1028+
1029+
tk.MustExec(`begin`)
1030+
tk.MustExec(`prepare delete_stmt from 'delete from t where a = ?'`)
1031+
tk.MustExec(`prepare insert_stmt from 'insert into t values (?, ?)'`)
1032+
tk.MustExec(`commit`)
1033+
1034+
tk.MustExec(`begin`)
1035+
tk.MustExec(`set @a = 4, @b= 4;`)
1036+
tk.MustExec(`execute delete_stmt using @a;`)
1037+
tk.MustExec(`execute insert_stmt using @a, @b;`)
1038+
tk.MustExec(`commit`)
1039+
1040+
tk.MustExec("begin")
1041+
1042+
ch := make(chan struct{})
1043+
1044+
first := true
1045+
testfailpoint.EnableCall(t, "github.com/pingcap/tidb/pkg/ddl/onJobUpdated", func(job *model.Job) {
1046+
switch job.SchemaState {
1047+
case model.StateWriteReorganization:
1048+
tbl, _ := dom.InfoSchema().TableByID(context.Background(), job.TableID)
1049+
idx := tbl.Meta().FindIndexByName("idx")
1050+
switch idx.BackfillState {
1051+
case model.BackfillStateRunning:
1052+
if first {
1053+
tk.MustExec(`begin`)
1054+
tk.MustExec(`set @a=9;`)
1055+
tk.MustExec(`execute delete_stmt using @a;`)
1056+
tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("0"))
1057+
tk.MustExec(`set @a=6, @b=4;`)
1058+
tk.MustExec(`execute insert_stmt using @a, @b;`)
1059+
tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("0"))
1060+
tk.MustExec(`commit`)
1061+
tk.MustExec(`begin`)
1062+
tk.MustExec(`set @a=4;`)
1063+
tk.MustExec(`execute delete_stmt using @a;`)
1064+
tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("1"))
1065+
tk.MustExec(`set @a=4, @b=4;`)
1066+
tk.MustExec(`execute insert_stmt using @a, @b;`)
1067+
tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("0"))
1068+
tk.MustExec(`commit`)
1069+
1070+
tk.MustExec("begin")
1071+
// Activate txn.
1072+
tk.MustExec("select * from t2")
1073+
first = false
1074+
tk3.MustExec("insert into test.t values(10000, 1000)")
1075+
return
1076+
}
1077+
}
1078+
}
1079+
})
1080+
1081+
ddl.MockDMLExecutionMerging = func() {
1082+
tk.MustExec(`execute delete_stmt using @a;`)
1083+
tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("0"))
1084+
tk.MustExec(`execute insert_stmt using @a, @b;`)
1085+
tk.MustExec("commit")
1086+
}
1087+
require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/pkg/ddl/mockDMLExecutionMerging", "1*return(true)->return(false)"))
1088+
1089+
var wg sync.WaitGroup
1090+
wg.Add(1)
1091+
go func() {
1092+
<-ch
1093+
tkDDL.MustExec("alter table test.t add index idx(a);")
1094+
wg.Done()
1095+
}()
1096+
1097+
ch <- struct{}{}
1098+
wg.Wait()
1099+
1100+
tk.MustExec("admin check table t")
1101+
}
1102+
10001103
func TestMDLDisable2Enable(t *testing.T) {
10011104
store, dom := testkit.CreateMockStoreAndDomain(t)
10021105
sv := server.CreateMockServer(t, store)

pkg/planner/core/plan_cache.go

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ package core
1717
import (
1818
"bytes"
1919
"context"
20+
<<<<<<< HEAD
21+
=======
22+
"math"
23+
"time"
24+
>>>>>>> 6b17068d75f (planner: fix incorrectly using the schema for plan cache (#57964))
2025

2126
"github.com/pingcap/errors"
2227
"github.com/pingcap/tidb/pkg/bindinfo"
@@ -41,9 +46,16 @@ import (
4146
"github.com/pingcap/tidb/pkg/util/chunk"
4247
"github.com/pingcap/tidb/pkg/util/collate"
4348
"github.com/pingcap/tidb/pkg/util/dbterror/plannererrors"
49+
<<<<<<< HEAD
4450
"github.com/pingcap/tidb/pkg/util/kvcache"
4551
utilpc "github.com/pingcap/tidb/pkg/util/plancache"
4652
"github.com/pingcap/tidb/pkg/util/ranger"
53+
=======
54+
"github.com/pingcap/tidb/pkg/util/hint"
55+
"github.com/pingcap/tidb/pkg/util/intest"
56+
"github.com/pingcap/tidb/pkg/util/logutil"
57+
"go.uber.org/zap"
58+
>>>>>>> 6b17068d75f (planner: fix incorrectly using the schema for plan cache (#57964))
4759
)
4860

4961
// PlanCacheKeyTestIssue43667 is only for test.
@@ -114,23 +126,27 @@ func planCachePreprocess(ctx context.Context, sctx sessionctx.Context, isNonPrep
114126
if err != nil {
115127
return plannererrors.ErrSchemaChanged.GenWithStack("Schema change caused error: %s", err.Error())
116128
}
129+
// Table ID is changed, for example, drop & create table, truncate table.
117130
delete(stmt.RelateVersion, stmt.tbls[i].Meta().ID)
118-
stmt.tbls[i] = tblByName
119-
stmt.RelateVersion[tblByName.Meta().ID] = tblByName.Meta().Revision
131+
tbl = tblByName
120132
}
133+
<<<<<<< HEAD
121134
newTbl, err := tryLockMDLAndUpdateSchemaIfNecessary(sctx.GetPlanCtx(), stmt.dbName[i], stmt.tbls[i], is)
135+
=======
136+
// newTbl is the 'should be used' table info for this execution.
137+
newTbl, err := tryLockMDLAndUpdateSchemaIfNecessary(ctx, sctx.GetPlanCtx(), stmt.dbName[i], tbl, is)
138+
>>>>>>> 6b17068d75f (planner: fix incorrectly using the schema for plan cache (#57964))
122139
if err != nil {
140+
logutil.BgLogger().Warn("meet error during tryLockMDLAndUpdateSchemaIfNecessary", zap.String("table name", tbl.Meta().Name.String()), zap.Error(err))
141+
// Invalid the cache key related fields to avoid using plan cache.
142+
stmt.RelateVersion[tbl.Meta().ID] = math.MaxUint64
123143
schemaNotMatch = true
124144
continue
125145
}
126-
// The revision of tbl and newTbl may not be the same.
127-
// Example:
128-
// The version of stmt.tbls[i] is taken from the prepare statement and is revision v1.
129-
// When stmt.tbls[i] is locked in MDL, the revision of newTbl is also v1.
130-
// The revision of tbl is v2. The reason may have other statements trigger "tryLockMDLAndUpdateSchemaIfNecessary" before, leading to tbl revision update.
131-
if stmt.tbls[i].Meta().Revision != newTbl.Meta().Revision || (tbl != nil && tbl.Meta().Revision != newTbl.Meta().Revision) {
146+
if stmt.tbls[i].Meta().Revision != newTbl.Meta().Revision {
132147
schemaNotMatch = true
133148
}
149+
// Update the cache key related fields.
134150
stmt.tbls[i] = newTbl
135151
stmt.RelateVersion[newTbl.Meta().ID] = newTbl.Meta().Revision
136152
}

0 commit comments

Comments
 (0)