MGR集群中GRANT不同步是因为其硬编码限制mysql系统库不参与复制,CREATE USER和GRANT语句不会生成binlog事件或广播至其他节点,仅本地生效;必须在所有节点显式执行幂等SQL并验证一致性。

为什么直接执行 GRANT 不会在 MGR 集群中同步账号
MGR 集群(包括单主和多主模式)默认不复制 mysql 系统库的任何变更,这是硬编码限制,不是配置能绕过的。哪怕你在主节点执行 CREATE USER 'u'@'%' IDENTIFIED BY 'p' 或 GRANT SELECT ON db.t TO 'u'@'%',这些语句根本不会生成 binlog 事件,也不会被组通信协议广播——因为 mysql.user、mysql.db 等表被明确排除在事务复制范围之外。
你看到“执行成功”,只是当前节点本地生效;其他节点查 SELECT User, Host FROM mysql.user 依然为空或旧状态,连接时自然报 Access denied。
常见误操作包括:
- 在从节点手动执行
GRANT(破坏一致性,后续主节点同名用户变更会冲突) - 用
INSERT INTO mysql.user直接改表(跳过权限校验逻辑,且在 8.0+ 中字段如account_locked由服务端维护,写入无效甚至导致崩溃) - 依赖
FLUSH PRIVILEGES(它不写 binlog,在 MGR 中纯属冗余操作,还可能掩盖权限未同步的问题)
必须在所有节点上逐条执行 CREATE USER 和 GRANT
唯一安全方式是:把权限变更封装为幂等 SQL,在所有 MGR 节点上显式、顺序执行。不能靠“主库下发”,必须人工或脚本驱动。
关键实操要点:
- 始终用
CREATE USER IF NOT EXISTS开头,避免某节点已存在用户时语句失败中断流程 -
GRANT必须带完整ON子句和TO目标,例如GRANT SELECT, INSERT ON mydb.* TO 'app'@'10.20.%';不要省略@'host',否则默认为@'%',不同节点 Host 解析差异会导致权限不一致 - MySQL 8.0+ 若启用密码策略(如
validate_password),建议拆成两步:CREATE USER显式指定IDENTIFIED WITH caching_sha2_password BY 'xxx',再GRANT,防止因插件不一致(如有的节点仍用mysql_native_password)导致认证失败 - 角色(
ROLE)需额外处理:CREATE ROLE IF NOT EXISTS+GRANT ... TO ROLE+GRANT role_name TO 'user'@'host'+SET DEFAULT ROLE,且SET DEFAULT ROLE必须在每台节点单独执行
用 Ansible 自动化时必须验证三件事
Ansible 是目前最可控的落地方式,但光跑 mysql_query 模块远远不够。以下三项验证必须嵌入脚本末尾,缺一不可:
- 比对所有节点的
SHOW GRANTS FOR 'app'@'10.20.%'输出是否完全一致(注意空格、换行、大小写)——仅靠“SQL 执行成功”不等于权限真生效 - 检查角色绑定是否写入系统表:
SELECT COUNT(*) FROM mysql.role_edges WHERE FROM_HOST = '10.20.%' AND FROM_USER = 'app',确保每台返回相同非零值 - 用该账号真实连接测试:
mysql -u app -h $ip -P3306 -e "SELECT 1" 2>/dev/null || echo "FAIL on $ip",这是唯一能暴露 DNS、防火墙、插件不匹配等问题的环节
GTID 和版本兼容性是隐藏雷区
即使你严格按步骤执行了所有节点的 CREATE USER 和 GRANT,仍可能因 GTID 或版本差异中断复制或权限失效:
- MySQL 8.0 的动态权限(如
BACKUP_ADMIN、CLONE_ADMIN)在 5.7 从节点上无法识别,会直接报ERROR 3528 (HY000)并停止组复制;必须确认所有节点SELECT VERSION()结果一致 - GTID 模式下,若主节点执行
CREATE USER因密码策略不满足而回滚,但从节点可能已应用部分 writeset,造成状态分裂;此时需手动清理从节点残留记录并重放 - 跨版本升级后,务必在所有节点执行
mysql_upgrade,否则mysql.user表结构不一致会导致后续GRANT静默失败
真正难的不是写几条 SQL,而是定义清楚哪些权限必须强一致(比如应用连接账号)、哪些可以容忍短暂不一致(比如临时运维账号),以及谁来触发、何时验证、出错后怎么回滚。这些决策比技术实现更影响集群稳定性。


















