Fix query-scope cache invalidation for Glue catalog#28266
Fix query-scope cache invalidation for Glue catalog#28266piotrrzysko wants to merge 3 commits intotrinodb:masterfrom
Conversation
e796ef4 to
05b11d6
Compare
findepi
left a comment
There was a problem hiding this comment.
"Add test for uncommitted manifest cleanup"
| //TODO: Fix https://github.com/trinodb/trino/issues/23941 | ||
| abort("Skipped for now due to #23941"); |
There was a problem hiding this comment.
the test is self-maintained when it follows the pattern
assertThatThrownBy(super::test_name)
.hasMessage...(...);
There was a problem hiding this comment.
I’m not sure yet about this. I think it fails nondeterministically, and I couldn’t find the error message with which it failed for me. Locally, I couldn’t reproduce failures for either this test or the one above.
There was a problem hiding this comment.
you're right. this pattern is not applicable for tests which fail nondeterministically
...rc/test/java/io/trino/plugin/iceberg/catalog/rest/TestIcebergS3TablesConnectorSmokeTest.java
Outdated
Show resolved
Hide resolved
...java/io/trino/plugin/iceberg/catalog/rest/TestIcebergUnityRestCatalogConnectorSmokeTest.java
Outdated
Show resolved
Hide resolved
plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/BaseIcebergConnectorSmokeTest.java
Outdated
Show resolved
Hide resolved
| public void testDeleteRowsConcurrently() {} | ||
|
|
||
| @Test | ||
| @Disabled("Moto is not concurrency safe") |
There was a problem hiding this comment.
😮
Does it make sense to continue to test with Moto? What value does it add?
There was a problem hiding this comment.
Does it make sense to continue to test with Moto?
That’s a good question, but I think it's outside the scope of this PR. I followed the existing pattern (see the test above).
There was a problem hiding this comment.
That’s a good question, but I think it's outside the scope of this PR.
of course!
| @@ -449,7 +443,7 @@ private void getColumnsFromIcebergMetadata( | |||
| for (SchemaTableName tableName : relationFilter.apply(glueTables.keySet())) { | |||
| Table table = glueTables.get(tableName); | |||
| // potentially racy with invalidation, but TrinoGlueCatalog is session-scoped | |||
There was a problem hiding this comment.
This comment was already here. Now we're adding QueryScopedCachingTrinoGlueClient.
Do we really need two levels of caching & invalidation?
There was a problem hiding this comment.
By two levels of caching & invalidation do you mean TrinoGlueCatalog (level 1) and QueryScopedCachingTrinoGlueClient (level 2)?
If so, I introduced QueryScopedCachingTrinoGlueClient to keep cache invalidation close to the state-modifying operations. Previously, they were decoupled, which in my opinion led to the bug I’m trying to fix.
There was a problem hiding this comment.
I get there is a subtle bug manifesting in partial cleanup.
Is the bug fixiable without introducing QueryScopedCachingTrinoGlueClient? what would the fix look like, and what would be the cons of doing it?
There was a problem hiding this comment.
I’m fixing a missing invalidation in GlueIcebergTableOperations#commitTableUpdate, where the raw GlueClient was used. I introduced QueryScopedCachingTrinoGlueClient to share invalidation logic between TrinoGlueCatalog and GlueIcebergTableOperations.
I didn’t intend to address this pre-existing code comment.
d56bb4c to
985fca7
Compare
Verify that uncommitted manifest files are properly cleaned up. The test uses concurrent INSERT operations to create conflicts, then checks if any orphaned manifests remain.
GlueIcebergTableOperations#commitTableUpdate was not invalidating the query-scope table metadata cache after a successful commit. This caused Iceberg to see stale metadata when determining which files were committed, resulting in uncommitted manifest files from failed retry attempts being left as orphans instead of being cleaned up automatically. Changes in testInformationSchemaTableAndColumns were required because now INSERTs in the test setup populate the filesystem cache so SELECTs hit the cache.
985fca7 to
5cefeca
Compare
|
|
||
| public void populateCache(SchemaTableName tableName, Table table) | ||
| { | ||
| uncheckedCacheGet(tableCache, tableName, () -> table); |
| } | ||
| } | ||
|
|
||
| private Set<String> listManifestFiles(String tableName) |
There was a problem hiding this comment.
Can we use computeActual("SELECT path FROM \"table$manifests\"").getOnlyColumnAsSet() ?
| assertGlueMetastoreApiInvocations("REFRESH MATERIALIZED VIEW test_refresh_mview_view", | ||
| ImmutableMultiset.<GlueMetastoreMethod>builder() | ||
| .addCopies(GET_TABLE, 6) | ||
| .addCopies(GET_TABLE, 7) |
| .add(new FileOperation(METADATA_JSON, "InputFile.length")) | ||
| .add(new FileOperation(METADATA_JSON, "InputFile.newInput")) |
There was a problem hiding this comment.
from commit message
Changes in testInformationSchemaTableAndColumns were required because
now INSERTs in the test setup populate the filesystem cache so SELECTs
hit the cache.
this means the test is no longer testing what it appears it tries to
DESCRIBE still can result in InputFile.newInput, just that it's hidden from the test,
The test should be running with iceberg.metadata-cache.enabled=false, or flush FS cache in assertInvocations
There was a problem hiding this comment.
This test class is about testing Glue catalog accesses, and that's what it should focus on.
There are other tests like TestIcebergFileOperations which focus on iceberg metadata accesses on filesystem.
There was a problem hiding this comment.
The filesystem access counts depend on catalog in use. In fact, they are here for metadata queries, which have have quite important catalog-specific component. Here we're asserting a metadata query. TestIcebergFileOperations is awesome for regular query access patterns and catalog-agnostic components. It doesn't run with Glue and doesn't, therefore, guard against potential metadata-related regressions in Glue catalog.
There was a problem hiding this comment.
I thought any catalog would need to look-up table entry in metastore and then read metadata.json from FS to show output of DESCRIBE. Not sure why the FS access would depend on catalog.
There was a problem hiding this comment.
|
This pull request has gone a while without any activity. Ask for help on #core-dev on Trino slack. |
Description
This PR fixes a bug where
GlueIcebergTableOperations#commitTableUpdatewas not invalidating the query-scope table metadata cache after a successful commit. As a result, Iceberg observed stale metadata when determining committed files. This caused uncommitted manifest files from failed retry attempts to remain as orphans instead of being cleaned up.Automatic cleanup is performed in BaseTransaction#commitSimpleTransaction However, it was never triggered because
committedFileswas null due to stale information returned by TableOperations::current.The fix refactors the code to wrap the Glue client in a caching client implementation, centralizing cache management and preventing similar bugs in the future.
Additional context and related issues
Release notes
( ) This is not user-visible or is docs only, and no release notes are required.
( ) Release notes are required. Please propose a release note for me.
(x) Release notes are required, with the following suggested text: