高可用方案
2台互为主备,互相复制。
注意:
keepalived + mysql
单独的2台机器,部署MySQL,配备单独的vip
keepalived配置妥当,注意keepalived绑定的网卡,在keepalived.conf 配置 interface
2台强制设置readonly给业务用户(因为root用户不受限制)
主备+互相复制配置过程
原单机操作
mysqldump -h127.0.0.1 -P3306 -uroot -p'密码' --single-transaction -E -R --triggers --all-databases --master-data=2 --add-drop-database --add-drop-table --verbose> 20221020-1.sql
在master和slave执行
1.停掉slb,防止执行过程中,有数据写入(如果没有使用keepalived,可以暂时把mysql端口修改为3307)
docker stop keepalived
2.删除MySQL容器
docker-compose down
3.删除(或备份到别处)data目录,新建MySQL的数据目录data,重建容器
docker-compose up -d
4.把sql复制到容器里面
docker cp 20221020-1.sql mysql_container:/.
5. 在master和slave,都同时执行导入初始化语句,此时2个MySQL还不通
source 20221020-1.sql;
6. 退出容器,重启mysql
docker restart mysql_server
7. 进入容器,检查slave账号是否存在,如果不存在分别创建slave账号 select user from mysql.user;
在master执行
1.挑选一台为master
show master status\G;
2.记下 master的 Executed_Gtid_Set
在slave执行
1.reset master;
2.stop slave;
3.reset slave all;
4.show slave status\G;
5.show master status\G;
6.change master to master_auto_position=0;
7.SET @@GLOBAL.GTID_PURGED='上一步的Executed_Gtid_Set的值'; (使用20221020-1.sql文件头部的GTID的值也可以)
8.CHANGE MASTER TO MASTER_HOST='ip', MASTER_PORT=3306, MASTER_USER='slave', MASTER_PASSWORD='密码', master_auto_position=1;
9.start slave;
10.show slave status\G;检查复制状态是否有2个yes
回到master执行
1.stop slave;
2.reset slave all;
3.show slave status\G;
4.change master to master_auto_position=0;
5.CHANGE MASTER TO MASTER_HOST='ip', MASTER_PORT=3306, MASTER_USER='slave', MASTER_PASSWORD='密码', master_auto_position=1;
6.start slave;
7.show slave status\G;检查复制状态是否有2个yes
master和slave都执行
1.show slave status\G;检查复制状态是否有2个yes
2.show variables like 'read_only';
检查2台机器的read_only 状态,如果没有需要设置其中一个为read_only(配合使用脚本实现)
监控MySQL的slave,设置read_only(高可用的一部分设置)
配置定时任务脚本check_mysql_read_only.sh
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
# 因为crontab最小间隔是1分钟,这里设置1分钟内执行11次
for((i=1;i<=11;i++));
do
echo $i >> /check_mysql_read_only.log
ip a| grep vip
if [ $? -eq 0 ]
then
# echo "-----`date "+%Y-%m-%d %H:%M:%S"` 当前节点有vip,不做处理-----" >> /check_mysql_read_only.log
# 如果是vip,那么就不停的设置为OFF
/usr/local/sbin/docker exec mysql_server mysql -uroot -p'密码' -e "set global read_only=0" >> /check_mysql_read_only.log
echo "-----`date "+%Y-%m-%d %H:%M:%S"` 当前节点有vip,设置read_only为OFF-----" >> /check_mysql_read_only.log
else
/usr/local/sbin/docker exec mysql_server mysql -uroot -p'密码' -e "set global read_only=1" >> /check_mysql_read_only.log
echo "-----`date "+%Y-%m-%d %H:%M:%S"` 当前节点没有vip,设置read_only为ON-----" >> /check_mysql_read_only.log
fi
sleep 5
done
# read_only 属性值,不会通过binlog主从同步
使用crontab执行
crontab -e 增加* * * * * bash /check_mysql_read_only.sh
清理设置read_only设置的日志
配置清理日志脚本 check_mysql_read_only_auto_clean_log.sh
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
file_size=`ls -la /check_mysql_read_only.log | awk '{print $5}'`
# 如果文件大于30M,那么删除
if [ $file_size -ge 31457280 ]
then
rm -rf /check_mysql_read_only.log
printf "\n-----`date "+%Y-%m-%d %H:%M:%S"` check_mysql_read_only.log size $file_size 大于30M 删除此文件\n\n" >> /check_mysql_read_only.log
else
printf "\n-----`date "+%Y-%m-%d %H:%M:%S"` check_mysql_read_only.log size $file_size 小于30M 不做处理\n\n" >> /check_mysql_read_only.log
fi
使用crontab执行
crontab 配置
* * * * * bash /check_mysql_read_only_auto_clean_log.sh
read_only设置无法生效问题(高可用的一部分设置)
read_only对于带有super权限的用户无效。所以不要使用带有super权限的用户。
1. 如myapp用户,root下执行下面语句,撤销super权限。
REVOKE Super ON *.* FROM 'myapp'@'%';
2. 执行 set global read_only=1(即ON)后,myapp就无法执行insert、update、delete了。
3. 执行 set global read_only=0(即OFF)后,myapp又恢复了读写权限。
测试
show variables like 'super_read_only'
show variables like 'read_only'
show slave status\G