Não sei o que é melhor:responder minha pergunta ou atualizá-la... então escolho responder. Por favor, deixe-me saber se é melhor atualizar
Finalmente descobrimos o problema. Desde a versão 3.1, Rails adicionou instruções preparadas em simples requisições como User.find(id). Versão 4.0, adicionou instruções preparadas para solicitações em associações (has_many, belongs_to, has_one). Por exemplo, o código a seguir:
class User
has_many :adresses
end
user.addresses
gerar solicitação
SELECT "addresses".* FROM "addresses" WHERE "addresses"."user_id" = $1 [["user_id", 1]]
O problema é que o Rails só adiciona variáveis de instrução preparadas para chaves estrangeiras (aqui user_id). Se você usar uma solicitação sql personalizada como
user.addresses.where("moved_at < ?", Time.now - 3.month)
ele não adicionará uma variável às instruções preparadas para move_at. Portanto, ele gera instruções preparadas toda vez que a solicitação é chamada. Rails lida com instruções preparadas com um pool de tamanho máximo de 1000.
No entanto, as instruções preparadas do postgresql não são compartilhadas na conexão, portanto, em uma ou duas horas, cada conexão tem 1.000 instruções preparadas. Alguns deles são muito grandes. Isso leva a um consumo de memória muito alto no servidor postgreqsl.