mysql高可用MHA
MHA(Master High Availability)目前在 MySQL 高可用方面是一个相对成熟的解决方案,它由日本 DeNA 公司的 youshimaton(现就职于 Facebook 公司)开发,是一套优秀的作为 MySQL 高可用性环境下故障切换和主从提升的高可用软件。
在 MySQL 故障切换过程中,MHA 能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA 能在最大程度上保证数据的一致性,以达到真正意义上的高可用。
该软件由两部分组成:MHA Manager(管理节点)和 MHA Node(数据节点)。MHA Manager 可以单独部署在一台独立的机器上管理多个 master-slave 集群,也可以部署在一台 slave 节点上。MHA Node 运行在每台 MySQL 服务器上,MHA Manager 会定时探测集群中的 master 节点,当 master 出现故障时,它可以自动将最新数据的 slave 提升为新的 master,然后将所有其他的 slave 重新指向新的 master。整个故障转移过程对应用程序完全透明。
在 MHA 自动故障切换过程中,MHA 试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。例如,如果主服务器硬件故障或无法通过ssh访问,MHA 没法保存二进制日志,只进行故障转移而丢失了最新的数据。使用 MySQL 5.5 的半同步复制,可以大大降低数据丢失的风险。MHA 可以与半同步复制结合起来。如果只有一个 slave 已经收到了最新的二进制日志,MHA 可以将最新的二进制日志应用于其他所有的 slave 服务器上,因此可以保证所有节点的数据一致性。
目前 MHA 主要支持一主多从的架构,要搭建 MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当 master,一台充当备用 master,另外一台充当从库,因为至少需要三台服务器,出于机器成本的考虑,淘宝也在该基础上进行了改造,目前淘宝TMHA已经支持一主一从。
# 实践
集群说明
IP | 角色 | 安装包 |
---|---|---|
192.168.14.144 | master | mha4mysql-node/keepalived |
192.168.14.145 | slave | mha4mysql-node/keepalived |
192.168.14.146 | slave/manager | mha4mysql-manager/perl-DBD-MySQL/mha4mysql-node |
主从检查
检查my.cnf 配置文件,*server-id* 三个实例的id不能一样
检查主从是否正常
数据库数据目录下的 auto.cnf 配置文件里面的uuid不能一样
2
3
# 使用keepalived配置VIP
keepalived起初是为LVS设计的,由于keepalived可以实现对集群节点的状态检测,他根据TCP/IP参考模型的第三次,四层,交换机制检测每个服务节点的状态,对网络比较敏感,可能出现脑裂,在网络延迟很大的时候,slave 会抢占VIP,导致两台机器都有VIP,在网络延迟比较大的时候需要注意
# 安装keepalived与配置
在144 和 145 安装keepalived ,虚拟VIP:192.168.14.150,
nopreempt 防止主库宕机,keepalived 起来的时候不会因为权重问题,虚拟VIP飘逸到主服务器,非抢占式
yum安装默认版本1.3.5:yum install keepalived -y
- 修改配置keepalived.conf
cat /etc/keepalived/keepalived.conf
global_defs {
router_id lb01
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 50
priority 100
advert_int 1
nopreempt #非抢占式
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.14.150
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
145同样的配置,只需要修改 router_id 为不一致就行
先启动主库keepalived,让虚拟VIP生成在主库服务器
systemctl start keepalived
systemctl enable keepalived
systemctl status keepalived
ip a #检查eth0 是否增加虚拟VIP
2
3
4
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:23:33:09 brd ff:ff:ff:ff:ff:ff
inet 192.168.14.144/24 brd 192.168.14.255 scope global dynamic eth0
valid_lft 1359sec preferred_lft 1359sec
inet 192.168.14.150/32 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe23:3309/64 scope link
valid_lft forever preferred_lft forever
2
3
4
5
6
7
8
通过VIP连接数据库插入数据,检查(连接用户权限%):mysql -uroot -p -h 192.168.14.150
建议是安装包,三个都安装,技多不压身
# 安装mha 包
#yum install perl-DBD-MySQL perl-ExtUtils-MakeMaker -y #wget http://www.mysql.gr.jp/frame/modules/bwiki/index.php?plugin=attach&pcmd=open&file=mha4mysql-node-0.56-0.el6.noarch.rpm&refer=matsunobu #wget http://www.mysql.gr.jp/frame/modules/bwiki/index.php?plugin=attach&pcmd=open&file=mha4mysql-manager-0.56-0.el6.noarch.rpm&refer=matsunobu
mha4mysql-manager-0.56-0.el6.noarch.rpm #管理节点包,查看包文件: rpm -ql mha4mysql-manager.noarch
mha4mysql-node-0.56-0.el6.noarch.rpm
perl-DBD-MySQL-4.023-6.el7.x86_64.rpm
# 三台服务器做ssh 密钥对
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa >/dev/null 2>&1
ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.14.14(4,5,6)(包括本机)
# 在Master 主库创建监听monitor用户
grant all privileges on *.* to 'monitor'@'192.168.14.%' identified by 'monitor123';
# 设置relay log清除,slave上配置
mysql -uroot -p -h 192.168.14.145 -e "set global relay_log_purge=0;"
mysql -uroot -p -h 192.168.14.146 -e "set global relay_log_purge=0;"
MHA在发生切换过程中,从库在恢复的过程中,依赖于relay log的相关信息,所以我们这里要将relay log的自动清楚设置为OFF,采用手动清楚relay log的方式。
在默认情况下,从服务器上的中继日志会在SQL线程执行完后被自动删除。但是在MHA环境中,这些中继日志在恢复其它从服务器时可能会被用到,因此需要禁用中继日志的自动清除。改为定期手动清除SQL线程应用完的中继日志。
设置定期清理relay脚本:MHA节点中包含了purge_relay_logs脚本,它可以为relay log创建硬链接,执行set global relay_log_purge=1,等待几秒钟以便SQL线程切换到新的中继日志,再执行set global relay_log_purge=0。
查看命令:which purge_relay_logs
注意:最好是每台slave服务器在不同时间点执行该计划任务。
添加定时任务:0 4 * * * /usr/bin/purge_relay_logs --user=monitor --password=monitor123 -disable_relay_log_purge --workdir=/tmp/ > /tmp/purge_relay_logs.log 2>&1 &
# 创建mha配置
mkdir -p /etc/mha/{logs,bin}
cat >/etc/mha/app1.cnf<<OPO
[server default]
manager_log=/etc/mha/logs/manager.log
manager_workdir=/etc/mha/logs
master_binlog_dir=/opt/mysql/logs
master_ip_failover_script=/etc/mha/bin/master_ip_failover
master_ip_online_change_script=/etc/mha/bin/master_ip_online_change
secondary_check_script=/usr/bin/masterha_secondary_check -s 192.168.14.145 -s 192.168.14.146 --user=root --master_host=192.168.14.144 --master_ip=192.168.14.144 --master_port=3306
remote_workdir=/tmp/mysqlbinlog
ping_interval=2
repl_password=yfk123
repl_user=rep
ssh_user=root
user=monitor
password=monitor123
[server1]
hostname=192.168.14.144
port=3306
[server2]
candidate_master=1
check_repl_delay=0
hostname=192.168.14.145
port=3306
[server3]
hostname=192.168.14.146
port=3306
OPO
curl -o /etc/mha/bin/master_ip_failover http://download.yfklife.cn/blog/dba/mysql/mha/master_ip_failover
curl -o /etc/mha/bin/master_ip_online_change http://download.yfklife.cn/blog/dba/mysql/mha/master_ip_online_change
chmod +x /etc/mha/bin/*
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
修改 /etc/mha/bin/master_ip_failover,和/etc/mha/bin/master_ip_online_change 脚本配置文件的VIP,第34行
参数说明
参数 | 说明 |
---|---|
manager_log=/etc/mha/logs/manager.log | 设置manager的日志 |
manager_workdir=/etc/mha/logs | 设置manager的工作目录 |
master_binlog_dir=/opt/mysql/logs | 设置master默认保存binlog的位置,以便MHA可以找到master的日志 |
master_ip_failover_script= /etc/mha/bin/master_ip_failover | 设置自动failover时候的切换脚本 |
master_ip_online_change_script= /etc/mha/bin/master_ip_online_change | 设置手动切换时候的切换脚本 |
secondary_check_script=/usr/bin/masterha_secondary_check -s 192.168.14.145 -s 192.168.14.146 --user=root --master_host=192.168.14.144 --master_ip=192.168.14.144 --master_port=3306 | 一旦MHA到master的监控之间出现问题,MHA Manager将会判断其它两个slave是否能建立到master_ip 3306端口的连接 |
shutdown_script="" | 设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机防止发生脑裂) |
report_script | 设置发生切换后发送的报警的脚本 |
user=monitor | 设置监控用户 |
password=monitor123 | 设置监控用户的密码 |
ping_interval=1 | 设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候进行自动failover |
remote_workdir=/tmp/mysqlbinlog | 设置远端mysql在发生切换时binlog的保存位置 |
repl_user=rep | 设置复制环境中的复制用户名 |
repl_password=yfk123 | 设置复制用户的密码 |
ssh_user=root | 设置ssh的登录用户名 |
candidate_master
如果设置了多台机器的caddidate_master = 1 , 优先策略依赖于块名字([server_xxx]). [server_1] 优衔权高于[server_2].
这个参数的作用是当设定candidate_master = 1时,这个服务器有较高的优先级提升为新的master(还要具备:开启binlog,复制没有延迟)。 所以当设置了candidate_master = 1的机器在master故障时必然成为新的master. 但这是很实用的设置优先级的一个参数。
check_repl_delay
这个选项是有用的,当你设置candidate_master=1,在一个特定的主机和你想确保主机可以新主。
check_repl_delay // 默认情况下,如果一个slave落后master超过100MB的中继日志(需要申请超过100mb的中继日志),MHA将不选择作为一个新的机器为master,因为这需要太长时间来恢复,通过设置 check_repl_delay=0,MHA忽略复制延迟当选一个新master。
# 检查免密状态
masterha_check_ssh --conf=/etc/mha/app1.cnf
睁大眼睛看看有没有error,可以通过执行echo $?
查看执行返回结果
# 检测主从复制状态
masterha_check_repl --conf=/etc/mha/app1.cnf
睁大眼睛看看有没有error,可以通过执行echo $?
查看执行返回结果
因为我之前部署服务的时候是通过添加path做的变量,而在这里需要通过做软链接才能解决
ln -s /opt/mysql/var/bin/* /usr/local/bin/
在配置文件的时候/etc/my.cnf里面添加skip_name_resolve,否则会报错
UUID报错目录检查
删除,/opt/mysql/data/auto.cnf 重启从库
也可以试试修改后面的ID(未尝试):server-uuid=e00d6721-fc26-11e8-92f6-000c293a3766
# 检查MHA Manager的状态
masterha_check_status --conf=/etc/mha/app1.cnf
- 如果正常,会显示“PING_OK”,否则会显示“NOT_RUNNING”,代表MHA监控还没有开启。
# 开启MHA_Manager监控,重复执行会重启进程
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/mha/logs/manager.log 2>&1 &
[root@basic mha]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/mha/logs/manager.log 2>&1 &
[1] 23488
[root@basic mha]#
[root@basic mha]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 monitoring program is now on initialization phase(10:INITIALIZING_MONITOR). Wait for a while and try checking again.
[root@basic mha]#
[root@basic mha]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:23488) is running(0:PING_OK), master:192.168.14.144
[root@basic mha]#
2
3
4
5
6
7
8
9
# 停止MHA_Manager监控命令
masterha_stop --conf=/etc/mha/app1.cnf
# 测试停止主库
当停止主库的时候,Manager 监控监测,重试3次之后,没有重连上,就认为主库宕机
这时,由于app1.cnf server2标签配置了 candidate_master=1 和check_repl_delay=0,就算server 3 机器的数据比server2 数据新,它也会把server2 提升为主库,然后把延迟数据更新,自动去除掉server1 标签
当我们把停掉的机器起来之后,想要再次加入到集群,就需要重新配置主从
查看当前position 位置点 复制图里命令更改密码
grep -i 'change master to' /etc/mha/logs/manager.log
# 添加到集群中
登录刚刚起来的数据库,重新指向CHANGE MASTER TO
CHANGE MASTER TO MASTER_HOST='192.168.14.145', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=548, MASTER_USER='rep', MASTER_PASSWORD='yfk123';
start slave;
show slave status\G
2
3
会发现,现在的主库信息是server2标签,修改app1.cnf 把去掉的server1 标签信息补上去,再次执行监控启动命令,检查状态,集群修复完成
# 个人存储下载地址。。。
mha4mysql-manager-0.56-0.el6.noarch.rpm
mha4mysql-node-0.56-0.el6.noarch.rpm
perl-DBD-MySQL-4.023-6.el7.x86_64.rpm
keepalived-1.3.5.zip
2
3
4
5