必须用外部权限中心统一管理,因MySQL原生mysql.user表不支持跨实例原子同步,硬改致主从不一致、权限漂移、回滚失效;常见错误包括GRANT漏执行、手动输错密码、备份后权限未同步;真实场景含K8s滚动更新50+ Pod、混合部署及动态权限管控。

MySQL大规模集群里,账号密码不能靠人工同步
直接结论:必须用外部权限中心统一管理,MySQL原生的mysql.user表不支持跨实例原子同步,硬改会导致主从不一致、权限漂移、回滚失效。
常见错误现象:GRANT语句在某个从库漏执行;DBA手动在30台机器上逐个CREATE USER,第17台输错密码;备份恢复后权限表没同步,应用连不上。
真实使用场景:K8s里滚动更新50+ MySQL Pod;混合部署(物理机+云RDS+ProxySQL);需要按部门/环境/角色动态开关权限。
- 不要把密码明文写进Ansible变量或Shell脚本——
ps aux可能泄露PASSWORD=xxx - 避免用
mysqldump mysql导出导入权限——authentication_string字段加密方式可能因MySQL版本不同而解密失败 - 禁止用
FLUSH PRIVILEGES代替GRANT——它只重载内存缓存,不持久化,重启即丢
用PAM插件对接LDAP或企业AD最省心
MySQL 5.7+原生支持authentication_ldap_sasl和auth_pam插件,权限验证完全交给目录服务,MySQL侧只存映射关系,不存密码。
关键参数差异:plugin_dir路径必须指向含auth_pam.so的目录;default_authentication_plugin要设为auth_pam而非mysql_native_password,否则新用户仍走本地密码校验。
性能影响:每次连接会触发一次LDAP查询,高并发下需配置ldap_cache_timeout;兼容性注意:阿里云RDS禁用插件加载,此方案仅适用于自建集群。
示例映射配置(/etc/pam.d/mysqld):
auth [success=done default=ignore] pam_ldap.so config=/etc/ldap.conf account [success=done default=ignore] pam_ldap.so
如果只能用MySQL原生机制,必须用GTID+事件注入做权限同步
不用主从复制权限表——mysql.user是系统库,传统基于binlog的复制在跨版本或启用了skip_slave_start时极易中断。
正确做法:把GRANT语句封装成带GTID的匿名事务,通过mysqlbinlog --base64-output=DECODE-ROWS -v确认事件类型,再用mysqlbinlog --read-from-remote-server注入到所有节点。
- 必须关闭
sql_log_bin=0后再执行GRANT,否则本地binlog会记录两次(一次原始语句,一次复制事件) - 所有节点的
gtid_mode=ON且enforce_gtid_consistency=ON,否则注入事务会被拒绝 - 检查
SELECT * FROM performance_schema.replication_applier_status_by_coordinator确认事件已应用,别只看Seconds_Behind_Master
密码轮换不能只改SET PASSWORD,得配合连接池热加载
应用层连接池(如HikariCP、Druid)不会自动感知MySQL端密码变更,改完ALTER USER 'app'@'%' IDENTIFIED BY 'new'后,旧连接仍可用,新连接却可能因池内缓存旧密码而失败。
真正生效要三步:先在MySQL改密 → 再触发连接池主动断开并重建(比如调用HikariDataSource.evictAllConnections())→ 最后确认SHOW PROCESSLIST里没有残留旧用户连接。
容易被忽略的点:max_connections限制下,轮换瞬间大量重连可能触发拒绝连接;某些云厂商控制台的“重置密码”按钮,实际是删用户再重建,GRANT权限不会自动恢复。


















