【问题标题】:Truncate does not physically release the diskspace截断不会物理释放磁盘空间
【发布时间】:2026-02-18 01:10:01
【问题描述】:

我使用spring-dataCrudRepository 进行任何数据库访问。每天一次,我还必须截断包含大约 100GB 数据的缓存表并重建它。

问题:表被成功截断(我验证表是空的),但是文件没有从数据库的硬盘中物理删除!

interface MyTableRepository extends CrudRepository<MyTableEntity, Long> {
    @Query(value = "TRUNCATE TABLE my_table", nativeQuery = true)
    @Modifying
    @Transactional
    void truncateTable();
}

因此,硬盘空间日益减少。 我注意到:如果我关闭我的 java 应用程序,那么 truncated 表之前的 truncated 部分会立即被删除!

这可能是什么原因?

当我使用 pgAdmin 截断同一张表时,磁盘空间按预期释放。

【问题讨论】:

  • 听起来好像您没有正确提交truncate
  • 提交应该由@Transactional自动处理
  • 也许它应该,但从你的描述我会说它没有。在您断开 Java 应用程序之前,pg_stat_activity 为您的应用程序连接显示了什么?也许 spring 不知道它需要提交 truncate 声明。
  • 是否有其他活动事务访问同一个表?如果它们在截断之前已经开始,那么在它们完成之前,不会释放该表。
  • 事实上,它在您的 SQL 客户端上运行良好,但在您通过混淆层运行语句时却不行,这意味着该层中的某些东西是错误的。尝试使用普通 JDBC 运行语句。

标签: java spring postgresql spring-data spring-data-jpa


【解决方案1】:

有两个可能的原因

  1. PostgresSQL 会在清理后删除此索引文件。所以等待或自己吸尘

  2. 在您退出此 java 程序之前不会提交 SQL

【讨论】:

  • 对于 2) 我可以说:使用 pgAdmin 我可以看到一个截断的空表!所以我假设sql实际上已经提交,否则我不会看到一个空的数据库?第 1 点):如果有任何事情仍在进行,我不应该在列表中看到一个真空 pid 吗?我没有看到任何清理过程,我也不认为几天后清理没有完成(但硬盘驱动器也包含上周的数据库文件,即使这些数据在很久以前被截断)......
  • 啊,是的。我错了。截断会立即删除文件