Différence PostgreSQL entre VACUUM FULL et CLUSTER

13

J'ai une table avec 200 Go de taille occupée par les données et 180 Go de taille par les 6 index dessus. Il est gonflé à 30%, donc je veux récupérer l'espace indésirable qu'il occupe. Il est regroupé sur un job_id_idindex x.

Donc, pour récupérer l'espace, dois-je utiliser la clustercommande ou la vacuum fullcommande?

  1. Quelle est la différence entre ces deux commandes?

  2. L' vacuum fullordre par colonne est-il identique à la clustercommande?

  3. L'index est-il recréé dans les deux commandes?

  4. Dans mon cas, lequel sera le plus rapide?

La version de la base de données PostgreSQL est la 9.1

Arun P
la source
1
Oui, les index seront recréés. Ce qui est plus rapide dépend de quelques choses, j'imagine. Mais une chose est sûre: il n'y a rien de tel que «passer l'aspirateur dans une colonne».
dezso
1
Permettez-moi également de mentionner que VACUUM ne peut pas s'exécuter dans une transaction, ce qui dans de nombreux cas fait de CLUSTER une meilleure alternative (et parfois la seule alternative) qui produit des résultats similaires.
2015

Réponses:

8

Pour vérifier ce qui se CLUSTERpasse, j'ai pris un tableau pour le mien d'une expérience antérieure qui contenait essentiellement les 10 premiers millions d'entiers positifs. J'ai déjà supprimé certaines lignes et il y a une autre colonne également, mais celles-ci n'affectent que la taille réelle du tableau, donc ce n'est pas si intéressant.

D'abord, ayant couru VACUUM FULLsur la table fka, j'ai pris sa taille:

\dt+ fka
                    List of relations
 Schema | Name | Type  |  Owner   |  Size  | Description 
--------+------+-------+----------+--------+-------------
 public | fka  | table | test     | 338 MB | 

Voyons ensuite l'ordre physique des données depuis le tout début du tableau:

SELECT *, ctid FROM fka ORDER BY ctid LIMIT 5;

 id  | col1 |  ctid   
-----+------+---------
   2 | 2    | (0,1)
   3 | 3    | (0,2)
   4 | 4    | (0,3)
   5 | 5    | (0,4)
   6 | 6    | (0,5)

Supprimons maintenant quelques lignes:

DELETE FROM fka WHERE id % 10 = 5;
--DELETE 1000000

Après cela, la taille du tableau signalée n'a pas changé. Voyons maintenant ce qui CLUSTERfait:

CLUSTER fka USING fka_pkey;

SELECT *, ctid FROM fka ORDER BY ctid LIMIT 5;

 id  | col1 |  ctid   
-----+------+---------
   2 | 2    | (0,1)
   3 | 3    | (0,2)
   4 | 4    | (0,3)
   6 | 6    | (0,4)
   7 | 7    | (0,5)

Après l'opération, la taille de la table est passée de 338 à 296 Mo. Dans la ctidcolonne, qui décrit l'emplacement physique du tuple dans la page, vous voyez également qu'il n'y a pas d'espace où se trouvait la correspondance de ligne id = 5.

Comme les tuples ont été réorganisés, les index auraient dû être recréés afin qu'ils pointent vers les bons endroits.

La différence semble donc VACUUM FULLne pas ordonner les lignes. Pour autant que je sache, il existe une certaine différence dans le mécanisme utilisé par les deux commandes, mais d'un point de vue pratique, cela semble être la principale différence (seulement?).

dezso
la source
Je n'étais pas sûr de la ctidcolonne. Il s'avère que c'est une colonne système décrivant l'emplacement physique de la ligne dans sa table. postgresql.org/docs/current/ddl-system-columns.html
Gajus
8

VACUUM FULLréécrit tout le contenu de la table dans un nouveau fichier disque sans espace supplémentaire, ce qui permet de renvoyer l'espace inutilisé au système d'exploitation. 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.

http://www.postgresql.org/docs/9.1/static/sql-vacuum.html

CLUSTERindique à PostgreSQL de regrouper la table spécifiée par nom_table en fonction de l'index spécifié par nom_index. L'index doit déjà avoir été défini sur nom_table. Lorsqu'une table est mise en cluster, elle est réorganisée physiquement en fonction des informations d'index et un verrou ACCESS EXCLUSIVE y est acquis.

http://www.postgresql.org/docs/9.1/static/sql-cluster.html

aussi intéressant: is-a-reindex-required-after-cluster

Mais peut-être que tout ce dont vous avez besoin est un simple REINDEXqui reconstruit un index en utilisant les données stockées dans la table de l'index, en remplaçant l'ancienne copie de l'index.

http://www.postgresql.org/docs/9.1/static/sql-reindex.html

cptPH
la source
1
Woah! Bon conseil sur le REINDEX aussi! J'ai rétréci quelques tables à la fois par VACUUM et CLUSTER (en essayant de comparer les temps et les impacts pour le faire en direct) et maintenant mes plus gros objets sont en fait des indices.
Mike