异步复制与半同步复制
1. 复制模式
1.1 异步复制
ini
# 主库
server-id = 1
log-bin = mysql-bin
binlog_format = ROW
# 从库
server-id = 2
relay-log = relay-bin
read_only = ONsql
-- 从库配置
CHANGE MASTER TO
MASTER_HOST='192.168.1.100',
MASTER_USER='repl',
MASTER_PASSWORD='secret',
MASTER_AUTO_POSITION=1;
START SLAVE;
SHOW SLAVE STATUS\G1.2 半同步复制
sql
-- 主库
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled = 1;
-- 从库
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
SET GLOBAL rpl_semi_sync_slave_enabled = 1;2. 复制原理与延迟处理
2.1 延迟问题
sql
-- 查看从库延迟
SHOW SLAVE STATUS\G
-- Seconds_Behind_Master2.2 复制原理详解
复制的数据来源是 Binlog,其记录格式与事件类型见 Binlog。
txt
主库:
1. 事务提交 → 写入 Binlog
2. Binlog Dump Thread 发送 Binlog 事件给从库
从库:
1. IO Thread 接收 Binlog 事件 → 写入 Relay Log
2. SQL Thread 读取 Relay Log → 重放 SQL/行变更
MySQL 8.0.26+ 改名:
- Binlog Dump Thread → Binlog Dump Thread
- IO Thread → Replica IO Thread
- SQL Thread → Replica SQL Thread2.3 复制延迟排查
sql
-- 查看从库延迟
SHOW REPLICA STATUS\G
-- Seconds_Behind_Source: 延迟秒数
-- Replica_SQL_Running: SQL 线程是否运行
-- Replica_IO_Running: IO 线程是否运行
-- 延迟原因排查:
-- 1. 主库大事务
SELECT * FROM information_schema.innodb_trx ORDER BY trx_started ASC;
-- 2. 从库单线程回放(MySQL 5.7 之前)
-- 解决:开启多线程复制
SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK';
SET GLOBAL slave_parallel_workers = 8;
-- 3. 从库硬件性能不足
-- 4. 网络延迟2.4 多线程复制
sql
-- MySQL 5.7+ 支持基于 LOGICAL_CLOCK 的多线程复制
-- 查看当前并行复制配置
SHOW VARIABLES LIKE 'slave_parallel_type'; -- DATABASE / LOGICAL_CLOCK
SHOW VARIABLES LIKE 'slave_parallel_workers'; -- 默认 0(单线程)
-- 启用多线程复制
STOP REPLICA;
SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK';
SET GLOBAL slave_parallel_workers = 8;
SET GLOBAL slave_preserve_commit_order = ON; -- 保证提交顺序
START REPLICA;
-- MySQL 8.0.27+ 支持写集(Write Set)并行复制
SET GLOBAL binlog_transaction_dependency_tracking = 'WRITESET';3. 过滤与监控
3.1 复制过滤
sql
-- 主库端过滤(不推荐,会丢失数据)
# my.cnf
binlog-do-db = mydb -- 只记录指定库
binlog-ignore-db = test -- 忽略指定库
-- 从库端过滤(推荐)
# my.cnf
replicate-do-db = mydb -- 只复制指定库
replicate-ignore-db = test -- 忽略指定库
replicate-do-table = mydb.users -- 只复制指定表
replicate-wild-do-table = mydb.log_% -- 通配符匹配
-- 动态设置(MySQL 8.0.26+)
STOP REPLICA;
CHANGE REPLICATION FILTER REPLICATE_DO_DB = (mydb, mydb2);
START REPLICA;3.2 复制监控
sql
-- 监控复制状态
SHOW REPLICA STATUS\G
-- 监控复制延迟
SELECT
TIMESTAMPDIFF(SECOND, MAX(COMMIT_TIMESTAMP), NOW()) AS delay_seconds
FROM performance_schema.replication_applier_status_by_worker;
-- 监控复制错误
SELECT * FROM performance_schema.replication_applier_status_by_worker
WHERE LAST_ERROR_NUMBER != 0;
-- 跳过错误(谨慎使用)
STOP REPLICA;
SET GLOBAL sql_replica_skip_counter = 1;
START REPLICA;4. 最佳实践
- 使用 ROW 格式 Binlog — 数据一致性最好
- 开启多线程复制 — 减少从库延迟
- 监控复制延迟 — 设置告警阈值
- 从库设置 read_only — 防止误写
- 定期检查复制一致性 — 使用 pt-table-checksum
- 主从切换使用 GTID — 简化切换流程