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);
+ }
}