From be8a023350edbc4932f5b85e9257178da1952add Mon Sep 17 00:00:00 2001 From: Shlomi Noach Date: Thu, 28 Jul 2016 14:37:17 +0200 Subject: [PATCH] nice-ratio is now float64 --- go/base/context.go | 22 +++++++++++++++++++++- go/cmd/gh-ost/main.go | 3 ++- go/logic/migrator.go | 13 +++++++------ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/go/base/context.go b/go/base/context.go index b580005..f906aeb 100644 --- a/go/base/context.go +++ b/go/base/context.go @@ -63,7 +63,7 @@ type MigrationContext struct { defaultNumRetries int64 ChunkSize int64 - NiceRatio int64 + niceRatio float64 MaxLagMillisecondsThrottleThreshold int64 replicationLagQuery string throttleControlReplicaKeys *mysql.InstanceKeyMap @@ -382,6 +382,26 @@ func (this *MigrationContext) GetCriticalLoad() LoadMap { return this.criticalLoad.Duplicate() } +func (this *MigrationContext) GetNiceRatio() float64 { + this.throttleMutex.Lock() + defer this.throttleMutex.Unlock() + + return this.niceRatio +} + +func (this *MigrationContext) SetNiceRatio(newRatio float64) { + if newRatio < 0.0 { + newRatio = 0.0 + } + if newRatio > 100.0 { + newRatio = 100.0 + } + + this.throttleMutex.Lock() + defer this.throttleMutex.Unlock() + this.niceRatio = newRatio +} + // ReadMaxLoad parses the `--max-load` flag, which is in multiple key-value format, // such as: 'Threads_running=100,Threads_connected=500' // It only applies changes in case there's no parsing error. diff --git a/go/cmd/gh-ost/main.go b/go/cmd/gh-ost/main.go index b925b91..a3178a7 100644 --- a/go/cmd/gh-ost/main.go +++ b/go/cmd/gh-ost/main.go @@ -72,7 +72,7 @@ func main() { chunkSize := flag.Int64("chunk-size", 1000, "amount of rows to handle in each iteration (allowed range: 100-100,000)") defaultRetries := flag.Int64("default-retries", 60, "Default number of retries for various operations before panicking") cutOverLockTimeoutSeconds := flag.Int64("cut-over-lock-timeout-seconds", 3, "Max number of seconds to hold locks on tables while attempting to cut-over (retry attempted when lock exceeds timeout)") - flag.Int64Var(&migrationContext.NiceRatio, "nice-ratio", 0, "force being 'nice', imply sleep time per chunk time. Example values: 0 is aggressive. 3: for every ms spend in a rowcopy chunk, spend 3ms sleeping immediately after") + niceRatio := flag.Float64("nice-ratio", 0, "force being 'nice', imply sleep time per chunk time; range: [0.0..100.0]. Example values: 0 is aggressive. 1.5: for every ms spend in a rowcopy chunk, spend 1.5ms sleeping immediately after") maxLagMillis := flag.Int64("max-lag-millis", 1500, "replication lag at which to throttle operation") replicationLagQuery := flag.String("replication-lag-query", "", "Query that detects replication lag in seconds. Result can be a floating point (by default gh-ost issues SHOW SLAVE STATUS and reads Seconds_behind_master). If you're using pt-heartbeat, query would be something like: SELECT ROUND(UNIX_TIMESTAMP() - MAX(UNIX_TIMESTAMP(ts))) AS delay FROM my_schema.heartbeat") @@ -169,6 +169,7 @@ func main() { if migrationContext.ServeSocketFile == "" { migrationContext.ServeSocketFile = fmt.Sprintf("/tmp/gh-ost.%s.%s.sock", migrationContext.DatabaseName, migrationContext.OriginalTableName) } + migrationContext.SetNiceRatio(*niceRatio) migrationContext.SetChunkSize(*chunkSize) migrationContext.SetMaxLagMillisecondsThrottleThreshold(*maxLagMillis) migrationContext.SetReplicationLagQuery(*replicationLagQuery) diff --git a/go/logic/migrator.go b/go/logic/migrator.go index 310331e..1ef71bb 100644 --- a/go/logic/migrator.go +++ b/go/logic/migrator.go @@ -705,11 +705,11 @@ help # This message } case "nice-ratio": { - if niceRatio, err := strconv.Atoi(arg); err != nil { + if niceRatio, err := strconv.ParseFloat(arg, 64); err != nil { fmt.Fprintf(writer, "%s\n", err.Error()) return log.Errore(err) } else { - atomic.StoreInt64(&this.migrationContext.NiceRatio, int64(niceRatio)) + this.migrationContext.SetNiceRatio(niceRatio) this.printStatus(ForcePrintStatusAndHint, writer) } } @@ -866,12 +866,12 @@ func (this *Migrator) printMigrationStatusHint(writers ...io.Writer) { )) maxLoad := this.migrationContext.GetMaxLoad() criticalLoad := this.migrationContext.GetCriticalLoad() - fmt.Fprintln(w, fmt.Sprintf("# chunk-size: %+v; max-lag-millis: %+vms; max-load: %s; critical-load: %s; nice-ratio: %d", + fmt.Fprintln(w, fmt.Sprintf("# chunk-size: %+v; max-lag-millis: %+vms; max-load: %s; critical-load: %s; nice-ratio: %f", atomic.LoadInt64(&this.migrationContext.ChunkSize), atomic.LoadInt64(&this.migrationContext.MaxLagMillisecondsThrottleThreshold), maxLoad.String(), criticalLoad.String(), - atomic.LoadInt64(&this.migrationContext.NiceRatio), + this.migrationContext.GetNiceRatio(), )) if replicationLagQuery := this.migrationContext.GetReplicationLagQuery(); replicationLagQuery != "" { fmt.Fprintln(w, fmt.Sprintf("# Replication lag query: %+v", @@ -1190,9 +1190,10 @@ func (this *Migrator) executeWriteFuncs() error { if err := copyRowsFunc(); err != nil { return log.Errore(err) } - if niceRatio := atomic.LoadInt64(&this.migrationContext.NiceRatio); niceRatio > 0 { + if niceRatio := this.migrationContext.GetNiceRatio(); niceRatio > 0 { copyRowsDuration := time.Now().Sub(copyRowsStartTime) - sleepTime := copyRowsDuration * time.Duration(niceRatio) + sleepTimeNanosecondFloat64 := niceRatio * float64(copyRowsDuration.Nanoseconds()) + sleepTime := time.Duration(time.Duration(int64(sleepTimeNanosecondFloat64)) * time.Nanosecond) time.Sleep(sleepTime) } }