根本原因是mysql主从默认不同步mysql.user表权限,5.7及更早版本grant不写binlog,8.0+需确保log_bin开启且未配置replicate_ignore_db=mysql。

为什么从库查不到主库创建的用户
因为 mysql.user 表默认不走 binlog 同步。MySQL 5.7 及更早版本中,GRANT、CREATE USER 等权限操作不会被写入 binlog(除非显式开启 log_bin_trust_function_creators=1 且 binlog_format 为 ROW 或 MIXED);MySQL 8.0+ 虽默认记录为 DDL 事件,但前提是主库没关 log_bin,且从库没配置 replicate_ignore_db=mysql——这是最常踩的坑。
检查从库是否跳过了 mysql 库
直接执行:SHOW SLAVE STATUS\G
查看输出中的 Replicate_Ignore_DB 字段。如果值包含 mysql,说明权限变更根本不会被读取和回放。
也可查配置:SELECT * FROM performance_schema.replication_applier_configuration;
确认是否有过滤规则生效。
常见错误现象:
• 主库 SELECT user,host FROM mysql.user 能查到用户,从库返回空
• 应用连从库报 Access denied for user
• SHOW GRANTS FOR 'u'@'h' 在从库返回空或报错
用 GRANT 同步权限比 INSERT 更可靠
直接 INSERT INTO mysql.user 不仅字段顺序、密码加密方式(authentication_string vs password)、过期策略易出错,还可能被 MySQL 静默拒绝,且不触发权限重载,也不保证 binlog 正确生成。
推荐做法:
• 在主库执行标准权限语句:CREATE USER 'reporter'@'%' IDENTIFIED BY 'pwd';GRANT SELECT ON db.* TO 'reporter'@'%';
• 执行后立即在从库手动运行:FLUSH PRIVILEGES;(虽非必须,但可避免因复制延迟导致内存权限未更新)
双向复制中权限无法自动同步怎么办
MySQL 对 mysql 库的 DML/DDL 做了硬编码跳过处理,即使你配了 binlog-do-db=mysql 或 log_slave_updates=1,也无效。
实操路径只能是人工对齐:
• 在 A 节点(权威源)执行权限变更后,导出语句:mysqldump --no-create-info --skip-extended-insert -u root -p mysql user db procs_priv | grep -E "^(INSERT|REPLACE) INTO `?user`?" > grants.sql
• 清理 grants.sql 中的注释、空行等非权限行
• 将该文件导入 B 节点:mysql -u root -p mysql <br>• 在 B 节点执行:<br><code>FLUSH PRIVILEGES;
GTID 模式下更严格:B 节点上连 INSERT INTO mysql.user 都会被拒绝,报 ERROR 1786 (HY000): Statement violates GTID consistency,所以必须走 A 导出 → B 导入流程。
最容易被忽略的一点:FLUSH PRIVILEGES 不产生 binlog,也不会被复制,必须在每个节点上单独执行,否则权限只存在磁盘,不在内存生效。











