MySQL 8.0+ 通过 ALTER USER 语句设置 PASSWORD EXPIRE 属性实现密码到期强制重置,该策略绑定用户账户、写入 mysql.user 表元数据,仅 ALTER USER 可更新,SET PASSWORD 无效;default_password_lifetime 仅影响新建用户默认值。

MySQL 8.0+ 怎么让密码到期自动要求重置
MySQL 8.0 开始原生支持密码过期策略,靠的是 PASSWORD EXPIRE 属性,不是插件也不是配置文件改参数。它直接绑定在用户账户上,下次登录就会强制走 ALTER USER ... IDENTIFIED BY 流程。
常见错误是以为设了全局变量(比如 default_password_lifetime)就万事大吉——其实那只是新用户的默认值,已有用户不受影响;还有人试 SET PASSWORD 后立刻 PASSWORD EXPIRE,结果报错:MySQL 要求必须用 ALTER USER 语句组合操作。
-
ALTER USER 'alice'@'%' PASSWORD EXPIRE;—— 立即过期,下次登录就卡住 -
ALTER USER 'alice'@'%' PASSWORD EXPIRE INTERVAL 90 DAY;—— 90 天后过期 -
ALTER USER 'alice'@'%' PASSWORD EXPIRE NEVER;—— 取消过期(注意不是DEFAULT)
为什么 ALTER USER 才生效,而 SET PASSWORD 不行
因为 PASSWORD EXPIRE 是用户属性(account lock / password history / password reuse 都同理),而 SET PASSWORD 只改密码哈希,不碰元数据字段。MySQL 把这些策略存在 mysql.user 表的 password_expired、password_last_changed、password_lifetime 列里,只有 ALTER USER 会更新它们。
实操中容易踩的坑:用 root 执行完 ALTER USER ... PASSWORD EXPIRE,自己切到该用户登录时看到 ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement,这是正常现象——但别慌着用 SET PASSWORD,必须用 ALTER USER CURRENT_USER() IDENTIFIED BY 'newpass';,否则还是报错。
default_password_lifetime 全局设置到底管谁
它只影响「新建用户」的默认 PASSWORD EXPIRE 行为,不影响已有用户,也不等于“所有密码 90 天后统一过期”。比如你设 SET PERSIST default_password_lifetime = 60;,之后创建的用户如 CREATE USER 'bob'@'localhost';,其 password_lifetime 字段就是 60;但 alice 的过期时间仍按她被 ALTER USER 设置过的值走。
性能和兼容性上没开销,纯元数据标记;不过要注意:如果设成 0,新建用户默认永不过期;设成 DEFAULT(即 NULL),则取决于 MySQL 版本默认值(8.0.19+ 默认是 0)。
密码过期后用户能做什么、不能做什么
过期用户登录成功,但任何 DML/DQL/DDL 操作都会被拦住,只允许执行 ALTER USER ... IDENTIFIED BY。连 SELECT 1; 都不行,报错仍是 ERROR 1820。
例外情况:如果用户有 CONNECTION_ADMIN 或 SUPER 权限,并且连接时加了 --skip-grant-tables(不推荐),可以绕过——但这属于运维应急手段,不是设计行为。
容易被忽略的一点:MySQL 不主动发邮件、不记录“过期提醒日志”,也不会在过期前自动告警。你得自己查 SELECT user, host, password_last_changed, password_lifetime FROM mysql.user;,结合当前时间算剩余天数。


















