En PostgreSQL, muchos comandos DDL pueden tardar mucho tiempo en ejecutarse. PostgreSQL tiene la capacidad de informar el progreso de los comandos DDL durante la ejecución del comando. Desde PostgreSQL 9.6, ha sido posible monitorear el progreso de ejecutar VACUUM manual y autovacuum usando un catálogo de sistema dedicado (llamado pg_stat_progress_vacuum).
PostgreSQL 12 ha agregado soporte para monitorear el progreso de algunos comandos más como CLUSTER, VACUUM FULL, CREATE INDEX y REINDEX.
Actualmente, la función de informe de progreso está disponible solo para los comandos que se muestran a continuación.
- comando VACÍO
- comando CLUSTER
- comando VACÍO COMPLETO
- Comando CREAR ÍNDICE
- Comando REINDEX
¿Por qué es importante la función de informes de progreso en PostgreSQL?
Esta función es muy importante para los operadores cuando realizan operaciones de larga duración, ya que es posible no esperar ciegamente a que finalice una operación.
Esta es una función muy útil para obtener información como:
- Cuánto trabajo total hay
- Cuánto trabajo ya se ha realizado
La función de informes de progreso también es útil cuando se realiza un análisis de la carga de trabajo de rendimiento; también está demostrando ser útil para evaluar el procesamiento de trabajos VACUUM para ajustar los parámetros a nivel del sistema o el nivel de relación una vez, según el patrón de carga.
Comandos compatibles y catálogo del sistema
Comando DDL | Catálogo del sistema | Versión de PostgreSQL admitida |
VACÍO | pg_stat_progress_vacuum | 9.6 |
VACÍO LLENO | pg_stat_progress_cluster | 12 |
GRUPO | pg_stat_progress_cluster | 12 |
CREAR ÍNDICE | pg_stat_progress_create_index | 12 |
REINDEX | pg_stat_progress_create_index | 12 |
Cómo monitorear el progreso del comando VACUUM
Siempre que se ejecute el comando VACUUM, la vista pg_stat_progress_vacuum contendrá una fila para cada backend (incluidos los procesos de trabajo de autovacuum) que se está aspirando actualmente. La vista para verificar el progreso de la ejecución de los comandos VACUUM y VACCUM FULL es diferente porque las fases de operación de ambos comandos son diferentes.
Fases de funcionamiento del Comando VACUUM
- Inicializando
- Montón de exploración
- Vacío de índices
- Aspirando montón
- Limpieza de índices
- Montón truncado
- Realizando la limpieza final
Esta vista está disponible en PostgreSQL 12 que brinda la siguiente información:
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 | | |
Ejemplo:
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
Sesión 1:
postgres=# vacuum verbose test;
[. . . waits for completion . . .]
Sesión 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
Informes de progreso para CLUSTER y VACUUM FULL
Los comandos CLUSTER y VACUUM FULL usan las mismas rutas de código para la reescritura de la relación, por lo que puede verificar el progreso de ambos comandos usando la vista pg_stat_progress_cluster.
Esta vista está disponible en PostgreSQL 12 y muestra la siguiente información:
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 | | |
Fases de Operación del Comando CLUSTER
- Inicializando
- Montón de análisis de secuencias
- Montón de escaneo de índice
- Ordenar tuplas
- Escribiendo nuevo montón
- Intercambio de archivos de relación
- Índice de reconstrucción
- Realizando la limpieza final
Ejemplo:
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.
Sesión 1:
postgres=# cluster verbose test using idx1;
[. . . waits for completion . . .]
Sesión 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)
Informes de progreso para CREATE INDEX y REINDEX
Siempre que se ejecute el comando CREATE INDEX o REINDEX, la vista pg_stat_progress_create_index contendrá una fila para cada backend que esté creando índices actualmente. La función de informe de progreso permite realizar un seguimiento también de los tipos CONCURRENTES de CREAR ÍNDICE y REINDEXAR. Las fases de ejecución interna de los comandos CREATE INDEX y REINDEX son las mismas, por lo que puede verificar el progreso de ambos comandos usando la misma vista.
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 | | |
Fases de operación de CREATE INDEX / REINDEX
- Inicializando
- Esperando a los escritores antes de compilar
- Índice de construcción
- Esperando a los escritores antes de la validación
- Validación de índice:índice de escaneo
- Validación de índice:clasificación de tuplas
- Validación de índice:tabla de exploración
- Esperando instantáneas antiguas
- Esperando lectores antes de marcar muerto
- Esperando a los lectores antes de abandonar
Ejemplo:
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
Sesión 1:
postgres=# CREATE INDEX idx ON test (b);
[. . . waits for completion . . .]
Sesión 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
Conclusión
PostgreSQL versión 9.6 en adelante tiene la capacidad de informar el progreso de ciertos comandos durante la ejecución del comando. Esta es una característica muy buena para que los administradores de bases de datos, los desarrolladores y los usuarios verifiquen el progreso de los comandos de ejecución prolongada. Esta capacidad de generación de informes puede extenderse a otros comandos en el futuro. Puede leer más sobre esta nueva característica en la documentación de PostgreSQL.