MySQL 主从复制全面指南
1. MySQL主从复制概述
MySQL主从复制是MySQL数据库提供的一种重要功能,它允许将一个数据库服务器(主库)的数据实时复制到一个或多个数据库服务器(从库)上。主从复制是构建高可用、高性能MySQL架构的基础技术。
1.1 主从复制的作用
- 读写分离:主库负责写入操作,从库负责读取操作,分散数据库访问压力
- 数据备份:从库作为主库的实时备份,提高数据安全性
- 高可用性:当主库出现故障时,可以快速切换到从库,保证服务持续运行
- 数据分析:可以在从库上进行数据分析、报表生成等操作,不影响主库性能
2. MySQL主从复制原理
2.1 基本原理
MySQL主从复制基于二进制日志(binlog)实现,整个复制过程涉及三个线程:
-
Binlog dump线程(主库):当从库连接到主库时,主库会创建一个binlog dump线程,用于读取主库上的二进制日志,并发送给从库
-
I/O线程(从库):负责连接主库,接收主库发送的二进制日志,并将其写入本地的中继日志(relay log)
-
SQL线程(从库):负责读取中继日志中的事件,并在从库上重放这些事件,使从库的数据与主库保持一致
2.2 复制过程
-
写入binlog:主库在执行事务时,会将所有的数据变更记录到二进制日志(binlog)中
-
同步binlog:从库的I/O线程连接到主库,请求获取二进制日志,主库的binlog dump线程读取二进制日志并发送给从库
-
写入relay log:从库的I/O线程将接收到的二进制日志写入本地的中继日志(relay log)
-
回放relay log:从库的SQL线程读取中继日志中的事件,并在从库上执行这些事件,使从库的数据与主库保持一致
3. MySQL主从复制模式
3.1 按拓扑结构分类
3.1.1 一主一从
最简单的主从复制结构,一个主库对应一个从库。适用于小型应用或作为更复杂架构的基础。
3.1.2 一主多从
一个主库对应多个从库。主库负责所有的写操作,多个从库分担读操作,提高系统的读性能和可用性。
3.1.3 双主复制(主主复制)
两个服务器互为主从,每个服务器既是主库也是从库。这种结构提供了更高的可用性,但需要解决数据冲突问题。
3.1.4 级联复制
从库可以作为其他从库的主库,形成一个复制链。这种结构可以减轻主库的复制压力,但会增加数据延迟。
3.2 按同步方式分类
3.2.1 异步复制(Asynchronous Replication)
- 原理:主库执行完事务后立即返回给客户端,不等待从库的响应
- 优点:性能高,主库写入速度不受从库影响
- 缺点:无法保证数据一致性,主库宕机可能导致数据丢失
- 适用场景:对数据一致性要求不高,但对性能要求较高的应用
3.2.2 半同步复制(Semi-synchronous Replication)
- 原理:主库执行完事务后,至少等待一个从库接收并写入relay log后才返回给客户端
- 优点:提高了数据安全性,降低了数据丢失的风险
- 缺点:相比异步复制,性能略有下降
- 适用场景:对数据一致性和性能都有一定要求的应用
3.2.3 全同步复制(Synchronous Replication)
- 原理:主库执行完事务后,必须等待所有从库执行完成才返回给客户端
- 优点:保证了数据的强一致性
- 缺点:性能较低,从库故障会影响主库可用性
- 适用场景:对数据一致性要求极高的金融、支付等关键业务
3.3 按复制格式分类
3.3.1 基于语句的复制(Statement-based Replication,SBR)
- 原理:记录修改数据的SQL语句,在从库上重新执行
- 优点:日志量小,节省带宽
- 缺点:某些函数和触发器可能导致主从不一致
3.3.2 基于行的复制(Row-based Replication,RBR)
- 原理:记录行数据的变化,在从库上重放这些变化
- 优点:保证数据一致性,支持所有SQL语句
- 缺点:日志量大,占用带宽
3.3.3 混合复制(Mixed Replication)
- 原理:默认使用基于语句的复制,在某些情况下自动切换到基于行的复制
- 优点:结合了SBR和RBR的优点
- 缺点:复杂度增加
4. GTID复制模式
4.1 GTID概述
GTID(Global Transaction ID) 是 MySQL 5.6 及以上版本引入的一种全局事务标识机制,用于在数据库集群中唯一标识每个事务,GTID由两部分组成:源服务器ID(UUID)和事务ID,格式为 server_uuid:transaction_id
。
GTID 的主要作用包括:
- 事务追踪与一致性保障:通过为每个事务分配唯一标识,GTID 确保事务在主从复制中不会被重复执行或丢失,从而提高数据一致性。
- 简化复制管理:GTID 允许从库自动定位复制起点(通过
MASTER_AUTO_POSITION=1
),无需手动指定 binlog 文件和位置,降低了配置复杂度。 - 支持故障恢复与主从切换:在故障恢复或主从切换场景中,GTID 能够快速确定事务执行状态,帮助实现无缝切换和数据同步。
- 支持多主复制与组复制:GTID 是 MySQL Group Replication 等全同步复制模式的基础,确保分布式环境中事务的正确管理和冲突检测。
4.2 GTID复制的优势
- 简化故障转移:从库可以自动找到正确的复制位置,无需手动指定binlog文件和位置
- 简化主从搭建:不需要确定binlog位置,直接使用GTID即可
- 提高数据一致性:可以确保每个事务只被应用一次
- 方便复制监控:可以清晰地知道哪些事务已经被复制
4.3 GTID复制的工作原理
- 主库为每个事务生成一个全局唯一的GTID
- 主库将事务和GTID一起写入binlog
- 从库接收到binlog后,提取GTID和事务内容
- 从库检查GTID是否已经执行过,如果已执行则跳过,否则执行该事务
- 从库记录已执行的GTID集合
5. MySQL主从复制配置
5.1 前提条件
- 两台或多台MySQL服务器
- 主库和从库的MySQL版本兼容
- 网络连通性良好
- 主库开启二进制日志
5.2 主库配置
- 修改主库的配置文件(my.cnf):
[mysqld]
# 服务器唯一ID
server-id = 1
# 开启二进制日志
log-bin = mysql-bin
# 二进制日志格式(推荐ROW格式)
binlog_format = ROW
# 指定需要复制的数据库(可选)
# 生产环境建议禁用,主库记录所有变更
# binlog-do-db = db_name
# 指定不需要复制的数据库(可选)
# binlog-ignore-db = db_name
- 重启MySQL服务:
sudo systemctl restart mysql
- 创建用于复制的用户:
CREATE USER 'repl'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
- 获取主库状态信息:
SHOW MASTER STATUS;
记录下File和Position的值,后续在从库配置中需要使用。
5.3 从库配置
- 修改从库的配置文件(my.cnf):
[mysqld]
# 服务器唯一ID(必须与主库不同)
server-id = 2
# 开启中继日志(可选)
relay-log = relay-bin
# 指定需要复制的数据库(可选)
# replicate-do-db = db_name
# 指定不需要复制的数据库(可选)
# replicate-ignore-db = db_name
- 重启MySQL服务:
sudo systemctl restart mysql
- 配置从库连接到主库:
CHANGE MASTER TO
MASTER_HOST='主库IP',
MASTER_PORT=3306,
MASTER_USER='repl',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000001', -- 使用主库状态中的File值
MASTER_LOG_POS=123; -- 使用主库状态中的Position值
- 启动从库复制进程:
START SLAVE;
- 检查从库状态:
SHOW SLAVE STATUS\G
确保Slave_IO_Running和Slave_SQL_Running都是Yes。
5.4 GTID复制配置
- 主库配置(my.cnf):
[mysqld]
server-id = 1
log-bin = mysql-bin
binlog_format = ROW
# 启用GTID
gtid_mode = ON
enforce_gtid_consistency = ON
log_slave_updates = ON
- 从库配置(my.cnf):
[mysqld]
server-id = 2
# 启用GTID
gtid_mode = ON
enforce_gtid_consistency = ON
log_slave_updates = ON
- 在从库上配置复制:
CHANGE MASTER TO
MASTER_HOST='主库IP',
MASTER_PORT=3306,
MASTER_USER='repl',
MASTER_PASSWORD='password',
MASTER_AUTO_POSITION = 1; -- 使用GTID自动定位
6. 多线程复制配置
MySQL 5.7引入了增强型多线程复制(Enhanced Multi-threaded Slave),可以大幅提高从库的复制性能,减少主从延迟。
6.1 多线程复制类型
MySQL 5.7支持两种多线程复制类型:
- DATABASE:基于库的并行复制,每个数据库对应一个复制线程(MySQL 5.6引入)
- LOGICAL_CLOCK:基于组提交的并行复制,同一个数据库下可以有多个线程并行执行(MySQL 5.7引入,推荐使用)
6.2 多线程复制配置
在从库上配置多线程复制:
-- 停止从库复制
STOP SLAVE;
-- 设置复制类型为LOGICAL_CLOCK(基于组提交的并行复制)
SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK';
-- 设置并行工作线程数(建议设置为CPU核心数)
SET GLOBAL slave_parallel_workers = 8;
-- 启动从库复制
START SLAVE;
6.3 多线程复制的持久化配置
在从库的my.cnf文件中添加以下配置:
[mysqld]
# 设置复制类型为LOGICAL_CLOCK
slave_parallel_type = LOGICAL_CLOCK
# 设置并行工作线程数(建议设置为CPU核心数)
slave_parallel_workers = 8
# 将master.info和relay.info保存在表中
master_info_repository = TABLE
relay_log_info_repository = TABLE
# 从库宕机后自动放弃损坏的relay-log,并重新从master上获取二进制日志
# 这样能保证relay-log的完整性,该功能默认是关闭的,建议开启
relay_log_recovery = ON
# 保证事务提交顺序
slave_preserve_commit_order = ON
7. 主从复制监控与延迟处理
7.1 主从延迟的原因
- 网络延迟:主从服务器之间的网络延迟
- 从库性能问题:从库的硬件配置比主库差
- 从库负载过高:从库上有大量查询操作
- 大事务执行:主库上执行了大事务,从库需要更多时间处理
- 单线程复制限制:MySQL 5.6之前的单线程复制模式效率低下
- 无主键或索引不合理:从库上的表缺少主键或索引不合理,导致回放效率低
7.2 监控主从延迟
- 使用Seconds_Behind_Master参数:
SHOW SLAVE STATUS\G
查看输出中的Seconds_Behind_Master值,该值表示从库与主库的延迟秒数:
- 0:表示无延迟
- NULL:表示从库的IO线程或SQL线程出现问题
- 大于0:表示存在延迟,值越大延迟越严重
- 比较二进制日志位置:
比较主库的当前二进制日志文件和位置与从库的Master_Log_File和Read_Master_Log_Pos,判断是否存在差异。
- 使用pt-heartbeat工具:
Percona Toolkit中的pt-heartbeat工具可以更准确地监控主从延迟。
7.3 减少主从延迟的方法
-
优化网络环境:确保主从服务器之间的网络连接稳定、延迟低
-
提升从库硬件配置:为从库配置更好的硬件,特别是CPU、内存和磁盘I/O
-
使用多线程复制:在MySQL 5.7及以上版本中启用多线程复制
-
优化SQL和索引:确保表有主键,优化索引结构,避免慢查询
-
避免大事务:将大事务拆分为小事务,或在业务低峰期执行
- 调整从库参数:
- 关闭从库的二进制日志(如果不需要)
- 调整innodb_flush_log_at_trx_commit和sync_binlog参数
- 使用SSD存储:使用SSD可以显著提高I/O性能
8. 主从复制的数据一致性保障
8.1 数据一致性问题
主从复制中的数据一致性问题主要来自两个方面:
- 主库日志写入不成功:导致从库无法获取完整的变更日志
- 从库回放失败:从库在应用主库日志时出现错误
8.2 提高主库数据安全性
配置主库参数以确保数据和日志的安全:
[mysqld]
# 开启InnoDB双写缓冲区,防止部分页写入
innodb_doublewrite = ON
# 支持两阶段提交
innodb_support_xa = ON
# 每次事务提交都刷新日志到磁盘
innodb_flush_log_at_trx_commit = 1
# 每次事务提交都刷新binlog到磁盘
sync_binlog = 1
这些参数开启后可以显著提升数据一致性和持久性,但是以性能为代价,适合对数据完整性要求极高的生产环境。如果在高并发场景下遇到性能问题,可以根据业务需求适当调整,并在调整前做好测试和监控。
8.3 复制模式选择
根据业务对数据一致性的要求,选择合适的复制模式:
- 异步复制:适用于对性能要求高,对数据一致性要求不严格的场景
- 半同步复制:适用于对数据一致性和性能都有要求的场景
- 配置参数:
rpl_semi_sync_master_enabled = 1
和rpl_semi_sync_slave_enabled = 1
- 设置等待点:
rpl_semi_sync_master_wait_point = AFTER_SYNC
(MySQL 5.7)
- 配置参数:
- 组复制(Group Replication):适用于对数据一致性要求极高的场景
- MySQL 5.7.17及以上版本支持
- 基于XCom协议(Paxos变种)实现的分布式一致性技术
- 支持单主和多主两种复制模式
- 提供自动故障检测、成员管理和脑裂保护等企业级特性
9. 主从复制的故障处理
9.1 常见故障类型
- 从库IO线程故障:无法从主库获取二进制日志
- 从库SQL线程故障:无法正确应用中继日志
- 主库故障:主库服务不可用
- 数据不一致:主从数据出现差异
9.2 故障排查与修复
- IO线程故障:
- 检查网络连接
- 验证复制用户权限
- 查看主库二进制日志是否存在
- SQL线程故障:
- 查看错误日志
- 跳过错误事务:
SET GLOBAL sql_slave_skip_counter = 1; START SLAVE;
- 修复数据不一致
- 主库故障:
- 将从库提升为主库
- 重新配置其他从库连接到新主库
9.3 主从切换
- 计划内切换:
- 停止主库写入
- 等待从库完全同步
- 将从库提升为主库
- 重新配置应用连接
- 故障切换:
- 确认主库不可用
- 选择延迟最小的从库作为新主库
- 提升从库为主库
- 重新配置应用连接
- 恢复原主库作为从库
10. 主从复制最佳实践
10.1 架构设计
- 合理规划服务器数量:根据业务需求和预算确定主从服务器数量
- 考虑地理分布:跨地域部署可提高灾备能力,但会增加网络延迟
- 使用负载均衡:在多个从库之间分配读请求
10.2 配置优化
- 使用GTID复制:简化故障恢复和主从搭建
- 启用多线程复制:提高从库复制性能
- 合理设置二进制日志格式:推荐使用ROW格式
- 定期清理二进制日志:避免磁盘空间耗尽
10.3 监控与维护
- 建立完善的监控系统:监控主从状态、复制延迟、服务器资源等
- 定期备份:即使有从库作为备份,也应定期进行全量备份
- 定期检查数据一致性:使用工具验证主从数据一致性
- 演练故障恢复:定期进行主从切换演练
10.4 安全性考虑
- 使用SSL加密复制连接:保护数据传输安全
- 限制复制用户权限:只授予必要的权限
- 设置防火墙规则:限制对MySQL端口的访问
总结
MySQL主从复制是构建高可用、高性能数据库架构的重要技术。通过合理配置和优化,可以实现读写分离、数据备份和故障转移等功能。随着MySQL版本的发展,GTID复制和多线程复制等新特性使主从复制更加强大和易用。在实际应用中,应根据业务需求选择合适的复制模式和配置,并建立完善的监控和维护机制,确保主从复制的稳定运行。