Pour renvoyer de l'espace au système d'exploitation, utilisez VACUUM FULL
. Tout en y étant, je suppose que vous courez VACUUM FULL ANALYZE
. Je cite le manuel :
FULL
Sélectionne un vide «complet», qui peut récupérer plus d'espace , mais prend beaucoup plus de temps et verrouille exclusivement la table. Cette méthode nécessite également de l'espace disque supplémentaire, car elle écrit une nouvelle copie de la table et ne libère pas l'ancienne copie tant que l'opération n'est pas terminée. Habituellement, cela ne doit être utilisé que lorsqu'une quantité importante d'espace doit être récupérée à l'intérieur de la table.
Accentuation sur moi.
CLUSTER
y parvient également comme effet collatéral.
Plain VACUUM
n'atteint normalement pas votre objectif ( "une ou plusieurs pages à la fin d'un tableau entièrement gratuites" ). Il ne réorganise pas les lignes et n'élague que les pages vides de la fin physique du fichier lorsque l'occasion se présente - comme l'indique votre citation du manuel.
Vous pouvez obtenir des pages vides à la fin du fichier physique lorsque vous INSERT
créez un lot de lignes et DELETE
les avant d'ajouter d'autres tuples. Ou cela peut arriver par coïncidence si suffisamment de lignes sont supprimées.
Il existe également des paramètres spéciaux qui peuvent empêcher VACUUM FULL
de récupérer de l'espace. Voir:
Préparer des pages vides à la fin d'un tableau pour les tests
La colonne système ctid
représente la position physique d'une ligne. Vous devez comprendre cette colonne:
Nous pouvons travailler avec cela et préparer un tableau en supprimant toutes les lignes de la dernière page:
DELETE FROM tbl t
USING (
SELECT (split_part(ctid::text, ',', 1) || ',0)')::tid AS min_tid
, (split_part(ctid::text, ',', 1) || ',65535)')::tid AS max_tid
FROM tbl
ORDER BY ctid DESC
LIMIT 1
) d
WHERE t.ctid BETWEEN d.min_tid AND d.max_tid;
Maintenant, la dernière page est vide. Cela ignore les écritures simultanées. Soit vous êtes le seul à écrire sur cette table, soit vous devez prendre un verrou d'écriture pour éviter les interférences.
La requête est optimisée pour identifier rapidement les lignes éligibles. Le deuxième nombre de a tid
est l'index de tuple stocké comme non signé int2
, et 65535
est le maximum pour ce type ( 2^16 - 1
), c'est donc la limite supérieure sûre.
SQL Fiddle (réutilisation d'une table simple à partir d'un cas différent.)
Outils pour mesurer la taille des lignes / tables:
Disque plein
Vous avez besoin de marge de manœuvre sur le disque pour chacune de ces opérations. Il existe également l'outil communautaire pg_repack
en remplacement de VACUUM FULL
/ CLUSTER
. Il évite les verrous exclusifs mais a également besoin d'espace libre pour fonctionner. Le manuel:
Nécessite un espace disque libre deux fois plus grand que les tables et index cibles.
En dernier recours, vous pouvez exécuter un cycle de vidage / restauration. Cela supprime également tous les ballonnements des tables et des index. Question étroitement liée:
La réponse là-bas est assez radicale. Si votre situation le permet (pas de clés étrangères ou d'autres références empêchant les suppressions de lignes), et pas d'accès simultané à la table), vous pouvez simplement:
Vider la table sur le disque en se connectant à partir d'un ordinateur distant avec beaucoup d'espace disque ( -a
pour --data-only
):
Depuis le shell distant, les données de la table de vidage:
pg_dump -h <host_name> -p <port> -t mytbl -a mydb > db_mytbl.sql
Dans une session pg, TRUNCATE
le tableau:
-- drop all indexes and constraints here for best performance
TRUNCATE mytbl;
Du shell distant, restaurez dans la même table:
psql -h <host_name> -p <port> mydb -f db_mytbl.sql
-- recreate all indexes and constraints here
Il est maintenant libre de toute ligne morte ou ballonnement.
Mais peut-être pouvez-vous avoir cela plus simple?
Pouvez-vous faire suffisamment d'espace sur le disque en supprimant (déplaçant) des fichiers non liés?
Pouvez-vous d'abord VACUUM FULL
réduire les tables, une par une, libérant ainsi suffisamment d'espace disque?
Pouvez-vous exécuter REINDEX TABLE
ou REINDEX INDEX
libérer de l'espace disque à partir d'index gonflés?
Quoi que vous fassiez, ne soyez pas téméraire . En cas de doute, sauvegardez tout d'abord dans un emplacement sécurisé.