MySQL不支持账号自动删除或权限定时失效,唯一可行的临时有效期方案是CREATE USER + PASSWORD EXPIRE INTERVAL N DAY,需配合SET PERSIST default_password_lifetime = 0、显式最小化授权、禁用SHOW DATABASES及FLUSH PRIVILEGES,过期后仅阻断新操作,已存在连接不受影响。

MySQL 本身不支持“账号自动删除”或“权限定时失效”,所谓“临时有效期”,只能靠 PASSWORD EXPIRE 机制实现——账号不会消失,但过期后无法执行任何语句,等效于失效。
必须用 CREATE USER + PASSWORD EXPIRE INTERVAL 一步创建
不能跳过建号直接 GRANT,否则报错 ERROR 1410 (42000): You are not allowed to create a user with GRANT;也不能先 GRANT USAGE 占位,那会导致后续所有操作都报 ERROR 1044。
- 正确写法(MySQL 8.0.19+):
CREATE USER 'tmp_api_202609'@'10.20.30.%' IDENTIFIED BY 'T3mp#902' PASSWORD EXPIRE INTERVAL 7 DAY; - 主机名别写
%,优先锁定 IP 段,降低暴露面 - 密码必须满足当前
validate_password策略(比如至少 8 位、含大小写字母+数字),否则CREATE USER直接失败 - 低版本(如 5.7 或 8.0.11 以下)不识别该语法,执行会静默失败或报
ERROR 1064
default_password_lifetime 必须设为 0 才能让用户级过期生效
如果全局策略没关,用户设的 7 天可能被覆盖成 min(7, 90) = 7,看似没影响;但一旦全局设了 0(永不过期),用户级 PASSWORD EXPIRE 就完全失效。
- 执行:
SET PERSIST default_password_lifetime = 0;(需SYSTEM_VARIABLES_ADMIN权限) - 该设置只影响新创建的用户,旧用户不受影响,但建议统一管理
- 注意:
default_password_lifetime = 0不代表“永久有效”,只是跳过检查;手动触发过期(如ALTER USER ... PASSWORD EXPIRE)仍会立即生效
授权必须显式、最小化,且禁用 SHOW DATABASES
过期只拦登录,不拦已建立的连接;权限给宽了,哪怕账号“过期”了,长连接照样能读写——所以授权比过期时间更重要。
- 只授必要权限,例如只读就只给
SELECT, SHOW VIEW:GRANT SELECT, SHOW VIEW ON `report_v3`.* TO 'tmp_api_202609'@'10.20.30.%'; - 必须补一句:
REVOKE SHOW DATABASES ON *.* FROM 'tmp_api_202609'@'10.20.30.%';,否则第三方工具能列全库名,暴露架构 - MySQL 不支持
ON `report_%`.*这类通配符库名,跨库访问要逐个GRANT - 显式执行:
FLUSH PRIVILEGES;,避免某些部署环境因缓存导致权限未加载
过期后行为和清理不能依赖自动机制
账号过期后,用户首次执行任意语句就会卡在 ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement;但已有连接不会中断,数据仍在被读取。
- 真正的清理还得靠人工或定时脚本执行
DROP USER 'tmp_api_202609'@'10.20.30.%'; - 可用查询识别待清理账号:
SELECT User, Host, password_last_changed FROM mysql.user WHERE User LIKE 'tmp_%' AND password_last_changed - 别指望
EVENT自动删用户或改权限——它默认不能执行GRANT/REVOKE/DROP USER,即使开了也受限于权限上下文


















