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éphane
mentionné dans les commentaires, celui-ci doit être au moins deux fois plus grand que le tableau en question comme le VACUUM 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:
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 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é).NULL
pg_default
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;