442 lines
18 KiB
Go
442 lines
18 KiB
Go
// Copyright 2021 PingCAP, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package tables_test
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/pingcap/tidb/infoschema"
|
|
"github.com/pingcap/tidb/parser/model"
|
|
"github.com/pingcap/tidb/table/tables"
|
|
"github.com/pingcap/tidb/testkit"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestCacheTableBasicScan(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 tmp1")
|
|
tk.MustExec("create table tmp1 (id int primary key auto_increment, u int unique, v int)")
|
|
tk.MustExec("insert into tmp1 values" +
|
|
"(1, 101, 1001), (3, 113, 1003), (5, 105, 1005), (7, 117, 1007), (9, 109, 1009)," +
|
|
"(10, 110, 1010), (12, 112, 1012), (14, 114, 1014), (16, 116, 1016), (18, 118, 1018)",
|
|
)
|
|
tk.MustExec("alter table tmp1 cache")
|
|
assertSelect := func() {
|
|
// For TableReader
|
|
// First read will read from original table
|
|
tk.MustQuery("select * from tmp1 where id>3 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",
|
|
))
|
|
// Test for join two cache table
|
|
tk.MustExec("drop table if exists join_t1, join_t2, join_t3")
|
|
tk.MustExec("create table join_t1 (id int)")
|
|
tk.MustExec("insert into join_t1 values(1)")
|
|
tk.MustExec("alter table join_t1 cache")
|
|
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.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)")
|
|
planUsed := false
|
|
for i := 0; i < 10; i++ {
|
|
tk.MustQuery("select *from join_t1 join join_t2").Check(testkit.Rows("1 2"))
|
|
if tk.HasPlan("select *from join_t1 join join_t2", "UnionScan") {
|
|
planUsed = true
|
|
break
|
|
}
|
|
}
|
|
require.True(t, planUsed)
|
|
result := tk.MustQuery("explain format = 'brief' select *from join_t1 join join_t2")
|
|
result.Check(testkit.Rows(
|
|
"HashJoin 100000000.00 root CARTESIAN inner join",
|
|
"├─UnionScan(Build) 10000.00 root ",
|
|
"│ └─TableReader 10000.00 root data:TableFullScan",
|
|
"│ └─TableFullScan 10000.00 cop[tikv] table:join_t2 keep order:false, stats:pseudo",
|
|
"└─UnionScan(Probe) 10000.00 root ",
|
|
" └─TableReader 10000.00 root data:TableFullScan",
|
|
" └─TableFullScan 10000.00 cop[tikv] table:join_t1 keep order:false, stats:pseudo"))
|
|
// 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.HasPlan("select *from join_t1 join join_t3", "UnionScan") {
|
|
planUsed = true
|
|
break
|
|
}
|
|
}
|
|
require.True(t, planUsed)
|
|
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",
|
|
"└─HashJoin 100000000.00 root CARTESIAN inner join",
|
|
" ├─UnionScan(Build) 10000.00 root ",
|
|
" │ └─TableReader 10000.00 root data:TableFullScan",
|
|
" │ └─TableFullScan 10000.00 cop[tikv] table:join_t1 keep order:false, stats:pseudo",
|
|
" └─TableReader(Probe) 10000.00 root data:TableFullScan",
|
|
" └─TableFullScan 10000.00 cop[tikv] table:join_t3 keep order:false, stats:pseudo"))
|
|
|
|
// Second read will from cache table
|
|
for i := 0; i < 100; 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.HasPlan("select * from tmp1 where id>4 order by id", "UnionScan") {
|
|
planUsed = true
|
|
break
|
|
}
|
|
}
|
|
require.True(t, planUsed)
|
|
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"))
|
|
// 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.HasPlan("select /*+ use_index(tmp1, u) */ * from tmp1 where u>101 order by u", "UnionScan") {
|
|
planUsed = true
|
|
break
|
|
}
|
|
}
|
|
require.True(t, planUsed)
|
|
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("show warnings").Check(testkit.Rows())
|
|
|
|
// For IndexReader
|
|
tk.MustQuery("select /*+ use_index(tmp1, u) */ id,u from tmp1 where u>101 order by id").Check(testkit.Rows(
|
|
"3 113", "5 105", "7 117", "9 109", "10 110",
|
|
"12 112", "14 114", "16 116", "18 118",
|
|
))
|
|
tk.MustQuery("show warnings").Check(testkit.Rows())
|
|
|
|
// For IndexMerge, cache table should not use index merge
|
|
tk.MustQuery("select /*+ use_index_merge(tmp1, primary, u) */ * from tmp1 where id>5 or u>110 order by u").Check(testkit.Rows(
|
|
"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("Warning 1105 IndexMerge is inapplicable or disabled"))
|
|
}
|
|
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")
|
|
for i := 0; i < 10; i++ {
|
|
time.Sleep(100 * time.Millisecond)
|
|
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)")
|
|
for i := 0; i < 10; i++ {
|
|
time.Sleep(100 * time.Millisecond)
|
|
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")
|
|
for i := 0; i < 10; i++ {
|
|
time.Sleep(100 * time.Millisecond)
|
|
require.False(t, tk.HasPlan("select * from t2 where id>0", "UnionScan"))
|
|
}
|
|
// Contains PointGet Update should not trigger cache.
|
|
tk.MustExec("update t2 set v = v + 1 where id = 2")
|
|
for i := 0; i < 10; i++ {
|
|
time.Sleep(100 * time.Millisecond)
|
|
require.False(t, tk.HasPlan("select * from t2 where id>0", "UnionScan"))
|
|
}
|
|
|
|
// Contains PointGet Delete should not trigger cache.
|
|
tk.MustExec("delete from t2 where id = 2")
|
|
for i := 0; i < 10; i++ {
|
|
time.Sleep(100 * time.Millisecond)
|
|
require.False(t, tk.HasPlan("select * from t2 where id>0", "UnionScan"))
|
|
}
|
|
|
|
// Normal query should trigger cache.
|
|
tk.MustQuery("select * from t2")
|
|
for !tk.HasPlan("select * from t2 where id>0", "UnionScan") {
|
|
tk.MustExec("select * from t2")
|
|
}
|
|
}
|
|
|
|
func TestCacheTableBasicReadAndWrite(t *testing.T) {
|
|
store, clean := testkit.CreateMockStore(t)
|
|
defer clean()
|
|
tk := testkit.NewTestKit(t, store)
|
|
tk.MustExec("use test")
|
|
tk1 := testkit.NewTestKit(t, store)
|
|
tk1.MustExec("use test")
|
|
tk.MustExec("drop table if exists write_tmp1")
|
|
tk.MustExec("create table write_tmp1 (id int primary key auto_increment, u int unique, v int)")
|
|
tk.MustExec("insert into write_tmp1 values" +
|
|
"(1, 101, 1001), (3, 113, 1003)",
|
|
)
|
|
|
|
tk.MustExec("alter table write_tmp1 cache")
|
|
// Read and add read lock
|
|
tk.MustQuery("select *from write_tmp1").Check(testkit.Rows("1 101 1001",
|
|
"3 113 1003"))
|
|
// read lock should valid
|
|
for i := 0; i < 10; i++ {
|
|
if tk.HasPlan("select *from write_tmp1", "UnionScan") {
|
|
break
|
|
}
|
|
}
|
|
tk.MustExec("use test")
|
|
tk1.MustExec("insert into write_tmp1 values (2, 222, 222)")
|
|
// write lock exists
|
|
require.False(t, tk.HasPlan("select *from write_tmp1", "UnionScan"))
|
|
// wait write lock expire and check cache can be used again
|
|
for !tk.HasPlan("select *from write_tmp1", "UnionScan") {
|
|
tk.MustExec("select *from write_tmp1")
|
|
}
|
|
tk.MustQuery("select *from write_tmp1").Check(testkit.Rows("1 101 1001", "2 222 222", "3 113 1003"))
|
|
tk1.MustExec("update write_tmp1 set v = 3333 where id = 2")
|
|
for !tk.HasPlan("select *from write_tmp1", "UnionScan") {
|
|
tk.MustExec("select *from write_tmp1")
|
|
}
|
|
tk.MustQuery("select *from write_tmp1").Check(testkit.Rows("1 101 1001", "2 222 3333", "3 113 1003"))
|
|
}
|
|
|
|
func TestCacheTableComplexRead(t *testing.T) {
|
|
store, clean := testkit.CreateMockStore(t)
|
|
defer clean()
|
|
doneCh := make(chan struct{}, 1)
|
|
tk1 := testkit.NewTestKit(t, store)
|
|
tk2 := testkit.NewTestKit(t, store)
|
|
tk1.MustExec("use test")
|
|
tk2.MustExec("use test")
|
|
tk1.MustExec("create table complex_cache (id int primary key auto_increment, u int unique, v int)")
|
|
tk1.MustExec("insert into complex_cache values" + "(5, 105, 1005), (7, 117, 1007), (9, 109, 1009)")
|
|
tk1.MustExec("alter table complex_cache cache")
|
|
tk1.MustExec("begin")
|
|
tk1.MustQuery("select *from complex_cache where id > 7").Check(testkit.Rows("9 109 1009"))
|
|
|
|
go func() {
|
|
tk2.MustExec("begin")
|
|
tk2.MustQuery("select *from complex_cache where id > 7").Check(testkit.Rows("9 109 1009"))
|
|
var i int
|
|
for i = 0; i < 10; i++ {
|
|
time.Sleep(100 * time.Millisecond)
|
|
if tk2.HasPlan("select *from complex_cache where id > 7", "UnionScan") {
|
|
break
|
|
}
|
|
}
|
|
require.True(t, i < 10)
|
|
tk2.MustExec("commit")
|
|
doneCh <- struct{}{}
|
|
}()
|
|
<-doneCh
|
|
tk1.HasPlan("select *from complex_cache where id > 7", "UnionScan")
|
|
tk1.MustExec("commit")
|
|
}
|
|
|
|
func TestBeginSleepABA(t *testing.T) {
|
|
// During the change "cache1 -> no cache -> cache2",
|
|
// cache1 and cache2 may be not the same anymore
|
|
// A transaction should not only check the cache exists, but also check the cache unchanged.
|
|
|
|
store, clean := testkit.CreateMockStore(t)
|
|
defer clean()
|
|
tk1 := testkit.NewTestKit(t, store)
|
|
tk2 := testkit.NewTestKit(t, store)
|
|
tk1.MustExec("use test")
|
|
tk2.MustExec("use test")
|
|
tk1.MustExec("drop table if exists aba")
|
|
tk1.MustExec("create table aba (id int, v int)")
|
|
tk1.MustExec("insert into aba values (1, 1)")
|
|
tk1.MustExec("alter table aba cache")
|
|
tk1.MustQuery("select * from aba").Check(testkit.Rows("1 1"))
|
|
|
|
// Begin, read from cache.
|
|
tk1.MustExec("begin")
|
|
cacheUsed := false
|
|
for i := 0; i < 100; i++ {
|
|
if tk1.HasPlan("select * from aba", "UnionScan") {
|
|
cacheUsed = true
|
|
break
|
|
}
|
|
}
|
|
require.True(t, cacheUsed)
|
|
|
|
// Another session change the data and make the cache unavailable.
|
|
tk2.MustExec("update aba set v = 2")
|
|
|
|
// And then make the cache available again.
|
|
for i := 0; i < 50; i++ {
|
|
tk2.MustQuery("select * from aba").Check(testkit.Rows("1 2"))
|
|
if tk2.HasPlan("select * from aba", "UnionScan") {
|
|
cacheUsed = true
|
|
break
|
|
}
|
|
time.Sleep(100 * time.Millisecond)
|
|
}
|
|
require.True(t, cacheUsed)
|
|
|
|
// tk1 should not use the staled cache, because the data is changed.
|
|
require.False(t, tk1.HasPlan("select * from aba", "UnionScan"))
|
|
}
|
|
|
|
func TestCacheTablePointGet(t *testing.T) {
|
|
store, clean := testkit.CreateMockStore(t)
|
|
defer clean()
|
|
tk := testkit.NewTestKit(t, store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("create table cache_point (id int primary key auto_increment, u int unique, v int)")
|
|
tk.MustExec("insert into cache_point values(1, 11, 101)")
|
|
tk.MustExec("insert into cache_point values(2, 12, 102)")
|
|
tk.MustExec("alter table cache_point cache")
|
|
// check point get out transaction
|
|
tk.MustQuery("select * from cache_point where id=1").Check(testkit.Rows("1 11 101"))
|
|
tk.MustQuery("select * from cache_point where u=11").Check(testkit.Rows("1 11 101"))
|
|
tk.MustQuery("select * from cache_point where id=2").Check(testkit.Rows("2 12 102"))
|
|
tk.MustQuery("select * from cache_point where u=12").Check(testkit.Rows("2 12 102"))
|
|
tk.MustQuery("select * from cache_point where u > 10 and u < 12").Check(testkit.Rows("1 11 101"))
|
|
|
|
// check point get in transaction
|
|
tk.MustExec("begin")
|
|
tk.MustQuery("select * from cache_point where id=1").Check(testkit.Rows("1 11 101"))
|
|
tk.MustQuery("select * from cache_point where u=11").Check(testkit.Rows("1 11 101"))
|
|
tk.MustQuery("select * from cache_point where id=2").Check(testkit.Rows("2 12 102"))
|
|
tk.MustQuery("select * from cache_point where u=12").Check(testkit.Rows("2 12 102"))
|
|
tk.MustExec("insert into cache_point values(3, 13, 103)")
|
|
tk.MustQuery("select * from cache_point where id=3").Check(testkit.Rows("3 13 103"))
|
|
tk.MustQuery("select * from cache_point where u=13").Check(testkit.Rows("3 13 103"))
|
|
tk.MustQuery("select * from cache_point where u > 12 and u < 14").Check(testkit.Rows("3 13 103"))
|
|
tk.MustExec("update cache_point set v=999 where id=2")
|
|
tk.MustQuery("select * from cache_point where id=2").Check(testkit.Rows("2 12 999"))
|
|
tk.MustExec("commit")
|
|
|
|
// check point get after transaction
|
|
tk.MustQuery("select * from cache_point where id=3").Check(testkit.Rows("3 13 103"))
|
|
tk.MustQuery("select * from cache_point where u=13").Check(testkit.Rows("3 13 103"))
|
|
tk.MustQuery("select * from cache_point where id=2").Check(testkit.Rows("2 12 999"))
|
|
}
|
|
|
|
func TestCacheTableBatchPointGet(t *testing.T) {
|
|
store, clean := testkit.CreateMockStore(t)
|
|
defer clean()
|
|
tk := testkit.NewTestKit(t, store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("create table bp_cache_tmp1 (id int primary key auto_increment, u int unique, v int)")
|
|
tk.MustExec("insert into bp_cache_tmp1 values(1, 11, 101)")
|
|
tk.MustExec("insert into bp_cache_tmp1 values(2, 12, 102)")
|
|
tk.MustExec("insert into bp_cache_tmp1 values(3, 13, 103)")
|
|
tk.MustExec("insert into bp_cache_tmp1 values(4, 14, 104)")
|
|
tk.MustExec("alter table bp_cache_tmp1 cache")
|
|
// check point get out transaction
|
|
tk.MustQuery("select * from bp_cache_tmp1 where id in (1, 3)").Check(testkit.Rows("1 11 101", "3 13 103"))
|
|
tk.MustQuery("select * from bp_cache_tmp1 where u in (11, 13)").Check(testkit.Rows("1 11 101", "3 13 103"))
|
|
tk.MustQuery("select * from bp_cache_tmp1 where id in (1, 3, 5)").Check(testkit.Rows("1 11 101", "3 13 103"))
|
|
tk.MustQuery("select * from bp_cache_tmp1 where u in (11, 13, 15)").Check(testkit.Rows("1 11 101", "3 13 103"))
|
|
tk.MustQuery("select * from bp_cache_tmp1 where u in (11, 13) and u in (12, 13)").Check(testkit.Rows("3 13 103"))
|
|
// check point get in transaction
|
|
tk.MustExec("begin")
|
|
tk.MustQuery("select * from bp_cache_tmp1 where id in (1, 3)").Check(testkit.Rows("1 11 101", "3 13 103"))
|
|
tk.MustQuery("select * from bp_cache_tmp1 where u in (11, 13)").Check(testkit.Rows("1 11 101", "3 13 103"))
|
|
tk.MustQuery("select * from bp_cache_tmp1 where id in (1, 3, 5)").Check(testkit.Rows("1 11 101", "3 13 103"))
|
|
tk.MustQuery("select * from bp_cache_tmp1 where u in (11, 13, 15)").Check(testkit.Rows("1 11 101", "3 13 103"))
|
|
tk.MustExec("insert into bp_cache_tmp1 values(6, 16, 106)")
|
|
tk.MustQuery("select * from bp_cache_tmp1 where id in (1, 6)").Check(testkit.Rows("1 11 101", "6 16 106"))
|
|
tk.MustQuery("select * from bp_cache_tmp1 where u in (11, 16)").Check(testkit.Rows("1 11 101", "6 16 106"))
|
|
tk.MustExec("update bp_cache_tmp1 set v=999 where id=3")
|
|
tk.MustQuery("select * from bp_cache_tmp1 where id in (1, 3)").Check(testkit.Rows("1 11 101", "3 13 999"))
|
|
tk.MustQuery("select * from bp_cache_tmp1 where u in (11, 13)").Check(testkit.Rows("1 11 101", "3 13 999"))
|
|
tk.MustQuery("select * from bp_cache_tmp1 where u in (11, 13) and u in (12, 13)").Check(testkit.Rows("3 13 999"))
|
|
tk.MustExec("delete from bp_cache_tmp1 where id=4")
|
|
tk.MustQuery("select * from bp_cache_tmp1 where id in (1, 4)").Check(testkit.Rows("1 11 101"))
|
|
tk.MustQuery("select * from bp_cache_tmp1 where u in (11, 14)").Check(testkit.Rows("1 11 101"))
|
|
tk.MustExec("commit")
|
|
|
|
// check point get after transaction
|
|
tk.MustQuery("select * from bp_cache_tmp1 where id in (1, 3, 6)").Check(testkit.Rows("1 11 101", "3 13 999", "6 16 106"))
|
|
tk.MustQuery("select * from bp_cache_tmp1 where u in (11, 13, 16)").Check(testkit.Rows("1 11 101", "3 13 999", "6 16 106"))
|
|
tk.MustQuery("select * from bp_cache_tmp1 where id in (1, 4)").Check(testkit.Rows("1 11 101"))
|
|
tk.MustQuery("select * from bp_cache_tmp1 where u in (11, 14)").Check(testkit.Rows("1 11 101"))
|
|
}
|
|
|
|
func TestRenewLease(t *testing.T) {
|
|
// Test RenewLeaseForRead
|
|
store, clean := testkit.CreateMockStore(t)
|
|
defer clean()
|
|
tk := testkit.NewTestKit(t, store)
|
|
tk.MustExec("use test")
|
|
se := tk.Session()
|
|
tk.MustExec("create table cache_renew_t (id int)")
|
|
tk.MustExec("alter table cache_renew_t cache")
|
|
tbl, err := se.GetInfoSchema().(infoschema.InfoSchema).TableByName(model.NewCIStr("test"), model.NewCIStr("cache_renew_t"))
|
|
require.NoError(t, err)
|
|
var i int
|
|
tk.MustExec("select * from cache_renew_t")
|
|
_, oldLease, _ := tables.MockStateRemote.Data.Load(tbl.Meta().ID)
|
|
for i = 0; i < 20; i++ {
|
|
time.Sleep(200 * time.Millisecond)
|
|
tk.MustExec("select * from cache_renew_t")
|
|
_, lease, _ := tables.MockStateRemote.Data.Load(tbl.Meta().ID)
|
|
if lease != oldLease {
|
|
break
|
|
}
|
|
}
|
|
require.True(t, i < 20)
|
|
}
|
|
|
|
func TestCacheTableWriteOperatorWaitLockLease(t *testing.T) {
|
|
store, clean := testkit.CreateMockStore(t)
|
|
defer clean()
|
|
tk := testkit.NewTestKit(t, store)
|
|
tk.MustExec("use test")
|
|
se := tk.Session()
|
|
tk.MustExec("drop table if exists wait_tb1")
|
|
tk.MustExec("create table wait_tb1(id int)")
|
|
tk.MustExec("alter table wait_tb1 cache")
|
|
tk.MustExec("select *from wait_tb1")
|
|
var i int
|
|
for i = 0; i < 10; i++ {
|
|
time.Sleep(100 * time.Millisecond)
|
|
if tk.HasPlan("select *from wait_tb1", "UnionScan") {
|
|
break
|
|
}
|
|
}
|
|
require.True(t, i < 10)
|
|
tk.MustExec("insert into wait_tb1 values(1)")
|
|
require.True(t, se.GetSessionVars().StmtCtx.WaitLockLeaseTime > 0)
|
|
}
|