В PostgreSQL изпълнението на много DDL команди може да отнеме много време. PostgreSQL има възможността да отчита напредъка на DDL командите по време на изпълнение на командата. След PostgreSQL 9.6 е възможно да се следи напредъка на стартирането на ръчно VACUUM и автоматично вакуумиране с помощта на специален системен каталог (наречен pg_stat_progress_vacuum).
PostgreSQL 12 добави поддръжка за наблюдение на напредъка на още няколко команди като CLUSTER, VACUUM FULL, CREATE INDEX и REINDEX.
В момента инструментът за отчитане на напредъка е достъпен само за команди, както е посочено по-долу.
- Команда VACUUM
- Команда CLUSTER
- Команда VACUUM FULL
- Команда CREATE INDEX
- команда REINDEX
Защо е важна функцията за отчитане на напредъка в PostgreSQL?
Тази функция е много важна за операторите, когато извършват някои продължителни операции, защото е възможно да не чакате сляпо за приключване на операцията.
Това е много полезна функция, за да получите някаква представа като:
- Колко обща работа има
- Колко работа вече е свършена
Функцията за отчитане на напредъка също е полезна, когато правите анализ на натоварването на производителността, това също се оказва полезно при оценката на VACUUM обработката на задания за настройка на параметри на ниво система или ниво на връзката веднъж в зависимост от модела на натоварване.
Поддържани команди и системен каталог
DDL команда | Системен каталог | Поддържана PostgreSQL версия |
ВАКУУМ | pg_stat_progress_vacuum | 9.6 |
ВАКУУМ ПЪЛЕН | pg_stat_progress_cluster | 12 |
КЛЪСТЕР | pg_stat_progress_cluster | 12 |
СЪЗДАВАНЕ НА ИНДЕКС | pg_stat_progress_create_index | 12 |
REINDEX | pg_stat_progress_create_index | 12 |
Как да наблюдавате напредъка на командата VACUUM
Когато се изпълнява командата VACUUM, изгледът pg_stat_progress_vacuum ще съдържа по един ред за всеки бекенд (включително работни процеси за автоматично вакуумиране), който в момента се почиства. Изгледът за проверка на напредъка на изпълнение на командите VACUUM и VACCUM FULL е различен, тъй като фазите на работа и на двете команди са различни.
Фази на работа на командата VACUUM
- Инициализира се
- Сканираща купчина
- Изчистване на индекси
- Изчистване на купчина
- Почистване на индекси
- Отрязваща купчина
- Извършване на окончателно почистване
Този изглед е наличен в PostgreSQL 12, който дава следната информация:
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 | | |
Пример:
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
Сесия 1:
postgres=# vacuum verbose test;
[. . . waits for completion . . .]
Сесия 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
Отчитане на напредъка за CLUSTER и VACUUM FULL
Командите CLUSTER и VACUUM FULL използват едни и същи кодови пътища за пренаписването на релацията, така че можете да проверите напредъка на двете команди с помощта на изгледа pg_stat_progress_cluster.
Този изглед е наличен в PostgreSQL 12 и показва следната информация:
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 | | |
Фази на работа на командата CLUSTER
- Инициализира се
- Seq сканираща купчина
- Комплект за сканиране на индекс
- Сортиране на кортежи
- Писане на нова купчина
- Размяна на релационни файлове
- Индекс за възстановяване
- Извършване на окончателно почистване
Пример:
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.
Сесия 1:
postgres=# cluster verbose test using idx1;
[. . . waits for completion . . .]
Сесия 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)
Отчитане на напредъка за CREATE INDEX и REINDEX
Когато се изпълнява командата CREATE INDEX или REINDEX, изгледът pg_stat_progress_create_index ще съдържа един ред за всеки бекенд, който в момента създава индекси. Функцията за отчитане на напредъка позволява също така да се проследяват ЕВРЕМЕННО вкусовете на CREATE INDEX и REINDEX. Вътрешните фази на изпълнение на командите CREATE INDEX и REINDEX са еднакви, така че можете да проверявате напредъка на двете команди, като използвате един и същ изглед.
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 | | |
Фази на работа на CREATE INDEX / REINDEX
- Инициализира се
- Изчакване на писатели преди изграждане
- Индекс на сграда
- Изчакване на автори преди валидиране
- Проверка на индекса:индекс за сканиране
- Проверка на индекса: сортиране на кортежи
- Проверка на индекса:таблица за сканиране
- В очакване на стари моментни снимки
- Изчакване на читатели, преди да се маркират като мъртви
- Изчакване на читатели, преди да се откаже
Пример:
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
Сесия 1:
postgres=# CREATE INDEX idx ON test (b);
[. . . waits for completion . . .]
Сесия 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
Заключение
PostgreSQL версия 9.6 по-нататък има възможността да докладва напредъка на определени команди по време на изпълнение на командата. Това е наистина приятна функция за DBA, разработчиците и потребителите, за да проверяват напредъка на дълго изпълняваните команди. Тази способност за докладване може да се разшири за някои други команди в бъдеще. Можете да прочетете повече за тази нова функция в документацията на PostgreSQL.