必须同时设置password_history和password_reuse_interval且均非零,否则策略静默失效;任一为0(含默认值)则完全不触发校验,即使用户复用刚改过的密码也无报错。

必须同时设置 password_history 和 password_reuse_interval,且二者都为非零值,否则策略完全不生效。
为什么只设 password_history 没反应
MySQL 8.0.19+ 的密码重用校验是“双条件绑定”:任一参数为 0(包括默认值),整个策略静默失效。常见错误是只执行 SET PERSIST password_history = 5;,却忽略 password_reuse_interval。此时即使用户试图复用刚改过的密码,也不会报错——不是延迟生效,而是根本没启动校验逻辑。
-
password_history = 5且password_reuse_interval = 0→ 只按次数拦,但 MySQL 实际行为是:**全都不拦** -
password_history = 0且password_reuse_interval = 180→ 同样不拦,报错ERROR 3753 (HY000): The 'password_reuse_interval' option is not supported for accounts without a password history policy - 两个变量必须用
SET PERSIST设置(写入mysqld-auto.cnf),SET GLOBAL重启即丢,且不触发持久化校验
用户级配置必须显式声明 PASSWORD HISTORY 和 PASSWORD REUSE INTERVAL
全局变量只是默认值,对已有用户无效。phpMyAdmin 界面改密、SET PASSWORD 命令、或 root 执行 ALTER USER 'u'@'h' IDENTIFIED BY 'p' 都不会激活历史检查——除非语句里明确带 PASSWORD HISTORY N 和 PASSWORD REUSE INTERVAL M DAY。
- 正确写法:
ALTER USER 'alice'@'%' PASSWORD HISTORY 5 PASSWORD REUSE INTERVAL 180 DAY; - 错误写法:
ALTER USER 'alice'@'%' IDENTIFIED BY 'newpass';→ 不查历史 - 老用户若仍用
mysql_native_password插件,先切插件:ALTER USER 'alice'@'%' IDENTIFIED WITH caching_sha2_password BY 'newpass'; -
PASSWORD HISTORY DEFAULT表示继承全局值,但前提是全局两个参数都已设为非零
mysql.password_history 表不能手动干预
该表由 MySQL 自动维护,存的是哈希和时间戳,仅用于内部校验。任何尝试 INSERT、UPDATE 或 DELETE 都会报错 ERROR 3716 (HY000): The 'mysql.password_history' table is read-only.
- 历史记录从第一次执行带
PASSWORD HISTORY的ALTER USER开始积累,之前密码不补录 - 空密码不会写入该表,
password_reuse_interval对其无效 - 查记录需有
SELECT权限:SELECT User, Host, Password, Timestamp FROM mysql.password_history WHERE User = 'alice'; - 没有命令能清空单个用户的历史,只能等新密码覆盖旧条目(按
password_history数值滚动)
验证策略是否真生效的唯一可靠方式
别只查 SHOW VARIABLES LIKE 'password%';,两个变量都非零只是前提。真正验证得靠行为:用目标用户执行一次改密,再立刻改回刚用过的密码。
- 成功拦截会报
ERROR 3031 (HY000): Cannot use the password from password history.或ERROR 3638 (HY000) - 如果没报错,检查三点:MySQL 版本是否 ≥ 8.0.19、用户插件是否为
caching_sha2_password、客户端是否用的是ALTER USER ... PASSWORD HISTORY而非图形界面或SET PASSWORD - 已登录会话不受新策略影响,必须重新连接(或断开重连)才能触发校验
最易被忽略的点:策略只在用户自己执行 ALTER USER ... IDENTIFIED BY 时触发,管理员代改密码(如 root 改 'u'@'h')若未显式加 PASSWORD HISTORY 子句,就不会写入历史记录——这意味着后续该用户自己改密时,可能因历史为空而绕过检查。











