W PostgreSQL wykonanie wielu poleceń DDL może zająć bardzo dużo czasu. PostgreSQL ma możliwość raportowania postępu poleceń DDL podczas wykonywania poleceń. Od wersji PostgreSQL 9.6 możliwe jest monitorowanie postępu ręcznego VACUUM i automatycznego odkurzania za pomocą dedykowanego katalogu systemowego (nazwanego pg_stat_progress_vacuum).
PostgreSQL 12 dodał obsługę monitorowania postępu kilku dodatkowych poleceń, takich jak CLUSTER, VACUUM FULL, CREATE INDEX i REINDEX.
Obecnie funkcja raportowania postępów jest dostępna tylko dla poleceń, jak poniżej.
- polecenie VACUUM
- polecenie CLUSTER
- polecenie VACUUM FULL
- polecenie CREATE INDEX
- polecenie REINDEX
Dlaczego funkcja raportowania postępów w PostgreSQL jest ważna?
Ta funkcja jest bardzo ważna dla operatorów podczas wykonywania długotrwałych operacji, ponieważ można nie czekać na ślepo na zakończenie operacji.
Jest to bardzo przydatna funkcja, która pozwala uzyskać wgląd, na przykład:
- Ile jest całkowitej pracy
- Ile pracy już wykonano
Funkcja raportowania postępów jest również przydatna podczas wykonywania analizy obciążenia wydajnością, okazuje się również przydatna podczas oceny przetwarzania zadań VACUUM w celu jednorazowego dostrojenia parametrów na poziomie systemu lub poziomu relacji w zależności od wzorca obciążenia.
Wspierane polecenia i katalog systemowy
Polecenie DDL | Katalog systemowy | Obsługiwana wersja PostgreSQL |
PRÓŻNIA | pg_stat_progress_vacuum | 9.6 |
PRÓŻNIA PEŁNA | pg_stat_progress_cluster | 12 |
KLASTER | pg_stat_progress_cluster | 12 |
UTWÓRZ INDEKS | pg_stat_progress_create_index | 12 |
REINDEKS | pg_stat_progress_create_index | 12 |
Jak monitorować postęp polecenia VACUUM
Za każdym razem, gdy uruchomione jest polecenie VACUUM, widok pg_stat_progress_vacuum będzie zawierał jeden wiersz dla każdego zaplecza (w tym procesów roboczych automatycznego odkurzania), który jest aktualnie odkurzany. Widok sprawdzania postępu wykonywania poleceń VACUUM i VACCUM FULL jest inny, ponieważ fazy działania obu poleceń są różne.
Fazy działania komendy VACUUM
- Inicjowanie
- Skanowanie sterty
- Odkurzanie indeksów
- Odkurzacz
- Czyszczenie indeksów
- Obcinanie sterty
- Wykonywanie końcowego czyszczenia
Ten widok jest dostępny w PostgreSQL 12 i zawiera następujące informacje:
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 | | |
Przykład:
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
Sesja 1:
postgres=# vacuum verbose test;
[. . . waits for completion . . .]
Sesja 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
Raportowanie postępów dla CLUSTER i VACUUM FULL
Polecenia CLUSTER i VACUUM FULL używają tych samych ścieżek kodu do przepisywania relacji, więc możesz sprawdzić postęp obu poleceń za pomocą widoku pg_stat_progress_cluster.
Ten widok jest dostępny w PostgreSQL 12 i pokazuje następujące informacje:
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 | | |
Fazy działania polecenia CLASTER
- Inicjowanie
- Skanowanie sekwencji
- Skanowanie indeksu sterty
- Sortowanie krotek
- Pisanie nowej sterty
- Zamiana plików relacji
- Odbudowa indeksu
- Wykonywanie końcowego czyszczenia
Przykład:
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.
Sesja 1:
postgres=# cluster verbose test using idx1;
[. . . waits for completion . . .]
Sesja 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)
Raportowanie postępów dla CREATE INDEX i REINDEX
Za każdym razem, gdy wykonywane jest polecenie CREATE INDEX lub REINDEX, widok pg_stat_progress_create_index będzie zawierał jeden wiersz dla każdego zaplecza, które aktualnie tworzy indeksy. Funkcja raportowania postępów pozwala również śledzić OBECNIE smaki CREATE INDEX i REINDEX. Wewnętrzne fazy wykonywania poleceń CREATE INDEX i REINDEX są takie same, więc możesz sprawdzić postęp obu poleceń w tym samym widoku.
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 | | |
Fazy operacyjne tworzenia indeksu / ponownego indeksowania
- Inicjowanie
- Czekam na pisarzy przed kompilacją
- Indeks budynków
- Oczekiwanie na autorów przed zatwierdzeniem
- Weryfikacja indeksu:skanowanie indeksu
- Weryfikacja indeksu:sortowanie krotek
- Weryfikacja indeksu:tabela skanowania
- Czekam na stare migawki
- Czekam na czytelników przed oznaczeniem martwych
- Czekam na czytelników przed porzuceniem
Przykład:
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
Sesja 1:
postgres=# CREATE INDEX idx ON test (b);
[. . . waits for completion . . .]
Sesja 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
Wnioski
PostgreSQL od wersji 9.6 ma możliwość raportowania postępu niektórych poleceń podczas wykonywania poleceń. Jest to naprawdę fajna funkcja dla administratorów baz danych, programistów i użytkowników, aby sprawdzić postęp długo działających poleceń. Ta możliwość raportowania może zostać rozszerzona o niektóre inne polecenia w przyszłości. Możesz przeczytać więcej o tej nowej funkcji w dokumentacji PostgreSQL.