MySQL5.7的主从和双主Keepalived配置

算是运维基本操作之一了,记个笔记吧。

主从配置

基本的MySQL服务端配置

这个反正自己根据资源条件和需求看着配吧,下面就是像征性配一点语言编码、binlog、慢查询相关的。

[mysqld]
# 内存使用相关的配置(略)
character-set-server=utf8
collation-server=utf8_general_ci

log_bin=mysql-bin
binlog_format=mixed
#binlog-ignore-db=mysql,information_schema,sys,performance_schema
max_binlog_size=100M
expire_logs_days=14

long_query_time=1
slow_query_log=ON

binlog部分是关键的,主从的数据同步主要就是靠它。其实主从同步的基本原理就是把主机的数据库日志放到从机上同样跑一遍。

主从配置

这个是主要需要配置的部分:

server-id={{ SERVER_ID }}  # 服务器ID
auto-increment-offset={{ SERVER_ID }}  # 自增起步,两台服务器要错开,否则双主模式下会冲突
auto-increment-increment=2  # 自增步长,确保两台服务器错开
innodb_flush_log_at_trx_commit=1
sync_binlog=1
log_slave_updates=1
gtid_mode=on  # 启用GTID,提交主从同步效率
enforce_gtid_consistency=1
binlog_gtid_simple_recovery=1
slave-skip-errors=all

master_info_repository="TABLE"
relay_log_info_repository="TABLE"
relay_log_recovery=1
relay-log=relay-bin
relay-log-index=slave-relay-bin.index

其中{{ SERVER_ID }}为1或2。各参数含义见注释。relay-log是slave进程缓存的同步日志。另外,其中的GTID选项一定要启用,同步起来比较高效。GTID就是给日志加一个全局唯一编号,没有这个就需要按日志顺序号来,两边的顺序号要匹配起来就麻烦一些,当然没有全局唯一的ID同步起来方便。

同步用户配置

如前面所说,主从同步是从机上同样执行一次主机的数据库日志,所以需要主机上建一个专门的用户供从机连过来读取日志,这就是同步用户:

grant replication slave on *.* to 'replica'@'192.168.0.102' identified by 'MySQL_1234';

这句就是创建一个同步用户并授权。这里假设从服务器的IP是192.168.0.102

配置主从同步

现在可以到从机上配置同步了,基本原理就是配置必要的主服务器信息,然后启动同步进程。

stop slave;
change master to master_host='192.168.0.101', master_user='replica', master_password='MySQL_1234', master_auto_position=1;
start slave;

这里假设主服务的IP是192.168.0.101,同步用户信息就是前面创建的那个。

注意,master_auto_position功能需要打开前面说过的GTID才能使用,否则这里需要使用日志顺序号,比较麻烦。

校验同步状态

在从服务器上查看:

show slave status \G

可以看到如下两行说明同步进程运行正常:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

还可以测试一下在主服务器做一些写入操作,比如建个库,建个表,插入些数据什么,然后在从服务器上查看是否有同步过来。

双主配置

主从配置好以后,双主配置就简单了,反向同步一下即可。

  • 在从服务器上创建一个同步用户,跟前面主服务器配置方法一样,用户IP改为主服务器的IP
  • 在主服务器启用同步,跟前面从服务器的配置方法一样,服务器IP改为从服务器的IP
  • 在主服务器上校验同步状态,然后在从服务器上写入测试,在主服务器上查看同步结果

至此安成双向同步的双主配置。

Keepalived配置

Keepalived是一个简单的高可用(HA)解决方案,基于Linux虚拟服务器(LVS)技术,核心是虚拟路由器冗余协议(VRRP)这个协议。

在这里的应用原理就是把keepalived作为一个虚拟路由器,绑定一个虚拟的IP,然后根据后端服务器的状态,自动选择可用的服务器。

更具体一点就是在双主MySQL服务器上分别跑一个Keepalived,两个Keepalived一方面定时检查对应的MySQL服务器状态,另一方面通过心跳请求检查对方Keepalived的状态。

在启动时,两个Keepalived会选举出一个主服务器(这里是根据配置的优先级指定),这时客户端通过虚拟IP连接过来时,会被Keepavlied的虚拟路由器机制转到对应的MySQL服务器IP上。如果这台MySQL服务器发生故障,对应的Keepalived检查到失败,就自动停止服务,另一台的Keepalived通过心跳检查发现对方离线,就自动通过VRRP协议广播把虚拟IP切换到本机MySQL服务的IP上,客户端在短暂中断后重新连接虚拟IP即到达新的MySQL服务器,恢复服务。

如果系统中有邮件服务器的话,还可以通过Keepalived配置把这一切换事件通过邮件发送通知。

安装

没什么好说的,apt/yum安装一下就是了。源码编译啥的就算了,没必要自找麻烦。

MySQL状态检查脚本

Keepalived是通过配置指定的脚本执行结果来判断后端服务的状态,所以需要写一个MySQL状态检查脚本给它。

#!/bin/bash

MYSQL_ROOT_PASSWORD=MySQL_1234

mysql=( mysql -h127.0.0.1 -uroot -p"${MYSQL_ROOT_PASSWORD}" )
if
    ! echo "select 1;" | "${mysql[@]}" &> /dev/null
then
    kill -15 $(cat /run/keepalived.pid)
    exit 1
fi

exit 0

就是简单地连上数据库并执行一个肯定成功的查询语句,出错就认为数据库服务器故障,否则就正常。15是Keepalived默认的停止信号值,具体有哪些信号值可以查看Keepalived的帮助。

配置Keepalived

配置文件内容大致如下,其中没有包含邮件通知部分,有需要的可以自己加。

! Configuration File for keepalived

global_defs {
   router_id MySQL_HA  # 定义一个名字
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_script check_mysql {
    script "/opt/mysql/check_mysql.sh"
    interval 2  # 检查间隔2秒
    weight -20  # 权重,每次检查失败优先级减20,这个及下面两个对于这个检查脚本没用,因为检查脚本直接停Keepalived,不通过优先级调整切换
    fall 1  # 失败一次即算失败,不重试
    rise 1  # 成功一次即算恢复,不改变优先级
}

vrrp_instance VI_1 {
    state BACKUP  # 一般是一个MASTER一个BACKUP,但是这样有个问题就是切到BACKUP后切不回来,所以最好是两个都用BACKUP
    interface eth0  # 网卡名
    virtual_router_id 51  # 虚拟路由ID,两台机器必须一样,这里用默认的51,如果网络里有多组,这个需要区别开
    priority 100  # 优先级,两个服务器必须不一样,数字大的默认为主服务器
    advert_int 1  # 心跳检查周期,默认1秒
    nopreempt  # 是否强制切回,只在优先级高的那台启用,另一台不用
    authentication {
        auth_type PASS
        auth_pass "password"  # 密码,防止非法加入
    }
    virtual_ipaddress {
        192.168.0.100  # 虚拟IP
    }
    track_script {
        check_mysql
    }
}

测试

两台服务器的keepalived都配置好并启动服务以后可以关闭MySQL服务测试。

  • 先用客户端连接虚拟IP,然后操作一下
  • 再把优先级高的主服务器MySQL服务停掉,可以看到日志显示Keepalived也退出,另一台的Keepalived日志显示虚拟IP对应的真实IP发生切换
  • 客户端操作一下可以看到连接中断,然后又连上,现在连接的是优先级低的备用服务器上的MySQL,可以继续操作
  • 再把优先级高的主服务器的MySQL和Keepalived启动
  • 客户端操作一下,连接未中断,现在仍然连接的是备用服务器
  • 再把备用服务器的MySQL服务停掉,可以看到日志显示Keepalived退出,主服务器上的Keepalived发生了IP切换
  • 客户端操作下可以看到连接再次中断并重连,现在连接到主服务器上,可以继续操作

测试成功。

推送到[go4pro.org]