Comment récupérer de l'espace disque sur PostgreSQL?

25

J'ai une installation locale de la base de données 9.1 avec quelques tables qui avaient cca. 300 millions d'enregistrements et la base de données est passée à environ 20 Go. Ensuite, j'ai émis une delete fromcommande pour supprimer tous les enregistrements de celui-ci (j'aurais dû utiliser truncate, mais je ne le savais pas). J'ai donc fait un vide complet sur ma base de données pour récupérer de l'espace disque, mais cela n'aide pas. Mon problème semble identique à celui-ci , mais aucune solution n'est proposée. J'ai déjà vérifié ce fil et la documentation sur "récupérer de l'espace disque" , mais je ne trouve toujours pas de solution. J'utilise ce code pour obtenir la taille de toutes les tables

 SELECT nspname || '.' || relname AS "relation",
 pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size"
 FROM pg_class C
 LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
 WHERE nspname NOT IN ('pg_catalog', 'information_schema')
 AND C.relkind <> 'i'
 AND nspname !~ '^pg_toast'
 ORDER BY pg_total_relation_size(C.oid) DESC
 LIMIT 15;

Cependant, pour un total inférieur à 1 Go

SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname)) AS size FROM pg_database 

affiche toujours environ 20 Go. Tout conseil très apprécié.

Communauté
la source
Eh bien, votre requête de taille exclut: les index, les tables dans pg_cataloget les tables dans information_schema. Essayez donc de voir si c'est le cas en supprimant ces restrictions dans la WHEREclause. Veuillez montrer votre version exacte de PostgreSQL ( SELECT version()) et ce que vous faites exactement pour "vider la base de données complète", c'est-à-dire la commande exacte. Si possible, exécutez VACUUM FULL VERBOSE;(aucun argument) et collez la sortie quelque part, puis liez-la ici.
Craig Ringer
Essayez de supprimer la base de données. Vous pouvez également essayer de vider la base de données, puis de la restaurer pour supprimer les déchets.
jb.
1
@jb Cela fonctionnerait, mais ne devrait pas être nécessaire. Mieux vaut savoir quel est le problème.
Craig Ringer

Réponses:

22

Bien que vous ne l'ayez pas déclaré, je suppose, d'après vos références aux documents que vous avez suivis, que vous avez effectué un VIDE PLEIN sur la base de données et / ou les tableaux concernés. Vous n'avez pas non plus spécifié quelle version postgresql vous utilisez - je suppose que c'est> 9.0 (VACUUM FULL s'est comporté différemment avant cela).

VACUUM FULL réécrira les tables affectées dans de nouveaux fichiers, puis supprimera les anciens fichiers. Cependant, si un processus a toujours l'ancien fichier ouvert, le système d'exploitation ne supprimera pas réellement le fichier - jusqu'à ce que le dernier processus l'ait fermé.

Si possible, le redémarrage de la base de données garantirait la fermeture de tous les fichiers ouverts.

Si ce n'est pas pratique, vous pourrez peut-être vérifier si c'est votre problème et savoir quel processus a les fichiers ouverts.

Si vous utilisez Linux (ou la plupart des autres systèmes de type Unix), vous pouvez utiliser la commande 'lsof' pour obtenir une liste de tous les fichiers ouverts dans tous les processus. Les fichiers ouverts mais qui ont depuis été supprimés auront «(supprimé)» ajouté au nom de fichier. Ainsi, vous pouvez grep la sortie de lsof, à la recherche de fichiers supprimés, comme ceci:

sudo lsof -u postgres | grep 'deleted'

Si cela identifie les processus qui ont toujours les anciens fichiers ouverts, vous pouvez utiliser pg_terminate_backend pour terminer ce processus:

SELECT pg_terminate_backend(xxx);

où xxx est le PID du processus, trouvé dans la sortie lsof.

Si vous utilisez Windows, le même principe pourrait s'appliquer, car postgres ouvre les fichiers à l'aide de l'indicateur FILE_SHARE_DELETE, ce qui lui permet de supprimer les fichiers ouverts dans un autre processus. La commande ' handle ' est l'équivalent approximatif de lsof, bien que je ne sais pas si vous pouvez dire si les fichiers sont supprimés ou non, donc un travail supplémentaire pourrait être nécessaire.

C'est une autre question de savoir pourquoi de tels processus s'accrocheraient aux anciens descripteurs de fichiers. Cependant, dans le fil que vous avez cité dans votre question, Tom Lane semble impliquer que cela peut se produire.

Harmique
la source
J'ai dû récupérer d'urgence de l'espace disque, j'ai donc supprimé la base de données et restaurée à partir de la sauvegarde. Cependant, le "comment" résoudre ce problème est toujours très utile pour les cas futurs. Ma base de données est 9.1, gagne 8 64 bits, la dénomination des fichiers (cas des fichiers ouverts) s'applique-t-elle de la même manière que sous Linux?
@arcull OK, je ne savais pas que vous utilisiez Windows. J'ai ajouté quelques informations à la réponse sur la façon dont cela s'applique à Windows. Si vous pensez que cela pourrait être une réponse utile, veuillez envisager un vote positif car cela permet aux autres de le trouver plus facilement.
harmic