Mysql+MHA高可用架构
MHA是什么
MHA是mysql高可用解决方案之一。
1.当mysql主库发生故障,MHA提升从库为主库,确保主库高可用。
2.MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。
MHA组成
1.MHA Manager(管理节点)
建议将MHA Manager单独部署在一台独立的机器上管理多个master-slave集群。
2.MHA Node(数据节点)
MHA Node运行在每台MySQL服务器上,是MHA Manager的员工,接收Manager的命令并执行
MHA各工具包作用
manager工具包:
masterha_check_ssh # 检查MHA的SSH-key配置状况
masterha_check_repl # 检查MySQL主从复制情况
masterha_manger # 启动MHA
masterha_check_status # 检测当前MHA运行状态
masterha_master_monitor # 检测master是否宕机
masterha_master_switch # 控制故障转移(自动或者手动)
masterha_conf_host # 添加或删除配置的server信息
masterha_secondary_check # 从远程服务器建立TCP连接
masterha_stop # 停止MHA
node工具包:(通常由MHA Manager的脚本触发,无需人为操作)
save_binary_logs # 保存和复制宕机的master的binlog
apply_diff_relay_logs # 识别差异的relay log事件并将其差异的事件应用于其他的slave
filter_mysqlbinlog # 去除不必要的ROLLBACK事件(MHA已不再使用这个工具)
purge_relay_logs # 清除中继日志(不会阻塞SQL线程)
部署MHA
1台Manager ip:192.168.232.100
1台master ip:192.168.232.101
2台slave, ip:192.168.232.102/103
虽然我们上面3台mysql,每台都有ip地址,但我们应用程序不直接访问这些IP,我们暴露给应用程序的是一个虚拟IP,简称VIP,应用程序通过VIP访问master。
起初,这个VIP(192.168.232.99)是位于我们的master(192.168.168.232.101),如果后面主机宕机,VIP漂移到slave1(192.168.232.102)或者slave2(192.168.232.103)的服务器上。那么应用程序就会写入其中的slave。
建立秘钥互信
每个节点都执行
[root@100 ~]# cd ~
[root@100 ~]# ssh-keygen -t rsa #看到提示不用管,一路回车就是
[root@100 ~]# cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
[root@100 ~]# chmod 600 ~/.ssh/authorized_keys
只要在一个节点执行即可。这里在 192.168.232.100上执行
[root@100 ~]# ssh 192.168.232.101 cat ~/.ssh/id_rsa.pub >>~/.ssh/authorized_keys
[root@100 ~]# ssh 192.168.232.102 cat ~/.ssh/id_rsa.pub >>~/.ssh/authorized_keys
[root@100 ~]# ssh 192.168.232.103 cat ~/.ssh/id_rsa.pub >>~/.ssh/authorized_keys
分发整合后的文件到其它节点
[root@100 ~]# scp ~/.ssh/authorized_keys 192.168.232.101:~/.ssh/
[root@100 ~]# scp ~/.ssh/authorized_keys 192.168.232.102:~/.ssh/
[root@100 ~]# scp ~/.ssh/authorized_keys 192.168.232.103:~/.ssh/
安装基础依赖包
在所有机器上执行:
yum install -y perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker perl-CPAN perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-ParallelForkManager perl-Time-HiRes
安装MHA组件
安装MHA Node组件
登陆100这台机器
[root@101 ~]# cd /usr/local/src/mha
安装包上传至目录
[root@100 mha]# ll | grep mha
-rw-r--r-- 1 root root 119801 Sep 15 16:11 mha4mysql-manager-0.58.tar.gz
-rw-r--r-- 1 root root 56220 Sep 15 16:11 mha4mysql-node-0.58.tar.gz
将mha4mysql-node-0.58.tar.gz分发到其它节点
scp mha4mysql-node-0.58.tar.gz root@192.168.232.101:/usr/local/src/mha/
scp mha4mysql-node-0.58.tar.gz root@192.168.232.102:/usr/local/src/mha/
scp mha4mysql-node-0.58.tar.gz root@192.168.232.103:/usr/local/src/mha/
在所有机器上执行解压安装
[root@node01 soft]# tar xf mha4mysql-node-0.58.tar.gz
[root@node01 soft]# cd mha4mysql-node-0.58
[root@node01 mha4mysql-node-0.58]# perl Makefile.PL
[root@node01 mha4mysql-node-0.58]# make && make install
Node安装完成后会得到四个工具,位于/usr/local/bin/下面
apply_diff_relay_logs filter_mysqlbinlog purge_relay_logs save_binary_logs
安装MHA Manager组件
只在100上安装mha4mysql-manager-0.58.tar.gz
查看 Manager 工具 ll /usr/local/bin/ | grep master
mysql安装命令(在3台mysql上都要执行):
[root@101 ~]# cd /usl/local/src/mha
[root@101 mha]# useradd -s /sbin/nologin -M mysql
[root@101 mha]# tar -zxxf mysql-5.7.18-linux-glibc2.5-x86_64.tar.gz
[root@101 mha]# mv mysql-5.7.18-linux-glibc2.5-x86_64 mysql-5.7
[root@101 mha]# ln -s /usr/local/src/mha/mysql-5.7 /usr/local/mysql-5.7
[root@101 mha]# ln -s /usr/local/src/mha/mysql-5.7 /usr/local/mysql
[root@101 mha]# echo 'export PATH=$PATH:/usr/local/mysql-5.7/bin' >> /etc/profile
[root@node01 mha]# source /etc/profile
[root@node01 mha]# mysql -V
mysql Ver 14.14 Distrib 5.7.18, for linux-glibc2.5 (x86_64) using EditLine wrapper
[root@101 mha]# cd /usr/local/mysql-5.7
[root@node01 mysql-5.7]# cp support-files/mysql.server /etc/init.d/mysqld
[root@node01 mysql-5.7]# sed -i 's@/etc/my.cnf@/usr/local/mysql-5.7/my.cnf@g' /etc/init.d/mysqld
[root@node01 mysql-5.7]# sed -i 's@/usr/local/mysql/data@/opt/mysql_data@g' /etc/init.d/mysqld
[root@node01 mysql-5.7]# chkconfig mysqld on
[root@node01 mysql-5.7]# mkdir -p /opt/mysql_data
[root@node01 mysql-5.7]# chown -R mysql.mysql /usr/local/src/mha/mysql-5.7
[root@node01 mysql-5.7]# chown -R mysql.mysql /opt/mysql_data
[root@node01 mysql-5.7]# ln -s /usr/local/src/mha/mysql-5.7/bin/mysqlbinlog /usr/local/bin/mysqlbinlog
[root@node01 mysql-5.7]# ln -s /usr/local/src/mha/mysql-5.7/bin/mysql /usr/local/bin/mysql
配置一主二从
mysql配置 vim /etc/my.cnf:
server-id=101
log-bin=master-bin
relay-log-index=slave-relay-bin.index
relay-log=slave-relay-bin
binlog_format = MIXED
sync_binlog = 1
expire_logs_days =7#二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
log_slave_updates = 1
binlog-do-db = test
binlog-ignore-db = mysql,performance_schema,sys,information_schema
replicate-do-db=test
replicate-ignore-db=mysql,performance_schema,sys,information_schema
注意:node server-id的值不能重复,否则主从会建立失败
初始化 MySQL
在所有node上执行:
[root@101 mysql-5.7]# mysqld --initialize --user=mysql --basedir=/usr/local/mysql-5.7 --datadir=/opt/mysql_data
执行完初始化操作后,会给予root的默认密码,可以在命令行操作页面上看到;
这里还有重置密码和容许外网登录的步骤,自己去解决,此处略过。
所有mysql增加主从用户
疑问:为什么是所有mysql呢?因为主从可能会切换。
mysql> grant replication slave on *.* to 'repl'@'%' identified by '123456';
mysql> flush privileges;
在101上MySQL执行
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.0000020| 234 | | | |
+------------------+----------+--------------+------------------+-------------------+
node02、node03 都执行下列语句
mysql> change master to master_host='192.168.232.101',master_user='repl',master_password='123456',master_log_file='mysql-bin.0000020',master_log_pos=234;
注意:上面的master_log_file和master_log_pos这2个参数, 是和master中的参数要一致的。
mysql> show slave status\G; #查看slave IO和slave sql是否都正常
如果出现下面这个,说明搭建基本OK:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
MHA构建
MHA Manager 配置,在192.168.232.100上:
# 创建MHA配置文件目录
[root@100 ~]# mkdir /etc/mha
# 创建MHA脚本目录
[root@100 ~]# mkdir /etc/mha/scripts
# 创建MHA日志目录
[root@100 ~]# mkdir /var/log/mha/
# 创建日志目录
[root@100 ~]# mkdir /var/log/mha/app1 -p
# 创建日志文件
[root@100 ~]# touch /var/log/mha/app1/manager.log
配置文件1:
vim /etc/mha/app1.cnf
[server default]
manager_workdir=/var/log/masterha/app1
manager_log=/var/log/masterha/app1/manager.log
[server1]
hostname=192.168.232.101
port=3306
[server2]
hostname=192.168.232.102
port=3306
candidate_master=1 #备选master,是否能提升为master
[server3]
hostname=192.168.232.103
port=3306
配置文件2:
vim /etc/masterha_default.cnf
[server default]
user=root #注释请去掉,避免报错
password=123456
repl_user=repl
repl_password=123456
ssh_user=root
ping_interval=1
master_binlog_dir=/opt/mysql_data
manager_workdir=/var/log/mha/app1
manager_log=/var/log/mha/manager.log
master_ip_failover_script="/etc/mha/scripts/master_ip_failover.sh"
master_ip_online_change_script="/etc/mha/scripts/master_ip_online_change"
report_script="/etc/mha/scripts/send_report"
remote_workdir=/tmp
secondary_check_script= /usr/local/bin/masterha_secondary_check -s 192.168.232.101 -s 192.168.232.102 -s 192.168.232.103
shutdown_script=""
MHA主要配置文件说明
manager_workdir=/var/log/masterha/app1:设置manager的工作目录
manager_log=/var/log/masterha/app1/manager.log:设置manager的日志文件
master_binlog_dir=/opt/mysql_data:设置master 保存binlog的位置,以便MHA可以找到master的日志
master_ip_failover_script="/etc/mha/scripts/master_ip_failover.sh":设置自动failover时候的切换脚本
master_ip_online_change_script="/etc/mha/scripts/master_ip_online_change":设置手动切换时候的切换脚本
user=root:设置监控mysql的用户
password=dayi123:设置监控mysql的用户,需要授权能够在manager节点远程登录
ping_interval=1:设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行railover
remote_workdir=/tmp:设置远端mysql在发生切换时binlog的保存位置
repl_user=repl :设置mysql中用于复制的用户密码
repl_password=replication:设置mysql中用于复制的用户
report_script=/usr/local/send_report:设置发生切换后发送的报警的脚本
shutdown_script="":设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机防止发生脑裂,这里没有使用)
ssh_user=root //设置ssh的登录用户名
candidate_master=1:在节点下设置,设置当前节点为候选的master
slave check_repl_delay=0 :在节点配置下设置,默认情况下如果一个slave落后master 100M的relay logs的话,MHA将不会选择该slave作为一个新的master;这个选项对于对于设置了candidate_master=1的主机非常有用
自动VIP管理配置
[root@100 ~]# vim /etc/mha/scripts/master_ip_failover.sh
master_ip_failover.txt
给刚刚配置的三个脚本增加执行权限
[root@100 ~]# chmod +x /etc/mha/scripts/master_ip_failover.sh
验证MHA相关操作
通过 masterha_check_ssh 命令验证ssh 信任登录是否成功
[root@100 ~]# masterha_check_ssh --conf=/etc/mha/app1.cnf
看到All SSH connection tests passed successfully.可见验证通过
通过 masterha_check_repl 命令验证 mysql 主从复制是否成功
[root@100 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf
最后出现以下提示,则表示通过
MySQL Replication Health is OK.
启动 MHA
初次使用的时候,需要先在master 192.168.232.101上添加vip,以后就不需要了。
[root@101 ~]ifconfig ens33:0 192.168.232.99 netmask 255.255.255.0 up
启动manager, 这一步在manager 192.168.232.100上操作:
[root@100 ~]nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &
检查 MHA 状态
[root@100 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
MHA 的日志保存在/var/log/masterha/app1/manager.log 下
[root@100 ~]# tail -f /var/log/mha/app1/manager.log
Thu Sep 17 10:49:17 2020 - [info] Reading default configuration from /etc/masterha_default.cnf..
Thu Sep 17 10:49:17 2020 - [info] Reading application default configuration from /etc/mha/app1.cnf..
Thu Sep 17 10:49:17 2020 - [info] Reading server configuration from /etc/mha/app1.cnf..
关闭 MHA
[root@100 ~]# masterha_stop --conf=/etc/mha/app1.cnf
MHA宕机测试
手动停止101 的 MySQL master,然后查看其它节点情况。
在192.168.232.102上查看VIP
[root@102 ~]# ifconfig | grep 232
inet 192.168.232.102 netmask 255.255.255.0 broadcast 192.168.232.255
inet 192.168.232.99 netmask 255.255.255.0 broadcast 192.168.232.255
发现192.168.232.99已经从192.168.232.101漂移到192.168.232.102上面了。
在192.168.232.103上查看复制状态:
[root@103 ~]# mysql -uroot -p123456 -e "show slave status\G" | egrep 'Master_Host'
可以看到Master_Host:192.168.232.102,因为101宕机了,所以mha将102提升为master,然后将其他slave的
复制源从原先的101转而指向102。
MHA总结
MHA 的切换过程,共包括以下的步骤:
- 配置文件检查阶段,这个阶段会检查整个集群配置文件配置
- 宕机的 master 处理,这个阶段包括虚拟 ip 摘除操作,主机关机操作(由于没有定义power_manager脚本,不会关机)
- 复制 dead master 和最新 slave 相差的 relay log,并保存到 MHA Manger 具体的目录下
- 识别含有最新更新的 slave
- 应用从 master 保存的二进制日志事件(binlog events)(这点信息对于将故障master修复后加入集群很重要)
- 提升一个 slave 为新的 master 进行复制
- 使其他的 slave 连接新的 master 进行复制