V PostgreSQL může provedení mnoha příkazů DDL trvat velmi dlouho. PostgreSQL má schopnost hlásit průběh příkazů DDL během provádění příkazů. Od PostgreSQL 9.6 bylo možné sledovat průběh manuálního VACUUM a autovakua pomocí vyhrazeného systémového katalogu (nazývaného pg_stat_progress_vacuum).
PostgreSQL 12 přidal podporu pro sledování průběhu několika dalších příkazů, jako je CLUSTER, VACUUM FULL, CREATE INDEX a REINDEX.
V současné době je možnost hlášení průběhu k dispozici pouze pro příkazy, jak je uvedeno níže.
- Příkaz VACUUM
- příkaz CLUSTER
- Příkaz VACUUM FULL
- Příkaz CREATE INDEX
- příkaz REINDEX
Proč je funkce Reporting Progress v PostgreSQL důležitá?
Tato funkce je velmi důležitá pro operátory při provádění některých dlouhotrvajících operací, protože je možné slepě čekat na dokončení operace.
Toto je velmi užitečná funkce pro získání přehledu, jako je:
- Kolik celkové práce
- Kolik práce již bylo vykonáno
Funkce hlášení průběhu je také užitečná při provádění analýzy pracovní zátěže výkonu, což se také ukázalo být užitečné při vyhodnocování zpracování úlohy VACUUM pro ladění parametrů na úrovni systému nebo úrovně vztahu jednou v závislosti na vzoru zatížení.
Podporované příkazy a systémový katalog
Příkaz DDL | Systémový katalog | Podporovaná verze PostgreSQL |
VAKUUM | pg_stat_progress_vacuum | 9,6 |
VAKUUM PLNO | pg_stat_progress_cluster | 12 |
CLUSTER | pg_stat_progress_cluster | 12 |
VYTVOŘIT INDEX | pg_stat_progress_create_index | 12 |
REINDEX | pg_stat_progress_create_index | 12 |
Jak sledovat průběh příkazu VACUUM
Když je spuštěn příkaz VACUUM, pohled pg_stat_progress_vacuum bude obsahovat jeden řádek pro každý backend (včetně pracovních procesů autovacuum), který právě vysává. Pohled na kontrolu průběhu spouštění příkazů VACUUM a VACCUM FULL je odlišný, protože provozní fáze obou příkazů se liší.
Fáze provozu příkazu VACUUM
- Inicializace
- Hromadu skenování
- Indexy vysávání
- Hromady vysávání
- Čištění indexů
- Zkrácení haldy
- Provádím závěrečné čištění
Toto zobrazení je dostupné v PostgreSQL 12, které poskytuje následující informace:
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 | | |
Příklad:
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
Relace 1:
postgres=# vacuum verbose test;
[. . . waits for completion . . .]
Relace 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
Hlášení o průběhu pro CLUSTER a VACUUM FULL
Příkazy CLUSTER a VACUUM FULL používají pro přepis vztahu stejné cesty kódu, takže průběh obou příkazů můžete zkontrolovat pomocí pohledu pg_stat_progress_cluster.
Toto zobrazení je dostupné v PostgreSQL 12 a zobrazuje následující informace:
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 | | |
Fáze provozu příkazu CLUSTER
- Inicializace
- Hromadu skenování Seq
- Hromadu skenování indexu
- Řazení n-tic
- Psaní nové haldy
- Výměna souborů vztahů
- Obnovení indexu
- Provádím závěrečné čištění
Příklad:
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.
Relace 1:
postgres=# cluster verbose test using idx1;
[. . . waits for completion . . .]
Relace 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)
Hlášení o průběhu pro CREATE INDEX a REINDEX
Když je spuštěn příkaz CREATE INDEX nebo REINDEX, pohled pg_stat_progress_create_index bude obsahovat jeden řádek pro každý backend, který aktuálně vytváří indexy. Funkce hlášení průběhu umožňuje také SOUČASNĚ sledovat příchutě CREATE INDEX a REINDEX. Interní fáze provádění příkazů CREATE INDEX a REINDEX jsou stejné, takže můžete kontrolovat průběh obou příkazů pomocí stejného zobrazení.
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 | | |
Fáze provozu CREATE INDEX / REINDEX
- Inicializace
- Čekání na autory před sestavením
- Vytváření indexu
- Čekání na autory před ověřením
- Ověření indexu:skenování indexu
- Ověření indexu: n-tice řazení
- Ověření indexu:skenovací tabulka
- Čekání na staré snímky
- Čekání na čtenáře před označením mrtvého
- Čekání na čtenáře před upuštěním
Příklad:
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
Relace 1:
postgres=# CREATE INDEX idx ON test (b);
[. . . waits for completion . . .]
Relace 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
Závěr
PostgreSQL verze 9.6 a novější má schopnost hlásit průběh určitých příkazů během provádění příkazů. Toto je opravdu pěkná funkce pro správce databází, vývojáře a uživatele ke kontrole průběhu dlouhých příkazů. Tato schopnost hlášení se může v budoucnu rozšířit o některé další příkazy. Více o této nové funkci si můžete přečíst v dokumentaci PostgreSQL.