password expire 是 mysql 唯一可行的账号生命周期控制手段,通过密码过期强制用户无法登录,而非回收权限;创建用户须用 create user + password expire after n,不可跳过建号直接 grant,且需满足密码策略、显式授权、最小权限、禁用 show databases、刷新权限、关闭全局 default_password_lifetime 等严格要求。

PASSWORD EXPIRE 是唯一能落地的“生命周期”控制手段,MySQL 本身不支持账号自动删除或权限定时失效。所谓“有生命周期”,本质是让账号在指定时间后无法登录——靠密码过期机制兜底,不是靠权限回收。
创建用户时必须用 CREATE USER + PASSWORD EXPIRE AFTER N
不能跳过建号直接 GRANT,否则报错 ERROR 1410 (42000): You are not allowed to create a user with GRANT。
也不能只给 USAGE,那等于只开了连接通道,后续所有操作都会被拒(ERROR 1044)。
-
CREATE USER 'temp_john'@'192.168.5.%' IDENTIFIED BY 'J0hn@2026' PASSWORD EXPIRE AFTER 5;—— 创建即生效,5 天后首次执行语句就卡在ERROR 1820 - 主机名别写
%,优先锁定 IP 段,降低暴露面 - 密码必须满足当前
validate_password策略,否则CREATE USER直接失败 - 低版本 MySQL(如 5.7)完全不识别
PASSWORD EXPIRE AFTER,执行会静默失败或报ERROR 1064
GRANT 前要显式限定库表,禁用通配符和 WITH GRANT OPTION
临时账号权限必须最小化:只读就只给 SELECT,调试可能需要 EXECUTE,但绝不能给 CREATE ROUTINE 或 ALTER。权限范围越宽,失控风险越大。
- 正确写法:
GRANT SELECT, SHOW VIEW ON `report_db`.* TO 'temp_john'@'192.168.5.%'; - 错误写法:
GRANT ALL ON *.* TO ...或GRANT SELECT ON `report_%`.*(MySQL 不支持库名通配符) - 务必补一句:
REVOKE SHOW DATABASES ON *.* FROM 'temp_john'@'192.168.5.%';,否则第三方工具能列全库名,暴露架构 - 显式执行
FLUSH PRIVILEGES;,避免跨版本或配置差异导致权限未加载
全局策略 default_password_lifetime 必须设为 0
如果没关全局策略,用户级的 PASSWORD EXPIRE AFTER 5 可能被覆盖。比如全局设了 90 天,那用户实际过期时间就是 min(5, 90) = 5 天;但如果全局是 0(永不过期),用户策略才真正生效。
- 执行:
SET PERSIST default_password_lifetime = 0;(需SYSTEM_VARIABLES_ADMIN权限) - 注意:
default_password_lifetime = 0不代表“永久有效”,只是跳过检查;一旦手动触发过期(如ALTER USER ... PASSWORD EXPIRE),仍会立即生效 - 该设置影响所有新用户,旧用户不受影响,但建议统一管理
别指望事件调度器自动 DROP USER 就万事大吉
EVENT 只能锁账号或删号,但已建立的长连接不会中断——第三方工具维持的连接池照样跑查询,权限照常生效。你看到“已过期”,其实连接还活着。
-
ALTER USER 'temp_john'@'192.168.5.%' ACCOUNT LOCK;只拦新连接 -
DROP USER 'temp_john'@'192.168.5.%';是即时生效,但不会杀掉活跃会话 - 真要清理,得先查
information_schema.PROCESSLIST确认无活跃连接,再删号 - 主从架构下,事件必须在所有节点定义一致,且
event_scheduler=ON才可靠
密码过期机制只是“登录闸机”,不是“权限开关”。第三方工具若不支持自动处理 ERROR 1820(绝大多数都不支持),它连一次有效查询都完不成——别指望它能自己重置密码。











