Comment récupérer de l'espace occupé par un index partiellement construit et terminé par une panne de courant

9

J'utilise postgres (postgis) 9.4.2 sur un mac (10.10.4).

J'ai quelques grandes tables (plusieurs To).

Au cours de la construction d'un index sur l'un d'entre eux, qui prend environ une semaine, j'ai vu l'espace HD disponible chuter comme vous vous attendez à presque le point où l'index serait terminé lorsqu'une panne de courant a duré plus longtemps que l'unité de batterie et le système est descendu. J'ai eu des tampons hors tension, et fillfactor=100pendant la construction car c'est une source de données statique. Au redémarrage, l'espace disponible restant sur le lecteur est exactement là où il se trouvait à la fin de la génération de l'index. L'analyse sous vide ne libère pas l'espace.

J'ai essayé de laisser tomber la table et de ré-ingérer, et cela n'a pas laissé de place. Maintenant, je suis à un endroit où je n'ai pas assez d'espace pour construire l'index.

Les fichiers générés lors de la construction de l'index sont-ils coincés dans des limbes où ils ne peuvent pas être supprimés par le système en raison de la panne de la machine pendant la panne de courant?

Quand je regarde les tailles de table + les index dans la base de données (qui sont les seules données sur ce lecteur), ils totalisent environ 6 To . Le disque est de 8 To , et il reste moins de 500 Go sur le disque, il semble donc qu'il y ait environ 1,5 To perdu quelque part, ce qui correspond à la taille de cet index.

Des idées?

dkitchel
la source
L'index est-il toujours répertorié avec une requête comme celle-ci? SELECT r.relname, r.relkind, n.nspname FROM pg_class r INNER JOIN pg_namespace n ON r.relnamespace = n.oid WHERE relkind = 'i';
Kassandry
Non, il n'apparaît pas dans les résultats de cette requête.
dkitchel
1
Avez-vous quelque chose dans la liste qui SELECT indexrelid::regclass, indrelid::regclass FROM pg_catalog.pg_index WHERE NOT indisvalid;vous donne?
dezso
Non, ça revient vide.
dkitchel

Réponses:

5

Normalement, nous nous attendions à ce que lorsque postgres soit redémarré, le processus de récupération après incident ait supprimé les fichiers liés à un index restauré du répertoire de données.

Supposons que cela ne fonctionne pas, ou du moins qu'il doit être vérifié manuellement.

La liste des fichiers qui devraient être dans le datadir peut être établie avec une requête comme celle-ci:

select pg_relation_filenode(oid)
   from pg_class
  where relkind in ('i','r','t','S','m')
    and reltablespace=0
  order by 1;

reltablespace=0est pour le tablespace par défaut. Si l'index problématique a été créé dans un espace de table non par défaut, il 0doit être remplacé par son OID dans pg_tablespace.

i, r, t, S, m in relkindcorrespondent respectivement aux index, tables, toasts, séquences, vues matérialisées. Tous ces objets ont leurs données dans des fichiers dont les noms correspondent pg_relation_filenode(oid).

Sur disque, les fichiers de données sont en dessous $PGDATA/base/oid/où se oidtrouve oidla base de données obtenue par select oid,datname from pg_database. Si nous ne parlons pas du tablespace par défaut, baseest remplacé par à la PG_version_somelabelplace.

Répertoriez et triez les fichiers correspondant aux relfilenodes dans ce répertoire:

ls | grep -E '^[0-9]+$' | sort -n > /tmp/list-of-relations.txt

(qui ne conserve en fait que le premier segment pour les relations supérieures à 1 Go. S'il existe des segments persistants qui ne sont attachés à rien, ils doivent être considérés séparément)

et diff ce fichier avec le résultat de la requête ci-dessus.

S'il existe des fichiers de données persistants qui ne correspondent à aucun objet connu de la base de données, ils doivent apparaître dans cette différence.

Daniel Vérité
la source
Impressionnant! J'ai trouvé 1 fichier dans le datadir qui n'apparaissait pas dans la liste de sélection. Puis-je supprimer ce fichier en toute sécurité?
dkitchel
En fait, cela correspond à environ 800 fichiers avec des itérations après le point - tous comme 499807.484, etc. Puis-je supprimer ces fichiers en toute sécurité?
dkitchel
@dkitchel: ce serait des segments de 1 Go chacun pour l'énorme indice. Vérifiez peut-être que leurs horodatages coïncident avec le moment où l'index de création était en cours d'exécution. Quant à les supprimer, eh bien, j'espère que mon raisonnement ci-dessus est correct, mais ce sont vos données, donc finalement c'est votre décision!
Daniel Vérité
Oui, les horodatages correspondent à la date de création de l'index et la somme des tailles de fichier correspond à la taille de l'index. Votre raisonnement semble solide. Je vais essayer avec une grande confiance. Merci beaucoup.
dkitchel
Il suffit de faire un suivi pour que ceux qui se trouvent dans la même situation puissent utiliser la solution de @ DanielVerite en toute confiance. Sa solution a en effet parfaitement fonctionné pour moi.
dkitchel