由于公司服务器全部是单节点,最近数据库主机压力过大,不得不手工执行主从库切换操作。
这种方式的问题是全程需要人工干预,宕机时间长,严重影响线上业务。于是开始调研MySQL 高可用解决方案,主库出现问题时快速自动切换到从库。
MySQL的高可用方案有很多HAPROXY + Keepalived, LVS + Keepalived ,MHA、这些方案各有优劣,但都比较复杂,安装配置有一定难度,对线上库实施动静太大。就我们的具体情况而言,并不需要这么复杂的环境,实施简单、对现有架构影响最小、能迅速解决问题的方案才是最适合的。
比如我们现在只是配置了MySQL 双主,加上如Keepalived这样的高可用软件,就能实现我们的需求。
RPM:
关闭防火墙,关闭selinux,配置阿里yum源。
1,下载rpm包
wget http://mirrors.ustc.edu.cn/mysql-ftp/Downloads/MySQL-8.0/mysql-community-client-8.0.23-1.el7.x86_64.rpm
wget http://mirrors.ustc.edu.cn/mysql-ftp/Downloads/MySQL-8.0/mysql-community-server-8.0.23-1.el7.x86_64.rpm
wget http://mirrors.ustc.edu.cn/mysql-ftp/Downloads/MySQL-8.0/mysql-community-common-8.0.23-1.el7.x86_64.rpm
wget http://mirrors.ustc.edu.cn/mysql-ftp/Downloads/MySQL-8.0/mysql-community-libs-8.0.23-1.el7.x86_64.rpm
2,安装三个相关软件
yum install -y net-tools.x86_64 libaio.x86_64 perl.x86_64
3,安装MySQL服务器
yum install -y mysql-community*
yum remove -y mariadb-libs.x86_64(出现错误解决办法)
4,启动MySQL服务器并设置开机启动
systemctl start mysqld systemctl enable mysqld
5,查询并修改MySQL密码
grep 'password' /var/log/mysqld.log mysqladmin -uroot -p'老密码' password '新密码
两台电脑都安装一边
主:
1,修改配置文件,开启二进制日志
vim /etc/my.cnf
log_bin server-id=1 gtid_mode=ON enforce_gtid_consistency=1
systemctl restart mysqld
2,创建复制用户
进入MySQL
grant replication slave, replication client on *.* to '名字'@'IP.%' identified by '密码';
flush privileges;
3,备份数据库数据
退出MySQL
mysqldump -p'密码' --all-databases --single-transaction --master-data=2 --flush-logs > `date +%F`-mysql-all.sql
scp -r mysql-all.sql IP:/tmp
从:
1,修改配置文件,开启二进制日志
vim /etc/my.cnf
log_bin server-id=2 gtid_mode=ON enforce_gtid_consistency=1
systemctl restart mysqld
2,创建复制用户
进入MySQL
grant replication slave, replication client on *.* to '名字'@'IP.%' identified by '密码';
flush privileges;
3,同步数据
set sql_log_bin=0; source /tmp/mysql-all.sql set sql_log_bin=1;
3,设置主服务器
change master to
master_host='主IP',
master_user='名字',
master_password='密码',
master_auto_position=1;
start slave;
4,查看状态
show slave status\G;
主
1,同步数据
set sql_log_bin=0; source /tmp/mysql-all.sql set sql_log_bin=1;
3,设置主服务器
change master to
master_host='主IP',
master_user='名字',
master_password='密码',
master_auto_position=1;
start slave;
在master1上插入数据,在master2上观察
在master2上插入数据,在master1上观察
双方同步成功,双主设置完成。
主主模式全部添加远程权限
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'Lyj@123456' WITH GRANT OPTION;
FLUSH PRIVILEGES;
keepalived:
yum -y install keepalived
如果出错:
1:net-snmp-agent-libs-5.7.2-49.el7_9.1.x86_64 来自 updates
1:net-snmp-libs-5.7.2-49.el7_9.1.x86_64 来自 updates
则:
yum install -y net-snmp net-snmp-utils --skip-broken
wget http://mirror.centos.org/centos/7/os/x86_64/Packages/keepalived-1.3.5-19.el7.x86_64.rpm
wget http://mirror.centos.org/centos/7/updates/x86_64/Packages/net-snmp-5.7.2-49.el7_9.1.x86_64.rpm
wget http://mirror.centos.org/centos/7/updates/x86_64/Packages/net-snmp-agent-libs-5.7.2-49.el7_9.1.x86_64.rpm
rpm -ivh net-snmp-5.7.2-49.el7_9.1.x86_64.rpm --force --nodeps
rpm -ivh net-snmp-5.7.2-49.el7_9.1.x86_64.rpm --force
rpm -ivh net-snmp-agent-libs-5.7.2-49.el7_9.1.x86_64.rpm --force --nodeps
rpm -ivh net-snmp-agent-libs-5.7.2-49.el7_9.1.x86_64.rpm --force
rpm -ivh keepalived-1.3.5-19.el7.x86_64.rpm --force --nodeps
rpm -ivh keepalived-1.3.5-19.el7.x86_64.rpm --forcesystemctl start keepalived
systemctl status keepalived
可以看到服务已经起来
主主双方部署keepalived:
master vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
lzx@test.com
}
notification_email_from admin@test.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id MYSQL_HA
}
vrrp_instance VI_1 {
state BACKUP
interface ens33 #根据实际网络接口进行更改
virtual_router_id 51
priority 100 #优先级,master设置为100
advert_int 1
nopreempt #不主动抢占资源,只在master上设置
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.30.131
}
}
virtual_server 192.168.30.131 3306 {
delay_loop 2
#lb_algo rr
#lb_kind NAT
persistence_timeout 50
protocol TCP
real_server 192.168.30.129 3306 { #检测本地mysql
weight 3
notify_down /tmp/mysql.sh #当mysql服务down时,执行此脚本,杀死keepalived实现切换
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
backup vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
lzx@test.com
}
notification_email_from admin@test.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id MYSQL_HA
}
vrrp_instance VI_1 {
state BACKUP
interface ens33 #根据实际网络接口进行更改
virtual_router_id 51
priority 90 #优先级,backup设置为90
advert_int 1
#nopreempt #主动抢占资源
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.30.131
}
}
virtual_server 192.168.30.131 3306 {
delay_loop 2
#lb_algo rr
#lb_kind NAT
persistence_timeout 50
protocol TCP
real_server 192.168.30.130 3306 { #检测本地mysql
weight 3
notify_down /tmp/mysql.sh #当mysql服务down时,执行此脚本,杀死keepalived实现切换
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
master和backup上编辑mysql.sh
vim /tmp/mysql.sh
#!/bin/bash
pkill keepalived
# chmod +x !$
# systemctl start keepalived
两台mysql服务器授权允许root远程登录
grant all on *.* to 'root'@'192.168.184.%' identified by '123456789';
测试高可用:
1,通过mysql客户端通过VIP连接,看是否连接成功。
2,停止master上mysql服务,是否能正常切换到backup上。(IP a)
3,master上查看是否有VIP,IP a
4,keepalived在mysql服务停掉之后也被停掉,VIP不在master上。
5,可以看到VIP在backup上。
6,查看/var/log/messages日志,可以看到主备切换过程,
7,恢复master服务器故障,看是否主动抢占资源,成为活动服务器。
8,可以看到,即使master故障恢复,也没有抢占资源,VIP仍然在backup上,这是因为之前已经配置了master为非抢占模式
9,nopreempt这个参数只能用于state为BACKUP的情况,所以在配置的时候要把master和backup的state都设置成BACKUP,这样才会实现keepalived的非抢占模式!
* 当state状态一个为MASTER,一个为BACKUP的时候,加不加nopreempt这个参数都是一样的效果。即都是根据priority优先级来决定谁抢占vip资源的,是抢占模式!
* 当state状态都设置成BACKUP,如果不配置nopreempt参数,那么也是看priority优先级决定谁抢占vip资源,即也是抢占模式。
* 当state状态都设置成BACKUP,如果配置nopreempt参数,那么就不会去考虑priority优先级了,是非抢占模式!即只有vip当前所在机器发生故障,另一台机器才能接管vip。
即使优先级高的那一台机器恢复正常后也不会主动抢回vip,只能等到对方发生故障,才会将vip切回来。