主从复制
约 1065 字大约 4 分钟
布欧-Lewyon
2026-05-15
首页 › MySQL › 运维与部署(在新窗口打开) › 主从复制
主从复制(Replication)是 MySQL 高可用的基石:主库(Master/Primary)处理写入,从库(Slave/Replica)同步数据并使读请求。
复制原理
- 主库将数据变更写入 Binary Log(binlog)。
- 从库的 I/O Thread 连接主库,请求 binlog,写入自己的 Relay Log。
- 从库的 SQL Thread 读取 Relay Log 并重放 SQL。
binlog 格式
| 格式 | 说明 | 适用场景 |
|---|---|---|
STATEMENT | 记录 SQL 语句 | 非确定性函数(如 NOW())会不一致 |
ROW(推荐) | 记录行变更(安全但空间大) | 大多数场景 |
MIXED | 混合模式 | 自动选择 |
生产推荐
binlog_format = ROW。恢复和同步最精确。
搭建主从复制
主库配置
[mysqld]
server_id = 1 # 唯一 ID,不能与从库重复
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW
expire_logs_days = 7 # binlog 保留 7 天-- 创建复制账号
CREATE USER 'repl'@'192.168.1.%' IDENTIFIED BY 'repl_password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.%';
-- 查看主库状态(记录 File 和 Position)
SHOW MASTER STATUS;
-- File: mysql-bin.000003, Position: 154从库配置
[mysqld]
server_id = 2 # 必须与主库不同
relay_log = /var/log/mysql/mysql-relay-bin.log
read_only = 1 # 防止应用误写入从库-- 如果从库已有数据,先用主库的全量备份恢复
-- 然后配置复制
CHANGE REPLICATION SOURCE TO -- MySQL 8.4 语法(MySQL 8.0 用 CHANGE MASTER TO)
SOURCE_HOST = '192.168.1.10',
SOURCE_PORT = 3306,
SOURCE_USER = 'repl',
SOURCE_PASSWORD = 'repl_password',
SOURCE_LOG_FILE = 'mysql-bin.000003',
SOURCE_LOG_POS = 154;
-- 启动复制
START REPLICA; -- MySQL 8.4 语法(8.0: START SLAVE)
-- 检查复制状态
SHOW REPLICA STATUS\G -- 8.4 语法
-- Slave_IO_Running: Yes
-- Slave_SQL_Running: Yes
-- Seconds_Behind_Master: 0查看复制状态
SHOW REPLICA STATUS\G关键字段:
| 字段 | 正常值 | 说明 |
|---|---|---|
Slave_IO_Running | Yes | I/O 线程是否运行 |
Slave_SQL_Running | Yes | SQL 线程是否运行 |
Seconds_Behind_Master | 0 | 从库延迟(秒),0 表示已同步 |
Last_IO_Error | 空 | I/O 线程错误信息 |
Last_SQL_Error | 空 | SQL 线程错误信息 |
Master_Log_File | — | 当前读取的主库 binlog 文件 |
Read_Master_Log_Pos | — | 当前读取的位置 |
GTID 复制
GTID(Global Transaction Identifier)为每个事务生成全局唯一 ID,简化复制配置和故障转移。
配置 GTID
[mysqld]
server_id = 1
gtid_mode = ON
enforce_gtid_consistency = ON # 保证 GTID 安全
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW-- 从库配置 GTID 复制
CHANGE REPLICATION SOURCE TO
SOURCE_HOST = '192.168.1.10',
SOURCE_USER = 'repl',
SOURCE_PASSWORD = 'repl_password',
SOURCE_AUTO_POSITION = 1; -- 使用 GTID 自动定位
START REPLICA;GTID 优势:
- 无需指定
LOG_FILE和LOG_POS,自动定位。 - 主从切换时更简单。
- 事务不丢失(每个事务全局唯一 ID)。
半同步复制
默认的异步复制中,主库不等待从库确认即返回。半同步复制保证至少一个从库收到 binlog 后主库才提交:
-- 主库安装半同步插件
INSTALL PLUGIN rpl_semi_sync_source
SONAME 'semisync_source.so';
-- 从库安装
INSTALL PLUGIN rpl_semi_sync_replica
SONAME 'semisync_replica.so';
-- 启用
SET GLOBAL rpl_semi_sync_source_enabled = ON;
SET GLOBAL rpl_semi_sync_replica_enabled = ON;[mysqld]
# 配置文件持久化
plugin-load = "rpl_semi_sync_source=semisync_source.so;rpl_semi_sync_replica=semisync_replica.so"
rpl_semi_sync_source_enabled = ON
rpl_semi_sync_replica_enabled = ON
rpl_semi_sync_source_timeout = 10000 # 超时 10s 后降级为异步常见问题
复制延迟
-- 检查延迟
SHOW REPLICA STATUS\G
-- Seconds_Behind_Master 如果持续增大,说明有延迟常见原因:
| 原因 | 解决 |
|---|---|
| 从库硬件比主库差 | 升级从库或增加从库 |
| 大事务(大量 UPDATE/DELETE) | 拆分大事务 |
| 从库只有单线程 SQL Thread | 开启并行复制(8.0+) |
| 主库写入量大 | 增加从库数量分担读负载 |
并行复制(8.0+):
[mysqld]
replica_parallel_workers = 4 # 并行复制线程数(8.4 语法)复制中断
-- 查看错误
SHOW REPLICA STATUS\G
-- Last_SQL_Error: Error 'Duplicate entry...' on query...
-- 常见原因:主键冲突、表不存在、从库被手动修改
-- 跳过单条错误(修复前请确认原因)
SET GLOBAL sql_slave_skip_counter = 1;
START REPLICA;
-- 使用 GTID 时,跳过事务
SHOW REPLICA STATUS\G -- 获取 Executed_Gtid_Set
-- 在从库上:
SET GTID_NEXT = 'xxxx-xxxx-xxxx:123';
BEGIN; COMMIT;
SET GTID_NEXT = 'AUTOMATIC';
START REPLICA;小结
- 主从复制:主库写 binlog → 从库 I/O 拉取 → Relay Log → SQL 重放。
SHOW REPLICA STATUS监控复制健康度:Slave_IO_Running/Slave_SQL_Running为 Yes,Seconds_Behind_Master为 0。- GTID 复制(
gtid_mode=ON)是推荐方案,简化运维和切换。 - 半同步复制在性能和一致性之间取得平衡,防止主库崩溃时丢失已提交事务。
- 复制延迟的常见原因:大事务、从库性能不足、单线程重放。
