大规模mysql集群权限一致性必须靠ansible等自动化工具维护,人工操作易导致host不一致、grant静默失败、flush privileges遗漏、默认角色未启用等问题;核心是封装sql任务、精确错误控制、分步验证账号存在性与权限结果,并明确强一致与容忍差异的权限范围。

大规模 MySQL 集群的权限一致性无法靠人工维护——只要有一个实例漏执行 GRANT 或忘记 FLUSH PRIVILEGES,就可能造成应用连不上、权限不生效、主从行为不一致等问题。
为什么不能在每个实例上手动跑 GRANT 语句
手动操作在 3 台以内尚可,超过 5 个实例后,以下问题会快速暴露:
- 同一账号在不同实例上的
Host值不一致(比如有的写'192.168.10.%',有的写'%'),导致连接被拒绝但错误提示模糊 -
CREATE USER和GRANT分两步执行时,若某台跳过CREATE USER,GRANT会静默失败(MySQL 8.0+ 默认行为) - 未显式执行
FLUSH PRIVILEGES(虽然多数情况自动刷新,但在某些 ProxySQL 或只读从库场景下仍需手动触发) - 角色(
ROLE)未在所有节点启用默认角色:SET DEFAULT ROLE ...必须逐台运行,否则新用户登录后权限不生效
用 Ansible 同步权限的核心要点
Ansible 是目前最稳妥的落地方式,关键不在“能不能跑”,而在“怎么避免误覆盖”和“如何验证结果”:
- 把用户创建、授权、角色绑定、默认角色设置封装成一个 playbook,所有 SQL 操作统一走
mysql_query模块,而非 shell 调用mysql -e - 必须为每个任务加
ignore_errors: yes+register:,再用failed_when:精确控制哪些错误可忽略(例如用户已存在)、哪些必须中断(如权限语法错误) - 对
mysql_user模块要谨慎:它不支持列级权限、角色绑定、WITH GRANT OPTION等高级能力,建议仅用于基础账号创建,其余全用mysql_query - 每次执行前,先用
mysql_query查询SELECT User, Host FROM mysql.user WHERE User = 'dev_app1',确认目标账号是否存在,再决定走 CREATE 还是直接 GRANT
脚本化同步时最容易被忽略的三个检查点
哪怕你写的是纯 Bash + mysql 命令,也必须在脚本末尾加入这三项验证逻辑:
- 检查所有目标实例是否返回完全一致的
SHOW GRANTS FOR 'dev_app1'@'192.168.10.%'结果(注意比对换行、空格、大小写) - 在每台实例上执行
SELECT COUNT(*) FROM mysql.role_edges WHERE TO_HOST = '192.168.10.%' AND TO_USER = 'dev_app1',确认角色关系已写入系统表 - 用测试账号实际连接一次:
mysql -u dev_app1 -h $ip -P3306 -e "SELECT 1" 2>/dev/null || echo "FAIL on $ip",光看 SQL 执行成功不等于权限真生效
真正难的不是写同步脚本,而是定义清楚「哪些权限必须强一致」「哪些可以容忍短暂差异」——比如监控账号的 PROCESS 权限必须全集群一致,而某个临时 BI 账号的视图查询权限,晚同步 10 分钟通常无影响。这个判断得由 DBA 和业务方一起拍板,不能全交给自动化工具兜底。











