ALTER USER ... PASSWORD EXPIRE 是唯一有效方式,它将 password_expired 设为 'Y',用户下次登录后首个非 SET 语句(如 SELECT 1)触发 ERROR 1820;SET PASSWORD 和直接更新 mysql.user 均无效,且需确保 default_password_lifetime ≠ 0、用户无 ALTER USER 权限。

ALTER USER ... PASSWORD EXPIRE 是唯一有效方式
MySQL 8.0 不再支持用 SET PASSWORD 或直接更新 mysql.user 表来触发首次登录改密。必须显式执行 ALTER USER 'user'@'host' PASSWORD EXPIRE;,且该语句会将 password_expired 字段设为 'Y',后续登录认证成功后,**首个非 SET 类语句(如 SELECT 1、SHOW DATABASES)才会报 ERROR 1820**。
常见错误现象:执行了 SET PASSWORD FOR 'u'@'h' = 'xxx'; 后用户仍能正常执行查询——因为该操作完全不修改 password_expired 字段,也不重置 password_last_changed 时间。
- 必须确保执行者拥有
ALTER USER权限 - 目标用户必须已存在,否则报
ERROR 1396 - 全局变量
default_password_lifetime不能为 0(查法:SELECT @@default_password_lifetime;),否则所有PASSWORD EXPIRE均失效
为什么 PASSWORD EXPIRE INTERVAL N DAY 不适合“首次登录”场景
PASSWORD EXPIRE INTERVAL 1 DAY 看似能实现“下次登录就过期”,但实际逻辑是:从当前 password_last_changed 时间起算 N 天后过期。若该字段为空或极旧(如初始安装时的值),可能导致“立即过期”效果不稳定,甚至跳过拦截。
更关键的是:ERROR 1820 只在新连接中触发,对已建立的连接无影响;而 INTERVAL 模式依赖时间推算,容易因系统时间偏差、字段未更新等导致行为不可控。
- 首次登录强制改密,应使用
PASSWORD EXPIRE(无INTERVAL),它写死password_expired = 'Y',不依赖时间计算 - 想让已有用户“下次登录即改密”,不要用
ALTER USER ... IDENTIFIED BY 'xxx' PASSWORD EXPIRE INTERVAL 1 DAY,而要用ALTER USER ... IDENTIFIED BY 'xxx' PASSWORD EXPIRE; - 新建用户时可一步到位:
CREATE USER 'u'@'localhost' IDENTIFIED BY 'pwd' PASSWORD EXPIRE;
用户登录后没报 ERROR 1820?优先检查这三点
即使执行了 ALTER USER ... PASSWORD EXPIRE;,用户仍可能跳过改密流程,最常被忽略的原因有:
- 该用户本身拥有
ALTER USER权限——MySQL 允许这类用户绕过强制重置 -
default_password_lifetime = 0(全局关闭过期策略),此时PASSWORD EXPIRE完全不生效 - 客户端连接时自动执行了
SET NAMES utf8mb4、SET autocommit=1等语句,误以为“已登录成功”;其实ERROR 1820要等到第一条非SET语句才抛出
验证是否真生效,可在登录后立刻执行 SELECT 1;,而不是先跑 USE db; 或其他 SET 命令。
重置密码时别让过期状态失效
用户完成首次改密后,如果管理员后续用 SET PASSWORD 或旧式 UPDATE mysql.user 修改密码,会导致 password_expired 字段被保留但 password_last_changed 不更新,下次又立刻触发 ERROR 1820。
正确做法是:用 ALTER USER 同时完成密码更新与状态控制。
- 仅改密、保留原过期策略:
ALTER USER 'u'@'h' IDENTIFIED BY 'newpass'; - 改密且取消过期:
ALTER USER 'u'@'h' IDENTIFIED BY 'newpass' PASSWORD EXPIRE NEVER; - 改密且重新设为“下次登录强制改密”:
ALTER USER 'u'@'h' IDENTIFIED BY 'newpass' PASSWORD EXPIRE;
最容易被忽略的一点:所有这些操作都只影响**新建立的连接**,正在运行的会话不会中断,也不会重新触发改密流程。


















