强制停止运行ActiveRecord,避免mysql max_execution_time

Posted

技术标签:

【中文标题】强制停止运行ActiveRecord,避免mysql max_execution_time【英文标题】:Force stop running ActiveRecord, avoid mysql max_execution_time 【发布时间】:2021-09-25 10:42:57 【问题描述】:

我们的应用具有以下规格:Ruby 2.6.5、Rails 4.2.11、mysql 5.7.33(max_execution_time = 1200000,20 分钟)

对于庞大的数据,例如公司数据,有时我们查询时会花费很长时间。所以我决定用Timeout::timeout强制停止查询,但是好像不行。

这是示例代码

begin
  max_time = 600 # 10minutes

  Timeout::timeout(max_time) do
    company = Company.where(location: 'West').last
  end
rescue => e
  company = nil
end

预期如果查询仍在处理,它应该在 10 分钟内停止。但它会在 20 分钟后停止,这是 MySQL 的最大超时。

我已经检查过了,它可以在 5 秒内停止

Timeout::timeout(5)  sleep(10) 

但是有了这个,它仍然会在 10 秒内停止

Timeout::timeout(5)  Company.select('SLEEP(10)').limit(1) 

是否可以使用 rails 停止查询?

【问题讨论】:

【参考方案1】:

我已经解决了这个问题,

begin
  query = <<-SQL
    SELECT /*+ MAX_EXECUTION_TIME(600000) */ id, location
    FROM companies
    WHERE location = 'West'
    ORDER BY id DESC LIMIT 1;
  SQL

  result = Company.find_by_sql(query)
  company = result.last
rescue => e
  company = nil
end

也许还有另一种方法。

【讨论】:

以上是关于强制停止运行ActiveRecord,避免mysql max_execution_time的主要内容,如果未能解决你的问题,请参考以下文章

停止 Activerecord 加载 Blob 列

有啥办法可以避免过多的 ActiveRecord 调用?

Python 强制停止多线程运行

将未维护的 ActiveRecord 适配器强制转换为 Rails 版本 6

Learn Rails5.2- ActiveRecord: Migration , spring的使用(不兼容的解决办法)

当应用程序处于“强制停止”状态时,如何允许定期 SyncAdapter 运行