PostgreSQL 临时表自动回收规则
一、核心销毁时机(优先级从高到低)
1. 会话断开,立刻自动删除(最常见)
CREATE TEMP TABLE 创建的临时表绑定当前数据库会话(连接):
- 客户端正常断开连接、关闭连接、程序释放连接池连接;
- 网络断连、进程崩溃、pg_terminate_backend 杀掉会话;
只要会话终止,该会话下所有临时表、临时序列全部自动清理,无需手动
DROP。
2. 事务结束(仅 ON COMMIT DROP 才会触发)
-- 事务提交/回滚后自动销毁临时表
CREATE TEMP TABLE t_tmp(id int) ON COMMIT DROP;
默认不带 ON COMMIT 时:事务提交、回滚不会删临时表,仅保留到会话结束。
另外两种 ON COMMIT 选项:
ON COMMIT PRESERVE ROWS:默认,事务结束保留表和数据ON COMMIT DELETE ROWS:事务结束清空数据,表结构还在
3. 会话内手动 DROP TABLE
DROP TABLE IF EXISTS t_tmp;
执行后立刻回收,无需等会话结束。
二、特殊场景:连接池导致临时表不释放
使用连接池(JDBC、PgBouncer、HikariCP)时会话不会频繁断开,临时表会长期残留,直到连接归还销毁/重启连接池: 解决方案:
- 创建时加
ON COMMIT DROP,用完事务提交自动删; - 每次使用完手动
DROP; - 业务结束时主动关闭连接。
三、重启 PostgreSQL 服务
数据库服务重启、服务器重启:所有临时表全部清空(临时表本身不持久化磁盘,只存在内存/临时文件)。
四、关键补充特性
- 隔离性:不同会话同名临时表互不干扰,只对当前连接可见;
- 无持久化:临时表数据不写入永久数据目录,存在
pg_temp_xxx临时 schema; - ** vacuum 不回收临时表**:普通自动真空、手动 vacuum 不会删除临时表,仅会话/事务规则生效。
总结最简记忆
- 不加特殊参数:连接断开 → 自动回收;
ON COMMIT DROP:事务提交/回滚 → 自动回收;- 手动 DROP / 数据库重启:立刻回收。
注意:本文归作者所有,未经作者允许,不得转载