Миграция с MySql: сервер MariaDB закрывает клиентские подключения неожиданно

Мы в процессе перехода с MySql на MariaDB из-за причин лицензирования/коммерческого использования.

Мы успешно заменили банку соединителя MySql на банку клиента MariaDB (первое изменение) и теперь пытаемся заменить сервер MySql сервером MariaDB без изменения файлов данных.

Все наши приложения работают отлично в течение 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, которую я должен делать?

Я даже запускаю наши приложения, увеличивая значение параметра "interactive_timeout" на сервере MariaDB, но это не помогло.

Btw, мы используем Spring -Hibernate и объединяем наши соединения с помощью Commons-pool jar.

Любая помощь будет глубоко оценена.

Ответы

Ответ 1

В последнее время мы столкнулись с той же проблемой из-за комбинации неправильных параметров. Эта ошибка вызвана тем, что ваш веб-экземпляр пытается использовать соединение, которое больше не является допустимым.

Это можно решить, убедившись, что следующие параметры верны:

  • У вас есть validationQuery, настроенный для подключения к базе данных. т.е. validationQuery="SELECT 1" в случае mariadb, в конфигурации сервера.
  • У вас есть wait_timeout, установленное на разумное значение. 8 часов keepAlive выглядит немного оптимистично, теперь мы используем wait_timeout=180
  • Убедитесь, что validationInterval, который вы также можете установить в конфигурации сервера (server.xml в случае установки tomcat), имеет значение, меньшее значения wait_timeout. Я уменьшил wait_timeout до 15 секунд в одном случае, причем значение validationInterval было выше, что заставило ошибку по-прежнему появляться время от времени. Теперь он установлен в validationInterval=60, в сочетании с wait_timeout=180, который должен ловить любые сломанные соединения во времени.

Ответ 2

Вы можете попытаться увеличить 'wait_timeout' вместо 'interactive_timeout'. 8-12 часов, пока ошибка не коррелирует с нормальным значением wait_timeout, которое составляет 10 часов. Драйвер JDBC не устанавливает флаг интерактивного клиента при подключении, поэтому изменение на "interactive_timeout" может не повлиять. Я также ответил на перекресток в Maria KB;)

Ответ 3

Посмотрите

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

Сравните значения my.cnf между двумя системами; вы можете увидеть разницу в таких вещах, как выше, что имеет значение. Если проблема все еще не очевидна, предоставьте эти значения для дальнейшего обсуждения.

Ответ 4

В соответствии с результатами этой статьи вы можете уйти с двумя вариантами:

  • Вам следует попробовать отключить innodb_file_per_table

    или...

  • Увеличение пределов открытых файлов, это говорит вам текущее значение на вашей машине $ ulimit -n, если вы работаете на высокопроизводительных машинах

Ответ 5

Я думаю, что проблема связана с коннектором MariaDB/J. Попробуйте использовать стабильный, например, MariaDB Connector/J 1.2.3. Кроме того, изучите "Отказоустойчивость" с базовым отказоустойчивостью, если для параметра autoReconnect установлено значение true или Standard failover.

Ответ 6

У меня также была ошибка, подобная этой Could not connect to localhost:3306: unexpected end of stream, read 0 bytes from 4

Моя архитектура была webapp Tomcat, которая вставляла данные в MariaDB.

Я использовал коннектор версии 1.5.1RC! Я переключился на версию версии 1.3.1 и теперь работает нормально!