使用 vacuum 删除未使用的数据文件

可以对 Delta 表运行 VACUUM 命令,以删除该表中不再引用且在保留期阈值之前创建的数据文件。 由于以下考虑因素,必须定期运行 VACUUM 才能实现成本节省与合规:

  • 删除未使用的数据文件可降低云存储成本。
  • VACUUM 删除的数据文件可能包含已修改或删除的记录。 从云存储中永久删除这些文件可确保这些记录不再可访问。

vacuum 注意事项

在运行 VACUUM 后,数据文件的默认保留期阈值为 7 天。 若要更改此行为,请参阅为“按时间顺序查看”查询配置数据保留

VACUUM 可能会在从目录中删除所有文件后留下空目录。 后续的 VACUUM 操作会删除这些空目录。

某些 Delta Lake 功能使用元数据文件将数据标记为已删除,而不是重写数据文件。 可以使用 REORG TABLE ... APPLY (PURGE) 提交这些删除操作并重写数据文件。 请参阅清除仅元数据删除以强制重写数据

重要

  • 在 Databricks Runtime 13.3 LTS 及更高版本中,VACUUM 使用 Unity Catalog 托管表的浅层克隆的语义与其他 Delta 表不同。 请参阅 Vacuum 和 Unity Catalog 浅表克隆
  • VACUUM 删除不由 Delta Lake 管理的目录中的所有文件,忽略以 _. 开头的目录。 如果要在 Delta 表目录中存储其他元数据(如结构化流式处理检查点),请使用目录名称,例如 _checkpoints
  • 运行 VACUUM 后,将无法查询早于保留期的表版本。
  • 日志文件会在检查点操作后自动异步删除,不受 VACUUM 的控制。 虽然日志文件的默认保留期为 30 天,但在表上运行 VACUUM 会删除按时间顺序查看所需的数据文件。

注意

启用磁盘缓存后,群集可能包含已使用 VACUUM 删除的 Parquet 文件中的数据。 因此,有可能可以查询到文件已删除的先前版本的表中的数据。 重启群集将删除缓存数据。 请参阅配置磁盘缓存

vacuum 的示例语法

VACUUM table_name   -- vacuum files not required by versions older than the default retention period

VACUUM table_name RETAIN 100 HOURS  -- vacuum files not required by versions more than 100 hours old

VACUUM table_name DRY RUN    -- do dry run to get the list of files to be deleted

有关 Spark SQL 语法详细信息,请参阅 VACUUM

请参阅 Delta Lake API 文档,了解 Scala、Java 和 Python 的语法详细信息。

注意

使用 RETAIN 关键字指定用于确定是否应删除数据文件的阈值。 VACUUM 命令使用此阈值来回溯指定的时间量,并识别当时的最新表版本。 Delta 保留查询该表版本和所有较新的表版本所需的所有数据文件。 此设置与其他表属性交互。 请参阅为“按时间顺序查看”查询配置数据保留

清除仅元数据删除以强制重写数据

REORG TABLE 命令提供用于重写数据的 APPLY (PURGE) 语法以应用软删除。 软删除不会重写数据或删除数据文件,而是使用元数据文件来指示某些数据值已更改。 请参阅 REORG TABLE

在 Delta Lake 中创建软删除的操作包括:

  • 删除启用了列映射的列。
  • 删除启用了删除向量的行。
  • 启用删除向量时,启用了 Photon 的群集上的任何数据修改。

启用软删除后,即使删除或更新数据,旧数据仍能以物理方式保留在表的当前文件中。 若要以物理方式从表中删除此数据,请完成以下步骤:

  1. 运行 REORG TABLE ... APPLY (PURGE)。 执行此操作后,旧数据不再存在于表的当前文件中,但它仍存在于用于“按时间顺序查看”的旧文件中。
  2. 运行 VACUUM 以删除这些旧文件。

在该操作完成时,REORG TABLE 会创建表的新版本。 历史记录中在此事务之前的所有表版本都引用旧数据文件。 从概念上讲,这类似于 OPTIMIZE 命令,即使当前表版本中的数据保持一致,该命令也会重写数据文件。

重要

仅当文件根据 VACUUM 保留期过期时,才会删除数据文件。 这意味着,必须在完成 REORG 之后,经过一段延迟时间再完成 VACUUM,以便旧文件过期。 可以缩短 VACUUM 保留期以缩短所需的等待时间,但代价是会减少保留的最大历史记录。

vacuum 需要多大的群集?

若要为 VACUUM 选择正确的群集大小,最好是先了解该操作的两个阶段:

  1. 作业首先使用所有可用的执行程序节点来并行列出源目录中的文件。 将此列表与 Delta 事务日志中当前引用的所有文件进行比较,以确定要删除的文件。 在此期间,驱动程序处于空闲状态。
  2. 然后,驱动程序针对要删除的每个文件发出删除命令。 文件删除是仅限驱动程序的操作,这意味着,所有操作是当工作器节点处于空闲状态时在单个节点中发生。

为了优化成本和性能,Databricks 建议执行以下操作,尤其是对于长时间运行的 vacuum 作业:

  • 在为其中 1-4 个工作器(每个工作器有 8 个核心)设置了自动缩放的群集上运行 vacuum。
  • 选择核心数为 8 到 32 的驱动程序。 增加驱动程序的大小以避免内存不足 (OOM) 错误。

如果 VACUUM 操作定期删除 1 万个以上的文件或占用 30 分钟以上的处理时间,则建议增加驱动程序的大小或工作器的数量。

如果你发现在确定要删除的文件时速度减慢,请添加更多工作器节点。 如果在运行删除命令时速度减慢,请尝试增加驱动程序的大小。

应多久运行一次 vacuum?

Databricks 建议在所有表上定期运行 VACUUM,以减少多余的云数据存储成本。 vacuum 的默认保留期阈值为 7 天。 设置较高的阈值可让你访问更长的表历史记录,但会增加存储的数据文件数,因此会在云提供商处产生更高的存储成本。

为什么不能使用低的保留期阈值清空 Delta 表?

警告

建议将保留期间隔设置为至少 7 天,因为并发读取器或写入器仍可将旧快照和未提交的文件用于表。 如果 VACUUM 清理活动文件,则并发读取器可能会失败;更糟糕的是,当 VACUUM 删除尚未提交的文件时,表可能会损坏。 选择的时间间隔必须比最长运行并发事务长,也必须比任何流可滞后于对表的最新更新的最长时间长。

Delta Lake 具有一项安全检查,用于防止运行危险的 VACUUM 命令。 如果确定对此表执行的操作所耗的时间均未超过计划指定的保留期间隔,可通过将 Spark 配置属性 spark.databricks.delta.retentionDurationCheck.enabled 设置为 false 来关闭此安全检查。

审核信息

VACUUM 提交给 Delta 事务日志的内容包含审核信息。 可以使用 DESCRIBE HISTORY 查询审核事件。