先说个核心观点:主从同步的配置本身并不复杂,但真正的难点都隐藏在细节里。很多开发者按照文档配置完成后,发现 Slave_IO_Running 显示为 No,就会陷入自我怀疑。实际上,问题通常只出现在三个地方:server-id 是否唯一、log-bin 是否被默认关闭、以及 CHANGE MASTER TO 中两个关键参数——MASTER_LOG_FILE 和 MASTER_LOG_POS——必须与主库执行 SHOW MASTER STATUS 后实时输出的结果完全一致,哪怕差一位数都不行。

主库配置:务必手动开启 binlog,不要依赖默认值
许多新手在第一步就踩了坑。在 CentOS 7 环境下,MariaDB 默认并未启用二进制日志。如果你仅仅修改了 server-id,服务并不会生效。必须在 /etc/my.cnf 或 /etc/my.cnf.d/server.cnf 文件的 [mysqld] 段中,手动添加以下两行:
server-id = 1 log-bin = mysql-bin
除此之外,还有两个强烈建议加入的配置:
binlog-format = ROW—— 使用行模式复制,能够有效避免因 SQL 语句执行环境不一致导致的主从数据不一致问题。expire_logs_days = 7—— 自动清理 7 天前的 binlog 文件,防止日志占满磁盘空间,这是一个经典的生产事故隐患。
修改完成后,记得重启 MariaDB 服务:systemctl restart mariadb。然后进行验证:执行 mysql -e "SHOW VARIABLES LIKE 'log_bin';",看到输出结果为 ON 才算真正生效。接着,再运行 SHOW MASTER STATUS;,确保能看到非空的 File 和 Position 值,这两个值就是后面复制配置时需要用到的关键信息。
从库配置:server-id 不要与主库冲突,log-bin 不要随意开启
从库的配置相对简单,核心要点只有一条:server-id 必须设置为一个非 0 且不与主库重复的数字,例如 server-id = 2。**千万不要画蛇添足地加上 log-bin**,除非你计划将来把这个从库升级为主库(比如搭建双主架构)。否则,开启它只会产生大量无用的 binlog 文件,既浪费磁盘空间,还可能干扰复制链路。
这里有两个常见的“送分题”级别的错误:
- 忘记修改
server-id,默认值为 0。当你执行START SLAVE时,系统会立即返回ERROR 1200 (HY000): The server is not configured as a replication slave错误。 - 主从两个库的
server-id设置成了相同的值。这时从库运行SHOW SLAVE STATUS\G,Seconds_Behind_Master会显示为NULL,IO 线程根本无法连接,启动失败。
CHANGE MASTER TO:关键步骤,不要偷懒使用旧值
这是整个配置过程中最关键的一步,也是最容易出问题的地方。请记住:MASTER_LOG_FILE 和 MASTER_LOG_POS 是主库当前 binlog 的“快照点”,它们是动态变化的。每次主库重启、刷新日志、甚至执行 FLUSH LOGS 都会改变它们。千万不要从之前的文档或历史记录中复制粘贴,那样无异于刻舟求剑。
标准操作流程如下:
- 在主库执行
FLUSH TABLES WITH READ LOCK;,先锁定所有表,确保后续导出的数据是一致的。 - 立即执行
SHOW MASTER STATUS;,当场记录下File(例如mysql-bin.000003)和Position(例如154)。 - 接着,导出数据(使用
mysqldump即可),传输到从库并导入。 - 最后,在从库上执行
CHANGE MASTER TO命令,将刚才记录的值填入。
命令示例如下(请替换其中的 IP、密码以及那两个关键值):
CHANGE MASTER TO MASTER_HOST='192.168.1.150', MASTER_USER='repl', MASTER_PASSWORD='your_pass', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=154;
然后,再执行 START SLAVE;。注意不要漏掉最后的分号。
验证:不要只看 Yes/No,要学会解读状态
配置完成后,执行 SHOW SLAVE STATUS\G,看到 Slave_IO_Running 和 Slave_SQL_Running 均为 Yes,可以先松一口气。但这只是表象,更关键的证据在后面:
Seconds_Behind_Master: 0—— 理想状态,表示无延迟。偶尔出现小幅度波动也算正常。Master_Host和Master_User—— 确认一下是否与你刚才设置的值一致,避免连错了主库。Last_IO_Errno和Last_SQL_Errno—— **这两个值必须都是0**。只要不是 0,就说明出现了错误。具体原因可以直接查看Last_IO_Error或Last_SQL_Error字段,它们会清晰地指明问题所在。例如:网络不通、密码错误、binlog 文件被删除、或者 SQL 冲突(最常见的是主键重复)。
如果遇到阻塞且想先跳过一条错误,可以使用 SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;。但这只是临时止血措施,真正需要做的是找到根本原因并解决。
最后再提一个更隐蔽的问题。如果没有开启半同步复制,主库写入完成后就会返回,从库虽然不报错,但数据可能仍然滞留在传输队列中。此时 Seconds_Behind_Master 可能显示为 0,给人“数据已同步”的假象。这种情况最危险,因为一旦主库宕机,你就会丢失数据。如何防范?最可靠的办法是定期使用工具对比两边的表行数,或者计算校验和进行验证。
