MySQL+keepalived主主复制
前言
在现代信息化系统中,数据库的高可用性与数据一致性是保障业务持续稳定运行的核心要素。MySQL 作为广泛使用的关系型数据库,其单点故障可能导致业务中断,而主主复制架构结合 Keepalived 高可用方案,能够有效提升系统的容错能力与负载均衡能力。
本文档详细阐述了基于 MySQL 主主复制与 Keepalived 实现高可用集群的完整部署流程,涵盖 MySQL 的编译安装、主主复制配置以及 Keepalived 的安装与监控脚本设置。通过该方案,可实现两台 MySQL 服务器互为主从,保证数据双向同步,同时借助 Keepalived 提供的虚拟 IP(VIP)机制,实现故障自动切换,确保数据库服务的持续可用,适用于对数据一致性和服务连续性有较高要求的业务场景。
1 MySQL编译安装
# 环境准备 yum -y install gcc gcc-c++ ncurses ncurses-devel bison cmake # 创建 MySQL 专用用户 useradd -s /sbin/nologin mysql # 源码解压与依赖 tar zxvf mysql-5.7.17.tar.gz -C /opt tar zxvf boost_1_59_0.tar.gz -C /usr/local/ mv /usr/local/boost_1_59_0 /usr/local/boost # CMake 编译配置 cd /opt/mysql-5.7.17/ ------------------------------------------------------------------------------------------------------------ cmake \ -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \ -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \ -DSYSCONFDIR=/etc \ -DSYSTEMD_PID_DIR=/usr/local/mysql \ -DDEFAULT_CHARSET=utf8 \ -DDEFAULT_COLLATION=utf8_general_ci \ -DWITH_EXTRA_CHARSETS=all \ -DWITH_INNOBASE_STORAGE_ENGINE=1 \ -DWITH_ARCHIVE_STORAGE_ENGINE=1 \ -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \ -DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \ -DMYSQL_DATADIR=/usr/local/mysql/data \ -DWITH_BOOST=/usr/local/boost \ -DWITH_SYSTEMD=1 ------------------------------------------------------------------------------------------------------------ # 编译安装 make -j 4 && make install ⚠️ 注意:如果 CMake 出错,解决后需删除 `CMakeCache.txt` 再重新执行 # 权限授权 chown -R mysql:mysql /usr/local/mysql/ chown mysql:mysql /etc/my.cnf # 环境变量设置 echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile source /etc/profile # 数据库初始化 cd /usr/local/mysql/bin/ ------------------------------------------------------------------------------------------------------------ ./mysqld \ --initialize-insecure \ --user=mysql \ --basedir=/usr/local/mysql \ --datadir=/usr/local/mysql/data ------------------------------------------------------------------------------------------------------------ # 启动服务 cp /usr/local/mysql/usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/ systemctl daemon-reload systemctl start mysqld.service systemctl enable mysqld netstat -anpt | grep 3306 # 账号密码设置 mysqladmin -u root -p password "123456" # 登入 mysql -u root -p123456
2 配置主主复制
# 修改配置文件/etc/my.cnf # 主1配置 vim /etc/my.cnf ------------------------------------------------------------------------------------------------------------ [client] port = 3306 socket=/usr/local/mysql/mysql.sock default-character-set=utf8 [mysqld] user = mysql basedir=/usr/local/mysql datadir=/usr/local/mysql/data port = 3306 character-set-server=utf8 pid-file = /usr/local/mysql/mysqld.pid socket=/usr/local/mysql/mysql.sock bind-address = 0.0.0.0 skip-name-resolve max_connections=2048 default-storage-engine=INNODB max_allowed_packet=16M server-id = 70 log_bin = /usr/local/mysql/data/master-bin binlog_do_db = test # 仅同步test库(可选) binlog_ignore_db = mysql # 忽略mysql系统库(可选) relay_log = /usr/local/mysql/data/slave-bin log_slave_updates = 1 # 允许从库日志被其他从库同步(主主必需) auto_increment_offset = 1 auto_increment_increment = 2 sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,PIPES_AS_CONCAT,ANSI_QUOTES [mysql] port = 3306 default-character-set=utf8 socket=/usr/local/mysql/mysql.sock auto-rehash ------------------------------------------------------------------------------------------------------------ # 主2配置 vim /etc/my.cnf ------------------------------------------------------------------------------------------------------------ [client] port = 3306 socket=/usr/local/mysql/mysql.sock default-character-set=utf8 [mysqld] user = mysql basedir=/usr/local/mysql datadir=/usr/local/mysql/data port = 3306 character-set-server=utf8 pid-file = /usr/local/mysql/mysqld.pid socket=/usr/local/mysql/mysql.sock bind-address = 0.0.0.0 skip-name-resolve max_connections=2048 default-storage-engine=INNODB max_allowed_packet=16M server-id = 71 log_bin = /usr/local/mysql/data/master-bin binlog_do_db = test # 仅同步test库(可选) binlog_ignore_db = mysql # 忽略mysql系统库(可选) relay_log = /usr/local/mysql/data/slave-bin log_slave_updates = 1 # 允许从库日志被其他从库同步(主主必需) auto_increment_offset = 2 auto_increment_increment = 2 sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,PIPES_AS_CONCAT,ANSI_QUOTES [mysql] port = 3306 default-character-set=utf8 socket=/usr/local/mysql/mysql.sock auto-rehash ------------------------------------------------------------------------------------------------------------ # 重启MySQL systemctl restart mysqld # 主1上创建账号(允许主2访问) mysql -uroot -p123456 GRANT REPLICATION SLAVE ON *.* TO 'slave'@'192.168.10.71' IDENTIFIED BY '123456'; flush privileges; # 主2上创建账号(允许主1访问) mysql -uroot -p123456 GRANT REPLICATION SLAVE ON *.* TO 'slave'@'192.168.10.70' IDENTIFIED BY '123456'; flush privileges; ------------------------------------------------------------------------------------------------------------ # 配置主从同步 # 查看 主2 的二进制日志状态 show master status; # 在主1上配置 CHANGE MASTER TO MASTER_HOST='192.168.10.71', MASTER_USER='slave', MASTER_PASSWORD='123456', MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=154; # 启动从库且查看同步状态 start slave; show slave status\G ------------------------------------------------------------------------------------------------------------ # 查看 主1 的二进制日志状态 show master status; # 在主2上配置 CHANGE MASTER TO MASTER_HOST='192.168.10.70', MASTER_USER='slave', MASTER_PASSWORD='123456', MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=154; # 启动从库且查看同步状态 start slave; show slave status\G
3 安装keepalived
# 安装 Keepalived yum install -y keepalived ============================================================================================================ # 配置主1的 Keepalived vim /etc/keepalived/keepalived.conf ------------------------------------------------------------------------------------------------------------ global_defs {router_id MYSQL_HA # 唯一标识 } # 监控MySQL的脚本(关键:检测MySQL是否存活) vrrp_script check_mysql {script "/etc/keepalived/check_mysql.sh" # 脚本路径interval 2 # 每2秒检测一次weight -20 # 检测失败时优先级减20 } vrrp_instance VI_1 {state MASTER # 节点A为默认主节点interface ens160 # 网卡名称(根据实际情况修改)virtual_router_id 51 # 虚拟路由ID(两节点需一致)priority 100 # 优先级(节点A > 节点B)advert_int 1 # 心跳间隔1秒 # 认证配置authentication {auth_type PASSauth_pass 1111} # 虚拟IP(VIP)virtual_ipaddress {192.168.10.110/24} # 引用监控脚本track_script {check_mysql} } ------------------------------------------------------------------------------------------------------------ # 配置主2的 Keepalived vim /etc/keepalived/keepalived.conf ------------------------------------------------------------------------------------------------------------ global_defs {router_id MYSQL_HA # 唯一标识 } # 监控MySQL的脚本(关键:检测MySQL是否存活) vrrp_script check_mysql {script "/etc/keepalived/check_mysql.sh" # 脚本路径interval 2 # 每2秒检测一次weight -20 # 检测失败时优先级减20 } vrrp_instance VI_1 {state BACKUP # 节点A为默认主节点interface ens160 # 网卡名称(根据实际情况修改)virtual_router_id 51 # 虚拟路由ID(两节点需一致)priority 90 # 优先级(节点A > 节点B)advert_int 1 # 心跳间隔1秒 # 认证配置authentication {auth_type PASSauth_pass 1111} # 虚拟IP(VIP)virtual_ipaddress {192.168.10.110/24} # 引用监控脚本track_script {check_mysql} } ============================================================================================================ # 编写检测脚本(2个主都需要) vim /etc/keepalived/check_mysql.sh ------------------------------------------------------------------------------------------------------------ # 在脚本开头添加日志路径 LOG_FILE="/var/log/check_mysql.log" echo "[$(date +'%F %T')] 开始检测MySQL" >> $LOG_FILE # 在关键步骤添加日志 MYSQL_CMD="/usr/local/mysql/bin/mysql" $MYSQL_CMD -uroot -p'123456' -e "exit" > /dev/null 2>&1 if [ $? -ne 0 ]; thenecho "[$(date +'%F %T')] MySQL连接失败,尝试重启" >> $LOG_FILEsystemctl restart mysqldsleep 3$MYSQL_CMD -uroot -p'123456' -e "exit" > /dev/null 2>&1if [ $? -ne 0 ]; thenecho "[$(date +'%F %T')] MySQL重启失败,停止Keepalived" >> $LOG_FILEsystemctl stop keepalivedfi fi ---------------------------------------------------------------------------------------
4 测试
4.1 测试主主复制
主1插入数据,主2同步成功
4.2 测试故障切换
1、MySQL和keepalived都是开启的状态,将主1 MySQL停止后,看看VIP会不会漂移到 主2
5 总结
本文档围绕 MySQL 主主复制与 Keepalived 高可用集群搭建展开,完成了从环境准备到最终高可用架构部署的全流程说明:
MySQL 编译安装:通过源码编译方式安装 MySQL,完成环境依赖配置、用户创建、编译参数设置、权限分配及初始化操作,为后续主主复制奠定基础。
主主复制配置:通过修改两台服务器的 MySQL 配置文件,设置不同的 server-id、自增偏移与步长,避免数据冲突;并通过创建复制账号、配置主从关系,实现两台 MySQL 服务器之间的双向数据同步,确保数据一致性。
Keepalived 部署:安装 Keepalived 服务,分别配置主从节点的 keepalived.conf 文件,定义虚拟路由 ID、虚拟 IP 及优先级;编写 MySQL 监控脚本,实现对数据库存活状态的检测,当主节点故障时自动切换至从节点,保障服务高可用。
通过上述步骤,构建了一套兼具数据同步与故障自动切换能力的 MySQL 高可用集群,可有效提升数据库服务的稳定性与可靠性。