mysql 8.0中密码过期与强密码必须分两套机制独立配置:过期靠alter user password expire interval或default_password_lifetime,强密码必须启用validate_password插件并设为strong策略,二者互不触发、缺一不可。

MySQL 8.0 中密码过期和强密码必须分两套机制独立配置,缺一不可:过期靠 ALTER USER PASSWORD EXPIRE INTERVAL 或 default_password_lifetime,强密码则必须启用 validate_password 插件并设为 STRONG 策略——两者互不触发、互不替代。
确认 validate_password 插件已安装且处于 STRONG 模式
MySQL 8.0 默认不加载该插件,即使版本是 8.0.17+,password_history 和 password_reuse_interval 这类参数也完全无效,查 INFORMATION_SCHEMA.PLUGINS 返回空或状态为 DISABLED 就得立刻装。
- 执行
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'validate_password';,无结果或状态非ACTIVE就需安装 - Linux 下运行:
INSTALL PLUGIN validate_password SONAME 'validate_password.so'; - Windows 下运行:
INSTALL PLUGIN validate_password SONAME 'validate_password.dll'; - 必须用
SET PERSIST validate_password.policy = 2;(等价于STRONG),设成MEDIUM或LOW会导致history和reuse_interval被静默忽略 -
STRONG模式强制要求字典文件,否则任何密码设置都会失败并报错:Plugin 'validate_password' could not be initialized - 准备字典文件(如
/etc/mysql/weak-passwords.txt),确保 MySQL 进程可读:chown mysql:mysql /etc/mysql/weak-passwords.txt,再执行SET PERSIST validate_password.dictionary_file = '/etc/mysql/weak-passwords.txt';
设置密码 90 天过期策略(账户级优先于全局)
全局 default_password_lifetime 只影响后续新建用户,对已有用户完全无效;真正可控的是对每个账号单独执行 ALTER USER ... PASSWORD EXPIRE INTERVAL。
- 对指定用户启用 90 天过期:
ALTER USER 'app_user'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY; - 验证是否生效:
SELECT user, host, password_last_changed, password_lifetime FROM mysql.user WHERE user = 'app_user';,password_lifetime字段值为90才算成功 - 若用户密码是旧方式(如
SET PASSWORD)设置的,password_last_changed可能未更新,建议紧接执行一次ALTER USER 'app_user'@'localhost' IDENTIFIED BY 'newpass';强制刷新时间戳 - 全局默认策略(仅影响新用户):
SET PERSIST default_password_lifetime = 90;,需 MySQL 8.0.14+ 且启用persist_only模式才持久;否则用SET GLOBAL(重启失效)或写入my.cnf的[mysqld]段后重启 - 管理员账号(如
'root'@'localhost')务必显式设为PASSWORD EXPIRE NEVER,否则监控脚本或高可用切换可能因连接失败中断
用户登录时报 ERROR 1820 怎么办
这是密码已过期(password_expired = 'Y')的明确信号,此时不能执行任何非密码修改语句,包括 SELECT、SHOW DATABASES,必须立即重置密码并解除过期标记。
- 在当前会话中执行:
ALTER USER USER() IDENTIFIED BY 'new_secure_pass' PASSWORD EXPIRE NEVER; - 如果已断开连接,需用 root 或高权限账号代为操作:
ALTER USER 'broken_user'@'%' IDENTIFIED BY 'newpass' PASSWORD EXPIRE NEVER; - 切勿使用
SET PASSWORD FOR 'user'@'host' = 'xxx';—— 它只会改密,不会清除password_expired = 'Y',下次登录仍卡死 - 检查状态用:
SELECT user, host, password_expired, password_last_changed FROM mysql.user WHERE user = 'broken_user';
为什么改了配置但弱密码还能设成功
常见原因不是配置遗漏,而是策略未真正激活或被绕过:STRONG 模式未启用、字典路径错误/权限不足、或用户拥有 ALTER USER 权限自行执行 PASSWORD EXPIRE NEVER 解除了限制。
-
validate_password插件状态必须为ACTIVE,且validate_password.policy值必须是2(STRONG),SHOW VARIABLES LIKE 'validate_password%';可全量核对 - STRONG 模式下,
validate_password.dictionary_file必须指向一个真实存在、MySQL 进程可读的文件,路径错或权限不足时插件初始化失败,但 MySQL 不报错,只让所有密码校验退化为无策略状态 - 用户若拥有
ALTER USER权限,可随时执行ALTER USER ... PASSWORD EXPIRE NEVER绕过所有过期策略,生产环境应严格控制该权限 -
SET PASSWORD在 8.0 中已丧失过期控制能力,所有密码生命周期操作必须用ALTER USER语法,混用会导致策略失效却不报错
STRONG 策略和密码过期是两把锁,一把管“能不能设”,一把管“能用多久”;但字典文件缺失、插件未激活、权限失控这三处,最容易被当成配置成功而埋下隐患。











