[ https://issues.apache.org/jira/browse/IMPALA-12831?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Quanlong Huang resolved IMPALA-12831. ------------------------------------- Fix Version/s: Impala 4.4.0 Resolution: Fixed > HdfsTable.toMinimalTCatalogObject() should hold table read lock to generate > incremental updates > ----------------------------------------------------------------------------------------------- > > Key: IMPALA-12831 > URL: https://issues.apache.org/jira/browse/IMPALA-12831 > Project: IMPALA > Issue Type: Bug > Components: Catalog > Reporter: Quanlong Huang > Assignee: Quanlong Huang > Priority: Critical > Fix For: Impala 4.4.0 > > > When enable_incremental_metadata_updates=true (default), catalogd sends > incremental partition updates to coordinators, which goes into > HdfsTable.toMinimalTCatalogObject(): > {code:java} > public TCatalogObject toMinimalTCatalogObject() { > TCatalogObject catalogObject = super.toMinimalTCatalogObject(); > if (!BackendConfig.INSTANCE.isIncrementalMetadataUpdatesEnabled()) { > return catalogObject; > } > catalogObject.getTable().setTable_type(TTableType.HDFS_TABLE); > THdfsTable hdfsTable = new THdfsTable(hdfsBaseDir_, getColumnNames(), > nullPartitionKeyValue_, nullColumnValue_, > /*idToPartition=*/ new HashMap<>(), > /*prototypePartition=*/ new THdfsPartition()); > for (HdfsPartition part : partitionMap_.values()) { > hdfsTable.partitions.put(part.getId(), part.toMinimalTHdfsPartition()); > } > hdfsTable.setHas_full_partitions(false); > // The minimal catalog object of partitions contain the partition names. > hdfsTable.setHas_partition_names(true); > catalogObject.getTable().setHdfs_table(hdfsTable); > return catalogObject; > }{code} > Accessing table fields without holding the table read lock might be failed by > concurrent DDLs. All workloads that use this method (e.g. INVALIDATE > commands) could hit this issue. We've saw event-processor failed in > processing a RELOAD event that want to invalidates an HdfsTable: > {noformat} > E0216 16:23:44.283689 253 MetastoreEventsProcessor.java:899] Unexpected > exception received while processing event > Java exception follows: > java.util.ConcurrentModificationException > at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911) > at java.util.ArrayList$Itr.next(ArrayList.java:861) > at org.apache.impala.catalog.Column.toColumnNames(Column.java:148) > at org.apache.impala.catalog.Table.getColumnNames(Table.java:844) > at > org.apache.impala.catalog.HdfsTable.toMinimalTCatalogObject(HdfsTable.java:2132) > at > org.apache.impala.catalog.CatalogServiceCatalog.addIncompleteTable(CatalogServiceCatalog.java:2221) > at > org.apache.impala.catalog.CatalogServiceCatalog.addIncompleteTable(CatalogServiceCatalog.java:2202) > at > org.apache.impala.catalog.CatalogServiceCatalog.invalidateTable(CatalogServiceCatalog.java:2797) > at > org.apache.impala.catalog.events.MetastoreEvents$ReloadEvent.processTableInvalidate(MetastoreEvents.java:2734) > at > org.apache.impala.catalog.events.MetastoreEvents$ReloadEvent.process(MetastoreEvents.java:2656) > at > org.apache.impala.catalog.events.MetastoreEvents$MetastoreEvent.processIfEnabled(MetastoreEvents.java:522) > at > org.apache.impala.catalog.events.MetastoreEventsProcessor.processEvents(MetastoreEventsProcessor.java:1052) > at > org.apache.impala.catalog.events.MetastoreEventsProcessor.processEvents(MetastoreEventsProcessor.java:881) > at > java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) > at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) > at > java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) > at > java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) > at > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) > at > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) > at java.lang.Thread.run(Thread.java:750){noformat} > I can reproduce the issue using the following test: > {code:python} > @CustomClusterTestSuite.with_args( > catalogd_args="--enable_incremental_metadata_updates=true") > def test_concurrent_invalidate_metadata_with_refresh(self, unique_database): > # Create a wide table with some partitions > tbl = unique_database + ".wide_tbl" > create_stmt = "create table {} (".format(tbl) > for i in range(600): > create_stmt += "col{} int, ".format(i) > create_stmt += "col600 int) partitioned by (p int) stored as textfile" > self.execute_query(create_stmt) > for i in range(10): > self.execute_query("alter table {} add partition (p={})".format(tbl, i)) > refresh_stmt = "refresh " + tbl > handle = self.client.execute_async(refresh_stmt) > for i in range(10): > self.execute_query("invalidate metadata " + tbl) > # Always keep a concurrent REFRESH statement running > if self.client.get_state(handle) == > self.client.QUERY_STATES['FINISHED']: > handle = self.client.execute_async(refresh_stmt){code} > and see a similar exception: > {noformat} > E0222 10:44:40.912338 6833 JniUtil.java:183] > da4099ef24bb1f03:01c8f5d200000000] Error in INVALIDATE TABLE > test_concurrent_invalidate_metadata_with_refresh_65c57cb0.wide_tbl issued by > quanlong. Time spent: 32ms > I0222 10:44:40.912528 6833 jni-util.cc:302] > da4099ef24bb1f03:01c8f5d200000000] java.util.ConcurrentModificationException > at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911) > at java.util.ArrayList$Itr.next(ArrayList.java:861) > at org.apache.impala.catalog.Column.toColumnNames(Column.java:148) > at org.apache.impala.catalog.Table.getColumnNames(Table.java:875) > at > org.apache.impala.catalog.HdfsTable.toMinimalTCatalogObject(HdfsTable.java:2132) > at > org.apache.impala.catalog.CatalogServiceCatalog.addIncompleteTable(CatalogServiceCatalog.java:2264) > at > org.apache.impala.catalog.CatalogServiceCatalog.addIncompleteTable(CatalogServiceCatalog.java:2245) > at > org.apache.impala.catalog.CatalogServiceCatalog.invalidateTable(CatalogServiceCatalog.java:2840) > at > org.apache.impala.service.CatalogOpExecutor.execResetMetadataImpl(CatalogOpExecutor.java:6676) > at > org.apache.impala.service.CatalogOpExecutor.execResetMetadata(CatalogOpExecutor.java:6612) > at > org.apache.impala.service.JniCatalog.lambda$resetMetadata$4(JniCatalog.java:327) > at > org.apache.impala.service.JniCatalogOp.lambda$execAndSerialize$1(JniCatalogOp.java:90) > at org.apache.impala.service.JniCatalogOp.execOp(JniCatalogOp.java:58) > at > org.apache.impala.service.JniCatalogOp.execAndSerialize(JniCatalogOp.java:89) > at > org.apache.impala.service.JniCatalogOp.execAndSerialize(JniCatalogOp.java:100) > at > org.apache.impala.service.JniCatalog.execAndSerialize(JniCatalog.java:243) > at > org.apache.impala.service.JniCatalog.execAndSerialize(JniCatalog.java:257) > at > org.apache.impala.service.JniCatalog.resetMetadata(JniCatalog.java:326){noformat} -- This message was sent by Atlassian Jira (v8.20.10#820010)