mysql_retry_lost_connection 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/README +63 -0
  2. data/lib/mysql_retry_lost_connection.rb +23 -0
  3. metadata +47 -0
data/README ADDED
@@ -0,0 +1,63 @@
1
+ Has your Rails app ever thrown the 'Lost Connection to MySQL
2
+ server' exception? I love that error. How about 'MySQL server has gone
3
+ away?' That.s a good one too. If you're a fan of these exceptions then
4
+ stop reading now because I'm about to make them go away.
5
+
6
+ Rails is set up to handle database connections in such a way that the
7
+ likelihood of hitting these errors increases with the size of your
8
+ code base. ActiveRecord maintains one database connection per model. If
9
+ you use that database command often enough then it times out resulting
10
+ in the errors listed above. You can set the timeout interval in your
11
+ environment.rb with this:
12
+
13
+ ActiveRecord::Base.verification_timeout = 14400
14
+
15
+ If your app only has a handful of models and you hit actions that
16
+ trigger activity on each model.s connection frequently enough then
17
+ bumping up the interval in the above config might just be a good enough
18
+ solution for you. But when you keep adding models to your app to keep
19
+ up with feature requests then you.ll eventually have a user execute a
20
+ code path on a process whose database connection has timed out. We have
21
+ 123 models at Zvents and counting. We got to the point where Increasing
22
+ the verification_timeout wasn't really helping - we still hit a handful
23
+ of connections timeouts on models that didn't receive a lot of usage
24
+ (backend stuff mostly).
25
+
26
+ The solution, quite simply, is to have the database adapter reconnect
27
+ to the database when it detects a lost connection. It's not an original
28
+ or groundbreaking idea, but I couldn.t any plugins so I threw together
29
+ the mysql_retry_lost_connection plugin. It looks like this:
30
+
31
+ module ActiveRecord
32
+ module ConnectionAdapters
33
+ class MysqlAdapter
34
+ def execute(sql, name = nil) #:nodoc:
35
+ reconnect_lost_connections = true
36
+ begin
37
+ log(sql, name) { @connection.query(sql) }
38
+ rescue ActiveRecord::StatementInvalid => exception
39
+ RAILS_DEFAULT_LOGGER.info("ActiveRecord::StatementInvalid Error: #{exception.message}\n#{exception.backtrace.join("\n")}")
40
+ if reconnect_lost_connections and exception.message =~ /(Lost connection to MySQL server during query|MySQL server has gone away)/
41
+ reconnect_lost_connections = false
42
+ reconnect!
43
+ retry
44
+ elsif exception.message.split(":").first =~ /Packets out of order/
45
+ raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql bindings."
46
+ else
47
+ raise
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ We've been running it in production for a couple weeks with no side
56
+ effects - and lost connections are just a happy memory now.
57
+
58
+ I'm not entirely happy with the code. Instead of clobbering the existing
59
+ execute method it should probably use alias_method to wrap the existing
60
+ method. That would make it more resilient to changes to the underlying
61
+ code in future Rails releases. But it works for me and I'm hitting
62
+ the sack. Free beer to the first person who rewrites it that manner or
63
+ improves it any other way.
@@ -0,0 +1,23 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ class MysqlAdapter
4
+ def execute(sql, name = nil) #:nodoc:
5
+ reconnect_lost_connections = true
6
+ begin
7
+ log(sql, name) { @connection.query(sql) }
8
+ rescue ActiveRecord::StatementInvalid => exception
9
+ RAILS_DEFAULT_LOGGER.info("ActiveRecord::StatementInvalid Error: #{exception.message}\n#{exception.backtrace.join("\n")}")
10
+ if reconnect_lost_connections and exception.message =~ /(Lost connection to MySQL server during query|MySQL server has gone away)/
11
+ reconnect_lost_connections = false
12
+ reconnect!
13
+ retry
14
+ elsif exception.message.split(":").first =~ /Packets out of order/
15
+ raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql bindings."
16
+ else
17
+ raise
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: mysql_retry_lost_connection
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2007-07-01 00:00:00 -07:00
8
+ summary: Reconnect to the MySQL server when you hit a lost connection error
9
+ require_paths:
10
+ - lib
11
+ email: tyler.kovacs@zvents.com
12
+ homepage: http://www.sparecycles.org/2007/7/2/saying-goodbye-to-lost-connections-in-rails
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: mysql_retry_lost_connection
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Tyler Kovacs
31
+ files:
32
+ - lib/mysql_retry_lost_connection.rb
33
+ - README
34
+ test_files: []
35
+
36
+ rdoc_options: []
37
+
38
+ extra_rdoc_files:
39
+ - README
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ requirements: []
45
+
46
+ dependencies: []
47
+