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

18

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 de quand VACUUMse terminera, que ce soit.

J'ai vu qu'il y pg_catalog.pg_stat_all_tablesavait une colonne pour le nombre de tuples morts. Il est donc possible d'avoir une estimation, même si cela signifie qu'il faut ANALYZEavant le tableau. D'un autre côté, autovacuum_vacuum_thresholdet les autovacuum_vacuum_scale_factorparamètres seuls 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 je lance VACUUM VERBOSE, je vois que non seulement les tables, mais les index sur celles-ci sont également traités.

zaadeh
la source

Réponses:

34

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 les VACUUMprocessus. Cela me donne une idée du nombre d'octets VACUUMà lire.
  2. Je cours VACUUMsur la table.
  3. Je trouve le piddu VACUUMprocessus (en pg_catalog.pg_stat_activity).
  4. Dans le shell Linux, je lance while true; do cat /proc/123/io | grep read_bytes; sleep 60; done(où 123est 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 VACUUMdoit 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 soient lues sur le disque (elles ne sont pas présentes dans la mémoire partagée de Postgres), donc le read_byteschamp 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.

Roman Hocke
la source
Nasty :) Est-ce que cela fonctionne aussi pour les versions ultérieures? Et, plus important encore, pour l'autovacuum?
dezso
Je ne l'ai pas essayé pour les versions plus récentes. Il devrait fonctionner VACUUM FULLsur 9.0+, car il réécrit complètement la table. Cela devrait aussi fonctionner régulièrement VACUUM, mais je ne l'ai pas encore testé. Car autovacuumcela fonctionnerait si vous pouviez attraper le processus de travail de l'autovacuum sur une table donnée, mais je ne sais pas comment y parvenir.
Roman Hocke
Avez-vous des suggestions pour y parvenir avec RDS? Naturellement, nous n'avons pas accès à un shell Linux lors de l'utilisation de RDS, mais nous aimerions beaucoup pouvoir l'estimer également.
jwg2s
@ jwg2s Que voulez-vous dire par "RDS", s'il vous plaît? Les services de base de données d'Amazon? Si c'est le cas, je ne le connais malheureusement pas :-( Peut-être que leur soutien serait utile.
Roman Hocke
1
Semble bien fonctionner sur PG 10 avec un vide plein également.
DylanYoung du
9

C'est très difficile à déterminer. Vous pouvez régler la purge automatique pour être plus agressif ou 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 nettement 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?

dezso
la source
2
Je préfère voir une sorte d'indicateur de progrès, même s'il recule, plutôt que rien.
zaadeh
3
VACUUM ANALYZE VERBOSEimprime au moins une certaine activité sur la console comme il le fait. Il vaut mieux alors juste regarder une invite statique se demandant si quelque chose est coincé pendant des heures.
Fake Name
La question porte sur "vide / autovacuum". Ce qui précède n'est utile que pour VACUUM, pas l'autovacuum, mais c'est toujours quelque chose.
Fake Name
@FakeName Eh, j'ai mal lu la question - j'ai raté la partie vide manuelle. Désolé, je supprime mon commentaire.
dezso
3

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.

stonelazy
la source
3

J'ai trouvé ce post et ce post utile, 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.

Cerin
la source