[IcebergIO] Use partition-aligned manifests for faster query pruning#39158
[IcebergIO] Use partition-aligned manifests for faster query pruning#39158atognolas wants to merge 1 commit into
Conversation
When AppendFilesToTables commits data files that all share the same partition spec, it currently places them into a single manifest via appendFile(). This prevents query engines (BigQuery, Trino) from performing manifest-level partition pruning. Group data files by their partition path and write one manifest per partition using appendManifest(). The commit remains atomic (single AppendFiles operation) while producing partition-aligned manifests that enable manifest-level pruning. Measured on a 400-partition table with 99-column schema: - Single manifest: 14s BQ slot time - 400 partition-aligned manifests: 2.86s BQ slot time (5x improvement) Note: Iceberg's commit.manifest-merge.enabled (default true) will merge these manifests. Users who want to preserve partition alignment should set this to false or run periodic rewriteManifests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request optimizes Iceberg table writes by implementing partition-aligned manifest generation. By grouping data files by their partition path before committing, the system allows downstream query engines to perform more efficient partition pruning, reducing scan times and improving overall query performance without sacrificing commit atomicity. Highlights
New Features🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request updates the appendDataFiles method in AppendFilesToTables.java to group data files by partition and write them into manifest files before appending them to the table. The review feedback highlights a compilation error due to an undefined createManifestWriter method and a potential resource leak if the writer is not closed within a try-finally block. A suggestion is provided to use standard Iceberg APIs and ensure proper resource cleanup.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| ManifestWriter<DataFile> writer = | ||
| createManifestWriter( | ||
| table.location(), uuid + "-" + manifestIdx++, spec, io); | ||
| for (DataFile file : files) { | ||
| writer.add(file); | ||
| } | ||
| writer.close(); | ||
| update.appendManifest(writer.toManifestFile()); |
There was a problem hiding this comment.
There are two issues here:
createManifestWriteris not a standard Iceberg API and is not defined in this class, which will cause a compilation error.- The
ManifestWriteris not closed within atry-finallyortry-with-resourcesblock. If an exception occurs while adding files, the writer will leak resources.
We can resolve both issues by using the standard ManifestFiles.write API from Iceberg and wrapping the write loop in a try-finally block to ensure the writer is closed properly before retrieving the manifest file.
Note: You will need to import org.apache.iceberg.ManifestFiles and org.apache.iceberg.io.OutputFile.
OutputFile outputFile = io.newOutputFile(
table.location() + "/metadata/" + uuid + "-" + manifestIdx++ + ".avro");
ManifestWriter<DataFile> writer = ManifestFiles.write(spec, outputFile);
try {
for (DataFile file : files) {
writer.add(file);
}
} finally {
writer.close();
}
update.appendManifest(writer.toManifestFile());|
@ahmedabu98 — Would you mind reviewing this? These are a set of IcebergIO fixes validated on production-scale benchmarks (39M users, 400 partitions, 99-column schema). The four PRs are independent and can be reviewed/merged in any order. |
|
Checks are failing. Will not request review until checks are succeeding. If you'd like to override that behavior, comment |
ahmedabu98
left a comment
There was a problem hiding this comment.
LGTM but please run ./gradlew sdks:java:io:iceberg:spotlessApply
Summary
AppendFilesToTables.appendDataFiles()to group data files by partition path and write one manifest per partition usingappendManifest()AppendFilesoperation) while producing partition-aligned manifestsrewriteManifestsstepMotivation
When all files share a single partition spec,
appendDataFiles()currently usesappendFile()which places everything into one manifest. With hundreds of partitions, query engines must scan all file entries in the manifest even for single-partition queries.Measured on a 400-partition table with 99-column schema:
Notes
Iceberg's
commit.manifest-merge.enabled(defaulttrue) will merge these manifests back into fewer manifests. Users who want to preserve partition alignment should set this tofalseor run periodicrewriteManifests.Test plan
AppendFilesToTablesTestpasses🤖 Generated with Claude Code