PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Aktualizacja wierszy bazy danych bez blokowania tabeli w PostgreSQL 9.2

MVCC

Po pierwsze, jeśli "normalne operacje" składają się z SELECT zapytań, model MVCC zajmie się tym automatycznie. UPDATE nie blokuje SELECT i wzajemnie. SELECT widzi tylko zatwierdzone dane (lub to, co zostało zrobione w tej samej transakcji), więc wynik dużej UPDATE pozostaje niewidoczny dla innych transakcji, dopóki nie zostanie wykonany (zatwierdzony).

Wydajność / wzdęcia

Jeśli nie masz innych obiektów odwołujących się do tej tabeli,
i nie masz jednoczesnych operacji zapisu (które zostałyby utracone!),
i możesz sobie pozwolić na bardzo krótką ekskluzywną blokadę na stole
i masz oczywiście dodatkowe miejsce na dysku:
Możesz ograniczyć blokowanie do minimum, tworząc zaktualizowaną wersję tabeli w tle. Upewnij się, że ma wszystko być zamiennikiem drop-in, a następnie usuń oryginał i zmień nazwę duplikatu.

CREATE TABLE tbl_new (LIKE tbl_org INCLUDING CONSTRAINTS);

INSERT INTO tbl_new 
SELECT col_a, col_b, array[col] aS col_c
FROM   tbl_org;

Używam CREATE TABLE (LIKE .. INCLUDING CONSTRAINTS) , ponieważ (cytując instrukcję tutaj):

Ograniczenia niepuste są zawsze kopiowane do nowej tabeli. CHECK ograniczenia zostaną skopiowane tylko wtedy, gdy INCLUDING CONSTRAINTS jest określony;inne typy ograniczeń nigdy nie zostaną skopiowane.

Upewnij się, że nowy stół jest gotowy. Następnie:

DROP tbl_org;
ALTER TABLE tbl_new RENAME TO tbl_org;

Powoduje to bardzo krótkie okno czasowe, w którym stół jest wyłącznie zablokowany.

Tak naprawdę chodzi tylko o wydajność. Dość szybko tworzy nowy stół bez żadnych wzdęć. Jeśli masz obce klucze lub widoki, nadal możesz iść tą drogą, ale musisz przygotować skrypt, aby usunąć i odtworzyć te obiekty, potencjalnie tworząc dodatkowe ekskluzywne blokady.

Równoczesne zapisy

Przy współbieżnych operacjach zapisu naprawdę wszystko, co możesz zrobić, to podzielić aktualizację na kawałki. Nie możesz tego zrobić w pojedynczej transakcji, ponieważ blokady są zwalniane dopiero po zakończeniu transakcji.

możesz zatrudnij dblink , który może uruchamiać niezależne transakcje na innej bazie danych, w tym na sobie. W ten sposób możesz zrobić to wszystko w jednym DO instrukcja lub funkcja plpgsql z pętlą. Oto luźno powiązana odpowiedź z dodatkowymi informacjami na temat dblink:

  • Upuść lub utwórz bazę danych z procedury składowanej w PostgreSQL

Twoje podejście z kursorami

Kursor wewnątrz funkcji nie kupi Ci niczego . Każda funkcja jest automatycznie włączana do transakcji, a wszystkie blokady są zwalniane dopiero na końcu transakcji. Nawet jeśli użyłeś CLOSE cursor (czego nie robisz) zwolniłoby to tylko niektóre zasoby, ale nie zwolnić nabyte blokady na stole. Cytuję instrukcję:

CLOSE zamyka portal pod otwartym kursorem. Można to wykorzystać do zwolnienia zasobów przed zakończeniem transakcji lub do zwolnienia zmiennej kursora do ponownego otwarcia.

Musisz uruchomić oddzielnie transakcje lub (ab)użyj dblink, który zrobi to za Ciebie.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Gdzie PostgreSQL przechowuje bazę danych?

  2. PG::UndefinedTable:BŁĄD:relacja nie istnieje z poprawnym nazewnictwem i konwencją Railsów

  3. Pięć fajnych rzeczy, których nauczyłem się na konferencji PostgreSQL w Europie 2018

  4. Nie można znaleźć punktu wejścia o nazwie „InterlockedIncrement” w bibliotece DLL „kernel32.dll” — [ochrona poczty e-mail] 64-bitowa

  5. Niezbędne monitorowanie PostgreSQL — część 3