Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails 3.2频繁postgres准备语句已存在错误_Ruby On Rails_Postgresql_Heroku_Ruby On Rails 3.2_Prepared Statement - Fatal编程技术网

Ruby on rails Rails 3.2频繁postgres准备语句已存在错误

Ruby on rails Rails 3.2频繁postgres准备语句已存在错误,ruby-on-rails,postgresql,heroku,ruby-on-rails-3.2,prepared-statement,Ruby On Rails,Postgresql,Heroku,Ruby On Rails 3.2,Prepared Statement,我一直在stackoverflow周围挖掘,试图找到其他获得这些准备好的语句的人已经存在错误 在大多数情况下,使用after/befork正确配置unicorn可以解决这些问题 然而,在我的案例中,我们仍然会遇到这样的错误: ActiveRecord::StatementInvalid: PG::Error: ERROR: prepared statement "a495" already exists: INSERT INTO "user_logins" ("account_id", "cre

我一直在stackoverflow周围挖掘,试图找到其他获得这些准备好的语句的人已经存在错误

在大多数情况下,使用after/befork正确配置unicorn可以解决这些问题

然而,在我的案例中,我们仍然会遇到这样的错误:

ActiveRecord::StatementInvalid: PG::Error: ERROR: prepared statement "a495" already exists: INSERT INTO "user_logins" ("account_id", "created_at", "ip_address", "user_agent", "user_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id"
这个错误会在我们的应用程序的不同区域抛出,但似乎总是有相同的语句编号“a495”

我们在rails 3.2.17上,使用postgres,我们在heroku上

我真的不知道为什么会发生这种情况,但现在这种情况开始越来越频繁了

任何帮助都将不胜感激

在rails堆栈跟踪中,此错误将在.prepare调用中抛出。我很困惑,因为它在语句集合中检查sql键。如果它不存在,它会准备新的一个…但是当试图准备它时,它会抛出错误

def prepare_statement(sql)
  sql_key = sql_key(sql)
  unless @statements.key? sql_key
    nextkey = @statements.next_key
    @connection.prepare nextkey, sql
    @statements[sql_key] = nextkey
  end
  @statements[sql_key]
end

这通常不是Postgres的问题,而是在Unicorn中共享数据库连接的问题:


    • 我们也遇到了同样的问题,并进行了非常彻底的调查。我们得出结论,在我们的例子中,这个错误是由
      Rack::Timeout
      引起的,在创建新语句之后,但在Rails端更新计数器之前,偶尔会中断代码执行。然后,下一个准备好的语句尝试使用相同的名称(例如,
      a494
      ),并发生冲突

      我认为Rails没有正确地实现预先准备好的语句。他们不应该使用递增计数器(
      a001
      a002
      ,…),而应该使用guid。这样,上述比赛条件就不会成为问题


      我们没有找到解决办法。提高应用程序的性能,并增加
      Rack::Timeout
      的窗口,使这个问题几乎消失,但它仍然时常发生

      这是我对Heroku的解决方案,不幸的是,它有点牵扯其中。不过,从好的方面来看,当这个错误开始发生时,您不需要遭受100次错误通知。所需要的只是重新启动应用程序/dyno

      该过程的基本要点是,当我们检测到一个
      ActiveRecord::StatementInvalid
      异常,并且错误消息描述中包含“prepared statement”字样时,我们使用heroku的
      平台api
      gem运行
      heroku restart
      命令

    • platformapi
      gem放入gem文件中,然后运行
      bundle安装
    • 将HEROKU_API_键设置为正确的值。(您可以从Heroku仪表板生成密钥)。使用heroku config:set heroku\u API\u KEY=无论值是什么
    • 将HEROKU_APP_名称设置为正确的值。您可以从heroku CLI获取此信息,但它只是您所称的应用程序
    • 将以下内容添加到您的
      应用程序控制器
      (/app/controllers/application\u controller.rb):
    • class ApplicationController

      就这样。希望这能有所帮助。

      在非Heroku PostgreSQL上,我会设置一个标识pid和会话的
      log\u line\u前缀,启用
      log\u statement=all
      ,并查看日志。在Heroku,我不知道这是否可行。我们按照Heroku的建议配置了独角兽,所以我不确定从这个角度出发我们还能做些什么;这里有一个初始值设定项可以做到这一点:还要注意Rails 4.1在database.ml上有这样的设置:
      prepared_statements:false
      根据@CharlesForcey关闭prepared statements实际上可以防止这个错误吗?这很有意义——我们也会遇到同样的问题(Rails 4/Heroku/Puma),我将寻找与超时的关联。谢谢。你用Rails开过票吗?它修好了吗?票:在经过几年可靠的服务后,这对我来说已经不起作用了
      class ApplicationController < ActionController::Base
      
      rescue_from ActiveRecord::StatementInvalid do |exception|
        # notify your error handler, or send an email, or whatever
        # ...
        if exception.message =~ /prepared statement/
          restart_dyno
        end
      end
      
      def restart_dyno
       heroku = PlatformAPI.connect_oauth(ENV["HEROKU_API_KEY"])
       heroku.dyno.restart(ENV["HEROKU_APP_NAME"], "web")
      end
      
      end