Skip to content

Commit

Permalink
infoschema: add 3 fields to statement summary table (pingcap#14096)
Browse files Browse the repository at this point in the history
  • Loading branch information
djshow832 authored and XiaTianliang committed Dec 21, 2019
1 parent bf8181f commit 560762f
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 91 deletions.
20 changes: 18 additions & 2 deletions executor/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,13 @@ func (a *recordSet) NewChunk() *chunk.Chunk {

func (a *recordSet) Close() error {
err := a.executor.Close()
// `LowSlowQuery` and `SummaryStmt` must be called before recording `PrevStmt`.
a.stmt.LogSlowQuery(a.txnStartTS, a.lastErr == nil, false)
a.stmt.SummaryStmt()
sessVars := a.stmt.Ctx.GetSessionVars()
pps := types.CloneRow(sessVars.PreparedParams)
sessVars.PrevStmt = FormatSQL(a.stmt.OriginText(), pps)
a.stmt.logAudit()
a.stmt.SummaryStmt()
return err
}

Expand Down Expand Up @@ -859,13 +860,26 @@ func getPlanDigest(sctx sessionctx.Context, p plannercore.Plan) (normalized, pla
// SummaryStmt collects statements for performance_schema.events_statements_summary_by_digest
func (a *ExecStmt) SummaryStmt() {
sessVars := a.Ctx.GetSessionVars()
if sessVars.InRestrictedSQL || !stmtsummary.StmtSummaryByDigestMap.Enabled() {
// Internal SQLs must also be recorded to keep the consistency of `PrevStmt` and `PrevStmtDigest`.
if !stmtsummary.StmtSummaryByDigestMap.Enabled() {
sessVars.SetPrevStmtDigest("")
return
}
stmtCtx := sessVars.StmtCtx
normalizedSQL, digest := stmtCtx.SQLDigest()
costTime := time.Since(sessVars.StartTime)

var prevSQL, prevSQLDigest string
if _, ok := a.StmtNode.(*ast.CommitStmt); ok {
// If prevSQLDigest is not recorded, it means this `commit` is the first SQL once stmt summary is enabled,
// so it's OK just to ignore it.
if prevSQLDigest = sessVars.GetPrevStmtDigest(); len(prevSQLDigest) == 0 {
return
}
prevSQL = sessVars.PrevStmt.String()
}
sessVars.SetPrevStmtDigest(digest)

execDetail := stmtCtx.GetExecDetails()
copTaskInfo := stmtCtx.CopTasksDetails()
memMax := stmtCtx.MemTracker.MaxConsumed()
Expand All @@ -879,6 +893,8 @@ func (a *ExecStmt) SummaryStmt() {
OriginalSQL: a.Text,
NormalizedSQL: normalizedSQL,
Digest: digest,
PrevSQL: prevSQL,
PrevSQLDigest: prevSQLDigest,
User: userString,
TotalLatency: costTime,
ParseLatency: sessVars.DurationParse,
Expand Down
79 changes: 13 additions & 66 deletions infoschema/perfschema/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,10 +390,10 @@ const tableStagesHistoryLong = "CREATE TABLE if not exists performance_schema."
"NESTING_EVENT_ID BIGINT(20) UNSIGNED," +
"NESTING_EVENT_TYPE ENUM('TRANSACTION','STATEMENT','STAGE'));"

// tableEventsStatementsSummaryByDigest contains the column name definitions for table
// events_statements_summary_by_digest, same as MySQL.
const tableEventsStatementsSummaryByDigest = "CREATE TABLE if not exists " + tableNameEventsStatementsSummaryByDigest + " (" +
// Fields in `events_statements_summary_by_digest` and `events_statements_summary_by_digest_history` are the same.
const fieldsInEventsStatementsSummary = " (" +
"SUMMARY_BEGIN_TIME TIMESTAMP(6) NOT NULL," +
"SUMMARY_END_TIME TIMESTAMP(6) NOT NULL," +
"STMT_TYPE VARCHAR(64) NOT NULL," +
"SCHEMA_NAME VARCHAR(64) DEFAULT NULL," +
"DIGEST VARCHAR(64) NOT NULL," +
Expand Down Expand Up @@ -447,78 +447,25 @@ const tableEventsStatementsSummaryByDigest = "CREATE TABLE if not exists " + tab
"MAX_PREWRITE_REGIONS INT(11) UNSIGNED NOT NULL," +
"AVG_TXN_RETRY DOUBLE NOT NULL," +
"MAX_TXN_RETRY INT(11) UNSIGNED NOT NULL," +
"SUM_BACKOFF_TIMES BIGINT(20) UNSIGNED NOT NULL," +
"BACKOFF_TYPES VARCHAR(1024) DEFAULT NULL," +
"AVG_MEM BIGINT(20) UNSIGNED NOT NULL," +
"MAX_MEM BIGINT(20) UNSIGNED NOT NULL," +
"AVG_AFFECTED_ROWS DOUBLE UNSIGNED NOT NULL," +
"FIRST_SEEN TIMESTAMP(6) NOT NULL," +
"LAST_SEEN TIMESTAMP(6) NOT NULL," +
"QUERY_SAMPLE_TEXT LONGTEXT DEFAULT NULL);"
"QUERY_SAMPLE_TEXT LONGTEXT DEFAULT NULL," +
"PREV_SAMPLE_TEXT LONGTEXT DEFAULT NULL);"

// tableEventsStatementsSummaryByDigest contains the column name definitions for table
// events_statements_summary_by_digest, same as MySQL.
const tableEventsStatementsSummaryByDigest = "CREATE TABLE if not exists " + tableNameEventsStatementsSummaryByDigest +
fieldsInEventsStatementsSummary

// tableEventsStatementsSummaryByDigestHistory contains the column name definitions for table
// events_statements_summary_by_digest_history.
const tableEventsStatementsSummaryByDigestHistory = "CREATE TABLE if not exists events_statements_summary_by_digest_history (" +
"SUMMARY_BEGIN_TIME TIMESTAMP(6) NOT NULL," +
"STMT_TYPE VARCHAR(64) NOT NULL," +
"SCHEMA_NAME VARCHAR(64) DEFAULT NULL," +
"DIGEST VARCHAR(64) NOT NULL," +
"DIGEST_TEXT LONGTEXT NOT NULL," +
"TABLE_NAMES TEXT DEFAULT NULL," +
"INDEX_NAMES TEXT DEFAULT NULL," +
"SAMPLE_USER VARCHAR(64) DEFAULT NULL," +
"EXEC_COUNT BIGINT(20) UNSIGNED NOT NULL," +
"SUM_LATENCY BIGINT(20) UNSIGNED NOT NULL," +
"MAX_LATENCY BIGINT(20) UNSIGNED NOT NULL," +
"MIN_LATENCY BIGINT(20) UNSIGNED NOT NULL," +
"AVG_LATENCY BIGINT(20) UNSIGNED NOT NULL," +
"AVG_PARSE_LATENCY BIGINT(20) UNSIGNED NOT NULL," +
"MAX_PARSE_LATENCY BIGINT(20) UNSIGNED NOT NULL," +
"AVG_COMPILE_LATENCY BIGINT(20) UNSIGNED NOT NULL," +
"MAX_COMPILE_LATENCY BIGINT(20) UNSIGNED NOT NULL," +
"COP_TASK_NUM BIGINT(20) UNSIGNED NOT NULL," +
"AVG_COP_PROCESS_TIME BIGINT(20) UNSIGNED NOT NULL," +
"MAX_COP_PROCESS_TIME BIGINT(20) UNSIGNED NOT NULL," +
"MAX_COP_PROCESS_ADDRESS VARCHAR(256) DEFAULT NULL," +
"AVG_COP_WAIT_TIME BIGINT(20) UNSIGNED NOT NULL," +
"MAX_COP_WAIT_TIME BIGINT(20) UNSIGNED NOT NULL," +
"MAX_COP_WAIT_ADDRESS VARCHAR(256) DEFAULT NULL," +
"AVG_PROCESS_TIME BIGINT(20) UNSIGNED NOT NULL," +
"MAX_PROCESS_TIME BIGINT(20) UNSIGNED NOT NULL," +
"AVG_WAIT_TIME BIGINT(20) UNSIGNED NOT NULL," +
"MAX_WAIT_TIME BIGINT(20) UNSIGNED NOT NULL," +
"AVG_BACKOFF_TIME BIGINT(20) UNSIGNED NOT NULL," +
"MAX_BACKOFF_TIME BIGINT(20) UNSIGNED NOT NULL," +
"AVG_TOTAL_KEYS BIGINT(20) UNSIGNED NOT NULL," +
"MAX_TOTAL_KEYS BIGINT(20) UNSIGNED NOT NULL," +
"AVG_PROCESSED_KEYS BIGINT(20) UNSIGNED NOT NULL," +
"MAX_PROCESSED_KEYS BIGINT(20) UNSIGNED NOT NULL," +
"AVG_PREWRITE_TIME BIGINT(20) UNSIGNED NOT NULL," +
"MAX_PREWRITE_TIME BIGINT(20) UNSIGNED NOT NULL," +
"AVG_COMMIT_TIME BIGINT(20) UNSIGNED NOT NULL," +
"MAX_COMMIT_TIME BIGINT(20) UNSIGNED NOT NULL," +
"AVG_GET_COMMIT_TS_TIME BIGINT(20) UNSIGNED NOT NULL," +
"MAX_GET_COMMIT_TS_TIME BIGINT(20) UNSIGNED NOT NULL," +
"AVG_COMMIT_BACKOFF_TIME BIGINT(20) UNSIGNED NOT NULL," +
"MAX_COMMIT_BACKOFF_TIME BIGINT(20) UNSIGNED NOT NULL," +
"AVG_RESOLVE_LOCK_TIME BIGINT(20) UNSIGNED NOT NULL," +
"MAX_RESOLVE_LOCK_TIME BIGINT(20) UNSIGNED NOT NULL," +
"AVG_LOCAL_LATCH_WAIT_TIME BIGINT(20) UNSIGNED NOT NULL," +
"MAX_LOCAL_LATCH_WAIT_TIME BIGINT(20) UNSIGNED NOT NULL," +
"AVG_WRITE_KEYS DOUBLE UNSIGNED NOT NULL," +
"MAX_WRITE_KEYS BIGINT(20) UNSIGNED NOT NULL," +
"AVG_WRITE_SIZE DOUBLE NOT NULL," +
"MAX_WRITE_SIZE BIGINT(20) UNSIGNED NOT NULL," +
"AVG_PREWRITE_REGIONS DOUBLE NOT NULL," +
"MAX_PREWRITE_REGIONS INT(11) UNSIGNED NOT NULL," +
"AVG_TXN_RETRY DOUBLE NOT NULL," +
"MAX_TXN_RETRY INT(11) UNSIGNED NOT NULL," +
"BACKOFF_TYPES VARCHAR(1024) DEFAULT NULL," +
"AVG_MEM BIGINT(20) UNSIGNED NOT NULL," +
"MAX_MEM BIGINT(20) UNSIGNED NOT NULL," +
"AVG_AFFECTED_ROWS DOUBLE UNSIGNED NOT NULL," +
"FIRST_SEEN TIMESTAMP(6) NOT NULL," +
"LAST_SEEN TIMESTAMP(6) NOT NULL," +
"QUERY_SAMPLE_TEXT LONGTEXT DEFAULT NULL);"
const tableEventsStatementsSummaryByDigestHistory = "CREATE TABLE if not exists " + tableNameEventsStatementsSummaryByDigestHistory +
fieldsInEventsStatementsSummary

// tableTiDBProfileCPU contains the columns name definitions for table tidb_profile_cpu
const tableTiDBProfileCPU = "CREATE TABLE IF NOT EXISTS " + tableNameTiDBProfileCPU + " (" +
Expand Down
8 changes: 4 additions & 4 deletions infoschema/perfschema/tables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,16 +153,16 @@ func (s *testTableSuite) TestStmtSummaryTable(c *C) {
tk.MustExec("commit")
tk.MustQuery(`select stmt_type, schema_name, table_names, index_names, exec_count, cop_task_num, avg_total_keys,
max_total_keys, avg_processed_keys, max_processed_keys, avg_write_keys, max_write_keys, avg_prewrite_regions,
max_prewrite_regions, avg_affected_rows, query_sample_text
max_prewrite_regions, avg_affected_rows, query_sample_text, prev_sample_text
from performance_schema.events_statements_summary_by_digest
where digest_text like 'insert into t%'`,
).Check(testkit.Rows("insert test test.t <nil> 1 0 0 0 0 0 0 0 0 0 1 insert into t values(1, 'a')"))
).Check(testkit.Rows("insert test test.t <nil> 1 0 0 0 0 0 0 0 0 0 1 insert into t values(1, 'a') "))
tk.MustQuery(`select stmt_type, schema_name, table_names, index_names, exec_count, cop_task_num, avg_total_keys,
max_total_keys, avg_processed_keys, max_processed_keys, avg_write_keys, max_write_keys, avg_prewrite_regions,
max_prewrite_regions, avg_affected_rows, query_sample_text
max_prewrite_regions, avg_affected_rows, query_sample_text, prev_sample_text
from performance_schema.events_statements_summary_by_digest
where digest_text='commit'`,
).Check(testkit.Rows("commit test <nil> <nil> 1 0 0 0 0 0 2 2 1 1 0 commit"))
).Check(testkit.Rows("commit test <nil> <nil> 1 0 0 0 0 0 2 2 1 1 0 commit insert into t values(1, 'a')"))

tk.MustQuery("select * from t where a=2")
tk.MustQuery(`select stmt_type, schema_name, table_names, index_names, exec_count, cop_task_num, avg_total_keys,
Expand Down
1 change: 1 addition & 0 deletions session/tidb.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ func runStmt(ctx context.Context, sctx sessionctx.Context, s sqlexec.Statement)
// If it is not a select statement, we record its slow log here,
// then it could include the transaction commit time.
if rs == nil {
// `LowSlowQuery` and `SummaryStmt` must be called before recording `PrevStmt`.
s.(*executor.ExecStmt).LogSlowQuery(origTxnCtx.StartTS, err == nil, false)
s.(*executor.ExecStmt).SummaryStmt()
pps := types.CloneRow(sessVars.PreparedParams)
Expand Down
15 changes: 15 additions & 0 deletions sessionctx/variable/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,9 @@ type SessionVars struct {
// PrevStmt is used to store the previous executed statement in the current session.
PrevStmt fmt.Stringer

// prevStmtDigest is used to store the digest of the previous statement in the current session.
prevStmtDigest string

// AllowRemoveAutoInc indicates whether a user can drop the auto_increment column attribute or not.
AllowRemoveAutoInc bool

Expand Down Expand Up @@ -1041,6 +1044,18 @@ func (s *SessionVars) setTxnMode(val string) error {
return nil
}

// SetPrevStmtDigest sets the digest of the previous statement.
func (s *SessionVars) SetPrevStmtDigest(prevStmtDigest string) {
s.prevStmtDigest = prevStmtDigest
}

// GetPrevStmtDigest returns the digest of the previous statement.
func (s *SessionVars) GetPrevStmtDigest() string {
// Because `prevStmt` may be truncated, so it's senseless to normalize it.
// Even if `prevStmtDigest` is empty but `prevStmt` is not, just return it anyway.
return s.prevStmtDigest
}

// SetLocalSystemVar sets values of the local variables which in "server" scope.
func SetLocalSystemVar(name string, val string) {
switch name {
Expand Down
Loading

0 comments on commit 560762f

Please sign in to comment.