Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: insert/update or explain should not trigger table cache condition #29477

Merged
merged 3 commits into from
Nov 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -4160,9 +4160,15 @@ func (b *PlanBuilder) buildDataSource(ctx context.Context, tn *ast.TableName, as
result = us
} else {
go func() {
err := cachedTable.UpdateLockForRead(b.ctx, txn.StartTS())
if err != nil {
log.Warn("Update Lock Info Error")
defer func() {
if r := recover(); r != nil {
tiancaiamao marked this conversation as resolved.
Show resolved Hide resolved
}
}()
if !b.inUpdateStmt && !b.inDeleteStmt && !b.ctx.GetSessionVars().StmtCtx.InExplainStmt {
err := cachedTable.UpdateLockForRead(b.ctx, txn.StartTS())
if err != nil {
log.Warn("Update Lock Info Error")
}
}
}()
}
Expand Down
5 changes: 5 additions & 0 deletions sessionctx/stmtctx/stmtctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,11 @@ func (sc *StatementContext) GetCacheTable(tblID int64) (bool, interface{}) {
return false, nil
}

// CacheTableUsed is used by test to check whether the last query use table cache.
func (sc *StatementContext) CacheTableUsed() bool {
return len(sc.cachedTables) > 0
}

// TableEntry presents table in db.
type TableEntry struct {
DB string
Expand Down
78 changes: 65 additions & 13 deletions table/tables/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import (
"testing"

"github.com/pingcap/tidb/testkit"
"github.com/stretchr/testify/require"
)

func TestCacheTableBasicScan(t *testing.T) {
t.Parallel()
store, clean := testkit.CreateMockStore(t)
defer clean()
tk := testkit.NewTestKit(t, store)
Expand All @@ -45,13 +45,19 @@ func TestCacheTableBasicScan(t *testing.T) {
tk.MustExec("create table join_t1 (id int)")
tk.MustExec("insert into join_t1 values(1)")
tk.MustExec("alter table join_t1 cache")
tk.MustExec("select *from join_t1")
tk.MustQuery("select *from join_t1").Check(testkit.Rows("1"))
tk.MustExec("create table join_t2 (id int)")
tk.MustExec("insert into join_t2 values(2)")
tk.MustExec("alter table join_t2 cache")
tk.MustExec("select *from join_t2")
tk.MustQuery("select *from join_t2").Check(testkit.Rows("2"))
tk.MustExec("create table join_t3 (id int)")
tk.MustExec("insert into join_t3 values(3)")
for i := 0; i < 10; i++ {
tk.MustQuery("select *from join_t1 join join_t2").Check(testkit.Rows("1 2"))
if tk.Session().GetSessionVars().StmtCtx.CacheTableUsed() {
break
}
}
result := tk.MustQuery("explain format = 'brief' select *from join_t1 join join_t2")
result.Check(testkit.Rows(
"HashJoin 100000000.00 root CARTESIAN inner join",
Expand All @@ -61,8 +67,13 @@ func TestCacheTableBasicScan(t *testing.T) {
"└─UnionScan(Probe) 10000.00 root ",
" └─TableReader 10000.00 root data:TableFullScan",
" └─TableFullScan 10000.00 cop[tikv] table:join_t1 keep order:false, stats:pseudo"))
tk.MustQuery("select *from join_t1 join join_t2").Check(testkit.Rows("1 2"))
// Test for join a cache table and a normal table
for i := 0; i < 10; i++ {
tk.MustQuery("select *from join_t1 join join_t3").Check(testkit.Rows("1 3"))
if tk.Session().GetSessionVars().StmtCtx.CacheTableUsed() {
break
}
}
result = tk.MustQuery("explain format = 'brief' select *from join_t1 join join_t3")
result.Check(testkit.Rows(
"Projection 100000000.00 root test.join_t1.id, test.join_t3.id",
Expand All @@ -73,26 +84,35 @@ func TestCacheTableBasicScan(t *testing.T) {
" └─TableReader(Probe) 10000.00 root data:TableFullScan",
" └─TableFullScan 10000.00 cop[tikv] table:join_t3 keep order:false, stats:pseudo"))

tk.MustQuery("select *from join_t1 join join_t3").Check(testkit.Rows("1 3"))
// Second read will from cache table
for i := 0; i < 10; i++ {
tk.MustQuery("select * from tmp1 where id>4 order by id").Check(testkit.Rows(
"5 105 1005", "7 117 1007", "9 109 1009",
"10 110 1010", "12 112 1012", "14 114 1014", "16 116 1016", "18 118 1018",
))
if tk.Session().GetSessionVars().StmtCtx.CacheTableUsed() {
break
}
}
result = tk.MustQuery("explain format = 'brief' select * from tmp1 where id>4 order by id")
result.Check(testkit.Rows("UnionScan 3333.33 root gt(test.tmp1.id, 4)",
"└─TableReader 3333.33 root data:TableRangeScan",
" └─TableRangeScan 3333.33 cop[tikv] table:tmp1 range:(4,+inf], keep order:true, stats:pseudo"))
tk.MustQuery("select * from tmp1 where id>4 order by id").Check(testkit.Rows(
"5 105 1005", "7 117 1007", "9 109 1009",
"10 110 1010", "12 112 1012", "14 114 1014", "16 116 1016", "18 118 1018",
))
// For IndexLookUpReader
for i := 0; i < 10; i++ {
tk.MustQuery("select /*+ use_index(tmp1, u) */ * from tmp1 where u>101 order by u").Check(testkit.Rows(
"5 105 1005", "9 109 1009", "10 110 1010",
"12 112 1012", "3 113 1003", "14 114 1014", "16 116 1016", "7 117 1007", "18 118 1018",
))
if tk.Session().GetSessionVars().StmtCtx.CacheTableUsed() {
break
}
}
result = tk.MustQuery("explain format = 'brief' select /*+ use_index(tmp1, u) */ * from tmp1 where u>101 order by u")
result.Check(testkit.Rows("UnionScan 3333.33 root gt(test.tmp1.u, 101)",
"└─IndexLookUp 3333.33 root ",
" ├─IndexRangeScan(Build) 3333.33 cop[tikv] table:tmp1, index:u(u) range:(101,+inf], keep order:true, stats:pseudo",
" └─TableRowIDScan(Probe) 3333.33 cop[tikv] table:tmp1 keep order:false, stats:pseudo"))
tk.MustQuery("select /*+ use_index(tmp1, u) */ * from tmp1 where u>101 order by u").Check(testkit.Rows(
"5 105 1005", "9 109 1009", "10 110 1010",
"12 112 1012", "3 113 1003", "14 114 1014", "16 116 1016", "7 117 1007", "18 118 1018",
))
tk.MustQuery("show warnings").Check(testkit.Rows())

// For IndexReader
Expand All @@ -113,3 +133,35 @@ func TestCacheTableBasicScan(t *testing.T) {
assertSelect()

}

func TestCacheCondition(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t2")
tk.MustExec("create table t2 (id int primary key, v int)")
tk.MustExec("alter table t2 cache")

// Explain should not trigger cache.
tk.MustQuery("explain select * from t2")
require.False(t, tk.HasPlan("select * from t2 where id>0", "UnionScan"))

// Insert should not trigger cache.
tk.MustExec("insert into t2 values (1,1)")
require.False(t, tk.HasPlan("select * from t2 where id>0", "UnionScan"))

// Update should not trigger cache.
tk.MustExec("update t2 set v = v + 1 where id > 0")
require.False(t, tk.HasPlan("select * from t2 where id>0", "UnionScan"))

// Normal query should trigger cache.
tk.MustQuery("select * from t2")
var i int
for ; i < 10; i++ {
if tk.HasPlan("select * from t2 where id>0", "UnionScan") {
return
}
}
require.True(t, i < 10)
}