web-dev-qa-db-fra.com

Combien de temps prendra une opération de vide / autovacuum?

Je gère une grande base de données (quelques centaines de concerts) contenant des tables avec différents rôles, certains d'entre eux détenant des millions d'enregistrements. Certaines tables ne reçoivent qu'un grand nombre d'insertions et de suppressions, d'autres quelques insertions et un grand nombre de mises à jour.

La base de données fonctionne sur PostgreSQL 8.4 sur un système Debian 6.0 AMD64 avec 16 gigaoctets de RAM.

La question est parfois le processus de vide automatique sur une table, prend beaucoup de temps (jours) pour terminer. Je veux pouvoir dire approximativement combien de temps une commande de vide particulière prendra, pour pouvoir décider de l'annuler ou non. De plus, s'il y avait un indicateur de progrès pour les opérations de vide postgres, ce serait vraiment utile.

Éditer:

Je ne cherche pas de solution pare-balles. Une simple indication approximative du nombre de tuples morts ou d'octets d'E/S nécessaires suffit pour décider. C'est vraiment ennuyeux de n'avoir aucune idée quand VACUUM se terminera, que ce soit.

J'ai vu ça pg_catalog.pg_stat_all_tables a une colonne pour le nombre de tuples morts. Il est donc possible d'avoir une estimation, même si cela signifie qu'il faut ANALYZE la table avant. D'autre part, autovacuum_vacuum_threshold et autovacuum_vacuum_scale_factor seuls les paramètres prouvent que postgres lui-même sait quelque chose sur la quantité de changement sur les tables et le met probablement entre les mains du DBA aussi.

Je ne sais pas quelle requête exécuter, car lorsque j'exécute VACUUM VERBOSE, Je constate que non seulement les tables, mais aussi les index sur celles-ci sont en cours de traitement.

18
zaadeh

Sur mon PostgreSQL (8.3) j'utilise cette astuce:

  1. J'obtiens la taille du disque de la table en utilisant pg_total_relation_size() - cela inclut les index et la taille de TOAST, qui est ce que VACUUM traite. Cela me donne une idée du nombre d'octets que le VACUUM doit lire.
  2. Je lance VACUUM sur la table.
  3. Je trouve le pid du processus VACUUM (dans pg_catalog.pg_stat_activity).
  4. Dans Linux Shell, je lance while true; do cat /proc/123/io | grep read_bytes; sleep 60; done (où 123 est le pid) - cela me montre les octets lus par le processus à partir du disque jusqu'à présent.

Cela me donne une idée approximative du nombre d'octets traités (lus) chaque minute par le VACUUM. Je suppose que le VACUUM doit lire toute la table (y compris les index et TOAST), dont je connais la taille du disque à l'étape 1.

Je suppose que la table est suffisamment grande pour que la majorité de ses pages doivent être lues à partir du disque (elles ne sont pas présentes dans la mémoire partagée de Postgres), donc le read_bytes est assez bon pour être utilisé comme compteur de progression.

Chaque fois que je faisais cela, le nombre total d'octets lus par le processus ne dépassait pas 5% de la taille totale de la relation, donc je suppose que cette approche peut être assez bonne pour vous.

35
Roman Hocke

C'est très difficile à déterminer. Vous pouvez régler le vide automatique pour être plus agressif ou pour être plus doux. Mais lorsqu'il est réglé sur doux et qu'il est à la traîne et que la charge d'E/S de base est trop élevée, il peut arriver qu'il n'atteigne jamais un état de vide approprié - alors vous voyez le processus en cours d'exécution et en cours d'exécution. De plus, les éditions ultérieures de PostreSQL ont des capacités d'autovacuum bien améliorées, cela seul peut suffire pour passer à l'une d'entre elles (de préférence 9.2 comme la plus récente).

La barre de progression semble une bonne idée, mais j'imagine que ce n'est pas si facile à mettre en œuvre de manière significative. Comme vous avez une charge constante sur vos tables, il est tout à fait possible que la progression recule apparemment (je veux dire que le nombre/pourcentage de lignes mortes augmente au lieu de diminuer) - alors quelle conclusion tirez-vous?

9
dezso

J'ai trouvé cet article et cet article utiles, mais comme d'autres l'ont mentionné, il peut être difficile de calculer la progression globale du vide, car le processus implique quelques opérations distinctes.

J'utilise cette requête pour surveiller la progression de l'analyse de la table de vide, qui semble être la majeure partie du travail:

SELECT heap_blks_scanned/cast(heap_blks_total as numeric)*100 as heap_blks_percent, progress.*, activity.query
FROM pg_stat_progress_vacuum AS progress
INNER JOIN pg_stat_activity AS activity ON activity.pid = progress.pid;

Cependant, cela n'inclura pas l'analyse d'index, qui se produit ensuite, et peut prendre autant de temps, sinon plus, si vous avez une tonne d'index. Malheureusement, je ne trouve aucun moyen de surveiller le balayage/la mise sous vide de l'index.

4
Cerin

Dans notre production, l'une des plus grandes tables avait ce journal:

pages: 0 removed, 1801722 remain
tuples: 238912 removed, 42582083 remain, 1396 are dead but not yet removable
buffer usage: 9477565 hits, 3834218 misses, 2220101 dirtied
avg read rate: 2.976 MB/s, avg write rate: 1.723 MB/s
system usage: CPU 68.47s/177.49u sec elapsed 10065.08 sec

C'est de loin la pire consommation de ressources, toutes les autres tables ont pris moins de 2 s.

Pour voir ces types de journaux, vous devez exécuter ceci:

alter system set log_autovacuum_min_duration TO 5; 

(pendant 5 ms), rechargez le fichier de configuration.

3
stonelazy