VACUUM renvoyant de l'espace disque au système d'exploitation


21

VACUUMne renvoie généralement pas d'espace disque au système d'exploitation, sauf dans certains cas particuliers.
De la documentation:

La forme standard de VACUUMsupprime les versions de lignes mortes dans les tables et les index et marque l'espace disponible pour une réutilisation future. Cependant, il ne restituera pas l'espace au système d'exploitation, sauf dans le cas spécial où une ou plusieurs pages à la fin d'une table deviennent entièrement libres et un verrou de table exclusif peut être facilement obtenu. En revanche, VACUUM FULLcompacte activement les tables en écrivant une nouvelle version complète du fichier de table sans espace mort. Cela minimise la taille de la table, mais peut prendre beaucoup de temps. Il nécessite également de l'espace disque supplémentaire pour la nouvelle copie de la table, jusqu'à la fin de l'opération.

La question est: comment cette base de données peut-elle indiquer quand elle one or more pages at the end of a table become entirely freesera réalisée? Cela peut être fait via VACUUM FULL, mais je n'ai pas assez d'espace pour l'implémenter. Y a-t-il donc d'autres possibilités?

Réponses:


29

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 VACUUMn'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 INSERTcréez un lot de lignes et DELETEles 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 FULLde récupérer de l'espace. Voir:

Préparer des pages vides à la fin d'un tableau pour les tests

La colonne système ctidrepré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 tidest l'index de tuple stocké comme non signé int2, et 65535est 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_repacken 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 ( -apour --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, TRUNCATEle 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 FULLréduire les tables, une par une, libérant ainsi suffisamment d'espace disque?

  • Pouvez-vous exécuter REINDEX TABLEou REINDEX INDEXlibé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é.


Erwin, désolé, j'ai oublié de mentionner que je n'ai pas assez d'espace pour passer l'aspirateur. Mis à jour la question.
faux-tout-

@Zapadlo: J'ai ajouté un chapitre pour la question mise à jour.
Erwin Brandstetter

Merci pour la réponse complète. En fait, je pensais que je pouvais placer des lignes mortes à la fin des pages de base de données par de fausses mises à jour, c'est update table set field_1 = field_1-à- dire , mais le fait de passer l'aspirateur sur cette table après que cette opération n'ait pas renvoyé d'espace libre, des idées?
faux-tout-

@Zapadlo: Les idées que j'ai eues sont déjà dans la réponse. :) Je ne connais pas d'outil qui puisse réorganiser les tuples morts sans avoir besoin de beaucoup de marge de manœuvre sur le disque. (Cela ne veut pas dire qu'il ne peut y en avoir un.)
Erwin Brandstetter

Ils disent que cet outil fait l'affaire, mais ne l'ont pas encore essayé: code.google.com/p/pgtoolkit/source/browse/trunk/bin/…
-about-everything
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.