Wydaje się, że nie ma ogólnej, obsługiwanej metody, ale istnieją pewne sztuczki, których można użyć w ograniczonych kontekstach do oceny postępu pojedynczego zapytania. Tutaj są niektóre z nich.
Sekwencje
Gdy zapytanie SELECT lub UPDATE zawiera dowolne zapytanie nextval(sequence_name)
lub INSERT ma nextval
domyślną kolumnę docelową , bieżąca wartość sekwencji może być wielokrotnie sprawdzana w innej sesji za pomocą SELECT sequence_name.last_value
. Działa, ponieważ sekwencje nie są ograniczone transakcjami. Jeśli plan wykonania jest taki, że sekwencja jest zwiększana liniowo podczas zapytania, można go użyć jako wskaźnika postępu.
pgstattuple
Moduł contg pgstattuple zapewnia funkcje, które mogą podglądać bezpośrednio na stronach danych. Wygląda na to, że kiedy krotki są wstawiane do pustej tabeli i jeszcze nie zatwierdzone, są liczone w dead_tuple_count
polu z pgstattuple
funkcji.
Demo z wersją 9.1: utwórz pustą tabelę
CREATE TABLE tt AS (n numeric);
Wstawmy do niego 10 mln wierszy:
INSERT INTO tt SELECT * FROM random() from generate_series(1,10000000);
W innej sesji sprawdzaj pgstattuple co sekundę podczas wstawiania:
$ while true;
do psql -Atc "select dead_tuple_count from pgstattuple('tt')";
sleep 1;
done
Wyniki:
0
69005
520035
1013430
1492210
1990415
2224625
2772040
3314460
3928660
4317345
4743770
5379430
6080950
6522915
7190395
7953705
8747725
9242045
0
Po zakończeniu wstawiania spada do 0 (wszystkie krotki stają się widoczne i aktywne).
Tej sztuczki można również użyć, gdy tabela nie jest świeżo utworzona, ale wartość początkowa dead_tuple_count
może mieć niezerową wartość i może również zmieniać się równocześnie, jeśli trwa inna czynność zapisu, taka jak autovacuum (przypuszczalnie? Nie wiesz, jaki poziom współbieżność oczekiwana z autovacuum).
Jednak nie można go użyć, jeśli tabela jest tworzona przez samą instrukcję ( CREATE TABLE ... AS SELECT
lub SELECT * INTO newtable
), ponieważ tworzenie jest transakcyjne. Obejściem tego problemu byłoby utworzenie tabeli bez wierszy (dodanie LIMIT 0
) i wypełnienie jej w następnej transakcji.
Pamiętaj, że pgstattuple
nie jest darmowy: skanuje cały stół przy każdym połączeniu. Również ogranicza się do superużytkowników.
Licznik niestandardowy
Na blogu Pavla Stehule'a zapewnia on funkcję licznika zaimplementowaną w C, która podnosi UWAGI przy określonej liczbie wykonań. Musisz w jakiś sposób połączyć funkcję z zapytaniem, aby wykonawca mógł je wywołać. Powiadomienia są wysyłane podczas zapytania i nie potrzebują osobnej sesji, tylko klient SQL, który je wyświetla ( psql
jest oczywistym kandydatem).
Przykład przeróbki INSERT INTO w celu podniesienia uwagi:
/* transformation */
INSERT INTO destination_table
SELECT (r).*
FROM (SELECT counter(to_destination_table(_source), 1000, true) r
FROM source _source) x
Powiązane pytanie dotyczące przepływu stosu dla funkcji:
Jak zgłosić postęp od długotrwałej funkcji PostgreSQL do klienta
Przyszłe opcje?
Od maja 2017 r. Do społeczności programistów została dostarczona obiecująca łatka:
[PATCH v2] Polecenie Progress do monitorowania postępu długotrwałych zapytań SQL
co może skończyć jako ogólne rozwiązanie w PostgreSQL 11 lub nowszym. Użytkownicy, którzy chcą uczestniczyć w funkcjach w toku, mogą zastosować najnowszą wersję poprawki i wypróbować proponowane PROGRESS
polecenie.
pv
poleceniem i nie było ono domyślnie instalowane na moim serwerze Debian, ale jest w repozytorium. Opis mówi „pv (Pipe Viewer) można wstawić do dowolnego normalnego potoku między dwoma procesami, aby wizualnie wskazać, jak szybko dane przechodzą”. Bardzo przydatne polecenie!