diff --git a/cluster/cluster.go b/cluster/cluster.go index db7a53d3b..c4ada5b7e 100644 --- a/cluster/cluster.go +++ b/cluster/cluster.go @@ -717,48 +717,59 @@ func (cluster *Cluster) StateProcessing() { cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlInfo, "Sending master physical backup to reseed %s", s.ServerUrl) if master != nil { backupext := ".xbtream" + task := "reseed" + cluster.Conf.BackupPhysicalType if cluster.Conf.CompressBackups { backupext = backupext + ".gz" } if mybcksrv != nil { - go cluster.SSTRunSender(mybcksrv.GetMyBackupDirectory()+cluster.Conf.BackupPhysicalType+backupext, servertoreseed) + go cluster.SSTRunSender(mybcksrv.GetMyBackupDirectory()+cluster.Conf.BackupPhysicalType+backupext, servertoreseed, task) } else { - go cluster.SSTRunSender(master.GetMasterBackupDirectory()+cluster.Conf.BackupPhysicalType+backupext, servertoreseed) + go cluster.SSTRunSender(master.GetMasterBackupDirectory()+cluster.Conf.BackupPhysicalType+backupext, servertoreseed, task) } } else { cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlErr, "No master cancel backup reseeding %s", s.ServerUrl) } } if s.ErrKey == "WARN0075" { - cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlInfo, "Sending master logical backup to reseed %s", s.ServerUrl) - if master != nil { - if mybcksrv != nil { - go cluster.SSTRunSender(mybcksrv.GetMyBackupDirectory()+"mysqldump.sql.gz", servertoreseed) - } else { - go cluster.SSTRunSender(master.GetMasterBackupDirectory()+"mysqldump.sql.gz", servertoreseed) - } - } else { - cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlErr, "No master cancel backup reseeding %s", s.ServerUrl) - } + /* + This action is inactive due to direct function from Job + */ + // //Only mysqldump exists in the script + // task := "reseed" + cluster.Conf.BackupLogicalType + // cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlInfo, "Sending master logical backup to reseed %s", s.ServerUrl) + // if master != nil { + // if mybcksrv != nil { + // go cluster.SSTRunSender(mybcksrv.GetMyBackupDirectory()+"mysqldump.sql.gz", servertoreseed, task) + // } else { + // go cluster.SSTRunSender(master.GetMasterBackupDirectory()+"mysqldump.sql.gz", servertoreseed, task) + // } + // } else { + // cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlErr, "No master cancel backup reseeding %s", s.ServerUrl) + // } } if s.ErrKey == "WARN0076" { + task := "flashback" + cluster.Conf.BackupPhysicalType cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlInfo, "Sending server physical backup to flashback reseed %s", s.ServerUrl) if mybcksrv != nil { - go cluster.SSTRunSender(mybcksrv.GetMyBackupDirectory()+cluster.Conf.BackupPhysicalType+".xbtream", servertoreseed) + go cluster.SSTRunSender(mybcksrv.GetMyBackupDirectory()+cluster.Conf.BackupPhysicalType+".xbtream", servertoreseed, task) } else { - go cluster.SSTRunSender(servertoreseed.GetMyBackupDirectory()+cluster.Conf.BackupPhysicalType+".xbtream", servertoreseed) + go cluster.SSTRunSender(servertoreseed.GetMyBackupDirectory()+cluster.Conf.BackupPhysicalType+".xbtream", servertoreseed, task) } } if s.ErrKey == "WARN0077" { - - cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlInfo, "Sending logical backup to flashback reseed %s", s.ServerUrl) - if mybcksrv != nil { - go cluster.SSTRunSender(mybcksrv.GetMyBackupDirectory()+"mysqldump.sql.gz", servertoreseed) - } else { - go cluster.SSTRunSender(servertoreseed.GetMyBackupDirectory()+"mysqldump.sql.gz", servertoreseed) - } + /* + This action is inactive due to direct function from rejoin + */ + // //Only mysqldump exists in the script + // task := "flashback" + cluster.Conf.BackupLogicalType + // cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlInfo, "Sending logical backup to flashback reseed %s", s.ServerUrl) + // if mybcksrv != nil { + // go cluster.SSTRunSender(mybcksrv.GetMyBackupDirectory()+"mysqldump.sql.gz", servertoreseed, task) + // } else { + // go cluster.SSTRunSender(servertoreseed.GetMyBackupDirectory()+"mysqldump.sql.gz", servertoreseed, task) + // } } if s.ErrKey == "WARN0101" { cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlInfo, "Cluster have backup") diff --git a/cluster/cluster_acl.go b/cluster/cluster_acl.go index 9d544659c..a33e488a1 100644 --- a/cluster/cluster_acl.go +++ b/cluster/cluster_acl.go @@ -579,7 +579,7 @@ func (cluster *Cluster) IsURLPassACL(strUser string, URL string) bool { if strings.Contains(URL, "/api/clusters/"+cluster.Name+"/settings/actions/discover") { return true } - if strings.Contains(URL, "/api/clusters/"+cluster.Name+"/settings/actions/reset-failover-control") { + if strings.Contains(URL, "/api/clusters/"+cluster.Name+"/actions/reset-failover-control") { return true } } diff --git a/cluster/cluster_sst.go b/cluster/cluster_sst.go index a96d2825d..b229be536 100644 --- a/cluster/cluster_sst.go +++ b/cluster/cluster_sst.go @@ -428,11 +428,13 @@ func (sst *SST) stream_copy_to_restic() <-chan int { return sync_channel } -func (cluster *Cluster) SSTRunSender(backupfile string, sv *ServerMonitor) { +func (cluster *Cluster) SSTRunSender(backupfile string, sv *ServerMonitor, task string) { port, _ := strconv.Atoi(sv.SSTPort) + cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModSST, config.LvlWarn, "SST Reseed to port %s server %s", sv.SSTPort, sv.Host) + if cluster.Conf.SchedulerReceiverUseSSL { - cluster.SSTRunSenderSSL(backupfile, sv) + cluster.SSTRunSenderSSL(backupfile, sv, task) return } @@ -457,6 +459,10 @@ func (cluster *Cluster) SSTRunSender(backupfile string, sv *ServerMonitor) { sendBuffer := make([]byte, cluster.Conf.SSTSendBuffer) //fmt.Println("Start sending file!") var total uint64 + + defer file.Close() + defer sv.RunTaskCallback(task) + for { if strings.Contains(backupfile, "gz") { fz, err := gzip.NewReader(file) @@ -480,11 +486,9 @@ func (cluster *Cluster) SSTRunSender(backupfile string, sv *ServerMonitor) { } cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModSST, config.LvlInfo, "Backup has been sent, closing connection!") - defer file.Close() - } -func (cluster *Cluster) SSTRunSenderSSL(backupfile string, sv *ServerMonitor) { +func (cluster *Cluster) SSTRunSenderSSL(backupfile string, sv *ServerMonitor, task string) { var ( client *tls.Conn err error @@ -505,6 +509,9 @@ func (cluster *Cluster) SSTRunSenderSSL(backupfile string, sv *ServerMonitor) { } sendBuffer := make([]byte, 16384) var total uint64 + + defer file.Close() + defer sv.RunTaskCallback(task) for { _, err = file.Read(sendBuffer) if err == io.EOF { diff --git a/cluster/cluster_tgl.go b/cluster/cluster_tgl.go index a6b52a8da..824820591 100644 --- a/cluster/cluster_tgl.go +++ b/cluster/cluster_tgl.go @@ -204,7 +204,14 @@ func (cluster *Cluster) SwitchRejoinPhysicalBackup() { func (cluster *Cluster) SwitchRejoinBackupBinlog() { cluster.Conf.AutorejoinBackupBinlog = !cluster.Conf.AutorejoinBackupBinlog } - +func (cluster *Cluster) SwitchRejoinForceRestore() { + out := "N" + cluster.Conf.AutorejoinForceRestore = !cluster.Conf.AutorejoinForceRestore + if cluster.Conf.AutorejoinForceRestore { + out = "Y" + } + cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlInfo, "Autorejoin active: %s", out) +} func (cluster *Cluster) SwitchRejoinSemisync() { cluster.Conf.AutorejoinSemisync = !cluster.Conf.AutorejoinSemisync } diff --git a/cluster/srv.go b/cluster/srv.go index 91b573c62..4adfde585 100644 --- a/cluster/srv.go +++ b/cluster/srv.go @@ -189,7 +189,9 @@ type ServerMonitor struct { IsInPFSQueryCapture bool InPurgingBinaryLog bool IsBackingUpBinaryLog bool + ActiveTasks sync.Map BinaryLogDir string + DBDataDir string sync.Mutex } diff --git a/cluster/srv_cnf.go b/cluster/srv_cnf.go index 2244b55ce..eecff7d36 100644 --- a/cluster/srv_cnf.go +++ b/cluster/srv_cnf.go @@ -8,8 +8,10 @@ package cluster import ( "strconv" + "strings" "github.com/signal18/replication-manager/config" + "github.com/signal18/replication-manager/utils/dbhelper" "github.com/signal18/replication-manager/utils/misc" ) @@ -94,9 +96,16 @@ func (server *ServerMonitor) GetDatabaseDatadir() string { } else if server.ClusterGroup.Conf.ProvOrchestrator == config.ConstOrchestratorSlapOS { return server.SlapOSDatadir + "/var/lib/mysql" } else if server.ClusterGroup.Conf.ProvOrchestrator == config.ConstOrchestratorOnPremise { - value := server.GetConfigVariable("DATADIR") - if value != "" { - return value + if server.DBDataDir == "" { + //Not using Variables[] due to uppercase values + if value, _, err := dbhelper.GetVariableByName(server.Conn, "DATADIR", server.DBVersion); err == nil { + value, _ := strings.CutSuffix(value, "/") + + server.DBDataDir = value + return server.DBDataDir + } + } else { + return server.DBDataDir } } return "/var/lib/mysql" diff --git a/cluster/srv_job.go b/cluster/srv_job.go index f8eb4bf16..b7e865c8c 100644 --- a/cluster/srv_job.go +++ b/cluster/srv_job.go @@ -168,6 +168,7 @@ func (server *ServerMonitor) JobReseedPhysicalBackup() (int64, error) { Heartbeat: strconv.Itoa(cluster.Conf.ForceSlaveHeartbeatTime), Mode: "SLAVE_POS", SSL: cluster.Conf.ReplicationSSL, + Channel: cluster.Conf.MasterConn, }, server.DBVersion) cluster.LogSQL(logs, err, server.URL, "Rejoin", config.LvlErr, "Reseed can't changing master for physical backup %s request for server: %s %s", cluster.Conf.BackupPhysicalType, server.URL, err) @@ -220,18 +221,27 @@ func (server *ServerMonitor) JobFlashbackPhysicalBackup() (int64, error) { func (server *ServerMonitor) JobReseedLogicalBackup() (int64, error) { cluster := server.ClusterGroup + task := "reseed" + cluster.Conf.BackupLogicalType + var dt DBTask = DBTask{task: task} if cluster.master != nil && !cluster.GetBackupServer().HasBackupLogicalCookie() { server.createCookie("cookie_waitbackup") return 0, errors.New("No Logical Backup") } - jobid, err := server.JobInsertTaks("reseed"+cluster.Conf.BackupLogicalType, server.SSTPort, cluster.Conf.MonitorAddress) + if v, ok := server.ActiveTasks.Load(task); ok { + dt = v.(DBTask) + } + jobid, err := server.JobInsertTaks(task, server.SSTPort, cluster.Conf.MonitorAddress) if err != nil { cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlErr, "Receive reseed logical backup %s request for server: %s %s", cluster.Conf.BackupLogicalType, server.URL, err) - return jobid, err + } else { + dt.ct++ + dt.id = jobid + server.ActiveTasks.Store(task, dt) } + logs, err := server.StopSlave() cluster.LogSQL(logs, err, server.URL, "Rejoin", config.LvlErr, "Failed stop slave on server: %s %s", server.URL, err) @@ -244,6 +254,7 @@ func (server *ServerMonitor) JobReseedLogicalBackup() (int64, error) { Heartbeat: strconv.Itoa(cluster.Conf.ForceSlaveHeartbeatTime), Mode: "SLAVE_POS", SSL: cluster.Conf.ReplicationSSL, + Channel: cluster.Conf.MasterConn, }, server.DBVersion) cluster.LogSQL(logs, err, server.URL, "Rejoin", config.LvlErr, "Reseed can't changing master for logical backup %s request for server: %s %s", cluster.Conf.BackupPhysicalType, server.URL, err) if err != nil { @@ -251,7 +262,9 @@ func (server *ServerMonitor) JobReseedLogicalBackup() (int64, error) { return jobid, err } cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlInfo, "Receive reseed logical backup %s request for server: %s", cluster.Conf.BackupLogicalType, server.URL) - if cluster.Conf.BackupLogicalType == config.ConstBackupLogicalTypeMydumper { + if cluster.Conf.BackupLogicalType == config.ConstBackupLogicalTypeMysqldump { + go server.JobReseedMysqldump(task) + } else if cluster.Conf.BackupLogicalType == config.ConstBackupLogicalTypeMydumper { go server.JobReseedMyLoader() } return jobid, err @@ -279,15 +292,24 @@ func (server *ServerMonitor) JobServerRestart() (int64, error) { func (server *ServerMonitor) JobFlashbackLogicalBackup() (int64, error) { cluster := server.ClusterGroup + task := "flashback" + cluster.Conf.BackupLogicalType + var dt DBTask = DBTask{task: task} + var err error if cluster.master != nil && !cluster.GetBackupServer().HasBackupLogicalCookie() { server.createCookie("cookie_waitbackup") return 0, errors.New("No Logical Backup") } - jobid, err := server.JobInsertTaks("flashback"+cluster.Conf.BackupLogicalType, server.SSTPort, cluster.Conf.MonitorAddress) + if v, ok := server.ActiveTasks.Load(task); ok { + dt = v.(DBTask) + } + jobid, err := server.JobInsertTaks(task, server.SSTPort, cluster.Conf.MonitorAddress) if err != nil { - cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlErr, "Receive reseed logical backup %s request for server: %s %s", cluster.Conf.BackupPhysicalType, server.URL, err) - + cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlErr, "Receive flashback logical backup %s request for server: %s %s", cluster.Conf.BackupLogicalType, server.URL, err) return jobid, err + } else { + dt.ct++ + dt.id = jobid + server.ActiveTasks.Store(task, dt) } logs, err := server.StopSlave() cluster.LogSQL(logs, err, server.URL, "Rejoin", config.LvlErr, "Failed stop slave on server: %s %s", server.URL, err) @@ -301,15 +323,19 @@ func (server *ServerMonitor) JobFlashbackLogicalBackup() (int64, error) { Heartbeat: strconv.Itoa(cluster.Conf.ForceSlaveHeartbeatTime), Mode: "SLAVE_POS", SSL: cluster.Conf.ReplicationSSL, + Channel: cluster.Conf.MasterConn, }, server.DBVersion) - cluster.LogSQL(logs, err, server.URL, "Rejoin", config.LvlErr, "Reseed can't changing master for logical backup %s request for server: %s %s", cluster.Conf.BackupPhysicalType, server.URL, err) + cluster.LogSQL(logs, err, server.URL, "Rejoin", config.LvlErr, "flashback can't changing master for logical backup %s request for server: %s %s", cluster.Conf.BackupLogicalType, server.URL, err) if err != nil { return jobid, err } - cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlInfo, "Receive reseed logical backup %s request for server: %s", cluster.Conf.BackupPhysicalType, server.URL) + cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlInfo, "Receive flashback logical backup %s request for server: %s", cluster.Conf.BackupLogicalType, server.URL) if cluster.Conf.BackupLoadScript != "" { + cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlInfo, "Using script from backup-load-script on %s", server.URL) go server.JobReseedBackupScript() + } else if cluster.Conf.BackupLogicalType == config.ConstBackupLogicalTypeMysqldump { + go server.JobReseedMysqldump(task) } else if cluster.Conf.BackupLogicalType == config.ConstBackupLogicalTypeMydumper { go server.JobReseedMyLoader() } @@ -416,6 +442,9 @@ func (server *ServerMonitor) JobReseedMyLoader() { threads := strconv.Itoa(cluster.Conf.BackupLogicalLoadThreads) myargs := strings.Split(strings.ReplaceAll(cluster.Conf.BackupMyLoaderOptions, " ", " "), " ") + if server.URL == cluster.GetMaster().URL { + myargs = append(myargs, "--enable-binlog") + } myargs = append(myargs, "--directory="+cluster.master.GetMasterBackupDirectory(), "--threads="+threads, "--host="+misc.Unbracket(server.Host), "--port="+server.Port, "--user="+cluster.GetDbUser(), "--password="+cluster.GetDbPass()) dumpCmd := exec.Command(cluster.GetMyLoaderPath(), myargs...) @@ -456,6 +485,24 @@ func (server *ServerMonitor) JobReseedMyLoader() { } +func (server *ServerMonitor) JobReseedMysqldump(task string) { + cluster := server.ClusterGroup + mybcksrv := cluster.GetBackupServer() + master := cluster.GetMaster() + go server.JobRunViaSSH() + + cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlInfo, "Sending logical backup to reseed %s", server.URL) + if master != nil { + if mybcksrv != nil { + go cluster.SSTRunSender(mybcksrv.GetMyBackupDirectory()+"mysqldump.sql.gz", server, task) + } else { + go cluster.SSTRunSender(master.GetMasterBackupDirectory()+"mysqldump.sql.gz", server, task) + } + } else { + cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlErr, "No master. Cancel backup reseeding %s", server.URL) + } +} + func (server *ServerMonitor) JobReseedBackupScript() { cluster := server.ClusterGroup cmd := exec.Command(cluster.Conf.BackupLoadScript, misc.Unbracket(server.Host), misc.Unbracket(cluster.master.Host)) @@ -541,17 +588,19 @@ func (server *ServerMonitor) JobMyLoaderParseMeta(dir string) (config.MyDumperMe return m, nil } +type DBTask struct { + task string + ct int + id int64 +} + func (server *ServerMonitor) JobsCheckRunning() error { cluster := server.ClusterGroup if server.IsDown() { return nil } //server.JobInsertTaks("", "", "") - type DBTask struct { - task string - ct int - } - rows, err := server.Conn.Queryx("SELECT task ,count(*) as ct FROM replication_manager_schema.jobs WHERE done=0 AND result IS NULL group by task ") + rows, err := server.Conn.Queryx("SELECT task ,count(*) as ct, max(id) as id FROM replication_manager_schema.jobs WHERE done=0 AND result IS NULL group by task ") if err != nil { cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlErr, "Scheduler error fetching replication_manager_schema.jobs %s", err) server.JobsCreateTable() @@ -560,7 +609,7 @@ func (server *ServerMonitor) JobsCheckRunning() error { defer rows.Close() for rows.Next() { var task DBTask - rows.Scan(&task.task, &task.ct) + rows.Scan(&task.task, &task.ct, &task.id) if task.ct > 0 { if task.ct > 10 { cluster.StateMachine.AddState("ERR00060", state.State{ErrType: "WARNING", ErrDesc: fmt.Sprintf(cluster.GetErrorList()["ERR00060"], server.URL), ErrFrom: "JOB", ServerUrl: server.URL}) @@ -596,8 +645,11 @@ func (server *ServerMonitor) JobsCheckRunning() error { cluster.StateMachine.AddState("WARN0077", state.State{ErrType: "WARNING", ErrDesc: fmt.Sprintf(cluster.GetErrorList()["WARN0077"], cluster.Conf.BackupLogicalType, server.URL), ErrFrom: "JOB", ServerUrl: server.URL}) } else if task.task == "flashbackmysqldump" { cluster.StateMachine.AddState("WARN0077", state.State{ErrType: "WARNING", ErrDesc: fmt.Sprintf(cluster.GetErrorList()["WARN0077"], cluster.Conf.BackupLogicalType, server.URL), ErrFrom: "JOB", ServerUrl: server.URL}) + } else { + //Skip adding to active task if not defined + continue } - + server.ActiveTasks.Store(task.task, task) } } @@ -844,7 +896,7 @@ func (server *ServerMonitor) JobBackupLogical() error { // --no-schemas --regex '^(?!(mysql))' threads := strconv.Itoa(cluster.Conf.BackupLogicalDumpThreads) - myargs := strings.Split(strings.ReplaceAll(cluster.Conf.BackupMyLoaderOptions, " ", " "), " ") + myargs := strings.Split(strings.ReplaceAll(cluster.Conf.BackupMyDumperOptions, " ", " "), " ") myargs = append(myargs, "--outputdir="+server.GetMyBackupDirectory(), "--threads="+threads, "--host="+misc.Unbracket(server.Host), "--port="+server.Port, "--user="+cluster.GetDbUser(), "--password="+cluster.GetDbPass()) dumpCmd := exec.Command(cluster.GetMyDumperPath(), myargs...) @@ -1377,3 +1429,54 @@ func (server *ServerMonitor) InitiateJobBackupBinlog(binlogfile string, isPurge return errors.New("Wrong configuration for Backup Binlog Method!") } + +func (server *ServerMonitor) RunTaskCallback(task string) error { + cluster := server.ClusterGroup + var err error + + if v, ok := server.ActiveTasks.Load(task); ok { + dt := v.(DBTask) + switch dt.task { + case "reseedmysqldump", "flashbackmysqldump": + go server.CallbackMysqldump(dt) + } + } else { + err = errors.New("No active task found!") + cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlErr, "Error executing callback, %s", err.Error()) + } + + return err +} + +func (server *ServerMonitor) CallbackMysqldump(dt DBTask) error { + cluster := server.ClusterGroup + var err error + + rows, err := server.Conn.Queryx("SELECT done FROM replication_manager_schema.jobs WHERE id=?", dt.id) + if err != nil { + cluster.LogModulePrintf(cluster.Conf.Verbose, config.ConstLogModGeneral, config.LvlErr, "Scheduler error fetching replication_manager_schema.jobs %s", err) + server.JobsCreateTable() + return err + } + + var done int + var count int = 0 + defer rows.Close() + for rows.Next() { + rows.Scan(&done) + count++ + } + + //Check if id exists + if count > 0 { + if done == 1 { + server.StartSlave() + return nil + } else { + time.Sleep(time.Second * time.Duration(cluster.Conf.MonitoringTicker)) + return server.CallbackMysqldump(dt) + } + } + + return err +} diff --git a/cluster/srv_rejoin.go b/cluster/srv_rejoin.go index 64e05fa3d..b610063e5 100644 --- a/cluster/srv_rejoin.go +++ b/cluster/srv_rejoin.go @@ -364,6 +364,7 @@ func (server *ServerMonitor) RejoinDirectDump() error { Logfile: realmaster.FailoverMasterLogFile, Logpos: realmaster.FailoverMasterLogPos, SSL: cluster.Conf.ReplicationSSL, + Channel: cluster.Conf.MasterConn, }, server.DBVersion) cluster.LogSQL(logs, err3, server.URL, "Rejoin", config.LvlErr, "Failed change master maxscale on %s: %s", server.URL, err3) } diff --git a/config/config.go b/config/config.go index d77d55e31..a06644b85 100644 --- a/config/config.go +++ b/config/config.go @@ -1865,7 +1865,7 @@ func (conf *Config) IsEligibleForPrinting(module int, level string) bool { break case module == ConstLogModHeartBeat: if conf.LogHeartbeat { - return conf.LogSSTLevel >= lvl + return conf.LogHeartbeatLevel >= lvl } break case module == ConstLogModConfigLoad: diff --git a/server/api_cluster.go b/server/api_cluster.go index ae7fcd73c..3341e1d45 100644 --- a/server/api_cluster.go +++ b/server/api_cluster.go @@ -1050,6 +1050,8 @@ func (repman *ReplicationManager) switchSettings(mycluster *cluster.Cluster, set mycluster.SwitchRejoinLogicalBackup() case "autorejoin-physical-backup": mycluster.SwitchRejoinPhysicalBackup() + case "autorejoin-force-restore": + mycluster.SwitchRejoinForceRestore() case "switchover-at-sync": mycluster.SwitchSwitchoverSync() case "check-replication-filters": diff --git a/server/server.go b/server/server.go index 160c6b330..485a4703f 100644 --- a/server/server.go +++ b/server/server.go @@ -651,7 +651,7 @@ func (repman *ReplicationManager) AddFlags(flags *pflag.FlagSet, conf *config.Co flags.StringVar(&conf.BackupMyDumperPath, "backup-mydumper-path", "/usr/bin/mydumper", "Path to mydumper binary") flags.StringVar(&conf.BackupMyLoaderPath, "backup-myloader-path", "/usr/bin/myloader", "Path to myloader binary") - flags.StringVar(&conf.BackupMyLoaderOptions, "backup-myloader-options", "--overwrite-tables --enable-binlog --verbose=3", "Extra options") + flags.StringVar(&conf.BackupMyLoaderOptions, "backup-myloader-options", "--overwrite-tables --verbose=3", "Extra options") flags.StringVar(&conf.BackupMyDumperOptions, "backup-mydumper-options", "--chunk-filesize=1000 --compress --less-locking --verbose=3 --triggers --routines --events --trx-consistency-only --kill-long-queries", "Extra options") flags.StringVar(&conf.BackupMysqldumpPath, "backup-mysqldump-path", "", "Path to mysqldump binary") flags.StringVar(&conf.BackupMysqldumpOptions, "backup-mysqldump-options", "--hex-blob --single-transaction --verbose --all-databases --routines=true --triggers=true --system=all", "Extra options") diff --git a/share/dashboard/app/dashboard.js b/share/dashboard/app/dashboard.js index 132678c0d..0c091c1c5 100644 --- a/share/dashboard/app/dashboard.js +++ b/share/dashboard/app/dashboard.js @@ -1185,7 +1185,7 @@ app.controller('DashboardController', function ( if (confirm("Confirm database apply config")) httpGetWithoutResponse(getClusterUrl() + '/settings/actions/apply-dynamic-config'); }; $scope.resetfail = function () { - if (confirm("Reset Failover counter?")) httpGetWithoutResponse(getClusterUrl() + '/actions/reset-failover-counter'); + if (confirm("Reset Failover counter?")) httpGetWithoutResponse(getClusterUrl() + '/actions/reset-failover-control'); }; $scope.resetsla = function () { if (confirm("Reset SLA counters?")) httpGetWithoutResponse(getClusterUrl() + '/actions/reset-sla'); @@ -1700,6 +1700,9 @@ app.controller('DashboardController', function ( $scope.changemaxdelay = function (delay) { if (confirm("Confirm change delay " + delay.toString())) httpGetWithoutResponse(getClusterUrl() + '/settings/actions/set/failover-max-slave-delay/' + delay); }; + $scope.changefailoverlimit = function (limit) { + if (confirm("Confirm change failover-limit " + limit.toString())) httpGetWithoutResponse(getClusterUrl() + '/settings/actions/set/failover-limit/' + limit); + }; $scope.changebackupbinlogskeep = function (delay) { if (confirm("Confirm change keep binlogs files " + delay.toString())) httpGetWithoutResponse(getClusterUrl() + '/settings/actions/set/backup-binlogs-keep/' + delay); }; diff --git a/share/dashboard/static/card-setting-rejoin.html b/share/dashboard/static/card-setting-rejoin.html index ee790dc30..c41c77d01 100644 --- a/share/dashboard/static/card-setting-rejoin.html +++ b/share/dashboard/static/card-setting-rejoin.html @@ -105,6 +105,20 @@ + + Force Rejoin With Restore + + + + + OnOff + + + + Auto seed from backup standalone server diff --git a/share/dashboard/static/card-setting-replication.html b/share/dashboard/static/card-setting-replication.html index b9a46f99f..e2ce434ae 100644 --- a/share/dashboard/static/card-setting-replication.html +++ b/share/dashboard/static/card-setting-replication.html @@ -1,5 +1,16 @@ + + + + + +
Failover Limit
+ + + {{selectedCluster.config.failoverLimit}} +
Checks failover & switchover constraints