Delta表执行VACUUM命令的处理逻辑及与compaction的区别
Delta Lake VACUUM 命令的实际行为
你提到的两种猜测都不准确:
- VACUUM的操作单位是整个parquet文件,永远不会进入parquet文件内部逐行删除旧版本记录——parquet本身是不可变存储格式,不支持原地修改单条记录,Delta的所有增删改操作都是通过写新文件+更新事务日志实现的,从来不会修改已有parquet的内容。
- VACUUM判断文件是否保留的依据,和文件内部存了什么记录没有关系,它只查询Delta的事务日志:
- 首先收集所有保留窗口期(默认7天,由
delta.deletedFileRetentionDuration参数配置)内的表版本,列出这些版本引用过的所有有效数据文件 - 遍历存储路径下的所有parquet文件,不在上述有效列表里的文件,会被直接物理删除;在列表里的文件,不管内部存了多少已经被更新/删除的旧行,都会完整保留
- 首先收集所有保留窗口期(默认7天,由
- 举个反例就能推翻“文件里有最新记录就会保留”的误解:如果你执行
OPTIMIZE做了文件合并,原来的小文件里哪怕存的全是当前版本的有效数据,只要从合并提交的版本开始这些小文件就不再被日志引用,等过了保留窗口期,VACUUM照样会把这些小文件整个删掉。
Compaction(OPTIMIZE命令)的运行机制
Compaction是Delta用来解决小文件问题的性能优化操作,运行逻辑如下:
- 首先根据配置的目标文件大小(默认约1GB),筛选出表/指定分区内大小远低于目标值的小文件
- 读取这些小文件中当前事务版本下仍然有效的数据(自动过滤掉已经被标记为删除、更新的旧行)
- 将读取到的有效数据重新写入若干个大小符合目标值的新parquet文件
- 提交事务到Delta日志:将之前选中的小文件标记为“不再被当前版本引用”,将新生成的大文件标记为当前版本的有效数据文件
- 整个过程只会新增文件、更新日志引用,不会删除任何已有的物理文件,原来的小文件会一直留在存储上,直到被VACUUM清理。
VACUUM 和 Compaction 的核心差异
两者是完全独立的操作,核心区别可以总结为几点:
- 定位不同:Compaction是性能优化手段,目的是减少小文件数量、降低查询时的文件扫描开销;VACUUM是存储清理手段,目的是删除过期无用文件、释放存储空间。
- 逻辑不同:Compaction需要读取parquet文件的内容,筛选有效数据重写为新文件;VACUUM完全不解析parquet文件内容,只根据事务日志的引用关系判断文件是否需要删除。
- 对文件的操作不同:Compaction只会新增数据文件、修改日志中的引用关系,不会删除任何已有文件;VACUUM不会新增或修改任何数据文件,只会物理删除符合过期条件的文件。
- 对时间旅行的影响不同:Compaction执行后,你依然可以通过时间旅行功能回滚到Compaction之前的版本,访问旧文件的数据;VACUUM执行后,被删除的文件对应的旧版本会彻底失效,无法再通过时间旅行访问。
内容的提问来源于stack exchange,提问作者poiuyqwerty0910
相关产品推荐
相关产品推荐

