Skip to content

Commit 4dab06e

Browse files
author
Justin Fudally
authored
Merge pull request #833 from github/jfudally-throttle-fix
Throttle on HTTP throttle error
2 parents 78dda8a + 2178b59 commit 4dab06e

File tree

4 files changed

+33
-4
lines changed

4 files changed

+33
-4
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
/bin/
33
/libexec/
44
/.vendor/
5+
.idea/

go/base/context.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ type MigrationContext struct {
119119
ThrottleAdditionalFlagFile string
120120
throttleQuery string
121121
throttleHTTP string
122+
IgnoreHTTPErrors bool
122123
ThrottleCommandedByUser int64
123124
HibernateUntil int64
124125
maxLoad LoadMap
@@ -574,6 +575,13 @@ func (this *MigrationContext) SetThrottleHTTP(throttleHTTP string) {
574575
this.throttleHTTP = throttleHTTP
575576
}
576577

578+
func (this *MigrationContext) SetIgnoreHTTPErrors(ignoreHTTPErrors bool) {
579+
this.throttleHTTPMutex.Lock()
580+
defer this.throttleHTTPMutex.Unlock()
581+
582+
this.IgnoreHTTPErrors = ignoreHTTPErrors
583+
}
584+
577585
func (this *MigrationContext) GetMaxLoad() LoadMap {
578586
this.throttleMutex.Lock()
579587
defer this.throttleMutex.Unlock()

go/cmd/gh-ost/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ func main() {
106106
throttleControlReplicas := flag.String("throttle-control-replicas", "", "List of replicas on which to check for lag; comma delimited. Example: myhost1.com:3306,myhost2.com,myhost3.com:3307")
107107
throttleQuery := flag.String("throttle-query", "", "when given, issued (every second) to check if operation should throttle. Expecting to return zero for no-throttle, >0 for throttle. Query is issued on the migrated server. Make sure this query is lightweight")
108108
throttleHTTP := flag.String("throttle-http", "", "when given, gh-ost checks given URL via HEAD request; any response code other than 200 (OK) causes throttling; make sure it has low latency response")
109+
ignoreHTTPErrors := flag.Bool("ignore-http-errors", false, "ignore HTTP connection errors during throttle check")
109110
heartbeatIntervalMillis := flag.Int64("heartbeat-interval-millis", 100, "how frequently would gh-ost inject a heartbeat value")
110111
flag.StringVar(&migrationContext.ThrottleFlagFile, "throttle-flag-file", "", "operation pauses when this file exists; hint: use a file that is specific to the table being altered")
111112
flag.StringVar(&migrationContext.ThrottleAdditionalFlagFile, "throttle-additional-flag-file", "/tmp/gh-ost.throttle", "operation pauses when this file exists; hint: keep default, use for throttling multiple gh-ost operations")
@@ -259,6 +260,7 @@ func main() {
259260
migrationContext.SetMaxLagMillisecondsThrottleThreshold(*maxLagMillis)
260261
migrationContext.SetThrottleQuery(*throttleQuery)
261262
migrationContext.SetThrottleHTTP(*throttleHTTP)
263+
migrationContext.SetIgnoreHTTPErrors(*ignoreHTTPErrors)
262264
migrationContext.SetDefaultNumRetries(*defaultRetries)
263265
migrationContext.ApplyCredentials()
264266
if err := migrationContext.SetupTLS(); err != nil {

go/logic/throttler.go

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,22 @@ import (
1919
)
2020

2121
var (
22-
httpStatusMessages map[int]string = map[int]string{
22+
httpStatusMessages = map[int]string{
2323
200: "OK",
2424
404: "Not found",
2525
417: "Expectation failed",
2626
429: "Too many requests",
2727
500: "Internal server error",
28+
-1: "Connection error",
2829
}
2930
// See https://github.com/github/freno/blob/master/doc/http.md
30-
httpStatusFrenoMessages map[int]string = map[int]string{
31+
httpStatusFrenoMessages = map[int]string{
3132
200: "OK",
3233
404: "freno: unknown metric",
3334
417: "freno: access forbidden",
3435
429: "freno: threshold exceeded",
3536
500: "freno: internal error",
37+
-1: "freno: connection error",
3638
}
3739
)
3840

@@ -84,6 +86,7 @@ func (this *Throttler) shouldThrottle() (result bool, reason string, reasonHint
8486
if statusCode != 0 && statusCode != http.StatusOK {
8587
return true, this.throttleHttpMessage(int(statusCode)), base.NoThrottleReasonHint
8688
}
89+
8790
// Replication lag throttle
8891
maxLagMillisecondsThrottleThreshold := atomic.LoadInt64(&this.migrationContext.MaxLagMillisecondsThrottleThreshold)
8992
lag := atomic.LoadInt64(&this.migrationContext.CurrentLag)
@@ -288,7 +291,14 @@ func (this *Throttler) collectThrottleHTTPStatus(firstThrottlingCollected chan<-
288291
return false, nil
289292
}
290293

291-
collectFunc()
294+
_, err := collectFunc()
295+
if err != nil {
296+
// If not told to ignore errors, we'll throttle on HTTP connection issues
297+
if !this.migrationContext.IgnoreHTTPErrors {
298+
atomic.StoreInt64(&this.migrationContext.ThrottleHTTPStatusCode, int64(-1))
299+
}
300+
}
301+
292302
firstThrottlingCollected <- true
293303

294304
ticker := time.Tick(100 * time.Millisecond)
@@ -297,7 +307,15 @@ func (this *Throttler) collectThrottleHTTPStatus(firstThrottlingCollected chan<-
297307
return
298308
}
299309

300-
if sleep, _ := collectFunc(); sleep {
310+
sleep, err := collectFunc()
311+
if err != nil {
312+
// If not told to ignore errors, we'll throttle on HTTP connection issues
313+
if !this.migrationContext.IgnoreHTTPErrors {
314+
atomic.StoreInt64(&this.migrationContext.ThrottleHTTPStatusCode, int64(-1))
315+
}
316+
}
317+
318+
if sleep {
301319
time.Sleep(1 * time.Second)
302320
}
303321
}

0 commit comments

Comments
 (0)