提问人:Gwyn Morfey 提问时间:9/19/2008 最后编辑:Peter MortensenGwyn Morfey 更新时间:5/18/2021 访问量:36232
Ruby on Rails 的“MySQL 服务器已经消失了”
"MySQL server has gone away" with Ruby on Rails
问:
在我们的 Ruby on Rails 应用程序运行了一段时间后,它开始抛出 500 秒,并显示“MySQL 服务器已经消失”。这通常发生在一夜之间。它最近开始这样做,我们的服务器配置没有明显变化。
Mysql::Error: MySQL server has gone away: SELECT * FROM `widgets`
重新启动(不是MySQL服务器)可以修复它。
我们该如何解决这个问题?
答:
与MySQL服务器的连接可能超时。
您应该能够增加 MySQL 中的超时时间,但要进行适当的修复,请让您的代码检查数据库连接是否仍处于活动状态,如果不是,请重新连接。
您是否监控打开的MySQL连接或线程的数量?max_connections的mysql.ini设置是什么?
mysql> show status;
查看连接、Max_used_connections、Threads_connected和Threads_created。
您可能需要增加 MySQL 配置中的限制,或者 rails 可能没有正确关闭连接*。
注意:我只短暂地使用过 Ruby on Rails......
服务器状态的MySQL文档 http://dev.mysql.com/doc/refman/5.0/en/server-status-variables.html。
这可能是由于与MySQL的持久连接消失(如果在夜间发生,则可能会超时),并且Ruby on Rails无法恢复连接,默认情况下应该这样做:
在文件 vendor/rails/actionpack/lib/action_controller/dispatcher.rb 中,代码如下:
if defined?(ActiveRecord)
before_dispatch { ActiveRecord::Base.verify_active_connections! }
to_prepare(:activerecord_instantiate_observers) {ActiveRecord::Base.instantiate_observers }
end
该方法执行多个操作,其中之一是重新创建任何过期的连接。verify_active_connections!
此错误的最可能原因是,这是因为猴子补丁将调度程序重新定义为不调用,或者已更改等。verify_active_connections!
verify_active_connections!
评论
ActiveRecord::StatementInvalid
ActiveRecord::Base.verify_active_connections!
ActiveRecord::StatementInvalid
application_controller.rb
正如该线程的其他贡献者所说,由于不活动,MySQL服务器很可能已经关闭了与Ruby on Rails应用程序的连接。默认超时为 28800 秒或 8 小时。
set-variable = wait_timeout=86400
将此行添加到 your 会将超时提高到 24 小时 http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#option_mysqld_wait_timeout。/etc/my.cnf
尽管文档没有指出这一点,但值为 0 可能会完全禁用超时,但您需要进行实验,因为这只是推测。
但是,据我所知,还有其他三种情况可以产生该错误。首先是正在重新启动的MySQL服务器。这显然会断开所有连接,但由于MySQL客户端是被动的,在进行下一个查询之前不会注意到这一点。
第二个条件是,如果有人从MySQL命令行终止了您的查询,这也会断开连接,因为它可能会使客户端处于未定义状态。
最后一种情况是,如果您的MySQL服务器由于致命的内部错误而重新启动。也就是说,如果你正在对一个表进行一个简单的查询,并立即看到“MySQL已经消失了”,我会仔细查看你的服务器日志,以检查硬件错误或数据库损坏。
评论
Ruby on Rails 2.3 有一个用于数据库连接的重新连接选项:
production:
# Your settings
reconnect: true
看:
祝你好运!
在 database.yml 中使用 reconnect: true 将导致在引发 ActiveRecord::StatementInvalid 错误后重新建立数据库连接(正如 Dave Cheney 所提到的)。
不幸的是,在数据库操作上添加重试似乎是必要的,以防止连接超时:
begin
do_some_active_record_operation
rescue ActiveRecord::StatementInvalid => e
Rails.logger.debug("Got statement invalid #{e.message} ... trying again")
# Second attempt, now that db connection is re-established
do_some_active_record_operation
end
我在使用 gem 的 Ruby on Rails 3 应用程序中遇到了这个问题。我复制了有问题的查询并尝试直接在MySQL中运行它,并得到了同样的错误,“MySQL服务器已经消失了。mysql2
有问题的查询非常非常大。一个非常大的插入 (+1 MB)。我尝试插入的字段是一个 TEXT 列,它们的最大大小为 64 KB。连接没有抛出错误,而是消失了。
我增加了字段的大小并得到了同样的东西,所以我仍然不确定确切的问题是什么。关键是,由于一些奇怪的查询,它在数据库中。无论如何!
评论
首先,确定MySQL中的max_connections:
show variables like "max_connections";
您需要确保在 Ruby on Rails 应用程序中建立的连接数小于允许的最大连接数。请注意,额外的连接可能来自您的 cron 作业、delayed_job进程(每个进程在您的 中都具有相同的池大小)等。database.yml
通过在MySQL中执行以下操作,在应用程序,运行进程等过程中监视SQL连接:
show status where variable_name = 'Threads_connected';
您可能需要考虑在完成执行后关闭连接,因为数据库连接不会自动关闭(我认为这对 Ruby on Rails 4 应用程序 Reaper 来说不是问题):Thread
Thread.new do
begin
# Thread work here
ensure
begin
if (ActiveRecord::Base.connection && ActiveRecord::Base.connection.active?)
ActiveRecord::Base.connection.close
end
rescue
end
end
end
尝试使用 Ruby on Rails 4。验证是否对服务器执行 ping 操作,如果未连接,则重新连接。ActiveRecord::Base.connection.verify!
其他要检查的是 Unicorn 配置是否正确。请参阅此处的 ActiveRecord 连接的before_fork和after_fork处理:https://gist.github.com/nebiros/2776085#file-unicorn-rb
在向MySQL发送非常大的语句时,我遇到了这个问题。MySQL限制了语句的大小,如果超过限制,将关闭连接。
set global max_allowed_packet = 1048576; # 2^20 bytes (1 MB) was enough in my case
评论
在 Rails 中分叉时。
对于在 Rails 中分叉时遇到此问题的任何人,请尝试在分叉之前清除现有连接,然后为每个分叉建立一个新连接,如下所示:
# Clear existing connections before forking to ensure they do not get inherited.
::ActiveRecord::Base.clear_all_connections!
fork do
# Establish a new connection for each fork.
::ActiveRecord::Base.establish_connection
# The rest of the code for each fork...
end
请在此处查看此 StackOverflow 答案:https://stackoverflow.com/a/8915353/293280
上一个:MySQL培训视频 [已结束]
下一个:返回表字段名的SQL命令是什么?
评论