MySQL 8.0.19+密码重用限制需同时启用password_history和password_reuse_interval,缺一不可;仅设其一无效,且依赖caching_sha2_password插件与validate_password组件。

MySQL 8.0.19+ 原生支持密码重用限制,但必须同时启用 password_history 和 password_reuse_interval,缺一不可;仅靠 validate_password 插件无法阻止旧密码复用。
为什么只设 password_reuse_interval 没用
MySQL 的密码重用校验是双条件绑定机制:新密码必须同时避开「最近 N 次历史密码」和「M 天内不可重用」两条线。只要其中任一值为 0(默认值),整个策略静默失效——不是效果变弱,而是完全不触发校验。
常见错误现象:ERROR 3753 (HY000): The 'password_reuse_interval' option is not supported for accounts without a password history policy,就是典型因未设 password_history 导致的报错。
-
SET PERSIST password_reuse_interval = 180单独执行 → 无效 -
SET PERSIST password_history = 5单独执行 → 无效 - 两个命令都执行,且值非零 → 才真正启用
- 验证是否生效:
SELECT @@global.password_history, @@global.password_reuse_interval,结果必须都是正整数
ALTER USER 必须显式声明用户级策略
全局变量只影响后续新建用户,对已有用户完全无效。哪怕你设了 password_history = 5 全局值,老用户照样能循环使用旧密码,除非你单独为其绑定策略。
关键点:两个关键词必须出现在同一条 ALTER USER 语句中,顺序无关,但缺一不可。
- ✅ 正确:
ALTER USER 'alice'@'%' PASSWORD HISTORY 5 PASSWORD REUSE INTERVAL 180 DAY - ❌ 错误:
ALTER USER 'alice'@'%' PASSWORD HISTORY 5(没带时间限制 → 不生效) - ❌ 错误:
ALTER USER 'alice'@'%' PASSWORD REUSE INTERVAL 180 DAY(没带次数限制 → 报错ERROR 3753) - 查是否生效:
SELECT User, Host, password_reuse_history, password_reuse_interval FROM mysql.user WHERE User = 'alice',字段有值才表示绑定成功
依赖 caching_sha2_password 插件,mysql_native_password 不支持
该功能底层由认证插件实现哈希存储与比对,mysql_native_password 完全不兼容,即使参数全设对也无校验行为,且通常不报错,只默默跳过。
- 确认当前用户插件:
SELECT user, host, plugin FROM mysql.user WHERE user = 'alice',结果必须是caching_sha2_password - 切换插件:
ALTER USER 'alice'@'%' IDENTIFIED WITH caching_sha2_password BY 'newpass' -
validate_password组件也必须启用(至少 STRONG 模式),否则重用检查逻辑不加载 - 升级陷阱:若从旧版本升级,
mysql.password_history表可能缺失或结构不匹配,启动日志会报ACL table mysql.password_history missing,必须执行mysql_upgrade或完整升级流程
哪些操作根本不会触发重用检查
策略只在特定路径下生效,其他改密方式一律绕过校验,这是最容易被忽略的盲区。
- 仅对
ALTER USER ... IDENTIFIED BY或密码过期强制修改生效 -
SET PASSWORD已在 8.0.19+ 被弃用,且不触发任何历史校验逻辑 - 已登录会话不受影响:策略变更后,当前连接仍可用旧密码继续操作,直到下次
ALTER USER - 首次设置密码不算“复用”,历史记录从第一次成功修改后才开始积累
- 不能用
SELECT authentication_string FROM mysql.user反查比对——该字段是内部 scrambler hash,与原始密码无确定关系
真正起作用的是服务端自动维护的 mysql.password_history 表,它只读、不可删、不可手动写入;所有历史哈希均由 MySQL 内部在每次合法 ALTER USER 后自动插入。想绕过这个机制自行建表拦截,反而会破坏一致性,得不偿失。


















