Conversation
…-format connectors and move AMS to Iceberg 1.10.2 Signed-off-by: Jiwon Park <jiwonpark@apache.org>
…a fixture to Iceberg 1.10 REPLACE validation Signed-off-by: Jiwon Park <jiwonpark@apache.org>
j1wonpark
force-pushed
the
poc/maintenance-iceberg-1.10
branch
from
September 18, 2026 10:40
24e8f5f to
1cc6f2c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why are the changes needed?
Close #4377.
This follows up on the Iceberg upgrade discussion: let the Iceberg version used by the self-optimizing / maintenance path evolve independently from the mixed-format connectors, so that a maintenance-side upgrade no longer forces engine drops on connector users.
It keeps every module and class where it is. AMS, the optimizers and
distselect Iceberg 1.10.2;amoro-format-iceberg,amoro-mixed-hiveand all engine connectors stay on 1.8.1.The code is ready for review. I am opening it as a draft because one point needs a community decision (Hadoop 2 support for AMS, see below); once that is settled I will mark it ready.
Brief change log
pom.xml: newmaintenance-iceberg.version(1.10.2) andmaintenance-parquet.version(1.16.0) properties.iceberg.versionstays 1.8.1.pom.xml: the connector-side Parquet version is now explicit as well.parquet-avro.versionbecomesparquet.version(still 1.15.2) and the root manages all six Parquet artifacts with it, so the two sides read asiceberg.version/parquet.versionvs.maintenance-iceberg.version/maintenance-parquet.version. On the connector sideparquet-jacksonkeeps its separate 1.13.1 pin; on the maintenance side it is managed at 1.16.0 like the rest of the family. Verified withdependency:listbefore and after: shipped artifacts (connector runtime jars, Trino) resolve exactly as before; the only change is thatamoro-format-paimonandamoro-mixed-spark-3-commonpreviously resolved a mix of 1.13.1 / 1.15.0 / 1.15.2 and now resolve 1.15.2 consistently.amoro-ams,amoro-optimizer,dist: seticeberg.versionto the maintenance version and manage the Iceberg artifacts the root does not pin (iceberg-api,iceberg-bundled-guava, Spark binding and extensions) plus the Parquet family. The Parquet alignment is required: Iceberg 1.10.x needs a newer Parquet than the one resolved through 1.8.1, and this shows up asNoSuchMethodErrorat runtime, not at build time.ParquetValueReaders.StructReader(types, readers)andParquetValueReader.setPageSource(pages, rowPosition)) are switched to the form that exists in both 1.8.1 and 1.10.x, inamoro-mixed-hiveand the Spark 3.4 / 3.5 readers that AMS loads for its local terminal. The shared modules are still compiled against 1.8.1; the same bytecode runs on both versions.TestMaintenanceIcebergCompatibilityinamoro-amswrites a Parquet file and reads it back through the mixed-Hive generic reader (AdaptHiveParquet/AdaptHiveGenericParquetReaders) and the Spark 3.5 reader (SparkParquetReaders) on the AMS classpath, i.e. against Iceberg 1.10.2. Without the reader change above both fail with theNoSuchMethodError; with it, both pass. It needs no metastore, so it does not interact with the shared test HMS of the other AMS tests.TestIcebergV3OptimizingCommit: one V2 fixture wrote three records to replace two. Iceberg 1.10 validates that a REPLACE commit does not add more records than it replaces (Invalid REPLACE operation: 3 added records > 2 replaced records), so the fixture now keeps the input row count. Amoro's rewrite outputs never add records, so no production code is affected.-pl '!amoro-ams,!dist'), see open questions below. The Hadoop 2 docker image buildsdistwith-Phadoop2,spark-3.5.dev/deps: dependency lists regenerated withdev/dependencies.sh --replace. Besides Iceberg 1.10.2 and Parquet 1.16.0, the maintenance classpath picks upparquet-variant,jts-core, and transitive bumps of aircompressor (0.27 -> 2.0.3), avro (1.12.0 -> 1.12.1) and httpclient5 / httpcore5 (5.4.1 / 5.3.1 -> 5.5 / 5.3.4). The Hadoop 2 list is nowdependencies-hadoop-2-spark-3.5because the Hadoop 2 dist build uses the Spark 3.5 profile.LICENSE-binary:jts-coreis a new transitive dependency of Parquet 1.16 (EDL 1.0). The other new or bumped artifacts are already covered.How was this patch tested?
Add some test cases that check the changes thoroughly including negative and positive cases if possible
Add screenshots for manual tests if appropriate
Run test locally before making a pull request
Same shared bytecode (
amoro-common,amoro-format-iceberg,amoro-mixed-hive, compiled with JDK 11 against Iceberg 1.8.1) run with the existing I/O tests on both an Iceberg 1.8.1 and an Iceberg 1.10.2 classpath: 85 passed / 15 assumption-skipped / 0 failed on each side. Class hashes verified identical between the two runs.On the AMS classpath (Iceberg 1.10.2, JDK 11):
TestKeyedContinuousOptimizingandTestUnKeyedContinuousOptimizing(12/12, native Iceberg, mixed Iceberg and mixed Hive),TestSnapshotExpire*andTestOrphanFileClean*(116 passed / 28 assumption-skipped / 0 failed).Local Spark 3.5 with the mixed, Iceberg and Paimon extensions registered together (the terminal's combination): create native Iceberg table, insert, aggregate.
Packaged artifacts inspected with a small probe on JDK 11:
amoro-ams-dependency/lib, Flink and Spark optimizer jars load Iceberg 1.10.2 (no duplicateorg/apache/icebergclasses); mixed Flink 1.18 / 1.19 / 1.20 and Spark 3.5 runtime jars load relocated Iceberg 1.8.1.Reactor builds: default (Spark 3.5),
-Pspark-3.4,-Pspark-3.3(connectors and optimizers only),-Phadoop2(connectors and optimizers only).Not covered: end-to-end run with an external optimizer process, real terminal API / mixed catalog SQL, Trino, full dist tarball run.
Decision needed
Hadoop 2 support for AMS. Parquet 1.16 calls
FileSystem.openFile(Path), which does not exist in Hadoop 2.10, so with-Phadoop2the AMS I/O tests fail withNoSuchMethodError. There is no workaround on our side short of keeping AMS on the old Parquet, which defeats the upgrade.My proposal: AMS requires Hadoop 3 from the next release; the mixed-format connectors keep their Hadoop 2 build. This PR already implements that on the CI side (the Hadoop 2 job builds connectors and optimizers only). What still needs to follow if we agree: drop the Hadoop 2 dist / docker image (it currently still compiles with
-Phadoop2,spark-3.5but AMS cannot read Parquet in it) and note the change in the release notes. If anyone still runs AMS on Hadoop 2, please speak up.Notes and limitations
iceberg-spark-3.3was last published for Iceberg 1.8.1, so AMS can no longer be built with-Pspark-3.3. The default AMS build is Spark 3.5 and is unaffected; the Spark 3.3 mixed-format connector is still built and published, just not in the same reactor as AMS.DataFileserialization is not compatible between 1.8.1 and 1.9+ (serialVersionUID). This PR sets both from the same property.MetadataColumns.ROW_ID, ...) cannot live inamoro-format-icebergas it is today. New V3-specific maintenance code needs a location that compiles against the maintenance version. This PR does not decide that; it only shows that the version split itself does not require moving modules first.Documentation