更新时间:2026-06-11 GMT+08:00
分享

rewrite_data_files

Iceberg会跟踪表中的每个数据文件,数据文件越多,清单文件中存储的元数据就越多;而小数据文件会产生不必要的元数据开销,并因文件打开成本导致查询效率降低。

Iceberg可通过rewriteDataFiles操作,利用Spark并行压缩数据文件。此操作会将小文件合并为大文件,以减少元数据开销和运行时的文件打开成本。

约束与限制

Iceberg默认会按照当前活跃的分区规范去重写所有符合条件的数据文件,尽管相关数据文件是按照历史分区规范所写的。如果需要按照指定的分区规则去合并指定的分区,需执行以下命令:

call rewrite_data_files(table => '', where => '', options => map('output-spec-id', ''))

语法参数介绍

  • 语法参数介绍
    表1 语法参数介绍

    参数名称

    参数类型

    参数说明

    table

    string

    必须参数,表示要更新的表名。

    strategy

    string

    策略名称,取值范围为“binpack”(默认值)或 “sort”。

    sort_order

    string

    表示排序方式,取值包括:

    • Zorder:格式为zorder(c1,c2,c3),使用逗号分隔的列名列表。
    • 其他情况:格式为逗号分隔的排序规则(ColumnName SortDirection NullOrder),其中SortDirection可为ASC或DESC,NullOrder可为NULLS FIRST或NULLS LAST默认使用表的排序规则。

    options

    map

    用于操作的选项参数。

    where

    string

    作为字符串的过滤条件,用于筛选需要重写的文件。

    需注意:所有可能包含与过滤条件匹配数据的文件都将被选中进行重写。

  • 语法可选项参数介绍
    表2 语法可选项参数介绍

    参数名称

    默认值

    参数说明

    max-concurrent-file-group-rewrites

    5

    同时重写的文件组最大数量。

    partial-progress.enabled

    false

    启用在整个重写完成前提交文件组。

    partial-progress.max-commits

    10

    如果启用部分进度,此重写操作允许的最大提交次数。

    partial-progress.max-failed-commits

    “partial-progress.max-commits”的值

    如果启用部分进度,作业失败前允许的最大失败提交次数。

    use-starting-sequence-number

    true

    使用压缩开始时快照的序列号,而非新生成快照的序列号。

    rewrite-job-order

    none

    强制重写作业的顺序:

    • bytes-asc:优先重写最小的作业组。
    • bytes-desc:优先重写最大的作业组。
    • files-asc:优先重写文件数量最少的作业组。
    • files-desc:优先重写文件数量最多的作业组。
    • none:按计划顺序重写作业组(无特定排序)。

    target-file-size-bytes

    536870912(512 MB,默认值来自表属性“write.target-file-size-bytes”)

    目标输出文件大小。

    min-file-size-bytes

    目标文件大小的75%

    无论其他条件,低于此阈值的文件将被视为需要重写。

    max-file-size-bytes

    目标文件大小的 180%

    无论其他条件,大于此阈值的文件将被视为需要重写。

    min-input-files

    5

    无论其他条件,任何文件组的文件数量超过此值时都将被重写。

    rewrite-all

    false

    强制重写所有提供的文件,将覆盖其他选项。

    max-file-group-size-bytes

    107374182400(100GB)

    单个文件组中应重写的最大数据量。整个重写操作会根据分区拆分,在分区内再根据大小拆分为文件组。将有助于拆分大型分区的重写任务,避免因集群资源限制而无法重写。

    delete-file-threshold

    2147483647

    与数据文件关联的删除操作数量的最小值,达到此值时数据文件将被考虑重写。

    output-spec-id

    当前分区规范ID

    输出分区规范的标识符。重写过程中,数据将被重新组织以匹配输出分区方式。

    remove-dangling-deletes

    false

    重写后移除悬空的位置删除和等值删除文件。如果删除文件不应用于任何活动数据文件,则视为悬空文件。开启此参数将额外生成一个提交来执行删除操作。

  • 排序策略参数介绍
    表3 排序策略参数介绍

    参数名称

    默认值

    参数说明

    compression-factor

    1.0

    Spark排序操作创建的Shuffle分区数量(进而决定输出文件数量)基于此文件重写器中使用的输入数据文件大小。由于压缩、磁盘文件大小可能无法准确反映输出文件的实际大小。

    此参数允许用户调整用于估算实际输出数据大小的文件大小。大于1.0的值会生成比基于磁盘文件大小预期更多的文件;小于1.0的值会生成比基于磁盘大小预期更少的文件。

    shuffle-partitions-per-file

    1

    每个输出文件使用的Shuffle分区数量。Iceberg会使用自定义的合并操作将排序后的分区重新拼接成一个单一的排序文件。

  • ZORDER排序顺序的排序策略选项介绍
    表4 ZORDER排序顺序的排序策略选项介绍

    参数名称

    默认值

    参数说明

    var-length-contribution

    8

    从可变长度类型(String、Binary)的输入列中截取的字节数。

    max-output-size

    2147483647

    ZORDER算法中间交错处理的字节量。

  • 输出结果参数介绍
    表5 输出结果参数介绍

    参数名称

    类型

    参数说明

    rewritten_data_files_count

    int

    此命令重写的数据文件数量。

    added_data_files_count

    int

    此命令写入的新数据文件数量。

    rewritten_bytes_count

    long

    此命令写入的字节数。

    failed_data_files_count

    int

    当“partial-progress.enabled”为“true”时,重写失败的数据文件数量。

示例

  • 使用默认的装箱算法改写表db.sample中的数据文件,合并小文件并根据表的默认写入大小拆分大文件:
    CALL prod.system.rewrite_data_files('db.sample');
  • 通过按id对所有数据进行排序来重写表db.sample中的数据文件,使用与装箱算法相同的默认值来确定需要重写的文件:
    CALL prod.system.rewrite_data_files(table => 'db.sample', strategy => 'sort', sort_order => 'id DESC NULLS LAST');
  • 通过对列c1c2执行ZORDER排序来重写表db.sample中的数据文件,使用与装箱算法相同的默认值来确定需要重写的文件:
    CALL prod.system.rewrite_data_files(table => 'db.sample', strategy => 'sort', sort_order => 'zorder(id,data)');
  • 使用装箱算法策略改写表db.sample中任何至少有两个文件需要重写的分区中的数据文件,然后移除所有悬空的删除文件:
    CALL prod.system.rewrite_data_files(table => 'db.sample', options => map('min-input-files', '2', 'remove-dangling-deletes', 'true'));
  • 重写表db.sample中的数据文件,并选择可能包含与筛选条件(id = 3")匹配的数据的文件进行重写:
    CALL prod.system.rewrite_data_files(table => 'db.sample', where => 'id = 3');

相关文档