In PostgreSQL kunnen veel DDL-opdrachten erg lang duren om uit te voeren. PostgreSQL heeft de mogelijkheid om de voortgang van DDL-opdrachten te rapporteren tijdens het uitvoeren van opdrachten. Sinds PostgreSQL 9.6 is het mogelijk om de voortgang van handmatig VACUM en autovacuüm te volgen met behulp van een speciale systeemcatalogus (pg_stat_progress_vacuum genaamd).
PostgreSQL 12 heeft ondersteuning toegevoegd voor het bewaken van de voortgang van nog een paar commando's zoals CLUSTER, VACUUM FULL, CREATE INDEX en REINDEX.
Momenteel is de voortgangsrapportagefunctie alleen beschikbaar voor commando's zoals hieronder.
- VACUUM-opdracht
- CLUSTER-opdracht
- VACUUM FULL-opdracht
- CREATE INDEX-opdracht
- REINDEX-opdracht
Waarom is de functie voor voortgangsrapportage in PostgreSQL belangrijk?
Deze functie is erg belangrijk voor operators bij het uitvoeren van langlopende bewerkingen, omdat het mogelijk is om niet blindelings te wachten tot een bewerking is voltooid.
Dit is een erg handige functie om inzicht te krijgen, zoals:
- Hoeveel werk is er in totaal
- Hoeveel werk is er al gedaan
Voortgangsrapportagefunctie is ook handig bij het uitvoeren van prestatie-werkbelastinganalyse, dit blijkt ook nuttig te zijn bij het evalueren van VACUUM-taakverwerking voor het afstemmen van parameters op systeemniveau of relatieniveau eenmaal, afhankelijk van het belastingpatroon.
Ondersteunde opdrachten en systeemcatalogus
DDL-opdracht
Systeemcatalogus
Ondersteunde PostgreSQL-versie
VACUM
pg_stat_progress_vacuum
9,6
VACUM VOL
pg_stat_progress_cluster
12
CLUSTER
pg_stat_progress_cluster
12
INDEX MAKEN
pg_stat_progress_create_index
12
REINDEX
pg_stat_progress_create_index
12
De voortgang van het VACUUM-commando volgen
Telkens wanneer de opdracht VACUUM wordt uitgevoerd, bevat de weergave pg_stat_progress_vacuum één rij voor elke backend (inclusief autovacuüm-werkprocessen) die momenteel wordt gestofzuigd. De weergave om de voortgang van het uitvoeren van de opdrachten VACUUM en VACCUM FULL te controleren is anders omdat de bedieningsfasen van beide opdrachten verschillend zijn.
Bedrijfsfasen van het VACUUM-commando
- Initialiseren
- Scanhoop
- Indexen stofzuigen
- Vacuümhoop
- Indexen opschonen
- Afkappingshoop
- Laatste opruiming uitvoeren
Deze weergave is beschikbaar in PostgreSQL 12 en geeft de volgende informatie:
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 | | |
Voorbeeld:
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
Sessie 1:
postgres=# vacuum verbose test;
[. . . waits for completion . . .]
Sessie 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
Voortgangsrapportage voor CLUSTER en VACUUM FULL
CLUSTER en VACUUM FULL commando gebruiken dezelfde code paden voor het herschrijven van de relatie, dus je kunt de voortgang van beide commando's controleren met de view pg_stat_progress_cluster.
Deze weergave is beschikbaar in PostgreSQL 12 en toont de volgende informatie:
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 | | |
Operatiefasen van CLUSTER Commando
- Initialiseren
- Seq scanning heap
- Index scanning heap
- Tuples sorteren
- Nieuwe hoop schrijven
- Relatiebestanden uitwisselen
- Index opnieuw opbouwen
- Laatste opruiming uitvoeren
Voorbeeld:
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.
Sessie 1:
postgres=# cluster verbose test using idx1;
[. . . waits for completion . . .]
Sessie 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)
Voortgangsrapportage voor CREATE INDEX en REINDEX
Wanneer de opdracht CREATE INDEX of REINDEX wordt uitgevoerd, bevat de weergave pg_stat_progress_create_index één rij voor elke backend die momenteel indexen maakt. De voortgangsrapportagefunctie maakt het mogelijk om ook de GELIJKTIJDIG smaken van CREATE INDEX en REINDEX te volgen. De interne uitvoeringsfasen van de opdrachten CREATE INDEX en REINDEX zijn hetzelfde, dus u kunt de voortgang van beide opdrachten met dezelfde weergave controleren.
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 | | |
Operatiefasen van CREATE INDEX / REINDEX
- Initialiseren
- Wachten op schrijvers voor het bouwen
- Bouwindex
- Wachten op schrijvers voor validatie
- Indexvalidatie:scanindex
- Indexvalidatie:tupels sorteren
- Indexvalidatie:scantabel
- Wachten op oude snapshots
- Wachten op lezers voordat hij dood markeert
- Wachten op lezers alvorens te laten vallen
Voorbeeld:
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
Sessie 1:
postgres=# CREATE INDEX idx ON test (b);
[. . . waits for completion . . .]
Sessie 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
Conclusie
PostgreSQL vanaf versie 9.6 heeft de mogelijkheid om de voortgang van bepaalde opdrachten te rapporteren tijdens het uitvoeren van opdrachten. Dit is echt een leuke functie voor DBA's, ontwikkelaars en gebruikers om de voortgang van langlopende opdrachten te controleren. Deze rapportagemogelijkheid kan in de toekomst voor sommige andere opdrachten worden uitgebreid. U kunt meer lezen over deze nieuwe functie in de PostgreSQL-documentatie.