MySQL 8.0+ 密码过期需用 ALTER USER 显式设置,SET PASSWORD 不再支持过期控制;新建用户强制首次改密用 PASSWORD EXPIRE,禁用过期用 NEVER,设 90 天过期用 INTERVAL 90 DAY;账户级策略优先于全局 default_password_lifetime。

MySQL 8.0+ 中密码过期策略如何设置
MySQL 8.0 开始默认启用密码过期机制,但新用户不会自动过期——必须显式配置。关键在于 password_expired 属性和 password_history/password_reuse_interval 等策略参数,它们不作用于单条 CREATE USER 语句,而是依赖全局或账户级的 ALTER USER 操作。
- 新建用户时强制首次登录改密:
CREATE USER 'u1'@'localhost' IDENTIFIED BY 'oldpass' PASSWORD EXPIRE; - 让已有用户下次登录必须改密:
ALTER USER 'u1'@'localhost' PASSWORD EXPIRE; - 禁用过期(恢复为永不过期):
ALTER USER 'u1'@'localhost' PASSWORD EXPIRE NEVER; - 设为 90 天后过期:
ALTER USER 'u1'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;
为什么 SET PASSWORD 不再生效,而 ALTER USER 成了唯一方式
MySQL 5.7.6 起弃用 SET PASSWORD 语句对密码过期状态的控制能力;8.0 后彻底移除其修改过期属性的功能。直接执行 SET PASSWORD FOR 'u1'@'localhost' = 'xxx' 只会重置密码, 不会清除过期标记 ,用户仍会在下次登录时被卡在改密流程。
- 错误做法(改密但不解锁):
SET PASSWORD FOR 'u1'@'localhost' = 'newpass123'; - 正确做法(重置密码 + 解除过期):
ALTER USER 'u1'@'localhost' IDENTIFIED BY 'newpass123' PASSWORD EXPIRE NEVER; - 如果只想重置密码并保留过期策略,不加
PASSWORD EXPIRE子句即可
登录时提示 ERROR 1820:You must SET PASSWORD before executing this statement 怎么办
这是 MySQL 强制改密流程触发的典型错误,说明该账户处于 password_expired = 'Y' 状态,且当前 session 尚未完成密码更新。此时不能执行任何非密码修改类语句(包括 SELECT、SHOW DATABASES)。
- 必须使用
ALTER USER …… IDENTIFIED BY(不是SET PASSWORD):ALTER USER USER() IDENTIFIED BY 'new_secure_pass'; - 若已断开连接,需用高权限账号(如 root)代为重置:
ALTER USER 'u1'@'localhost' IDENTIFIED BY 'newpass' PASSWORD EXPIRE NEVER; - 检查状态可查:
SELECT user, host, password_expired FROM mysql.user WHERE user = 'u1';
全局策略与账户级策略的优先级关系
MySQL 支持两层密码策略:全局系统变量(如 default_password_lifetime)和账户级显式设置。后者永远优先——哪怕全局设为 0(永不过期),只要对某个用户执行了 PASSWORD EXPIRE,该用户仍会过期。
- 查看全局默认生命周期:
SELECT @@default_password_lifetime;(0 表示永不过期)
- 修改全局策略(影响后续新建用户,不影响已有用户):
SET PERSIST default_password_lifetime = 180; - 账户级设置一旦存在,就覆盖全局值;用
PASSWORD EXPIRE NEVER可显式解除继承 -
password_history和password_reuse_interval同样遵循账户 > 全局的优先级,且仅在用户改密时校验(不阻止登录)
实际操作中容易忽略的是:密码过期状态不随密码重置自动清除,也不受全局策略动态调整影响。每次变更都要明确指定 PASSWORD EXPIRE 子句,否则策略残留会导致后续维护混乱。






























