我们在Heroku上的Rails应用程序上遇到了一个奇怪的问题。 Juste从Rails 3.2.17迁移到Rails 4.0.3后,我们的postgresql服务器显示内存使用量无限增加,然后在每次请求时返回以下错误:
ERROR: out of memory
DETAIL: Failed on request of size xxx
Juste在使用rails 4释放应用程序后,postgresql内存开始增加。
正如您在下面的屏幕截图中看到的,它在3小时内从500 MO增加到3,5 Go以上
同时,每秒提交加倍。它从每秒120次提交中传递出来:
每秒280次提交:
值得注意的是,当我们重新启动应用程序时,内存会下降到600 Mo的正常值,然后上升到3个以上后几个小时(然后每个sql请求显示内存不足&# 39;错误)。这就像杀死ActiveRecord连接在postgresql服务器上释放内存一样。
我们可能会在某处发生内存泄漏。 但是:
我们的筹码是:
我们的代码似乎没什么特别的。
我们的postgresql配置是:
有人在切换到Rails 4时遇到过这样的行为吗?我正在寻找重现的想法。
非常欢迎所有帮助。
提前致谢。
答案 0 :(得分:22)
我不知道什么是更好的:回答我的问题或更新它...所以我选择回答。如果最好更新
,请告知我们我们终于找到了问题所在。从版本3.1开始,Rails就像User.find(id)这样的简单请求添加了预准备语句。版本4.0,为关联请求添加了预准备语句(has_many,belongs_to,has_one)。 例如以下代码:
class User
has_many :adresses
end
user.addresses
生成请求
SELECT "addresses".* FROM "addresses" WHERE "addresses"."user_id" = $1 [["user_id", 1]]
问题是Rails只为外键添加准备好的语句变量(这里是user_id)。如果使用自定义sql请求,如
user.addresses.where("moved_at < ?", Time.now - 3.month)
它不会为moving_at的预处理语句添加变量。因此,每次调用请求时它都会生成一个准备好的语句。 Rails处理带有最大大小为1000的池的预准备语句。
但是,postgresql预处理语句不是跨连接共享的,因此在一两个小时内,每个连接都有1000个预准备语句。其中一些非常大。这导致postgreqsl服务器上的内存消耗非常高。