mysql 8.0.12+支持account expire语法设置账号过期时间,需用create user或alter user配合'yyyy-mm-dd'格式日期(如account expire '2025-06-30'),now表示立即过期,never取消过期;过期后新登录报error 1820,实际状态查mysql.user表password_expired字段或information_schema.user_attributes中account_expires字段。

MySQL 8.0+ 中用 ACCOUNT EXPIRE 设置账号过期时间
MySQL 8.0.12 起才支持 ACCOUNT EXPIRE 语法,低于这个版本直接执行会报错 ERROR 1064 (42000)。确认版本是第一步:
SELECT VERSION();返回值必须 ≥
8.0.12 才能继续。创建或修改用户时指定过期日期
过期时间必须是未来某个具体日期(YYYY-MM-DD 格式),不能是相对时间(比如“30天后”)。MySQL 不解析自然语言或时间偏移量。
常见写法:
- 新建用户并设过期日:
CREATE USER 'dev_user'@'%' IDENTIFIED BY 'pwd123' ACCOUNT EXPIRE '2025-06-30';
- 修改已有用户过期时间:
ALTER USER 'dev_user'@'%' ACCOUNT EXPIRE '2025-06-30';
- 立即过期(等效于禁用):
ALTER USER 'dev_user'@'%' ACCOUNT EXPIRE NOW;
- 取消过期(恢复为永不过期):
ALTER USER 'dev_user'@'%' ACCOUNT UNLOCK ACCOUNT EXPIRE NEVER;
注意:ACCOUNT UNLOCK是独立操作,和过期无关,但常一起用以防被锁。
账号过期后实际表现与验证方式
过期不等于删除,用户记录仍在 mysql.user 表中,只是登录会被拒绝。错误信息是:ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.——这个提示有误导性,它其实也覆盖了过期场景,不是真要你改密码。
验证是否已过期:
- 查
mysql.user表:SELECT user, host, account_locked, password_expired, password_last_changed, password_lifetime FROM mysql.user WHERE user = 'dev_user';
其中password_expired字段为Y表示已过期(注意:该字段名有历史包袱,实际反映的是ACCOUNT EXPIRE状态) - 更准确的方式是查
information_schema.USER_ATTRIBUTES(MySQL 8.0.19+):SELECT * FROM information_schema.USER_ATTRIBUTES WHERE USER = 'dev_user';
看account_expires字段值
容易被忽略的权限与兼容性细节
ACCOUNT EXPIRE 是 DDL 操作,需要 CREATE USER 或 ALTER USER 权限,普通 GRANT OPTION 不够。如果用低权限账号执行,会报 ERROR 1227 (42000): Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation。
另外要注意:
- 过期时间按服务器本地时区解释,不是 UTC,也不是客户端时区
- 如果服务器时间不准(比如没开 NTP 同步),可能导致提前或延后失效
- MySQL 5.7 及更早版本完全不支持该语法,强行使用会直接报错退出,不会静默忽略
- 某些旧版客户端(如 MySQL Workbench 8.0.20 之前)在用户过期后仍可能缓存连接,表现为“看起来还能连”,实则是复用旧连接;真正的新连接会失败
过期机制本身不触发自动清理动作,也不会发通知,所有依赖需自行监控 password_expired 字段或集成外部巡检脚本。











