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

Zakleszczenia w PostgreSQL podczas uruchamiania UPDATE

W PostgreSQL wiersze będą blokowane w miarę ich aktualizacji — w rzeczywistości działa to tak, że każda krotka (wersja wiersza) ma pole systemowe o nazwie xmin aby wskazać, która transakcja uczyniła tę krotkę bieżącą (przez wstawienie lub aktualizację) oraz pole systemowe o nazwie xmax aby wskazać, która transakcja wygasła w tej krotce (przez aktualizację lub usunięcie). Gdy uzyskujesz dostęp do danych, sprawdza każdą krotkę, aby określić, czy jest ona widoczna dla Twojej transakcji, porównując aktywną „migawkę” z tymi wartościami.

Jeśli wykonujesz UPDATE, a krotka, która pasuje do twoich warunków wyszukiwania, ma xmin, dzięki czemu jest widoczna dla twojego zrzutu i xmax aktywnej transakcji, blokuje się, czekając na zakończenie tej transakcji. Jeśli transakcja, która jako pierwsza zaktualizowała krotkę, zostanie wycofana, transakcja budzi się i przetwarza wiersz; jeśli pierwsza transakcja zostanie zatwierdzona, transakcja budzi się i podejmuje działania w zależności od aktualnego poziomu izolacji transakcji.

Oczywiście impas jest wynikiem tego, co dzieje się z rzędami w innej kolejności. W pamięci RAM nie ma blokady na poziomie wiersza, którą można uzyskać dla wszystkich wierszy w tym samym czasie, ale jeśli wiersze są aktualizowane w tej samej kolejności, nie można mieć blokady kołowej. Niestety sugerowany IN(1, 2) składnia tego nie gwarantuje. Różne sesje mogą mieć aktywne różne współczynniki kosztów, zadanie "analizy" w tle może zmienić statystyki dla tabeli między generowaniem jednego planu a drugim lub może używać seqscan i być pod wpływem optymalizacji PostgreSQL, co powoduje nowy seqscan aby dołączyć do jednego, który jest już w toku i "zapętlić się", aby zredukować dyskowe I/O.

Jeśli będziesz wykonywać aktualizacje pojedynczo w tej samej kolejności, w kodzie aplikacji lub za pomocą kursora, będziesz miał tylko proste blokowanie, a nie zakleszczenia. Generalnie jednak relacyjne bazy danych są podatne na awarie serializacji i najlepiej jest uzyskać do nich dostęp za pośrednictwem frameworka, który rozpozna je na podstawie SQLSTATE i automatycznie ponawia całą transakcję od początku. W PostgreSQL błąd serializacji zawsze będzie miał stan SQLSTATE 40001 lub 40P01.

http://www.postgresql.org/docs/current/interactive/mvcc-intro.html




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Rozpakuj tablicę o jeden poziom

  2. Heroku Postgres:Za dużo połączeń. Jak zabić te połączenia?

  3. PostgreSQL UTWÓRZ TABELĘ

  4. Jak przekonwertować ciąg na znacznik czasu w PostgreSQL

  5. Postgres SELECT gdzie WHERE jest UUID lub ciągiem