I've got a problem with stale connections to MySQL server (it shuts down connections after 8 hours by default).
After the timeout happened the connection seems to be completely broken and no sort of reconnect happens:
2009-04-06 17:51:53.571:/:WARN: Exception caught
com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:
-
- BEGIN NESTED EXCEPTION **
java.io.EOFException
STACKTRACE:
java.io.EOFException
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1913)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2304)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2803)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1573)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1665)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3170)
at com.mysql.jdbc.Connection.setAutoCommit(Connection.java:5273)
at jdbc_adapter.RubyJdbcConnection.begin(RubyJdbcConnection.java:106)
at jdbc_adapter.RubyJdbcConnection$i_method_0_0$RUBYINVOKER$begin.call(jdbc_adapter/RubyJdbcConnection$i_method_0_0$RUBYINVOKER$begin.gen)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:70)
.....
Last packet sent to the server was 33 ms ago.
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2515)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2803)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1573)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1665)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3170)
at com.mysql.jdbc.Connection.setAutoCommit(Connection.java:5273)
at jdbc_adapter.RubyJdbcConnection.begin(RubyJdbcConnection.java:106)
at jdbc_adapter.RubyJdbcConnection$i_method_0_0$RUBYINVOKER$begin.call(jdbc_adapter/RubyJdbcConnection$i_method_0_0$RUBYINVOKER$begin.gen)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:70)
at org.jruby.ast.CallNoArgNode.interpret(CallNoArgNode.java:61)
....
This situation can be easily be repdoruced by restarting mysqld (sudo /etc/init.d/mysql restart on a typical Linux box).
I patched jdbc_adapter.RubyJdbcConnection#begin so it uses withConnectionAndRetry (like many other methods do). Now the sanity of the connection
is checked before the transaction starts and a reconnect happens in case. This patch seems to work but I've got the feeling like I'm cargo-culting a bit...
Christian
I've forked AR-JDBC on github (I wanted to play with github a bit), you can find the change there:
http://github.com/chrismuc/activerecord-jdbc-adapter/tree/master