Vous n'êtes pas identifié(e).
Bonjour,
J'utilise actuellement une application qui s'appuie sur une base de donnée Postgresql 8.4. Cette application déclare des curseurs et les utilise pour afficher des résultats.
J'ai actuellement un problème de lenteur sur l'utilisation d'un de ces curseurs, et je soupçonne un problème d'index manquant, générant un full table scan.
Pour confirmer ou infirmer mes soupçons, je souhaiterais savoir la requête incluse dans ce curseur et c'est là tout le problème : je ne sais pas comment faire !
J'ai bien trouvé une vue "pg_cursors" mais qui reste désespérément vide.
Mon test actuel :
Je prépare un fichier .sql, dont le contenu est :
SELECT * FROM pg_stat_activity WHERE datname='mydb';
SELECT * FROM pg_cursors;
SELECT * FROM pg_stat_activity WHERE datname='mydb';
J’exécute l'action actuellement lente
J'exécute le script SQL pour voir ce qui se passe
Mon résultat :
datid | datname | procpid | usesysid | usename | current_query | waiting | xact_start | query_start | backend_start | client_addr | client_port
---------+-------------+---------+----------+----------+-------------------------------------------------------------------------------------------+---------+-------------------------------+-------------------------------+-------------------------------+---------------+-------------
7570372 | mydb | 14854 | 16420 | myuser | FETCH 30 FROM CUR162 | f | 2014-01-22 10:57:42.042005+01 | 2014-01-22 10:57:42.042702+01 | 2014-01-22 06:00:37.289572+01 | 192.168.3.109 | 49998
name | statement | is_holdable | is_binary | is_scrollable | creation_time
------+-----------+-------------+-----------+---------------+---------------
(0 rows)
datid | datname | procpid | usesysid | usename | current_query | waiting | xact_start | query_start | backend_start | client_addr | client_port
---------+-------------+---------+----------+----------+-------------------------------------------------------------------------------------------+---------+-------------------------------+-------------------------------+-------------------------------+---------------+-------------
7570372 | mydb | 14854 | 16420 | myuser | FETCH 30 FROM CUR162 | f | 2014-01-22 10:57:42.042005+01 | 2014-01-22 10:57:42.042702+01 | 2014-01-22 06:00:37.289572+01 | 192.168.3.109 | 49998
On voit bien le curseur en train d'être parcouru, et pourtant, je n'ai aucune mention dans "pg_cursors".
Ma question est : comment je peux voir les curseurs actuellement déclarés et la requête qu'ils contiennent ?
Merci pour votre aide.
Dernière modification par sterfield (23/01/2014 12:08:28)
Hors ligne
C'est normal : vous ne verrez que l'activité courante, c'est à dire le fetch.
Le texte de la requête doit être considérée comme le contenu d'une variable, même si c'est un peu plus complexe que ça. Or PG ne dispose pas d'un débugeur permettant de "voir" le contenu des variables, et ne fournit pas non plus d'outil pour aller capturer en mémoire le contenu d'une entrée du cache, comme c'est le cas danc SQL Server ou Oracle...
A +
Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES, Expert langage SQL
Le site sur les SGBD relationnel et langage SQL : http://sqlpro.developpez.com/
Modélisation de données, conseil, expertise, audit, optimisation, tuning, formation
* * * * * Enseignant CNAM PACA, ISEN Toulon, CESI Aix en Provence * * * * *
Hors ligne
C'est ballot.
Bon bah, ca ne va pas m'aider pour débugger tout ca !
Merci pour ta réponse.
Hors ligne
Seuls certains curseurs sont visibles dans cette vue (http://docs.postgresql.fr/9.3/view-pg-cursors.html).
Le plus simple serait de tracer toutes les requêtes exécutées, un peu avant l'ouverture du curseur, puis de suivre ce que fait le processus grâce aux traces.
Guillaume.
Hors ligne
Re,
J'ai réussi à attraper ma requête en passant mon "log_statement" à "all" pendant un court instant et en rechargeant la configuration.
C'est un peu bourrin et je ne sais pas si ca serait utilisable sur un moteur qui travaille à fond les ballets mais je suis arrivé à mes fins.
Merci à tous !
Hors ligne
Si vous voulez être plus sélectif, vous pouvez le faire dans le traitement, en l'entourant des commandes suivantes :
set log_min_duration_statement to 0;
-- traitement
reset log_min_duration_statement;
Vous pouvez spécifier la durée minimum en ms pour tracer moins de requêtes.
Julien.
https://rjuju.github.io/
Hors ligne