
# 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 | 作为字符串的过滤条件，用于筛选需要重写的文件。 需注意：所有可能包含与过滤条件匹配数据的文件都将被选中进行重写。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
     
  
- Options可选项参数介绍
  表2Options可选项参数介绍 
  | 参数名称                                | 默认值                                                      | 参数说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
  |:---|:---|:---|
  | 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                                                    | 重写后移除悬空的位置删除和等值删除文件。如果删除文件不应用于任何活动数据文件，则视为悬空文件。开启此参数将额外生成一个提交来执行删除操作。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
     
  
- sort_order其他排序策略参数介绍
  表3排序策略参数介绍 
  | 参数名称                        | 默认值 | 参数说明                                                                                                                                                                                                                               |
  |:---|:---|:---|
  | compression-factor          | 1.0 | Spark排序操作创建的Shuffle分区数量（进而决定输出文件数量）基于此文件重写器中使用的输入数据文件大小。由于压缩、磁盘文件大小可能无法准确反映输出文件的实际大小。 此参数允许用户调整用于估算实际输出数据大小的文件大小。大于1.0的值会生成比基于磁盘文件大小预期更多的文件；小于1.0的值会生成比基于磁盘大小预期更少的文件。 |
  | shuffle-partitions-per-file | 1   | 每个输出文件使用的Shuffle分区数量。Iceberg会使用自定义的合并操作将排序后的分区重新拼接成一个单一的排序文件。                                                                                                                                                                      |
     
  
- sort_order ZORDER排序顺序的排序策略选项介绍
  表4ZORDER排序顺序的排序策略选项介绍 
  | 参数名称                    | 默认值        | 参数说明                               |
  |:---|:---|:---|
  | 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');
  ```
  
- 通过对列**c1** 和**c2** 执行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');
  ```
  
 
