In PostgreSQL kann die Ausführung vieler DDL-Befehle sehr lange dauern. PostgreSQL kann den Fortschritt von DDL-Befehlen während der Befehlsausführung melden. Seit PostgreSQL 9.6 ist es möglich, den Fortschritt der Ausführung von manuellem VACUUM und Autovacuum mithilfe eines dedizierten Systemkatalogs (namens pg_stat_progress_vacuum) zu überwachen.
PostgreSQL 12 hat Unterstützung für die Überwachung des Fortschritts einiger weiterer Befehle wie CLUSTER, VACUUM FULL, CREATE INDEX und REINDEX hinzugefügt.
Derzeit ist die Fortschrittsberichtsfunktion nur für den folgenden Befehl verfügbar.
- VACUUM-Befehl
- CLUSTER-Befehl
- VACUUM FULL-Befehl
- CREATE INDEX-Befehl
- REINDEX-Befehl
Warum ist die Statusberichtsfunktion in PostgreSQL wichtig?
Diese Funktion ist für Operatoren sehr wichtig, wenn sie lang andauernde Operationen durchführen, da es möglich ist, nicht blind auf das Ende einer Operation zu warten.
Dies ist eine sehr nützliche Funktion, um Einblicke zu erhalten, wie zum Beispiel:
- Wie viel Arbeit es insgesamt gibt
- Wie viel Arbeit bereits geleistet wurde
Die Fortschrittsberichtsfunktion ist auch nützlich, wenn Sie eine Performance-Workload-Analyse durchführen, dies erweist sich auch als nützlich bei der Bewertung der VACUUM-Jobverarbeitung zur einmaligen Abstimmung von Parametern auf Systemebene oder der Beziehungsebene je nach Lastmuster.
Unterstützte Befehle und Systemkatalog
DDL-Befehl | Systemkatalog | Unterstützte PostgreSQL-Version |
VAKUUM | pg_stat_progress_vacuum | 9.6 |
VAKUUM VOLL | pg_stat_progress_cluster | 12 |
CLUSTER | pg_stat_progress_cluster | 12 |
INDEX ERSTELLEN | pg_stat_progress_create_index | 12 |
REINDEX | pg_stat_progress_create_index | 12 |
Wie man den Fortschritt des VACUUM-Befehls überwacht
Immer wenn der VACUUM-Befehl ausgeführt wird, enthält die pg_stat_progress_vacuum-Ansicht eine Zeile für jedes Backend (einschließlich Autovacuum-Worker-Prozesse), das gerade vakuumiert. Die Ansicht zur Überprüfung des Fortschritts der Befehle VACUUM und VACCUM FULL ist unterschiedlich, da die Betriebsphasen beider Befehle unterschiedlich sind.
Operationsphasen des VAKUUM-Befehls
- Initialisierung
- Haufen scannen
- Indizes leeren
- Haufen saugen
- Indizes bereinigen
- Haufen abschneiden
- Endbereinigung durchführen
Diese Ansicht ist in PostgreSQL 12 verfügbar, die die folgenden Informationen liefert:
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 | | |
Beispiel:
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
Sitzung 1:
postgres=# vacuum verbose test;
[. . . waits for completion . . .]
Sitzung 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
Fortschrittsbericht für CLUSTER und VACUUM FULL
CLUSTER- und VACUUM FULL-Befehl verwenden die gleichen Codepfade für das Umschreiben von Beziehungen, sodass Sie den Fortschritt beider Befehle mit der Ansicht pg_stat_progress_cluster überprüfen können.
Diese Ansicht ist in PostgreSQL 12 verfügbar und zeigt die folgenden Informationen:
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 | | |
Operationsphasen des CLUSTER-Befehls
- Initialisierung
- Seq-Scanning-Heap
- Index-Scan-Heap
- Tupel sortieren
- Neuen Heap schreiben
- Beziehungsdateien austauschen
- Index neu erstellen
- Endbereinigung durchführen
Beispiel:
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.
Sitzung 1:
postgres=# cluster verbose test using idx1;
[. . . waits for completion . . .]
Sitzung 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)
Fortschrittsbericht für CREATE INDEX und REINDEX
Wann immer der Befehl CREATE INDEX oder REINDEX ausgeführt wird, enthält die Ansicht pg_stat_progress_create_index eine Zeile für jedes Backend, das derzeit Indizes erstellt. Die Fortschrittsberichtsfunktion ermöglicht es, auch die CONCURRENTLY-Varianten von CREATE INDEX und REINDEX zu verfolgen. Die internen Ausführungsphasen der Befehle CREATE INDEX und REINDEX sind identisch, sodass Sie den Fortschritt beider Befehle in derselben Ansicht überprüfen können.
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 | | |
Operationsphasen von CREATE INDEX / REINDEX
- Initialisierung
- Warten auf Autoren vor dem Erstellen
- Gebäudeindex
- Warten auf Autoren vor Validierung
- Indexvalidierung:Index scannen
- Indexvalidierung:Sortieren von Tupeln
- Indexvalidierung:Scantabelle
- Warten auf alte Schnappschüsse
- Auf Leser warten, bevor man sie als tot markiert
- Warten auf Leser vor dem Ablegen
Beispiel:
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
Sitzung 1:
postgres=# CREATE INDEX idx ON test (b);
[. . . waits for completion . . .]
Sitzung 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
Fazit
Ab PostgreSQL-Version 9.6 kann der Fortschritt bestimmter Befehle während der Befehlsausführung gemeldet werden. Dies ist eine wirklich nette Funktion für DBAs, Entwickler und Benutzer, um den Fortschritt lang laufender Befehle zu überprüfen. Diese Berichtsfunktion kann in Zukunft für einige andere Befehle erweitert werden. Sie können mehr über diese neue Funktion in der PostgreSQL-Dokumentation lesen.