Skip to content

Commit

Permalink
sessionctx: add some information about the rewriting phase into the s…
Browse files Browse the repository at this point in the history
…low log (#17569)
  • Loading branch information
qw4990 authored Jun 9, 2020
1 parent 88dfb22 commit 0ec197f
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 3 deletions.
1 change: 1 addition & 0 deletions executor/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,7 @@ func (a *ExecStmt) LogSlowQuery(txnTS uint64, succ bool, hasMoreResults bool) {
Prepared: a.isPreparedStmt,
HasMoreResults: hasMoreResults,
PlanFromCache: sessVars.FoundInPlanCache,
RewriteInfo: sessVars.RewritePhaseInfo,
}
if _, ok := a.StmtNode.(*ast.CommitStmt); ok {
slowItems.PrevStmt = sessVars.PrevStmt.String()
Expand Down
6 changes: 6 additions & 0 deletions executor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,12 @@ func init() {
// but the plan package cannot import the executor package because of the dependency cycle.
// So we assign a function implemented in the executor package to the plan package to avoid the dependency cycle.
plannercore.EvalSubqueryFirstRow = func(ctx context.Context, p plannercore.PhysicalPlan, is infoschema.InfoSchema, sctx sessionctx.Context) ([]types.Datum, error) {
defer func(begin time.Time) {
s := sctx.GetSessionVars()
s.RewritePhaseInfo.PreprocessSubQueries++
s.RewritePhaseInfo.DurationPreprocessSubQuery += time.Since(begin)
}(time.Now())

if span := opentracing.SpanFromContext(ctx); span != nil && span.Tracer() != nil {
span1 := span.Tracer().StartSpan("executor.EvalSubQuery", opentracing.ChildOf(span.Context()))
defer span1.Finish()
Expand Down
12 changes: 12 additions & 0 deletions executor/slow_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,9 @@ type slowQueryTuple struct {
queryTime float64
parseTime float64
compileTime float64
rewriteTime float64
preprocSubqueries uint64
preprocSubQueryTime float64
preWriteTime float64
waitPrewriteBinlogTime float64
commitTime float64
Expand Down Expand Up @@ -467,6 +470,12 @@ func (st *slowQueryTuple) setFieldValue(tz *time.Location, field, value string,
st.sql = value
case variable.SlowLogDiskMax:
st.diskMax, err = strconv.ParseInt(value, 10, 64)
case variable.SlowLogRewriteTimeStr:
st.rewriteTime, err = strconv.ParseFloat(value, 64)
case variable.SlowLogPreprocSubQueriesStr:
st.preprocSubqueries, err = strconv.ParseUint(value, 10, 64)
case variable.SlowLogPreProcSubQueryTimeStr:
st.preprocSubQueryTime, err = strconv.ParseFloat(value, 64)
}
if err != nil {
return valid, errors.Wrap(err, "Parse slow log at line "+strconv.FormatInt(int64(lineNum), 10)+" failed. Field: `"+field+"`, error")
Expand All @@ -484,6 +493,9 @@ func (st *slowQueryTuple) convertToDatumRow() []types.Datum {
record = append(record, types.NewFloat64Datum(st.queryTime))
record = append(record, types.NewFloat64Datum(st.parseTime))
record = append(record, types.NewFloat64Datum(st.compileTime))
record = append(record, types.NewFloat64Datum(st.rewriteTime))
record = append(record, types.NewUintDatum(st.preprocSubqueries))
record = append(record, types.NewFloat64Datum(st.preprocSubQueryTime))
record = append(record, types.NewFloat64Datum(st.preWriteTime))
record = append(record, types.NewFloat64Datum(st.waitPrewriteBinlogTime))
record = append(record, types.NewFloat64Datum(st.commitTime))
Expand Down
2 changes: 1 addition & 1 deletion executor/slow_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ select * from t;`
}
recordString += str
}
expectRecordString := "2019-04-28 15:24:04.309074,405888132465033227,,,0,0.216905,0,0,0,0,0,0,0,,0,0,0,0,0,0,0.38,0.021,0,0,0,1,637,0,,,1,42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772,t1:1,t2:2,0.1,0.2,0.03,127.0.0.1:20160,0.05,0.6,0.8,0.0.0.0:20160,70724,65536,0,1,,60e9378c746d9a2be1c791047e008967cf252eb6de9167ad3aa6098fa2d523f4,update t set i = 1;,select * from t;"
expectRecordString := "2019-04-28 15:24:04.309074,405888132465033227,,,0,0.216905,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,0,0,0.38,0.021,0,0,0,1,637,0,,,1,42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772,t1:1,t2:2,0.1,0.2,0.03,127.0.0.1:20160,0.05,0.6,0.8,0.0.0.0:20160,70724,65536,0,1,,60e9378c746d9a2be1c791047e008967cf252eb6de9167ad3aa6098fa2d523f4,update t set i = 1;,select * from t;"
c.Assert(expectRecordString, Equals, recordString)

// fix sql contain '# ' bug
Expand Down
3 changes: 3 additions & 0 deletions infoschema/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,9 @@ var slowQueryCols = []columnInfo{
{name: variable.SlowLogQueryTimeStr, tp: mysql.TypeDouble, size: 22},
{name: variable.SlowLogParseTimeStr, tp: mysql.TypeDouble, size: 22},
{name: variable.SlowLogCompileTimeStr, tp: mysql.TypeDouble, size: 22},
{name: variable.SlowLogRewriteTimeStr, tp: mysql.TypeDouble, size: 22},
{name: variable.SlowLogPreprocSubQueriesStr, tp: mysql.TypeLonglong, size: 20, flag: mysql.UnsignedFlag},
{name: variable.SlowLogPreProcSubQueryTimeStr, tp: mysql.TypeDouble, size: 22},
{name: execdetails.PreWriteTimeStr, tp: mysql.TypeDouble, size: 22},
{name: execdetails.WaitPrewriteBinlogTimeStr, tp: mysql.TypeDouble, size: 22},
{name: execdetails.CommitTimeStr, tp: mysql.TypeDouble, size: 22},
Expand Down
5 changes: 3 additions & 2 deletions infoschema/tables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@ func prepareSlowLogfile(c *C, slowLogFileName string) {
# Query_time: 4.895492
# Parse_time: 0.4
# Compile_time: 0.2
# Rewrite_time: 0.000000003 Preproc_subqueries: 2 Preproc_subqueries_time: 0.000000002
# LockKeys_time: 1.71 Request_count: 1 Prewrite_time: 0.19 Wait_prewrite_binlog_time: 0.21 Commit_time: 0.01 Commit_backoff_time: 0.18 Backoff_types: [txnLock] Resolve_lock_time: 0.03 Write_keys: 15 Write_size: 480 Prewrite_region: 1 Txn_retry: 8
# Cop_time: 0.3824278 Process_time: 0.161 Request_count: 1 Total_keys: 100001 Process_keys: 100000
# Wait_time: 0.101
Expand Down Expand Up @@ -620,10 +621,10 @@ func (s *testTableSuite) TestSlowQuery(c *C) {
tk.MustExec("set time_zone = '+08:00';")
re := tk.MustQuery("select * from information_schema.slow_query")
re.Check(testutil.RowsWithSep("|",
"2019-02-12 19:33:56.571953|406315658548871171|root|127.0.0.1|6|4.895492|0.4|0.2|0.19|0.21|0.01|0|0.18|[txnLock]|0.03|0|15|480|1|8|0.3824278|0.161|0.101|0.092|1.71|1|100001|100000|test||0|42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772|t1:1,t2:2|0.1|0.2|0.03|127.0.0.1:20160|0.05|0.6|0.8|0.0.0.0:20160|70724|65536|1|1|abcd|60e9378c746d9a2be1c791047e008967cf252eb6de9167ad3aa6098fa2d523f4|update t set i = 2;|select * from t_slim;"))
"2019-02-12 19:33:56.571953|406315658548871171|root|127.0.0.1|6|4.895492|0.4|0.2|0.000000003|2|0.000000002|0.19|0.21|0.01|0|0.18|[txnLock]|0.03|0|15|480|1|8|0.3824278|0.161|0.101|0.092|1.71|1|100001|100000|test||0|42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772|t1:1,t2:2|0.1|0.2|0.03|127.0.0.1:20160|0.05|0.6|0.8|0.0.0.0:20160|70724|65536|1|1|abcd|60e9378c746d9a2be1c791047e008967cf252eb6de9167ad3aa6098fa2d523f4|update t set i = 2;|select * from t_slim;"))
tk.MustExec("set time_zone = '+00:00';")
re = tk.MustQuery("select * from information_schema.slow_query")
re.Check(testutil.RowsWithSep("|", "2019-02-12 11:33:56.571953|406315658548871171|root|127.0.0.1|6|4.895492|0.4|0.2|0.19|0.21|0.01|0|0.18|[txnLock]|0.03|0|15|480|1|8|0.3824278|0.161|0.101|0.092|1.71|1|100001|100000|test||0|42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772|t1:1,t2:2|0.1|0.2|0.03|127.0.0.1:20160|0.05|0.6|0.8|0.0.0.0:20160|70724|65536|1|1|abcd|60e9378c746d9a2be1c791047e008967cf252eb6de9167ad3aa6098fa2d523f4|update t set i = 2;|select * from t_slim;"))
re.Check(testutil.RowsWithSep("|", "2019-02-12 11:33:56.571953|406315658548871171|root|127.0.0.1|6|4.895492|0.4|0.2|0.000000003|2|0.000000002|0.19|0.21|0.01|0|0.18|[txnLock]|0.03|0|15|480|1|8|0.3824278|0.161|0.101|0.092|1.71|1|100001|100000|test||0|42a1c8aae6f133e934d4bf0147491709a8812ea05ff8819ec522780fe657b772|t1:1,t2:2|0.1|0.2|0.03|127.0.0.1:20160|0.05|0.6|0.8|0.0.0.0:20160|70724|65536|1|1|abcd|60e9378c746d9a2be1c791047e008967cf252eb6de9167ad3aa6098fa2d523f4|update t set i = 2;|select * from t_slim;"))

// Test for long query.
f, err := os.OpenFile(slowLogFileName, os.O_CREATE|os.O_WRONLY, 0644)
Expand Down
6 changes: 6 additions & 0 deletions planner/optimize.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"context"
"math"
"strings"
"time"

"github.com/pingcap/errors"
"github.com/pingcap/parser"
Expand Down Expand Up @@ -151,10 +152,15 @@ func optimize(ctx context.Context, sctx sessionctx.Context, node ast.Node, is in
hintProcessor := &hint.BlockHintProcessor{Ctx: sctx}
node.Accept(hintProcessor)
builder := plannercore.NewPlanBuilder(sctx, is, hintProcessor)

// reset fields about rewrite
sctx.GetSessionVars().RewritePhaseInfo.Reset()
beginRewrite := time.Now()
p, err := builder.Build(ctx, node)
if err != nil {
return nil, nil, 0, err
}
sctx.GetSessionVars().RewritePhaseInfo.DurationRewrite = time.Since(beginRewrite)

sctx.GetSessionVars().StmtCtx.Tables = builder.GetDBTableInfo()
activeRoles := sctx.GetSessionVars().ActiveRoles
Expand Down
37 changes: 37 additions & 0 deletions sessionctx/variable/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,25 @@ type TableSnapshot struct {

type txnIsolationLevelOneShotState uint

// RewritePhaseInfo records some information about the rewrite phase
type RewritePhaseInfo struct {
// DurationRewrite is the duration of rewriting the SQL.
DurationRewrite time.Duration

// DurationPreprocessSubQuery is the duration of pre-processing sub-queries.
DurationPreprocessSubQuery time.Duration

// PreprocessSubQueries is the number of pre-processed sub-queries.
PreprocessSubQueries int
}

// Reset resets all fields in RewritePhaseInfo.
func (r *RewritePhaseInfo) Reset() {
r.DurationRewrite = 0
r.DurationPreprocessSubQuery = 0
r.PreprocessSubQueries = 0
}

const (
// oneShotDef means default, that is tx_isolation_one_shot not set.
oneShotDef txnIsolationLevelOneShotState = iota
Expand Down Expand Up @@ -542,6 +561,9 @@ type SessionVars struct {
// DurationCompile is the duration of compiling AST to execution plan of the last query.
DurationCompile time.Duration

// RewritePhaseInfo records all information about the rewriting phase.
RewritePhaseInfo

// PrevStmt is used to store the previous executed statement in the current session.
PrevStmt fmt.Stringer

Expand Down Expand Up @@ -1503,6 +1525,12 @@ const (
SlowLogParseTimeStr = "Parse_time"
// SlowLogCompileTimeStr is the compile plan time.
SlowLogCompileTimeStr = "Compile_time"
// SlowLogRewriteTimeStr is the rewrite time.
SlowLogRewriteTimeStr = "Rewrite_time"
// SlowLogPreprocSubQueriesStr is the number of pre-processed sub-queries.
SlowLogPreprocSubQueriesStr = "Preproc_subqueries"
// SlowLogPreProcSubQueryTimeStr is the total time of pre-processing sub-queries.
SlowLogPreProcSubQueryTimeStr = "Preproc_subqueries_time"
// SlowLogDBStr is slow log field name.
SlowLogDBStr = "DB"
// SlowLogIsInternalStr is slow log field name.
Expand Down Expand Up @@ -1583,6 +1611,7 @@ type SlowQueryLogItems struct {
PrevStmt string
Plan string
PlanDigest string
RewriteInfo RewritePhaseInfo
}

// SlowLogFormat uses for formatting slow log.
Expand Down Expand Up @@ -1620,6 +1649,14 @@ func (s *SessionVars) SlowLogFormat(logItems *SlowQueryLogItems) string {
writeSlowLogItem(&buf, SlowLogParseTimeStr, strconv.FormatFloat(logItems.TimeParse.Seconds(), 'f', -1, 64))
writeSlowLogItem(&buf, SlowLogCompileTimeStr, strconv.FormatFloat(logItems.TimeCompile.Seconds(), 'f', -1, 64))

buf.WriteString(SlowLogRowPrefixStr + fmt.Sprintf("%v%v%v", SlowLogRewriteTimeStr,
SlowLogSpaceMarkStr, strconv.FormatFloat(logItems.RewriteInfo.DurationRewrite.Seconds(), 'f', -1, 64)))
if logItems.RewriteInfo.PreprocessSubQueries > 0 {
buf.WriteString(fmt.Sprintf(" %v%v%v %v%v%v", SlowLogPreprocSubQueriesStr, SlowLogSpaceMarkStr, logItems.RewriteInfo.PreprocessSubQueries,
SlowLogPreProcSubQueryTimeStr, SlowLogSpaceMarkStr, strconv.FormatFloat(logItems.RewriteInfo.DurationPreprocessSubQuery.Seconds(), 'f', -1, 64)))
}
buf.WriteString("\n")

if execDetailStr := logItems.ExecDetail.String(); len(execDetailStr) > 0 {
buf.WriteString(SlowLogRowPrefixStr + execDetailStr + "\n")
}
Expand Down
6 changes: 6 additions & 0 deletions sessionctx/variable/session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ func (*testSessionSuite) TestSlowLogFormat(c *C) {
# Query_time: 1
# Parse_time: 0.00000001
# Compile_time: 0.00000001
# Rewrite_time: 0.000000003 Preproc_subqueries: 2 Preproc_subqueries_time: 0.000000002
# Process_time: 2 Wait_time: 60 Backoff_time: 0.001 Request_count: 2 Total_keys: 10000 Process_keys: 20001
# DB: test
# Index_names: [t1:a,t2:b]
Expand Down Expand Up @@ -218,6 +219,11 @@ select * from t;`
PlanFromCache: true,
HasMoreResults: true,
Succ: true,
RewriteInfo: variable.RewritePhaseInfo{
DurationRewrite: 3,
DurationPreprocessSubQuery: 2,
PreprocessSubQueries: 2,
},
})
c.Assert(logString, Equals, resultString)
}
Expand Down

0 comments on commit 0ec197f

Please sign in to comment.