主从切换后从库用户权限丢失,根源在于mysql复制默认过滤mysql系统库(如replicate-ignore-db=mysql或row格式下不复制),导致user、db等权限表未同步,切换后原从库变主库但权限仍为旧状态;应先查mysql.user和show grants验证缺失情况,再根据是否有旧主库访问权选择pt-show-grants导出导入等恢复路径。

主从切换后从库用户权限丢失的根源
主从切换后从库用户权限丢失,不是“权限被删了”,而是从库默认不写入 mysql 系统库——MySQL 的复制默认过滤掉 mysql 库(尤其在 replicate-ignore-db=mysql 或基于行复制 + binlog_format=ROW 时),导致 user、db 等权限表不会同步。切换后原从库变主库,但它的 mysql.user 还停留在旧状态,用户自然登录失败或权限不足。
确认权限是否真丢失:先查 mysql.user 再查 SHOW GRANTS
别急着导入或重建,先验证:
- 用 root 登录新主库(即原从库):
SELECT User, Host FROM mysql.user;—— 若关键用户不在列表里,说明账号记录缺失 - 若用户存在,执行:
SHOW GRANTS FOR 'appuser'@'10.20.%';—— 注意必须带完整Host,否则报ERROR 1141 - 如果报错
ERROR 1141 (42000): There is no such grant defined for user,说明该用户在mysql.user中存在,但mysql.db或mysql.tables_priv没对应记录,权限为空
恢复权限的三种实操路径(按优先级排序)
选哪条取决于你有没有旧主库访问权、是否启用 GTID、以及 MySQL 版本:
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
-
有旧主库且可连:直接用
pt-show-grants导出(比手写SHOW GRANTS更全,含CREATE USER和 DEFINER):pt-show-grants --host=old-master-ip --user=root --password=xxx > grants.sql,然后在新主库执行:mysql -u root -p -
无旧主库,但有备份:还原迁移前导出的
mysql库(必须含--routines --triggers --events):mysql -u root -p mysql —— 注意命令末尾必须指定数据库名 <code>mysql,否则导入到test库里就失效 -
啥都没有,只能手动补:先
CREATE USER(注意认证插件!8.0+ 默认caching_sha2_password,老应用连不上就得显式指定):CREATE USER 'appuser'@'10.20.%' IDENTIFIED WITH mysql_native_password BY 'pwd';,再GRANT,最后务必FLUSH PRIVILEGES;
容易踩的三个坑
权限恢复后仍连不上?大概率栽在这几个细节上:
-
Host字段不匹配:比如原用户是'appuser'@'10.20.1.%',你建成了'appuser'@'%',虽然能连,但权限可能受限;反过来,'localhost'和'127.0.0.1'是两个不同账号,不能混用 - MySQL 8.0+ 认证插件不兼容:应用驱动不支持
caching_sha2_password时,CREATE USER必须加IDENTIFIED WITH mysql_native_password,否则密码正确也报ERROR 1045 - 复制过滤规则残留:检查新主库的
my.cnf是否还留着replicate-ignore-db=mysql或replicate-wild-ignore-table=mysql.%,这些会阻止后续权限变更同步,必须删掉并重启
最麻烦的不是恢复权限本身,而是 Host 和认证插件这两个字段——它们不报错,但会让连接静默失败。每次重建用户后,用 SELECT plugin, host FROM mysql.user WHERE user='xxx'; 对照一眼,比反复试连高效得多。










