主从同步成功的关键在于server-id唯一、log-bin开启且CHANGE MASTER TO中的MASTER_LOG_FILE和MASTER_LOG_POS必须严格匹配主库SHOW MASTER STATUS的实时输出,否则Slave_IO_Running将为No;主库需在[mysqld]段配置server-id=1和log-bin=mysql-bin,从库server-id须非零且不重复,重启服务后验证log_bin=ON及Master_Status非空,再执行CHANGE MASTER TO并START SLAVE,最后通过SHOW SLAVE STATUSG确认Slave_IO_Running和Slave_SQL_Running均为Yes。
主从同步不是“配完就通”,关键在 server-id 唯一性、log-bin 开启状态、以及 CHANGE MASTER TO 中的 MASTER_LOG_FILE 和 MASTER_LOG_POS 必须严格匹配主库 SHOW MASTER STATUS 的实时输出——错一位,从库就卡在 Slave_IO_Running: No。
CentOS 7 上 MariaDB 默认不开启二进制日志,光改 server-id 没用。必须在 /etc/my.cnf 或 /etc/my.cnf.d/server.cnf 的 [mysqld] 段落里加这两行:
server-id = 1log-bin = mysql-bin
可选但强烈建议加上:
binlog-format = ROW(避免语句级复制引发的主从不一致)expire_logs_days = 7(自动清理旧 binlog,防磁盘打满)改完重启服务:systemctl restart mariadb。验证是否生效:mysql -e "SHOW VARIABLES LIKE 'log_bin';" 输出应为 ON;再执行 SHOW MASTER STATUS; 确保有非空的 File 和 Position 值。
从库配置里只写 server-id = 2(或任意非 0、非主库值)就行,不要加 log-bin——除非你打算把它也当主库用(比如双主)。否则会多出一堆无用 binlog,还可能干扰复制链路。
常见错误:
server-id,默认是 0,START SLAVE 直接报错:ERROR 1200 (HY000): The server is not configured as a replication slave
server-id 相同,从库启动后 SHOW SLAVE STATUSG 里 Seconds_Behind_Master 显示 NULL,IO 线程起不来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
命令示例(替换对应值):
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;,别漏掉分号。
SHOW SLAVE STATUSG 里两个关键字段必须同时为 Yes:
Slave_IO_Running: Yes(能连上主库并拉日志)Slave_SQL_Running: Yes(能解析并执行日志里的事件)但更要看:
Seconds_Behind_Master: 0(理想状态,偶尔波动正常)Master_Host 和 Master_User 是否是你设的值Last_IO_Errno 和 Last_SQL_Errno 是否为 0(非 0 就代表出错了)如果卡住,先查错误号:SHOW SLAVE STATUSG 里 Last_IO_Error 或 Last_SQL_Error 字段直接告诉你问题在哪——比如网络不通、用户密码错、binlog 文件被删、SQL 冲突(主键重复)等。跳过单条错误用 SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;,但这是临时止血,得立刻查根本原因。
真正麻烦的是半同步没开时的“静默延迟”:主库写了,从库没报错但也没同步过去,Seconds_Behind_Master 却显示 0。这种情况只能靠定期比对表行数或校验和来发现。