J'ai besoin d'exécuter VACUUM FULL sans espace disque disponible
27
J'ai une table qui occupe près de 90% de l'espace HD sur notre serveur. J'ai décidé de supprimer quelques colonnes pour libérer de l'espace. Mais je dois restituer l'espace au système d'exploitation. Le problème, cependant, est que je ne sais pas ce qui se passera si j'exécute VACUUM FULL et qu'il n'y a pas assez d'espace libre pour faire une copie de la table.
Je comprends que VACUUM FULL ne doit pas être utilisé mais j'ai pensé que c'était la meilleure option dans ce scénario.
Puisque vous n'avez pas assez d'espace pour exécuter un vacumm ou reconstruire, vous pouvez toujours reconstruire vos bases de données postgresql en les restaurant. La restauration des bases de données, des tables et des index permettra de libérer de l'espace et de la défragmentation. Ensuite, vous pouvez configurer une maintenance automatisée pour vacumm vos bases de données sur une base régulière.
1 Sauvegardez toutes les bases de données sur votre serveur postgresql
Vous souhaiterez sauvegarder toutes vos bases de données sur une partition qui a suffisamment d'espace. Si vous étiez sous Linux, vous pouvez utiliser gzip pour compresser davantage la sauvegarde pour économiser de l'espace
su - postgres
pg_dumpall | gzip -9>/some/partition/all.dbs.out.gz
Merci, c'est ce que j'ai fini par faire, avec quelques différences. Je viens de supprimer la base de données après l'avoir sauvegardée. Puis en a créé un nouveau et l'a restauré.
Justin
De rien. J'ai pensé que supprimer le contenu du répertoire de données et faire initdb aurait été suffisant.
Craig Efrein
Fonctionne très bien, je recommande simplement de sauter la gzippartie pour gagner du temps.
Rafael Barbosa
17
REMARQUE: j'ai testé cela sur 9.1. Je n'ai pas de serveur 9.0 qui traîne ici. Je suis sûr que cela fonctionnera bien sur 9.0.
ATTENTION (comme indiqué dans les commentaires de @erny):
Note that high CPU load due to I/O operations may be expected.
Vous pouvez le faire sans pratiquement aucun temps d'arrêt en utilisant un espace de table temporaire. Le temps d'arrêt sera sous la forme de verrous exclusifs. Mais seulement sur la table, vous passez l'aspirateur. Donc, tout ce qui se passera, c'est que les requêtes des clients attendront simplement que le verrou soit acquis s'ils accèdent à la table en question. Vous n'avez pas besoin de fermer les connexions existantes.
Une chose à savoir cependant, c'est que le déplacement de la table et le vide complet devront eux-mêmes attendre d'abord un verrou exclusif!
Tout d'abord, vous avez évidemment besoin de stockage supplémentaire. Comme Stéphanementionné dans les commentaires, celui-ci doit être au moins deux fois plus grand que le tableau en question comme le VACUUM FULLfait une copie complète. Si vous êtes chanceux et pouvez ajouter dynamiquement un disque à la machine, faites-le. Dans le pire des cas, vous pouvez simplement connecter un disque USB (risqué et lent cependant)!
Ensuite, montez le nouveau périphérique et rendez-le disponible en tant qu'espace disque logique:
Vous pouvez facilement répertorier les espaces disque logiques en utilisant:
\db
Revérifiez l'espace de table actuel de votre table (vous devez savoir où le déplacer):
SELECT tablespace FROM pg_tables WHERE tablename ='mytable';
Si c'est le cas NULL, ce sera dans le tablespace par défaut:
SHOW default_tablespace;
Si c'est aussi bien, il sera probablement (vérifier les documents officiels dans le cas où il a changé).NULLpg_default
Déplacez maintenant le tableau:
ALTERTABLE mytable SET TABLESPACE tempspace;COMMIT;-- if autocommit is off
Passez l'aspirateur:
VACUUM FULL mytable;
Reculez:
-- assuming you are using the defaults, the tablespace will be "pg_default".-- Otherwise use the value from the SELECT we did earlier.ALTERTABLE mytable SET TABLESPACE pg_default;COMMIT;-- if autocommit is off
NB: le déplacement semble utiliser plus d'espace disque dans le répertoire de données d'origine ...
Chris Withers
Je viens de le tester sur 9.3 et cela fonctionne comme un charme.
Bartek Jablonski
Utilisé avec succès en production le 9.1. Après avoir changé l'espace disque logique, l'espace utilisé d'origine est libéré. Notez qu'une charge CPU élevée due aux opérations d'E / S peut être attendue.
erny
2
Des conseils incroyables, merci pour cette explication détaillée. Notez que sur l'espace table temporaire, vous aurez besoin d'au moins size of table x 2, car il VACUUM FULLs'agit de faire une copie complète de la table.
Stéphane
Merci @ Stéphane. J'ai ajouté les informations au corps principal.
exhuma
2
Rapide et sale:
Arrêtez Postgres
Déplacez le répertoire de la base de données principale vers un autre disque où il y a suffisamment de place pour passer l'aspirateur
À l'emplacement d'origine de main, ajoutez un lien symbolique vers le nouvel emplacement
Vide
Supprimez le lien symbolique et ramenez le répertoire principal à son emplacement d'origine
Si vous disposez de l'espace disque pour effectuer un vidage et une restauration, vous devez disposer de l'espace disque pour effectuer un vacuumdb --full. Le problème est que vacuumdb --full fera une copie de tout le fichier de données. Donc, ce que vous pourriez faire, c'est:
copiez les fichiers qui contiennent l'énorme table sur un autre lecteur, par exemple un lecteur plus lent et plus gros.
créer des liens symboliques entre l'emplacement d'origine et le nouvel emplacement sur l'autre lecteur.
exécutez vacuumdb --full, maintenant il devrait lire les données de l'autre disque et écrire la table finale sur votre disque de données d'origine.
gzip
partie pour gagner du temps.REMARQUE: j'ai testé cela sur 9.1. Je n'ai pas de serveur 9.0 qui traîne ici. Je suis sûr que cela fonctionnera bien sur 9.0.
ATTENTION (comme indiqué dans les commentaires de @erny):
Vous pouvez le faire sans pratiquement aucun temps d'arrêt en utilisant un espace de table temporaire. Le temps d'arrêt sera sous la forme de verrous exclusifs. Mais seulement sur la table, vous passez l'aspirateur. Donc, tout ce qui se passera, c'est que les requêtes des clients attendront simplement que le verrou soit acquis s'ils accèdent à la table en question. Vous n'avez pas besoin de fermer les connexions existantes.
Une chose à savoir cependant, c'est que le déplacement de la table et le vide complet devront eux-mêmes attendre d'abord un verrou exclusif!
Tout d'abord, vous avez évidemment besoin de stockage supplémentaire. Comme
Stéphane
mentionné dans les commentaires, celui-ci doit être au moins deux fois plus grand que le tableau en question comme leVACUUM FULL
fait une copie complète. Si vous êtes chanceux et pouvez ajouter dynamiquement un disque à la machine, faites-le. Dans le pire des cas, vous pouvez simplement connecter un disque USB (risqué et lent cependant)!Ensuite, montez le nouveau périphérique et rendez-le disponible en tant qu'espace disque logique:
Vous pouvez facilement répertorier les espaces disque logiques en utilisant:
Revérifiez l'espace de table actuel de votre table (vous devez savoir où le déplacer):
Si c'est le cas
NULL
, ce sera dans le tablespace par défaut:Si c'est aussi bien, il sera probablement (vérifier les documents officiels dans le cas où il a changé).
NULL
pg_default
Déplacez maintenant le tableau:
Passez l'aspirateur:
Reculez:
Supprimez l'espace temporaire:
la source
size of table x 2
, car ilVACUUM FULL
s'agit de faire une copie complète de la table.Rapide et sale:
Par exemple,:
$ service postgresql stop $ mv /var/lib/postgresql/9.5/main /mnt/bigdisk $ ln -sr /mnt/bigdisk/main /var/lib/postgresql/9.5 $ vacuumdb --all --full $ rm /var/lib/postgresql/9.5/main $ mv /mnt/bigdisk/main /var/lib/postgresql/9.5 $ service postgresql start
la source
Si vous disposez de l'espace disque pour effectuer un vidage et une restauration, vous devez disposer de l'espace disque pour effectuer un vacuumdb --full. Le problème est que vacuumdb --full fera une copie de tout le fichier de données. Donc, ce que vous pourriez faire, c'est:
la source