一、MySQL复制概述:为什么需要它?
MySQL复制是官方提供的核心高可用与扩展解决方案,通过将数据从一个源(Source) 服务器同步到一个或多个副本(Replica) 服务器,实现数据的冗余与分流。
复制的核心价值:
-
高可用:数据多副本存储,单点故障时可通过切换副本恢复服务。
-
性能扩展 :实现读写分离,将读请求分发到副本节点,提升整体并发处理能力。
-
异地灾备:将副本部署在异地机房,提供数据级别的容灾能力。
-
业务隔离:将分析报表、数据备份等低频重负载任务分流到副本,避免影响核心OLTP事务。
重要术语更新 :自MySQL 8.0起,官方推荐使用 Source/Replica 替代旧版的 Master/Slave。
二、复制的心脏:二进制日志(Binlog)
所有的复制都基于一个核心------Binlog。它记录了所有对数据库的修改事件(Event),是数据同步的源泉。
-- 查看Binlog文件列表
SHOW BINARY LOGS;
-- 查看具体Binlog事件内容
SHOW BINLOG EVENTS IN 'mysql-bin.000001';
复制的两种数据同步方式
-
基于Binlog位点(File & Position):传统方式,需手动指定日志文件和位置。
-
基于全局事务标识符(GTID):现代方式,通过唯一事务ID自动定位,是未来主流。
三、复制类型详解:从异步到半同步
1. 异步复制(默认)
这是MySQL默认的复制方式,其核心是 "先提交,后复制"。
工作流程:
-
主库写入Binlog并提交事务。
-
立即向客户端返回成功。
-
一个异步线程将Binlog发送给从库,从库写入中继日志(Relay Log)后应用。
优点 :性能最佳,对主库影响最小。
缺点 :存在主从延迟。若主库在Binlog发送前宕机,存在数据丢失风险(非持久化)。
2. 半同步复制
MySQL 5.7+引入,核心是 "等待至少一个从库确认后再返回"。
工作流程:
-
主库写入Binlog。
-
等待至少一个从库将事务事件写入其中继日志并刷盘后,返回ACK确认。
-
主库收到ACK后,才提交事务并向客户端返回成功。
关键参数:
-
rpl_semi_sync_source_wait_for_replica_count: 需要等待的从库数量(默认1)。 -
rpl_semi_sync_source_wait_point:-
AFTER_SYNC(默认): 先等复制,再提交。数据安全,推荐。 -
AFTER_COMMIT: 先提交,再等复制。存在不一致窗口。
-
优点 :显著提升数据安全性,确保事务在至少一个从库持久化。
缺点 :增加网络往返和磁盘IO的耗时,响应时间变长。若从库无响应,会退化为异步复制。
四、GTID复制:运维自动化的飞跃
基于文件位点的复制在搭建和维护时极其繁琐(找位点、设位点、跳错误)。GTID(Global Transaction Identifier)彻底解决了这个痛点。
什么是GTID?
一个全局唯一的事务ID,格式为:source_id:transaction_id
-
source_id: 源服务器的server_uuid。 -
transaction_id: 事务序列号,单调递增。
例如:3E11FA47-71CA-11E1-9E33-C80AA9429562:23
GTID的核心优势
-
自动化故障转移 :无需再找
MASTER_LOG_FILE和MASTER_LOG_POS。 -
搭建简便 :从库只需知道源服务器信息,通过
SOURCE_AUTO_POSITION=1自动同步。 -
一致性保障:GTID具有全局唯一性,同一事务不会在不同服务器上重复执行。
-
数据零丢失(结合半同步):GTID连续无空洞,易于验证数据一致性。
GTID工作原理
从库连接主库后,会将自己的已执行GTID集合发送给主库。主库计算 "主库GTID集合 - 从库GTID集合" 的差集,然后仅发送差集对应的Binlog给从库。这个过程完全自动,无需人工干预。
配置核心:
# 主从配置文件均需添加
[mysqld]
gtid_mode = ON
enforce_gtid_consistency = ON
从库连接命令:
-- MySQL 8.0.23+
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='192.168.1.100',
SOURCE_USER='repl_user',
SOURCE_PASSWORD='password',
SOURCE_PORT=3306,
SOURCE_AUTO_POSITION = 1; -- 关键!
五、实战:基于Docker搭建异步主从复制(位点)
1. 环境规划
| 角色 | 容器名 | 服务器ID | 宿主机端口 | Docker网络IP |
|---|---|---|---|---|
| 源 | mysql-source |
10 | 3307 | 自动分配 |
| 副本1 | mysql-replica1 |
11 | 3308 | 自动分配 |
| 副本2 | mysql-replica2 |
12 | 3309 | 自动分配 |
2. 关键配置(以源为例)
/mysql/replication/source/conf/custom.cnf:
[mysqld]
server-id = 10 # 必须唯一
log-bin = mysql-bin # 开启Binlog
副本只需修改 server-id 为 11 和 12。
3. 核心操作步骤
-- 1. 在源库创建复制专用用户
CREATE USER 'fox'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'fox'@'%';
FLUSH PRIVILEGES;
-- 2. 查看源库当前Binlog状态
SHOW MASTER STATUS;
-- 记下 File (mysql-bin.000003) 和 Position (1273)
-- 3. 在从库上配置主从关系 (MySQL 8.0.23+语法)
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='192.168.65.185',
SOURCE_PORT=3307,
SOURCE_USER='fox',
SOURCE_PASSWORD='123456',
SOURCE_LOG_FILE='mysql-bin.000003', -- 上一步的File
SOURCE_LOG_POS=1273; -- 上一步的Position
-- 4. 启动从库复制线程
START REPLICA; -- 或 START SLAVE;
-- 5. 检查从库状态
SHOW REPLICA STATUS\G
-- 关键指标: `Replica_IO_Running: Yes`, `Replica_SQL_Running: Yes`
六、GTID实战与故障处理
1. 启用GTID
在原有异步复制基础上,修改配置文件并重启所有实例:
[mysqld]
gtid_mode = ON
enforce_gtid_consistency = ON
重启后,从库重新配置并启用自动定位:
STOP REPLICA;
CHANGE REPLICATION SOURCE TO ... SOURCE_AUTO_POSITION=1; -- 关键变化
START REPLICA;
2. GTID复制中断的经典修复案例
场景:从库误删表,主库继续写入导致复制因"表不存在"错误而中断。
修复步骤 (无需重做整个实例):
-- 1. 停止从库复制
STOP REPLICA;
-- 2. 手动“空执行”导致中断的那个GTID事务(跳过它)
-- 假设错误的GTID是 `aac92b21...:7`
SET @@SESSION.GTID_NEXT = 'aac92b21-b6a4-11ee-bab5-0242ac120002:7';
BEGIN; COMMIT; -- 执行一个空事务,使该GTID在从库被标记为“已执行”
SET SESSION GTID_NEXT = AUTOMATIC; -- 恢复自动分配
-- 3. 手动从主库同步缺失的表结构及数据(可通过mysqldump或手动操作)
-- 4. 重新启动复制
START REPLICA;
此方法精准跳过特定错误事务,是GTID相比位点复制的巨大运维优势。
七、组复制(MGR):迈向真正的集群化
MySQL Group Replication (MGR) 是基于Paxos分布式协议的官方集群方案,实现了数据强一致性和自动故障转移。
MGR vs 传统主从复制
| 特性 | 传统主从 | MGR |
|---|---|---|
| 一致性 | 最终一致 (异步) / 半同步 | 强一致,基于Paxos多写确认 |
| 高可用 | 需外部工具手动切换 | 自动选主,多数派存活即可服务 |
| 写节点 | 单主(或手动切换多主) | 支持单主和多主模式 |
| 故障检测 | 弱 | 内置,快速 |
MGR单主模式部署核心配置
每个节点的 custom.cnf 需包含以下核心参数:
[mysqld]
# 基础
server_id = 1 # 各节点不同
gtid_mode = ON
enforce_gtid_consistency = ON
log_bin = mysql-bin
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
# MGR核心
plugin_load_add='group_replication.so'
group_replication_group_name="117dc7ea-b9bd-11ee-9bdb-0242ac120002" # UUID,集群内相同
group_replication_start_on_boot=off
group_replication_local_address= "mgr-node1:33061" # 内部通信地址,各节点不同
group_replication_group_seeds="mgr-node1:33061,mgr-node2:33061,mgr-node3:33061"
group_replication_bootstrap_group=off
引导与加入集群
-- 在第一个节点(引导节点)执行
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
-- 在其他节点执行,加入集群
-- 先配置好复制用户和恢复通道
CHANGE REPLICATION SOURCE TO SOURCE_USER='fox', SOURCE_PASSWORD='123456' FOR CHANNEL 'group_replication_recovery';
-- 然后启动组复制
START GROUP_REPLICATION;
查看集群状态:
SELECT MEMBER_HOST, MEMBER_ROLE, MEMBER_STATE
FROM performance_schema.replication_group_members;
八、总结与选型建议
| 方案 | 数据一致性 | 性能 | 可用性 | 复杂度 | 适用场景 |
|---|---|---|---|---|---|
| 异步复制 | 最终一致 | ★★★★★ | ★★☆ | ★☆☆ | 读扩展、非核心业务备份 |
| 半同步复制 | 强一致(单从库) | ★★★☆☆ | ★★★☆ | ★★☆☆ | 通用业务,平衡安全与性能 |
| GTID复制 | 同异步/半同步 | 同异步/半同步 | 同异步/半同步 | ★★★★☆ | 所有生产环境推荐,大幅简化运维 |
| MGR单主 | 强一致 | ★★★☆☆ | ★★★★★ | ★★★★☆ | 金融级高可用,替代传统主从 |
| MGR多主 | 强一致(冲突检测) | ★★☆☆☆ (写冲突) | ★★★★★ | ★★★★★ | 多活写入,全球化部署 |
演进路线建议:
-
新项目 :直接使用 MySQL 8.0 + GTID + 半同步复制。
-
高可用升级 :在GTID半同步基础上,评估并切换到 MGR单主模式。
-
多活需求 :在充分测试冲突解决机制后,考虑 MGR多主模式。