mysql主从复制需主库开启binlog并设唯一server-id;从库需正确配置change master to位置;启动后须检查io/sql线程状态;读写分离需应用或中间件显式路由,从库应设read_only=on。

主库必须开启 binlog 且设置唯一 server-id
MySQL 主从复制依赖 binlog 记录写操作,如果主库没开 binlog,从库连日志都拉不到,复制直接失败。常见错误现象是执行 START SLAVE; 后,SHOW SLAVE STATUS\G 显示 IO_Running: No,且 Seconds_Behind_Master 为 NULL,错误信息里常出现 Could not find first log file name in binary log index file。
实操建议:
- 确认主库配置文件(如
/etc/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf)中已启用log-bin,例如:log-bin = /var/lib/mysql/mysql-bin - 必须设置非零且全局唯一的
server-id,比如server-id = 1;从库不能和主库相同,也不能和其他从库重复 - 修改后重启 MySQL(
systemctl restart mysql),并用SHOW VARIABLES LIKE 'log_bin';和SHOW VARIABLES LIKE 'server_id';验证 - 注意:binlog 格式建议用
ROW(binlog_format = ROW),避免语句级复制在从库因函数/时间戳等产生不一致
从库执行 CHANGE MASTER TO 前要先获取主库的 binlog 位置
从库需要知道从哪个 binlog 文件、哪个偏移量开始同步,否则会漏数据或报错 Could not parse relay log event entry。这个位置不是固定值,必须在主库锁表导出时实时获取,不能靠猜或复用旧值。
实操建议:
- 主库执行
FLUSH TABLES WITH READ LOCK;(仅限低峰期,阻塞写入) - 立刻执行
SHOW MASTER STATUS;,记下File(如mysql-bin.000003)和Position(如154) - 用
mysqldump导出数据时加--master-data=2参数,它会自动在 dump 文件开头插入CHANGE MASTER TO语句,省去手动记位置的步骤 - 解锁主库:
UNLOCK TABLES;—— 这步漏掉会导致业务写入卡死
从库启动复制后要持续检查 IO 和 SQL 线程状态
START SLAVE; 只是发起指令,不代表复制真正跑起来了。很多问题发生在启动后几分钟内,比如网络不通、权限不对、SQL 冲突,但 SHOW SLAVE STATUS\G 的输出容易被忽略关键字段。
实操建议:
- 检查两个核心字段:
IO_Running和SQL_Running必须同时为Yes,任一为No就说明断了 - 若
IO_Running: No,重点看Last_IO_Error,常见原因是从库连接主库失败(用户名密码错、防火墙拦了 3306、主库bind-address没放开远程) - 若
SQL_Running: No,看Last_SQL_Error,典型如主键冲突、表不存在、DDL 不兼容——此时不能直接SET GLOBAL sql_slave_skip_counter = 1跳过,得先定位是不是业务双写主从导致的数据混乱 - 用
SELECT SLEEP(1); SHOW SLAVE STATUS\G多刷几次,观察Seconds_Behind_Master是否持续增长
读写分离不是配完主从就自动生效
MySQL 本身不提供读写分离路由能力。主从搭好了,应用代码或中间件仍可能把 SELECT 发到主库,或者把 UPDATE 发到从库导致报错 ERROR 1290 (HY000): The MySQL server is running with the --read-only option。
实操建议:
- 确认从库开启了
read_only = ON(配置文件里加,或运行时执行SET GLOBAL read_only = ON;),防止误写 - 应用层需显式区分连接:写操作走主库地址(如
jdbc:mysql://master-host:3306/db),读操作走从库地址(如jdbc:mysql://slave-host:3306/db) - 如果用 ShardingSphere、MyCat 或 ProxySQL,注意它们的读写分离策略默认可能不识别事务内读操作——事务中的 SELECT 默认仍发往主库,否则会读到旧数据
- 不要依赖 DNS 轮询或简单负载均衡器做读写分离,它们无法识别 SQL 类型,纯属瞎转
主从延迟、网络抖动、大事务、从库性能瓶颈都会让 Seconds_Behind_Master 突然跳高,这时候读从库就可能看到脏数据。没有银弹,只有监控 + 切换 + 应用兜底逻辑。











