• mysql之搭建MHA架构实现高可用


    1、定义

    全称是masterhigh avaliabulity。基于主库的高可用环境下可以实现主从复制及故障切换(基于主从复制才能故障切换)

    MHA最少要求一主两从,半同步复制模式

    2、作用

    解决mysql的单点故障问题。一旦主库崩溃,MHA可以在0-30秒内自动完成故障切换

    3、原理

    (1)MHA使用的是半同步复制方式,只要有一台从服务器写入数据,就会自动提交给客户端

    (2)若master崩溃,slave会从主的二进制日志保存文件;slave会识别最新更新的日志,差异部分同步到slave;提升一个新的slave作为master;其他的slave继续和新的master同步

    4、mysql之MHA实验

    实验思路:

    (1)MHA架构

    (2)数据库安装

    (3)一主两从

    (4)MHA搭建

    实验条件:

    主机名

    修改名称

    IP地址

    作用

    部署组件

    mysql1

    master

    20.0.0.13

    主服务器

    ssh、node、epel源、MHA依赖环境

    mysql2

    slave1

    20.0.0.23

    从服务器1

    ssh、node、epel源、MHA依赖环境

    mysql3

    slave2

    20.0.0.33

    从服务器2

    ssh、node、epel源、MHA依赖环境

    test1

    MHA manager

    20.0.0.10

    MHA

    ssh、node、epel源、MHA依赖环境

    所有服务器上部署:

    epel源——MHA依赖环境——node组件——MHA安装包——ssh

    主、从服务器上部署:

    mysql服务

    ①所有服务器上部署node组件,manage组件依赖node组件,node组件监控mysql的状态,node组件靠ssh来进行通信

    ②所有服务器都要安装MHA的依赖环境(必须安装epel源)

    ③安装epel源:yum install epel-release --nogpgcheck -y

    ④安装MHA依赖环境:yum install -y perl-DBD-MySQL \

    perl-Config-Tiny \

    perl-Log-Dispatch \

    perl-Parallel-ForkManager \

    perl-ExtUtils-CBuilder \

    perl-ExtUtils-MakeMaker \

    perl-CPAN

    实验步骤:

    1.Master、Slave1、Slave2 节点上安装 mysql5.7

    2.修改 Master、Slave1、Slave2 节点的主机名【便于后期识别】

    hostnamectl set-hostname Master

    hostnamectl set-hostname Slave1

    hostnamectl set-hostname Slave2

    3.修改 Master、Slave1、Slave2 节点的 Mysql主配置文件/etc/my.cnf

    ##Master 节点##

    vim /etc/my.cnf

    [mysqld]

    server-id = 1

    log_bin = master-bin

    log-slave-updates = true

    ①log_bin = master-bin:

    用于记录主服务器上的更改操作的日志文件。

    这个配置用于主服务器,将生成的二进制日志文件保存为"master-bin"(可以是其他自定义的名称)

    ②log-slave-updates = true:

    从服务器是否要记录它自己执行的更改操作到自己的二进制日志文件中

    设置为"true"表示从服务器会记录自己执行的更改操作,将其写入从服务器的二进制日志文件中

    ①log_bin = master-bin:

    指定主服务器(master)的二进制日志文件名称,用于记录主服务器上的更改操作的日志文件

    ②relay-log = relay-log-bin:

    指定从服务器的中继日志文件名称,即用于记录主服务器的二进制日志在从服务器上执行的中继日志

    从服务器会读取主服务器的二进制日志并将其记录到中继日志中。这个配置用于从服务器

    ③relay-log-index = slave-relay-bin.index:

    指定从服务器的中继日志索引文件的名称,该索引文件用于跟踪中继日志文件的位置和顺序

    通过这个索引文件,从服务器知道哪个中继日志文件是下一个要读取和执行的。这个配置用于从服务器

    #slave2不用设置master,指定主的备服务器为slave1即可

    4.在 Master、Slave1、Slave2 节点上都创建两个软链接

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

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

    5.配置 mysql 一主两从

    (1)所有数据库节点进行 mysql 授权

    mysql -uroot -p123456

    #从数据库同步使用

    grant replication slave on *.* to 'myslave'@'20.0.0.%' identified by '123';

    #manager 使用

    grant all privileges on *.* to 'mha'@'20.0.0.%' identified by 'manager';

    #防止从库通过主机名连接不上主库

    grant all privileges on *.* to 'mha'@'master' identified by 'manager';

    grant all privileges on *.* to 'mha'@'slave1' identified by 'manager';

    grant all privileges on *.* to 'mha'@'slave2' identified by 'manager';

    flush privileges;

    (2)在 Master 节点查看二进制文件和同步点

    show master status;

    (3)在 Slave1、Slave2 节点执行同步操作

    change master to master_host='20.0.0.13',master_user='myslave',master_password='123',master_log_file='master-bin.000001',master_log_pos=1737;

    start slave;

    (4)在 Slave1、Slave2 节点查看数据同步结果

    show slave status\G;

    //确保 IO 和 SQL 线程都是 Yes,代表同步正常。

    Slave_IO_Running: Yes

    Slave_SQL_Running: Yes

    (5)两个从库必须设置为只读模式:

    set global read_only=1;

    (6)插入数据测试数据库同步

    ##在 Master 主库插入条数据,测试是否同步##

    create database yst;

    6.安装 MHA 软件

    (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

    (2)安装 MHA 软件包,先在所有服务器上必须先安装 node 组件

    对于每个操作系统版本不一样,这里 CentOS7.6选择 0.57 版本。

    在所有服务器上必须先安装 node 组件,最后在 MHA-manager 节点上安装 manager 组件,因为 manager 依赖 node 组件。

    cd /opt

    tar zxvf mha4mysql-node-0.57.tar.gz

    cd mha4mysql-node-0.57

    perl Makefile.PL

    make && make install

    (3)在 MHA manager 节点上安装 manager 组件

    cd /opt

    tar zxvf mha4mysql-manager-0.57.tar.gz

    cd mha4mysql-manager-0.57

    perl Makefile.PL

    make && make install

    MHA重要文件(没有这几个文件,安装不成功)

    masterha_check_ssh

    检查MHA的SSH的配置状况

    masterha_check_repl

    检查mysql的复制情况

    masterha_manager

    启动manager的脚本

    masterha_check_status

    检测MHA的运行状态

    masterha_master_monitor

    检测master主机的情况,master是否宕机

    masterha_master_switch

    控制故障转移

    masterha_conf_host

    添加或删除配置的server信息

    masterha_stop

    停止MHA服务的脚本

    node重要文件(没有这几个文件,安装不成功)

    save_binary_logs

    保存和复制master的二进制日志

    apply_diff_relay_logs

    识别二进制日志中的差异事件,然后发送给其他的slave

    filter_mysqlbinlog

    去除不必要的回滚时间(MHA已不用此文件)

    purge_relay_logs

    同步后清除中继日志(作用:不会阻塞sql的线程)

    7.在所有服务器上配置无密码认证

    (1)在 manager 节点上配置到所有数据库节点的无密码认证

    ssh-keygen -t rsa #一路按回车键

    ssh-copy-id 20.0.0.13

    ssh-copy-id 20.0.0.23

    ssh-copy-id 20.0.0.33

    (2)在 master 上配置到数据库节点 slave1 和 slave2 的无密码认证

    ssh-keygen -t rsa

    ssh-copy-id 20.0.0.23

    ssh-copy-id 20.0.0.33

    (3)在 slave1 上配置到数据库节点 master 和 slave2 的无密码认证

    ssh-keygen -t rsa

    ssh-copy-id 20.0.0.13

    ssh-copy-id 20.0.0.33

    (4)在 slave2 上配置到数据库节点 master 和 slave1 的无密码认证

    ssh-keygen -t rsa

    ssh-copy-id 20.0.0.13

    ssh-copy-id 20.0.0.23

    8.在 manager 节点上配置 MHA

    (1)在 manager 节点上复制相关脚本到/usr/local/bin 目录

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

    (2)复制上述的自动切换时 VIP 管理的脚本到 /usr/local/bin 目录,

    这里使用master_ip_failover脚本来管理 VIP 和故障切换

    cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin

    (3)修改内容如下:(删除原有内容,直接复制并修改vip相关参数)

    vim /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 = '192.168.233.100'; #指定vip的地址

    my $brdc = '192.168.233.255'; #指定vip的广播地址

    my $ifdev = 'ens33'; #指定vip绑定的网卡

    my $key = '1'; #指定vip绑定的虚拟网卡序列号

    my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip"; #代表此变量值为ifconfig ens33:1 192.168.233.100

    my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down"; #代表此变量值为ifconfig ens33:1 192.168.233.100 down

    my $exit_code = 0; #指定退出状态码为0

    #my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip;iptables -F;";

    #my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key";

    ##################################################################################

    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 \"`;

    }

    ## A simple system call that disable the VIP on the old_master

    sub stop_vip() {

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

    }

    ----------------------------------------------------------------------------------------------------------------

    #!/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.233.100';

    my $brdc = '192.168.233.255';

    my $ifdev = 'ens33';

    my $key = '1';

    my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";

    my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";

    my $exit_code = 0;

    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 \"`;

    }

    ### A simple system call that disable the VIP on the old_master

    sub stop_vip() {

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

    }

    管理 MySQL 主从复制设置中的虚拟 IP 故障切换而设计的,可能用于主服务器需要切换到另一台服务器的情景。

    它使用 SSH 在远程服务器上执行命令来控制虚拟 IP 地址

    (4)创建 MHA 软件目录并拷贝配置文件,这里使用app1.cnf配置文件来管理 mysql 节点服务器

    mkdir /etc/masterha

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

    vim /etc/masterha/app1.cnf

    #删除原有内容,直接复制并修改节点服务器的IP地址

    [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.233.22 -s 192.168.233.23

    #从对主监听

    shutdown_script=""

    ssh_user=root

    user=mha

    [server1]

    hostname=192.168.233.21

    #主服务器

    port=3306

    [server2]

    candidate_master=1   

    check_repl_delay=0

    hostname=192.168.233.22  

    #备用主服务器

    port=3306

    [server3]

    hostname=192.168.233.23  

    #从服务器2

    port=3306

    ----------------------------------------------------------------------------------------------------------

    [server default]

    manager_log=/var/log/masterha/app1/manager.log #manager日志

    manager_workdir=/var/log/masterha/app1            #manager工作目录

    master_binlog_dir=/usr/local/mysql/data/ #master保存binlog的位置,这里的路径要与master里配置的binlog的路径一致,以便MHA能找到

    master_ip_failover_script=/usr/local/bin/master_ip_failover #设置自动failover时候的切换脚本,也就是上面的那个脚本

    master_ip_online_change_script=/usr/local/bin/master_ip_online_change #设置手动切换时候的切换脚本

    password=manager #设置mysql中root用户的密码,这个密码是前文中创建监控用户的那个密码

    ping_interval=1 #设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行failover

    remote_workdir=/tmp #设置远端mysql在发生切换时binlog的保存位置

    repl_password=123     #设置复制用户的密码

    repl_user=myslave #设置复制用户的用户

    report_script=/usr/local/send_report #设置发生切换后发送的报警的脚本

    secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.233.22 -s 192.168.233.23 #指定检查的从服务器IP地址

    shutdown_script="" #设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机防止发生脑裂,这里没有使用)

    ssh_user=root #设置ssh的登录用户名

    user=mha #设置监控用户root

    [server1]

    hostname=192.168.233.21

    port=3306

    [server2]

    hostname=192.168.233.22

    port=3306

    candidate_master=1

    #设置为候选master,设置该参数以后,发生主从切换以后将会将此从库提升为主库,

    即使这个从库不是集群中最新的slave

    check_repl_delay=0

    #默认情况下如果一个slave落后master 超过100M的relay logs的话,MHA将不会选择该slave作为一个新的master,

    因为对于这个slave的恢复需要花费很长时间;通过设置check_repl_delay=0,

    MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,

    因为这个候选主在切换的过程中一定是新的master

    [server3]

    hostname=192.168.233.23

    port=3306

    9.第一次配置需要在 Master 节点上手动开启虚拟IP

    /sbin/ifconfig ens33:1 20.0.0.100/24

    10.在 manager 节点上测试 ssh 无密码认证,如果正常最后会输出 successfully,如下所示。

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

    11.在 manager 节点上测试 mysql 主从连接情况,最后出现 MySQL Replication Health is OK 字样说明正常。如下所示。

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

    12.在 manager 节点上启动 MHA

    nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &

    13.查看 MHA 状态,可以看到当前的 master 是 master 节点

    masterha_check_status --conf=/etc/masterha/app1.cnf

    14. 查看 MHA 日志,也以看到当前的 master 是20.0.0.13,如下所示

    cat /var/log/masterha/app1/manager.log | grep "current master"

    15. 查看master 的 VIP 地址 20.0.0.100 是否存在,这个 VIP 地址不会因为 manager 节点停止 MHA 服务而消失

    ifconfig

    //若要关闭 manager 服务,可以使用如下命令

    masterha_stop --conf=/etc/masterha/app1.cnf

    或者可以直接采用 kill 进程 ID 的方式关闭

    16、模拟故障

    关闭主服务器的mysql服务,看虚拟网卡是否漂移到从服务器

    systemctl stop mysqld

    17、故障恢复

    原主服务器故障,从服务器变为新的主。现要恢复故障的服务器,将原主变为从,配置文件也要随之改变

    (1)编辑原主服务器的配置文件【主→从】

    vim /etc/my.cnf

    末尾改成

    log_bin = master-bin

    relay-log = relay-log-bin

    relay-log-index = slave-relay-bin.index

    systemctl restart mysqld.service

    (2)编辑原从服务器的配置文件【从→主】

    vim /etc/my.cnf

    末尾改成

    log_bin = master-bin

    log-slave-updates = true

    systemctl restart mysqld.service

    (3)在manager上关闭manager服务

    //若要关闭 manager 服务,可以使用如下命令

    masterha_stop --conf=/etc/masterha/app1.cnf

    (4)在 manager 节点上修改配置文件app1.cnf(再把这个记录添加进去,因为它检测掉失效时候会自动消失)

    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=123

    repl_user=myslave

    secondary_check_script=/usr/local/bin/masterha_secondary_check -s 20.0.0.23 -s 20.0.0.33

    shutdown_script=""

    ssh_user=root

    user=mha

    [server1]

    hostname=20.0.0.23

    port=3306

    [server2]

    candidate_master=1

    check_repl_delay=0

    hostname=20.0.0.13

    port=3306

    [server3]

    hostname=20.0.0.33

    port=3306

    (5)在 manager 节点上启动 MHA

    nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &

    remove_dead_master_conf

    如果发生主从切换,老的主库的IP地址会从文件中删除

    /var/log/masterha/app1/manager.log

    MHA的管理日志

    ignore_last_failover

    忽略时间间隔,只要发生故障就会切换。若检测到连续发生宕机,且宕机的时间间隔不会进行自动切换

    (6)在现Master 节点查看二进制文件和同步点

    mysql -u root -p123

    show master status;

    +-------------------+----------+--------------+------------------+-------------------+

    | File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

    +-------------------+----------+--------------+------------------+-------------------+

    | master-bin.000003 |      310|              |                  |                   |

    +-------------------+----------+--------------+------------------+-------------------+

    1 row in set (0.00 sec)

    (7)在现slave1 节点上赋权

    mysql -u root -p123

    stop slave;

    change master to master_host='20.0.0.23',master_user='myslave',master_password='123',master_log_file='master-bin.000003',master_log_pos=310;

    reset slave;

    start slave;

    (8)测试

    结论:故障恢复

    18、出现错误

    错误原因:没有在 slave2 上配置到数据库节点 master 和 slave1 的无密码认证

    解决方法:在 slave2 上配置到数据库节点 master 和 slave1 的无密码认证

    ssh-keygen -t rsa

    ssh-copy-id 20.0.0.13

    ssh-copy-id 20.0.0.23

  • 相关阅读:
    极客范儿的浏览器主页YuIndex
    入门力扣自学笔记137 C++ (题目编号793)(未理解)
    前端用JavaScript实现桑基图(Sankey图)
    [附源码]计算机毕业设计JAVA高校新生报到管理系统
    如何监控电动车充电桩能耗?
    Windows11安装配置Git
    python抠图(去水印)开源库lama-cleaner入门应用实践
    java面试题整理《集合篇》二
    通用BIOS自动化修改脚本
    第一章 Google软件测试介绍
  • 原文地址:https://blog.csdn.net/2303_79207100/article/details/134404345