一、概述
MySQL高可用方案通常包含以下几种:keepalived + 双主、MHA、PXC、MMM、Heartbeat + DRBD等。在实际应用中,keepalived + 双主、MHA和PXC较为常用。
本节重点阐述如何运用keepalived达成MySQL数据库的高可用。
借助keepalived + mysql双主模式构建MySQL - HA时,确保两台MySQL数据库数据完全一致至关重要。其基本原理为:让两台MySQL互为对方的主从,借助Keepalived配置虚拟IP。如此一来,当其中一台MySQL数据库发生宕机故障时,应用程序能够自动切换至另一台MySQL数据库,从而保障系统的高可用性。
二、环境介绍
本文描述的环境为模拟环境,仅用于测试方案可行性。
操作系统: Red Hat Enterprise Linux release 8.10 (Ootpa)
数据库版本:8.0.40 MySQL Community Server - GPL
keepalived:v2.1.5
主机名 | IP 地址 | 数据库角色 | VIP |
mm-host01 | 192.168.3.31 | Master主机 | 192.168.3.30 |
mm-host02 | 192.168.3.32 | Master备机 | - |
三、环境准备
3.1. 创建用户、组
以 root
用户登录,执行以下命令创建 MySQL 数据库专用的用户和组
groupadd mysql
useradd -r -g mysql -s /bin/false mysql
3.2. 规划安装目录
为方便管理和提高性能,根据文件的不同读写特性,将 MySQL 的各类数据和日志分开存放,以分散 IO 压力。推荐的目录结构如下:
序号 | 目录路径 | 目录描述 |
1 | /usr/local | 存放mysql安装程序文件 |
2 | /etc | 存放mysql配置文件 |
3 | /mysqldata | 存放数据文件,错误日志以及慢查询日志 |
4 | /redolog | 存放mysql重做日志文件 |
5 | /undolog | 存放undo表空间文件 |
6 | /binlog | 存放mysql binlog文件 |
3.3. 创建目录并更改目录属主,确保 MySQL 用户具有目录权限
mkdir /mysqldata
mkdir /redolog
mkdir /undolog
mkdir /binlog
chown -R mysql:mysql /mysqldata
chown -R mysql:mysql /redolog
chown -R mysql:mysql /undolog
chown -R mysql:mysql /binlog
3.4. 配置MySQL参数文件(双主配置)
编辑MySQL 配置文件 ( /etc/my.cnf
) 添加数据库参数配置,以下为 mm-host01 的参数配置。
[client]
port = 3306
socket = /tmp/mysql.sock
[mysql]
prompt = "\u@mysqldb \R:\m:\s [\d]> "
no_auto_rehash
[mysqld]
user = mysql
sql_mode = "STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO"
port = 3306
server_id = 31
datadir = /mysqldata
socket = /tmp/mysql.sock
pid_file = mysqldb.pid
character_set_server = UTF8MB4
skip_name_resolve = 1
default_time_zone = "+8:00"
admin_address = '127.0.0.1'
admin_port = 4444
lower_case_table_names = 1
#performance setttings
lock_wait_timeout = 3600
open_files_limit = 65535
back_log = 1024
max_connections = 2000
max_connect_errors = 1000000
table_open_cache = 1024
table_definition_cache = 1024
thread_stack = 512K
sort_buffer_size = 4M
join_buffer_size = 4M
read_buffer_size = 8M
read_rnd_buffer_size = 4M
bulk_insert_buffer_size = 64M
thread_cache_size = 768
interactive_timeout = 3600
wait_timeout = 3600
tmp_table_size = 1024M
max_heap_table_size = 32M
#log settings
log_timestamps = SYSTEM
log_error = /mysqldata/error.log
log_error_verbosity = 3
slow_query_log = 1
log_slow_extra = 1
slow_query_log_file = /mysqldata/slow.log
long_query_time = 1
min_examined_row_limit = 10000
log_slow_admin_statements = 1
log_slow_slave_statements = 1
log_bin = /binlog/bin
binlog_format = ROW
sync_binlog = 1
binlog_cache_size = 4M
max_binlog_cache_size = 2G
max_binlog_size = 1G
binlog_rows_query_log_events = 1
binlog_expire_logs_seconds = 604800
binlog_checksum = CRC32
gtid_mode = ON
enforce_gtid_consistency = TRUE
log-bin-trust-function-creators = 1
#replication settings
relay_log_recovery = 1
slave_parallel_type = LOGICAL_CLOCK
slave_parallel_workers = 2
binlog_transaction_dependency_tracking = WRITESET
slave_preserve_commit_order = 1
slave_checkpoint_period = 2
log-slave-updates=1
auto_increment_increment=2
auto_increment_offset=1
#innodb settings
transaction_isolation = READ-COMMITTED
innodb_buffer_pool_size = 2048M
innodb_buffer_pool_instances = 4
innodb_data_file_path = ibdata1:12M:autoextend
innodb_flush_log_at_trx_commit = 1
innodb_log_buffer_size = 32M
innodb_log_group_home_dir = /redolog
innodb_log_file_size = 1G
innodb_log_files_in_group = 3
innodb_undo_directory = /undolog
innodb_max_undo_log_size = 1G
innodb_io_capacity = 2000
innodb_io_capacity_max = 4000
innodb_open_files = 65535
innodb_flush_method = O_DIRECT
innodb_lru_scan_depth = 2000
innodb_lock_wait_timeout = 10
innodb_rollback_on_timeout = 1
innodb_print_all_deadlocks = 1
innodb_online_alter_log_max_size = 4G
innodb_print_ddl_logs = 1
innodb_status_file = 1
innodb_status_output = 0
innodb_status_output_locks = 1
innodb_sort_buffer_size = 67108864
innodb_adaptive_hash_index = OFF
#innodb monitor settings
innodb_monitor_enable = "module_innodb"
innodb_monitor_enable = "module_server"
innodb_monitor_enable = "module_dml"
innodb_monitor_enable = "module_ddl"
innodb_monitor_enable = "module_trx"
innodb_monitor_enable = "module_os"
innodb_monitor_enable = "module_purge"
innodb_monitor_enable = "module_log"
innodb_monitor_enable = "module_lock"
innodb_monitor_enable = "module_buffer"
innodb_monitor_enable = "module_index"
innodb_monitor_enable = "module_ibuf_system"
innodb_monitor_enable = "module_buffer_page"
#pfs settings
performance_schema = 1
performance_schema_instrument = '%lock%=on'
[mysqldump]
quick
mm-host02 不同的部分参数
server_id = 32
auto_increment_increment=2
auto_increment_offset=2
3.5. 检查glibc 版本
MySQL 的二进制发行版是基于特定的 glibc
版本编译的,例如 glibc 2.28
。如果系统中的 glibc
版本低于此版本,MySQL将无法正常运行 。
ldd --version
ldd (GNU libc) 2.28
四、安装MySQL数据库
安装MySQL部分操作需要在所有节点上执行。
4.1. 上传安装文件
将安装文件上传至服务器的 /usr/local
目录。
4.2. 登录服务器并执行安装
登录服务器并执行安装,使用 root
用户登录服务器,依次执行以下命令:
# 进入目标目录
cd /usr/local
# 解压安装包
tar xf mysql-8.0.40-linux-glibc2.28-x86_64.tar.xz
# 创建符号链接
ln -s /usr/local/mysql-8.0.40-linux-glibc2.28-x86_64 mysql
# 进入 MySQL 目录
cd mysql
# 设置目录权限
chown -R root:mysql .
# 初始化 MySQL
bin/mysqld --initialize --user=mysql
# 复制启动脚本
cp support-files/mysql.server /etc/init.d/mysqld
# 配置环境变量
echo "export PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
# 使环境变量生效
source /etc/profile
4.3. 启动 MySQL 服务
执行以下命令启动 MySQL 服务:
# 启动 MySQL
/etc/init.d/mysqld start
4.4. 验证安装
检查 MySQL 是否正常运行:
# 查看 MySQL 进程
ps -ef | grep mysql
# 查看 MySQL 端口监听状态
netstat -tuln | grep 3306
4.5. 修改 root 密码
在初始化后需要修改 root
用户的密码,执行以下命令进行修改:
# 使用初始化时生成的临时密码登录 MySQL
mysql -uroot -p
# 修改 root 密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'strong_password';
# 配置mysql开机自启
chkconfig mysqld on
chkconfig --list mysqld
五、配置MySQL互为主从复制
5.1. 在主库创建主从复制专用账号
首先,在主库上创建一个用于主从复制的专用账号,并授予必要的权限。
CREATE USER 'repl'@'192.168.3.%' IDENTIFIED with mysql_native_password BY 'strong_password';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'192.168.3.%';
5.2. 主库端执行备份
在主库上执行全库备份,并确保备份文件中包含 GTID 信息。
mysqldump -uroot -p --all-databases --single-transaction --triggers --routines --events > /tmp/alldb.sql
5.3. 将备份文件传输到从库
使用 scp
或其他文件传输工具将备份文件传输到从库。
scp /tmp/alldb.sql [email protected]:/tmp/
5.4. 从库端执行恢复
在从库上执行以下操作来恢复备份文件。
mysql -uroot -p
slave> stop slave;
slave> reset slave all;
slave> reset master;
slave> set @@global.gtid_purged='';
slave> source /tmp/alldb.sql;
slave> show databases;
5.5. 配置 Master 备机成为 Master 主机的从机
配置 Master 备机从 Master 主机同步数据:
CHANGE MASTER TO
MASTER_HOST='192.168.3.31',
MASTER_USER='repl',
MASTER_PASSWORD='strong_password',
MASTER_PORT=3306,
MASTER_AUTO_POSITION=1;
5.6. 启动从机并查看状态
启动从机并查看同步状态:
START SLAVE;
SHOW SLAVE STATUS\G;
5.7. 配置 Master 主机成为 Master 备机的从机
配置 Master 主机从 Master 备机同步数据:
master> stop slave;
master> reset slave all;
CHANGE MASTER TO
MASTER_HOST='192.168.3.32',
MASTER_USER='repl',
MASTER_PASSWORD='strong_password',
MASTER_PORT=3306,
MASTER_AUTO_POSITION=1;
5.8. 启动从机并查看状态
启动从机并查看同步状态:
START SLAVE;
SHOW SLAVE STATUS\G;
六、Keepalived 故障自动切换配置指南
6.1. 配置 hosts 解析
首先,在所有服务器上配置 hosts 文件,确保主机名与 IP 地址的映射正确。
vi /etc/hosts
192.168.3.31 mm-host01
192.168.3.32 mm-host02
6.2. 安装 Keepalived
在每台服务器上安装 Keepalived。
yum install keepalived
6.3. 配置 Keepalived
以下是主从节点的 Keepalived 配置文件示例,红色字部分需要根据服务器实际情况进行修改。
主节点配置(mm-host01)
cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
mm-host01 # 路由器标识,建议使用主机名
script_user root
}
vrrp_script chk_mysql {
script "/etc/keepalived/mysql_check.sh"
interval 2
weight 15 # 此值需要大于MASTER的priority减去BACKUP的priority
}
vrrp_instance VI_1 {
state BACKUP # 主节点为:MASTER,备节点为:BACKUP
interface ens160
virtual_router_id 100
unicast_src_ip 192.168.3.31
unicast_peer {
192.168.3.32
}
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_mysql
}
virtual_ipaddress {
192.168.3.30
}
}
从节点配置(mm-host02)
cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
mm-host02 # 路由器标识,建议使用主机名
script_user root
}
vrrp_script chk_mysql {
script "/etc/keepalived/mysql_check.sh"
interval 2
weight 20 # 此值需要大于MASTER的priority减去BACKUP的priority
fall 2
rise 1
}
vrrp_instance VI_1 {
state MASTER # 主节点为:MASTER,备节点为:BACKUP
nopreemt
interface ens192
virtual_router_id 100
unicast_src_ip 192.168.3.32
unicast_peer {
192.168.3.31
}
priority 110
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_mysql
}
virtual_ipaddress {
192.168.3.30
}
}
6.4. MySQL 检查脚本
创建一个 MySQL 检查脚本,用于监控 MySQL 服务的状态。
vi /etc/keepalived/mysql_check.sh
#!/bin/bash
counter=$(netstat -na |grep "LISTEN"|grep "3306"|wc -l)
if [ "${counter}" -eq 0 ]; then
systemctl stop keepalived
fi
6.5. Keepalived检查脚本
创建一个Keepalived 检查脚本,定期检查 Keepalived 服务的运行状态。
vi /etc/keepalived/keepalived_check.sh
#!/bin/bash
CMD=$(ps -ef |grep 'keepalived -D'|grep -v grep |wc -l)
count=$(netstat -na |grep "LISTEN"|grep "3306"|wc -l)
if [ "${count}" -ne 0 ]; then
if [ "${CMD}" -eq 0 ]; then
echo "重新执行keepalvied"
# systemctl restart keepalived
fi
fi
6.6. 授权脚本执行权限
chmod +x keepalived_check.sh
chmod +x mysql_check.sh
6.7. 启动keepalived
systemctl start keepalived
systemctl status keepalived
6.8. 查看vip信息
如果需要查看虚拟 IP(VIP)信息,可以使用以下命令:
ip addr show
如果需要更详细的信息,可以查看 keepalived 的日志,了解 VIP 切换或错误信息:
journalctl -u keepalived
6.9. 定时任务
配置一个定时任务,定期检查 Keepalived 服务的运行状态。
crontab -l
*/3 * * * * /etc/keepalived/keepalived_check.sh
总结
Keepalived+mysql双主一般来说,中小型规模的时候,采用这种架构是最省事的。 在master节点发生故障后,利用keepalived的高可用机制实现快速切换到备用节点。 在这个方案里,有几个需要注意的地方:
采用keepalived作为高可用方案时,两个节点最好都设置成BACKUP模式,避免因为意外情况下(比如脑裂)相互抢占导致往两个节点写入相同数据而引发冲突;
把两个节点的auto_increment_increment(自增步长)和auto_increment_offset(自增起始值)设成不同值。其目的是为了避免master节点意外宕机时,可能会有部分binlog未能及时复制到slave上被应用,从而会导致slave新写入数据的自增值和原先master上冲突了,因此一开始就使其错开,当然了,如果有合适的容错机制能解决主从自增ID冲突的话,也可以不这么做;
slave节点服务器配置不要太差,否则更容易导致复制延迟。作为热备节点的slave服务器,硬件配置不能低于master节点;
如果对延迟问题很敏感的话,可考虑使用MariaDB分支版本,或者直接上线MySQL 5.7最新版本,利用多线程复制的方式可以很大程度降低复制延迟;
END
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件举报,一经查实,本站将立刻删除。
文章由技术书栈整理,本文链接:https://study.disign.me/article/202510/12.mysql-master-keepalived.md
发布时间: 2025-03-05