临时表在show tables中不可见,因其作用域仅限当前会话且不注册到information_schema.tables;可通过innodb_temp_table_info视图或show create table查结构;数据与结构按引擎分别存于tmpdir、ibtmp1或内存,不会出现在datadir。
临时表为什么 show tables 看不到?
因为 mysql 的临时表(create temporary table)作用域严格限定在**当前会话**,且被设计为“隐身”——它不注册进 information_schema.tables,也不出现在 show tables 结果里。这不是 bug,是机制:避免跨会话冲突,也防止元数据膨胀。
常见错误现象:SHOW TABLES 执行后没看到刚建的 #sql12345_67890_1 这类名字的表,以为建失败了;或者用 SELECT * FROM information_schema.tables WHERE table_schema = 'your_db' 查不到,就误判“临时表不存在”。
- 临时表只对创建它的连接可见,其他会话哪怕 root 权限也查不到
-
SHOW CREATE TABLE对临时表完全有效,但必须知道表名(不能靠SHOW TABLES反推) - 表名若与普通表同名,所有操作(
SELECT/INSERT/SHOW CREATE TABLE)默认走临时表,直到DROP TEMPORARY TABLE或会话断开
怎么查当前会话的临时表结构?
没有直接命令列出“当前会话所有临时表”,但有两条可靠路径:
- 查
INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO(MySQL 5.7+):该视图只暴露 InnoDB 临时表的元信息,含表名、引擎、行数等,但不含字段定义。执行SELECT * FROM INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO;可确认是否存在及大致状态 - 用
SHOW CREATE TABLE逐个查:如果你记得临时表名(比如建时用了temp_user),直接SHOW CREATE TABLE temp_user;就能拿到完整 DDL,包括字段、索引、引擎——这是获取结构的唯一标准方式 - 注意:如果表名是系统生成的(如
#sql-ib123-456789),通常只在错误日志或调试场景出现,生产中应显式命名临时表,便于追踪
临时表数据和结构到底存在哪?
结构(.frm 文件)和数据存放位置取决于 MySQL 版本和引擎,搞错会导致误删或排查无果:
- 结构文件:始终存于系统临时目录(
SELECT @@tmpdir;查),文件名形如#sql{pid}_{thread_id}_seq.frm,重启后自动清理 - InnoDB 临时表数据(5.7+):不再写磁盘临时文件,而是统一进入共享临时表空间(由
innodb_temp_data_file_path配置,默认在ibtmp1中),不随会话结束立即释放,而是在空闲时由 purge 线程回收 - Memory 引擎临时表:纯内存,结构 + 数据都在 RAM,会话断开即清,无磁盘痕迹
- 别去
@@datadir下翻找临时表文件——它们不在数据库目录里,硬找只会浪费时间
如何安全清理临时表?
临时表不需要手动“清空数据”,只需显式删除或等待会话结束。但要注意几个关键点:
- 用
DROP TEMPORARY TABLE table_name;主动释放,比等连接断开更可控;DROP TABLE(无 TEMPORARY)会报错,不是疏忽,是语法强制校验 - 不要依赖
COMMIT或ROLLBACK来“清理”临时表——事务提交不影响临时表生命周期 - 长连接中反复创建同名临时表却不
DROP,可能触发ERROR 1137: Can't reopen table(尤其在子查询中引用多次时) - 如果怀疑临时表残留影响性能(比如
ibtmp1持续增长),可重启 MySQL——这是最彻底的清理方式,但需业务允许停机
真正容易被忽略的是:InnoDB 临时表空间(ibtmp1)不会自动收缩,即使所有临时表都已释放。它只增大,不减小,除非重启。线上长期运行的实例,这块空间可能悄悄吃掉几十 GB。










