diff --git a/pkg/backup.go b/pkg/backup.go index a6693239..d1b1ef5a 100644 --- a/pkg/backup.go +++ b/pkg/backup.go @@ -18,6 +18,7 @@ package pkg import ( "context" + "fmt" "path/filepath" api_v1beta1 "stash.appscode.dev/apimachinery/apis/stash/v1beta1" @@ -219,6 +220,17 @@ func (opt *mysqlOptions) backupMySQL(targetRef api_v1beta1.TargetRef) (*restic.B return nil, err } + databases, err := session.fetchNonSystemDatabases() + if err != nil { + return nil, err + } + + if len(databases) == 0 { + return nil, fmt.Errorf("unable to find any databases for backup") + } + + session.setTargetDatabases(databases) + session.setUserArgs(opt.myArgs) // add backup command in the pipeline diff --git a/pkg/restore.go b/pkg/restore.go index 94ea291a..9bcfaa86 100644 --- a/pkg/restore.go +++ b/pkg/restore.go @@ -161,7 +161,7 @@ func (opt *mysqlOptions) restoreMySQL(targetRef api_v1beta1.TargetRef) (*restic. return nil, err } - session := opt.newSessionWrapper(MySqlRestoreCMD) + session := opt.newSessionWrapper(MySqlCMD) err = session.setDatabaseCredentials(opt.kubeClient, appBinding) if err != nil { diff --git a/pkg/utils.go b/pkg/utils.go index 2a287aeb..7f8f1841 100644 --- a/pkg/utils.go +++ b/pkg/utils.go @@ -43,7 +43,7 @@ const ( MySqlPassword = "password" MySqlDumpFile = "dumpfile.sql" MySqlDumpCMD = "mysqldump" - MySqlRestoreCMD = "mysql" + MySqlCMD = "mysql" EnvMySqlPassword = "MYSQL_PWD" ) @@ -158,3 +158,39 @@ func (session sessionWrapper) waitForDBReady(waitTimeout int32) error { return false, nil }) } + +func (session sessionWrapper) fetchNonSystemDatabases() ([]string, error) { + sh := shell.NewSession() + for k, v := range session.sh.Env { + sh.SetEnv(k, v) + } + + args := append(session.cmd.Args, "--raw", "--execute", "show databases") + out, err := sh.Command(MySqlCMD, args...).Command("tail", "-n+2").Output() + if err != nil { + return nil, err + } + + allDatabases := strings.Split(string(out), "\n") + + var databases []string + for _, db := range allDatabases { + db := strings.TrimSpace(db) + if db != "" && !isSystemDatabase(db) { + databases = append(databases, db) + } + } + + return databases, nil +} + +func isSystemDatabase(db string) bool { + return db == "information_schema" || db == "mysql" || db == "performance_schema" || db == "sys" +} + +func (session *sessionWrapper) setTargetDatabases(databases []string) { + session.cmd.Args = append(session.cmd.Args, "--databases") + for _, db := range databases { + session.cmd.Args = append(session.cmd.Args, db) + } +}