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

#1 03/03/2009 13:26:06

mnementh64
Membre

Comment réparer des index endommagés ?

Bonjour,

Sur une base de prod avec beaucoup de tables (34806) et d'index (133985). J'ai repéré quelques défauts d'intégrités et je voudrais savoir s'il existe des méthodes pour réparer.

Considérant une table normalement avec 3 index (nomtable_i1, nomtable_i2 et nomtable_i3), j'ai un seul des 3 index qui est correct : je peux le dropper, le re-créer, ...
Si je tente de dropper les autres, j'obtiens une erreur : ERROR : could not open relation with OID 9050310.
Si je tente de créer un index avec le même nom, j'obtiens : ERROR : relation "nomtable_i2" already exists

En fouillant dans les tables systèmes, j'ai trouvé que les index en erreur existent bien dans pg_class mais leur lien avec la table mère n'est pas dans pg_index. Or je ne peux pas agir sur les tables système : trop dangereux.

J'ai tenté : REINDEX TABLE ... ou REINDEX INDEX ... ou VACUUM table mais rien n'y fait.

Quelqu'un connait-il une méthode adequat pour résoudre ce problème ??

Merci de votre aide :-)

Sylvain Caillet

Hors ligne

#2 03/03/2009 15:06:26

gleu
Administrateur

Re : Comment réparer des index endommagés ?

Il y a certainement un problème plus grave.

ERROR : could not open relation with OID 9050310.

Ce message indique que le fichier représentant l'index n'existe plus. Ce qui laisse supposer que, soit quelqu'un a supprimé le fichier, soit il y a un problème de système de fichiers.

La solution la plus simple est évidemment de supprimer cette ligne dans pg_class, mais cela n'est qu'une solution à court terme. Il faut savoir comment ce fichier a disparu.

Quelle version de PostgreSQL avez-vous ?


Guillaume.

Hors ligne

#3 03/03/2009 15:18:03

mnementh64
Membre

Re : Comment réparer des index endommagés ?

Merci de votre réponse.

Il s'agit de Postgresql 8.3.3

Quant à des problèmes fichiers, le serveur est totalement dédié à une seule tâche d'alimentation de la base via un robot Java qui ne manipule des fichiers que dans un seul dossier. Par contre, il y a quelques mois, on avait des pbs de perfs : on avait toutes les tables dans le tablespace par défaut ... et on avait atteint les limites systèmes en terme de nb de fichiers dans un seul dossier. On a alors décidé de mettre en place une politique de tablespace et il y a eu une migration massive des données et donc un déplacement par Postgresql des ses fichiers de stockage. Peut-être est-ce à cette occasion que certains fichiers ont été endommagés ?

Sylvain

Hors ligne

#4 03/03/2009 15:27:59

gleu
Administrateur

Re : Comment réparer des index endommagés ?

J'ai du mal à y croire. Comment ont été déplacé les fichiers ?

Pouvez faire ceci :

select spclocation, relfilenode from pg_class, pg_tablespace where reltablespace=pg_tablespace.oid and pg_class.oid=9050310

spclocation est l'emplacement du fichier (si vide, il s'agit du tablespace par défaut, soit $PGDATA), relfilenode le nom du fichier correspondant à cet OID.

en faisant sur le shell un

ll <spclocation>/<relfilenode>*

, qu'obtenez-vous ?


Guillaume.

Hors ligne

#5 03/03/2009 15:33:24

mnementh64
Membre

Re : Comment réparer des index endommagés ?

Aucune réponse à la requête : le fichier semble ne pas exister.

Hors ligne

#6 03/03/2009 15:44:12

gleu
Administrateur

Re : Comment réparer des index endommagés ?

Aucune réponse à la requête ou à la commande shell ?

Si c'est à la requête, pouvez-vous essayer ceci :

select relfilenode from pg_class where oid=9050310

et ceci

select * from pg_class where relfilenode=9050310

Guillaume.

Hors ligne

#7 03/03/2009 16:04:29

mnementh64
Membre

Re : Comment réparer des index endommagés ?

En fait l'objet référencé par l'oid indiqué semble ne pas exister. Pour synthétiser le pb, j'ai utilisé un autre index (j'avais perdu le nom du premier) et voici la suite de requêtes :

flows=# DROP INDEX flows_a37_h14_m30_in_inf;
ERROR:  could not open relation with OID 9964489

flows=# CREATE INDEX flows_a37_h14_m30_in_inf ON flows_a37_h14_m30 USING btree(in_inf);
ERROR:  relation "flows_a37_h14_m30_in_inf" already exists

flows=# select * from pg_class where oid=9964489;
(0 rows)

flows=# select * from pg_index where indexrelid=9964489;
(0 rows)

flows=# select spclocation, relfilenode from pg_class, pg_tablespace where reltablespace=pg_tablespace.oid and pg_class.oid=9964489;
(0 rows)

flows=# select relfilenode from pg_class where oid=9964489;
(0 rows)

flows=# select relfilenode from pg_class where oid=9964489;
(0 rows)

Mais si je cherche l'index par son nom, là je trouve :

flows=# select oid,* from pg_class where relname='flows_a37_h14_m30_in_inf';
   oid   |         relname          | relnamespace | reltype | relowner | relam | relfilenode | reltablespace | relpages | reltuples | reltoastrelid | reltoastidxid | relhasindex | relisshared | relkind | relnatts | relchecks | reltriggers | relukeys | relfkeys | relrefs | relhasoids | relhaspkey | relhasrules | relhassubclass | relfrozenxid | relacl | reloptions 
---------+--------------------------+--------------+---------+----------+-------+-------------+---------------+----------+-----------+---------------+---------------+-------------+-------------+---------+----------+-----------+-------------+----------+----------+---------+------------+------------+-------------+----------------+--------------+--------+------------
 9964786 | flows_a37_h14_m30_in_inf |         2200 |       0 |       10 |   403 |     9964786 |             0 |        2 |       356 |             0 |             0 | f           | f           | i       |        1 |         0 |           0 |        0 |        0 |       0 | f          | f          | f           | f              |            0 |        | 
(1 row)

Et on retrouve l'OID du début avec

flows=# select * from pg_index where indexrelid=9964786;
 indexrelid | indrelid | indnatts | indisunique | indisprimary | indisclustered | indisvalid | indcheckxmin | indisready | indkey | indclass | indoption | indexprs | indpred 
------------+----------+----------+-------------+--------------+----------------+------------+--------------+------------+--------+----------+-----------+----------+---------
    9964786 |  9964489 |        1 | f           | f            | f              | t          | f            | t          | 14     | 1978     | 0         |          | 
(1 row)

Revoilà le 9964489 qu'il n'arrive pas à ouvrir. A quoi est-ce que ça correspond ?

Sylvain

Hors ligne

#8 03/03/2009 16:10:31

gleu
Administrateur

Re : Comment réparer des index endommagés ?

Ça correspond à l'OID de la table. Autrement dit l'index est bien là, c'est la table qui a disparu.


Guillaume.

Hors ligne

#9 03/03/2009 16:32:59

mnementh64
Membre

Re : Comment réparer des index endommagés ?

Pourtant, la table est bien là ! Il arrive d'ailleurs à supprimer d'autres index sur la même table.

Une particularité est que les index sont tous droppés dans la même query :

DROP INDEX flows_a37_h14_m30_timestamp;DROP INDEX flows_a37_h14_m30_in_inf;DROP INDEX flows_a37_h14_m30_out_inf;

Une autre particularité est que cette table est en fait une partition et au moment où on essaye de dropper ses index (pour accélérer des COPY), elle est encore connectée à la table mère. Serait-ce plus sûr de la déconnecter avant ?

Hors ligne

#10 03/03/2009 17:18:17

gleu
Administrateur

Re : Comment réparer des index endommagés ?

Le fait qu'elle soit une partition n'est pas un problème en soi. Le fait de supprimer tous les index dans une même requête non plus. Le fait que la table est toujours connectée à la table mère non plus.

Il faudrait savoir quel est l'OID de cette table et remplacer la valeur de indrelid dans pg_index pour indexrelid=9964786, histoire de voir si le problème est réglé après ça.


Guillaume.

Hors ligne

#11 03/03/2009 17:35:34

mnementh64
Membre

Re : Comment réparer des index endommagés ?

Voici les requêtes.

flows=# select oid from pg_class where relname='flows_a37_h14_m30';
   oid    
----------
 29619941

flows=# update pg_index set indrelid=29619941 where indexrelid=9964786;
UPDATE 1

Ensuite, je demande l'affichage des propriétés des la table avec

flows=# \d flows_a37_h14_m30

et il ne sort toujours pas l'index en question.

Hors ligne

#12 03/03/2009 18:16:34

gleu
Administrateur

Re : Comment réparer des index endommagés ?

\d récupère les index via cette requête SQL :

SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, i.indisvalid, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true), c2.reltablespace
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
WHERE c.oid = '29619941' AND c.oid = i.indrelid AND i.indexrelid = c2.oid

Que donne l'exécution de cette requête ?


Guillaume.

Hors ligne

#13 03/03/2009 18:26:49

mnementh64
Membre

Re : Comment réparer des index endommagés ?

Aucune ligne.

Hors ligne

#14 03/03/2009 19:09:13

gleu
Administrateur

Re : Comment réparer des index endommagés ?

Il n'y a aucun index sur cette table ? je croyais qu'il y en avait plusieurs, mais qu'une seule ne s'affichait pas.


Guillaume.

Hors ligne

#15 04/03/2009 10:00:59

mnementh64
Membre

Re : Comment réparer des index endommagés ?

Il y avait un index correct mais je l'ai droppé pour tester. Et il y avait 2 index incorrects.

Hors ligne

#16 04/03/2009 10:30:55

gleu
Administrateur

Re : Comment réparer des index endommagés ?

La seule idée qui me vienne est que l'index pg_class_oid_index est corrompu. Il serait intéresser de réindexer pg_class et pg_index. Mais pour cela, il vous faut arrêter le serveur, le démarrer en mode autonome et lancer un réindexage... puis arrêter le mode autonome et relancer PostgreSQL.


Guillaume.

Hors ligne

#17 04/03/2009 10:50:42

mnementh64
Membre

Re : Comment réparer des index endommagés ?

ok, merci, je tente la manip et reviens vers le forum.

Hors ligne

#18 04/03/2009 12:06:04

mnementh64
Membre

Re : Comment réparer des index endommagés ?

Démarrage en mode autonome puis REINDEX SYSTEM postgres sur la base système.

--> Aucune erreur à la réindexation.
--> Par contre la commande DROP INDEX flows_a37_h14_m30_in_inf; ne fonctionne toujours pas (could not open relation with OID 9964489).

Hors ligne

#19 04/03/2009 12:24:01

gleu
Administrateur

Re : Comment réparer des index endommagés ?

Alors là je ne comprends plus. Sans avoir accès au serveur, je ne vois pas quoi vous dire. Envoyer un mail expliquant votre problème sur pgsql-general me semble une bonne idée.


Guillaume.

Hors ligne

#20 04/03/2009 13:05:00

mnementh64
Membre

Re : Comment réparer des index endommagés ?

Ok, merci de votre aide en tout cas et si j'obtiens des infos, je publierai à la suite de ce post.

Hors ligne

Pied de page des forums