MySQL 高可用性クラスター (MHA)

1. MHA クラスタの概要

  • クラスタの定義:(ウェブクラスタ)など、複数のサーバがまとめて同じサービスを提供するもの。
  • 共通クラスターの分類:
  1. LB (負荷分散クラスター): サーバーは、クライアントからの複数の接続要求を共同で均等に共有し、処理します。
    HA (高可用性クラスター): アクティブ/スタンバイ モード。メイン サーバーがダウンした後、スタンバイ サーバーが自動的にジョブを引き継ぎます。
  • 共通クラスタ サービス ソフトウェア:
    LB: LVS、Nginx、haproxy など。
    HA: キープアライブ、ハートビート、

1.1. ソフトウェアの紹介

  • MHA(マスターハイアベイラビリティ)
  • Perl スクリプト言語を介して日本の DeNA 会社 youshimaton によって開発されました。
  • これは、MySQL の高可用性を実現する優れたソリューションです。
  • データベースの自動フェイルオーバー操作は 0 ~ 30 秒以内に完了できます。
  • MHA は、フェールオーバー中に最大のデータ整合性を確保して、真の高可用性を実現します。

1.2. MHAの組成

  • MHA マスター (管理ノード)
  • すべてのデータベース サーバーを管理する
  • スタンドアロン マシンに個別に展開可能
  • データベースサーバーに展開することもできます
  • MHAノード(データノード)
  • データを保存する MySQL サーバー
  • 各 MySQL サーバーで実行

1.3. MHA 作業プロセス

  • MHA クラスタ アーキテクチャ図:
    ここに画像の説明を挿入
  • MHA 作業プロセス:
  • Manager は定期的にクラスタ内のマスター ノードを検出します
  • マスターに障害が発生すると、マネージャーは自動的に最新のデータを持つスレーブを新しいマスターに昇格させ、他のスレーブ ホストは自動的に新しいマスターのスレーブ ライブラリになるため、クラスター グループ内のホストは 1 つのマスターを持つ必要があります。マルチスレーブ構造。

1.4. IP プランニング

IPアドレス マスタースレーブ同期の役割 クラスターの役割 CPU名
192.168.2.10 クライアント なし クライアント10
192.168.2.20 なし 管理ホスト mha20
192.168.2.30 主図書館 現在のメイン ライブラリ mysql30
192.168.2.40 図書館から スタンバイメインライブラリ mysql40
192.168.2.50 図書館から スタンバイメインライブラリ mysql50
192.168.2.100 なし VIPアドレス なし

2. MHA クラスターをデプロイする

2.1. クラスター環境の準備

2.1.1. 依存パッケージのインストール

  • システムに付属の prel パッケージをインストールします
##需要在mha20、mysql30、mysql40、mysql50安装
[root@mha20 ~]# yum  -y install perl-*
wget http://rpmfind.net/linux/epel/7/x86_64/Packages/p/perl-Email-Date-Format-1.002-15.el7.noarch.rpm
wget http://rpmfind.net/linux/epel/7/x86_64/Packages/p/perl-Mail-Sender-0.8.23-1.el7.noarch.rpm
wget http://rpmfind.net/linux/epel/7/x86_64/Packages/p/perl-Mail-Sendmail-0.79-21.el7.noarch.rpm
wget http://rpmfind.net/linux/epel/7/x86_64/Packages/p/perl-MIME-Lite-3.030-1.el7.noarch.rpm
wget http://rpmfind.net/linux/epel/7/x86_64/Packages/p/perl-MIME-Types-1.38-2.el7.noarch.rpm
wget http://rpmfind.net/linux/epel/7/x86_64/Packages/p/perl-Parallel-ForkManager-1.18-2.el7.noarch.rpm
wget http://rpmfind.net/linux/centos/7.9.2009/os/x86_64/Packages/perl-Config-Tiny-2.14-7.el7.noarch.rpm
wget http://rpmfind.net/linux/epel/7/x86_64/Packages/p/perl-Log-Dispatch-2.41-1.el7.1.noarch.rpm

[root@mha20 ~]# ls
perl-Config-Tiny-2.14-7.el7.noarch.rpm          perl-Mail-Sendmail-0.79-21.el7.noarch.rpm
perl-Email-Date-Format-1.002-15.el7.noarch.rpm  perl-MIME-Lite-3.030-1.el7.noarch.rpm
perl-Log-Dispatch-2.41-1.el7.1.noarch.rpm       perl-MIME-Types-1.38-2.el7.noarch.rpm
perl-Mail-Sender-0.8.23-1.el7.noarch.rpm        perl-Parallel-ForkManager-1.18-2.el7.noarch.rpm
##在mha20、mysql30、mysql40、mysql50安装
[root@mha20 ~]# yum -y install perl-*.rpm

2.1.2. ssh キーペア認証ログインの設定

  • ssh を介してパスワードなしですべてのデータベース サーバーにログインするように、管理ホスト mha20 を構成します。
##在mha20上创建秘钥对
[root@mha20 ~]# ssh-keygen  ---全部回车即可
##把秘钥对中公钥拷贝给mysql30、mysql40、mysql50
[root@mha20 ~]# ssh-copy-id [email protected]
[root@mha20 ~]# ssh-copy-id [email protected]
[root@mha20 ~]# ssh-copy-id [email protected]
##验证mha20 ssh登录mysql30、mysql40、mysql50是否需要密码,不用密码才是对的,这里不展示了。
  • 相互に ssh パスワードなしでログインできるように、すべてのデータベース サーバーを構成します。
##在mysql30操作如下:
[root@mysql30 ~]# ssh-keygen
[root@mysql30 ~]# ssh-copy-id [email protected]
[root@mysql30 ~]# ssh-copy-id [email protected]
##在mysql40操作如下:
[root@mysql40 ~]# ssh-keygen
[root@mysql40 ~]# ssh-copy-id [email protected]
[root@mysql40 ~]# ssh-copy-id [email protected]
##在mysql50操作如下:
[root@mysql50 ~]# ssh-keygen
[root@mysql50 ~]# ssh-copy-id [email protected]
[root@mysql50 ~]# ssh-copy-id [email protected]
##执行完后验证mysql30、mysql40、mysql50是否可以彼此之间免密登录,这里就不展示了。

2.1.3. 1 つのマスターと複数のスレーブの設定

  • ファイアウォールと selinux をオフにする必要があります

2.1.3.1. メイン ライブラリの設定 (mysql30)

##修改配置文件开启binlog日志
[root@mysql30 ~]# vim /etc/my.cnf
[mysqld]
....
log_bin=mysql30
server_id=30
##安装半同步模块
plugin-load=rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so
##启动半同步模块
rpl_semi_sync_master_enabled=1
rpl_semi_sync_slave_enabled=1
##禁止删除本机中继日志
relay_log_purge=0
##重启mysql服务
[root@mysql30 ~]# systemctl restart mysqld
##查看binlog日志文件名称和pos值
mysql> show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| mysql30.000001 |      154 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
##创建授权用户
mysql> grant replication slave on *.* to 'master'@'%' identified by '1234';

2.1.3.2. スレーブサーバーの設定 (mysql40)

##修改配置文件
[root@mysql40 ~]# vim /etc/my.cnf
[mysqld]
....
server_id=40
log_bin=master40
plugin-load=rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so
rpl_semi_sync_master_enabled=1
rpl_semi_sync_slave_enabled=1
relay_log_purge=0

##重启服务
[root@mysql40 ~]# systemctl restart mysqld
##指定主服务器,pos的值必须是在主库创建授权用户之前,不然从库无法同步授权用户,需要手动创建授权用户。
mysql> change master to
    -> master_host="192.168.2.30",
    -> master_user="master",
    -> master_password="1234",
    -> master_log_file="mysql30.000001",
    -> master_log_pos=154;
##启动slave
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
##查看是否配置成功
mysql> show slave status\G;  
查看Slave_IO_Running和Slave_SQL_Running是yes那就配置成功,这里不展示了。

2.1.3.3. スレーブサーバーの設定 (mysql50)

##修改配置文件
[root@mysql50 ~]# vim /etc/my.cnf
[mysqld]
....
server_id=50
log_bin=master50
plugin-load=rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so
rpl_semi_sync_master_enabled=1
rpl_semi_sync_slave_enabled=1
relay_log_purge=0

##重启服务
[root@mysql50 ~]# systemctl restart mysqld
##指定主服务器
mysql> change master to
    -> master_host="192.168.2.30",
    -> master_user="master",
    -> master_password="1234",
    -> master_log_file="mysql30.000001",
    -> master_log_pos=154;
##启动slave
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
##查看是否配置成功
mysql> show slave status\G;  
查看Slave_IO_Running和Slave_SQL_Running是yes那就配置成功,这里不展示了。

2.2. 管理ノードの設定 (mha20)

2.2.1. mha パッケージのインストール

##下载软件包
[root@mha20 ~]# wget https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58.tar.gz
[root@mha20 ~]# wget https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.centos.noarch.rpm
##安装mha4mysql-node
[root@mha20 ~]# yum -y install mha4mysql-node-0.58-0.el7.centos.noarch.rpm
##源码编译安装mha4mysql-manager
[root@mha20 ~]# tar -xf mha4mysql-manager-0.58.tar.gz -C /usr/local/
[root@mha20 ~]#  cd /usr/local/mha4mysql-manager-0.58/
[root@mha20 ~]#  perl Makefile.PL  --预编译有报错很有可能是依赖包的问题。
[root@mha20 ~]# make;make install
##配置环境变量:
[root@mha20 ~]#  echo "export PATH=/usr/local/mha4mysql-manager-0.58/bin:$PATH" >/etc/profile.d/mha4mysql.sh
[root@mha20 ~]# . /etc/profile.d/mha4mysql.sh
[root@mha20 ~]# echo $PATH

2.2.2. クラスターコマンドの管理

[root@mha20 ~]# ls /usr/local/mha4mysql-manager-0.58/bin/
masterha_check_repl  masterha_check_status  masterha_manager         masterha_master_switch    masterha_stop
masterha_check_ssh   masterha_conf_host     masterha_master_monitor  masterha_secondary_check
注文 効果
masterha_check_ssh MHA の SSH 構成ステータスを確認する
masterha_check_repl MySQL のレプリケーション ステータスを確認する
masterha_manager MHAを開始
masterha_check_status MHA の実行状況を確認する
masterha_stop MHA を停止します。
masterha_master_monitor マスターがダウンしているかどうかを検出する
masterha_master_switch フェイルオーバーの制御 (自動または手動)
masterha_conf_host 構成済みサーバー情報の追加または削除

2.2.3. メイン設定ファイルの変更

##创建工作目录
[root@mha20 ~]# mkdir  /etc/mha
[root@mha20 ~]# cp -r /usr/local/mha4mysql-manager-0.58/samples/conf/app1.cnf /etc/mha/
## 修改配置文件
[root@mha20 mha]# vim /etc/mha/app1.cnf
修改内容如下:
[server default]          ---管理服务的默认配置
manager_workdir=/etc/mha      ---指定工作目录路径
manager_log=/etc/mha/manager.log    ---指定管理服务运行后日志文件的名称和存放路径
master_ip_failover_script=/etc/mha/master_ip_failover      ---指定故障切换脚本
ssh_user=root    ---指定ssh连接时候的用户名和端口号
ssh_port=22

repl_user=master       ---指定主库授权的用户名和密码
repl_password=1234

user=mysqldb				---指定监控用户和密码,三台mysql需要一样。
password=1234

ping_interval=1         ---ping间隔时长
[server1]       			---指定第一台mysql服务器
hostname=192.168.2.30       ---指定第一台mysqlIP地址
port=3306                   ---端口号
candidate_master=1          ---指定该数据库服务器参与竞选主库,1代表参与。

[server2]
hostname=192.168.2.40
port=3306
candidate_master=1

[server3]
hostname=192.168.2.50
port=3306
candidate_master=1

2.2.4. フェイルオーバースクリプトの作成

[root@mha20 mha]# cp -r /usr/local/mha4mysql-manager-0.58/samples/scripts/master_ip_failover /etc/mha/
##给脚本添加执行权限
[root@mha20 mha]# chmod +x /etc/mha/master_ip_failover
##下面是完整的脚本文件,需要修改VIP地址和网卡名称。
[root@mha20 mha]# vim  /etc/mha/master_ip_failover
#!/usr/bin/env perl

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

use Getopt::Long;

my (
    $command,          $ssh_user,        $orig_master_host, $orig_master_ip,
    $orig_master_port, $new_master_host, $new_master_ip,    $new_master_port
);

my $vip = '192.168.2.100/24';     #指定VIP地址
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";   #这里需要注意的就是网卡名称,没人的主机网卡名不一样需要注意。
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";

GetOptions(
    'command=s'          => \$command,
    'ssh_user=s'         => \$ssh_user,
    'orig_master_host=s' => \$orig_master_host,
    'orig_master_ip=s'   => \$orig_master_ip,
    'orig_master_port=i' => \$orig_master_port,
    'new_master_host=s'  => \$new_master_host,
    'new_master_ip=s'    => \$new_master_ip,
    'new_master_port=i'  => \$new_master_port,
);

exit &main();

sub main {
    
    

    print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";

    if ( $command eq "stop" || $command eq "stopssh" ) {
    
    

        my $exit_code = 1;
        eval {
    
    
            print "Disabling the VIP on old master: $orig_master_host \n";
            &stop_vip();
            $exit_code = 0;
        };
        if ($@) {
    
    
            warn "Got Error: $@\n";
            exit $exit_code;
        }
        exit $exit_code;

    }
elsif ( $command eq "start" ) {
    
    

        my $exit_code = 10;
        eval {
    
    
            print "Enabling the VIP - $vip on the new master - $new_master_host \n";
            &start_vip();
            $exit_code = 0;
        };
        if ($@) {
    
    
            warn $@;
            exit $exit_code;
        }
        exit $exit_code;
    }
    elsif ( $command eq "status" ) {
    
    
        print "Checking the Status of the script.. OK \n";
        exit 0;
    }
    else {
    
    
        &usage();
        exit 1;
    }
}
sub start_vip() {
    
    
    `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
sub stop_vip() {
    
    
    return 0  unless  ($ssh_user);
    `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}

sub usage {
    
    
    print
    "Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}

2.2.5. メインデータベース (mysql30) に VIP アドレスを作成する

[root@mysql30 ~]# ifconfig ens33:1 192.168.2.100
[root@mysql30 ~]# ifconfig ens33:1
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.2.100  netmask 255.255.255.0  broadcast 192.168.2.255
        ether 00:0c:29:88:4f:b0  txqueuelen 1000  (Ethernet)

2.3. データベースサーバーの設定 (mysql30-50)

2.3.1. データベースサーバーへの mha4mysql-node パッケージのインストール

##在mysql30、mysql40、mysql50执行如下命令
[root@mysql30 ~]# wget https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.centos.noarch.rpm
[root@mysql30 ~]# yum -y install mha4mysql-node-0.58-0.el7.centos.noarch.rpm

2.3.2. 監視ユーザーの作成

##监控用户是在管理服务器配置文件上指定的:user=xxx,password=xxxx
##在主库上执行,从库自然同步过去。
mysql> grant all on *.* to 'mysqldb'@'%' identified by '1234';
Query OK, 0 rows affected, 1 warning (0.00 sec)

3.構成を確認する

3.1. ssh 設定のテスト

##在mha20服务器上执行测试:
[root@mha20 ~]# masterha_check_ssh --conf=/etc/mha/app1.cnf
....
All SSH connection tests passed successfully    ---最后出现这个就说明配置正确。

3.2. マスター/スレーブ構成のテスト

[root@mha20 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf
...
MySQL Replication Health is OK.    ---出现这个说明MySQL复制运行状况正常

3.3. 管理サービスの開始

  • masterha_manager コマンドで管理サービスを開始します

—— --remove_dead_master_conf は、メイン ライブラリがダウンしたときに、ダウンタイム メイン ライブラリの構成が削除されることを意味します。そうしないと、メイン ライブラリがダウンした後にサービスが開始されません。 --ignore_last_failover は、xxx.health ファイルを無視することを意味します。これは、メイン ライブラリがダウンしている場合、ホストの後、指定された時間内にサービスが残りのスレーブ サーバーに接続して、マスター ライブラリを選択することを意味します。サービス開始時にこのオプションを追加しないと、指定時間内に接続しないとメインライブラリに切り替わらず、本オプション追加後は指定時間内に残りのスレーブに接続できなくなりますメインライブラリが切り替えられるまで、サーバーはその後も接続を試み続けます。

##启动
[root@mha20 ~]# masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf   --ignore_last_failover
##后台启动
nohup  masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf   --ignore_last_failover  &
##查看mha运行状态:
[root@mha20 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:39934) is running(0:PING_OK), master:192.168.2.30
##如果想停止服务可以输入下面命令
[root@mha20 ~]# masterha_stop --conf=/etc/mha/app1.cnf

4 高可用性のテスト

4.1. メイン データベース サーバーの障害をシミュレートする

  • 失敗をシミュレートする方法:
  • mysqld サービスを停止します
  • シャットダウン
  • フェールオーバー プロセス:
    管理ホストが mysql マスター サーバーに接続できない場合、mysql マスター サーバーがダウンしていると見なされ、管理ホストのサービスが自動的に停止され、フェールオーバー スクリプトが呼び出されて内容が削除されます。管理ホストの mysql マスター サーバー ( /etc/mha/app1.cnf) 次に、スクリプトは選択されたマスター サーバーに VIP アドレスを作成します。
##在mysql30主服务关闭mysql服务
[root@mysql30 ~]# systemctl stop mysqld.service
##检查管理主机的配置文件是否删除mysql30的信息。
[root@mha20 ~]# grep "192.168.2.30" /etc/mha/app1.cnf   --执行这条命令可以看的出来,已经没有mysql30的信息了。
##在管理主机上查看日志文件master现在是哪台?
[root@mha20 ~]# grep "new master" /etc/mha/manager.log
Fri Feb 24 14:58:16 2023 - [info] Searching new master from slaves..
192.168.2.40(192.168.2.40:3306) (new master)
Fri Feb 24 14:58:16 2023 - [info] Getting new master's binlog name and position..
Enabling the VIP - 192.168.2.100/24 on the new master - 192.168.2.40
Fri Feb 24 14:58:17 2023 - [info]  Resetting slave 192.168.2.50(192.168.2.50:3306) and starting replication from the new master 192.168.2.40(192.168.2.40:3306)..
Fri Feb 24 14:58:18 2023 - [info] Resetting slave info on the new master..
Selected 192.168.2.40(192.168.2.40:3306) as a new master.
##可以看的出来mysql40被选举出来作为master
##在mysql40上查看VIP地址是否在
[root@mysql40 ~]# ifconfig ens33:1
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.2.100  netmask 255.255.255.0  broadcast 192.168.2.255
        ether 00:0c:29:83:e3:d4  txqueuelen 1000  (Ethernet)
##查看mysql50的slave状态
[root@mysql50 ~]# mysql -uroot -p1234 -e "show slave status \G;"|head -13|tail -11
mysql: [Warning] Using a password on the command line interface can be insecure.
                  Master_Host: 192.168.2.40     ---可以看的出来mysql40已经是masterl 
                  Master_User: master
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master40.000001
          Read_Master_Log_Pos: 154
               Relay_Log_File: mysql50-relay-bin.000002
                Relay_Log_Pos: 319
        Relay_Master_Log_File: master40.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes	
##启动管理主机的mha服务
[root@mha20 ~]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf   --ignore_last_failover &
##查看mha状态
[root@mha20 ~]# masterha_check_status  --conf=/etc/mha/app1.cnf
app1 (pid:57758) is running(0:PING_OK), master:192.168.2.40

4.2. 障害が発生したデータベースサーバーの修復

4.2.1. データサーバーの設定

  • 具体的な操作は次のとおりです。
  1. mysql サービスを開始する
  2. マスター サーバー データとの整合性
  3. マスターサーバー情報の指定
  4. スレーブ プロセスを開始する
  5. スレーブのステータス情報を表示する
## 启动mysql30服务
[root@mysql30 ~]# systemctl start mysqld
##指定主库服务器信息。
mysql> change master to
    -> master_host="192.168.2.40",
    -> master_user="master",
    -> master_password="1234",
    -> master_log_file="master40.000001",
    -> master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.00 sec)
##注意这里指定的binlog的文件名称master40.000001的原因是因为mysql40第一次变成master所以他的文件名是从master40.000001开始的。
##然而pos值=154的原因是为了mysql30和mysql40数据一致,因为假如你查看现在的mysql40的pos值应该会有变化,因为mysql30宕机后生产环境下肯定会往里面写入数据,但是pos值是从154开始的所以直接指定154才能很快的保证数据一致。
mysql> start slave;
##这里就不显示slave的状态了。

4.2.2. 管理ホストの設定

##停止mha服务
[root@mha20 ~]# masterha_stop   --conf=/etc/mha/app1.cnf
##修改mha主配置文件
[root@mha20 ~]# vim /etc/mha/app1.cnf
....
##添加如下:
[server1]
candidate_master=1
hostname=192.168.2.30
port=3306
##启动mha服务
[root@mha20 ~]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf   --ignore_last_failover &
##查看mha状态
[root@mha20 ~]# masterha_check_status   --conf=/etc/mha/app1.cnf
app1 (pid:60567) is running(0:PING_OK), master:192.168.2.40

おすすめ

転載: blog.csdn.net/weixin_45625174/article/details/129158002