diff --git a/go/cmd/vtbackup/plugin_prometheusbackend.go b/go/cmd/vtbackup/plugin_prometheusbackend.go new file mode 100644 index 00000000000..de4ecbb5e9f --- /dev/null +++ b/go/cmd/vtbackup/plugin_prometheusbackend.go @@ -0,0 +1,31 @@ +/* +Copyright 2022 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +// This plugin imports Prometheus to allow for instrumentation +// with the Prometheus client library + +import ( + "vitess.io/vitess/go/stats/prometheusbackend" + "vitess.io/vitess/go/vt/servenv" +) + +func init() { + servenv.OnRun(func() { + prometheusbackend.Init("vtbackup") + }) +} diff --git a/go/cmd/vtbackup/vtbackup.go b/go/cmd/vtbackup/vtbackup.go index fd1aedcb3b0..3c595f6ae67 100644 --- a/go/cmd/vtbackup/vtbackup.go +++ b/go/cmd/vtbackup/vtbackup.go @@ -64,7 +64,6 @@ import ( "math" "math/big" "os" - "os/signal" "strings" "syscall" "time" @@ -113,11 +112,12 @@ var ( initShard string concurrency = 4 // mysqlctld-like flags - mysqlPort = 3306 - mysqlSocket string - mysqlTimeout = 5 * time.Minute - initDBSQLFile string - detachedMode bool + mysqlPort = 3306 + mysqlSocket string + mysqlTimeout = 5 * time.Minute + initDBSQLFile string + detachedMode bool + keepAliveTimeout = 0 * time.Second ) func registerFlags(fs *pflag.FlagSet) { @@ -138,19 +138,36 @@ func registerFlags(fs *pflag.FlagSet) { fs.DurationVar(&mysqlTimeout, "mysql_timeout", mysqlTimeout, "how long to wait for mysqld startup") fs.StringVar(&initDBSQLFile, "init_db_sql_file", initDBSQLFile, "path to .sql file to run after mysql_install_db") fs.BoolVar(&detachedMode, "detach", detachedMode, "detached mode - run backups detached from the terminal") + fs.DurationVar(&keepAliveTimeout, "keep-alive-timeout", keepAliveTimeout, "Wait until timeout elapses after a successful backup before shutting down.") acl.RegisterFlags(fs) } func init() { + servenv.RegisterDefaultFlags() + dbconfigs.RegisterFlags(dbconfigs.All...) + mysqlctl.RegisterFlags() servenv.OnParse(registerFlags) } func main() { defer exit.Recover() - dbconfigs.RegisterFlags(dbconfigs.All...) - mysqlctl.RegisterFlags() + servenv.ParseFlags("vtbackup") + servenv.Init() + + ctx, cancel := context.WithCancel(context.Background()) + servenv.OnClose(func() { + cancel() + }) + + defer func() { + servenv.ExitChan <- syscall.SIGTERM + <-ctx.Done() + }() + + go servenv.RunDefault() + if detachedMode { // this method will call os.Exit and kill this process cmd.DetachFromTerminalAndExit() @@ -163,16 +180,6 @@ func main() { exit.Return(1) } - // Catch SIGTERM and SIGINT so we get a chance to clean up. - ctx, cancel := context.WithCancel(context.Background()) - sigChan := make(chan os.Signal, 1) - signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) - go func() { - sig := <-sigChan - log.Infof("Cancelling due to signal: %v", sig) - cancel() - }() - // Open connection backup storage. backupStorage, err := backupstorage.GetBackupStorage() if err != nil { @@ -205,6 +212,15 @@ func main() { log.Errorf("Couldn't prune old backups: %v", err) exit.Return(1) } + + if keepAliveTimeout > 0 { + log.Infof("Backup was successful, waiting %s before exiting (or until context expires).", keepAliveTimeout) + select { + case <-time.After(keepAliveTimeout): + case <-ctx.Done(): + } + } + log.Info("Exiting.") } func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage backupstorage.BackupStorage) error { diff --git a/go/flags/endtoend/vtbackup.txt b/go/flags/endtoend/vtbackup.txt index 888a266d6c7..6abe64f5ecd 100644 --- a/go/flags/endtoend/vtbackup.txt +++ b/go/flags/endtoend/vtbackup.txt @@ -168,6 +168,7 @@ Usage of vtbackup: --init_keyspace string (init parameter) keyspace to use for this tablet --init_shard string (init parameter) shard to use for this tablet --initial_backup Instead of restoring from backup, initialize an empty database with the provided init_db_sql_file and upload a backup of that for the shard, if the shard has no backups yet. This can be used to seed a brand new shard with an initial, empty backup. If any backups already exist for the shard, this will be considered a successful no-op. This can only be done before the shard exists in topology (i.e. before any tablets are deployed). + --keep-alive-timeout duration Wait until timeout elapses after a successful backup before shutting down. --keep_logs duration keep logs for this long (using ctime) (zero to keep forever) --keep_logs_by_mtime duration keep logs for this long (using mtime) (zero to keep forever) --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) @@ -200,6 +201,7 @@ Usage of vtbackup: --mysql_server_version string MySQL server version to advertise. --mysql_socket string path to the mysql socket --mysql_timeout duration how long to wait for mysqld startup (default 5m0s) + --port int port for the server --pprof strings enable profiling --purge_logs_interval duration how often try to remove old logs (default 1h0m0s) --remote_operation_timeout duration time to wait for a remote operation (default 30s)