Skip to content

Commit f33c908

Browse files
djshow832winkyao
authored andcommitted
session, executor: support setting tidb_enable_stmt_summary in session scope (#12217) (#12308)
1 parent a3e1d01 commit f33c908

File tree

10 files changed

+171
-31
lines changed

10 files changed

+171
-31
lines changed

domain/global_vars_cache.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func checkEnableStmtSummary(rows []chunk.Row, fields []*ast.ResultField) {
8383
}
8484
}
8585

86-
stmtsummary.OnEnableStmtSummaryModified(sVal)
86+
stmtsummary.StmtSummaryByDigestMap.SetEnabled(sVal, false)
8787
break
8888
}
8989
}

domain/global_vars_cache_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
package domain
1515

1616
import (
17-
"sync/atomic"
1817
"time"
1918

2019
. "github.com/pingcap/check"
@@ -26,6 +25,7 @@ import (
2625
"github.com/pingcap/tidb/store/mockstore"
2726
"github.com/pingcap/tidb/types"
2827
"github.com/pingcap/tidb/util/chunk"
28+
"github.com/pingcap/tidb/util/stmtsummary"
2929
"github.com/pingcap/tidb/util/testleak"
3030
)
3131

@@ -127,18 +127,18 @@ func (gvcSuite *testGVCSuite) TestCheckEnableStmtSummary(c *C) {
127127
Collate: charset.CollationBin,
128128
}
129129

130-
atomic.StoreInt32(&variable.EnableStmtSummary, 0)
130+
stmtsummary.StmtSummaryByDigestMap.SetEnabled("0", false)
131131
ck := chunk.NewChunkWithCapacity([]*types.FieldType{ft, ft1}, 1024)
132132
ck.AppendString(0, variable.TiDBEnableStmtSummary)
133133
ck.AppendString(1, "1")
134134
row := ck.GetRow(0)
135135
gvc.Update([]chunk.Row{row}, []*ast.ResultField{rf, rf1})
136-
c.Assert(atomic.LoadInt32(&variable.EnableStmtSummary), Equals, int32(1))
136+
c.Assert(stmtsummary.StmtSummaryByDigestMap.Enabled(), Equals, true)
137137

138138
ck = chunk.NewChunkWithCapacity([]*types.FieldType{ft, ft1}, 1024)
139139
ck.AppendString(0, variable.TiDBEnableStmtSummary)
140140
ck.AppendString(1, "0")
141141
row = ck.GetRow(0)
142142
gvc.Update([]chunk.Row{row}, []*ast.ResultField{rf, rf1})
143-
c.Assert(atomic.LoadInt32(&variable.EnableStmtSummary), Equals, int32(0))
143+
c.Assert(stmtsummary.StmtSummaryByDigestMap.Enabled(), Equals, false)
144144
}

executor/adapter.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ func (a *ExecStmt) LogSlowQuery(txnTS uint64, succ bool) {
713713
// SummaryStmt collects statements for performance_schema.events_statements_summary_by_digest
714714
func (a *ExecStmt) SummaryStmt() {
715715
sessVars := a.Ctx.GetSessionVars()
716-
if sessVars.InRestrictedSQL || atomic.LoadInt32(&variable.EnableStmtSummary) == 0 {
716+
if sessVars.InRestrictedSQL || !stmtsummary.StmtSummaryByDigestMap.Enabled() {
717717
return
718718
}
719719
stmtCtx := sessVars.StmtCtx

executor/set.go

+9-4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/pingcap/tidb/util/chunk"
3131
"github.com/pingcap/tidb/util/gcutil"
3232
"github.com/pingcap/tidb/util/logutil"
33+
"github.com/pingcap/tidb/util/stmtsummary"
3334
"go.uber.org/zap"
3435
)
3536

@@ -119,6 +120,7 @@ func (e *SetExecutor) setSysVariable(name string, v *expression.VarAssignment) e
119120
if sysVar.Scope == variable.ScopeNone {
120121
return errors.Errorf("Variable '%s' is a read only variable", name)
121122
}
123+
var valStr string
122124
if v.IsGlobal {
123125
// Set global scope system variable.
124126
if sysVar.Scope&variable.ScopeGlobal == 0 {
@@ -131,18 +133,18 @@ func (e *SetExecutor) setSysVariable(name string, v *expression.VarAssignment) e
131133
if value.IsNull() {
132134
value.SetString("")
133135
}
134-
svalue, err := value.ToString()
136+
valStr, err = value.ToString()
135137
if err != nil {
136138
return err
137139
}
138-
err = sessionVars.GlobalVarsAccessor.SetGlobalSysVar(name, svalue)
140+
err = sessionVars.GlobalVarsAccessor.SetGlobalSysVar(name, valStr)
139141
if err != nil {
140142
return err
141143
}
142144
err = plugin.ForeachPlugin(plugin.Audit, func(p *plugin.Plugin) error {
143145
auditPlugin := plugin.DeclareAuditManifest(p.Manifest)
144146
if auditPlugin.OnGlobalVariableEvent != nil {
145-
auditPlugin.OnGlobalVariableEvent(context.Background(), e.ctx.GetSessionVars(), name, svalue)
147+
auditPlugin.OnGlobalVariableEvent(context.Background(), e.ctx.GetSessionVars(), name, valStr)
146148
}
147149
return nil
148150
})
@@ -179,7 +181,6 @@ func (e *SetExecutor) setSysVariable(name string, v *expression.VarAssignment) e
179181
sessionVars.SnapshotTS = oldSnapshotTS
180182
return err
181183
}
182-
var valStr string
183184
if value.IsNull() {
184185
valStr = "NULL"
185186
} else {
@@ -190,6 +191,10 @@ func (e *SetExecutor) setSysVariable(name string, v *expression.VarAssignment) e
190191
logutil.Logger(context.Background()).Info("set session var", zap.Uint64("conn", sessionVars.ConnectionID), zap.String("name", name), zap.String("val", valStr))
191192
}
192193

194+
if name == variable.TiDBEnableStmtSummary {
195+
stmtsummary.StmtSummaryByDigestMap.SetEnabled(valStr, !v.IsGlobal)
196+
}
197+
193198
return nil
194199
}
195200

infoschema/perfschema/tables_test.go

+33-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func (s *testTableSuite) TestStmtSummaryTable(c *C) {
109109
).Check(testkit.Rows("test 4 4 insert into t values(1, 'a')"))
110110

111111
// Disable it again
112-
tk.MustExec("set global tidb_enable_stmt_summary = 0")
112+
tk.MustExec("set global tidb_enable_stmt_summary = false")
113113
tk.MustQuery("select @@global.tidb_enable_stmt_summary").Check(testkit.Rows("0"))
114114

115115
// Create a new session to test
@@ -122,4 +122,36 @@ func (s *testTableSuite) TestStmtSummaryTable(c *C) {
122122
tk.MustQuery(`select schema_name, exec_count, sum_rows_affected, query_sample_text
123123
from performance_schema.events_statements_summary_by_digest`,
124124
).Check(testkit.Rows())
125+
126+
// Enable it in session scope
127+
tk.MustExec("set session tidb_enable_stmt_summary = on")
128+
// It should work immediately
129+
tk.MustQuery("select * from t where a=2")
130+
tk.MustQuery(`select schema_name, exec_count, sum_rows_affected, query_sample_text
131+
from performance_schema.events_statements_summary_by_digest
132+
where digest_text like 'select * from t%'`,
133+
).Check(testkit.Rows("test 1 0 select * from t where a=2"))
134+
135+
// Disable it in global scope
136+
tk.MustExec("set global tidb_enable_stmt_summary = off")
137+
138+
// Create a new session to test
139+
tk = testkit.NewTestKitWithInit(c, s.store)
140+
141+
tk.MustQuery("select * from t where a=2")
142+
143+
// Statement summary is still enabled
144+
tk.MustQuery(`select schema_name, exec_count, sum_rows_affected, query_sample_text
145+
from performance_schema.events_statements_summary_by_digest
146+
where digest_text like 'select * from t%'`,
147+
).Check(testkit.Rows("test 2 0 select * from t where a=2"))
148+
149+
// Unset session variable
150+
tk.MustExec("set session tidb_enable_stmt_summary = ''")
151+
tk.MustQuery("select * from t where a=2")
152+
153+
// Statement summary is disabled
154+
tk.MustQuery(`select schema_name, exec_count, sum_rows_affected, query_sample_text
155+
from performance_schema.events_statements_summary_by_digest`,
156+
).Check(testkit.Rows())
125157
}

sessionctx/variable/sysvar.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ var defaultSysVars = []*SysVar{
710710
{ScopeSession, TiDBLowResolutionTSO, "0"},
711711
{ScopeSession, TiDBExpensiveQueryTimeThreshold, strconv.Itoa(DefTiDBExpensiveQueryTimeThreshold)},
712712
{ScopeSession, TiDBAllowRemoveAutoInc, BoolToIntStr(DefTiDBAllowRemoveAutoInc)},
713-
{ScopeGlobal, TiDBEnableStmtSummary, BoolToIntStr(DefTiDBEnableStmtSummary)},
713+
{ScopeGlobal | ScopeSession, TiDBEnableStmtSummary, "0"},
714714
}
715715

716716
// SynonymsSysVariables is synonyms of system variables.

sessionctx/variable/tidb_vars.go

-2
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,6 @@ const (
351351
DefTiDBExpensiveQueryTimeThreshold = 60 // 60s
352352
DefWaitSplitRegionTimeout = 300 // 300s
353353
DefTiDBAllowRemoveAutoInc = false
354-
DefTiDBEnableStmtSummary = false
355354
)
356355

357356
// Process global variables.
@@ -371,5 +370,4 @@ var (
371370
MaxOfMaxAllowedPacket uint64 = 1073741824
372371
ExpensiveQueryTimeThreshold uint64 = DefTiDBExpensiveQueryTimeThreshold
373372
MinExpensiveQueryTimeThreshold uint64 = 10 //10s
374-
EnableStmtSummary int32 = BoolToInt32(DefTiDBEnableStmtSummary)
375373
)

sessionctx/variable/varsutil.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ func ValidateSetSystemVar(vars *SessionVars, name string, value string) (string,
420420
TiDBOptInSubqToJoinAndAgg, TiDBEnableFastAnalyze,
421421
TiDBBatchInsert, TiDBDisableTxnAutoRetry, TiDBEnableStreaming,
422422
TiDBBatchDelete, TiDBBatchCommit, TiDBEnableCascadesPlanner, TiDBEnableWindowFunction,
423-
TiDBCheckMb4ValueInUTF8, TiDBLowResolutionTSO, TiDBScatterRegion, TiDBEnableStmtSummary:
423+
TiDBCheckMb4ValueInUTF8, TiDBLowResolutionTSO, TiDBScatterRegion:
424424
if strings.EqualFold(value, "ON") || value == "1" || strings.EqualFold(value, "OFF") || value == "0" {
425425
return value, nil
426426
}
@@ -577,6 +577,16 @@ func ValidateSetSystemVar(vars *SessionVars, name string, value string) (string,
577577
return "off", nil
578578
}
579579
return value, ErrWrongValueForVar.GenWithStackByArgs(name, value)
580+
case TiDBEnableStmtSummary:
581+
switch {
582+
case strings.EqualFold(value, "ON") || value == "1":
583+
return "1", nil
584+
case strings.EqualFold(value, "OFF") || value == "0":
585+
return "0", nil
586+
case value == "":
587+
return "", nil
588+
}
589+
return value, ErrWrongValueForVar.GenWithStackByArgs(name, value)
580590
}
581591
return value, nil
582592
}

util/stmtsummary/statement_summary.go

+74-11
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@ package stmtsummary
1616
import (
1717
"strings"
1818
"sync"
19-
"sync/atomic"
2019
"time"
2120

2221
"github.com/pingcap/parser/mysql"
2322
"github.com/pingcap/tidb/config"
24-
"github.com/pingcap/tidb/sessionctx/variable"
2523
"github.com/pingcap/tidb/types"
2624
"github.com/pingcap/tidb/util/hack"
2725
"github.com/pingcap/tidb/util/kvcache"
@@ -55,6 +53,15 @@ type stmtSummaryByDigestMap struct {
5553
// It's rare to read concurrently, so RWMutex is not needed.
5654
sync.Mutex
5755
summaryMap *kvcache.SimpleLRUCache
56+
57+
// enabledWrapper encapsulates variables needed to judge whether statement summary is enabled.
58+
enabledWrapper struct {
59+
sync.RWMutex
60+
// enabled indicates whether statement summary is enabled in current server.
61+
sessionEnabled string
62+
// setInSession indicates whether statement summary has been set in any session.
63+
globalEnabled string
64+
}
5865
}
5966

6067
// StmtSummaryByDigestMap is a global map containing all statement summaries.
@@ -97,9 +104,13 @@ type StmtExecInfo struct {
97104
// newStmtSummaryByDigestMap creates an empty stmtSummaryByDigestMap.
98105
func newStmtSummaryByDigestMap() *stmtSummaryByDigestMap {
99106
maxStmtCount := config.GetGlobalConfig().StmtSummary.MaxStmtCount
100-
return &stmtSummaryByDigestMap{
107+
ssMap := &stmtSummaryByDigestMap{
101108
summaryMap: kvcache.NewSimpleLRUCache(maxStmtCount, 0, 0),
102109
}
110+
// enabledWrapper.defaultEnabled will be initialized in package variable.
111+
ssMap.enabledWrapper.sessionEnabled = ""
112+
ssMap.enabledWrapper.globalEnabled = ""
113+
return ssMap
103114
}
104115

105116
// newStmtSummaryByDigest creates a stmtSummaryByDigest from StmtExecInfo
@@ -164,7 +175,7 @@ func (ssMap *stmtSummaryByDigestMap) AddStatement(sei *StmtExecInfo) {
164175

165176
ssMap.Lock()
166177
// Check again. Statements could be added before disabling the flag and after Clear()
167-
if atomic.LoadInt32(&variable.EnableStmtSummary) == 0 {
178+
if !ssMap.Enabled() {
168179
ssMap.Unlock()
169180
return
170181
}
@@ -188,7 +199,7 @@ func (ssMap *stmtSummaryByDigestMap) Clear() {
188199
ssMap.Unlock()
189200
}
190201

191-
// Convert statement summary to Datum
202+
// ToDatum converts statement summary to Datum
192203
func (ssMap *stmtSummaryByDigestMap) ToDatum() [][]types.Datum {
193204
ssMap.Lock()
194205
values := ssMap.summaryMap.Values()
@@ -219,12 +230,64 @@ func (ssMap *stmtSummaryByDigestMap) ToDatum() [][]types.Datum {
219230
return rows
220231
}
221232

222-
// OnEnableStmtSummaryModified is triggered once EnableStmtSummary is modified.
223-
func OnEnableStmtSummaryModified(newValue string) {
224-
if variable.TiDBOptOn(newValue) {
225-
atomic.StoreInt32(&variable.EnableStmtSummary, 1)
233+
// SetEnabled enables or disables statement summary in global(cluster) or session(server) scope.
234+
func (ssMap *stmtSummaryByDigestMap) SetEnabled(value string, inSession bool) {
235+
value = ssMap.normalizeEnableValue(value)
236+
237+
ssMap.enabledWrapper.Lock()
238+
if inSession {
239+
ssMap.enabledWrapper.sessionEnabled = value
240+
} else {
241+
ssMap.enabledWrapper.globalEnabled = value
242+
}
243+
sessionEnabled := ssMap.enabledWrapper.sessionEnabled
244+
globalEnabled := ssMap.enabledWrapper.globalEnabled
245+
ssMap.enabledWrapper.Unlock()
246+
247+
// Clear all summaries once statement summary is disabled.
248+
var needClear bool
249+
if ssMap.isSet(sessionEnabled) {
250+
needClear = !ssMap.isEnabled(sessionEnabled)
251+
} else {
252+
needClear = !ssMap.isEnabled(globalEnabled)
253+
}
254+
if needClear {
255+
ssMap.Clear()
256+
}
257+
}
258+
259+
// Enabled returns whether statement summary is enabled.
260+
func (ssMap *stmtSummaryByDigestMap) Enabled() bool {
261+
ssMap.enabledWrapper.RLock()
262+
var enabled bool
263+
if ssMap.isSet(ssMap.enabledWrapper.sessionEnabled) {
264+
enabled = ssMap.isEnabled(ssMap.enabledWrapper.sessionEnabled)
226265
} else {
227-
atomic.StoreInt32(&variable.EnableStmtSummary, 0)
228-
StmtSummaryByDigestMap.Clear()
266+
enabled = ssMap.isEnabled(ssMap.enabledWrapper.globalEnabled)
267+
}
268+
ssMap.enabledWrapper.RUnlock()
269+
return enabled
270+
}
271+
272+
// normalizeEnableValue converts 'ON' to '1' and 'OFF' to '0'
273+
func (ssMap *stmtSummaryByDigestMap) normalizeEnableValue(value string) string {
274+
switch {
275+
case strings.EqualFold(value, "ON"):
276+
return "1"
277+
case strings.EqualFold(value, "OFF"):
278+
return "0"
279+
default:
280+
return value
229281
}
230282
}
283+
284+
// isEnabled converts a string value to bool.
285+
// 1 indicates true, 0 or '' indicates false.
286+
func (ssMap *stmtSummaryByDigestMap) isEnabled(value string) bool {
287+
return value == "1"
288+
}
289+
290+
// isSet judges whether the variable is set.
291+
func (ssMap *stmtSummaryByDigestMap) isSet(value string) bool {
292+
return value != ""
293+
}

0 commit comments

Comments
 (0)