Миграция с 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 и теперь работает нормально!