Rails:SQL查询让生产服务器永远挂起

Rails:SQL查询让生产服务器永远挂起

问题描述:

我试图找出一个奇怪的错误的原因,这一整天。Rails:SQL查询让生产服务器永远挂起

我有一个模型,这行代码(由控制器操作调用):

# it always works 
self.deliveries.create(subscriptions.pluck('DISTINCT endpoint').collect {|e| {endpoint: e}}) 

一切正常(我的本地计算机上,在生产服务器上,甚至上千交付)。

为了提高性能我更换了原始的SQL上述行:

# it hangs forever on the production server if you have many deliveries 
inserts = subscriptions.pluck('DISTINCT endpoint').collect do |e| 
    "(#{self.id}, #{ActiveRecord::Base::sanitize(e)})" 
end 
ActiveRecord::Base.connection.execute("INSERT INTO deliveries (notification_id, endpoint) VALUES #{inserts.join(', ')}") 

此作品在我的本地机器上如预期甚至数千交付。然而,在我的生产服务器(2GB RAM/2核心)这第二个版本只适用于当我有几个记录插入,否则与2000交付或请求永远挂起

为了更精确:

  • 浏览器没有得到回应和HTTP请求挂起永远
  • 的交付在数据库
  • 以下行保存execute永远不会执行

如果我使用第三个版本的代码,并使用activerecord-import替换原始SQL,我会得到完全相同的错误。

什么可以导致此错误?

我甚至想知道它是否可以是崩溃应用程序(我使用logz.io)生成的长输出消息(大sql查询)。

+0

你为什么涉及的Rails在这呢?一个简单的'insert into ... select ...'SQL位将是一个更好的起点,不是吗? –

我的嫌疑人是正确的。

问题是由日志消息太长时的logstash-logger gem造成的。

从铁轨控制台,我可以重现这个问题,我得到了(用于一个查询):

LogStashLogger::Device::UDP - Errno::EMSGSIZE - Message too long 
LogStashLogger::Device::UDP - Errno::EMSGSIZE - Message too long 
LogStashLogger::Device::UDP - Errno::EMSGSIZE - Message too long 
LogStashLogger::Device::UDP - Errno::EMSGSIZE - Message too long 
... [and many many more]