MySQL 8.0双密码仅支持通过ALTER USER ... IDENTIFIED BY ... RETAIN CURRENT PASSWORD实现,SET PASSWORD不支持;需确保当前密码非空,主从同步完成后再切换应用,DISCARD OLD PASSWORD须显式调用清理辅助密码。

SET PASSWORD 语句本身不支持设置双密码。MySQL 8.0 的双密码(主密码 + 辅助密码)机制只能通过 ALTER USER 语句配合 RETAIN CURRENT PASSWORD 或 DISCARD OLD PASSWORD 子句实现。
如果你在文档或脚本里看到用 SET PASSWORD 配置双密码,那基本是混淆了语法,执行会失败或仅更新主密码、丢弃辅助密码——这恰恰是你要避免的。
ALTER USER ... IDENTIFIED BY ... RETAIN CURRENT PASSWORD 是唯一可靠入口
这是启用双密码的唯一正确方式,适用于 MySQL 8.0.14 及以上版本(生产环境建议 ≥ 8.0.23)。
- 它要求账户当前已有有效密码(即不能是空密码或已过期未重置状态)
- 执行后,新密码成为主密码,旧密码自动降级为辅助密码
- 主密码和辅助密码均可用于登录,无时间窗口限制,连接完全兼容
常见错误现象:
- 执行
ALTER USER 'u'@'h' IDENTIFIED BY 'new' RETAIN CURRENT PASSWORD报错ERROR 3031 (HY000): Cannot retain current password for account with empty password→ 账户当前密码为空,不满足前提 - 用
SET PASSWORD FOR 'u'@'h' = 'new'替代 → 辅助密码被清空,双密码失效 - 在从库上执行但未等复制完成就切应用 → 部分节点尚未支持新主密码,连接拒绝
实操建议:
- 先确认账户当前密码有效:
SELECT user, host, authentication_string FROM mysql.user WHERE user = 'u' AND host = 'h';,确保authentication_string非空且非NULL - 主库执行后,用
SHOW SLAVE STATUS\G确认所有从库Seconds_Behind_Master = 0再推进应用端切换 - 不要在事务中执行该语句 ——
ALTER USER是隐式提交,事务包裹无意义且易误导
DISCARD OLD PASSWORD 必须显式调用才能关闭双密码
双密码不会自动过期或自动清理。即使你改了十次密码,只要没执行 DISCARD OLD PASSWORD,最老那次被 RETAIN CURRENT PASSWORD 保留下来的密码仍有效。
典型误操作:
- 以为“再执行一次
ALTER USER ... IDENTIFIED BY ... RETAIN CURRENT PASSWORD”就能覆盖旧辅助密码 → 实际是把上一轮的主密码变成新的辅助密码,形成三级密码链(主 / 辅1 / 辅2),增加爆破面 - 跳过
DISCARD OLD PASSWORD直接删用户重建 → 权限、资源限制、SSL 设置等需重新配置,风险远高于原地清理
安全建议:
- 清理前务必确认所有客户端已完成新密码切换,可用审计日志验证:
SELECT * FROM performance_schema.events_statements_summary_by_account_by_event_name WHERE event_name = 'statement/sql/select' AND count_star > 0;结合连接来源分析 -
DISCARD OLD PASSWORD不接受条件判断,也不支持批量执行,每个账户必须单独调用 - 执行后立刻测试:用旧密码尝试登录应返回
ERROR 1045 (28000): Access denied
双密码与密码策略插件共存时的优先级
当 validate_password 组件启用时,对双密码的影响只发生在设置主密码阶段:
-
RETAIN CURRENT PASSWORD中的新密码(主密码)必须满足当前策略(长度、字符类型等) - 辅助密码(旧密码)不受策略约束,哪怕它当初是弱密码,只要当时被接受,现在仍可登录
-
DISCARD OLD PASSWORD不校验任何密码强度,只做删除动作
这意味着:
- 不能靠开启
validate_password来“倒逼”淘汰旧辅助密码 - 若旧密码是
123456,而策略已设为validate_password.length=12,它依然能登录 —— 这是设计使然,不是 bug - 真正清理弱辅助密码,唯一办法仍是人工确认后执行
DISCARD OLD PASSWORD
双密码机制本质是运维灰度能力,不是安全加固开关。它的复杂点不在语法,而在业务节奏把控:什么时候加、谁在用旧密码、哪台实例还没同步、是否真完成了全量切换——这些没法靠一条 SQL 自动判断。


















