Vous n'êtes pas identifié(e).

#1 25/03/2014 17:14:35

kiki
Membre

impossible de tuer une requête

Bonjour.
Régulièrement, j'ai des requêtes que je suis dans l'impossibilité de tuer. elles consomment de la CPU, et peuvent durer jusqu'à plusieurs jours.
un kill -INT ou un kill -15 ou un pg_cancel_backend ou un pg_terminate_backend n'y font rien. Les seules solutions que j'ai pu trouver c'est soit un kill -9 en espèrant que postgres sorte du recovery mode ou un stop/start. A noter quand je fais un stop/start, posgres inscrit dans les logs la requête toute entière : ce qui me permet de la rejouer dans pg_admin ou psql sans problème dans la majorité des cas.
Mon environnement :
Postgres 9.1.4 RHEL 5 64 bits.

J'ai épluché les releases notes de la 9.1 sans trouver quelque chose (mais je suis peut-être passé à côté).
Voici un exemple de requête que j'ai dû arrêter par start/stop postgres (elle tournait depuis 2h48', alors que dans pgadmin elle met 4 secondes) :
Par ailleurs il semble que ce soit lié à l'opérateur IN (tout du moins à chaque fois que j'ai le problème, la requête utilise IN)

SELECT B.MBUL , B.MMODEL , B.PVER , B.DFIN , R.* FROM RBULLETIN B , RRUB R WHERE B.MBUL IN ( 'AVIS_25264_2012-07_4' , 'AVIS_25209_2013-01_2' , 'AVIS_21904_2012-08_1' , 'AVIS_26036_2013-03_6' , 'AVIS_25795_2012-08_13' , 'AVIS_24101_2012-09_2' , 'AVIS_26043_2012-11_1' , 'AVIS_26578_2012-07_17' , 'AVIS_26849_2013-01_2' , 'AVIS_26564_2012-07_3' , 'AVIS_24985_2013-05_5' , 'AVIS_24767_2012-10_2' , 'AVIS_26827_2012-10_8' , 'AVIS_25017_2012-06_1' , 'AVIS_25017_2012-07_1' , 'AVIS_25017_2012-08_1' , 'AVIS_25017_2012-09_1' , 'AVIS_25017_2012-10_1' , 'AVIS_25017_2012-11_1' , 'AVIS_25017_2012-12_1' , 'AVIS_25017_2013-01_1' , 'AVIS_25017_2013-02_1' , 'AVIS_25017_2013-03_1' , 'AVIS_25017_2013-04_1' , 'AVIS_25017_2013-05_1' , 'AVIS_25793_2012-09_3' , 'AVIS_26140_2012-10_3' , 'AVIS_25942_2012-10_1' , 'AVIS_21739_2012-08_1' , 'AVIS_25160_2012-06_1' , 'AVIS_25160_2012-07_1' , 'AVIS_25160_2012-08_1' , 'AVIS_25160_2012-09_1' , 'AVIS_25160_2012-10_1' , 'AVIS_25160_2012-11_1' , 'AVIS_25160_2012-12_1' , 'AVIS_25160_2013-01_1' , 'AVIS_25160_2013-02_1' , 'AVIS_25160_2013-03_1' , 'AVIS_25160_2013-04_1' , 'AVIS_25160_2013-05_1' , 'AVIS_26681_2012-08_2' , 'AVIS_26673_2012-07_6' , 'AVIS_26517_2012-08_2' , 'AVIS_26972_2013-04_2' , 'AVIS_24821_2012-08_14' , 'AVIS_24862_2012-11_9' , 'AVIS_25300_2012-06_1' , 'AVIS_25300_2012-07_1' , 'AVIS_25300_2012-08_1' , 'AVIS_25300_2012-09_1' , 'AVIS_25300_2012-10_1' , 'AVIS_25300_2012-11_1' , 'AVIS_25300_2012-12_1' , 'AVIS_25300_2013-01_1' , 'AVIS_25300_2013-02_1' , 'AVIS_25300_2013-03_1' , 'AVIS_25300_2013-04_1' , 'AVIS_25300_2013-05_1' , 'AVIS_25488_2012-07_2' , 'AVIS_24101_2012-12_6' , 'AVIS_26589_2012-10_1' , 'AVIS_26742_2012-08_1' , 'AVIS_25232_2012-12_6' , 'AVIS_26217_2012-06_1' , 'AVIS_26217_2012-07_1' , 'AVIS_26217_2012-08_1' , 'AVIS_26217_2012-09_1' , 'AVIS_26217_2012-10_1' , 'AVIS_26217_2012-11_1' , 'AVIS_26217_2012-12_1' , 'AVIS_26217_2013-01_1' , 'AVIS_26217_2013-02_1' , 'AVIS_26217_2013-03_1' , 'AVIS_26217_2013-04_1' , 'AVIS_26217_2013-05_1' , 'AVIS_21573_2012-08_7' , 'AVIS_25598_2012-12_3' , 'AVIS_24812_2012-07_10' , 'AVIS_26761_2013-05_12' , 'AVIS_19059_2012-08_8' , 'AVIS_25917_2012-10_9' , 'AVIS_19007_2012-11_1' , 'AVIS_25694_2012-07_6' , 'AVIS_26822_2012-11_18' , 'AVIS_25562_2013-04_9' , 'AVIS_26702_2012-12_8' , 'AVIS_24020_2012-11_7' , 'AVIS_23746_2012-10_4' , 'AVIS_24812_2012-10_2' , 'AVIS_26704_2012-09_2' , 'AVIS_25443_2013-03_3' , 'AVIS_26254_2013-02_7' , 'AVIS_25922_2012-10_9' , 'AVIS_23219_2012-08_7' , 'AVIS_27011_2013-05_3' , 'AVIS_26254_2012-10_5' , 'AVIS_26760_2012-11_1' , 'AVIS_23639_2012-06_1' , 'AVIS_23639_2012-07_1' ) AND R.MBUL = B.MBUL AND R.RUNID = B.RUNID;

Si quelqu'un avait une idée ou un lien qui expliquerait ce problème peut-être connu .....
Merci

Hors ligne

#2 25/03/2014 17:19:32

rjuju
Administrateur

Re : impossible de tuer une requête

Bonjour,

ce n'est pas normal. La seule explication qui me vient en tête serait du fait que le processus soit en sommeil ininterruptible (dans ps, colonne STAT à D). Vous devriez récupérer le PID du backend et regarder son état au niveau du système d'exploitation la prochaine fois que cela arrive.

Hors ligne

#3 26/03/2014 10:05:17

kiki
Membre

Re : impossible de tuer une requête

Bonjour.
ok. Je vérifierai cela la prochaine fois.
Merci

Hors ligne

#4 28/03/2014 11:36:31

Postgres.0
Membre

Re : impossible de tuer une requête

Bonjour,

quand tu relance ta requête, est-ce-que tu es sur que les données n'étaient  pas dans le cache système?

Hors ligne

#5 28/03/2014 12:46:38

kiki
Membre

Re : impossible de tuer une requête

Bonjour.
Il est possible effectivement que les données soient déjà dans le cache. Il faudrait que je re-teste cela sur de la la recette.
Par contre en ré-examinant les logs (on ne regarde jamais assez les logs :-( ) j'ai trouvé un message d'erreur très interessant :
"stack depth limit exceeded" sur un process dont la requête durait depuis des heures. Après vérification du status de ce process (ps -efl) ce dernier était en S (Interruptible sleep). J'ai donc modifié max_stack_depth. Je me pose toutefois la question : ok, la requête a fait exploser la pile, postgres le détecte bien (puisqu'il l'indique dans ses logs), mais pourquoi le process reste-t-il ? Même en état S, à priori les verrous sont toujours là ce qui est bloquant pour les autres requêtes. dans tous les cas j'attends que cela se reproduise pour aller un peu plus loin dans l'analyse.

Hors ligne

#6 07/04/2014 13:59:23

kiki
Membre

Re : impossible de tuer une requête

Bonjour.
Quelques investigations supplémentaires m'ont mené à constater les choses suivantes :
- le process est en état S
- un kill -15 n'y fait rien
- le process est bloqué dans l'appel system : sendto

Je pense que le client (jdbc) a initié une requête et qu'il ne lit pas les résultats, ou que le close n'est pas fait sur le résultset. La requête ramenant suffisamment de données, postgres écrit dans le socket et fini par remplir les buffer TCP qui ne sont pas vidés par le client , d'où le blocage. En tuant le process java côté client, cela décoince bien le process côté postgres.
Questions :
  - est-ce qu'un statement_timeout pourrait m'aider (j'en doute vu que mon kill -15 ne marche pas) ?
  - y-a-t-il un moyen de positionner un timeout sur le read et sur le write du socket côté postgres (l'équivalent du setsockopt). Je n'ai rien trouvé dans ce sens dans postgresql.conf ?

Hors ligne

#7 07/04/2014 14:18:18

gleu
Administrateur

Re : impossible de tuer une requête

est-ce qu'un statement_timeout pourrait m'aider (j'en doute vu que mon kill -15 ne marche pas) ?

Toujours possible d'essayer mais j'avoue que je doute que cela fonctionne mieux que le kill -15.

y-a-t-il un moyen de positionner un timeout sur le read et sur le write du socket côté postgres (l'équivalent du setsockopt). Je n'ai rien trouvé dans ce sens dans postgresql.conf ?

Ailleurs, je ne sais pas. Mais pas dans le postgresql.conf.


Guillaume.

Hors ligne

Pied de page des forums