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 PASS
        auth_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 PASS
        auth_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 ]; then
    echo "[$(date +'%F %T')] MySQL连接失败,尝试重启" >> $LOG_FILE
    systemctl restart mysqld
    sleep 3
    $MYSQL_CMD -uroot -p'123456' -e "exit" > /dev/null 2>&1
    if [ $? -ne 0 ]; then
        echo "[$(date +'%F %T')] MySQL重启失败,停止Keepalived" >> $LOG_FILE
        systemctl stop keepalived
    fi
fi
---------------------------------------------------------------------------------------

4 测试

4.1 测试主主复制

主1插入数据,主2同步成功

4.2 测试故障切换

1、MySQL和keepalived都是开启的状态,将主1 MySQL停止后,看看VIP会不会漂移到 主2

5 总结

本文档围绕 MySQL 主主复制与 Keepalived 高可用集群搭建展开,完成了从环境准备到最终高可用架构部署的全流程说明:

  1. MySQL 编译安装:通过源码编译方式安装 MySQL,完成环境依赖配置、用户创建、编译参数设置、权限分配及初始化操作,为后续主主复制奠定基础。

  2. 主主复制配置:通过修改两台服务器的 MySQL 配置文件,设置不同的 server-id、自增偏移与步长,避免数据冲突;并通过创建复制账号、配置主从关系,实现两台 MySQL 服务器之间的双向数据同步,确保数据一致性。

  3. Keepalived 部署:安装 Keepalived 服务,分别配置主从节点的 keepalived.conf 文件,定义虚拟路由 ID、虚拟 IP 及优先级;编写 MySQL 监控脚本,实现对数据库存活状态的检测,当主节点故障时自动切换至从节点,保障服务高可用。

通过上述步骤,构建了一套兼具数据同步与故障自动切换能力的 MySQL 高可用集群,可有效提升数据库服务的稳定性与可靠性。

相关推荐
流星白龙11 小时前
【MySQL高阶】7.MySQL日志
数据库·mysql·adb
流星白龙11 小时前
【MySQL高阶】0.MySQL的安装
数据库·mysql·adb
流星白龙13 小时前
【MySQL高阶】6.MySQL数据目录,日志
android·mysql·adb
流星白龙14 小时前
【MySQL高阶】2.MySQL命令行客户端(2)
android·mysql·adb
流星白龙14 小时前
【MySQL高阶】5.MySQL服务器简介
服务器·mysql·adb
流星白龙14 小时前
【MySQL高阶】9.在一台机器上运行多个MySQL实例
数据库·mysql·adb
流星白龙16 小时前
【MySQL高阶】8.MySQL系统库
android·mysql·adb
亚空间仓鼠3 天前
Docker容器化高可用架构部署方案(十七)
adb
AI人工智能+电脑小能手4 天前
【大白话说Java面试题 第80题】【Mysql篇】第10题:MySQL 在什么条件下索引失效?
java·开发语言·mysql·adb·面试
会Tk矩阵群控的小木4 天前
深入解析tk矩阵系统ADB实时投屏与多设备控制实现
运维·线性代数·adb·矩阵·个人开发