Dans PostgreSQL, de nombreuses commandes DDL peuvent prendre très longtemps à s'exécuter. PostgreSQL a la capacité de signaler la progression des commandes DDL pendant l'exécution de la commande. Depuis PostgreSQL 9.6, il est possible de surveiller la progression de l'exécution de VACUUM manuel et d'autovacuum à l'aide d'un catalogue système dédié (appelé pg_stat_progress_vacuum).
PostgreSQL 12 a ajouté la prise en charge de la surveillance de la progression de quelques commandes supplémentaires telles que CLUSTER, VACUUM FULL, CREATE INDEX et REINDEX.
Actuellement, la fonction de rapport de progression n'est disponible que pour la commande ci-dessous.
- Commande VACUUM
- Commande CLUSTER
- Commande VACUUM FULL
- Commande CREATE INDEX
- Commande REINDEX
Pourquoi la fonctionnalité de rapport de progression dans PostgreSQL est-elle importante ?
Cette fonctionnalité est très importante pour les opérateurs lorsqu'ils effectuent des opérations de longue durée, car il est possible de ne pas attendre aveuglément qu'une opération se termine.
Il s'agit d'une fonctionnalité très utile pour obtenir des informations telles que :
- Combien de travail total il y a
- Combien de travail déjà effectué
La fonction de rapport de progression est également utile lors de l'analyse de la charge de travail des performances, cela s'avère également utile pour évaluer le traitement des tâches VACUUM pour régler les paramètres au niveau du système ou le niveau de relation une fois en fonction du modèle de charge.
Commandes prises en charge et catalogue système
Commande DDL | Catalogue système | Version PostgreSQL prise en charge |
VIDE | pg_stat_progress_vacuum | 9.6 |
VIDE PLEIN | pg_stat_progress_cluster | 12 |
CLUSTER | pg_stat_progress_cluster | 12 |
CRÉER UN INDEX | pg_stat_progress_create_index | 12 |
REINDEX | pg_stat_progress_create_index | 12 |
Comment surveiller la progression de la commande VACUUM
Chaque fois que la commande VACUUM est en cours d'exécution, la vue pg_stat_progress_vacuum contiendra une ligne pour chaque backend (y compris les processus de travail autovacuum) qui effectue actuellement un aspirateur. La vue permettant de vérifier la progression de l'exécution des commandes VACUUM et VACCUM FULL est différente car les phases de fonctionnement des deux commandes sont différentes.
Phases de fonctionnement de la commande VACUUM
- Initialisation
- Analyse du tas
- Nettoyage des index
- Aspirer le tas
- Nettoyage des index
- Tronquer le tas
- Effectuer le nettoyage final
Cette vue est disponible dans PostgreSQL 12 qui donne les informations suivantes :
postgres=# \d pg_stat_progress_vacuum ;
View "pg_catalog.pg_stat_progress_vacuum"
Column | Type | Collation | Nullable | Default
--------------------+---------+-----------+----------+---------
pid | integer | | |
datid | oid | | |
datname | name | | |
relid | oid | | |
phase | text | | |
heap_blks_total | bigint | | |
heap_blks_scanned | bigint | | |
heap_blks_vacuumed | bigint | | |
index_vacuum_count | bigint | | |
max_dead_tuples | bigint | | |
num_dead_tuples | bigint | | |
Exemple :
postgres=# create table test ( a int, b varchar(40), c timestamp );
CREATE TABLE
postgres=# insert into test ( a, b, c ) select aa, bb, cc from generate_series(1,10000000) aa, md5(aa::varchar) bb, now() cc;
INSERT 0 10000000
postgres=# DELETE FROM test WHERE mod(a,6) = 0;
DELETE 1666666
Session 1 :
postgres=# vacuum verbose test;
[. . . waits for completion . . .]
Séance 2 :
postgres=# select * from pg_stat_progress_vacuum;
-[ RECORD 1 ]------+--------------
pid | 22800
datid | 14187
datname | postgres
relid | 16388
phase | scanning heap
heap_blks_total | 93458
heap_blks_scanned | 80068
heap_blks_vacuumed | 80067
index_vacuum_count | 0
max_dead_tuples | 291
num_dead_tuples | 18
Rapport de progression pour CLUSTER et VACUUM FULL
Les commandes CLUSTER et VACUUM FULL utilisent les mêmes chemins de code pour la réécriture de la relation, vous pouvez donc vérifier la progression des deux commandes à l'aide de la vue pg_stat_progress_cluster.
Cette vue est disponible dans PostgreSQL 12 et affiche les informations suivantes :
postgres=# \d pg_stat_progress_cluster
View "pg_catalog.pg_stat_progress_cluster"
Column | Type | Collation | Nullable | Default
---------------------+---------+-----------+----------+---------
pid | integer | | |
datid | oid | | |
datname | name | | |
relid | oid | | |
command | text | | |
phase | text | | |
cluster_index_relid | bigint | | |
heap_tuples_scanned | bigint | | |
heap_tuples_written | bigint | | |
heap_blks_total | bigint | | |
heap_blks_scanned | bigint | | |
index_rebuild_count | bigint | | |
Phases de fonctionnement de la commande CLUSTER
- Initialisation
- Tas d'analyse Seq
- Tas d'analyse d'index
- Trier les tuples
- Écriture d'un nouveau tas
- Permuter les fichiers de relation
- Reconstruction de l'index
- Effectuer le nettoyage final
Exemple :
postgres=# create table test as select a,md5(a::text) as txt, now() as date from generate_series(1,3000000) a;
SELECT 3000000
postgres=# create index idx1 on test(a);
CREATE INDEX
postgres=# create index idx2 on test(txt);
CREATE INDEX
postgres=# create index idx3 on test(date);
CREATE INDEX
Now execute the CLUSTER table command and see the progress in pg_stat_progress_cluster.
Session 1 :
postgres=# cluster verbose test using idx1;
[. . . waits for completion . . .]
Séance 2 :
postgres=# select * from pg_stat_progress_cluster;
pid | datid | datname | relid | command | phase | cluster_index_relid | heap_tuples_scanned | heap_tuples_written | heap_blks_total | heap_blks_scanned | index_rebuild_count
------+-------+----------+-------+---------+------------------+---------------------+---------------------+---------------------+-----------------+-------------------+---------------------
1273 | 13586 | postgres | 15672 | CLUSTER | rebuilding index | 15680 | 3000000 | 3000000 | 0 | 0 | 2
(1 row)
Rapport d'avancement pour CREATE INDEX et REINDEX
Chaque fois que la commande CREATE INDEX ou REINDEX est en cours d'exécution, la vue pg_stat_progress_create_index contiendra une ligne pour chaque backend qui crée actuellement des index. La fonction de rapport de progression permet également de suivre les variantes CONCURRENTLY de CREATE INDEX et REINDEX. Les phases d'exécution internes des commandes CREATE INDEX et REINDEX sont les mêmes, vous pouvez donc vérifier la progression des deux commandes à l'aide de la même vue.
postgres=# \d pg_stat_progress_create_index
View "pg_catalog.pg_stat_progress_create_index"
Column | Type | Collation | Nullable | Default
--------------------+---------+-----------+----------+---------
pid | integer | | |
datid | oid | | |
datname | name | | |
relid | oid | | |
phase | text | | |
lockers_total | bigint | | |
lockers_done | bigint | | |
current_locker_pid | bigint | | |
blocks_total | bigint | | |
blocks_done | bigint | | |
tuples_total | bigint | | |
tuples_done | bigint | | |
partitions_total | bigint | | |
partitions_done | bigint | | |
Phases de fonctionnement de CREATE INDEX / REINDEX
- Initialisation
- Attendre les rédacteurs avant la construction
- Index des bâtiments
- Attente des rédacteurs avant validation
- Validation de l'index :analyse de l'index
- Validation de l'index :tri des tuples
- Validation d'index :table de balayage
- En attente des anciens instantanés
- Attendre les lecteurs avant de marquer comme mort
- Attendre les lecteurs avant de déposer
Exemple :
postgres=# create table test ( a int, b varchar(40), c timestamp );
CREATE TABLE
postgres=# insert into test ( a, b, c ) select aa, bb, cc from generate_series(1,10000000) aa, md5(aa::varchar) bb, now() cc;
INSERT 0 10000000
postgres=# CREATE INDEX idx ON test (b);
CREATE INDEX
Session 1 :
postgres=# CREATE INDEX idx ON test (b);
[. . . waits for completion . . .]
Séance 2 :
postgres=# SELECT * FROM pg_stat_progress_create_index;
-[ RECORD 1 ]------+-------------------------------
pid | 19432
datid | 14187
datname | postgres
relid | 16405
index_relid | 0
command | CREATE INDEX
phase | building index: scanning table
lockers_total | 0
lockers_done | 0
current_locker_pid | 0
blocks_total | 93458
blocks_done | 46047
tuples_total | 0
tuples_done | 0
partitions_total | 0
partitions_done | 0
postgres=# SELECT * FROM pg_stat_progress_create_index;
-[ RECORD 1 ]------+---------------------------------------
pid | 19432
datid | 14187
datname | postgres
relid | 16405
index_relid | 0
command | CREATE INDEX
phase | building index: loading tuples in tree
lockers_total | 0
lockers_done | 0
current_locker_pid | 0
blocks_total | 0
blocks_done | 0
tuples_total | 10000000
tuples_done | 4346240
partitions_total | 0
partitions_done | 0
Conclusion
PostgreSQL version 9.6 et ultérieure a la capacité de signaler la progression de certaines commandes pendant l'exécution de la commande. C'est une fonctionnalité vraiment intéressante pour les DBA, les développeurs et les utilisateurs pour vérifier la progression des commandes de longue durée. Cette capacité de rapport peut s'étendre à d'autres commandes à l'avenir. Vous pouvez en savoir plus sur cette nouvelle fonctionnalité dans la documentation PostgreSQL.