mysql 8.0+无原生密码过期提醒功能,仅支持到期后强制重置;需用alter user显式设置password expire interval、配合default_password_lifetime全局配置,并手动检查password_last_changed计算过期时间。

MySQL 8.0+ 不提供“过期提醒”功能,只支持密码到期后强制重置;所谓“提醒”必须靠外部脚本或监控系统实现,原生无通知机制。
设置用户密码有效期:用 ALTER USER PASSWORD EXPIRE INTERVAL 显式指定
这是最可靠、最可控的方式,适用于关键账号(如 admin、backup)或需差异化策略的场景。
-
PASSWORD EXPIRE INTERVAL 90 DAY表示从password_last_changed时间起,90 天后自动进入过期状态 -
PASSWORD EXPIRE NEVER显式禁用过期(注意不是PASSWORD EXPIRE DEFAULT,后者会继承全局值) -
PASSWORD EXPIRE不带时间,表示立即过期,下次登录即报ERROR 1820 - 必须精确匹配
user@host,'root'@'localhost'和'root'@'%'是两个独立账户
让新用户默认遵守有效期:配置 default_password_lifetime
该变量只影响「后续新建」的用户,对已有用户完全无效——这是线上事故最高发点。
- 永久生效:在
/etc/my.cnf的[mysqld]段添加default_password_lifetime = 90,然后重启mysqld - 临时测试可用
SET GLOBAL default_password_lifetime = 90,但重启后丢失 - 验证是否生效:执行
SELECT @@default_password_lifetime;,返回90才算成功 - 设为
0表示永不过期;设为NULL表示交由用户级策略决定(不推荐)
查哪些用户已经过期或即将过期:别只看 password_expired
password_expired = 'Y' 只代表被手动设为过期,不代表“已超期”。真正超期要靠计算:
- 查显式过期用户:
SELECT user, host FROM mysql.user WHERE password_expired = 'Y'; - 查自动超期用户(含已过期 + 7 天内将过期):
SELECT user, host, password_last_changed, TIMESTAMPADD(DAY, @@default_password_lifetime, password_last_changed) AS expires_at FROM mysql.user WHERE password_last_changed IS NOT NULL AND @@default_password_lifetime > 0 AND TIMESTAMPADD(DAY, @@default_password_lifetime, password_last_changed) -
password_last_changed是 UTC 时间,和本地时区无关
密码过期后用户能做什么?别指望 SELECT 或连接池自动处理
过期用户仍可建立连接,但几乎不能执行任何业务语句:
- 允许执行:
SET类命令(如SET NAMES utf8mb4)、SELECT(仅限SELECT 1这类无表查询)、UNLOCK TABLES、ALTER USER ... IDENTIFIED BY - 禁止执行:
SELECT * FROM t、INSERT、SHOW TABLES、任何 DML/DDL —— 全部报ERROR 1820 (HY000) - 应用连接池(如 HikariCP)若未配置
connection-test-query或健康检查逻辑,可能持续复用过期连接,直到首次执行业务 SQL 才暴露问题
真正落地时,default_password_lifetime 只是半截路;存量账号必须用 ALTER USER 逐个覆盖,漏掉 root 或 monitor 这类高权限账号,就是生产隐患。计算过期时间得自己写脚本,MySQL 不给你算剩余天数,也不发邮件提醒。











