MySQL 8.0双密码轮转必须用ALTER USER ... IDENTIFIED BY ... RETAIN CURRENT PASSWORD,因SET PASSWORD会强制清空辅助密码导致业务中断,且该机制不自动过期,须显式执行DISCARD OLD PASSWORD才能清理旧密码。

只能用 ALTER USER ... IDENTIFIED BY ... RETAIN CURRENT PASSWORD,其他方式都会丢掉旧密码或直接报错。
为什么 SET PASSWORD 不能用于双密码切换
SET PASSWORD 在 MySQL 8.0 中完全不参与双密码机制。它只覆盖主密码,并无条件清空辅助密码——哪怕你刚用 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 前必须确认三件事
这个语句看似一行 SQL,但卡在前置条件上的失败率极高。漏检任意一项,都会触发 ERROR 3031 或 ERROR 3894。
- 账户当前密码不能为空:
SELECT authentication_string FROM mysql.user WHERE user = 'u' AND host = 'h'返回值不能是NULL或空字符串 - 不能在从库执行:必须只在主库运行,且需等所有从库
Seconds_Behind_Master = 0后再切应用 - 认证插件不能变更:语句中不能同时指定
IDENTIFIED WITH xxx,否则报错ERROR 3894
DISCARD OLD PASSWORD 不是自动清理,必须显式调用
双密码不会随改密次数增加而自动过期。只要没执行 DISCARD OLD PASSWORD,最早那次被 RETAIN CURRENT PASSWORD 保留下来的密码就一直有效——哪怕你已经改了七次密码。
- 安全审计时发现半年前的密码仍能登录,大概率就是漏掉了这一步
- 误执行一次不带
RETAIN CURRENT PASSWORD的ALTER USER ... IDENTIFIED BY 'x',会导致主密码变成x,但辅助密码仍是最初那个,等于凭空多留一个长期有效口令 -
DISCARD OLD PASSWORD不接受参数,也不支持批量操作,每个账户都得单独执行
最容易被忽略的是:双密码状态完全依赖 mysql.user 表里的元数据标记,而不是密码哈希本身。这意味着你查 authentication_string 看不到“两个密码”,只能靠行为验证——新旧密码都能连上,才是真生效。


















