主库必须开启binlog且设为row格式;新从库需基于一致gtid或binlog位点启动复制;server_id须全局唯一;mysqldump导出应加--set-gtid-purged=off;start slave后须检查io/sql线程状态及延迟。

主库必须开启 binlog 且设置为 ROW 格式
MySQL 动态加从库本质是让新从库拉取主库的 binlog 并重放,如果主库没开 binlog 或格式是 STATEMENT,后续复制会失败或数据不一致。
检查方式:SHOW VARIABLES LIKE 'log_bin'; 和 SHOW VARIABLES LIKE 'binlog_format';
-
log_bin必须为ON;若为OFF,需重启 mysqld 并在配置文件中添加log-bin = /var/lib/mysql/mysql-bin -
binlog_format推荐强制设为ROW(SET GLOBAL binlog_format = 'ROW';),尤其涉及非确定性函数、自增、触发器时,STATEMENT容易丢数据 - 注意:修改
binlog_format不影响已写入的 binlog,只对后续新事件生效
从库需要基于一致的 GTID 或 binlog 位置启动复制
“在线”不等于“无感知”,新从库必须从一个主库上存在的、未被 purge 的 binlog 位点开始同步,否则复制线程立即报错 Could not find first log file name in binary log index file 或 Client requested master to start replication from position > file size。
推荐用 GTID(MySQL 5.6+):主库执行 SHOW MASTER STATUS; 查看 Executed_Gtid_Set,从库用 CHANGE MASTER TO ... MASTER_AUTO_POSITION = 1;
- 若用传统 position 方式,必须先锁表
FLUSH TABLES WITH READ LOCK;,再记下File和Position,最后UNLOCK TABLES;—— 这个锁时间很短,但不是完全无锁 - GTID 模式下,主库
gtid_mode = ON和enforce_gtid_consistency = ON必须启用,否则START SLAVE会失败 - 新从库的
server_id必须全局唯一,且不能和主库或其他从库重复,否则复制无法启动
mysqldump 导出时要带 --set-gtid-purged=OFF 或 --skip-log-bin
直接 mysqldump 全量导出再导入到新从库是最常用方式,但默认行为会在 dump 文件开头写入 SET @@GLOBAL.GTID_PURGED,如果目标实例已有其他 GTID 集合,导入会失败并报错 Cannot add or update a child row: a foreign key constraint fails 或更常见的 GTID_PURGED can only be set when GTID_EXECUTED is empty。
- 安全做法:导出时加
--set-gtid-purged=OFF(适用于目标从库是全新实例) - 如果目标从库之前跑过复制,建议先
RESET MASTER;清空 GTID_EXECUTED,再导入;或者改用--skip-log-bin+--single-transaction组合避免锁表和 binlog 写入 - 别忘了加
--master-data=2(position 模式)或--set-gtid-purged=ON(GTID 模式且确认环境干净)—— 选哪个取决于你后续怎么配CHANGE MASTER
复制延迟与 IO/SQL 线程状态必须人工确认
执行 START SLAVE; 后,复制看似启动了,但实际是否正常工作,得看两个线程是否都在 Running 状态,以及 Seconds_Behind_Master 是否持续收敛。常见假成功现象:IO 线程 Running,SQL 线程 Waiting,说明中继日志里有不兼容语句(比如 DROP DATABASE 在从库不存在的库上执行)。
- 查状态用
SHOW SLAVE STATUS\G,重点关注Slave_IO_Running、Slave_SQL_Running、Seconds_Behind_Master、Retrieved_Gtid_Set和Executed_Gtid_Set是否在增长 - 如果 SQL 线程卡住,
Last_SQL_Error字段会明确告诉你哪条语句、哪个库、哪个表出问题,不要只看Seconds_Behind_Master: NULL就以为挂了 - 大表导入后首次同步容易积压,可临时调高
slave_parallel_workers(需slave_parallel_type = LOGICAL_CLOCK),但别设超过 CPU 核数
真正难的不是“怎么加”,而是确保新从库的 binlog 位点、GTID 集合、表结构、字符集、SQL mode 都和主库严格对齐——差一个 sql_mode='STRICT_TRANS_TABLES',都可能让某条 INSERT 在从库被静默截断。











