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

*: remove non-prepared plan cache #7040

Merged
merged 3 commits into from
Jul 13, 2018
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
6 changes: 0 additions & 6 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ type Config struct {
Status Status `toml:"status" json:"status"`
Performance Performance `toml:"performance" json:"performance"`
XProtocol XProtocol `toml:"xprotocol" json:"xprotocol"`
PlanCache PlanCache `toml:"plan-cache" json:"plan-cache"`
PreparedPlanCache PreparedPlanCache `toml:"prepared-plan-cache" json:"prepared-plan-cache"`
OpenTracing OpenTracing `toml:"opentracing" json:"opentracing"`
ProxyProtocol ProxyProtocol `toml:"proxy-protocol" json:"proxy-protocol"`
Expand Down Expand Up @@ -287,11 +286,6 @@ var defaultConf = Config{
Networks: "",
HeaderTimeout: 5,
},
PlanCache: PlanCache{
Enabled: false,
Capacity: 2560,
Shards: 256,
},
PreparedPlanCache: PreparedPlanCache{
Enabled: false,
Capacity: 100,
Expand Down
5 changes: 0 additions & 5 deletions config/config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,6 @@ networks = ""
# PROXY protocol header read timeout, unit is second
header-timeout = 5

[plan-cache]
enabled = false
capacity = 2560
shards = 256

[prepared-plan-cache]
enabled = false
capacity = 100
Expand Down
17 changes: 0 additions & 17 deletions executor/aggregate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
. "github.com/pingcap/check"
"github.com/pingcap/tidb/plan"
"github.com/pingcap/tidb/terror"
"github.com/pingcap/tidb/util/kvcache"
"github.com/pingcap/tidb/util/testkit"
)

Expand Down Expand Up @@ -550,22 +549,6 @@ func (s *testSuite) TestAggEliminator(c *C) {
tk.MustQuery("select min(b*b) from t").Check(testkit.Rows("1"))
}

func (s *testSuite) TestIssue5663(c *C) {
tk := testkit.NewTestKitWithInit(c, s.store)
plan.GlobalPlanCache = kvcache.NewShardedLRUCache(2, 1)
planCahche := tk.Se.GetSessionVars().PlanCacheEnabled
defer func() {
tk.Se.GetSessionVars().PlanCacheEnabled = planCahche
}()

tk.Se.GetSessionVars().PlanCacheEnabled = true
tk.MustExec("drop table if exists t1;")
tk.MustExec("create table t1 (i int unsigned, primary key(i));")
tk.MustExec("insert into t1 values (1),(2),(3);")
tk.MustQuery("select group_concat(i) from t1 where i > 1;").Check(testkit.Rows("2,3"))
tk.MustQuery("select group_concat(i) from t1 where i > 1;").Check(testkit.Rows("2,3"))
}

func (s *testSuite) TestMaxMinFloatScalaFunc(c *C) {
tk := testkit.NewTestKitWithInit(c, s.store)

Expand Down
87 changes: 0 additions & 87 deletions plan/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package plan
import (
"time"

"github.com/pingcap/tidb/ast"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/util/codec"
Expand All @@ -25,82 +24,12 @@ import (
)

var (
// GlobalPlanCache stores the global plan cache for every session in a tidb-server.
GlobalPlanCache *kvcache.ShardedLRUCache

// PreparedPlanCacheEnabled stores the global config "prepared-plan-cache-enabled".
PreparedPlanCacheEnabled bool
// PreparedPlanCacheCapacity stores the global config "prepared-plan-cache-capacity".
PreparedPlanCacheCapacity uint
)

type sqlCacheKey struct {
user string
host string
database string
sql string
snapshot uint64
schemaVersion int64
sqlMode mysql.SQLMode
timezoneOffset int
readOnly bool // stores the current tidb-server status.

hash []byte
}

// Hash implements Key interface.
func (key *sqlCacheKey) Hash() []byte {
if key.hash == nil {
var (
userBytes = hack.Slice(key.user)
hostBytes = hack.Slice(key.host)
dbBytes = hack.Slice(key.database)
sqlBytes = hack.Slice(key.sql)
bufferSize = len(userBytes) + len(hostBytes) + len(dbBytes) + len(sqlBytes) + 8*4 + 1
)

key.hash = make([]byte, 0, bufferSize)
key.hash = append(key.hash, userBytes...)
key.hash = append(key.hash, hostBytes...)
key.hash = append(key.hash, dbBytes...)
key.hash = append(key.hash, sqlBytes...)
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))
if key.readOnly {
key.hash = append(key.hash, '1')
} else {
key.hash = append(key.hash, '0')
}
}
return key.hash
}

// NewSQLCacheKey creates a new sqlCacheKey object.
func NewSQLCacheKey(sessionVars *variable.SessionVars, sql string, schemaVersion int64, readOnly bool) kvcache.Key {
timezoneOffset, user, host := 0, "", ""
if sessionVars.TimeZone != nil {
_, timezoneOffset = time.Now().In(sessionVars.TimeZone).Zone()
}
if sessionVars.User != nil {
user = sessionVars.User.Username
host = sessionVars.User.Hostname
}

return &sqlCacheKey{
user: user,
host: host,
database: sessionVars.CurrentDB,
sql: sql,
snapshot: sessionVars.SnapshotTS,
schemaVersion: schemaVersion,
sqlMode: sessionVars.SQLMode,
timezoneOffset: timezoneOffset,
readOnly: readOnly,
}
}

type pstmtPlanCacheKey struct {
database string
connID uint64
Expand Down Expand Up @@ -149,22 +78,6 @@ func NewPSTMTPlanCacheKey(sessionVars *variable.SessionVars, pstmtID uint32, sch
}
}

// SQLCacheValue stores the cached Statement and StmtNode.
type SQLCacheValue struct {
StmtNode ast.StmtNode
Plan Plan
Expensive bool
}

// NewSQLCacheValue creates a SQLCacheValue.
func NewSQLCacheValue(ast ast.StmtNode, plan Plan, expensive bool) *SQLCacheValue {
return &SQLCacheValue{
StmtNode: ast,
Plan: plan,
Expensive: expensive,
}
}

// PSTMTPlanCacheValue stores the cached Statement and StmtNode.
type PSTMTPlanCacheValue struct {
Plan Plan
Expand Down
6 changes: 2 additions & 4 deletions plan/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ func (s *testCacheSuite) SetUpSuite(c *C) {

func (s *testCacheSuite) TestCacheKey(c *C) {
defer testleak.AfterTest(c)()
key1 := NewSQLCacheKey(s.ctx.GetSessionVars(), "select * from t", 0, false)
c.Assert(key1.Hash(), DeepEquals, []byte{0x74, 0x65, 0x73, 0x74, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x2a, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30})
key2 := NewPSTMTPlanCacheKey(s.ctx.GetSessionVars(), 1, 1)
c.Assert(key2.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})
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})
}
95 changes: 27 additions & 68 deletions session/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -767,86 +767,45 @@ func (s *session) execute(ctx context.Context, sql string) (recordSets []ast.Rec
}

s.PrepareTxnCtx(ctx)
var (
cacheKey kvcache.Key
cacheValue kvcache.Value
hitCache = false
connID = s.sessionVars.ConnectionID
planCacheEnabled = s.sessionVars.PlanCacheEnabled // Its value is read from the global configuration, and it will be only updated in tests.
)
connID := s.sessionVars.ConnectionID
err = s.loadCommonGlobalVariablesIfNeeded()
if err != nil {
return nil, errors.Trace(err)
}

if planCacheEnabled {
schemaVersion := domain.GetDomain(s).InfoSchema().SchemaMetaVersion()
readOnly := s.Txn() == nil || s.Txn().IsReadOnly()
charsetInfo, collation := s.sessionVars.GetCharsetInfo()

cacheKey = plan.NewSQLCacheKey(s.sessionVars, sql, schemaVersion, readOnly)
cacheValue, hitCache = plan.GlobalPlanCache.Get(cacheKey)
// Step1: Compile query string to abstract syntax trees(ASTs).
startTS := time.Now()
stmtNodes, err := s.ParseSQL(ctx, sql, charsetInfo, collation)
if err != nil {
s.rollbackOnError(ctx)
log.Warnf("con:%d parse error:\n%v\n%s", connID, err, sql)
return nil, errors.Trace(err)
}
metrics.SessionExecuteParseDuration.Observe(time.Since(startTS).Seconds())

if hitCache {
metrics.PlanCacheCounter.WithLabelValues("select").Inc()
stmtNode := cacheValue.(*plan.SQLCacheValue).StmtNode
stmt := &executor.ExecStmt{
InfoSchema: executor.GetInfoSchema(s),
Plan: cacheValue.(*plan.SQLCacheValue).Plan,
Expensive: cacheValue.(*plan.SQLCacheValue).Expensive,
Text: stmtNode.Text(),
StmtNode: stmtNode,
Ctx: s,
}

compiler := executor.Compiler{Ctx: s}
for _, stmtNode := range stmtNodes {
s.PrepareTxnCtx(ctx)
if err = executor.ResetStmtCtx(s, stmtNode); err != nil {
return nil, errors.Trace(err)
}
if recordSets, err = s.executeStatement(ctx, connID, stmtNode, stmt, recordSets); err != nil {
return nil, errors.Trace(err)
}
} else {
err = s.loadCommonGlobalVariablesIfNeeded()
if err != nil {

// Step2: Transform abstract syntax tree to a physical plan(stored in executor.ExecStmt).
startTS = time.Now()
// Some executions are done in compile stage, so we reset them before compile.
if err := executor.ResetStmtCtx(s, stmtNode); err != nil {
return nil, errors.Trace(err)
}

charsetInfo, collation := s.sessionVars.GetCharsetInfo()

// Step1: Compile query string to abstract syntax trees(ASTs).
startTS := time.Now()
stmtNodes, err := s.ParseSQL(ctx, sql, charsetInfo, collation)
stmt, err := compiler.Compile(ctx, stmtNode)
if err != nil {
s.rollbackOnError(ctx)
log.Warnf("con:%d parse error:\n%v\n%s", connID, err, sql)
log.Warnf("con:%d compile error:\n%v\n%s", connID, err, sql)
return nil, errors.Trace(err)
}
metrics.SessionExecuteParseDuration.Observe(time.Since(startTS).Seconds())

compiler := executor.Compiler{Ctx: s}
for _, stmtNode := range stmtNodes {
s.PrepareTxnCtx(ctx)
metrics.SessionExecuteCompileDuration.Observe(time.Since(startTS).Seconds())

// Step2: Transform abstract syntax tree to a physical plan(stored in executor.ExecStmt).
startTS = time.Now()
// Some executions are done in compile stage, so we reset them before compile.
if err := executor.ResetStmtCtx(s, stmtNode); err != nil {
return nil, errors.Trace(err)
}
stmt, err := compiler.Compile(ctx, stmtNode)
if err != nil {
s.rollbackOnError(ctx)
log.Warnf("con:%d compile error:\n%v\n%s", connID, err, sql)
return nil, errors.Trace(err)
}
metrics.SessionExecuteCompileDuration.Observe(time.Since(startTS).Seconds())

// Step3: Cache the physical plan if possible.
if planCacheEnabled && stmt.Cacheable && len(stmtNodes) == 1 && !s.GetSessionVars().StmtCtx.HistogramsNotLoad() {
plan.GlobalPlanCache.Put(cacheKey, plan.NewSQLCacheValue(stmtNode, stmt.Plan, stmt.Expensive))
}

// Step4: Execute the physical plan.
if recordSets, err = s.executeStatement(ctx, connID, stmtNode, stmt, recordSets); err != nil {
return nil, errors.Trace(err)
}
// Step3: Execute the physical plan.
if recordSets, err = s.executeStatement(ctx, connID, stmtNode, stmt, recordSets); err != nil {
return nil, errors.Trace(err)
}
}

Expand Down
9 changes: 0 additions & 9 deletions session/session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/parser"
"github.com/pingcap/tidb/plan"
"github.com/pingcap/tidb/privilege/privileges"
"github.com/pingcap/tidb/session"
"github.com/pingcap/tidb/sessionctx"
Expand All @@ -38,7 +37,6 @@ import (
"github.com/pingcap/tidb/terror"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/auth"
"github.com/pingcap/tidb/util/kvcache"
"github.com/pingcap/tidb/util/sqlexec"
"github.com/pingcap/tidb/util/testkit"
"github.com/pingcap/tidb/util/testleak"
Expand Down Expand Up @@ -110,18 +108,11 @@ func (p *mockBinlogPump) PullBinlogs(ctx context.Context, in *binlog.PullBinlogR
}

func (s *testSessionSuite) TestForCoverage(c *C) {
plan.GlobalPlanCache = kvcache.NewShardedLRUCache(2, 1)

// Just for test coverage.
tk := testkit.NewTestKitWithInit(c, s.store)
planCache := tk.Se.GetSessionVars().PlanCacheEnabled
defer func() {
tk.Se.GetSessionVars().PlanCacheEnabled = planCache
}()
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (id int auto_increment, v int, index (id))")
tk.MustExec("insert t values ()")
tk.Se.GetSessionVars().PlanCacheEnabled = true
tk.MustExec("insert t values ()")
tk.MustExec("insert t values ()")

Expand Down
4 changes: 0 additions & 4 deletions sessionctx/variable/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,6 @@ type SessionVars struct {
// PlanID is the unique id of logical and physical plan.
PlanID int

// PlanCacheEnabled stores the global config "plan-cache-enabled", and it will be only updated in tests.
PlanCacheEnabled bool

// User is the user identity with which the session login.
User *auth.UserIdentity

Expand Down Expand Up @@ -341,7 +338,6 @@ func NewSessionVars() *SessionVars {
} else {
enableStreaming = "0"
}
vars.PlanCacheEnabled = config.GetGlobalConfig().PlanCache.Enabled
terror.Log(vars.SetSystemVar(TiDBEnableStreaming, enableStreaming))
return vars
}
Expand Down
5 changes: 0 additions & 5 deletions tidb-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ import (
"github.com/pingcap/tidb/store/tikv/gcworker"
"github.com/pingcap/tidb/terror"
"github.com/pingcap/tidb/util"
"github.com/pingcap/tidb/util/kvcache"
"github.com/pingcap/tidb/util/logutil"
"github.com/pingcap/tidb/util/printer"
"github.com/pingcap/tidb/util/systimemon"
Expand Down Expand Up @@ -380,10 +379,6 @@ func setGlobalVars() {
plan.AllowCartesianProduct = cfg.Performance.CrossJoin
privileges.SkipWithGrant = cfg.Security.SkipGrantTable

if cfg.PlanCache.Enabled {
plan.GlobalPlanCache = kvcache.NewShardedLRUCache(cfg.PlanCache.Capacity, cfg.PlanCache.Shards)
}

plan.PreparedPlanCacheEnabled = cfg.PreparedPlanCache.Enabled
if plan.PreparedPlanCacheEnabled {
plan.PreparedPlanCacheCapacity = cfg.PreparedPlanCache.Capacity
Expand Down
Loading