mysql 8.0.12+ 支持 alter user ... password expire interval 90 day 设置密码90天过期,登录时超期即阻断并提示重置;仅作用于指定用户,依赖 password_last_changed 时间戳,需手动刷新旧密码时间戳,全局默认策略通过 set persist default_password_lifetime = 90 配置。

MySQL 8.0+ 中设置密码过期策略的正确方式
MySQL 本身不支持“每90天强制改密”的自动提醒或拦截机制,但可通过 ALTER USER ... PASSWORD EXPIRE INTERVAL 90 DAY 启用密码生命周期控制——用户下次登录时若密码已超期,会被阻断并提示必须重置。
- 仅适用于 MySQL 8.0.12 及以上版本;5.7 不支持
PASSWORD EXPIRE INTERVAL,只能设为PASSWORD EXPIRE(立即过期) - 策略作用于具体用户,不是全局配置,需对每个账户单独执行
- 过期判断基于密码最后修改时间(
password_last_changed字段),而非创建时间 - 若用户有
CREATE USER或ALTER USER权限,可能自行绕过:执行ALTER USER ... PASSWORD EXPIRE NEVER即可禁用
执行命令与验证步骤
以用户 'app_user'@'localhost' 为例:
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表示策略已生效;NULL表示沿用全局默认(由default_password_lifetime系统变量决定) - 修改后无需重启 MySQL,也不需要 flush privileges
- 注意:如果该用户当前密码是通过
SET PASSWORD或旧版mysqladmin设置的,password_last_changed可能未更新,建议随后执行一次ALTER USER ... IDENTIFIED BY 'xxx'强制刷新时间戳
全局默认策略与例外处理
若希望所有新建用户默认 90 天过期,可设置系统变量:
SET PERSIST default_password_lifetime = 90;
但要注意:
-
SET PERSIST要求 MySQL 8.0.14+ 且启用 persist_only 模式,否则用SET GLOBAL(重启失效) - 已有用户不受影响,只对后续
CREATE USER生效 - 某些场景需排除管理员账户(如
'root'@'localhost'),应显式为其设置PASSWORD EXPIRE NEVER,否则高可用切换或监控脚本可能因密码过期中断 - 应用连接池(如 HikariCP、Druid)在复用连接时不会触发过期检查,只有新建连接会校验——所以真正阻断发生在连接重建时刻,不是 SQL 执行中
客户端报错与用户实际体验
密码过期后,用户首次尝试登录会收到明确错误:
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
此时只能执行:
ALTER USER USER() IDENTIFIED BY 'new_password';
- 不能用
SET PASSWORD,MySQL 8.0+ 过期状态下该语句被禁用 -
USER()是安全写法,避免硬编码用户名;若用程序自动处理,需确保连接用户具备ALTER USER权限 - 部分 JDBC 驱动(如 mysql-connector-java 8.0.23+)支持自动重试改密流程,但需开启
allowPublicKeyRetrieval=true&requireSSL=false等配合参数,否则直接抛异常
真正难处理的是无交互环境:定时任务、ETL 脚本、监控探针。它们无法响应交互式改密提示,一旦密码过期就静默失败。这类账户建议单独管理,不启用自动过期,而靠外部密码轮转系统统一维护。











