mysql 8.0双密码平滑轮换必须用alter user ... retain current password启动、discard old password收尾;set password会清空辅助密码致业务中断,且不支持双密码机制。

MySQL 8.0 的双密码特性不能靠 SET PASSWORD 实现平滑轮换,必须用 ALTER USER ... IDENTIFIED BY ... RETAIN CURRENT PASSWORD 启动,再用 ALTER USER ... DISCARD OLD PASSWORD 收尾——漏掉任一环节,或顺序颠倒,都会导致连接中断、旧密码残留或新密码不生效。
为什么 SET PASSWORD 会直接破坏双密码
SET PASSWORD 完全不参与双密码机制。它只覆盖主密码,且无条件清空辅助密码。哪怕你刚用 RETAIN CURRENT PASSWORD 设好双密码,下一条 SET PASSWORD 就会让旧密码立即失效。
- 执行
SET PASSWORD FOR 'u'@'h' = 'new'后,应用连接会随机断开(取决于哪台节点已同步) - 混写
SET PASSWORD ... RETAIN CURRENT PASSWORD会直接报错ERROR 1064 (42000) -
SET PASSWORD不校验当前密码是否为空、不检查认证插件、失败时也无明确提示
ALTER USER ... RETAIN CURRENT PASSWORD 执行前必须确认的三件事
这条语句失败率高,主要卡在前置条件上。不满足任意一项,就会报 ERROR 3031 或 ERROR 3894:
- 账户当前密码不能为空:
SELECT authentication_string FROM mysql.user WHERE user = 'u' AND host = 'h'返回值不能是NULL或空字符串 - 不能在从库执行:必须只在主库运行;主库执行后,需等所有从库
Seconds_Behind_Master = 0再推进应用切换 - 认证插件不能变更:执行时若同时指定
IDENTIFIED WITH caching_sha2_password,会报ERROR 3894—— 双密码仅支持caching_sha2_password插件
主从环境下的验证与收尾要点
双密码不是主库一执行就全局生效。从库没同步完成前切应用,会出现“部分节点认新密码、部分只认旧密码”的访问拒绝问题:
-
ALTER USER ... RETAIN CURRENT PASSWORD是隐式提交,包裹在事务中无意义,反而误导人以为能回滚 - 验证是否生效:用旧密码和新密码分别登录,都应成功;查
mysql.user表,authentication_string字段值不变(仍是旧密码哈希),说明辅助密码已保留 -
DISCARD OLD PASSWORD不是自动发生的,也不接受参数、不支持批量操作——每个账户都得单独执行,且必须显式调用才能清理最老那次被保留下来的辅助密码
最容易被忽略的是:双密码不会随改密次数增加而自动过期。哪怕你用 RETAIN CURRENT PASSWORD 操作了十次,只要没执行 DISCARD OLD PASSWORD,第一次设的旧密码就一直有效——安全审计时发现半年前的密码还能登,大概率就是这一步漏了。











