[TOC]
MHA介绍
1 | 该软件由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署 |
环境准备
系统:centos7_1804
lab01: 10.0.0.11 master mha4mysql-node
lab02: 10.0.0.12 slave1 mha4mysql-node
lab03: 10.0.0.13 slave2 mha4mysql-node mha4mysql-manager
lab04: 10.0.0.14 haproxy [node2, node3] (备读)
VIP: 10.0.0.10 [node1, node2](主写)
配置步骤:
1. 配置相互ssh密钥登陆
2. 主从复制 master:[lab01] slave:[lab02, lab03]
3. 安装 mha node:[lab01, lab02, lab03] manager:[lab03]
4. 测试
配置ssh密钥登陆
生成密钥,安装自动交互工具
所有节点执行
[ -f ~/.ssh/id_dsa ] || { ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa;}
[ -f /usr/bin/expect ] || { yum install -y expect;}
发送公钥到远程主机
所有节点执行
(实际上只需要控制节点能无需密码登陆从节点即可)
# 远程主机root密码
rootpass=123.com
SSH_KEY(){
/usr/bin/expect <<EOF
set timeout 30
spawn ssh-copy-id -i /root/.ssh/id_dsa.pub root@$1
expect {
"(yes/no)?" { send "yes\r"; exp_continue }
"password:" { send "$rootpass\r" }
}
expect eof
EOF
}
for ip in 10.0.0.{11..13};do
SSH_KEY $ip
done
安装MySql
配置安装源
所有节点
yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm # 安装mysql软件安装源
yum repolist all | grep mysql # 查看所有 mysql 子存储库
yum install -y yum-utils # 安装 yum 配置工具管理 YUM 源
yum-config-manager --disable mysql80-community # 禁用 mysql80 子存储库
yum-config-manager --enable mysql57-community # 启用 mysql57 子存储库
yum repolist enabled | grep mysql # 查看已启用的 mysql 子存储库
安装 mysql-5.7 启动服务
所有节点
yum install -y mysql-community-server
systemctl start mysqld
配置主从复制
lab01 操作; 开启二进制日志,设置 server-id,启动服务,更改root密码及授权,创建同步用户及授权
# 开启二进制日志(注意 server-id 唯一)
cp /etc/my.cnf{,.bak}
cat <<EOF >>/etc/my.cnf
# binlog
server-id = 1
log-bin = mysql-bin
log-bin-index = master-bin.index
EOF
# 重启服务,跟随系统启动
systemctl restart mysqld
systemctl enable mysqld
systemctl status mysqld
# 更改root密码,开启root用户远程登陆授权(密码:Hc.1234456)
grep 'temporary password' /var/log/mysqld.log # 查看初始化密码
def_pass=$(grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}')
ChangePass="alter user 'root'@'localhost' identified by 'Hc.123456';"
mysql -uroot -p$def_pass -e "$ChangePass" --connect-expired-password
Author="grant all privileges on *.* to root@'%' identified by 'Hc.123456' with grant option;"
mysql -uroot -pHc.123456 -e "$Author"
# 创建同步账号,授权
mysql -uroot -pHc.123456
create user 'sync'@'10.0.0.%' identified by 'Hc.123456';
grant replication slave on *.* to 'sync'@'10.0.0.%' identified by 'Hc.123456';
flush privileges;
show master status;
exit
# mysql> show master status; # 记录下二进制日志文件名及偏移量
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 1390 | | | |
+------------------+----------+--------------+------------------+-------------------+
lab02 操作; 开启二进制日志,设置 server-id,启动服务,更改root密码及授权,创建同步用户及授权,配置连接lab01
# 开启二进制日志(注意 server-id 唯一)
cp /etc/my.cnf{,.bak}
cat <<EOF >>/etc/my.cnf
# binlog
server-id = 2
log-bin = mysql-bin
log-bin-index = master-bin.index
EOF
# 重启服务,跟随系统启动
systemctl restart mysqld
systemctl enable mysqld
systemctl status mysqld
# 更改root密码,开启root用户远程登陆授权(密码:Hc.1234456)
grep 'temporary password' /var/log/mysqld.log # 查看初始化密码
def_pass=$(grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}')
ChangePass="alter user 'root'@'localhost' identified by 'Hc.123456';"
mysql -uroot -p$def_pass -e "$ChangePass" --connect-expired-password
Author="grant all privileges on *.* to root@'%' identified by 'Hc.123456' with grant option;"
mysql -uroot -pHc.123456 -e "$Author"
# 创建同步账号,授权,配置连接lab01
mysql -uroot -pHc.123456
create user 'sync'@'10.0.0.%' identified by 'Hc.123456';
grant replication slave on *.* to 'sync'@'10.0.0.%' identified by 'Hc.123456';
flush privileges;
change master to master_host='10.0.0.11', # lab01数据库 IP或主机名(需解析通)
master_port=3306, # lab01数据库端口号
master_user='sync', # 同步账号
master_password='Hc.123456', # 同步账号的密码
master_log_file='mysql-bin.000001', # lab01数据库执行 show master status; 获取的二进制日志文件名
master_log_pos=1390; # lab01数据库执行 show master status; 获取的二进制日志偏移量
start slave; # 启动slave
show slave status\G; # 查看同步状态
exit
lab03 操作; 开启二进制日志,设置 server-id,启动服务,更改root密码及授权,创建同步用户及授权,配置连接lab01
# 开启二进制日志(注意 server-id 唯一)
cp /etc/my.cnf{,.bak}
cat <<EOF >>/etc/my.cnf
# binlog
server-id = 3
log-bin = mysql-bin
log-bin-index = master-bin.index
EOF
# 重启服务,跟随系统启动
systemctl restart mysqld
systemctl enable mysqld
systemctl status mysqld
# 更改root密码,开启root用户远程登陆授权(密码:Hc.1234456)
grep 'temporary password' /var/log/mysqld.log # 查看初始化密码
def_pass=$(grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}')
ChangePass="alter user 'root'@'localhost' identified by 'Hc.123456';"
mysql -uroot -p$def_pass -e "$ChangePass" --connect-expired-password
Author="grant all privileges on *.* to root@'%' identified by 'Hc.123456' with grant option;"
mysql -uroot -pHc.123456 -e "$Author"
# 创建同步账号,授权,配置连接lab01
mysql -uroot -pHc.123456
create user 'sync'@'10.0.0.%' identified by 'Hc.123456';
grant replication slave on *.* to 'sync'@'10.0.0.%' identified by 'Hc.123456';
flush privileges;
change master to master_host='10.0.0.11', # lab01数据库 IP或主机名(需解析通)
master_port=3306, # lab01数据库端口号
master_user='sync', # 同步账号
master_password='Hc.123456', # 同步账号的密码
master_log_file='mysql-bin.000001', # lab01数据库执行 show master status; 获取的二进制日志文件名
master_log_pos=1390; # lab01数据库执行 show master status; 获取的二进制日志偏移量
start slave; # 启动slave
show slave status\G; # 查看同步状态
exit
安装 MHA
所有节点安装
mha4mysql-node
# yum install -y https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.centos.noarch.rpm
curl http://117.50.70.211:88/attach_files/sql/12 -o mha4mysql-node-0.58-0.el7.centos.noarch.rpm
yum install -y mha4mysql-node-0.58-0.el7.centos.noarch.rpm
lab03安装
mha4mysql-manager
# yum install -y https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
curl http://117.50.70.211:88/attach_files/sql/12 -o mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
yum install -y mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
配置 MHA(lab03)
创建配置文件
# 创建日志路径及文件
mkdir /etc/mha
touch /etc/mha/manager.log
# 创建配置文件
cat <<EOF >/etc/mha/mha.cnf
[server default]
# mysql admin account and password
user=root
password=Hc.123456
# mha workdir and worklog
manager_workdir=/etc/mha
manager_log=/etc/mha/manager.log
# mysql A/B account and pw
repl_user=sync
repl_password=Hc.123456
# check_mha_node time
ping_interval=1
# ssh account
ssh_user=root
# mha change VIP
#report_script=/etc/mha/send_report
#master_ip_failover_script=/etc/mha/master_ip_failover
#master_ip_online_change_script=/etc/mha/master_ip_online_change
[server1]
hostname=10.0.0.11
ssh_port=22
master_binlog_dir=/var/lib/mysql
candidate_master=1
[server2]
hostname=10.0.0.12
ssh_port=22
master_binlog_dir=/var/lib/mysql
candidate_master=1
[server3]
hostname=10.0.0.13
ssh_port=22
master_binlog_dir=/var/lib/mysql
candidate_master=2
EOF
创建服务器启动脚本
cat <<EOF >/etc/mha/mha_start
#!/bin/bash
/usr/bin/nohup /usr/bin/masterha_manager --conf=/etc/mha/mha.cnf >/tmp/mha_manager.log 2>&1 &
EOF
chmod +x /etc/mha/mha_start
检测ssh密钥登陆配置
masterha_check_ssh --conf=/etc/mha/mha.cnf
检测数据库复制
masterha_check_repl --conf=/etc/mha/mha.cnf
测试
测试故障恢复;
1. lab03 启动 masterha_manager 服务
2. lab01 关闭 mysqld 服务
3. lab03 上验证当前 master
4. 恢复 lab01(slave)
5. 设置 lab01 为 master
6. lab03 启动 masterha_manager 服务
1.
lab03
启动masterha_manager
服务
/etc/mha/mha_start # 启动 masterha_manager 服务
ps aux | grep masterha
tail -f /tmp/mha_manager.log # 查看 masterha_manager 实时日志
2.
lab01
关闭mysql
服务
systemctl stop mysqld
3.
lab03
验证
mysql -uroot -pHc.123456 -e 'show slave status\G;' | grep Master_Host
4.
lab01
恢复为slave
systemctl start mysqld
ssh 10.0.0.13 'grep -i change /etc/mha/manager.log' # 查看管理节点上的恢复参数
mysql -uroot -pHc.123456
CHANGE MASTER TO MASTER_HOST='10.0.0.12',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000001', # 替换此处为 manager.log 对应参数
MASTER_LOG_POS=1390, # 替换此处为 manager.log 对应参数
MASTER_USER='sync',
MASTER_PASSWORD='Hc.123456'; # 替换此处为同步用户密码
start slave;
show slave status\G;
5.设置 lab01 为 master
# lab03 执行
rm -f /etc/mha/mha.failover.complete
/etc/mha/mha_start # 启动 masterha_manager 服务
ps aux | grep masterha
tail -f /tmp/mha_manager.log # 查看 masterha_manager 实时日志
# lab02关闭mysld服务(lab02执行)
systemctl stop mysqld
# lab03 验证(lab03执行)
mysql -uroot -pHc.123456 -e 'show slave status\G;' | grep Master_Host
# 恢复lab02(lab02执行)
systemctl start mysqld
ssh 10.0.0.13 'grep -i change /etc/mha/manager.log' # 查看管理节点上的恢复参数
mysql -uroot -pHc.123456
CHANGE MASTER TO MASTER_HOST='10.0.0.11',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000002', # 替换此处为 manager.log 对应参数
MASTER_LOG_POS=154, # 替换此处为 manager.log 对应参数
MASTER_USER='sync',
MASTER_PASSWORD='Hc.123456'; # 替换此处为同步用户密码
start slave;
show slave status\G;
6.
lab03
启动masterha_manager
服务
rm -f /etc/mha/mha.failover.complete
/etc/mha/mha_start # 启动 masterha_manager 服务
ps aux | grep masterha
tail -f /tmp/mha_manager.log # 查看 masterha_manager 实时日志
创建VIP切换脚本
lab03 当主从切换时触发脚本执行删除/添加 VIP
1 | cat <<'EOF' >/etc/mha/master_ip_failover |
开启切换主从时触发脚本VIP
sed -i 's/#master_ip_failover_script/master_ip_failover_script/' /etc/mha/mha.cnf
节点快速恢复
systemctl start mysqld
mysql -uroot -pHc.123456 -e 'stop slave;'
mysql -uroot -pHc.123456 -e 'reset slave;'
echo $(ssh 10.0.0.13 'grep -i change /etc/mha/manager.log' | awk -F 'be: ' '{print $2}' | tail -n 2) >/tmp/bin.log
sed -i 's/xxx/Hc.123456/' /tmp/bin.log
sql=$(cat /tmp/bin.log)
mysql -uroot -pHc.123456 -e "$sql"
mysql -uroot -pHc.123456 -e 'start slave;'
mysql -uroot -pHc.123456 -e 'show slave status\G;'
slave集群
lab04安装 haproxy ; 代理 lab02 lab03 数据库读请求
yum -y install haproxy
配置haproxy
1 | cp /etc/haproxy/haproxy.cfg{,.bak} |
配置日志
1 | cat <<'!' >/etc/rsyslog.d/haproxy.conf |
设置启动方式
# 允许没VIP时启动(如果没有配置此项且应用会导致 haproxy 服务无法启动)
echo "net.ipv4.ip_nonlocal_bind = 1" >>/etc/sysctl.conf
sysctl -p
服务管理
systemctl start haproxy # 启动服务
systemctl enable haproxy # 随系统启动
systemctl status haproxy # 运行状态
配置手动切换主从
创建 VIP 切换脚本(使用 perl 脚本 1)
1 | cat <<'EOF' >/etc/mha/master_ip_online_change |
创建 VIP 切换脚本(使用 shell 脚本 2)
1 | cat <<EOF >/etc/mha/master_ip_online_change.sh |
开启手动切换VIP功能
shell
,perl
方式二选一(注意:手动切换时不要开启masterha_manager服务)
# shell 方式
shell='/etc/mha/master_ip_online_change.sh'
sed -i '23d' /etc/mha/mha.cnf
sed -i "22a master_ip_online_change_script=$shell" /etc/mha/mha.cnf
# perl 方式
perl='/etc/mha/master_ip_online_change'
sed -i '23d' /etc/mha/mha.cnf
sed -i "22a master_ip_online_change_script=$perl" /etc/mha/mha.cnf
切换10.0.0.11为主
masterha_master_switch --conf=/etc/mha/mha.cnf -master_state=alive --new_master_host=10.0.0.11 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000
触发切换时发送邮件
安装
mailx
yum install -y mailx
配置
mail.rc
cat <<EOF >/etc/mail.rc
# mail $(date '+%F %T')
set from=gaojing_2018@163.com smtp=smtp.163.com
set smtp-auth-user=gaojing_2018@163.com
set smtp-auth-password=password
set smtp-auth=login
EOF
systemctl restart postfix
测试配置
echo "服务器已恢复正常,恢复时间:$(date '+%F %T')"| mailx -s "MHA服务监控" 544025211@qq.com
触发发送邮件脚本
1 | cat <<'EOF' >/etc/mha/send_report |
开启切换触发邮件
sed -i 's/#report_script/report_script/' /etc/mha/mha.cnf
测试
管理节点(确认集群运行正常 主从从)
rm -f mha.failover.complete
masterha_manager --conf=/etc/mha/mha.cnf &
ps aux | grep mha
mysql -uroot -pHc.123456 -e 'show slave status\G;' # 查看主节点是谁
关闭主节点的mysqld服务
systemctl stop mysqld
状态
此时 master 已经切换到其他节点 VIP 已经转移 指定邮箱也收到邮件包含集群信息
说明
数据库写入使用VIP
数据库读使用 haproxy 代理的IP 或者使用VIP(haproxy可以不安装)