当slave_io_running和slave_sql_running均为no时,需先执行show slave status\g检查last_io_error或last_sql_error定位原因,再针对性修复,切勿直接start slave。

Slave_IO_Running 和 Slave_SQL_Running 都为 No 怎么办
线程消失不是“丢了”,而是 MySQL 主动停了,通常因为错误不可恢复或配置失效。先别急着 START SLAVE,得确认停因。
执行 SHOW SLAVE STATUS\G,重点看三处:Seconds_Behind_Master(是否为 NULL)、Slave_IO_Running 和 Slave_SQL_Running(是否都为 No),以及最关键的 Last_IO_Error 或 Last_SQL_Error。
- 如果
Last_IO_Error提到 “authentication plugin” 或 “Access denied”,大概率是主库账号密码变了,或从库CHANGE MASTER TO里用的用户没权限 - 如果
Last_SQL_Error是 “Duplicate entry” 或 “No such table”,说明从库数据已偏离主库,不能直接启 SQL 线程 - 若两字段都是
Connecting却卡住,检查主库bind_address是否监听了从库可访问的 IP,防火墙是否放行3306
CHANGE MASTER TO 参数写错导致线程无法启动
常见于手动重配主从时漏掉关键参数,或用了过时语法(比如 MySQL 8.0+ 不再支持 MASTER_SSL=1 这种写法,改用 GET_MASTER_PUBLIC_KEY=1)。
典型错误配置:CHANGE MASTER TO MASTER_HOST='192.168.1.10', MASTER_USER='repl', MASTER_PASSWORD='xxx' —— 缺少 MASTER_PORT(默认 3306 没问题),但更常被忽略的是 MASTER_AUTO_POSITION=0 和 MASTER_LOG_FILE/MASTER_LOG_POS 的配合逻辑。
- 启用 GTID 时必须设
MASTER_AUTO_POSITION=1,且不能同时指定MASTER_LOG_FILE;否则报错ERROR 1777 (HY000) - 关闭 GTID 时,
MASTER_LOG_FILE和MASTER_LOG_POS必须严格匹配主库SHOW MASTER STATUS输出,差一个字节都会让 IO 线程拒绝连接 - MySQL 5.7+ 默认启用
enforce_gtid_consistency=ON,如果主库 binlog 里混有非事务语句(如CREATE TEMPORARY TABLE),从库可能在启动时静默失败
SQL 线程卡在某个事务里不动了
现象是 Slave_SQL_Running: Yes,但 Seconds_Behind_Master 持续增长,Exec_Master_Log_Pos 停滞,Relay_Log_Space 却在涨——说明 relay log 在写,但 SQL 线程没消费。
执行 SHOW PROCESSLIST,找状态为 Reading event from the relay log 或 Waiting for dependent transaction to commit 的线程。这往往是因为从库开启了并行复制(slave_parallel_workers > 0),而某条事务依赖未就绪。
- 临时解决:设
SET GLOBAL slave_parallel_workers = 0,再STOP SLAVE; START SLAVE;,强制串行回放 - 长期方案:检查主库是否开了
binlog_transaction_dependency_tracking = WRITESET,从库对应参数也要一致,否则依赖判断失准 - 别用
SLAVE_SKIP_COUNTER跳过事务——它只对基于位置的复制有效,GTID 模式下会直接报错ERROR 1858 (HY000)
重启后 IO 线程自动退出,日志里没报错
MySQL 服务重启后,从库线程不自动恢复是默认行为,不是 bug。很多运维误以为“配置写进 my.cnf 就万事大吉”,其实 skip-slave-start 是默认开启的(尤其 MySQL 5.7+ 官方包)。
检查 my.cnf 中是否有 skip-slave-start(哪怕注释掉了也得确认没被其他配置文件覆盖)。没有?那可能是 systemd 启动脚本里加了 --skip-slave-start 参数。
- 安全做法:在
my.cnf的[mysqld]段落显式写skip-slave-start = 0,而不是删掉这一行 - 如果用 Docker,注意官方镜像默认带
--skip-slave-start,需在command或entrypoint里覆盖 - 即便设了自动启动,首次启动仍建议人工执行一次
START SLAVE并立刻查SHOW SLAVE STATUS,因为磁盘延迟、网络抖动可能导致初始连接失败,后续不会重试
真正麻烦的不是线程启不来,而是它启了又悄无声息地停——比如 relay log 写满磁盘、relay_log_space_limit 触顶、或者 slave_net_timeout 设得太小,在主库短暂无响应时直接断连。这些都不会在 ERROR LOG 里打 warning,只会在 SHOW SLAVE STATUS 里留下一个干干净净的 No。











