MySQL 8.0双密码机制仅通过ALTER USER ... RETAIN CURRENT PASSWORD和DISCARD OLD PASSWORD手动实现,不支持自动轮转;SET PASSWORD会清空辅助密码导致业务中断,且执行前须确保当前密码非空、主从同步完成、认证插件未变更。

MySQL 8.0 本身不提供“自动密码轮转”功能,所谓无缝切换,完全依赖 ALTER USER ... RETAIN CURRENT PASSWORD 和 ALTER USER ... DISCARD OLD PASSWORD 这两个手动操作步骤——没有后台任务、没有配置开关、也没有定时器。所谓“自动”,必须由外部系统(如运维脚本、CI/CD 流程或密码管理平台)驱动。
执行 RETAIN CURRENT PASSWORD 前必须满足的条件
这个语句不是万能钥匙,它会直接拒绝不符合前提的操作:
- 账户当前密码不能为空:
authentication_string字段必须非 NULL 且非空字符串,否则报错ERROR 3031 (HY000): Cannot retain current password for account with empty password - 当前会话必须用旧密码成功认证过——如果已用新密码登录再执行该语句,会触发
ER_CANT_RETAIN_CURRENT_PASSWORD - 不能同时更改认证插件,例如从
caching_sha2_password切到sha256_password,否则报错ERROR 3894 (HY000) - 主库执行后,必须确认所有从库复制完成(
Seconds_Behind_Master = 0),否则部分节点尚未支持新主密码,连接会被拒绝
SET PASSWORD 不能用于双密码,误用会导致辅助密码丢失
很多脚本沿用旧习惯写 SET PASSWORD FOR 'u'@'h' = 'new',这在 MySQL 8.0 双密码场景下是危险操作:
-
SET PASSWORD完全不识别RETAIN CURRENT PASSWORD,它只会更新主密码,并清空辅助密码 - 执行后看似“改了密码”,实则退回到单密码状态,旧连接立刻失效,业务中断
- 即便你后续再补
ALTER USER ... RETAIN CURRENT PASSWORD,旧密码已不可恢复(除非你还记得)
验证双密码是否生效及何时执行 DISCARD OLD PASSWORD
不能凭感觉清理旧密码,必须有可观测依据:
- 检查
performance_schema.threads中活跃连接的认证用户字段(PROCESSLIST_USER+PROCESSLIST_HOST),确认无连接仍使用旧密码建连 - 翻查应用日志或数据库审计日志(如启用
audit_log插件),搜索旧密码哈希或明文凭证出现痕迹 -
DISCARD OLD PASSWORD是不可逆操作:执行后旧密码彻底删除,无法回滚;且它不会自动清理历史残留——哪怕你轮换十次,只要没丢弃,最老那次保留的辅助密码依然有效
最容易被忽略的一点:双密码机制对连接池行为高度敏感。如果应用使用连接池(如 HikariCP、Druid),即使代码已切新密码,池中存活连接仍可能长期复用旧凭证——这意味着你得等连接自然超时或强制刷新池,而不是改完 SQL 就以为万事大吉。


















