2011-12-22 77 views
6

我遇到麻烦了升级我的rails 2.3.14 /红宝石1.8.7应用3.1.1/1.9.2:我有一些的Rails 3.1/mysql2错误: “MySQL服务器消失”

(ActiveRecord::StatementInvalid) "Mysql2::Error: MySQL server has gone away" 

偶尔出现错误。准确的说,我从来没有在2.3.14上使用'mysql'gem和完全相同的数据库(所以这个错误不应该来自mysql(v5.5.10))。

例子:

$ rails c production 
Loading production environment (Rails 3.1.1) 
ruby-1.9.2-p290 :001 > ActiveRecord::Base.connection.active? 
=> false 
ruby-1.9.2-p290 :002 > exit 
$ rails c production 
Loading production environment (Rails 3.1.1) 
ruby-1.9.2-p290 :001 > ActiveRecord::Base.connection.active? 
=> true 

这只发生在我的(远程)生产数据库,与我的地方发展数据库没有问题。我试图设置“重新连接:真正的”在我的database.yml,但它导致了

Mysql2::Error: Host '****' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts':... 

我试图用一个小RB脚本只加载mysql2和ActiveRecord的隔离问题,但我没有”设法重现这种方式的bug(所以它可能被链接到铁轨堆栈)。

由于编码问题(http://www.rorra.com.ar/2010/07/30/rails-3-mysql-and-utf-8/),我无法从'mysql2'回到'mysql'宝石。因此,我不得不将我的产品回滚到我的rails 2.3.14应用程序,这让我非常伤心...

你看到我能做些什么来调试吗?我什至不能找到一个可靠的方法来重现错误...有没有人遇到同样的错误?

我刚刚发现几个人提到这个bug(例如:https://github.com/brianmario/mysql2/issues/213),但没有解决方案。

感谢您的帮助。

回答

11

好吧,我想我解决我的问题。当我发布我的问题时,我没有注意到它,但似乎错误与超时有关:大约20秒后,activerecord失去了连接。

$ rails runner "sleep 23; puts ActiveRecord::Base.connection.active?" 
=> true 
$ rails runner "sleep 25; puts ActiveRecord::Base.connection.active?" 
=> false 

所以我挖进一步,我意识到,MySQL和mysql2宝石没有处理好与MySQL“WAIT_TIMEOUT”帕拉姆以同样的方式:mysql的宝石不设置这样它采用了MySQL default value 28800,而mysql2 gem sets it at 2592000如果不是在database.yml中定义。 但我的印象是2592000的值超过了这个参数的最大值:2147483!这可能会导致我所描述的意外行为...

我打造出了错误的脚本测试:https://gist.github.com/1514154

如果我有一些明显的随机断开而装载轨控制台(CF我的问题),我想这是因为我的应用程序花费很长的时间来加载和我有时会等几秒钟才能输入我的命令。

我无法解释为什么我们很少遇到这个问题。也许它是特定于我的conf(远程数据库,MySQL版本?)。我试着用另一个远程临时数据库:错误没有重现...

因此,作为结论,我将在我的database.yml中设置wait_timeout: 2147483。也许拉请求轨...

+0

谢谢,这似乎解决了我的随机'走''错误。 – Delameko 2012-01-17 09:27:42

+0

2147483限制是针对窗口的,对吧?它在“Type(windows)”块中。对于其他平台,限制为31536000. http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_wait_timeout – kenn 2012-05-20 19:51:55

+0

使用'mysql2 0.3.16'和'activerecord 4.0进行测试。 0/4.1.4'在Windows 7中 - 'wait_timeout'正在工作,但在真正的导轨中,我遇到连接丢失甚至内存不足的情况。 – Paul 2014-10-20 16:35:02

2

有很多失去了联系 - 但如果他们走了我不能说由于以下的调整或elsewise:/

不得不把下面的脚本到初始化并添加一行配置在我database.yml中我的每个数据库是这样的:

... 
flags: <%= 65536 | 131072 %> 
... 

脚本是这样的:

/config/initializers/mysql2.rb

module ActiveRecord 
    class Base 
    # Overriding ActiveRecord::Base.mysql2_connection 
    # method to allow passing options from database.yml 
    # 
    # Example of database.yml 
    # 
    # login: &login 
    #  socket: /tmp/mysql.sock 
    #  adapter: mysql2 
    #  host: localhost 
    #  encoding: utf8 
    #  flags: 131072 
    # 
    # @param [Hash] config hash that you define in your 
    # database.yml 
    # @return [Mysql2Adapter] new MySQL adapter object 
    # 
    def self.mysql2_connection(config) 
     config[:username] = 'root' if config[:username].nil? 

     if Mysql2::Client.const_defined? :FOUND_ROWS 
     config[:flags] = config[:flags] ? config[:flags] | Mysql2::Client::FOUND_ROWS : Mysql2::Client::FOUND_ROWS 
     end 

     client = Mysql2::Client.new(config.symbolize_keys) 
     options = [config[:host], config[:username], config[:password], config[:database], config[:port], config[:socket], 0] 
     ConnectionAdapters::Mysql2Adapter.new(client, logger, options, config) 
    end 
    end 
end 
+1

感谢您的回答,但我不认为我们的2个问题是相关的:你可能有多个报表/多结果查询在你的应用程序?由于您添加的标志对应于CLIENT_MULTI_RESULTS和CLIENT_MULTI_STATEMENTS,是不是?顺便说一句,使用Mysql2 :: Client :: MULTI_STATEMENTS和Mysql2 :: Client :: PS_MULTI_RESULTS(而不是原始整数)应该可以工作。 – Flackou 2011-12-23 17:41:34