Skip to content
This repository was archived by the owner on Jun 30, 2025. It is now read-only.

Commit 8781a61

Browse files
authored
Merge pull request #88 from percona/PMM-2433-PMM-2434
PMM-2433, PMM-2434: Use new options, SlowLogRotation and RetainSlowLogs
2 parents bd814b8 + 2ffdadd commit 8781a61

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+3468
-2240
lines changed

glide.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

glide.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,14 @@ import:
1313
- log/slow
1414
- query
1515
- package: github.com/percona/percona-toolkit
16-
version: b53d67f6ead42c7c0e27b21c4f89b1cd3f349aee
1716
subpackages:
1817
- src/go/mongolib/explain
1918
- src/go/mongolib/fingerprinter
2019
- src/go/mongolib/proto
2120
- src/go/mongolib/stats
2221
- package: github.com/percona/pmgo
2322
- package: github.com/percona/pmm
24-
version: f190773155b8927dee5c0400a6385bbb83a10f44
23+
version: 88b7a3ea548f89aa63c3ec946c5a20db949db715
2524
subpackages:
2625
- proto
2726
- proto/config

qan/analyzer/mysql/analyzer.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,11 @@ func (a *RealAnalyzer) TakeOverPerconaServerRotation() error {
165165
a.logger.Debug("TakeOverPerconaServerRotation:call")
166166
defer a.logger.Debug("TakeOverPerconaServerRotation:return")
167167

168+
// If slow log rotation is disabled, don't take over Percona Server slow log rotation.
169+
if !boolValue(a.config.SlowLogRotation) {
170+
return nil
171+
}
172+
168173
// max_slowlog_size: https://www.percona.com/doc/percona-server/LATEST/flexibility/slowlog_rotation.html#max_slowlog_size
169174
maxSlowLogSizeNullInt64, err := a.mysqlConn.GetGlobalVarInteger("max_slowlog_size")
170175
if err != nil {
@@ -451,3 +456,12 @@ func (a *RealAnalyzer) runWorker(interval *iter.Interval) {
451456
a.logger.Warn("Lost report:", err)
452457
}
453458
}
459+
460+
// boolValue returns the value of the bool pointer passed in or
461+
// false if the pointer is nil.
462+
func boolValue(v *bool) bool {
463+
if v != nil {
464+
return *v
465+
}
466+
return false
467+
}

qan/analyzer/mysql/analyzer_test.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,14 @@ func (s *AnalyzerTestSuite) SetUpTest(t *C) {
124124
s.worker = qan_worker.NewQanWorker()
125125
// Config needs to be recreated on every test since it can be modified by the test analyzers
126126
exampleQueries := true
127+
slowLogRotation := true
127128
s.config = pc.QAN{
128-
UUID: s.mysqlUUID,
129-
CollectFrom: "slowlog",
130-
Interval: 60,
131-
WorkerRunTime: 60,
132-
MaxSlowLogSize: MAX_SLOW_LOG_SIZE,
129+
UUID: s.mysqlUUID,
130+
CollectFrom: "slowlog",
131+
Interval: 60,
132+
WorkerRunTime: 60,
133+
MaxSlowLogSize: MAX_SLOW_LOG_SIZE,
134+
SlowLogRotation: &slowLogRotation,
133135
Start: []string{
134136
"-- start",
135137
},

qan/analyzer/mysql/config/config.go

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,15 @@ import (
2727
)
2828

2929
var (
30-
DEFAULT_INTERVAL uint = 60 // 1 minute
31-
DEFAULT_MAX_SLOW_LOG_SIZE int64 = 1073741824 // 1G
32-
DEFAULT_REMOVE_OLD_SLOW_LOGS = true // whether to remove old slow logs after rotation
33-
DEFAULT_OLD_SLOW_LOGS_TO_KEEP = 1 // how many slow logs to keep on filesystem
34-
DEFAULT_EXAMPLE_QUERIES = true
30+
DefaultInterval uint = 60 // 1 minute
31+
DefaultMaxSlowLogSize int64 = 1073741824 // 1G
32+
DefaultSlowLogRotation = true // whether to rotate slow logs
33+
DefaultRemoveOldSlowLogs = true // whether to remove old slow logs after rotation
34+
DefaultRetainSlowLogs = 1 // how many slow logs to keep on filesystem
35+
DefaultExampleQueries = true
3536
// internal
36-
DEFAULT_WORKER_RUNTIME uint = 55
37-
DEFAULT_REPORT_LIMIT uint = 200
37+
DefaultWorkerRuntime uint = 55
38+
DefaultReportLimit uint = 200
3839
)
3940

4041
type MySQLVarType int
@@ -110,17 +111,32 @@ func ReadInfoFromShowGlobalStatus(conn mysql.Connector) (info map[string]interfa
110111
func ValidateConfig(setConfig pc.QAN) (pc.QAN, error) {
111112
runConfig := pc.QAN{
112113
UUID: setConfig.UUID,
113-
Interval: DEFAULT_INTERVAL,
114+
Interval: DefaultInterval,
114115
ExampleQueries: new(bool),
115-
MaxSlowLogSize: DEFAULT_MAX_SLOW_LOG_SIZE,
116-
WorkerRunTime: DEFAULT_WORKER_RUNTIME,
117-
ReportLimit: DEFAULT_REPORT_LIMIT,
116+
// "slowlog" specific options.
117+
MaxSlowLogSize: DefaultMaxSlowLogSize,
118+
SlowLogRotation: new(bool),
119+
RetainSlowLogs: new(int),
120+
// internal
121+
WorkerRunTime: DefaultWorkerRuntime,
122+
ReportLimit: DefaultReportLimit,
118123
}
119124
// I know this is an ugly hack, but we need runConfig.ExampleQueries to be a pointer since
120125
// the default value for a boolean is false, there is no way to tell if it was false in the
121126
// config or if the value was missing.
122127
// If it was missing (nil) we should take the default=true
123-
*runConfig.ExampleQueries = DEFAULT_EXAMPLE_QUERIES
128+
*runConfig.ExampleQueries = DefaultExampleQueries
129+
if setConfig.ExampleQueries != nil {
130+
runConfig.ExampleQueries = setConfig.ExampleQueries
131+
}
132+
*runConfig.SlowLogRotation = DefaultSlowLogRotation
133+
if setConfig.SlowLogRotation != nil {
134+
runConfig.SlowLogRotation = setConfig.SlowLogRotation
135+
}
136+
*runConfig.RetainSlowLogs = DefaultRetainSlowLogs
137+
if setConfig.RetainSlowLogs != nil {
138+
runConfig.RetainSlowLogs = setConfig.RetainSlowLogs
139+
}
124140

125141
// Strings
126142
if setConfig.CollectFrom != "slowlog" && setConfig.CollectFrom != "perfschema" {
@@ -133,11 +149,7 @@ func ValidateConfig(setConfig pc.QAN) (pc.QAN, error) {
133149
return runConfig, fmt.Errorf("Interval must be > 0 and <= 3600 (1 hour)")
134150
}
135151
if setConfig.Interval > 0 {
136-
runConfig.Interval = uint(setConfig.Interval)
137-
}
138-
139-
if setConfig.ExampleQueries != nil {
140-
runConfig.ExampleQueries = setConfig.ExampleQueries
152+
runConfig.Interval = setConfig.Interval
141153
}
142154

143155
runConfig.WorkerRunTime = uint(float64(runConfig.Interval) * 0.9) // 90% of interval

qan/analyzer/mysql/mysql.go

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -187,22 +187,15 @@ func (m *MySQLAnalyzer) Stop() error {
187187

188188
func (m *MySQLAnalyzer) GetDefaults(uuid string) map[string]interface{} {
189189
// Configuration
190-
collectFrom := m.config.CollectFrom
191-
interval := m.config.Interval
192-
exampleQueries := m.config.ExampleQueries
193-
// For old format of qan config, get Interval and ExampleQueries from running config.
194-
if interval == 0 {
195-
interval = m.analyzer.Config().Interval
196-
exampleQueries = m.analyzer.Config().ExampleQueries
197-
}
198190
cfg := map[string]interface{}{
199-
"CollectFrom": collectFrom,
200-
"Interval": interval,
201-
"MaxSlowLogSize": config.DEFAULT_MAX_SLOW_LOG_SIZE,
202-
"RemoveOldSlowLogs": config.DEFAULT_REMOVE_OLD_SLOW_LOGS,
203-
"ExampleQueries": exampleQueries,
204-
"WorkerRunTime": config.DEFAULT_WORKER_RUNTIME,
205-
"ReportLimit": config.DEFAULT_REPORT_LIMIT,
191+
"CollectFrom": m.config.CollectFrom,
192+
"Interval": m.config.Interval,
193+
"MaxSlowLogSize": config.DefaultMaxSlowLogSize,
194+
"RetainSlowLogs": m.config.RetainSlowLogs,
195+
"SlowLogRotation": m.config.SlowLogRotation,
196+
"ExampleQueries": m.config.ExampleQueries,
197+
"WorkerRunTime": config.DefaultWorkerRuntime,
198+
"ReportLimit": config.DefaultReportLimit,
206199
}
207200

208201
// Info from SHOW GLOBAL STATUS

qan/analyzer/mysql/worker/slowlog/slowlog_test.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -285,12 +285,16 @@ func (s *WorkerTestSuite) TestRotateAndRemoveSlowLog(t *C) {
285285

286286
// See TestStartService() for description of these startup tasks.
287287
exampleQueries := true
288+
slowLogsRotation := true
289+
slowLogsToKeep := 1
288290
config := pc.QAN{
289-
UUID: s.mysqlInstance.UUID,
290-
Interval: 300,
291-
MaxSlowLogSize: 1000, // <-- HERE
292-
ExampleQueries: &exampleQueries,
293-
WorkerRunTime: 600,
291+
UUID: s.mysqlInstance.UUID,
292+
Interval: 300,
293+
MaxSlowLogSize: 1000, // <-- HERE
294+
ExampleQueries: &exampleQueries,
295+
SlowLogRotation: &slowLogsRotation,
296+
RetainSlowLogs: &slowLogsToKeep,
297+
WorkerRunTime: 600,
294298
Start: []string{
295299
"-- start",
296300
},
@@ -384,12 +388,16 @@ func (s *WorkerTestSuite) TestRotateSlowLog(t *C) {
384388

385389
// See TestStartService() for description of these startup tasks.
386390
exampleQueries := true
391+
slowLogsRotation := true
392+
slowLogsToKeep := 1
387393
config := pc.QAN{
388-
UUID: s.mysqlInstance.UUID,
389-
Interval: 300,
390-
MaxSlowLogSize: 1000,
391-
ExampleQueries: &exampleQueries,
392-
WorkerRunTime: 600,
394+
UUID: s.mysqlInstance.UUID,
395+
Interval: 300,
396+
MaxSlowLogSize: 1000,
397+
ExampleQueries: &exampleQueries,
398+
SlowLogRotation: &slowLogsRotation,
399+
RetainSlowLogs: &slowLogsToKeep,
400+
WorkerRunTime: 600,
393401
Start: []string{
394402
"-- start",
395403
},

qan/analyzer/mysql/worker/slowlog/worker.go

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ type Job struct {
6565
StartOffset int64
6666
EndOffset int64
6767
ExampleQueries bool
68+
RetainSlowLogs int
6869
}
6970

7071
func (j *Job) String() string {
@@ -139,21 +140,30 @@ func (w *Worker) Setup(interval *iter.Interval) error {
139140
w.logger.Debug("Setup:call")
140141
defer w.logger.Debug("Setup:return")
141142
w.logger.Debug("Setup:", interval)
142-
if interval.EndOffset >= w.config.MaxSlowLogSize {
143-
w.logger.Info(fmt.Sprintf("Rotating slow log: %s >= %s",
144-
pct.Bytes(uint64(interval.EndOffset)),
145-
pct.Bytes(uint64(w.config.MaxSlowLogSize))))
146-
if err := w.rotateSlowLog(interval); err != nil {
147-
w.logger.Error(err)
143+
144+
// Check if slow log rotation is enabled.
145+
if boolValue(w.config.SlowLogRotation) {
146+
// Check if max slow log size was reached.
147+
if interval.EndOffset >= w.config.MaxSlowLogSize {
148+
w.logger.Info(fmt.Sprintf("Rotating slow log: %s >= %s",
149+
pct.Bytes(uint64(interval.EndOffset)),
150+
pct.Bytes(uint64(w.config.MaxSlowLogSize))))
151+
// Rotate slow log.
152+
if err := w.rotateSlowLog(interval); err != nil {
153+
w.logger.Error(err)
154+
}
148155
}
149156
}
157+
158+
// Create new Job.
150159
w.job = &Job{
151160
Id: fmt.Sprintf("%d", interval.Number),
152161
SlowLogFile: interval.Filename,
153162
StartOffset: interval.StartOffset,
154163
EndOffset: interval.EndOffset,
155164
RunTime: time.Duration(w.config.WorkerRunTime) * time.Second,
156165
ExampleQueries: boolValue(w.config.ExampleQueries),
166+
RetainSlowLogs: intValue(w.config.RetainSlowLogs),
157167
}
158168
w.logger.Debug("Setup:", w.job)
159169

@@ -429,18 +439,18 @@ func (w *Worker) rotateSlowLog(interval *iter.Interval) error {
429439
interval.EndOffset, _ = pct.FileSize(newSlowLogFile) // todo: handle err
430440

431441
// Purge old slow logs.
432-
if !config.DEFAULT_REMOVE_OLD_SLOW_LOGS {
442+
if !config.DefaultRemoveOldSlowLogs {
433443
return nil
434444
}
435445
filesFound, err := filepath.Glob(fmt.Sprintf("%s-*", curSlowLog))
436446
if err != nil {
437447
return err
438448
}
439-
if len(filesFound) <= config.DEFAULT_OLD_SLOW_LOGS_TO_KEEP {
449+
if len(filesFound) <= intValue(w.config.RetainSlowLogs) {
440450
return nil
441451
}
442452
sort.Strings(filesFound)
443-
for _, f := range filesFound[:len(filesFound)-config.DEFAULT_OLD_SLOW_LOGS_TO_KEEP] {
453+
for _, f := range filesFound[:len(filesFound)-intValue(w.config.RetainSlowLogs)] {
444454
w.status.Update(w.name, "Removing slow log "+f)
445455
if err := os.Remove(f); err != nil {
446456
w.logger.Warn(err)
@@ -460,3 +470,12 @@ func boolValue(v *bool) bool {
460470
}
461471
return false
462472
}
473+
474+
// intValue returns the value of the int pointer passed in or
475+
// 0 if the pointer is nil.
476+
func intValue(v *int) int {
477+
if v != nil {
478+
return *v
479+
}
480+
return 0
481+
}

qan/manager_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ func (s *ManagerTestSuite) TestStartTool(t *C) {
564564
// For some reasons MaxSlowLogSize is explicitly marked to not be saved in config file
565565
// type QAN struct {
566566
// ...
567-
// MaxSlowLogSize int64 `json:"-"` // bytes, 0 = DEFAULT_MAX_SLOW_LOG_SIZE. Don't write it to the config
567+
// MaxSlowLogSize int64 `json:"-"` // bytes, 0 = DefaultMaxSlowLogSize. Don't write it to the config
568568
// ...
569569
// }
570570
t.Check(gotConfig.MaxSlowLogSize, Equals, int64(0))

vendor/github.com/percona/pmm/doc/source/.res/code/sql.org

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)