MySQL MHA详细搭建步骤
发布时间:2022-07-04 22:30:09 所属栏目:MySql教程 来源:互联网
导读:环境: 用3台服务器搭建MySQL MHA 主节点:192.168.157.128 CentOS 7.6 数据库:mysql-5.7.27-linux-glibc2.12-x86_64 从节点:192.168.157.129 CentOS 7.6 数据库:mysql-5.7.27-linux-glibc2.12-x86_64 管理节点:192.168.157.130 CentOS 7.6 数据库:my
环境: 用3台服务器搭建MySQL MHA 主节点:192.168.157.128 CentOS 7.6 数据库:mysql-5.7.27-linux-glibc2.12-x86_64 从节点:192.168.157.129 CentOS 7.6 数据库:mysql-5.7.27-linux-glibc2.12-x86_64 管理节点:192.168.157.130 CentOS 7.6 数据库:mysql-5.7.27-linux-glibc2.12-x86_64 1、3台服务器都安装操作系统 CentOS 7.6 2、 MySQL 安装以及主从设置 三台机器都要做: 关闭防火墙: systemctl stop firewalld.service systemctl disable firewalld.service systemctl status firewalld.service #关闭selinux setenforce 0 PS: 临时关闭: [root@localhost ~]# getenforce Enforcing [root@localhost ~]# setenforce 0 [root@localhost ~]# getenforce Permissive 永久关闭: [root@localhost ~]# vi /etc/sysconfig/selinux SELINUX=enforcing 改为 SELINUX=disabled 重启服务reboot #删除预装mysql rpm -qa|grep mariadb rpm -e --nodeps mariadb-libs-5.5.60-1.el7_5.x86_64 #解压 tar zxvf mysql-5.7.27-linux-glibc2.12-x86_64.tar.gz -C /opt #改名 mv mysql-5.7.27-linux-glibc2.12-x86_64 mysql #新建mysql用户 useradd mysql passwd mysql # #初始化 mkdir -p /opt/mysql/data chown -R mysql:mysql /opt/ chown -R mysql:mysql /opt/ #建立相关文件夹 mkdir -p /opt/mysql/tmp mkdir -p /opt/mysql/log #更改文件夹权限 chown -R mysql:mysql /opt/mysql #创建mysql.err文件 [root@mha02 opt]# cd mysql/log [root@mha02 log]# ll total 0 [root@mha02 log]# touch mysql.err [root@mha02 log]# chown -R mysql:mysql mysql.err #初始化数据库 mysql/bin/mysqld --initialize --user=mysql --basedir=/opt/mysql/ --datadir=/opt/mysql/data/ #简单配置 ln -s /opt/mysql/bin/mysql /usr/bin ln -s /opt/mysql/bin/mysqladmin /usr/bin ln -s /opt/mysql/bin/mysqldump /usr/bin #mysql配置文件,每个服务器的server-id要不同 vi /etc/my.cnf [client] port=3306 socket=/opt/mysql/tmp/mysql.sock [mysqld] user=mysql datadir=/opt/mysql/data basedir=/opt/mysql socket=/opt/mysql/tmp/mysql.sock log-error=/opt/mysql/log/mysql.err pid-file=/opt/mysql/tmp/mysqld.pid # id每台机器要不同 server-id = 186 #做双主时的设置,保证另一个主库操作能写入 log_slave_updates #从库不会跟着主库重启 skip-slave-start #开启gtid模式,5.7特有 gtid_mode = on enforce_gtid_consistency = 1 log_slave_updates = 1 #半同步复制模式 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 = 5000 #指定binlog与relay地址 log-bin = /opt/mysql/log/mysql-bin relay-log = /opt/mysql/log/mysql-relay-bin #不要同步哪些库,较好的写法 replicate-wild-ignore-table=mysql.% replicate-wild-ignore-table=test.% replicate-wild-ignore-table=information_schema.% #开启数据库 /opt/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf & #登录数据库,修改root密码 mysql -p 之前初始化的密码 mysql> alter user root@'localhost' identified by '123456'; mysql>flush privileges; 增加root远程登录用户: mysql> create user root@'%' identified by '123456'; Query OK, 0 rows affected (0.01 sec) mysql> grant all privileges on *.* to root@'%'; mysql> flush privileges; 关闭MySQL服务: [root@mha01 bin]# mysqladmin -uroot -p -S /opt/mysql/tmp/mysql.sock shutdown 开启MySQL服务: /opt/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf & 同样在其余两个服务器上安装MySQL服务。 #登录mysql,在三个mysql中都配置账号,注意,不能把mysql库作为binlog复制库,否则新建的slave账号会报错 #创建slave账号 mysql> grant replication slave,replication client on *.* to 'repl'@'%' identified by '123456'; #创建mha管理账号 mysql> grant all on *.* to 'monitor'@'%' identified by '123456'; #在slave节点上执行 mysql> set global read_only=1; #由于从库随时会提升成主库,不能写在配置文件里 #MHA需要通过relay-log去校验slave是否数据读写一致,不要写进配置文件,所有mysql节点执行 mysql>set global relay_log_purge=0; #设置主从 1、主库查看master mysql> show master status; +------------------+----------+--------------+------------------+------------------------------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+------------------------------------------+ | mysql-bin.000002 | 932 | | | 58d16735-bdae-11e9-b8d3-000c29f97b79:1-8 | +------------------+----------+--------------+------------------+------------------------------------------+ 1 row in set (0.00 sec) 2、slave库执行 mysql> change master to master_host='192.168.157.128', master_user='repl', master_password='123456', master_log_file='mysql-bin.000002', master_log_pos=932; 用GTID启动slave: mysql>change master to master_host='192.168.157.128', master_user='repl', master_password='123456', master_auto_position=1; mysql> start slave; Query OK, 0 rows affected (0.02 sec) mysql> show slave statusG; Relay_Master_Log_File: mysql-bin.000003 Slave_IO_Running: Yes Slave_SQL_Running: Yes 看到两个YES,即代表主从成功。 3、搭建MHA 三台主机ssh互信 注意:三台主机都要做,并且要本机对本机的SSH认证 #因为mha需要manager对自己ssh免密登录 ssh-keygen -t rsa ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.157.128 ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.157.129 ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.157.130 三台机器都要做: 在/opt目录下安装: 在所有节点安装MHA node所需的perl模块,如下: #CentOS 6 下载点 rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm #CentOS 7 下载点 rpm -ivh http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm #安装所需控件 #yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-YAML-Tiny perl-PAR-Dist perl-Module-ScanDeps perl-Module-CoreList perl-Module-Build perl-CPAN perl-CPANPLUS perl-File-Remove perl-Module-Install #下载node和manager软件 # node git 地址:https://github.com/yoshinorim/mha4mysql-node # manager git 地址:https://github.com/yoshinorim/mha4mysql-manager # node 所有机器都要安装 # manager 只需要管理节点安装 yum -y install git git clone https://github.com/yoshinorim/mha4mysql-node.git #管理节点安装 git clone https://github.com/yoshinorim/mha4mysql-manager.git 安装MHA cd /opt/mha4mysql-node perl Makefile.PL make && make install cd /opt/mha4mysql-manager perl Makefile.PL make && make install 注意:在perl Makefile.PL时,可能会出现类似Can't locate inc/Module/XXX.pm in @INC的报错 这是由于缺少组件造成的,只需要安装相应附件 例: yum -y install perl-Module-XXX 一般有对应的名字插件,安装就好 #node方面的都已经配好了,然后是manager节点的操作 配置 Manager 节点,以下步骤都是Manager节点操作 #新建MHA配置文件 mkdir /var/log/mha/app1 -p touch /var/log/mha/app1/manager.log vi /etc/masterha.cnf [server default] #监控用户 user=monitor password=123456 #ssh 用户 ssh_user=root #slave 用户 repl_user=repl repl_password=123456 #ping 三次不通判断失联 ping_interval=3 #使用其他主机去ping,判断是否主机本身故障 secondary_check_script=masterha_secondary_check -s 192.168.157.128 -s 192.168.157.129 -s 192.168.157.130 #相关脚本位置,都要自建,默认是没有的 master_ip_failover_script=/usr/local/bin/master_ip_failover master_ip_online_change_script= /usr/local/bin/master_ip_online_change report_script=/usr/local/bin/send_report #指定MHA日志目录 manager_workdir=/var/log/mha/app1 manager_log=/var/log/mha/app1/manager.log #指定bin-log位置 master_binlog_dir=/opt/mysql/log/ remote_workdir=/var/log/mha/mysqltmp [server1] hostname=192.168.157.128 port=3306 [server2] hostname=192.168.157.129 port=3306 #是否无视落后进度让他成为master candidate_master=1 check_repl_delay=0 [server3] hostname=192.168.157.130 #永远不会成为master。多用于manager no_master=1 port=3306 #配置VIP #为了防止脑裂发生,推荐生产环境采用脚本的方式来管理虚拟 ip,而不是使用 keepalived来完成 vi /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 ); #定义VIP变量 #此处修改VIP地址,预先选择的VIP地址 my $vip = '192.168.157.197/24'; my $key = '1'; #修改ifconfig之后的网卡名,其他地方都不要改动 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 "nnIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===nn"; 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 { "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=portn"; } #配置报警邮件脚本 #安装邮件 yum install mailx -y vi /etc/mail.rc #修改mail配置文件,在配置文件最后新增 #邮箱地址 set from=ywzj_002@163.com #邮箱的smtp地址 set smtp=smtp.163.com #邮箱的用户名 set smtp-auth-user=ywzj_002 #这个并非邮箱密码,而是授权码 set smtp-auth-password=pousheng123 set smtp-auth=login vi /usr/local/bin/send_report #!/bin/bash source /root/.bash_profile orig_master_host=`echo "$1" | awk -F = '{print $2}'` new_master_host=`echo "$2" | awk -F = '{print $2}'` new_slave_hosts=`echo "$3" | awk -F = '{print $2}'` subject=`echo "$4" | awk -F = '{print $2}'` body=`echo "$5" | awk -F = '{print $2}'` email="ywzj_001@163.com" tac /var/log/mha/app1/manager.log | sed -n 2p | grep 'successfully' > /dev/null if [ $? -eq 0 ] then messages=`echo -e "MHA $subject 主从切换成功n master:$orig_master_host --> $new_master_host n $body n 当前从库:$new_slave_hosts"` echo "$messages" | mail -s "Mysql 实例宕掉,MHA $subject 切换成功" $email > >/tmp/mailx.log 2>&1 else messages=`echo -e "MHA $subject 主从切换失败n master:$orig_master_host --> $new_master_host n $body" ` echo "$messages" | mail -s ""Mysql 实例宕掉,MHA $subject 切换失败"" $email >>/tmp/mailx.log 2>&1 fi #配置VIP更换脚本 vi /usr/local/bin/master_ip_online_change #预先选择的VIP地址 vip=`echo '192.168.157.197/24'` key=`echo '1'` command=`echo "$1" | awk -F = '{print $2}'` orig_master_host=`echo "$2" | awk -F = '{print $2}'` new_master_host=`echo "$7" | awk -F = '{print $2}'` orig_master_ssh_user=`echo "${12}" | awk -F = '{print $2}'` new_master_ssh_user=`echo "${13}" | awk -F = '{print $2}'` #修改网卡名称 stop_vip=`echo "ssh root@$orig_master_host /usr/sbin/ifconfig ens33:$key down"` start_vip=`echo "ssh root@$new_master_host /usr/sbin/ifconfig ens33:$key $vip"` if [ $command = 'stop' ] then echo -e "nnn****************************n" echo -e "Disabled thi VIP - $vip on old master: $orig_master_host n" $stop_vip if [ $? -eq 0 ] then echo "Disabled the VIP successfully" else echo "Disabled the VIP failed" fi echo -e "***************************nnn" fi if [ $command = 'start' -o $command = 'status' ] then echo -e "nnn*************************n" echo -e "Enabling the VIP - $vip on new master: $new_master_host n" $start_vip if [ $? -eq 0 ] then echo "Enabled the VIP successfully" else echo "Enabled the VIP failed" fi echo -e "***************************nnn" fi #赋予脚本权限 #*代表之前创建的三个脚本 chmod 555 /usr/local/bin/* chmod 555 /usr/local/bin/master_ip_failover chmod 555 /usr/local/bin/master_ip_online_change chmod 555 /usr/local/bin/send_report #测试MHA设置是否正确 masterha_check_repl --conf=/etc/masterha.cnf 。。。 MySQL Replication Health is OK. 最后 显示OK,才算正常,否则就要看报错信息,按照之前的操作配置,基本不会有错误。 #在主库,而不是Manager管理口,配置VIP到网口 /usr/sbin/ifconfig ens33:1 192.168.157.197/24 注意:如果是最小化安装,需yum ifconfig yum -y install net-tools #在Manager节点操作 #启动MHA nohup masterha_manager --conf=/etc/masterha.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 & #检查状态 [root@mha03 bin]# masterha_check_status --conf=/etc/masterha.cnf masterha (pid:15546) is running(0:PING_OK), master:192.168.157.128 #显示OK则正常 测试切换功能以及主库宕机上线: 1、在线切换 #MHA 在线切换是 MHA 除了自动监控切换换提供的另外一种方式,多用于诸如硬件升级,MySQL 数据库迁移等等。该方式提供快速切换和优雅的阻塞写入,无需关闭原有服务器,整个切换过程在 0.5-2s 的时间左右,大大减少了停机时间 注意:需要关闭mha监控才能运行 A、老master上的vip已经正确生效了 B、各个salve节点数据库的sql_IO和sql_sql进程都正常(即YES) show slave statusG; C、MHA脚本不能运行,若已处于监控状态,需要停掉它 masterha_stop --conf=/etc/masterha.cnf #执行切换 #需要填写新的master的IP masterha_master_switch --conf=/etc/masterha.cnf --master_state=alive --new_master_host=192.168.157.129 --orig_master_is_new_slave --running_updates_limit=10000 --interactive=0 masterha_master_switch --conf=/etc/masterha.cnf --master_state=alive --new_master_host=192.168.157.128 --orig_master_is_new_slave --running_updates_limit=10000 --interactive=0 #MHA 在线切换基本步骤: a、检测 MHA 配置置及确认当前 master b、决定新的 master c、阻塞写入到当前 master d、等待所有从服务器与现有 master 完成同步 e、在新 master 授予写权限,以及并行切换从库 f、重置原 master 为新 master 的 slave g、在线切换不会删除/etc/masterha.cnf 配置文件中原来老的 master 配置 注意:如果手动切换后,原来的配置如果想直接运行,需要在配置文件中将master的地址改成新的IP,原Master主机的IP写到slave中 2、自动切换 第一:要实现自动 Failover,必须先启动 MHA Manager,否则无法自动切换 A、杀掉主库 mysql 进程,模拟主库发生故障,进行自动 failover 操作。 B、看 MHA 切换日志,了解整个切换过程 tailf /var/log/mha/app1/manager.log 第二:从上面的输出可以看出整个 MHA 的切换过程,共包括以下的步骤: 1).配置文件检查阶段,这个阶段会检查整个集群配置文件配置 2).宕机的 master 处理,这个阶段包括虚拟 ip 摘除操作,主机关机操作(由于没有定义power_manager脚本,不会关机) 3).复制 dead maste 和最新 slave 相差的 relay log,并保存到 MHA Manger 具体的目录下 4).识别含有最新更新的 slave 5).应用从 master 保存的二进制日志事件(binlog events)(这点信息对于将故障master修复后加入集群很重要) 6).提升一个 slave 为新的 master 进行复制 7).使其他的 slave 连接新的 master 进行复制 第三:切换完成后,关注如下变化: 1、vip 自动从原来的 master 切换到新的 master,同时,manager 节点的监控进程自动退出。 2、在日志目录(/var/log/mha/app1)产生一个 app1.failover.complete 文件 3、/etc/mha/app1.cnf 配置文件中原来老的 master 配置被删除。 4、切换一次后,MHA监控程序会stop,需要重新修改配置文件后再次重启 #会发现此时192.168.157.129从库已经提升为主库,并且MHA Manager已停止运行。 重要:将主库重新恢复加入到队列的操作 1)、修改 manager 配置文件(只针对自动切换的,在线切换不会删除配置) #将如下内容添加到/etc/masterha.cnf中 [server1] hostname=192.168.157.128 candidate_master=1 port=3306 master_binlog_dir=/opt/mysql/log/ #由于之前主库宕机后,MHA会自动将配置文件内宕机的主库信息删除 #主库恢复如需重新加入,需要在配置文件新增原主库信息,并作为从库加入 2)、修复老的 master,然后设置为 slave 从自动切换时刻的 MHA 日志上可以发现类似如下信息: #意思是说,如果 Master 主机修复好了,可以在修复好后的 Master 上执行 CHANGE MASTER操作,作为新的 slave 库。 [root@mha03 app1]# cat manager.log|grep CHANGE [root@mha03 app1]# pwd /var/log/mha/app1 #GTID没有开启 Sat May 27 14:59:17 2017 - [info] All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.0.40.187', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000009', MASTER_LOG_POS=120, MASTER_USER='repl', MASTER_PASSWORD='xxx'; #GTID开启 Sat May 19 05:00:48 2018 - [info] All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.0.40.187', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx'; Thu Aug 15 15:31:18 2019 - [info] All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='192.168.157.129', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx'; Thu Aug 15 15:31:19 2019 - [info] Executed CHANGE MASTER. 在老的 master 执行如下命令:(具体执行哪条,根据上面输出来确定,区别是一个有日志的定位,一个是自动定位) #GTID没有开启,按照日志的log-file和log-pos填写 mysql> change master to master_host='10.0.40.187',master_user='repl',master_password='123456',master_log_file='mysql-bin.0000124',master_log_pos=120; #GTID开启,只能使用MASTER_AUTO_POSITION=1,否则报错 mysql> change master to master_host='10.0.40.187',master_user='repl',master_password='123456',MASTER_AUTO_POSITION=1; CHANGE MASTER TO MASTER_HOST='192.168.157.129', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123456'; mysql> CHANGE MASTER TO MASTER_HOST='192.168.157.129', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123456'; Query OK, 0 rows affected, 2 warnings (0.02 sec) mysql> start slave; Query OK, 0 rows affected (0.01 sec) mysql> show slave statusG; 郑州不孕不育医院:http://jbk.39.net/yiyuanzaixian/zztjyy/ #这样,数据就开始同步到老的 master 上了。此时老的 master 已经重新加入集群,变成 mha集群中的一个 slave 角色了。 (3)、在 manger 节点上重新启动监控进程 nohup masterha_manager --conf=/etc/masterha.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 & (编辑:大连站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
站长推荐