Vous n'êtes pas identifié(e).
Pages : 1
Bonjour,
en essayant d'effectuer mon dump ce matin, j'obtiens ceci :
"
pg_dump: Message d'erreur du serveur : ERREUR: 2 trigger record(s) not found for relation "14209031MC"
pg_dump: La commande était : LOCK TABLE public."14209031MC" IN ACCESS SHARE MODE
"
Le probleme vient probablement d'une manipulation effectuée hier : ne sachant pas supprimer une fonction car elle était utilisée par un trigger, j'ai été dans la table trigger et ai supprimé directement le trigger en question. Bêtise or not?
Comment réparer ?
Merci pour votre aide.
Avr.
Hors ligne
Quelle version de PostgreSQL utilisez-vous ? je ne trouve pas ce message dans les sources...
Guillaume.
Hors ligne
Bonjour,
je suis sous Debian Lenny et c'est la postgres 8.3.9.
Merci pour votre aide.
Avr.
Hors ligne
Oui, j'ai fini par trouver que c'était une 8.3.
Pour répondre un peu mieux à votre question, supprimer le trigger avant de supprimer la fonction n'est pas un problème, c'est au contraire la bonne façon de le faire.
Pourrait-on avoir la définition de la table ? telle que l'indique la méta commande \d de psql.
Question subsidiaire : utilisez-vous slony ?
Guillaume.
Hors ligne
Si je vous suis, l'idée est de retrouver la table qui utilise le trigger qui a été supprimé (pour ensuite sans doute supprimer ce trigger de cette table) ?
Problème : je ne sais pas quelle table et j'ai 14430 tables dans cette base .
Existe-t-il un moyen (via les tables systemes par exemple) de retrouver les tables qui utilisent un trigger lorsqu'on connait le nom de celui-ci?
Je n'utilise pas (encore) Slony.
Hors ligne
Ce message :
ERREUR: 2 trigger record(s) not found for relation "14209031MC"
veut-il bien dire que la table "14209031MC" possede 2 trigger qui "n'existent plus" ?
Dans ce message, la relation "14209031MC" est-ce bien une table ?
et donc, je reformule la question precedente :
est-il possible de connaitre le nom de cette table "14209031MC"
Suis-je sur la voie ou completement à côté?
Autr info, lorsque je réessaye de supprimer la fonction, j'obtiens le message :
ERREUR: could not find tuple for trigger 142177
Hors ligne
Vous avez dit au tout début « j'ai été dans la table trigger et ai supprimé directement le trigger en question ». Il ne s'agissait pas de cette table ?
Ce message :
ERREUR: 2 trigger record(s) not found for relation "14209031MC"
veut-il bien dire que la table "14209031MC" possede 2 trigger qui "n'existent plus" ?
J'aurais tendance à dire que la table 14209031MC avait deux triggers et que ces deux triggers n'existent plus dans pg_trigger.
Dans ce message, la relation "14209031MC" est-ce bien une table ?
Oui. Une relation est soit une table soit un index. Dans ce contexte, on peut raisonnablement penser qu'il s'agit d'une table.
et donc, je reformule la question precedente :
est-il possible de connaitre le nom de cette table "14209031MC"
14209031MC est le nom de la table.
Autr info, lorsque je réessaye de supprimer la fonction, j'obtiens le message :
ERREUR: could not find tuple for trigger 142177
Comment avez-vous supprimé la fonction ? quelle requête avez-vous exécuté ?
Guillaume.
Hors ligne
En essayant d reproduire le problème, j'ai relu votre premier message :
Le probleme vient probablement d'une manipulation effectuée hier : ne sachant pas supprimer une fonction car elle était utilisée par un trigger, j'ai été dans la table trigger et ai supprimé directement le trigger en question. Bêtise or not?
Si vous parlez de la table pg_trigger, alors, oui, c'est une grosse bêtise.
Bon, en testant avec une 8.3, j'ai pu reproduire le phénomène. Je l'ai corrigé en exécutant cette requête :
update pg_class set reltriggers=0 where relname='14209031MC';
Évidemment, c'est à vos risques et périls étant donné qu'on touche aux tables systèmes de la base. Ceci dit, c'est vous qui avez commencé
Bref, après ça, j'arrive à faire un dump.
Si jamais cela fonctionne, promettez-moi de ne plus *JAMAIS* modifier les tables systèmes (celles qui commencent par un pg_).
Guillaume.
Hors ligne
C'est effectivement la table pg_trigger que j'ai modifié :-(
Et, promis, je ne touche plus aux tables systèmes.
Ok compris pour relation=table, cela devient plus clair.
Pour supprimer la fonction, c'est tout simplment via l'interface de pgAdmin.
La requête que vous fournissez fonctionne, mais malheureusement, j'ai beaucoup de table à modifier. Je reviens donc à cette idée, existe-t-il un moyen de trouver les tables qui utilisent un trigger à partir du nom de ce dernier ? Cela me permettrait via une seule requête de supprimer ce trigger de ces tables.
En tous les cas, merci pour le coup de main.
Hors ligne
Tout d'abord, première question, arrivez-vous à faire cette sauvegarde ?
Si oui, on peut passer à la suite. De quelle requête parlez-vous ?
Guillaume.
Hors ligne
Toujours pas de sauvegarde : pour l'instant, j'utilise votre requête (UPDATE pg_class SET ...) pour corriger le problème.
Si je lance le dump, il passe les tables 'nettoyées' et bloque sur la suivante non encore nettoyée.
Et comme je le disais, j'ai beaucoup de tables ...
Par contre mon raisonnement doit être erroné : pour rappel, j'ai supprimé dans pg_trigger un trigger qui utilisait une procedure que je souhaitais supprimer. Mais des tables font toujours reference à ce trigger !
Je pensais donc qu'en supprimant toutes references à ce trigger dans toutes les tables de la base cela corrigerait mon problème. J'ai donc ecrit et utilisé ceci sur toutes les tables de la base :
DROP TRIGGER IF EXISTS triger_name ON table_name.
Or, cela ne change rien : le dump bloque toujours sur les tables non nettoyées via votre requête !
Donc je continue à utiliser votre query.
Si vous avez une idée ...
Hors ligne
Pouvez-vous indiquer la requête exacte que vous avez exécuté ? pour moi, vous n'aviez modifié le trigger que d'une seule table.
Et que vous donne comme résultat l'exécution de cette requête :
select relname from pg_class where reltriggers>0 and reltriggers != (select count(*) from pg_trigger where tgrelid=pg_class.oid);
Guillaume.
Hors ligne
Cette requête (select relname from pg_class where ...) me sort 2561 tables.
La requête que j'ai executée est :
DROP TRIGGER IF EXISTS triger_name ON table_name
celle-ci est incorporée à un script python qui boucle sur toutes les tables de la base (table_name est bien entendu une variable qui est remplacée par le nom des tables dans la boucle).
En fait, le triger que j'ai supprimé était encore utilisé par un grand nombre de table de la base.
Et c'est precisement là, je pense, ma principale erreur : je pensais l'avoir au préalablement remplacé par un autre triger.
Pour être plus précis encore, j'étais occupé à harmoniser la syntaxe de mes trigers et de mes fonctions, pour cela, je créais une nouvelle fonction avec la nouvelle syntaxe, je créais le nouveau triger avec la nouvelle syntaxe, je remplacais l'ancien triger par le nouveau dans les tables (via script python) et je supprimais ensuite l'ancienne fonction et l'ancien triger.
L'erreur vient du script pyhton, qui au lieu de boucler sur toutes les tables n'en a effectué qu'une partie du travail.
D'où la persistence de tables utilisant toujours l'ancien triger, que j'ai bêtement supprimé dans pg_triger.
J'espère ainsi avoir un peu mieux cerné l'historique du problème.
J'ai donc maintenant refait tourner le script python sur TOUTES les tables, et l'ancien triger ne devrait donc plus être présent dans aucune table.
Hélas le dump bloque toujours.
J'utilise donc votre requête (update pg_class set reltrigge ....) pour corriger le problème, table par table.
Hors ligne
Pour la requête, je ne parlais pas du « DROP TRIGGER » mais de l'UPDATE sur pg_trigger.
À priori, pour vous sortir de ça, vous pouvez essayer la requête suivante :
update pg_trigger
set reltriggers=(select count(*) from pg_trigger where tgrelid=pg_class.oid)
from pg_class
where
reltriggers>0
and
reltriggers != (select count(*) from pg_trigger where tgrelid=pg_class.oid);
Guillaume.
Hors ligne
Cela retourne :
ERREUR: la colonne « reltriggers » de la relation « pg_trigger » n'existe pas
Hors ligne
Ne serait-ce pas pg_class que je dois updater ?
Hors ligne
Ah mince, y'a un s en trop et c'est pg_class qu'il faut mettre à jour. On recommence :
update pg_class
set reltrigger=(select count(*) from pg_trigger where tgrelid=pg_class.oid)
where
reltriggers>0
and
reltriggers != (select count(*) from pg_trigger where tgrelid=pg_class.oid);
Guillaume.
Hors ligne
Bravo,
problème résolu et dump effectué.
Vous m'avez sorti d'un mauvais pas, un grand merci !
Si je puis me permettre, encore une ou 2 petites questions:
1. où trouver l'info pour comprendre le fonctionnement des tables système ?
certes, je n'y toucherai plus sur une base en prod ou en dev, mais je ne dis pas que sur une machine dédiée à l'aspect didactique ...
2. l'utilisation de Slony m'aurait-elle aidé ?
Encore merci.
Avr.
Hors ligne
1. où trouver l'info pour comprendre le fonctionnement des tables système ?
Le manuel de PostgreSQL (http://docs.postgresql.fr/8.4/catalogs.html) donne quelques informations sur ces tables. L'article http://www.dalibo.org/glmf106_les_vues_ … gresql_8.3 se concentre sur les catalogues statistiques de PostgreSQL.
2. l'utilisation de Slony m'aurait-elle aidé ?
Non.
Guillaume.
Hors ligne
Pages : 1