11 votes

Les balises HTML doivent être conservées dans la traduction. Rails 4.2 Postgres 9.4.4 statement_timeout ne fonctionne pas

Je suis en train d'essayer de définir un statement_timeout. J'ai essayé de le définir dans le fichier database.yml comme ceci

variables:
  statement_timeout: 1000

Et ceci

ActiveRecord::Base.connection.execute("SET statement_timeout = 1000")

Testé avec

ActiveRecord::Base.connection.execute("select pg_sleep(4)")

Et les deux n'ont aucun effet.

Je suis en train d'exécuter postgres 10 en local et les statement_timeouts fonctionnent comme prévu. Mais sur mon serveur qui exécute postgres 9.4.4, cela ne fait tout simplement rien.

J'ai vérifié la documentation de Postgres pour 9.4 et statement_timeout est disponible. Quelqu'un pourrait-il éclairer ma lanterne?

1voto

draganstankovic Points 1948

Je n'ai pas pu reproduire ce problème localement en utilisant : Postgresql 9.4.26. Mais il pourrait être utile de partager ce que j'ai essayé et quelques réflexions autour du problème du serveur. Voici ce que j'ai essayé (une partie utile pourrait être une requête pour vérifier la version PG depuis Rails) :

# Confirmation que j'utilise PG 9.4.x :

irb(main):002:0> ActiveRecord::Base.connection.execute("select version()")
   (10.8ms)  select version()
=> #
irb(main):003:0> _.first
=> {"version"=>"PostgreSQL 9.4.26 on x86_64-apple-darwin18.7.0, compilé par Apple clang version 11.0.0 (clang-1100.0.33.17), 64-bit"}

# Définir un délai d'attente :

irb(main):004:0> ActiveRecord::Base.connection.execute("SET statement_timeout = 1000")
   (0.4ms)  SET statement_timeout = 1000
=> #

# Confirmer que cela fonctionne - c'est ~1s et la stacktrace est assez explicite à ce sujet :

irb(main):005:0> ActiveRecord::Base.connection.execute("select pg_sleep(4)")
   (1071.2ms)  select pg_sleep(4)
.... (stacktrace cachée)
ActiveRecord::StatementInvalid (PG::QueryCanceled: ERROR:  cancelation de la requête en raison d'un dépassement du délai d'attente de la requête)
: select pg_sleep(4)

Voici ce qu'il faut essayer

Comme le problème survient uniquement sur le serveur et que statement_timeout fonctionne sur d'autres versions mineures et localement, une chose qui vient à l'esprit est le manque de privilèges pour mettre à jour statement_timeout à partir de l'endroit où cela est tenté. Peut-être que le login pg de rails utilisé pour établir la connexion à la base de données n'est pas autorisé à mettre à jour ce paramètre. Le mieux serait de vérifier cela soit via la console rails sur un serveur :

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"}

Ou, cela peut être vérifié directement via la console psql (certaines installations le permettent aussi) :

psql myserveruser # si c'était le pg d'heroku : heroku pg:psql

postgres=# set statement_timeout = 1000;
SET
postgres=# select pg_sleep(4);
ERROR:  cancelation de la requête en raison d'un dépassement du délai d'attente de la requête
Time: 1068.067 ms (00:01.068)

Autre chose à garder à l'esprit (extrait de https://dba.stackexchange.com/a/83035/90903) :

La façon dont statement_timeout fonctionne, le temps commence à être compté lorsque le serveur reçoit une nouvelle commande du client...

Et si une fonction fait SET statement_timeout = 100; cela n'aura d'effet qu'à partir de la prochaine commande du client.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X