我正在尝试设置一个statement_timeout。我试过像这样在database.yml
文件中进行设置
variables:
statement_timeout: 1000
还有这个
ActiveRecord::Base.connection.execute("SET statement_timeout = 1000")
经过测试
ActiveRecord::Base.connection.execute("select pg_sleep(4)")
它们都没有任何作用。
我正在本地运行postgres 10,并且statement_timeouts可以正常工作。但是在运行Postgres 9.4.4的服务器上,它什么也没做。
我已检查Postgres' doc for 9.4,并且statement_timeout可用。任何人都可以露面吗?
答案 0 :(得分:1)
我无法使用:Postgresql 9.4.26在本地复制此问题。但是分享我的尝试和有关服务器问题的一些想法可能会很有用。 这是我尝试过的方法(有用的一点可能是从rails验证PG版本的查询):
# Confirming I am executing against 9.4.x PG:
irb(main):002:0> ActiveRecord::Base.connection.execute("select version()")
(10.8ms) select version()
=> #<PG::Result:0x00007ff74782e060 status=PGRES_TUPLES_OK ntuples=1 nfields=1 cmd_tuples=1>
irb(main):003:0> _.first
=> {"version"=>"PostgreSQL 9.4.26 on x86_64-apple-darwin18.7.0, compiled by Apple clang version 11.0.0 (clang-1100.0.33.17), 64-bit"}
# Set timeout:
irb(main):004:0> ActiveRecord::Base.connection.execute("SET statement_timeout = 1000")
(0.4ms) SET statement_timeout = 1000
=> #<PG::Result:0x00007ff7720a3d88 status=PGRES_COMMAND_OK ntuples=0 nfields=0 cmd_tuples=0>
# Confirm it works - it is ~1s and also stacktrace is pretty explicit about it:
irb(main):005:0> ActiveRecord::Base.connection.execute("select pg_sleep(4)")
(1071.2ms) select pg_sleep(4)
.... (stacktrace hidden)
ActiveRecord::StatementInvalid (PG::QueryCanceled: ERROR: canceling statement due to statement timeout)
: select pg_sleep(4)
这是尝试的方法
由于此问题仅在服务器上发生,并且由于statement_timeout
在其他次要版本和本地上均可使用,因此想到的一件事是缺少从尝试更新statement_timeout
的特权。也许用于建立数据库连接的Rails pg登录名不允许更新该设置。
最好的办法是通过服务器上的Rails控制台来验证:
irb(main):004:0> ActiveRecord::Base.connection.execute("SET statement_timeout = 1000")
irb(main):004:0> irb(main):003:0> ActiveRecord::Base.connection.execute("show statement_timeout").first
(0.2ms) show statement_timeout
=> {"statement_timeout"=>"1s"}
或者,可以直接通过psql控制台对其进行检查(某些部署也允许这样做):
psql myserveruser # if this was heroku's pg: heroku pg:psql
postgres=# set statement_timeout = 1000;
SET
postgres=# select pg_sleep(4);
ERROR: canceling statement due to statement timeout
Time: 1068.067 ms (00:01.068)
其他要记住的事情(摘自https://dba.stackexchange.com/a/83035/90903):
statement_timeout的工作方式,时间从 服务器从客户端接收到新命令...
如果一个函数执行SET statement_timeout = 100;它只会在 来自客户端的下一个命令。