我希望使用ActiveRecord::Base.connection.execute(sql)
在Rails中执行一个非常长的查询。
但是,这个查询一直超时。是否可以更改此特定查询的超时值,而不必更改database.yml
中所有查询的超时值?
谢谢
我希望使用ActiveRecord::Base.connection.execute(sql)
在Rails中执行一个非常长的查询。
但是,这个查询一直超时。是否可以更改此特定查询的超时值,而不必更改database.yml
中所有查询的超时值?
谢谢
我们必须小心处理超时变量,它们大多与连接超时有关,而不是查询超时本身。
似乎直到MySQL 5.7.4版本之前,唯一终止长时间查询的方法是通过mysql命令kill
,但我不确定您是否也会失去客户端/服务器连接,所以您的Rails进程可能会变得无法使用。
在MySQL 5.7.4中出现了系统变量max_statement_time,它允许精确配置服务器以符合原始问题所询问的 "SELECT语句的执行超时时间"。
要通过Rails设置此系统变量,可以使用选项variables在database.yml
中。
development:
adapter: mysql2
[...]
variables:
max_statement_time: 60000 # 1 minute
要检查变量是否已在您的ActiveRecord连接中正确设置,您可以在Rails控制台中运行以下内容:
ActiveRecord::Base.connection.execute('show variables like "%max_execution_time%"').to_a
PS:MySQL 5.7.8中系统变量更名为max_execution_time。
PS2:我无法访问MySQL >= 5.7.4,无法测试这些结论,如果有人可以确认一下,我将不胜感激。
# in database.yml
production: &prod
adapter: whatever
timeout: 5000
long_connection_production:
<<: prod
timeout: 10000
# app/models/long_connection.rb
class LongConnection < ActiveRecord::Base
establish_connection "long_connection_#{Rails.env}"
def self.do_thing_that_takes_a_long_time
connection.execute(sql)
end
end
timeout
变量的引用。此外,这里并不清楚您正在定义连接超时还是查询执行超时。 - fguillenmysql2
gem连接时,timeout
对我不起作用。我已经设置了timeout: 1
,但是当我执行句子ActiveRecord::Base.connection.exec_query(SQL)
时,它需要超过2秒而没有任何超时错误。 - fguillenmysql
gem(也许还有 SQLserver),但是似乎在使用 mysql2
gem 时,您可能需要设置 wait_timeout
键而不是 timeout
。 - Unixmonkeywait_timeout
是用于 非交互式连接在关闭之前服务器等待活动的秒数。在 Rails + MySQL 中没有明确的方法来设置查询超时时间,或者至少我还没有找到。我认为我们需要注意这一点,并声明这个答案不正确,否则可能会带来很多麻烦...就像我现在遇到的一样 ;) - fguillen
Mysql2 :: Error:Unknown system variable 'max_statement_time'
。 - wscourge