@@ -579,13 +579,16 @@ func (e *MHAExecutor) validateMHADeployment(ctx context.Context, config MHAConfi
579579 }
580580 }
581581
582- replCmd := mhaShellCommand (ctx , config .ManagerHost , config .SSHUser , config .SSHPrivateKey , "perl -X $(command -v masterha_check_repl) --conf=/etc/mha/app1.cnf" )
583- if out , err := replCmd .CombinedOutput (); err != nil {
584- if ! mhaOutputContains (string (out ), "MySQL Replication Health is OK" ) {
582+ for i , host := range config .SlaveHosts {
583+ port := config .MasterPort
584+ if i < len (config .SlavePorts ) && config .SlavePorts [i ] != 0 {
585+ port = config .SlavePorts [i ]
586+ }
587+ if err := validateMHAReplica (ctx , host , port , config ); err != nil {
585588 return & TaskResult {
586589 Status : "failed" ,
587590 Progress : 85 ,
588- Message : fmt .Sprintf ("MHA replication check failed: %v, output: %s " , err , strings . TrimSpace ( string ( out )) ),
591+ Message : fmt .Sprintf ("MHA replication check failed on %s:%d: %v " , host , port , err ),
589592 Timestamp : time .Now (),
590593 }
591594 }
@@ -600,6 +603,36 @@ func (e *MHAExecutor) validateMHADeployment(ctx context.Context, config MHAConfi
600603 }
601604}
602605
606+ func validateMHAReplica (ctx context.Context , host string , port int , config MHAConfig ) error {
607+ output , err := mysqlExecCommand (ctx , host , port , config .ManagerUser , config .ManagerPass , "SHOW REPLICA STATUS\\ G" ).CombinedOutput ()
608+ if err != nil {
609+ legacyOutput , legacyErr := mysqlExecCommand (ctx , host , port , config .ManagerUser , config .ManagerPass , "SHOW SLAVE STATUS\\ G" ).CombinedOutput ()
610+ if legacyErr != nil {
611+ return fmt .Errorf ("%v, output: %s; fallback: %v, output: %s" , err , strings .TrimSpace (string (output )), legacyErr , strings .TrimSpace (string (legacyOutput )))
612+ }
613+ output = legacyOutput
614+ }
615+
616+ status := string (output )
617+ if strings .TrimSpace (status ) == "" {
618+ return fmt .Errorf ("replica status is empty" )
619+ }
620+ if ! mhaReplicaStatusContainsRunning (status , "Replica_IO_Running" , "Slave_IO_Running" ) {
621+ return fmt .Errorf ("replica IO thread is not running: %s" , strings .TrimSpace (status ))
622+ }
623+ if ! mhaReplicaStatusContainsRunning (status , "Replica_SQL_Running" , "Slave_SQL_Running" ) {
624+ return fmt .Errorf ("replica SQL thread is not running: %s" , strings .TrimSpace (status ))
625+ }
626+ if ! strings .Contains (status , "Source_Host: " + config .MasterHost ) && ! strings .Contains (status , "Master_Host: " + config .MasterHost ) {
627+ return fmt .Errorf ("replica source does not match master %s: %s" , config .MasterHost , strings .TrimSpace (status ))
628+ }
629+ return nil
630+ }
631+
632+ func mhaReplicaStatusContainsRunning (status string , modernKey string , legacyKey string ) bool {
633+ return strings .Contains (status , modernKey + ": Yes" ) || strings .Contains (status , legacyKey + ": Yes" )
634+ }
635+
603636func mhaOutputContains (output , marker string ) bool {
604637 return strings .Contains (output , marker )
605638}
0 commit comments