[AMORO-4163][ams] Fix CommitFailedException when loading legacy mixed-iceberg tables on Iceberg 1.7.2#4182
Open
lintingbin wants to merge 1 commit intoapache:masterfrom
Conversation
…-iceberg tables on Iceberg 1.7.x Found while investigating the CI failure in apache#4179. Iceberg 1.7.x introduced a breaking change in HadoopTableOperations.commit(): it now uses reference equality (==) to compare the `base` argument against the cached currentMetadata. Previously, newTableOperations() called ops.current() to obtain the current metadata, but versionAndMetadata() inside commit() may refresh the internal state and return a different object instance. When the two references differ, commit() throws CommitFailedException("Cannot commit changes based on stale table metadata") even though the metadata content is identical, causing table loading to fail. Fix: replace ops.current() with ops.refresh() so that the returned TableMetadata reference is the same object stored in ops' internal cache. When commit() then calls versionAndMetadata(), it finds the version unchanged on disk and returns the same cached reference, satisfying the reference-equality check. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
e8176fa to
603e139
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.
Search before asking
What type of PR is this?
What does this PR do?
Found while investigating the CI failure in #4179.
Root Cause
Iceberg 1.7.x introduced a breaking change in
HadoopTableOperations.commit(): it now uses reference equality (==) to compare thebaseargument against the internally cachedcurrentMetadata. If they differ, it throwsCommitFailedException("Cannot commit changes based on stale table metadata").In
InternalMixedIcebergHandler.newTableOperations(), when loading a legacy mixed-iceberg table (created before v0.7.0), the code calledops.current()to obtain the current metadata, then passed it asbasetoops.commit(base, legacyCurrent). However,commit()internally callsversionAndMetadata()which may refresh the internal state and return a different object instance than whatcurrent()returned — even when the on-disk metadata has not changed. This causes the reference-equality check to fail, throwingCommitFailedExceptionwith no cause.The exception propagates through
MixedHadoopTableOperations(which only wrapsCommitFailedExceptionwith a cause) and the Thrift layer, causingBasicMixedCatalog.createTableMeta()to throwIllegalStateException("update table meta failed"), which makes table creation fail.This is the root cause of the flaky
TestInternalMixedCatalogService.CompatibilityCatalogTests#testNewCatalogLoadHistoricalregression observed after the Iceberg 1.7.2 upgrade (#4163).Fix
Replace
ops.current()withops.refresh().refresh()reads from disk and stores the result as the internal cached reference, returning that same object. Whencommit()then callsversionAndMetadata(), it finds the version unchanged on disk and returns the same cached reference — satisfying the reference-equality check without any additional disk I/O beyond the singlerefresh()call.Checklist