password_history 是 MySQL 8.0.19+ 内置全局策略参数,控制新密码不得与最近 N 次修改过的密码重复,由 MySQL 自动维护 mysql.password_history 表,无需手动建表;设为 3 表示需至少改密 3 次后方可重用首次密码,支持动态设置但需重启生效,与 password_reuse_interval(按天限制)可叠加使用。

password_history 是 MySQL 8.0+ 的全局策略参数,不是插件或额外表结构
MySQL 8.0.19 起正式支持 password_history,它控制的是“新密码不能与最近 N 次修改过的密码重复”——注意:是「修改次数」,不是「时间跨度」,也不是「是否在 password_history 表里存在」。它不依赖你手动建表,MySQL 内部自动维护 mysql.password_history 表(只读),你只需配好参数、重启服务即可生效。
常见误解是以为要先 CREATE TABLE 才能用这个功能,其实完全不需要;只要版本够、配置对、服务重启过,用户改密时就会触发校验。
-
password_history = 0表示禁用策略(默认值) - 设为
3意味着:用户必须至少改密 3 次后,才能重新用回第 1 次的密码 - 该参数作用范围是 Global,可动态设置:
SET GLOBAL password_history = 3;,但推荐写进配置文件并重启,避免服务重启后丢失 - 动态设置后,**已连接的会话不会立即感知新策略**,下次 ALTER USER 时才生效
配置文件里加 [mysqld] password_history=3 就完事?别跳过重启和权限检查
很多人改完 /etc/mysql/my.cnf 或 C:\Program Files\MySQL\MySQL Server X.X\my.ini 就以为搞定了,结果 ALTER USER 时不报错——大概率是没重启 mysqld 进程,或者配置没落到正确 section 下。
- 确认修改的是
[mysqld]段,不是[client]或[mysql] - Linux 下执行
sudo systemctl restart mysql(或mariadb),别只 kill 进程再手工启 - Windows 下要用服务管理器重启 “MySQLXX” 服务,直接双击 mysqld.exe 启动不加载 my.ini
- 重启后验证:
SELECT @@global.password_history;,输出应为 3;若仍是 0,说明配置未加载(路径错 / 权限不足 / 有语法错误)
ALTER USER 报 ERROR 3638?不是 bug,是策略正在起作用
当你设了 password_history = 3,然后用户连续改密两次就试图切回初始密码,就会遇到:ERROR 3638 (HY000): Cannot use these credentials for 'root@localhost' because they contradict the password history policy。这不是配置失败,恰恰说明策略生效了。
- 该错误只在
ALTER USER ... IDENTIFIED BY时触发,SET PASSWORD语句不走此校验(已弃用,不建议用) - 如果想绕过策略临时重置某用户密码(如管理员代操作),可用
ALTER USER 'u'@'h' IDENTIFIED WITH mysql_native_password BY 'xxx' PASSWORD HISTORY DEFAULT;,其中PASSWORD HISTORY DEFAULT强制继承全局值,但无法跳过校验;真正跳过只能临时设SET GLOBAL password_history = 0; - 用户级覆盖更灵活:
CREATE USER 'app'@'%' IDENTIFIED BY 'p' PASSWORD HISTORY 5;,此时该用户独立遵循 5 次限制,不受全局影响
和 password_reuse_interval 容易混淆,它们管的是两件事
password_history 看“改了多少次”,password_reuse_interval 看“隔了多少天”。二者可同时启用,MySQL 会做「与」判断:新密码必须既没出现在最近 N 次中,也没出现在最近 M 天内。
- 例如:
password_history = 3+password_reuse_interval = 90,意味着:即使用户改密满 3 次,但如果上次用该密码是 89 天前,仍不允许重用 - 两个参数都默认为 0(禁用),且都支持动态设置,但
password_reuse_interval单位是天,不能设小数 - 查策略实际生效情况,看
mysql.user表:SELECT user, host, password_reuse_history, password_reuse_time FROM mysql.user WHERE user = 'xxx';,注意字段名带下划线,不是驼峰
真正容易被忽略的是:password_history 不记录首次初始化密码(比如安装后第一次 set password),只从第一次 ALTER USER 开始计数;另外,如果用 replication 同步用户,password_history 策略不会同步,从库需单独配置。











