外观
MySQL 基本主从复制配置
主从复制工作原理
复制流程
核心组件
- 主库(Master):接收写入请求,记录二进制日志
- 从库(Slave):读取主库二进制日志,执行相同的更新
- I/O 线程:从主库读取二进制日志,写入本地中继日志
- SQL 线程:读取中继日志,执行更新操作
主从复制前提条件
软件要求
- MySQL 版本:主从库版本兼容
- 推荐使用相同版本
- 从库版本可以高于主库,但不建议低于主库
- 版本差异应在一个主版本内(如 5.7 → 8.0 可能需要特殊处理)
硬件要求
主库:
- 足够的 CPU 和内存处理写入请求
- 高速磁盘用于存储二进制日志
- 足够的带宽用于复制
从库:
- 与主库相当的硬件配置
- 足够的存储空间用于存储数据和中继日志
- 高速网络连接到主库
配置要求
- 服务器 ID:每个服务器必须有唯一的
server_id - 二进制日志:主库必须启用二进制日志
- 中继日志:从库自动创建中继日志
- 用户权限:主库需要创建具有复制权限的用户
主库配置
配置文件修改
ini
# 启用二进制日志
log_bin = mysql-bin
# 设置服务器 ID(必须唯一)
server_id = 1
# 使用 row 格式(推荐)
binlog_format = row
# 二进制日志保留时间(秒)
# expire_logs_days = 7 # MySQL 8.0 后推荐使用 binlog_expire_logs_seconds
binlog_expire_logs_seconds = 604800
# 二进制日志缓存大小
binlog_cache_size = 32m
max_binlog_cache_size = 512m
# 单个二进制日志大小限制
max_binlog_size = 1024m
# 同步写入二进制日志(可选,提高可靠性)
sync_binlog = 1
# 启用 binlog_checksum(MySQL 5.6+)
binlog_checksum = CRC32
# 跳过错误(生产环境不推荐)
# slave_skip_errors = 1062,1032重启主库
bash
# 使用 systemd 重启
systemctl restart mysqld
# 使用 service 重启
service mysqld restart创建复制用户
sql
-- 创建复制用户
CREATE USER 'repl'@'%' IDENTIFIED BY 'password';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
-- 刷新权限
FLUSH PRIVILEGES;锁定主库并备份
sql
-- 锁定主库,防止数据写入
FLUSH TABLES WITH READ LOCK;
-- 查看主库状态,记录文件名和位置
SHOW MASTER STATUS;输出示例:
文件名称: mysql-bin.000001
位置: 154
记录数据库:
忽略数据库:
已执行GTID集合:备份主库数据
bash
# 使用 mysqldump 备份
mysqldump --single-transaction --master-data=2 --all-databases --triggers --routines --events > master_backup.sql
# 使用 xtrabackup 备份(推荐)
xtrabackup --backup --user=root --password=password --target-dir=/backup/mysql解锁主库
sql
-- 解锁主库,允许数据写入
UNLOCK TABLES;从库配置
配置文件修改
ini
# 启用二进制日志(级联复制需要)
log_bin = mysql-bin
# 设置服务器 ID(必须与主库不同)
server_id = 2
# 使用 row 格式
binlog_format = row
# 中继日志相关配置
relay_log = relay-bin
relay_log_index = relay-bin.index
# 从库只读(可选,提高安全性)
read_only = ON
# 从库超级用户只读(可选)
super_read_only = ON
# 自动清理中继日志
relay_log_recovery = ON
# 中继日志保留时间
relay_log_purge = ON
relay_log_space_limit = 4G
# 复制线程配置
slave_parallel_workers = 4 # MySQL 5.7+ 支持并行复制
slave_parallel_type = LOGICAL_CLOCK # 并行复制类型
# 跳过错误(生产环境不推荐)
# slave_skip_errors = 1062,1032重启从库
bash
# 使用 systemd 重启
systemctl restart mysqld
# 使用 service 重启
service mysqld restart恢复主库数据到从库
bash
# 使用 mysqldump 备份恢复
mysql -u root -p < master_backup.sql
# 使用 xtrabackup 备份恢复
xtrabackup --prepare --target-dir=/backup/mysql
xtrabackup --copy-back --target-dir=/backup/mysql --datadir=/var/lib/mysql
chown -R mysql:mysql /var/lib/mysql配置从库连接主库
sql
-- 停止从库复制线程
STOP SLAVE;
-- 重置从库复制信息
RESET SLAVE;
-- 配置主库连接信息
CHANGE MASTER TO
MASTER_HOST = 'master_host',
MASTER_PORT = 3306,
MASTER_USER = 'repl',
MASTER_PASSWORD = 'password',
MASTER_LOG_FILE = 'mysql-bin.000001', -- 从 SHOW MASTER STATUS 获取
MASTER_LOG_POS = 154; -- 从 SHOW MASTER STATUS 获取
-- 启动从库复制线程
START SLAVE;验证从库状态
sql
-- 查看从库状态
SHOW SLAVE STATUS\G关键状态指标:
Slave_IO_Running:I/O 线程状态,应为YesSlave_SQL_Running:SQL 线程状态,应为YesSeconds_Behind_Master:从库落后主库的秒数,应为0Master_Log_File和Read_Master_Log_Pos:I/O 线程读取的主库日志位置Relay_Master_Log_File和Exec_Master_Log_Pos:SQL 线程执行的主库日志位置
主从复制管理
查看主库状态
sql
-- 查看主库状态
SHOW MASTER STATUS;
-- 查看二进制日志列表
SHOW BINARY LOGS;
-- 查看二进制日志内容
SHOW BINLOG EVENTS IN 'mysql-bin.000001';
-- 查看当前正在使用的二进制日志
SHOW MASTER STATUS LIKE 'File';查看从库状态
sql
-- 查看从库状态
SHOW SLAVE STATUS\G
-- 查看从库线程状态
SHOW PROCESSLIST;
-- 查看从库的 GTID 执行情况(如果启用 GTID)
SHOW GLOBAL VARIABLES LIKE 'gtid_executed';暂停和恢复复制
sql
-- 暂停复制
STOP SLAVE;
-- 暂停特定线程
STOP SLAVE IO_THREAD;
STOP SLAVE SQL_THREAD;
-- 恢复复制
START SLAVE;
-- 恢复特定线程
START SLAVE IO_THREAD;
START SLAVE SQL_THREAD;重置复制
sql
-- 重置从库复制信息
RESET SLAVE;
-- 重置从库所有复制信息,包括 GTID
RESET SLAVE ALL;
-- 重置主库二进制日志
RESET MASTER;跳过错误
sql
-- 跳过一个错误
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE SQL_THREAD;
-- 通过配置文件跳过特定错误
slave_skip_errors = 1062,1032主从复制常见问题及解决方案
复制延迟
原因:
- 从库硬件性能不足
- 主库写入压力过大
- 从库有长时间运行的查询
- 网络延迟
- 并行复制配置不当
解决方案:
- 升级从库硬件
- 优化主库写入性能
- 避免在从库执行长时间查询
- 优化网络连接
- 调整
slave_parallel_workers参数 - 使用半同步或异步复制
复制错误
常见错误代码:
- 1062:主键冲突
- 1032:找不到记录
- 1146:表不存在
- 1007:数据库已存在
解决方案:
- 检查数据一致性
- 修复数据冲突
- 跳过错误(生产环境谨慎使用)
- 重新同步数据
从库 I/O 线程错误
原因:
- 主库连接信息错误
- 复制用户权限问题
- 主库二进制日志文件不存在
- 网络连接问题
解决方案:
- 检查主库连接信息
- 验证复制用户权限
- 检查主库二进制日志文件
- 测试网络连接
从库 SQL 线程错误
原因:
- 数据不一致
- 表结构不一致
- 权限问题
- 存储引擎不兼容
解决方案:
- 检查数据一致性
- 修复表结构
- 验证权限
- 确保存储引擎兼容
主从复制最佳实践
配置最佳实践
- 使用 row 格式:提高复制可靠性和一致性
- 启用中继日志自动恢复:减少复制故障恢复时间
- 设置合理的二进制日志保留时间:避免磁盘空间耗尽
- 从库设置只读:提高安全性,防止误写入
- 使用并行复制:提高从库复制速度
部署最佳实践
- 主从库版本一致:避免版本差异导致的兼容性问题
- 主从库配置一致:确保相同的字符集、时区等配置
- 使用独立的复制用户:提高安全性,便于权限管理
- 定期备份主库和从库:确保数据安全
- 测试复制功能:定期测试主从复制是否正常
监控最佳实践
监控复制状态:
- 复制线程运行状态
- 复制延迟
- 二进制日志和中继日志状态
监控工具:
- MySQL Enterprise Monitor
- Prometheus + Grafana
- Zabbix
- 自定义脚本
维护最佳实践
定期检查数据一致性:
- 使用
pt-table-checksum工具 - 使用
mysqldiff工具比较表结构
- 使用
定期清理二进制日志和中继日志:
- 设置合理的保留时间
- 定期手动清理旧日志
定期更换复制用户密码:提高安全性
主从复制升级
从传统复制升级到 GTID 复制
升级步骤:
- 确保主从库版本支持 GTID
- 配置 GTID 参数
- 逐步启用 GTID 模式
- 切换到 GTID 复制
具体操作:
sql-- 主从库都执行 SET GLOBAL gtid_mode = OFF_PERMISSIVE; SET GLOBAL enforce_gtid_consistency = WARN; SET GLOBAL enforce_gtid_consistency = ON; SET GLOBAL gtid_mode = ON_PERMISSIVE; -- 等待所有事务完成 -- 检查没有使用传统复制的事务 SELECT COUNT(*) FROM performance_schema.replication_applier_status WHERE CHANNEL_NAME = ''; -- 主从库都执行 SET GLOBAL gtid_mode = ON; -- 从库执行 STOP SLAVE; CHANGE MASTER TO MASTER_AUTO_POSITION = 1; START SLAVE;
升级 MySQL 版本
升级顺序:
- 先升级从库
- 测试从库功能正常
- 升级主库
- 验证主从复制正常
注意事项:
- 备份所有数据和配置
- 测试升级后的功能
- 准备回滚计划
- 监控升级过程
常见问题(FAQ)
Q1: 主从复制可以跨版本吗?
A1: 可以,但需要注意版本兼容性:
- 从库版本可以高于主库,但不建议低于主库
- 版本差异应在一个主版本内(如 5.7 → 8.0 可能需要特殊处理)
- 跨版本复制可能存在功能差异和性能问题
- 建议使用相同版本的主从库
Q2: 如何解决主从复制延迟问题?
A2: 可以通过以下方式解决:
- 升级从库硬件,尤其是 CPU 和磁盘
- 优化主库写入性能,如使用批量写入
- 避免在从库执行长时间查询
- 调整并行复制参数
slave_parallel_workers - 使用 SSD 磁盘提高 I/O 性能
- 考虑使用半同步或异步复制
Q3: 主从复制中的数据一致性如何保证?
A3: 可以通过以下方式保证数据一致性:
- 使用
row格式的二进制日志 - 启用 GTID 复制
- 定期使用
pt-table-checksum工具检查数据一致性 - 使用半同步或全同步复制
- 避免在从库手动修改数据
Q4: 如何添加新的从库到现有复制架构?
A4: 可以通过以下步骤添加新从库:
- 配置新从库的
server_id和其他参数 - 从主库或现有从库备份数据
- 恢复数据到新从库
- 配置新从库连接主库
- 启动复制并验证状态
Q5: 主库故障时如何切换到从库?
A5: 可以通过以下步骤切换:
- 停止应用程序写入主库
- 等待从库追上主库(复制延迟为 0)
- 检查从库数据一致性
- 将从库提升为主库
- 更新应用程序连接到新主库
- 配置其他从库连接到新主库
Q6: 如何监控主从复制状态?
A6: 可以通过以下方式监控:
- 使用
SHOW SLAVE STATUS命令查看复制状态 - 使用 MySQL Enterprise Monitor 进行专业监控
- 使用 Prometheus + Grafana 进行可视化监控
- 使用 Zabbix 监控复制线程状态和延迟
- 编写自定义脚本定期检查复制状态,发送告警
