MySQL无临时权限,只有临时账号,需先CREATE USER再GRANT,用户名带任务标识、限定IP、设密码策略及PASSWORD EXPIRE,权限最小化且显式授予CREATE TEMPORARY TABLES,禁用WITH GRANT OPTION,回收须手动DROP USER。

MySQL 没有“临时权限”这个东西,只有临时账号——权限依附于账号存在,所谓“临时访问”,本质是控制账号生命周期 + 最小化授予权限。
CREATE USER 必须先做,GRANT 不能自动建用户
MySQL 8.0+ 默认禁用 GRANT 自动建用户行为。直接写 GRANT SELECT ON `log_db`.* TO 'task_user'@'10.10.20.%' 会报错 ERROR 1410 (42000): You are not allowed to create a user with GRANT。
- 必须拆成两步:先
CREATE USER,再GRANT - 用户名建议带任务标识,比如
tmp_etl_20260702,避免重名或误复用 - 主机名别用
'%',优先指定来源 IP 段(如'10.10.20.%')或跳板机地址 - 密码需满足当前
validate_password策略(例如至少 8 位、大小写+数字+符号),否则CREATE USER直接失败
PASSWORD EXPIRE 是唯一靠谱的“有效期”机制
MySQL 原生不支持 GRANT ... UNTIL 或权限级过期。能落地的只有账号级密码过期控制,且仅对新登录生效。
- 创建时设相对过期:
CREATE USER 'tmp_etl_20260702'@'10.10.20.%' IDENTIFIED BY 'Etl@2026!' PASSWORD EXPIRE INTERVAL 2 DAY - 或事后补设精确时间:
ALTER USER 'tmp_etl_20260702'@'10.10.20.%' PASSWORD EXPIRE AT '2026-07-04 15:00:00' - 必须确保全局
default_password_lifetime≠ 0,否则用户级PASSWORD EXPIRE不生效 - 注意:过期只阻断新连接,已建立的长连接(比如 ETL 工具维持的连接池)仍可执行操作,直到断开
权限必须卡死到库表级,且显式授予 CREATE TEMPORARY TABLES
临时任务常涉及中间计算,但 CREATE TEMPORARY TABLES 权限不会随 SELECT 或 ALL PRIVILEGES 自动继承,必须单独给,且绑定具体数据库。
- 最小化授权示例:
GRANT SELECT, INSERT, CREATE TEMPORARY TABLES ON `log_db`.* TO 'tmp_etl_20260702'@'10.10.20.%' - 禁止
WITH GRANT OPTION,防止权限扩散 - 若需访问
performance_schema查锁或慢日志,得额外执行:GRANT SELECT ON performance_schema.* TO 'tmp_etl_20260702'@'10.10.20.%'(注意暴露风险) - 执行完记得
FLUSH PRIVILEGES,尤其在低版本或非标准部署中
回收权限不能靠 EVENT,得靠外部调度或人工确认
MySQL 的事件调度器默认不能执行 REVOKE 或 DROP USER,即使开启 event_scheduler=ON 且用户有 EVENT 权限,也受限于权限上下文——事件以 DEFINER 身份运行,但 DEFINER 若无足够权限,语句照样失败。
- 真要自动回收,得用外部定时任务(如 cron + mysql 客户端)调
REVOKE ... FROM ...或DROP USER ... -
REVOKE后必须跟FLUSH PRIVILEGES才生效(部分版本可省略,但建议写全) - 更稳妥的做法是:任务结束即手动执行
DROP USER 'tmp_etl_20260702'@'10.10.20.%',一劳永逸 - 别依赖注释或文档记“三天后删”,90% 会忘;建议在创建账号时同步发一条钉钉/企微提醒给自己
最易被忽略的点是:已有连接不受 PASSWORD EXPIRE 影响,而第三方工具往往长连接不断开——这意味着账号“过期”后,它还在跑任务。真正安全的做法,永远是任务结束立刻删用户,而不是等它“到期”。


















