Skip to content

Commit

Permalink
cherry pick #22568 to release-4.0 (#22641)
Browse files Browse the repository at this point in the history
Signed-off-by: ti-srebot <[email protected]>

Co-authored-by: Kenan Yao <[email protected]>
  • Loading branch information
ti-srebot and eurekaka committed Mar 1, 2021
1 parent 17f20a7 commit 66d97de
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 8 deletions.
8 changes: 4 additions & 4 deletions executor/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1315,11 +1315,11 @@ func (b *executorBuilder) getSnapshotTS() (uint64, error) {
}

snapshotTS := b.ctx.GetSessionVars().SnapshotTS
txn, err := b.ctx.Txn(true)
if err != nil {
return 0, err
}
if snapshotTS == 0 {
txn, err := b.ctx.Txn(true)
if err != nil {
return 0, err
}
snapshotTS = txn.StartTS()
}
b.snapshotTS = snapshotTS
Expand Down
3 changes: 0 additions & 3 deletions planner/core/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ type pstmtPlanCacheKey struct {
database string
connID uint64
pstmtID uint32
snapshot uint64
schemaVersion int64
sqlMode mysql.SQLMode
timezoneOffset int
Expand All @@ -90,7 +89,6 @@ func (key *pstmtPlanCacheKey) Hash() []byte {
key.hash = append(key.hash, dbBytes...)
key.hash = codec.EncodeInt(key.hash, int64(key.connID))
key.hash = codec.EncodeInt(key.hash, int64(key.pstmtID))
key.hash = codec.EncodeInt(key.hash, int64(key.snapshot))
key.hash = codec.EncodeInt(key.hash, key.schemaVersion)
key.hash = codec.EncodeInt(key.hash, int64(key.sqlMode))
key.hash = codec.EncodeInt(key.hash, int64(key.timezoneOffset))
Expand Down Expand Up @@ -134,7 +132,6 @@ func NewPSTMTPlanCacheKey(sessionVars *variable.SessionVars, pstmtID uint32, sch
database: sessionVars.CurrentDB,
connID: sessionVars.ConnectionID,
pstmtID: pstmtID,
snapshot: sessionVars.SnapshotTS,
schemaVersion: schemaVersion,
sqlMode: sessionVars.SQLMode,
timezoneOffset: timezoneOffset,
Expand Down
2 changes: 1 addition & 1 deletion planner/core/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ func (s *testCacheSuite) SetUpSuite(c *C) {
func (s *testCacheSuite) TestCacheKey(c *C) {
defer testleak.AfterTest(c)()
key := NewPSTMTPlanCacheKey(s.ctx.GetSessionVars(), 1, 1)
c.Assert(key.Hash(), DeepEquals, []byte{0x74, 0x65, 0x73, 0x74, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x74, 0x69, 0x64, 0x62, 0x74, 0x69, 0x6b, 0x76, 0x74, 0x69, 0x66, 0x6c, 0x61, 0x73, 0x68})
c.Assert(key.Hash(), DeepEquals, []byte{0x74, 0x65, 0x73, 0x74, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x74, 0x69, 0x64, 0x62, 0x74, 0x69, 0x6b, 0x76, 0x74, 0x69, 0x66, 0x6c, 0x61, 0x73, 0x68})
}
50 changes: 50 additions & 0 deletions planner/core/prepare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -893,3 +893,53 @@ func (s *testPrepareSerialSuite) TestPrepareCacheWithJoinTable(c *C) {
tk.MustQuery("execute stmt using @a").Check(testkit.Rows())
tk.MustQuery("execute stmt using @b").Check(testkit.Rows("a <nil> <nil>"))
}

func (s *testPlanSerialSuite) TestPlanCacheSnapshot(c *C) {
store, _, err := newStoreWithBootstrap()
c.Assert(err, IsNil)
tk := testkit.NewTestKit(c, store)
orgEnable := core.PreparedPlanCacheEnabled()
defer func() {
store.Close()
core.SetPreparedPlanCache(orgEnable)
}()
core.SetPreparedPlanCache(true)

tk.Se, err = session.CreateSession4TestWithOpt(store, &session.Opt{
PreparedPlanCache: kvcache.NewSimpleLRUCache(100, 0.1, math.MaxUint64),
})
c.Assert(err, IsNil)

tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(id int)")
tk.MustExec("insert into t values (1),(2),(3),(4)")

// For mocktikv, safe point is not initialized, we manually insert it for snapshot to use.
timeSafe := time.Now().Add(-48 * 60 * 60 * time.Second).Format("20060102-15:04:05 -0700 MST")
safePointSQL := `INSERT HIGH_PRIORITY INTO mysql.tidb VALUES ('tikv_gc_safe_point', '%[1]s', '')
ON DUPLICATE KEY
UPDATE variable_value = '%[1]s'`
tk.MustExec(fmt.Sprintf(safePointSQL, timeSafe))

tk.MustExec("prepare stmt from 'select * from t where id=?'")
tk.MustExec("set @p = 1")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
tk.MustQuery("execute stmt using @p").Check(testkit.Rows("1"))
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
tk.MustQuery("execute stmt using @p").Check(testkit.Rows("1"))
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

// Record the current tso.
tk.MustExec("begin")
tso := tk.Se.GetSessionVars().TxnCtx.StartTS
tk.MustExec("rollback")
c.Assert(tso > 0, IsTrue)
// Insert one more row with id = 1.
tk.MustExec("insert into t values (1)")

tk.MustExec(fmt.Sprintf("set @@tidb_snapshot = '%d'", tso))
tk.MustQuery("select * from t where id = 1").Check(testkit.Rows("1"))
tk.MustQuery("execute stmt using @p").Check(testkit.Rows("1"))
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
}

0 comments on commit 66d97de

Please sign in to comment.