This is an automated email from the ASF dual-hosted git repository.

yuqi1129 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/main by this push:
     new 91a5966054 [#12589] fix(iceberg-catalog): Fix JDBC 
CommunicationsException after idle timeout for MySQL backend (#12662)
91a5966054 is described below

commit 91a5966054da451a4e38886b35875b13b1451ef2
Author: Arvin <[email protected]>
AuthorDate: Thu Sep 3 18:56:38 2026 +0800

    [#12589] fix(iceberg-catalog): Fix JDBC CommunicationsException after idle 
timeout for MySQL backend (#12662)
    
    ## What changes were proposed in this pull request?
    
    Add SQLSTATE `08S01` (Communication link failure) to the JDBC client
    pool retryable status codes, so that idle connections dropped by MySQL
    `wait_timeout` are automatically retried instead of failing with
    `CommunicationsException`.
    
    ## Why are the changes needed?
    
    Fixes #12589
    
    The Iceberg JDBC catalog uses `JdbcClientPool` which does not retry on
    `08S01` by default. When MySQL `wait_timeout` closes an idle connection,
    the driver throws `CommunicationsException` with SQLSTATE `08S01`,
    causing catalog operations to fail.
    
    ## Does this PR introduce any user-facing change?
    
    No.
    
    Signed-off-by: zhang-arvin <[email protected]>
---
 .../iceberg/common/utils/IcebergCatalogUtil.java   |  8 ++++++++
 .../common/utils/TestIcebergCatalogUtil.java       | 22 ++++++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git 
a/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/utils/IcebergCatalogUtil.java
 
b/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/utils/IcebergCatalogUtil.java
index 466a9de314..5674b6c1a7 100644
--- 
a/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/utils/IcebergCatalogUtil.java
+++ 
b/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/utils/IcebergCatalogUtil.java
@@ -128,6 +128,14 @@ public class IcebergCatalogUtil {
     // explicit config.
     properties.putIfAbsent(IcebergConstants.ICEBERG_JDBC_STRICT_MODE, "true");
 
+    // Add SQLSTATE 08S01 (Communication link failure) to retryable status 
codes so that
+    // idle connections dropped by MySQL wait_timeout are automatically 
retried instead of
+    // failing with CommunicationsException.
+    String existing = properties.putIfAbsent("retryable_status_codes", 
"08S01");
+    if (existing != null && !existing.contains("08S01")) {
+      properties.put("retryable_status_codes", existing + ",08S01");
+    }
+
     HdfsConfiguration hdfsConfiguration = new HdfsConfiguration();
     properties.forEach(hdfsConfiguration::set);
     AuthenticationConfig authenticationConfig = new 
AuthenticationConfig(properties);
diff --git 
a/iceberg/iceberg-common/src/test/java/org/apache/gravitino/iceberg/common/utils/TestIcebergCatalogUtil.java
 
b/iceberg/iceberg-common/src/test/java/org/apache/gravitino/iceberg/common/utils/TestIcebergCatalogUtil.java
index 79e18b5028..a575352d3e 100644
--- 
a/iceberg/iceberg-common/src/test/java/org/apache/gravitino/iceberg/common/utils/TestIcebergCatalogUtil.java
+++ 
b/iceberg/iceberg-common/src/test/java/org/apache/gravitino/iceberg/common/utils/TestIcebergCatalogUtil.java
@@ -338,4 +338,26 @@ public class TestIcebergCatalogUtil {
     return new UncheckedSQLException(
         new SQLSyntaxErrorException(causeMessage), "Cannot check and 
eventually update SQL schema");
   }
+
+  @Test
+  void testJdbcRetryableStatusCodes() {
+    Map<String, String> properties = new HashMap<>();
+    properties.put(CatalogProperties.URI, "jdbc:sqlite::memory:");
+    properties.put(CatalogProperties.WAREHOUSE_LOCATION, "test");
+    properties.put(IcebergConstants.GRAVITINO_JDBC_DRIVER, "org.sqlite.JDBC");
+    properties.put(IcebergConstants.ICEBERG_JDBC_USER, "test");
+    properties.put(IcebergConstants.ICEBERG_JDBC_PASSWORD, "test");
+    properties.put(IcebergConstants.ICEBERG_JDBC_INITIALIZE, "true");
+
+    Catalog catalog =
+        IcebergCatalogUtil.loadCatalogBackend(
+            IcebergCatalogBackend.JDBC, new IcebergConfig(properties));
+    Assertions.assertInstanceOf(ClosableJdbcCatalog.class, catalog);
+
+    // Verify that calling loadCatalogBackend again does not throw
+    Catalog catalog2 =
+        IcebergCatalogUtil.loadCatalogBackend(
+            IcebergCatalogBackend.JDBC, new IcebergConfig(properties));
+    Assertions.assertInstanceOf(ClosableJdbcCatalog.class, catalog2);
+  }
 }

Reply via email to