beyondhj opened a new issue, #12589:
URL: https://github.com/apache/gravitino/issues/12589
### Version
main branch
### Describe what's wrong
**Title:** JDBC catalog operations fail with `CommunicationsException` after
idle period when using MySQL backend
---
### Describe what's wrong
When using Gravitino with Paimon or Iceberg catalogs that store metadata in
a MySQL database via JDBC, operations such as `listSchemas` (or `listDatabases`
for Paimon) occasionally fail after the system has been idle for some time.
The failure stack trace shows that the underlying MySQL connection has been
closed by the server due to exceeding the configured `wait_timeout`, but the
application attempts to reuse the stale connection, resulting in a
`CommunicationsException` with a `Broken pipe` cause.
This affects both:
- `PaimonCatalogOperations.listSchemas` → `JdbcCatalog.listDatabases`
- `IcebergCatalogOperations.listSchemas` → `JdbcCatalog.listNamespaces`
The error is observed in the Gravitino server logs when calling the REST API
or through the UI.
---
### Error message and/or stacktrace
For Paimon catalog:
```
Failed to operate object operation [LIST] under [paimon_550222763176624128],
reason [Failed to execute query: SELECT DISTINCT database_name FROM
paimon_tables WHERE catalog_key = ?]
java.lang.RuntimeException: Failed to execute query: SELECT DISTINCT
database_name FROM paimon_tables WHERE catalog_key = ?
at org.apache.paimon.jdbc.JdbcCatalog.fetch(JdbcCatalog.java:462)
at org.apache.paimon.jdbc.JdbcCatalog.listDatabases(JdbcCatalog.java:163)
...
Caused by: com.mysql.cj.jdbc.exceptions.CommunicationsException: The last
packet successfully received from the server was 53,516,254 milliseconds ago.
The last packet sent successfully to the server was 53,516,256 milliseconds
ago. is longer than the server configured value of 'wait_timeout'.
...
Caused by: java.net.SocketException: Broken pipe
```
For Iceberg catalog:
```
Failed to operate object operation [LIST] under
[iceberg_526363515375091712], reason [Failed to execute query: SELECT DISTINCT
table_namespace FROM iceberg_tables WHERE catalog_name = ?]
org.apache.iceberg.jdbc.UncheckedSQLException: Failed to execute query:
SELECT DISTINCT table_namespace FROM iceberg_tables WHERE catalog_name = ?
at org.apache.iceberg.jdbc.JdbcCatalog.fetch(JdbcCatalog.java:813)
at org.apache.iceberg.jdbc.JdbcCatalog.listNamespaces(JdbcCatalog.java:437)
...
Caused by: com.mysql.cj.jdbc.exceptions.CommunicationsException: The last
packet successfully received from the server was ... longer than wait_timeout.
...
Caused by: java.net.SocketException: Broken pipe
```
### Error message and/or stacktrace
Failed to operate object operation [LIST] under [paimon_550222763176624128],
reason [Failed to execute query: SELECT DISTINCT database_name FROM
paimon_tables WHERE catalog_key = ?]
java.lang.RuntimeException: Failed to execute query: SELECT DISTINCT
database_name FROM paimon_tables WHERE catalog_key = ?
at org.apache.paimon.jdbc.JdbcCatalog.fetch(JdbcCatalog.java:462)
at org.apache.paimon.jdbc.JdbcCatalog.listDatabases(JdbcCatalog.java:163)
at
org.apache.paimon.catalog.DelegateCatalog.listDatabases(DelegateCatalog.java:66)
at
org.apache.gravitino.catalog.lakehouse.paimon.ops.PaimonCatalogOps.listDatabases(PaimonCatalogOps.java:69)
at
org.apache.gravitino.catalog.lakehouse.paimon.PaimonCatalogOperations.listSchemas(PaimonCatalogOperations.java:144)
at
org.apache.gravitino.catalog.SchemaOperationDispatcher.lambda$listSchemas$0(SchemaOperationDispatcher.java:83)
at
org.apache.gravitino.catalog.CatalogManager$CatalogWrapper.lambda$doWithSchemaOps$0(CatalogManager.java:148)
at
org.apache.gravitino.utils.IsolatedClassLoader.withClassLoader(IsolatedClassLoader.java:86)
at
org.apache.gravitino.catalog.CatalogManager$CatalogWrapper.doWithSchemaOps(CatalogManager.java:143)
at
org.apache.gravitino.catalog.SchemaOperationDispatcher.lambda$listSchemas$1(SchemaOperationDispatcher.java:83)
at
org.apache.gravitino.catalog.OperationDispatcher.doWithCatalog(OperationDispatcher.java:98)
at
org.apache.gravitino.catalog.SchemaOperationDispatcher.lambda$listSchemas$2(SchemaOperationDispatcher.java:81)
at
org.apache.gravitino.lock.TreeLockUtils.doWithTreeLock(TreeLockUtils.java:49)
at
org.apache.gravitino.catalog.SchemaOperationDispatcher.listSchemas(SchemaOperationDispatcher.java:77)
at
org.apache.gravitino.catalog.SchemaNormalizeDispatcher.listSchemas(SchemaNormalizeDispatcher.java:60)
at
org.apache.gravitino.listener.SchemaEventDispatcher.listSchemas(SchemaEventDispatcher.java:77)
at
org.apache.gravitino.hook.SchemaHookDispatcher.listSchemas(SchemaHookDispatcher.java:62)
at
org.apache.gravitino.server.web.rest.SchemaOperations.lambda$listSchemas$0(SchemaOperations.java:110)
at
java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.base/javax.security.auth.Subject.doAs(Subject.java:439)
at org.apache.gravitino.utils.PrincipalUtils.doAs(PrincipalUtils.java:53)
at org.apache.gravitino.server.web.Utils.doAs(Utils.java:209)
at
org.apache.gravitino.server.web.rest.SchemaOperations.listSchemas(SchemaOperations.java:100)
at jdk.internal.reflect.GeneratedMethodAccessor109.invoke(Unknown Source)
at
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at
org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)
at
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:146)
at
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:189)
at
org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:176)
at
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:93)
at
org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:478)
at
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:400)
at
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:256)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
at
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
at
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:235)
at
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684)
at
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
at
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:358)
at
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:311)
at
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799)
at
org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1656)
at
org.apache.gravitino.server.authentication.AuthenticationFilter.lambda$doFilter$0(AuthenticationFilter.java:106)
at
java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
at java.base/javax.security.auth.Subject.doAs(Subject.java:439)
at org.apache.gravitino.utils.PrincipalUtils.doAs(PrincipalUtils.java:53)
at
org.apache.gravitino.server.authentication.AuthenticationFilter.doFilter(AuthenticationFilter.java:103)
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
at
org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
at
org.apache.gravitino.server.web.VersioningFilter.doFilter(VersioningFilter.java:111)
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
at
org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
at
org.apache.gravitino.server.web.HttpAuditFilter.doFilter(HttpAuditFilter.java:162)
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
at
org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
at
org.apache.gravitino.server.web.RequestContextFilter.doFilter(RequestContextFilter.java:59)
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
at
org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
at
org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:552)
at
org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at
org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600)
at
org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at
org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
at
org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
at
org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
at
org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440)
at
org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
at
org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505)
at
org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
at
org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
at
org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355)
at
org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at
org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
at
org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.Server.handle(Server.java:516)
at
org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479)
at
org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
at
org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
at
org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
at
org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
at
org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
at
org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
at
org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409)
at
org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
at
org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: com.mysql.cj.jdbc.exceptions.CommunicationsException: The last
packet successfully received from the server was 53,516,254 milliseconds ago.
The last packet sent successfully to the server was 53,516,256 milliseconds
ago. is longer than the server configured value of 'wait_timeout'. You should
consider either expiring and/or testing connection validity before use in your
application, increasing the server configured values for client timeouts, or
using the Connector/J connection property 'autoReconnect=true' to avoid this
problem.
at
com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:165)
at
com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:55)
at
com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:988)
at
com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1056)
at org.apache.paimon.jdbc.JdbcCatalog.lambda$fetch$12(JdbcCatalog.java:453)
at
org.apache.paimon.client.ClientPool$ClientPoolImpl.run(ClientPool.java:68)
at org.apache.paimon.jdbc.JdbcCatalog.fetch(JdbcCatalog.java:446)
... 97 more
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: The last
packet successfully received from the server was 53,516,254 milliseconds ago.
The last packet sent successfully to the server was 53,516,256 milliseconds
ago. is longer than the server configured value of 'wait_timeout'. You should
consider either expiring and/or testing connection validity before use in your
application, increasing the server configured values for client timeouts, or
using the Connector/J connection property 'autoReconnect=true' to avoid this
problem.
at
java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native
Method)
at
java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at
java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at
java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at
java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
at
com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:52)
at
com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:95)
at
com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:140)
at
com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:156)
at com.mysql.cj.protocol.a.NativeProtocol.send(NativeProtocol.java:635)
at
com.mysql.cj.protocol.a.NativeProtocol.sendCommand(NativeProtocol.java:689)
at
com.mysql.cj.protocol.a.NativeProtocol.sendQueryPacket(NativeProtocol.java:938)
at com.mysql.cj.NativeSession.execSQL(NativeSession.java:817)
at
com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:963)
... 101 more
Caused by: java.net.SocketException: Broken pipe
at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:420)
at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:440)
at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:826)
at java.base/java.net.Socket$SocketOutputStream.write(Socket.java:1035)
at
java.base/java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:81)
at
java.base/java.io.BufferedOutputStream.flush(BufferedOutputStream.java:142)
at
com.mysql.cj.protocol.a.SimplePacketSender.send(SimplePacketSender.java:48)
at
com.mysql.cj.protocol.a.TimeTrackingPacketSender.send(TimeTrackingPacketSender.java:43)
at com.mysql.cj.protocol.a.NativeProtocol.send(NativeProtocol.java:628)
... 105 more
### How to reproduce
1. Deploy Gravitino with a Paimon or Iceberg catalog configured to use MySQL
as the JDBC metadata store (e.g., set `jdbc.url`, `jdbc.user`, `jdbc.password`).
2. Ensure the MySQL server has a `wait_timeout` value (e.g., 53,516,254
milliseconds) that is shorter than the typical idle period of the Gravitino
server.
3. Start Gravitino and perform a successful schema listing operation to
establish a database connection.
4. Leave the system idle for a duration longer than MySQL’s `wait_timeout`.
5. Perform another schema listing operation (e.g., via REST API or the UI).
6. The operation fails with the above `CommunicationsException`.
### Additional context
_No response_
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]