必须显式授予create temporary tables权限才能创建临时表,该权限独立于create和select,仅在库级生效且需指定db_name.*,不支持全局或表级授权。

用户必须显式获得 CREATE TEMPORARY TABLES 权限才能执行 CREATE TEMPORARY TABLE,默认不带、不继承、不隐含——哪怕你已经给了 CREATE 或 SELECT 也完全没用。
为什么 GRANT CREATE 不等于能建临时表
MySQL 把普通表和临时表的创建权限拆得非常彻底:CREATE 只管建持久表(比如 CREATE TABLE t1),而 CREATE TEMPORARY TABLES 是独立权限位,存于 mysql.db 表中,只在库级生效。
-
GRANT CREATE ON mydb.* TO 'u'@'%'→ 允许建mydb.t1,但CREATE TEMPORARY TABLE t2仍报ERROR 1142 (42000) -
GRANT SELECT ON mydb.* TO 'u'@'%'→ 能查,但连CREATE TEMPORARY TABLE AS SELECT都会卡在权限检查阶段 -
USAGE用户(仅登录)或ALL PRIVILEGES(MySQL 8.0+ 默认不含该权限)都不自动包含它
必须用 ON db_name.* 显式授权,不能省略数据库名
这个权限不支持全局 *.*(5.7 及以前直接报错;8.0+ 虽语法通过但语义模糊,不推荐),也不能写成 ON mydb(缺 .* 会被当表名,触发 ERROR 1144)。
- 正确写法:
GRANT CREATE TEMPORARY TABLES ON app_db.* TO 'app_user'@'10.0.1.%'; - 若需多库支持,得逐个授:
GRANT CREATE TEMPORARY TABLES ON log_db.* TO 'app_user'@'10.0.1.%'; - 执行后无需
FLUSH PRIVILEGES(GRANT语句已实时更新内存权限缓存)
建完临时表却 INSERT 失败?不是权限没给全,是源表权限另算
有 CREATE TEMPORARY TABLES 只代表你能“建壳”,不代表你能“灌数据”。INSERT / SELECT 的数据来源(比如 FROM real_table)仍受独立权限约束。
-
CREATE TEMPORARY TABLE tmp AS SELECT * FROM orders;→ 要求对orders有SELECT权限 -
INSERT INTO tmp SELECT * FROM users;→ 同样要SELECTonusers,且INSERTontmp自动允许(临时表写入不额外校验) - 常见误操作:只授了
CREATE TEMPORARY TABLES,忘了同步给源表SELECT,结果卡在 INSERT 阶段报错,容易误判为临时表权限问题
临时表权限无法跨库引用,也不能授给单个表
权限绑定的是「数据库名」,不是表名,所以以下两种写法都无效:
-
GRANT CREATE TEMPORARY TABLES ON app_db.orders TO 'u'@'%'→ MySQL 忽略表名,静默降级为app_db.*,但语义错误 -
CREATE TEMPORARY TABLE app_db.tmp ...→ 语法上允许,但实际创建位置仍归属当前默认库;若当前库未授权,直接失败 - 临时表本身不可跨库访问:在
db_a创建的tmp,不能在db_b的查询里直接写db_a.tmp(会提示表不存在)
最容易被忽略的一点:临时表权限只在 CREATE TEMPORARY TABLE 执行瞬间校验,不是连接时预检。这意味着权限可以中途回收,且下次建表就会立即生效——别指望靠“已建好的临时表还能撑一会儿”。











