有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java从MySql迁移:MariaDB服务器意外关闭客户端连接

由于许可/商业使用原因,我们正在从MySql迁移到MariaDB

我们已经成功地用MariaDB客户机jar替换了MySql连接器jar(第一次更改),现在正在尝试在不更改数据文件的情况下用MariaDB服务器替换MySql服务器

我们所有的应用程序都能完美运行约8-12小时,之后我们会看到以下异常:


org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Cannot open connection
Caused by:
org.hibernate.exception.JDBCConnectionException: Cannot open connection
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:74)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:29)
        at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:426)
        at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:144)
        at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:119)
        at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:57)
        at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1326)
        at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:494)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:315)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:257)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:102)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:209)
        at $Proxy4.getMessageCountByStatus(Unknown Source)
        at com.onmobile.cmfweb.monitoring.CmfMessagesMonitor.getMessageCounts(CmfMessagesMonitor.java:56)
        at sun.reflect.GeneratedMethodAccessor625.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:270)
        at com.onmobile.cmfshare.MethodInvockingBean.invoke(MethodInvockingBean.java:28)
        at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:212)
        at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:79)
        at org.quartz.core.JobRunShell.run(JobRunShell.java:203)
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520)
Caused by: java.sql.SQLNonTransientConnectionException: Could not connect to localhost:3306: unexpected end of stream, read 0bytes from 4
        at org.mariadb.jdbc.internal.SQLExceptionMapper.get(SQLExceptionMapper.java:136)
        at org.mariadb.jdbc.internal.SQLExceptionMapper.throwException(SQLExceptionMapper.java:106)
        at org.mariadb.jdbc.Driver.connect(Driver.java:114)
        at org.apache.commons.dbcp.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:37)
        at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:290)
        at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:840)
        at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:95)
        at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:544)
        at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81)
        at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:423)
        ... 21 more
Caused by: org.mariadb.jdbc.internal.common.QueryException: Could not connect to localhost:3306: unexpected end of stream, read 0bytes from 4
        at org.mariadb.jdbc.internal.mysql.MySQLProtocol.connect(MySQLProtocol.java:509)
        at org.mariadb.jdbc.internal.mysql.MySQLProtocol.connect(MySQLProtocol.java:669)
        at org.mariadb.jdbc.internal.mysql.MySQLProtocol.<init>(MySQLProtocol.java:264)
        at org.mariadb.jdbc.Driver.connect(Driver.java:110)
        ... 28 more
Caused by: java.io.EOFException: unexpected end of stream, read 0bytes from 4
        at org.mariadb.jdbc.internal.common.packet.buffer.ReadUtil.readFully(ReadUtil.java:84)
        at org.mariadb.jdbc.internal.common.packet.buffer.ReadUtil.readFully(ReadUtil.java:92)
        at org.mariadb.jdbc.internal.common.packet.RawPacket.nextPacket(RawPacket.java:77)
        at org.mariadb.jdbc.internal.common.packet.SyncPacketFetcher.getRawPacket(SyncPacketFetcher.java:67)
        at org.mariadb.jdbc.internal.mysql.MySQLProtocol.connect(MySQLProtocol.java:467)
        ... 31 more

如果再次使用MySql服务器,异常将消失

从我目前调试的情况来看,由于某种原因,MariaDB服务器正在关闭客户端连接。我最初怀疑存在空闲连接,但我们使用的是Hibernate配置,如“testOnBorrow”,因此情况不应该如此

有人能帮我们找出原因并解决问题吗?MariaDB中是否有我应该执行的特定配置

我甚至通过增加MariaDB服务器中参数“interactive_timeout”的值来运行我们的应用程序,但这没有帮助

顺便说一句,我们正在使用SpringHibernate,并使用CommonsPoolJar将连接池化

任何形式的帮助都将不胜感激


共 (6) 个答案

  1. # 1 楼答案

    根据本article中的研究结果,你可以选择两种方式:

    1. 你应该试着关掉innodb_file_per_table

      或者

    2. 增加打开文件的限制,这将告诉您在高规格机器上运行的计算机$ ulimit -n上的当前值

  2. # 2 楼答案

    你可以尝试增加“等待超时”而不是“交互超时”。8-12小时,直到错误与等待超时的默认值(10小时)非常相关。JDBC驱动程序在连接时没有设置交互客户端标志,所以更改为“interactive_timeout”可能没有效果。我还回复了Maria KB中的交叉帖子;)

  3. # 3 楼答案

    我也面临着这个问题。这个问题随着等待超时时间的降低而消失

    SHOW SESSION VARIABLES LIKE 'wait_timeout'; ->> would be 8 hours. which is huge.
    SET session wait_timeout=300; ->> this should fix the issue.
    
  4. # 4 楼答案

    由于参数组合不正确,我们最近遇到了同样的问题。 此错误是由于您的web实例试图使用不再有效的连接造成的

    这可以通过确保以下参数正确来解决:

    1. 您已经为数据库连接配置了validationQuery。i、 e.validationQuery="SELECT 1"如果是mariadb,则在服务器配置中
    2. 您已将等待超时设置为合理的值。8小时keepAlive似乎有点乐观,我们现在使用wait_timeout=180
    3. 确保validationInterval的值低于wait_timeout值,validationInterval也可以在服务器配置中设置(如果是tomcat设置,则为server.xml)。在一种情况下,我将等待超时时间减少到15秒,validationInterval值高于这个值,这导致错误有时仍然出现。 现在,它被设置为validationInterval=60,与wait_timeout=180相结合,它应该及时捕获任何断开的连接
  5. # 5 楼答案

    SHOW VARIABLES LIKE 'max_connections';
    SHOW GLOBAL STATUS LIKE '%connect%';
    

    比较一下我的。两个系统之间的cnf值;你可能会看到上面这些事情的不同之处。如果问题仍然不明显,请提供这些值以供进一步讨论

  6. # 6 楼答案

    我也犯过这样的错误Could not connect to localhost:3306: unexpected end of stream, read 0 bytes from 4

    我的架构是Tomcat的一个Web应用程序,它将数据插入MariaDB

    我正在使用连接器版本1.5.1RC! 我切换到1.3.1连接器版本,现在运行良好