MySQL:MHA高可用集群部署及故障切换

目录

一、MHA概述

1、什么是MHA

2、MHA 的组成

3、MHA 的特点

4、MHA的工作原理

二、搭建MHA环境

manager


一、MHA概述

1、什么是MHA

MHA(MasterHigh Availability)是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。
MHA 的出现就是解决MySQL 单点的问题。
MySQL故障切换过程中,MHA能做到0-30秒内自动完成故障切换操作。
MHA能在故障切换的过程中最大程度上保证数据的一致性,以达到真正意义上的高可用。

主服务器会保存最新的二进制文件,

2、MHA 的组成

①MHA Node(数据节点)

MHA Node 运行在每台 MySQL 服务器上。

②MHA Manager(管理节点)

MHA Manager 可以单独部署在一台独立的机器上,管理多个 master-slave 集群;也可以部署在一台 slave 节点上。

MHA Manager 会定时探测集群中的 master 节点。当 master 出现故障时,它可以自动将最新数据的 slave 提升为新的 master, 然后将所有其他的 slave 重新指向新的 master。整个故障转移过程对应用程序完全透明。

先装node在装manager;node和node之间通过manager去管理;

3、MHA 的特点

自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据不丢失
使用半同步复制,可以大大降低数据丢失的风险,如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性
目前MHA支持一主多从架构,最少三台服务,即一主两从

4、MHA的工作原理

1、从宕机的 Master 保存二进制日志事件(binlog event);
2、识别含有最新更新的 Slave;
3、应用差异的中继日志(relay log)到其他 Slave;
4、应用从 Master 保存的二进制日志事件;
5、提升一个 Slave 为新的 Master;
6、使其他的 Slave 连接新的 Master 进行复制;
 

数据流向: 数据先经过master通过manger管理数据分配,然后当主服务器挂了之后,需要去匹配从服务器最接近主服务器内容的顶上去,通过vip去进行地址漂移,此时从服务器变成了主服务器,接下来就是主从复制+读写分离原理。

MHA使用半同步复制

二、搭建MHA环境

准备三台MySQL做一主两从,一台做manager

systemctl stop firewalld
setenforce 0
systemctl status firewalld.service

hostnamectl set-hostname master
su

vim /etc/my.cnf
[mysqld]
server-id = 1
log_bin = master-bin
log-slave-updates = true

systemctl restart mysqld

ln -s /usr/local/mysql/bin/mysql /usr/sbin/
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/

mysql -uroot -p123456;
grant replication slave on *.* to 'myslave'@'192.168.111.%' identified by '123456';
grant all privileges on *.* to 'mha'@'192.168.111.%' identified by 'manager';		

grant all privileges on *.* to 'mha'@'mysql1' identified by 'manager';
grant all privileges on *.* to 'mha'@'mysql2' identified by 'manager';
grant all privileges on *.* to 'mha'@'mysql3' identified by 'manager';
flush privileges;

show master status;

在 Master 主库插入条数据,测试是否同步
create database test_db;
use test_db;
create table test(id int);
insert into test(id) values (1);

安装 MHA 依赖的环境,首先安装 epel 源
yum install epel-release --nogpgcheck -y

yum install -y perl-DBD-MySQL \
perl-Config-Tiny \
perl-Log-Dispatch \
perl-Parallel-ForkManager \     
perl-ExtUtils-CBuilder \
perl-ExtUtils-MakeMaker \
perl-CPAN

安装 MHA 软件包,先在所有服务器上必须先安装 node 组件
cd /opt
tar zxvf mha4mysql-node-0.57.tar.gz
cd mha4mysql-node-0.57
perl Makefile.PL
make && make install

在 mysql1 上配置到数据库节点 mysql2 和 mysql3 的无密码认证
ssh-keygen -t rsa
ssh-copy-id 192.168.111.75
ssh-copy-id 192.168.111.78

第一次配置需要在 Master 节点上手动开启虚拟IP
/sbin/ifconfig ens33:1 192.168.111.200/24

systemctl stop firewalld
systemctl disable firewalld
setenforce 0

vim /etc/my.cnf
server-id = 2
log_bin = master-bin
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index

systemctl restart mysqld

ln -s /usr/local/mysql/bin/mysql /usr/sbin/
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/

所有数据库节点进行 mysql 授权
mysql -uroot -p123456;
grant replication slave on *.* to 'myslave'@'192.168.10.%' identified by '123456';
grant all privileges on *.* to 'mha'@'192.168.10.%' identified by 'manager';		

grant all privileges on *.* to 'mha'@'mysql1' identified by 'manager';
grant all privileges on *.* to 'mha'@'mysql2' identified by 'manager';
grant all privileges on *.* to 'mha'@'mysql3' identified by 'manager';
flush privileges;

在 Slave1、Slave2 节点执行同步操作
CHANGE master to master_host='192.168.111.72',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=734; 

start slave;

两个从库必须设置为只读模式
set global read_only=1;

安装 MHA 依赖的环境,首先安装 epel 源
yum install epel-release --nogpgcheck -y

yum install -y perl-DBD-MySQL \
perl-Config-Tiny \
perl-Log-Dispatch \
perl-Parallel-ForkManager \     
perl-ExtUtils-CBuilder \
perl-ExtUtils-MakeMaker \
perl-CPAN

安装 node 组件
cd /opt
tar zxvf mha4mysql-node-0.57.tar.gz
cd mha4mysql-node-0.57
perl Makefile.PL
make && make install

配置到数据库节点无密码认证
ssh-keygen -t rsa
ssh-copy-id 192.168.1

manager

systemctl stop firewalld
systemctl disable firewalld
setenforce 0

安装 MHA 依赖的环境,首先安装 epel 源
yum install epel-release --nogpgcheck -y

yum install -y perl-DBD-MySQL \
perl-Config-Tiny \
perl-Log-Dispatch \
perl-Parallel-ForkManager \     
perl-ExtUtils-CBuilder \
perl-ExtUtils-MakeMaker \
perl-CPAN

安装 node 组件
cd /opt
tar zxvf mha4mysql-node-0.57.tar.gz
cd mha4mysql-node-0.57
perl Makefile.PL
make && make install

安装 manager 组件
cd /opt
tar zxvf mha4mysql-manager-0.57.tar.gz
cd mha4mysql-manager-0.57
perl Makefile.PL
make && make install

在 manager 节点上配置到所有数据库节点的无密码认证
ssh-keygen -t rsa
ssh-copy-id

cp -rp /opt/mha4mysql-manager-0.57/samples/scripts /usr/local/bin
ll /usr/local/bin/scripts/
cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin

vim /usr/local/bin/master_ip_failover
dy installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.111.75's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '192.168.111.75'"
and check to make sure that only the key(s) you wanted were added.

[root@manager mha4mysql-manager-0.57]# ssh-copy-id 192.168.111.78
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.111.78 (192.168.111.78)' can't be established.
ECDSA key fingerprint is SHA256:c6BYknrovGpGKJtBFROMjCa6EU/tUjR+ttgsWXmDVUA.
ECDSA key fingerprint is MD5:9d:df:69:f7:d8:5b:72:5e:12:13:02:d3:60:82:fd:85.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.111.78's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '192.168.111.78'"
and check to make sure that only the key(s) you wanted were added.

[root@manager mha4mysql-manager-0.57]# cp -rp /opt/mha4mysql-manager-0.57/samples/scripts /usr/local/bin
[root@manager mha4mysql-manager-0.57]# ll /usr/local/bin/scripts/
总用量 32
-rwxr-xr-x. 1 mysql mysql  3648 5月  31 2015 master_ip_failover
-rwxr-xr-x. 1 mysql mysql  9870 5月  31 2015 master_ip_online_change
-rwxr-xr-x. 1 mysql mysql 11867 5月  31 2015 power_manager
-rwxr-xr-x. 1 mysql mysql  1360 5月  31 2015 send_report
[root@manager mha4mysql-manager-0.57]# cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin
[root@manager mha4mysql-manager-0.57]# vim /usr/local/bin/master_ip_failover
[root@manager mha4mysql-manager-0.57]# ifconfig 
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.111.71  netmask 255.255.255.0  broadcast 192.168.111.255
        inet6 fe80::eb98:89fc:bd9a:c81c  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::e686:3db:f2ad:954b  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:82:83:96  txqueuelen 1000  (Ethernet)
        RX packets 863608  bytes 1150503472 (1.0 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 355925  bytes 33035802 (31.5 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1  (Local Loopback)
        RX packets 96  bytes 8248 (8.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 96  bytes 8248 (8.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

virbr0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 192.168.122.1  netmask 255.255.255.0  broadcast 192.168.122.255
        ether 52:54:00:23:4c:d4  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@manager mha4mysql-manager-0.57]# vim /usr/local/bin/master_ip_failover
[root@manager mha4mysql-manager-0.57]# mkdir /etc/masterha
[root@manager mha4mysql-manager-0.57]# cp /opt/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha
[root@manager mha4mysql-manager-0.57]# vim /etc/masterha/app1.cnf
[root@manager mha4mysql-manager-0.57]# vim /etc/masterha/app1.cnf
[root@manager mha4mysql-manager-0.57]# masterha_check_ssh -conf=/etc/masterha/app1.cnf
Tue Jul 25 16:17:54 2023 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipp
Tue Jul 25 16:17:54 2023 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
Parameter name mger_log is invalid!
 at /usr/local/share/perl5/MHA/SSHCheck.pm line 148.
[root@manager mha4mysql-manager-0.57]# systemctl stop firewalld
[root@manager mha4mysql-manager-0.57]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since 日 2023-07-23 20:25:45 CST; 1 day 19h ago
     Docs: man:firewalld(1)
 Main PID: 823 (code=exited, status=0/SUCCESS)

7月 23 20:24:16 localhost.localdomain systemd[1]: Starting firewalld - dynamic firewall daemon...
7月 23 20:24:16 localhost.localdomain systemd[1]: Started firewalld - dynamic firewall daemon.
7月 23 20:24:17 localhost.localdomain firewalld[823]: WARNING: ICMP type 'beyond-scope' is not support...
7月 23 20:24:17 localhost.localdomain firewalld[823]: WARNING: beyond-scope: INVALID_ICMPTYPE: No supp...
7月 23 20:24:17 localhost.localdomain firewalld[823]: WARNING: ICMP type 'failed-policy' is not suppor...
7月 23 20:24:17 localhost.localdomain firewalld[823]: WARNING: failed-policy: INVALID_ICMPTYPE: No sup...
7月 23 20:24:17 localhost.localdomain firewalld[823]: WARNING: ICMP type 'reject-route' is not support...
7月 23 20:24:17 localhost.localdomain firewalld[823]: WARNING: reject-route: INVALID_ICMPTYPE: No supp...
7月 23 20:25:44 localhost.localdomain systemd[1]: Stopping firewalld - dynamic firewall daemon...
7月 23 20:25:45 localhost.localdomain systemd[1]: Stopped firewalld - dynamic firewall daemon.
Hint: Some lines were ellipsized, use -l to show in full.
[root@manager mha4mysql-manager-0.57]# masterha_check_ssh -conf=/etc/masterha/app1.cnf
Tue Jul 25 16:18:42 2023 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipp
Tue Jul 25 16:18:42 2023 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
Parameter name mger_log is invalid!
 at /usr/local/share/perl5/MHA/SSHCheck.pm line 148.
[root@manager mha4mysql-manager-0.57]# vim /etc/masterha/app1.cnf
[root@manager mha4mysql-manager-0.57]# cd ..
[root@manager opt]# masterha_check_ssh -conf=/etc/masterha/app1.cnf
Tue Jul 25 16:21:07 2023 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipp
Tue Jul 25 16:21:07 2023 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
Parameter name mger_log is invalid!
 at /usr/local/share/perl5/MHA/SSHCheck.pm line 148.
[root@manager opt]# cd /usr/local/share/perl5/MHA/
[root@manager MHA]# ls
BinlogHeaderParser.pm  BinlogPosFindManager.pm  ManagerAdmin.pm         MasterMonitor.pm  Server.pm
BinlogManager.pm       Config.pm                ManagerAdminWrapper.pm  MasterRotate.pm   SlaveUtil.pm
BinlogPosFinderElp.pm  DBHelper.pm              ManagerConst.pm         NodeConst.pm      SSHCheck.pm
BinlogPosFinder.pm     FileStatus.pm            ManagerUtil.pm          NodeUtil.pm
BinlogPosFinderXid.pm  HealthCheck.pm           MasterFailover.pm       ServerManager.pm
[root@manager MHA]# cat SSHCheck.pm 
#!/usr/bin/env perl

#  Copyright (C) 2011 DeNA Co.,Ltd.
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#  Foundation, Inc.,
#  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

package MHA::SSHCheck;

use strict;
use warnings FATAL => 'all';

use English qw(-no_match_vars);
use Getopt::Long qw(:config pass_through);
use Carp qw(croak);
use Time::HiRes qw( sleep );
use Log::Dispatch;
use Log::Dispatch::Screen;
use Parallel::ForkManager;
use MHA::Config;
use MHA::ManagerConst;
use MHA::ManagerUtil;
$| = 1;
my $g_global_config_file = $MHA::ManagerConst::DEFAULT_GLOBAL_CONF;
my $g_config_file;

sub do_ssh_connection_check {
  my $servers_ref = shift;
  my $log         = shift;
  my $log_level   = shift;
  my $workdir     = shift;
  my @servers     = @$servers_ref;
  $log->info("Starting SSH connection tests..");
  my $failed = 0;
  my $pm     = new Parallel::ForkManager( $#servers + 1 );

  $pm->run_on_start(
    sub {
      my ( $pid, $target ) = @_;
    }
  );

  $pm->run_on_finish(
    sub {
      my ( $pid, $exit_code, $target ) = @_;
      return if ( $target->{skip_init_ssh_check} );
      my $local_file =
        "$workdir/$target->{ssh_host}_$target->{ssh_port}_ssh_check.log";
      if ($exit_code) {
        $failed = 1;
        if ( -f $local_file ) {
          $log->error( "\n" . `cat $local_file` );
        }
      }
      else {
        if ( -f $local_file ) {
          $log->debug( "\n" . `cat $local_file` );
        }
      }
      unlink $local_file;
    }
  );

  foreach my $src (@servers) {
    if ( $pm->start($src) ) {

 # By default, sshd normally accepts only 10 concurrent authentication requests.
 # If we have lots of alive servers, we might reach this limitation so
 # shifting child process invocation time a bit to avoid this problem.
      sleep 0.5;
      next;
    }
    my ( $file, $pplog );
    eval {
      $SIG{INT} = $SIG{HUP} = $SIG{QUIT} = $SIG{TERM} = "DEFAULT";
      $pm->finish(0) if ( $src->{skip_init_ssh_check} );
      $file = "$workdir/$src->{ssh_host}_$src->{ssh_port}_ssh_check.log";
      unlink $file;
      $pplog = Log::Dispatch->new( callbacks => $MHA::ManagerConst::log_fmt );
      $pplog->add(
        Log::Dispatch::File->new(
          name      => 'file',
          filename  => $file,
          min_level => $log_level,
          callbacks => $MHA::ManagerConst::add_timestamp,
          mode      => 'append'
        )
      );
      foreach my $dst (@servers) {
        next if ( $dst->{skip_init_ssh_check} );
        next if ( $src->{id} eq $dst->{id} );
        $pplog->debug(
" Connecting via SSH from $src->{ssh_user}\@$src->{ssh_host}($src->{ssh_ip}:$src->{ssh_port}) to $dst->{sser}\@$dst->{ssh_host}($dst->{ssh_ip}:$dst->{ssh_port}).."
        );
        my $command =
"ssh $MHA::ManagerConst::SSH_OPT_CHECK -p $src->{ssh_port} $src->{ssh_user}\@$src->{ssh_ip} \"ssh $MHA::MerConst::SSH_OPT_CHECK -p $dst->{ssh_port} $dst->{ssh_user}\@$dst->{ssh_ip} exit 0\"";
        my ( $high, $low ) = MHA::ManagerUtil::exec_system( $command, $file );
        if ( $high != 0 || $low != 0 ) {
          $pplog->error(
"SSH connection from $src->{ssh_user}\@$src->{ssh_host}($src->{ssh_ip}:$src->{ssh_port}) to $dst->{ssh_us@$dst->{ssh_host}($dst->{ssh_ip}:$dst->{ssh_port}) failed!"
          );
          $pm->finish(1);
        }
        $pplog->debug("  ok.");
      }
      $pm->finish(0);
    };
    if ($@) {
      $pplog->error($@) if ($pplog);
      undef $@;
      $pm->finish(1);
    }
  }
  $pm->wait_all_children;
  croak "SSH Configuration Check Failed!\n" if ($failed);

  $log->info("All SSH connection tests passed successfully.");
}

sub main {
  @ARGV = @_;
  GetOptions(
    'global_conf=s' => \$g_global_config_file,
    'conf=s'        => \$g_config_file,
  );
  unless ($g_config_file) {
    print "--conf=<server_config_file> must be set.\n";
    return 1;
  }
  my $log  = MHA::ManagerUtil::init_log();
  my $conf = new MHA::Config(
    logger     => $log,
    globalfile => $g_global_config_file,
    file       => $g_config_file
  );
  my ( $sc_ref, undef ) = $conf->read_config();
  my @servers_config = @$sc_ref;
  $log = MHA::ManagerUtil::init_log( undef, "debug" );
  return do_ssh_connection_check( \@servers_config, $log, "debug", "/tmp" );
}

1;

[root@manager MHA]# cat -n SSHCheck.pm 
     1	#!/usr/bin/env perl
     2	
     3	#  Copyright (C) 2011 DeNA Co.,Ltd.
     4	#
     5	#  This program is free software; you can redistribute it and/or modify
     6	#  it under the terms of the GNU General Public License as published by
     7	#  the Free Software Foundation; either version 2 of the License, or
     8	#  (at your option) any later version.
     9	#
    10	#  This program is distributed in the hope that it will be useful,
    11	#  but WITHOUT ANY WARRANTY; without even the implied warranty of
    12	#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13	#  GNU General Public License for more details.
    14	#
    15	#  You should have received a copy of the GNU General Public License
    16	#   along with this program; if not, write to the Free Software
    17	#  Foundation, Inc.,
    18	#  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    19	
    20	package MHA::SSHCheck;
    21	
    22	use strict;
    23	use warnings FATAL => 'all';
    24	
    25	use English qw(-no_match_vars);
    26	use Getopt::Long qw(:config pass_through);
    27	use Carp qw(croak);
    28	use Time::HiRes qw( sleep );
    29	use Log::Dispatch;
    30	use Log::Dispatch::Screen;
    31	use Parallel::ForkManager;
    32	use MHA::Config;
    33	use MHA::ManagerConst;
    34	use MHA::ManagerUtil;
    35	$| = 1;
    36	my $g_global_config_file = $MHA::ManagerConst::DEFAULT_GLOBAL_CONF;
    37	my $g_config_file;
    38	
    39	sub do_ssh_connection_check {
    40	  my $servers_ref = shift;
    41	  my $log         = shift;
    42	  my $log_level   = shift;
    43	  my $workdir     = shift;
    44	  my @servers     = @$servers_ref;
    45	  $log->info("Starting SSH connection tests..");
    46	  my $failed = 0;
    47	  my $pm     = new Parallel::ForkManager( $#servers + 1 );
    48	
    49	  $pm->run_on_start(
    50	    sub {
    51	      my ( $pid, $target ) = @_;
    52	    }
    53	  );
    54	
    55	  $pm->run_on_finish(
    56	    sub {
    57	      my ( $pid, $exit_code, $target ) = @_;
    58	      return if ( $target->{skip_init_ssh_check} );
    59	      my $local_file =
    60	        "$workdir/$target->{ssh_host}_$target->{ssh_port}_ssh_check.log";
    61	      if ($exit_code) {
    62	        $failed = 1;
    63	        if ( -f $local_file ) {
    64	          $log->error( "\n" . `cat $local_file` );
    65	        }
    66	      }
    67	      else {
    68	        if ( -f $local_file ) {
    69	          $log->debug( "\n" . `cat $local_file` );
    70	        }
    71	      }
    72	      unlink $local_file;
    73	    }
    74	  );
    75	
    76	  foreach my $src (@servers) {
    77	    if ( $pm->start($src) ) {
    78	
    79	 # By default, sshd normally accepts only 10 concurrent authentication requests.
    80	 # If we have lots of alive servers, we might reach this limitation so
    81	 # shifting child process invocation time a bit to avoid this problem.
    82	      sleep 0.5;
    83	      next;
    84	    }
    85	    my ( $file, $pplog );
    86	    eval {
    87	      $SIG{INT} = $SIG{HUP} = $SIG{QUIT} = $SIG{TERM} = "DEFAULT";
    88	      $pm->finish(0) if ( $src->{skip_init_ssh_check} );
    89	      $file = "$workdir/$src->{ssh_host}_$src->{ssh_port}_ssh_check.log";
    90	      unlink $file;
    91	      $pplog = Log::Dispatch->new( callbacks => $MHA::ManagerConst::log_fmt );
    92	      $pplog->add(
    93	        Log::Dispatch::File->new(
    94	          name      => 'file',
    95	          filename  => $file,
    96	          min_level => $log_level,
    97	          callbacks => $MHA::ManagerConst::add_timestamp,
    98	          mode      => 'append'
    99	        )
   100	      );
   101	      foreach my $dst (@servers) {
   102	        next if ( $dst->{skip_init_ssh_check} );
   103	        next if ( $src->{id} eq $dst->{id} );
   104	        $pplog->debug(
   105	" Connecting via SSH from $src->{ssh_user}\@$src->{ssh_host}($src->{ssh_ip}:$src->{ssh_port}) to ->{ssh_user}\@$dst->{ssh_host}($dst->{ssh_ip}:$dst->{ssh_port}).."
   106	        );
   107	        my $command =
   108	"ssh $MHA::ManagerConst::SSH_OPT_CHECK -p $src->{ssh_port} $src->{ssh_user}\@$src->{ssh_ip} \"sshA::ManagerConst::SSH_OPT_CHECK -p $dst->{ssh_port} $dst->{ssh_user}\@$dst->{ssh_ip} exit 0\"";
   109	        my ( $high, $low ) = MHA::ManagerUtil::exec_system( $command, $file );
   110	        if ( $high != 0 || $low != 0 ) {
   111	          $pplog->error(
   112	"SSH connection from $src->{ssh_user}\@$src->{ssh_host}($src->{ssh_ip}:$src->{ssh_port}) to $dst-h_user}\@$dst->{ssh_host}($dst->{ssh_ip}:$dst->{ssh_port}) failed!"
   113	          );
   114	          $pm->finish(1);
   115	        }
   116	        $pplog->debug("  ok.");
   117	      }
   118	      $pm->finish(0);
   119	    };
   120	    if ($@) {
   121	      $pplog->error($@) if ($pplog);
   122	      undef $@;
   123	      $pm->finish(1);
   124	    }
   125	  }
   126	  $pm->wait_all_children;
   127	  croak "SSH Configuration Check Failed!\n" if ($failed);
   128	
   129	  $log->info("All SSH connection tests passed successfully.");
   130	}
   131	
   132	sub main {
   133	  @ARGV = @_;
   134	  GetOptions(
   135	    'global_conf=s' => \$g_global_config_file,
   136	    'conf=s'        => \$g_config_file,
   137	  );
   138	  unless ($g_config_file) {
   139	    print "--conf=<server_config_file> must be set.\n";
   140	    return 1;
   141	  }
   142	  my $log  = MHA::ManagerUtil::init_log();
   143	  my $conf = new MHA::Config(
   144	    logger     => $log,
   145	    globalfile => $g_global_config_file,
   146	    file       => $g_config_file
   147	  );
   148	  my ( $sc_ref, undef ) = $conf->read_config();
   149	  my @servers_config = @$sc_ref;
   150	  $log = MHA::ManagerUtil::init_log( undef, "debug" );
   151	  return do_ssh_connection_check( \@servers_config, $log, "debug", "/tmp" );
   152	}

mkdir /etc/masterha
cp /opt/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha

vim /etc/masterha/app1.cnf
[server default]
manager_log=/var/log/masterha/app1/manager.log
manager_workdir=/var/log/masterha/app1
master_binlog_dir=/usr/local/mysql/data
master_ip_failover_script=/usr/local/bin/master_ip_failover
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
password=manager
ping_interval=1
remote_workdir=/tmp
repl_password=123456
repl_user=myslave
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.111.75 -s 192.168.10.78
shutdown_script=""
ssh_user=root
user=mha

[server1]
hostname=192.168.111.72
port=3306

[server2]
candidate_master=1
check_repl_delay=0
hostname=192.168.111.75
port=3306

[server3]
hostname=192.168.111.78
port=3306

masterha_check_ssh -conf=/etc/masterha/app1.cnf
masterha_check_repl -conf=/etc/masterha/app1.cnf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/53582.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

消息中间件ActiveMQ介绍

一、消息中间件的介绍 介绍 ​ 消息队列 是指利用 高效可靠 的 消息传递机制 进行与平台无关的 数据交流&#xff0c;并基于 数据通信 来进行分布式系统的集成。 特点(作用) 应用解耦 异步通信 流量削峰 (海量)日志处理 消息通讯 …... 应用场景 根据消息队列的特点&a…

Android adb shell 查看App内存(java堆内存/vss虚拟内存/详细的内存状况/内存快照hprof)和系统可用内存

1.adb shell 获取app 进程的pid adb shell "ps|grep com.xxx包名"根据某个渠道包&#xff0c;去查询对应的pid&#xff0c;如下所示&#xff1a; 2.通过adb shell 查看设备的java dalvik 堆内存的最大值 执行命令行&#xff1a; adb shell getprop dalvik.vm.h…

【RabbitMQ】之消息的可靠性方案

目录 一、数据丢失场景二、数据可靠性方案 1、生产者丢失消息解决方案2、MQ 队列丢失消息解决方案3、消费者丢失消息解决方案 一、数据丢失场景 MQ 消息数据完整的链路为&#xff1a;从 Producer 发送消息到 RabbitMQ 服务器中&#xff0c;再由 Broker 服务的 Exchange 根据…

微服务项目,maven无法加载其他服务依赖

微服务项目&#xff0c;导入了工具类工程&#xff0c;但是一直报错&#xff0c;没有该类&#xff0c; 检查maven 这里的Maven的版本与idea版本不匹配可能是导致依赖加载失败的最重要原因 检查maven配置&#xff0c;我这是原来的maven&#xff0c;home 修改之后,就不报错了

python文件处理方式

python文件处理方式 file open(D:\pythonText.txt, r, encodingUTF-8) print(file) # <_io.TextIOWrapper nameD:\\pythonText.txt moder encodingUTF-8> print(type(file)) # <class _io.TextIOWrapper>读取文件 file open(D:\pythonText.txt, r, encodingU…

C#文件操作从入门到精通(2)——查看某个dll中有哪些函数

kernel32.dll中含有ini文件操作使用的函数,我们可以通过VisualStudio自带的dumpbin.exe查看dll所包含的函数,操作步骤如下: 1、找到dumpbin.exe所在的文件夹 我的电脑中安装了VisualStudio2019社区版以及VisualStudio2017Professional,但是我发现VisualStudio2019社区版中…

【Linux下6818开发板(ARM)】在液晶屏上显示RGB颜色和BMP图片

(꒪ꇴ꒪ ),hello我是祐言博客主页&#xff1a;C语言基础,Linux基础,软件配置领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff01;送给读者的一句鸡汤&#x1f914;&#xff1a;集中起来的意志可以击穿顽石!作者水平很有限&#xff0c;如果发现错误&#x…

使用 CSS 自定义属性

我们常见的网站日夜间模式的变化&#xff0c;其实用到了 css 自定义属性。 CSS 自定义属性&#xff08;也称为 CSS 变量&#xff09;是一种在 CSS 中预定义和使用的变量。它们提供了一种简洁和灵活的方式来通过多个 CSS 规则共享相同的值&#xff0c;使得样式更易于维护和修改。…

PS - Photoshop 抠图与剪贴蒙版功能与 Stable Diffusion 重绘

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/131978632 Photoshop 的剪贴蒙版是一种将上层图层的内容限制在下层图层的形状范围内的方法&#xff0c;也就是说&#xff0c;上层图层只能在下层图…

数据结构:谈快速排序的多种优化和非递归展开,以及排序思想归纳

文章目录 写在前面快速排序的基本体系快速排序的优化快速排序的非递归实现排序分类总结插入排序选择排序交换排序归并排序 写在前面 快速排序作为效率相当高的排序算法&#xff0c;除了对于特殊数据有其一定的局限性&#xff0c;在大多数应用场景中都有它特有的优势和应用&…

类加载机制与类加载器

点击下方关注我&#xff0c;然后右上角点击...“设为星标”&#xff0c;就能第一时间收到更新推送啦~~~ Java 源码是如何形成类文件的&#xff0c;类文件又是如何加载到虚拟机的&#xff0c;类加载有哪些机制和原则呢&#xff1f;本文将为大家一一介绍。 1 Java 源码形成类文件…

1.Flink概述

1.1 技术架构 应用框架层: 在API层之上构建的满足特定应用场景的计算框架&#xff0c;总体上分为流计算和批处理两类应用框架。API 层&#xff1a; Flink对外提供能力的接口 &#xff0c;实现了面向流计算的DataStream API和面向批处理的DataSet API。运行时层&#xff1a;Flin…

No Spring环境Mybatis-Plus批量插入并返回主键的两种方式

批量插入,可以把Mybatis-Plus看作是Mybatis加强版;故Mybatis中的相关操作都可以在Mybatis-Plus中使用;在mysql数据库中支持批量插入&#xff0c;所以只要配置useGeneratedKeys和keyProperty就可以批量插入并返回主键了。 下面是批量插入的Dao层接口 一注解方式: 直接撸代码:…

SpringBoot —程序包org.springframework.boot.test.context不存在

一. 遇到问题 &#xff1a;程序包org.springframework.boot.test.context不存在 发生错误的原因是项目中缺少spring-boot-starter-test依赖导致的&#xff0c;解决方案如下: 在项目根目录的pom.xm文件中的<dependencies>节点下增加以下依赖即可&#xff1a; <depen…

网上办理的三网低月租大流量,到底能不能选归属地?

网上办理的三网低月租大流量&#xff0c;到底能不能选归属地&#xff1f; 首先&#xff0c;小编就明确地告诉大家&#xff0c;如果默认的是归属地随机&#xff0c;那么是不可以选择归属地的。 看到这里&#xff0c;可能有人会有疑问&#xff0c;网上的流量卡也是运营商推出的…

编程小白的自学笔记十二(python爬虫入门四Selenium的使用实例二)

系列文章目录 编程小白的自学笔记十一&#xff08;python爬虫入门三Selenium的使用实例详解&#xff09; 编程小白的自学笔记十&#xff08;python爬虫入门二实例代码详解&#xff09; 编程小白的自学笔记九&#xff08;python爬虫入门代码详解&#xff09; 目录 系列文章…

【Python】Web学习笔记_flask(1)——getpost

flask提供的request请求对象可以实现获取url或表单中的字段值 GET请求 从URL中获取name、age两个参数 from flask import Flask,url_for,redirect,requestappFlask(__name__)app.route(/) def index():namerequest.args.get(name)agerequest.args.get(age)messagef姓名:{nam…

Electron逆向调试

复杂程序处理方式&#xff1a; 复杂方式通过 调用窗口 添加命令行参数 启动允许调用&#xff0c;就可以实现调试发布环境的electron程序。 断点调试分析程序的走向&#xff0c;程序基本上会有混淆代码处理&#xff0c; 需要调整代码格式&#xff0c;处理程序。

32.选择器

选择器 html部分 <div class"toggle-container"><input type"checkbox" id"good" class"toggle"><label for"good" class"label"><div class"ball"></div></label&…

Spring学习笔记之spring概述

文章目录 Spring介绍Spring8大模块Spring特点 Spring介绍 Spring是一个轻量级的控制反转和面向切面的容器框架 Spring最初的出现是为了解决EJB臃肿的设计&#xff0c;以及难以测试等问题。 Spring为了简化开发而生&#xff0c;让程序员只需关注核心业务的实现&#xff0c;尽…