Delta Lake Vacuum与Deletion Vector的存储回收机制
Delta Lake的VACUUM命令和Deletion Vector(删除向量)如何配合实现高效的存储回收?请解释Deletion Vector的『软删除』机制:标记删除而非立即物理删除,配合VACUUM的物理清理策略(retention duration阈值),以及如何避免误删正在使用的文件。给出一个Delta Lake VACUUM的配置示例和监控方法。
回答
屠龙少年
Delta Lake Vacuum与Deletion Vector存储回收:
1. Deletion Vector(删除向量):
- Delta 2.3+引入的『软删除』机制
- 当执行DELETE/UPDATE/MERGE时,不在数据文件中真正删除
- 而是在
_delta_log/中记录Deletion Vector:标记哪些行被删除 - 读取时自动过滤Deletion Vector标记的行
Parquet File [0,1,2,3,4,5,6,7,8,9] → 原始文件
Deletion Vector: [2, 5, 7] → 标记删除行2,5,7
读取结果: [0,1,3,4,6,8,9] → 自动跳过
2. VACUUM物理清理:
-- 物理删除7天前未被引用的文件
VACUUM delta.`/path/table` RETAIN 168 HOURS;
- 删除未被任何Delta Log引用且超过保留期的文件
- 默认保留期:7天(168小时)
- VACUUM前确保所有Reader已切换到新的Snapshot
3. 配置示例:
-- 设置默认保留期(SparkSession级别)
SET spark.databricks.delta.retentionDurationCheck.enabled = false;
SET spark.databricks.delta.vacuum.parallelDelete.enabled = true;
-- 执行VACUUM
VACUUM delta.`/path/table` RETAIN 168 HOURS;
-- 仅预览要删除的文件(不实际删除)
VACUUM delta.`/path/table` DRY RUN;
4. Deletion Vector + VACUUM配合流程:
时间线:
t0: INSERT 100行 → Base File A
t1: DELETE 10行 → Deletion Vector标记删除 (File A的10行标记)
t2: VACUUM → 文件A仍被t1的Delta Log引用 → 不删除
t3: OPTIMIZE → 新文件B包含未删除的90行
t4: 删除t1的Delta Log(触发条件)
t5: VACUUM → 文件A不再被任何Log引用 → 物理删除
5. 最佳实践:
| 操作 | 说明 |
|------|------|
| VACUUM频率 | 每日或每周运行 |
| 保留期 | 7天(默认,足够下游消费) |
| DRY RUN先行 | 先预览要删除的文件再实际执行 |
| 监控 delta.log.fsMetrics.numDeletedFiles | 确认删除文件数 |
6. 监控方法:
-- 查看表文件清单
DESCRIBE DETAIL delta.`/path/table`;
-- 查看.numFiles和.totalSize
-- 查看已标记删除的行
SELECT COUNT(*) FROM delta.`/path/table` VERSION AS OF 1
EXCEPT
SELECT COUNT(*) FROM delta.`/path/table`;