必须显式授予 create temporary tables 权限,它独立于 create 权限;正确语法为 grant create temporary tables on db.* to 'u'@'h';,且权限不跨库生效,授完需验证 show grants 并检查 tmpdir 空间。
mysql 中授予 create temporary tables 权限的实际操作
直接给用户临时建表权限,不是加个 create 就行——mysql 把它单独拆成了一个细粒度权限,必须显式授予。
常见错误是执行 GRANT CREATE ON db.* TO 'u'@'h';,结果用户仍报错:ERROR 1142 (42000): CREATE TEMPORARY TABLES command denied to user。这是因为 CREATE TEMPORARY TABLES 不属于 CREATE 权限集合,也不依赖数据库级 CREATE。
- 用
GRANT CREATE TEMPORARY TABLES ON *.* TO 'user'@'host';授予全局权限(最常用) - 若只允许在某库建临时表,用
GRANT CREATE TEMPORARY TABLES ON `mydb`.* TO 'user'@'host'; - 注意:该权限不能跨库生效——即使用户有
mydb的临时表权限,也不能在otherdb里CREATE TEMPORARY TABLE - 授完别忘了
FLUSH PRIVILEGES;(仅当直接改了 mysql.tables 表才强制需要;用GRANT语句通常自动生效)
为什么不用 CREATE 权限替代?
MySQL 设计上把临时表权限独立出来,核心原因是安全隔离:临时表只对当前会话可见,但创建动作本身可能被滥用(比如撑爆 tmpdir、触发大量磁盘 I/O),所以 DBA 需要单独控制。
典型场景是应用中间件或连接池复用账号时,你希望它能建临时表做 JOIN 缓存或分页中间结果,但又不给它建永久表的能力。
-
CREATE TEMPORARY TABLES不隐含CREATE、DROP或任何其他权限 - 用户即使有该权限,也无法
DROP TEMPORARY TABLE其他会话的临时表(根本看不见) - 临时表生命周期严格绑定会话,断连自动清理,所以权限本身不带来数据残留风险
权限验证与常见失效点
授完权限后用户仍报错,大概率卡在这几个地方:
- 用户连接用的是旧账号缓存——检查
SELECT CURRENT_USER();确认实际匹配的'user'@'host'是否和 GRANT 目标一致 - 账号被
REVOKE过其他权限导致冲突(极少,但 MySQL 权限合并逻辑有时会意外覆盖) - MySQL 8.0+ 使用角色(role)管理时,没把权限赋给角色,或用户没
SET ROLE - 某些云数据库(如阿里云 RDS)默认禁用该权限,需在控制台额外开启“临时表权限开关”
快速验证命令:SHOW GRANTS FOR 'user'@'host';,确认输出里明确含 CREATE TEMPORARY TABLES 字样。
临时表权限和 tmpdir 空间的关系
授了权限 ≠ 能成功建表。最终能否落地,还取决于 MySQL 的 tmpdir 是否可写、是否有足够空间。
- 临时表默认走
tmpdir,不是数据库目录;即使用户对目标库有完全权限,tmpdir满了也会报ERROR 1034 (HY000): Incorrect key file...或磁盘满错误 -
innodb_tmpdir(5.7+)可单独指定 InnoDB 临时表路径,但不影响 MyISAM 临时表行为 - 应用层建大量临时表时,建议监控
Created_tmp_disk_tables和Created_tmp_tables状态变量比值,过高说明内存不足被迫落盘
权限只是开门的钥匙,门后有没有地方放东西,得看服务器配置和磁盘水位。










