mysql5.7MHA配置

莫莫学习發表於2024-03-11

準備工作,三臺伺服器,安裝mysql5.7-glibc版本,做主從配置,用gtid模式。

安裝mysql

1、準備安裝包

[root@hk2 install]# ll mysql-5.7.32-linux-glibc2.12-x86_64.tar.gz 
-rw-r--r-- 1 root root 661214270 Jan 20 19:59 mysql-5.7.32-linux-glibc2.12-x86_64.tar.gz

2、解壓縮,環境變數,加path

tar zxvf mysql-5.7.32-linux-glibc2.12-x86_64.tar.gz 
mv mysql-5.7.32-linux-glibc2.12-x86_64 /data/server/mysql
環境變數
echo 'export PATH=$PATH:/data/server/mysql/bin'  >> /etc/profile
source /etc/profile
建使用者,授權
useradd -s /sbin/nologin -M mysql
mkdir -p /linux0224/
mkdir -p /linux0224/mysql_3306/

授權
chown -R mysql.mysql /linux0224/
chown -R mysql.mysql /linux0224/mysql_3306/
# 因為解壓目錄不一樣,所以做一個軟連結
ln -s /data/server/mysql /opt/mysql
chown -R mysql.mysql /opt/mysql*

3、初始化

mysqld --initialize-insecure --user=mysql --basedir=/opt/mysql --datadir=/linux0224/mysql_3306/

4、修改配置檔案

cat >/etc/my.cnf <<'EOF'

[mysqld]
port=3306
user=mysql
basedir=/opt/mysql
datadir=/linux0224/mysql_3306/
socket=/tmp/mysql.sock

[mysql]
socket=/tmp/mysql.sock
EOF

5、修改啟動指令碼

cp /opt/mysql/support-files/mysql.server   /etc/init.d/mysqld
systemctl daemon-reload
systemctl status mysqld
systemctl start mysqld

6、登入驗證

[root@hk2 install]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.32 MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

# 完成

三臺伺服器都安裝好mysql,這是基礎安裝,沒有做主從和最佳化,先保證mysql能夠啟動正常。

主從配置:

如果主庫有資料,先做備份,從庫匯入。

mysqldump -A > all.sql
複製到從庫
for i in 52 53 ;do scp /data/full.sql 172.16.5.$i:/opt/;done
mysql < /opt/all.sql

主從配置,主庫:

[root@hk33 install]# cat /etc/my.cnf

[mysqld]

binlog_format=row
gtid-mode=on 
enforce-gtid-consistency=true
log-slave-updates=1

port=3306
user=mysql
basedir=/opt/mysql
datadir=/linux0224/mysql_3306/
socket=/tmp/mysql.sock
log_error=/var/log/mysql/mysql.err 
server_id=1
log_bin=/binlog/mysql-bin
[mysql]
socket=/tmp/mysql.sock
[client] 
socket=/tmp/mysql.sock

從庫兩臺和主庫配置一樣,id不一樣。

建立binlog目錄,授權
mkdir /binlog/
chown mysql.mysql /binlog/
日誌目錄
mkdir /var/log/mysql/
chown mysql.mysql /var/log/mysql/

建立主從關係,因為要做MHA,三臺伺服器都執行如下語句。

grant replication slave on *.* to 'slave'@'%' identified by 'slave_pwd';

然後在主庫上執行如下命令,檢視binlog

mysql> show master status;
+------------------+----------+--------------+------------------+------------------------------------------------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                                                                  |
+------------------+----------+--------------+------------------+------------------------------------------------------------------------------------+
| mysql-bin.000003 |      652 |              |                  | 03a2b688-ddc5-11ee-90df-000c293d0361:1-2,
1b604040-ddc4-11ee-929d-000c291478ee:1-3 |
+------------------+----------+--------------+------------------+------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

在兩臺從庫上執行建立同步

從庫分別執行
停止slave
stop slave;
change master to master_host='172.16.5.51',master_user='slave',master_password='slave_pwd',MASTER_AUTO_POSITION=1;
開啟slave
start slave;

MHA過程

建立一個只讀使用者,在主庫執行就可以,會自動同步操作
grant select  on *.* to dev0224@'172.16.5.%' identified by 'dev0224';
# 用root設定全域性鎖
set global read_only=1;

區別
1. grant select 是我們主動給使用者賬戶,限制只查詢的許可權,只是針對這個賬號而已

2. 設定--read-only只讀會話,是針對當前資料庫例項而言的,所有使用者而言

MHA工具會檢測mysql命令,這裡還需要加軟連線

ln -s /opt/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog

ln -s /opt/mysql/bin/mysql /usr/bin/mysql

2.所有節點執行-全部互相通訊

yum install sshpass -y


ssh-keygen
sshpass -p '123123' ssh-copy-id 172.16.5.51 -o StrictHostKeyChecking=no
sshpass -p '123123' ssh-copy-id 172.16.5.52 -o StrictHostKeyChecking=no
sshpass -p '123123' ssh-copy-id 172.16.5.53 -o StrictHostKeyChecking=no

所有節點安裝MHA-node

mha-node軟體,--mha-manage通訊

# mha perl語言開發的
# 1.先安裝依賴環境

yum install  -y perl-DBD-MySQL -y


# 2.安裝軟體
yum localinstall mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y

db-53安裝MHA-Manager,manager節點不能是master節點,因為需要其他伺服器檢測主伺服器是否掛了

因為Manager管理節點,透過ssh檢測mysql叢集,如果master節點伺服器當機,或者網路故障,MHA也無法完成故障切換了。

因此mha-manager不能裝在master節點

yum install epel-release -y

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


yum localinstall -y mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

所有節點建立mha使用者

mha命令,指令碼,透過這個使用者,檢測 所有機器的 主從複製狀態

# db-51執行即可

mysql> 
mysql> grant all privileges on *.* to mha@'%' identified by 'mha0224';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

建立db-53的manager配置檔案

mkdir -p /etc/mha           #<==在/etc下建立mha目錄。
mkdir -p /var/log/mha/app1  #<==在/etc下建立mha目錄。

使用該配置即可

所有節點要執行下邊這一句,mysql命令列

grant replication slave on . to repl_0224@'%' identified by 'repl_pwd';

以下在53上執行

# author:www.yuchaoit.cn
cat > /etc/mha/app1.cnf << 'EOF'
[server default]
manager_log=/var/log/mha/app1/manager.log
manager_workdir=/var/log/mha/app1.log
master_binlog_dir=/mysql_binlog/
# 該指令碼暫時先註釋
master_ip_failover_script=/usr/local/bin/master_ip_failover
user=mha
password=mha0224
ping_interval=2
# 填入你當前主從賦值,賬號密碼

repl_user=repl_0224
repl_password=repl_pwd
#  mha 用這個賬戶,免密登入3個節點機器
# 聽懂111

ssh_user=root

[server1]
hostname=172.16.5.51
port=3306

[server2]
hostname=172.16.5.52
port=3306

[server3]
hostname=172.16.5.53
port=3306
EOF

建立基於VIP的MHA高可用性資料庫

只需要修改這個指令碼,填入你的網路卡環境即可

建立如下指令碼,mha配置檔案,會自動呼叫它,perl語言指令碼

/usr/local/bin/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 = '172.16.5.55/24';
# 給網路卡新增的別名
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";
my $ssh_Bcast_arp="/sbin/arping -I ens33 -c 3 -A 172.16.5.55";

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;
    }
}

# author: www.yuchaoit.cn

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";
}

給當前的主庫機器,新增VIP,我的在51上

# 建立
ifconfig ens33:1 172.16.5.55/24


下邊兩行不用執行
# 刪除
ifconfig ens33:1 del 172.16.5.55


# 停止
ifconfig ens33:1 down

準備啟動MHA,先進行一下狀態檢查

檢測如下MHA執行條件
# mha提供了很方便的指令碼,檢測你的mha環境搭建情況
- SSH免密登入
- MySQL主從複製


[root@db-53 ~]#masterha_check_ssh --conf=/etc/mha/app1.cnf 
Tue Aug  2 00:36:08 2022 - [info] All SSH connection tests passed successfully.



# 主從檢測指令碼,會用到mha賬號,在三個機器上進行檢測登入

# 再檢查主從複製狀態
masterha_check_repl --conf=/etc/mha/app1.cnf

結果要全部成功才行

啟動MHA,然後進行故障演示

1. 啟動mha的管理節點,後臺執行即可---用的是 db-53機器

[root@db-53 ~]#
[root@db-53 ~]#nohup masterha_manager --conf=/etc/mha/app1.cnf  --remove_dead_master_conf  --ignore_last_failover /var/log/mha/app1/manager.log 2>&1 &
[1] 3647
[root@db-53 ~]#nohup: ignoring input and appending output to ‘nohup.out’

[root@db-53 ~]#
[root@db-53 ~]#
[root@db-53 ~]#jobs
[1]+  Running                 nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover /var/log/mha/app1/manager.log 2>&1 &
[root@db-53 ~]#
[root@db-53 ~]#
[root@db-53 ~]#ps -ef|grep mha
root       3647   1634  1 20:37 pts/0    00:00:00 perl /usr/bin/masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover /var/log/mha/app1/manager.log
root       3664   1634  0 20:37 pts/0    00:00:00 grep --color=auto mha


2 .檢查MHA是否執行中
[root@db-53 ~]#masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:3647) is running(0:PING_OK), master:172.16.5.51
# mha此時確認主庫正常,還是 51機器

故障演練

期望的結果是
1. 當前環境
db-51    master 

db-52   slave  

db-53    slave  

2. 幹掉主庫
pkill mysql


2.1 檢視VIP的狀態,MHA指令碼切換VIP到新的主庫上,51機器的VIP沒了
已確認 51機器的VIP沒了


3. 檢視主從複製關係
[root@db-53 ~]#mysql -uroot -plinux0224
mysql> show slave status\G

得到結論,MHA自動選舉 db-52為新的主庫

還得做資料的驗證,看看舊的主庫51機器的binlog,和52新主庫對比
[root@db-51 /mysql_binlog]#mysqlbinlog -vv  mysql-bin.000002 |grep -i 'gtid'

最後一次提交是 事務id是 8
自動下一次的事務,9開始

---看52機器


----52機器




4.  MHA再發生切換後,該程式會掛掉
也確認了

測試新的主從關係

52機器寫入資料
已確認 事務提交更新,寫入到新機器 52的 GTID版本號裡了
6a952706-1a30-11ed-882e-000c294c7d18:2

去新的從庫檢視資料,以及比對GTID號碼

GTID號碼
以配置檔案裡 server_id 
SHOW GLOBAL VARIABLES LIKE 'server_uuid';

到現在,52已經提升為主了。

恢復MHA,先將51加入進mysql叢集,做為52的從。

1. 51機器,直接啟動,和新的主庫建立複製就行,預測,51機器,是否能看到最新的 52機器的資料

# 1.啟動
systemctl start mysqld

# 2. 加入主從
mysql -uroot -plinux0224

change master to master_host='172.16.5.52', master_user='slave', master_password='slave_pwd' , MASTER_AUTO_POSITION=1;


start slave;

show slave status;

然後將51加入到MHA叢集中

[root@db-53 ~]#cat /etc/mha/app1.cnf 
[server default]
manager_log=/var/log/mha/app1/manager.log
manager_workdir=/var/log/mha/app1.log
master_binlog_dir=/mysql_binlog/
master_ip_failover_script=/usr/local/bin/master_ip_failover
password=mha0224
ping_interval=2
repl_password=repl0224
repl_user=repl
ssh_user=root
user=mha

[server2]
hostname=10.0.0.52
port=3306

[server3]
hostname=10.0.0.53
port=3306



1.新增db-51機器的 配置資訊
masterha_conf_host --command=add --conf=/etc/mha/app1.cnf --hostname=172.16.5.51 --block=server1 --params="port=3306"


[root@db-53 ~]#cat /etc/mha/app1.cnf 
[server default]
manager_log=/var/log/mha/app1/manager.log
manager_workdir=/var/log/mha/app1.log
master_binlog_dir=/mysql_binlog/
master_ip_failover_script=/usr/local/bin/master_ip_failover
password=mha0224
ping_interval=2
repl_password=repl0224
repl_user=repl
ssh_user=root
user=mha

[server1]
hostname=10.0.0.51
port=3306

[server2]
hostname=10.0.0.52
port=3306

[server3]
hostname=10.0.0.53
port=3306
[root@db-53 ~]#

2.重新檢測2 ssh,repl

先檢查複製情況
[root@db-53 ~]#masterha_check_repl --conf=/etc/mha/app1.cnf

masterha_check_ssh --conf=/etc/mha/app1.cnf

3. 啟動即可

nohup masterha_manager --conf=/etc/mha/app1.cnf  --remove_dead_master_conf  --ignore_last_failover /var/log/mha/app1/manager.log 2>&1 &

這時是將51加入到叢集中了,但現在主還在52上,需要手動將52再停掉,51會自動提升為master。然後再執行上邊類似的命令,將52再加入回來。整個演練就結束了。