修改密码后从库不拉取数据,需手动启动IO线程并检查Last_IO_Error;优先用ALTER USER改密,CHANGE MASTER TO仅用于兼容旧版;GTID模式下必须设MASTER_AUTO_POSITION=1;master_info_repository为TABLE时需重执行CHANGE MASTER TO刷新明文密码。

CHANGE MASTER TO 修改密码后从库不拉取数据?先确认 IO 线程状态
直接改完 CHANGE MASTER TO 就以为同步会自动恢复,结果 SHOW SLAVE STATUS\G 里 Slave_IO_Running: No,这是最常见误判。MySQL 不会在密码变更后自动重连主库,必须手动触发重连,且前提是账号权限和网络都正常。
实操建议:
- 执行
CHANGE MASTER TO后,立刻运行START SLAVE IO_THREAD(不是START SLAVE),只启 IO 线程,方便快速定位是认证失败还是网络问题 - 检查错误日志:
SHOW SLAVE STATUS\G中的Last_IO_Error字段,典型报错如Access denied for user 'repl'@'xxx' (using password: YES),说明密码没生效或账号没刷到权限表 - 确保主库已执行
FLUSH PRIVILEGES(如果用ALTER USER修改密码则不需要;但用UPDATE mysql.user直接改表就必须)
用 ALTER USER vs CHANGE MASTER TO 改密码,哪个更安全?
答案是:优先用 ALTER USER,CHANGE MASTER TO 只该用于临时绕过或兼容旧版本(5.7 及以前)。因为后者把密码明文写进 relay log 和 master info repository(如果启用了 master_info_repository = TABLE),有泄露风险。
实操建议:
- MySQL 8.0+ 统一走
ALTER USER 'repl'@'%' IDENTIFIED BY 'newpass123';,然后在从库执行CHANGE MASTER TO MASTER_PASSWORD='newpass123'—— 注意,这只是告诉从库“下次连主库用这个密码”,不存密文到系统表 - 如果主库是 5.7 且不能升级,
SET PASSWORD FOR 'repl'@'%' = PASSWORD('newpass123');后必须跟FLUSH PRIVILEGES - 避免在
CHANGE MASTER TO语句里写裸密码,尤其别放在脚本里;生产环境建议用配置文件 +mysql_config_editor管理凭据
CHANGE MASTER TO 执行时报错 ERROR 3021 / ERROR 3009 怎么办?
这两个错误本质都是“从库元数据状态冲突”:3021 表示 GTID mode 下试图用 MASTER_LOG_FILE + MASTER_LOG_POS 指定位置,但主库已启用 GTID;3009 是反向情况——GTID 已开启,却没提供 MASTER_AUTO_POSITION = 1。
实操建议:
- 先查主从是否同开 GTID:
SELECT @@global.gtid_mode;,两边必须一致 - GTID 开启时,
CHANGE MASTER TO必须带MASTER_AUTO_POSITION = 1,删掉所有MASTER_LOG_FILE、MASTER_LOG_POS参数 - 如果只是想换密码,GTID 模式下可以只写:
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='newpass123', MASTER_AUTO_POSITION=1;,其他参数保持原样 - 切勿在 GTID 模式下手动指定 binlog 位置,MySQL 会拒绝并报 3021
从库重启后密码失效?检查 master info repository 存储方式
MySQL 默认把主库连接信息(含密码)存在文件 master.info,但若设了 master_info_repository = TABLE,就会存进 mysql.slave_master_info 表——而这张表里的 Master_password 字段是明文存储的,且不会随 ALTER USER 自动更新。
实操建议:
- 查看当前设置:
SELECT * FROM performance_schema.replication_connection_configuration\G(8.0+)或SELECT * FROM mysql.slave_master_info\G(5.7) - 如果
Master_password列值是旧密码,必须重新执行完整CHANGE MASTER TO(哪怕只改密码),MySQL 才会刷新该字段 - 更稳妥的做法:设
master_info_repository = FILE(默认),避免密码滞留在系统表中;如必须用 TABLE,记得每次改密后验证该表内容 - 注意:
slave_master_info表权限仅限 root,普通复制账号看不到,排查时容易忽略这点
密码改完不是终点,IO 线程是否真正连上主库、GTID 是否对齐、master info 是否被持久化——这三个点漏查一个,同步就静默卡住。尤其是 slave_master_info 表里的密码字段,看着像自动更新,其实完全依赖你有没有重发 CHANGE MASTER TO 命令。

















