diff --git a/build.sh b/build.sh index deb0e83..5e960f8 100644 --- a/build.sh +++ b/build.sh @@ -1,7 +1,7 @@ #!/bin/bash # # -RELEASE_VERSION="0.7.17" +RELEASE_VERSION="0.8.2" buildpath=/tmp/gh-ost target=gh-ost diff --git a/go/cmd/gh-ost/main.go b/go/cmd/gh-ost/main.go index 57dfc5f..d5218c9 100644 --- a/go/cmd/gh-ost/main.go +++ b/go/cmd/gh-ost/main.go @@ -9,6 +9,8 @@ import ( "flag" "fmt" "os" + "os/signal" + "syscall" "github.com/github/gh-ost/go/base" "github.com/github/gh-ost/go/logic" @@ -17,6 +19,26 @@ import ( var AppVersion string +// acceptSignals registers for OS signals +func acceptSignals(migrationContext *base.MigrationContext) { + c := make(chan os.Signal, 1) + + signal.Notify(c, syscall.SIGHUP) + go func() { + for sig := range c { + switch sig { + case syscall.SIGHUP: + log.Infof("Received SIGHUP. Reloading configuration") + if err := migrationContext.ReadConfigFile(); err != nil { + log.Errore(err) + } else { + migrationContext.MarkPointOfInterest() + } + } + } + }() +} + // main is the application's entry point. It will either spawn a CLI or HTTP itnerfaces. func main() { migrationContext := base.GetMigrationContext() @@ -122,6 +144,7 @@ func main() { migrationContext.ApplyCredentials() log.Infof("starting gh-ost %+v", AppVersion) + acceptSignals(migrationContext) migrator := logic.NewMigrator() err := migrator.Migrate() diff --git a/go/logic/migrator.go b/go/logic/migrator.go index 7dc32a7..cc50fda 100644 --- a/go/logic/migrator.go +++ b/go/logic/migrator.go @@ -578,8 +578,21 @@ func (this *Migrator) printStatus() { if rowsEstimate > 0 { progressPct = 100.0 * float64(totalRowsCopied) / float64(rowsEstimate) } - var etaSeconds float64 = math.MaxFloat64 + // Before status, let's see if we should print a nice reminder for what exactly we're doing here. + shouldPrintCourtesyReminder := (elapsedSeconds%600 == 0) + if shouldPrintCourtesyReminder { + courtesyReminder := fmt.Sprintf("# Migrating %s.%s; Ghost table is %s.%s; migration started at %+v", + sql.EscapeName(this.migrationContext.DatabaseName), + sql.EscapeName(this.migrationContext.OriginalTableName), + sql.EscapeName(this.migrationContext.DatabaseName), + sql.EscapeName(this.migrationContext.GetGhostTableName()), + this.migrationContext.StartTime.Format(time.RubyDate), + ) + fmt.Println(courtesyReminder) + } + + var etaSeconds float64 = math.MaxFloat64 eta := "N/A" if isThrottled, throttleReason := this.migrationContext.IsThrottled(); isThrottled { eta = fmt.Sprintf("throttled, %s", throttleReason) @@ -606,7 +619,7 @@ func (this *Migrator) printStatus() { shouldPrintStatus = (elapsedSeconds%5 == 0) } else if elapsedSeconds <= 180 { shouldPrintStatus = (elapsedSeconds%5 == 0) - } else if this.migrationContext.TimeSincePointOfInterest() <= 60 { + } else if this.migrationContext.TimeSincePointOfInterest().Seconds() <= 60 { shouldPrintStatus = (elapsedSeconds%5 == 0) } else { shouldPrintStatus = (elapsedSeconds%30 == 0) diff --git a/go/logic/streamer.go b/go/logic/streamer.go index e6beaa2..255bf9f 100644 --- a/go/logic/streamer.go +++ b/go/logic/streamer.go @@ -189,6 +189,7 @@ func (this *EventsStreamer) StreamEvents(canStopStreaming func() bool) error { for { if err := this.binlogReader.StreamEvents(canStopStreaming, this.eventsChannel); err != nil { log.Infof("StreamEvents encountered unexpected error: %+v", err) + this.migrationContext.MarkPointOfInterest() time.Sleep(ReconnectStreamerSleepSeconds * time.Second) // Reposition at same binlog file. Single attempt (TODO: make multiple attempts?)