Skip to content

[#11196] feat(maintenance): Add builtin-iceberg-rewrite-manifests job - #12937

Open
laserninja wants to merge 8 commits into
apache:mainfrom
laserninja:feature/11196-iceberg-rewrite-manifests
Open

laserninja wants to merge 8 commits into
apache:mainfrom
laserninja:feature/11196-iceberg-rewrite-manifests

Conversation

@laserninja

@laserninja laserninja commented Sep 7, 2026 •

Copy link
Copy Markdown
Collaborator

What changes were proposed in this pull request?

Adds builtin-iceberg-rewrite-manifests, invoking Iceberg's Spark SQL procedure with table, optional use_caching, and optional spec_id. Registers the template, reuses shared job utilities, validates parameters, handles omitted optional arguments, and reports rewritten/added counts.

Continues #11216 by @ibrahimErbilen. Their original commits retain authorship, and follow-up commits retain their co-author credit. Design: #12942.

Why are the changes needed?

Manifest maintenance consolidates and clusters manifest entries independently of data-file compaction. spec_id selects an existing spec's manifests; it does not repartition files or migrate manifests from another spec.

Fix: #11196

Does this PR introduce any user-facing change?

New job template with catalog_name, table_identifier, use_caching, spec_id, and spark_conf configuration. The CLI reference explains how to discover spec IDs from Iceberg metadata and includes a day-to-hour evolution example. Omitted caching uses the installed Iceberg default.

How was this patch tested?

  • Previously passed 30 job unit tests plus the module test suite.
  • Latest documentation update: :docs:build, :maintenance:jobs:spotlessCheck, and git diff --check.
  • Spec selection and caching defaults verified against Iceberg 1.11.0 source.

A dedicated Spark-backed test for this job is still pending; the module's existing integration checks do not establish its spec-selection behavior end to end.

ibrahimErbilen and others added 3 commits September 6, 2026 18:57
Rebases the job onto current main and resolves the review comments left on
apache#11216:

- Fix the misplaced closing parenthesis in BuiltInJobTemplateProvider that
  left the new job outside ImmutableList.of(...) and broke compilation, and
  restore alphabetical import ordering.
- Use IcebergJobUtils for SQL escaping, argument parsing and Spark config
  parsing instead of reaching into IcebergRewriteDataFilesJob, and drop the
  duplicated parseArguments implementation.
- Drop unresolved {{...}} template placeholders for optional arguments. The
  server forwards them verbatim when a jobConf key is absent, so
  use_caching => {{use_caching}} silently parsed to false instead of leaving
  Iceberg's default in place.
- Reject a use-caching value that is neither true nor false rather than
  letting Boolean.parseBoolean turn a typo into false.
- Read the procedure output through collectAsList and Number so the job does
  not depend on whether the runtime Iceberg version types the manifest counts
  as int or long. The Iceberg jar is a compileOnly dependency supplied by the
  cluster, so that width can differ from what we compile against.
- Update the SQL assertions for backtick-quoted catalog identifiers, which is
  what escapeSqlIdentifier now produces, and rename
  testJobTemplateHasMainClass to match the property it asserts on.
- Document the job in the table maintenance CLI reference alongside the other
  three built-in templates.

Co-authored-by: İbrahim ERBİLEN <ibrahimerblnn46@gmail.com>
@lasdf1234

lasdf1234 commented Sep 7, 2026 •

Copy link
Copy Markdown
Collaborator

Could u write a design document for th rewrite mainfests job?

Iceberg's rewrite_manifests procedure takes three in-parameters: table,
use_caching, and spec_id. Only the first two were reachable, which left
the "align manifests with a better partition spec" half of apache#11196
unavailable - a spec evolution had no way to re-cluster old manifests
onto the new spec.

Expose it as jobConf key spec_id, validated as a non-negative integer so
a malformed value fails before the Spark session is created rather than
reaching Spark as an unparseable SQL literal. Like use_caching, an
unresolved {{spec_id}} placeholder is dropped so an omitted parameter
leaves the table's current spec in force.

Co-authored-by: İbrahim ERBİLEN <ibrahimerblnn46@gmail.com>
@laserninja

Copy link
Copy Markdown
Collaborator Author

@lasdf1234 done - #12942, following the convention that every design doc lands as its own PR.

It covers why manifest bloat is distinct from data-file bloat and why neither rewrite_data_files nor expire_snapshots addresses it, the four approaches considered with the reasons the Iceberg Java action lost to the Spark SQL procedure, the parameter surface and its validation, and the JobManager.replacePlaceholder behaviour that shapes the job's input handling. The follow-up section sequences the manifest metrics and the policy that would fire on them, aligned with table compaction per your comment on #11700 - DataRequirement.TABLE_STATISTICS, and any last-run signal in statistic_meta as a custom- statistic rather than bespoke state.

Two things changed on this PR while writing it:

  • rewrite_manifests takes a third in-parameter, spec_id, which was not exposed. It is what makes the partition-spec half of [FEATURE] Add builtin-iceberg-rewrite-manifests maintenance job #11196's motivation reachable, so it is now a jobConf key, validated as a non-negative integer and placeholder-filtered like use_caching.
  • The doc records one gap this PR does not close: no Spark-backed integration test, unlike the two sibling *WithSpark tests. Happy to add it here if you would prefer that over a follow-up.

@laserninja
laserninja requested a review from lasdf1234 September 7, 2026 03:09
@github-actions

github-actions Bot commented Sep 7, 2026 •

Copy link
Copy Markdown

Code Coverage Report

Overall Project 70.05% +0.01% 🟢
Files changed 73.0% 🟢

Module Coverage
aliyun 19.74% 🔴
api 51.59% 🟢
authorization-common 85.96% 🟢
authorization-ranger 4.38% 🔴
aws 53.54% 🟢
azure 32.1% 🔴
catalog-common 28.4% 🔴
catalog-fileset 82.2% 🟢
catalog-glue 71.52% 🟢
catalog-hive 83.07% 🟢
catalog-jdbc-common 45.72% 🟢
catalog-jdbc-doris 83.47% 🟢
catalog-jdbc-mysql 81.8% 🟢
catalog-jdbc-postgresql 83.89% 🟢
catalog-jdbc-starrocks 79.16% 🟢
catalog-kafka 75.21% 🟢
catalog-lakehouse-generic 61.16% 🟢
catalog-lakehouse-hudi 79.1% 🟢
catalog-lakehouse-iceberg 85.9% 🟢
catalog-lakehouse-paimon 84.29% 🟢
catalog-model 77.99% 🟢
cli 44.62% 🟢
client-java 77.96% 🟢
common 58.29% 🟢
core 84.65% 🟢
filesystem-hadoop3 76.48% 🟢
flink 0.0% 🔴
flink-common 53.63% 🟢
flink-runtime 0.0% 🔴
gcp 32.2% 🔴
hadoop-auth 68.0% 🟢
hadoop-common 17.84% 🔴
hive-metastore-common 54.41% 🟢
iceberg-aliyun-bundle 0.0% 🔴
iceberg-common 66.16% 🟢
iceberg-rest-server 77.03% 🟢
idp-basic 86.77% 🟢
integration-test-common 0.0% 🔴
jobs 60.52% +0.92% 🟢
lance-common 34.02% 🔴
lance-rest-server 69.51% 🟢
lineage 59.39% 🟢
optimizer 83.24% 🟢
optimizer-api 22.3% +10.27% 🔴
server 90.17% 🟢
server-common 82.0% 🟢
spark 56.42% 🟢
tencent 81.78% 🟢
trino-connector 59.91% 🟢
Files
Module File Coverage
jobs IcebergJobUtils.java 100.0% 🟢
BuiltInJobTemplateProvider.java 81.82% 🟢
IcebergRewriteManifestsJob.java 43.02% 🔴
optimizer-api IcebergSparkConfigUtils.java 98.15% 🟢

laserninja and others added 3 commits September 14, 2026 10:48
Document spec discovery and correct CLI examples and help text without changing execution behavior.

Co-authored-by: İbrahim ERBİLEN <ibrahimerblnn46@gmail.com>
Use matching argument placeholders and the catalog key in Spark configuration while preserving defaults for existing jobs.

Co-authored-by: İbrahim ERBİLEN <ibrahimerblnn46@gmail.com>
Revert CLI/key alignment after the review restriction was withdrawn. Restore the shared catalog helper and original tests and examples.

Co-authored-by: İbrahim ERBİLEN <ibrahimerblnn46@gmail.com>
roryqi pushed a commit that referenced this pull request Sep 18, 2026
…12942)

### What changes were proposed in this pull request?

Design for `builtin-iceberg-rewrite-manifests`, following the numbered
architecture and layer structure of #11700. Covers template
registration, procedure parameters, spec ID discovery, execution,
safety, and the implementation plan.

The initial job is submitted directly. Follow-up statistics are limited
to `custom-manifest-number-by-spec` and
`custom-avg-manifest-size-by-spec`; automatic policy triggering remains
separate implementation work. The design defines defaults of 500
manifests (critical), or 100 manifests with average size below 8 MiB,
and preserves one resolved spec ID across collection, evaluation, and
submission. Initial CI/runtime support is Spark 3.5 with Iceberg 1.11.0.

Related: #11196, #12937 (implementation), #8864. Continues the original
work by @ibrahimErbilen in #11216, with co-authorship retained.

### Why are the changes needed?

Operators need a dedicated manifest maintenance job and clear guidance
after partition evolution. The document explains that `spec_id` selects
manifests belonging to an existing spec; it does not migrate data files
between specs. Includes the Iceberg 1.11.0 source supporting that
behavior.

### Does this PR introduce _any_ user-facing change?

No runtime changes. User-facing documentation is maintained in #12937.

### How was this patch tested?

- Checked all Markdown tables for aligned columns and balanced code
fences.
- Verified spec selection and caching defaults against Iceberg 1.11.0
source.
- `git diff --check`.
- `./gradlew rat` passed; companion CLI documentation passed `./gradlew
:docs:build`.

---------

Co-authored-by: İbrahim ERBİLEN <ibrahimerblnn46@gmail.com>
roryqi pushed a commit that referenced this pull request Sep 28, 2026
…13329)

### What changes were proposed in this pull request?

Implements the first phase of the merged design in #12942: the
`builtin-iceberg-rewrite-manifests` Spark job, registration, validated
arguments, spec selection, and operator documentation. Manifest
statistics and the Policy -> Strategy -> Adapter integration for
automatic triggering remain separate follow-ups in the design, as
requested in review.

Continues #12937 on current main and preserves the original commits by
@ibrahimErbilen from #11216, with co-author attribution on follow-up
work.

Adds Spark-backed tests invoking the job entry point through resolved
template arguments. They verify default and explicit partition-spec
selection, unchanged table records and other-spec manifests, repeat-run
no-op behavior, and cleanup without metadata changes after an
unknown-spec failure. The entry point checks the Iceberg runtime, closes
Spark on success or failure, prints user-visible results to stdout for
output.log, and reports concise errors to stderr with a nonzero exit.
Strict argument parsing is shared through IcebergJobUtils while
preserving existing callers. The overview and configuration guides
document direct submission and the remaining policy integration.

### Why are the changes needed?

Manifest rewriting maintains manifest layout independently of data-file
compaction. The previous implementation lacked Spark-backed verification
of partition-spec selection and failure cleanup.

Fix: #11196

### Does this PR introduce _any_ user-facing change?

Adds `builtin-iceberg-rewrite-manifests` with required `catalog_name`
and `table_identifier`, plus optional `use_caching`, `spec_id`, and
`spark_conf`. Existing jobConf/CLI naming conventions are retained.
Invalid, duplicate, or missing argument values fail before session
creation; omitted optional values retain Iceberg defaults. `spec_id`
selects an existing spec, without migrating files between specs.

### How was this patch tested?

- 183 jobs-module tests passed, including 33 manifest unit tests and 3
Spark-backed tests on Spark 3.5 / Iceberg 1.11.0.
- `./gradlew :maintenance:jobs:test :maintenance:jobs:spotlessCheck
:maintenance:jobs:javadoc :docs:build rat -PskipITs` passed with JDK 17.
- Process-level checks verified exit code 1, concise stderr, and no
stdout or stack trace for missing arguments and malformed Spark
configuration.
- `git diff --check` passed.

Spark tests use a local Hadoop catalog; remote catalog deployment and
the server REST submission path were not exercised end to end.

---------

Co-authored-by: İbrahim ERBİLEN <ibrahimerblnn46@gmail.com>
@lasdf1234

Copy link
Copy Markdown
Collaborator

@roryqi This is a split PR that has been reviewed several times. This PR seems fine for me. If you have time, please take a look. Thank you.

Resolve conflicts by retaining the implementation merged in apache#13329 and subsequent upstream improvements. The resulting tree matches upstream main.
@roryqi
roryqi self-requested a review October 16, 2026 06:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Add builtin-iceberg-rewrite-manifests maintenance job

3 participants