Czy COMMIT działa w ramach anonimowej funkcji plgpsql w PostgreSQL 9.5?


8

Importuję dużą liczbę dużych plików do wielu tabel, które mają być podzielone na partycje za pomocą pętli w anonimowym bloku kodu plpgsql $do$.

$do$
BEGIN
    FOR yyyy in 2012..2016 THEN 
        EXECUTE $$COPY table$$||yyyy||$$ FROM 'E:\data\file$$||yyyy||$$.csv DELIMITER ',' CSV;$$;
    END LOOP;
END;
$do$ LANGUAGE plpgsql

Cały ten proces powinien zająć około 15 godzin i mam nadzieję, że cały import nie zostanie przywrócony, jeśli w pewnym momencie wystąpi błąd importu.

IIRC COMMITnie działa w ramach przechowywanych funkcji, ponieważ cała funkcja jest traktowana jako pojedyncza transakcja.

Z dokumentacji dla$do$

Blok kodu jest traktowany tak, jakby był ciałem funkcji bez parametrów, zwracając wartość void. Jest analizowany i wykonywany jednorazowo.

Zakładam, że oznacza to, że całość $do$jest jedną transakcją, więc zatwierdzenia w bloku nie będą działać. Mam rację?


1
Spróbuj BEGINlub COMMITw treści funkcji. Otrzymasz wyjątek, ponieważ jest to niedozwolone (niemożliwe).
Erwin Brandstetter,

Odpowiedzi:


9

Nie,

Nie można kontrolować transakcji wewnątrz plpgsqlfunkcji (lub anonimowego bloku).

Jedyną opcją jest utworzenie transakcji poza blokiem, np .:

BEGIN;

DO $$
  -- function stuff

  -- but if you use a exception, you will force a rollback
  RAISE EXCEPTION 'message';
$$ LANGUAGE 'plpgsql';

COMMIT; -- OR ROLLBACK

BTW, DO BLOCKSmają ten sam efekt, co funkcje, które powraca void.

Proszę zobaczyć więcej w dokumencie:


Czy wiemy, czy nadal tak jest? Mam funkcję, która musi zapętlić się kilkaset razy. Pierwsza pętla trwa 2 sekundy po tym, jak siódma jest blisko godziny, a po 10. pętli nic nie widziałem.
Dennis Bauszus

1

Jedynym rozwiązaniem do zatwierdzenia w blokach (lub funkcjach DO) (dla wersji Postgresql mniejszej niż 11) jest użycie połączenia dblink z tym samym serwerem i wykonanie tam zapytań. Pamiętaj tylko o widoczności zmiennych i obiektów tymczasowych.

więcej informacji o dblink Począwszy od Postgresql-11 kontrola transakcji z bloku „DO” jest dostępna, gdy „DO-blok” nie działa w ramach innej transakcji.


postgresql.org/docs/11/sql-do.html stwierdza: „Instrukcje kontroli transakcji są dozwolone tylko wtedy, gdy DO jest wykonywane we własnej transakcji”. Nie było to oczywiście prawdą w przypadku wersji 9.5. OTOH z dblinktobą otworzy kolejną transakcję, więc twoje COMMITpołączenie nie wpłynie na transakcję połączenia, jeśli się nie mylę.
dezso,

Mój błąd. Kontrola transakcji w ramach „DO” została wprowadzona w Postgresql-11. Po prostu sprawdzam, czy 10.4 nadal nie działa.
Dzhureedzh,

@dezso Dziękujemy za wskazanie mi tego, używałem metody dblink nawet na serwerach PG11.
Dzhureedzh,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.