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查询)。
答
我的嫌疑人是正确的。
问题是由日志消息太长时的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]
你为什么涉及的Rails在这呢?一个简单的'insert into ... select ...'SQL位将是一个更好的起点,不是吗? –