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 je me suis dit que c'était la meilleure option dans ce scénario.
Toute idée serait appréciée.
J'utilise PostgreSQL 9.0.6
Comme 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
2 Sauvegardez vos fichiers de configuration
cp /path/to/postgresql/data_directory/*.conf /some/partition/
Stop Postgresql
pg_ctl -D /path/to/postgresql/data_directory stop
4 efface le contenu du répertoire de données
rm -Rf /path/to/postgresql/data_directory/*
5 Exécutez initdb pour réinitialiser votre répertoire de données
initdb -D /path/to/postgresql/data_directory
6 Restaurer les fichiers de configuration
cp /some/partition/*.conf /path/to/postgresql/data_directory/*.conf
7 Démarrer Postgresql
pg_ctl -D /path/to/postgresql/data_directory start
8 Restaurez le vidage de toutes les bases de données que vous avez créées
gunzip /some/partition/all.dbs.out.gz
psql -f /some/partition/all.dbs.out
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.
[~ # ~] prudence [~ # ~] (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 si 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
mentionne dans les commentaires, cela doit être au moins deux fois plus grand que le tableau en question que VACUUM FULL
fait une copie complète. Si vous êtes chanceux et pouvez ajouter dynamiquement un disque à la machine, faites-le. Dans le cas pire 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:
CREATE TABLESPACE tempspace LOCATION '/path/to/new/folder';
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 NULL
, ce sera dans le tablespace par défaut:
SHOW default_tablespace;
Si ça est également NULL
, ce sera probablement pg_default
(vérifiez les documents officiels au cas où cela changerait).
Déplacez maintenant le tableau:
ALTER TABLE 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.
ALTER TABLE mytable SET TABLESPACE pg_default;
COMMIT; -- if autocommit is off
Supprimez l'espace temporaire:
DROP TABLESPACE tempspace;
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
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: