1. 程式人生 > 實用技巧 >mysql mha高可用叢集

mysql mha高可用叢集

master: 192.168.1.51
slave01: 192.168.1.47
slave02: 192.168.1.48
manager: 192.168.1.23
VIP 192.168.1.80

1、關閉防火牆、selinux

2、配置伺服器相互金鑰登陸(遠端埠10022)

3、三臺伺服器上都建立mha管理資料庫的賬號 (我是直接用的root賬戶,密碼全設定的一樣)

4、三臺伺服器上都建立用於主從複製的MySQL使用者repl

一、資料庫配置

master 新增

server_id=1
log_bin=mysql_bin
relay_log=relay_bin
log_slave_updates
=on gtid_mode=ON enforce_gtid_consistency=1 binlog-ignore-db = sys binlog-ignore-db = information_schema binlog-ignore-db = mysql binlog-ignore-db = performance_schema plugin_load="rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so" loose_rpl_semi_sync_master_enabled=1 loose_rpl_semi_sync_slave_enabled
=1 loose_rpl_semi_sync_master_timeout=1000

slave001和slave002(server _id不一樣 )

server_id=2
log_bin=mysql_bin
relay_log=relay_bin
log_slave_updates=on
gtid_mode=ON
enforce_gtid_consistency=1
read_only=1
binlog-ignore-db = sys
binlog-ignore-db = information_schema
binlog-ignore-db = mysql
binlog-ignore-db = performance_schema

plugin_load
="rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so" loose_rpl_semi_sync_master_enabled=1 loose_rpl_semi_sync_slave_enabled=1 loose_rpl_semi_sync_master_timeout=1000

完成以上配置檔案的修改後,分別重啟這三個節點上的MySQL服務

  • 查詢master節點binlog日誌及位點

show master status;

進入slave-01節點的MySQL命令列終端,分別執行如下語句來配置主從複製鏈路:
stop slave;
change master to master_host='192.168.1.51',master_port=3306,master_user='repl',master_password='xxxxxxxxx',master_log_file='mysql_bin.000011',master_log_pos=412;
start slave;
show slave status\G;

匯出匯入資料庫
mysqldump -u root -p --master-data=1 --single-transaction -all-databases >/all.sql
source /all.sql

二、所有伺服器都安裝mha node節點

1、安裝依賴環境

yum install -y epel-release
yum -y install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm

2、下載mha node 軟體

wget https://raw.githubusercontent.com/linyue515/mysql-master-ha/master/mha4mysql-node-0.58-0.el7.noarch.rpm

3、安裝node

rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm

三、manager伺服器安裝mha manage

1、安裝依賴環境

yum install -y epel-release
yum -y install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm

2、下載mha manage 軟體

wget https://raw.githubusercontent.com/linyue515/mysql-master-ha/master/mha4mysql-manager-0.58-0.el7.noarch.rpm

3、安裝manage軟體

rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

4、建立mha配置檔案mysql_mha.cnf

vim /etc/mha/mysql_mha.cnf

[server default]
# mha用於訪問資料庫的賬戶和密碼
user=root
password=@abcd123#w!99
# 指定mha的工作目錄
manager_workdir=/home/mysql_mha
# mha日誌檔案的存放路徑
manager_log=/home/mysql_mha/manager.log
# 指定mha在遠端節點上的工作目錄
remote_workdir=/home/mysql_mha/tmp
# 可以使用ssh登入的使用者
ssh_user=root
ssh_port=10022
# 用於主從複製的MySQL使用者和密碼
repl_user=repl
repl_password=TTdjy911.500
# 指定間隔多少秒檢測一次
ping_interval=1
# 指定master節點存放binlog日誌檔案的目錄
master_binlog_dir=/var/lib/mysql
# 指定一個指令碼,該指令碼實現了在主從切換之後,將虛擬IP漂移到新的Master上
master_ip_failover_script = /usr/bin/master_ip_failover
master_ip_online_change_script = /usr/bin/master_ip_online_change
# 指定用於二次檢查節點狀態的指令碼
secondary_check_script=/usr/bin/masterha_secondary_check -s 192.168.1.51 -s 192.168.1.47 -s 192.168.1.48 --port=10022

# 配置叢集中的節點資訊
[server1]
hostname=192.168.1.51
port=3306
#master_binlog_dir=/usr/local/mysql/logs
# 指定該節點可以參與Master選舉
candidate_master=1
check_repl_delay=0

[server2]
hostname=192.168.1.47
port=3306
#master_binlog_dir=/usr/local/mysql/logs
candidate_master=1
check_repl_delay=0

[server3]
hostname=192.168.1.48
port=3306
#master_binlog_dir=/usr/local/mysql/logs
# 指定該節點不能參與Master選舉
no_master=1
ignore_fail=1

建立配置檔案路徑、日誌檔案路徑

mkdir -p /etc/mha
mkdir -p /home/mysql_mha

5、配置VIP切換指令碼master_ip_failover

vim -b /usr/bin/master_ip_failover (vim -b 檢視是否有中文符號, 後面帶M的就是有中文字元,要刪掉,不然在測試的時候會提示找不到檔案)

#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;

my (
    $command, $orig_master_host, $orig_master_ip,$ssh_user,
    $orig_master_port, $new_master_host, $new_master_ip,$new_master_port,
    $orig_master_ssh_port,$new_master_ssh_port,$new_master_user,$new_master_password
);

# 這裡定義的虛擬IP可以根據實際情況進行修改
my $vip = '192.168.1.80/24';
my $key = '1';
# 這裡的網絡卡名稱 “ens224” 需要根據你機器的網絡卡名稱進行修改
my $ssh_start_vip = "sudo /usr/sbin/ifconfig ens224:$key $vip";
my $ssh_stop_vip = "sudo /usr/sbin/ifconfig ens224:$key down";
#my $ssh_Bcast_arp= "sudo /sbin/arping -I bond0 -c 3 -A $vip";

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,
    'orig_master_ssh_port=i' => \$orig_master_ssh_port,
    'new_master_host=s'  => \$new_master_host,
    'new_master_ip=s'    => \$new_master_ip,
    'new_master_port=i'  => \$new_master_port,
    'new_master_ssh_port' => \$new_master_ssh_port,
    'new_master_user' => \$new_master_user,
    'new_master_password' => \$new_master_password

);

exit &main();

sub main {
    $ssh_user = defined $ssh_user ? $ssh_user : 'root';
    print "\n\nIN SCRIPT TEST====$ssh_user|$ssh_stop_vip==$ssh_user|$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();
        &start_arp();
            $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 -p 10022 $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
sub stop_vip() {
    `ssh -p 10022 $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}


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

6、建立線上手動切換vip指令碼master_ip_online_change

vim -b /usr/bin/master_ip_online_change

#!/usr/bin/env perl
use strict; 
use warnings FATAL =>'all';
 
use Getopt::Long; 
 
my $vip = '192.168.1.80/24'; 
my $key = "1";  
my $ssh_start_vip = "/sbin/ifconfig ens224:$key $vip";  
my $ssh_stop_vip = "/sbin/ifconfig ens224:$key down";  
my $exit_code = 0;  
  
my (  
  $command,              $orig_master_is_new_slave, $orig_master_host,  
  $orig_master_ip,       $orig_master_port,         $orig_master_user,  
  $orig_master_password, $orig_master_ssh_user,     $new_master_host,  
  $new_master_ip,        $new_master_port,          $new_master_user,  
  $new_master_password,  $new_master_ssh_user,  
);  
GetOptions(  
  'command=s'                => \$command,  
  'orig_master_is_new_slave' => \$orig_master_is_new_slave,  
  'orig_master_host=s'       => \$orig_master_host,  
  'orig_master_ip=s'         => \$orig_master_ip,  
  'orig_master_port=i'       => \$orig_master_port,  
  'orig_master_user=s'       => \$orig_master_user,  
  'orig_master_password=s'   => \$orig_master_password,  
  'orig_master_ssh_user=s'   => \$orig_master_ssh_user,  
  'new_master_host=s'        => \$new_master_host,  
  'new_master_ip=s'          => \$new_master_ip,  
  'new_master_port=i'        => \$new_master_port,  
  'new_master_user=s'        => \$new_master_user,  
  'new_master_password=s'    => \$new_master_password,  
  'new_master_ssh_user=s'    => \$new_master_ssh_user,  
);  
  
  
exit &main();  
  
sub main {  
  
#print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";  
  
if ( $command eq "stop" || $command eq "stopssh" ) {  
  
        # $orig_master_host, $orig_master_ip, $orig_master_port are passed.  
        # If you manage master ip address at global catalog database,  
        # invalidate orig_master_ip here.  
        my $exit_code = 1;  
        eval {  
            print "\n\n\n***************************************************************\n";  
            print "Disabling the VIP - $vip on old master: $orig_master_host\n";  
            print "***************************************************************\n\n\n\n";  
&stop_vip();  
            $exit_code = 0;  
        };  
        if ($@) {  
            warn "Got Error: $@\n";  
            exit $exit_code;  
        }  
        exit $exit_code;  
}  
elsif ( $command eq "start" ) {  
  
        # all arguments are passed.  
        # If you manage master ip address at global catalog database,  
        # activate new_master_ip here.  
        # You can also grant write access (create user, set read_only=0, etc) here.  
my $exit_code = 10;  
        eval {  
            print "\n\n\n***************************************************************\n";  
            print "Enabling the VIP - $vip on new master: $new_master_host \n";  
            print "***************************************************************\n\n\n\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";  
        `ssh -p 10022 $orig_master_ssh_user\@$orig_master_host \" $ssh_start_vip \"`;  
        exit 0;  
}  
else {  
&usage();  
        exit 1;  
}  
}  
 
# A simple system call that enable the VIP on the new master  
sub start_vip() {  
`ssh -p 10022 $new_master_ssh_user\@$new_master_host \" $ssh_start_vip \"`;  
}  
# A simple system call that disable the VIP on the old_master  
sub stop_vip() {  
`ssh -p 10022 $orig_master_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_maste
r_ip=ip --new_master_port=port\n";

將指令碼賦予可執行許可權

chmod +x /usr/bin/master_ip_failover

chmod +x /usr/bin/master_ip_online_change

四、在master伺服器建立vip

ifconfig ens224:1 192.168.1.80/24

ifconfig ens224:1 del 192.168.1.80 #刪除vip

ifconfig ens224:1 down #關閉vip

五、測試MHA配置資訊是否正常

檢查ssh配置

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

檢查主從複製情況

masterha_check_repl --conf=/etc/mha/mysql_mha.cnf

六、啟動mha

nohup masterha_manager --conf=/etc/mha/mysql_mha.cnf --ignore_last_failover /home/mysql_mha/manager.log 2>&1 &

檢視mha狀態
masterha_check_status --conf=/etc/mha/mysql_mha.cnf
關閉mha
masterha_stop --conf=/etc/mha/mysql_mha.cnf

檢視mha日誌

tail -30f /home/mysql_mha/manager.log

日誌中大致的流程是檢測到主庫(192.168.1.51:3306)不可用-->連續試探3次(次數可自定義)-->檢測進群中剩餘存活的節點-->從備選主節點中選擇一個節點為主節點-->漂移VIP至新的主節點(如果原主節點系統正常則將VIP在原主機上刪除)-->拷貝原主節點的binlog日誌-->新主節點判斷是否需要補充日誌-->其他節點全部改為從新主節點複製資料(組成新的叢集)

七、手動進行主備切換(在進行手動切換前要先停值manager程序)

masterha_master_switch --conf=/etc/mha/mysql_mha.cnf --master_state=alive --new_master_host=192.168.1.47 --orig_master_is_new_slave --running_updates_limit=10000 --interactive=0

八、舊主啟動之後,把它重新加入mha並把它重新設定為master的流程


set global read_only=1;設定為從
stop slave;
然後根據manage日誌查切換到新的master時的master_log_file、master_log_pos

change master to master_host='192.168.1.47',master_port=3306,master_user='repl',master_password='xxxxxxxx',master_log_file='mysql_bin.000023',master_log_pos=779;

加入mha叢集重新檢測repl複製狀態

masterha_check_repl --conf=/etc/mha/mysql_mha.cnf

沒問題的話手動進行主備切換(在進行手動切換前要先停值manager程序)

masterha_master_switch --conf=/etc/mha/mysql_mha.cnf --master_state=alive --new_master_host=192.168.1.51 --orig_master_is_new_slave --running_updates_limit=10000 --interactive=0

沒問題的話啟動mha程序

報錯:

主節點SlaveIO未執行

[/usr/share/perl5/vendor_perl/MHA/Server.pm,ln490]SlaveIOthreadisnotrunningon192.168.1.51(192.168.1.51:3306)

因為主庫自己設成自己從庫了,你主庫showslavestatus,就知道咋回事了;可以stopslave——resetslave——servicemysqldrestart。然後測試實施

ERROR 1776 (HY000): Parameters MASTER_LOG_FILE, MASTER_LOG_POS, RELAY_LOG_FILE and RELAY_LOG_POS can

change master to master_auto_position=0;

Multi-master configuration is detected, but two or more masters are eith er writable (read-only is not set) or dead!

set global read_only=1;

參考:

https://blog.51cto.com/zero01/2468767
https://www.cnblogs.com/qixing/p/13205542.html
https://blog.csdn.net/fw19940314/article/details/107118776
https://www.lagou.com/lgeduarticle/129881.html
https://mp.weixin.qq.com/s?__biz=MzIwMjcwMTQzMA==&mid=2247483742&idx=1&sn=cd43e876326c815680424278368a8c38&chksm=96dbee47a1ac6751980bbe3b4ca2b91289f3eca48c5b339480369e95958600d2426e2b80cd74&mpshare=1&scene=24&srcid=1017OBKmvZ5iwnVgwBD8veOs&sharer_sharetime=1602901600026&sharer_shareid=914430d88182d4290318605488d02a01&key=221452a4d6b5ef37177a4e3daae922a8ec075c34fdc30f66a619e6d1291b5f042d03303e6d7e85f7c362ee7bd242bd7baa474d24bba076a4ce20087440481ecda973025eaae46bf98632fd75d1d9d325af4e3ccdc1d2bc95fb65b98f239d32510b58af3d8c2eb16130a68fc9cb010ba575d278e2d66df3b653b9a8b041bba2ef&ascene=14&uin=MjA2MzczMTEyMQ%3D%3D&devicetype=Windows+7+x64&version=62090529&lang=zh_CN&exportkey=Acyzr1VmssT6jrN8EdFdPK4%3D&pass_ticket=oyQy3uk3wXjNBom4WfmxkmHzUAQ%2FQmi7OdJgaxmrxurE54MfCPaaqy%2B5mv7QAYPe&wx_header=0