Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Transkrypcja wykładu Bruce'a Momjiana z 2020 r. „Odblokowywanie menedżera blokad Postgres”.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

(Uwaga: wszystkie zapytania SQL ze slajdów można uzyskać pod tym linkiem: http://momjian.us/main/writings/pgsql/locking.sql)

Cześć! Wspaniale jest znów być tutaj, w Rosji. Przepraszam, że nie mogłem przyjechać w zeszłym roku, ale w tym roku Ivan i ja mamy wielkie plany. Mam nadzieję, że będę tu znacznie częściej. Uwielbiam przyjeżdżać do Rosji. Odwiedzę Tiumeń, Twer. Bardzo się cieszę, że będę mogła odwiedzić te miasta.

Nazywam się Bruce Momjian. Pracuję w EnterpriseDB i współpracuję z Postgres od ponad 23 lat. Mieszkam w Filadelfii, USA. Podróżuję około 90 dni w roku. Biorę udział w około 40 konferencjach. Mój Strona internetowa, który zawiera slajdy, które teraz pokażę. Dlatego po konferencji będzie można je pobrać z mojej osobistej strony internetowej. Zawiera także około 30 prezentacji. Istnieją również filmy i duża liczba wpisów na blogu, ponad 500. Jest to dość pouczające źródło informacji. A jeśli zainteresował Cię ten materiał, to zapraszam do skorzystania z niego.

Zanim zacząłem pracować w Postgres, byłem nauczycielem, profesorem. I bardzo się cieszę, że teraz będę mógł powiedzieć wam to, co zamierzam wam powiedzieć. To jedna z moich najciekawszych prezentacji. Ta prezentacja zawiera 110 slajdów. Zaczniemy mówić o prostych rzeczach, a pod koniec raport będzie coraz bardziej złożony i dość złożony.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

To dość nieprzyjemna rozmowa. Blokowanie nie jest najpopularniejszym tematem. Chcemy, żeby to gdzieś zniknęło. To jak pójście do dentysty.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

  1. Blokowanie stanowi problem dla wielu osób pracujących w bazach danych i mających wiele procesów uruchomionych w tym samym czasie. Wymagają blokady. Oznacza to, że dzisiaj przekażę Ci podstawową wiedzę na temat blokowania.
  2. Identyfikatory transakcji. To dość nudna część prezentacji, ale trzeba ją zrozumieć.
  3. Następnie porozmawiamy o rodzajach blokowania. To dość mechaniczna część.
  4. Poniżej podamy kilka przykładów blokowania. I będzie to dość trudne do zrozumienia.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Porozmawiajmy o blokowaniu.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Nasza terminologia jest dość złożona. Ilu z Was wie, skąd pochodzi ten fragment? Dwoje ludzi. To jest z gry o nazwie Colossal Cave Adventure. Wydaje mi się, że była to tekstowa gra komputerowa z lat 80. Tam trzeba było wejść do jaskini, do labiryntu i tekst się zmieniał, ale treść była za każdym razem mniej więcej taka sama. Tak pamiętam ten mecz.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

I tutaj widzimy nazwę zamków, która przyszła do nas od Oracle. Używamy ich.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Tutaj widzimy terminy, które mnie dezorientują. Na przykład UDOSTĘPNIJ AKTUALIZUJ ECXLUSIVE. Dalej UDOSTĘPNIJ SUROWY EKXLUSIVE. Szczerze mówiąc, nazwy te nie są zbyt jasne. Postaramy się rozważyć je bardziej szczegółowo. Niektóre zawierają słowo „dzielić”, co oznacza oddzielanie. Niektóre zawierają słowo „ekskluzywny”. Niektóre zawierają oba te słowa. Chciałbym zacząć od tego, jak działają te zamki.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Bardzo ważne jest również słowo „dostęp”. A słowa „rząd” są ciągiem znaków. Oznacza to dystrybucję dostępu, dystrybucję wierszy.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Kolejną kwestią wymagającą zrozumienia w Postgresie, której niestety nie będę w stanie poruszyć w moim wykładzie, jest MVCC. Na mojej stronie internetowej znajduje się osobna prezentacja na ten temat. A jeśli uważasz, że ta prezentacja jest trudna, MVCC jest prawdopodobnie najtrudniejszy dla mnie. A jeśli jesteście ciekawi, możecie obejrzeć go na stronie internetowej. Możesz obejrzeć wideo.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Kolejną rzeczą, którą musimy zrozumieć, są identyfikatory transakcji. Wiele transakcji nie może działać bez unikalnych identyfikatorów. I tutaj mamy wyjaśnienie, czym jest transakcja. Postgres ma dwa systemy numeracji transakcji. Wiem, że to nie jest zbyt ładne rozwiązanie.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Pamiętaj też, że slajdy będą dość trudne do zrozumienia, dlatego należy zwrócić uwagę na to, co jest zaznaczone na czerwono.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

http://momjian.us/main/writings/pgsql/locking.sql

Zobaczmy. Numer transakcji jest podświetlony na czerwono. Tutaj pokazana jest funkcja SELECT pg_back. Zwraca moją transakcję i identyfikator transakcji.

Jeszcze jedno, jeśli podoba Ci się ta prezentacja i chcesz uruchomić ją w swojej bazie danych, możesz wejść w ten link oznaczony na różowo i pobrać kod SQL do tej prezentacji. Możesz po prostu uruchomić go w swoim PSQL, a cała prezentacja natychmiast pojawi się na ekranie. Nie będzie na nim kwiatów, ale przynajmniej będziemy mogli go zobaczyć.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

W tym przypadku widzimy identyfikator transakcji. To jest numer, który jej przypisaliśmy. W Postgres istnieje inny typ identyfikatora transakcji, który nazywa się wirtualnym identyfikatorem transakcji

I musimy to zrozumieć. Jest to bardzo ważne, w przeciwnym razie nie będziemy w stanie zrozumieć blokowania w Postgresie.

Identyfikator transakcji wirtualnej to identyfikator transakcji, który nie zawiera trwałych wartości. Przykładowo, jeśli uruchomię polecenie SELECT, to najprawdopodobniej nie zmienię bazy danych, nie zablokuję niczego. Kiedy więc uruchamiamy prosty SELECT, nie nadajemy tej transakcji trwałego identyfikatora. Tam podajemy jej jedynie wirtualny identyfikator.

A to poprawia wydajność Postgres, poprawia możliwości czyszczenia, więc wirtualny identyfikator transakcji składa się z dwóch liczb. Pierwsza liczba przed ukośnikiem to identyfikator zaplecza. A po prawej stronie widzimy tylko licznik.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Dlatego jeśli uruchomię żądanie, wyświetli się informacja, że ​​identyfikator zaplecza to 2.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A jeśli przeprowadzę serię takich transakcji, to zobaczymy, że licznik rośnie za każdym razem, gdy uruchamiam zapytanie. Na przykład, gdy uruchomię zapytanie 2/10, 2/11, 2/12 itd.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Pamiętaj, że są tu dwie kolumny. Po lewej stronie widzimy wirtualny identyfikator transakcji – 2/12. A po prawej stronie mamy stały identyfikator transakcji. A to pole jest puste. Ta transakcja nie modyfikuje bazy danych. Dlatego nie nadaję mu stałego identyfikatora transakcji.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Gdy tylko uruchomię polecenie analizy ((ANALYZE)), to samo zapytanie daje mi stały identyfikator transakcji. Zobacz, jak to się dla nas zmieniło. Wcześniej nie miałem tego identyfikatora, ale teraz go mam.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Oto kolejna prośba, kolejna transakcja. Numer wirtualnej transakcji to 2/13. A jeśli poproszę o trwały identyfikator transakcji, to po uruchomieniu zapytania otrzymam go.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Więc jeszcze raz. Mamy wirtualny identyfikator transakcji i trwały identyfikator transakcji. Po prostu zrozum ten punkt, aby zrozumieć zachowanie Postgres.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Przechodzimy do trzeciej części. Tutaj po prostu przejdziemy przez różne typy zamków w Postgres. To nie jest zbyt interesujące. Ostatnia część będzie znacznie ciekawsza. Musimy jednak wziąć pod uwagę podstawowe rzeczy, bo inaczej nie zrozumiemy, co będzie dalej.

Przejdziemy przez tę sekcję, przyjrzymy się każdemu rodzajowi zamka. Pokażę ci przykłady ich instalacji, działania, pokażę kilka zapytań, których możesz użyć, aby zobaczyć, jak działa blokowanie w Postgresie.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Aby utworzyć zapytanie i zobaczyć co się dzieje w Postgresie musimy wystawić zapytanie w widoku systemowym. W tym przypadku pg_lock jest podświetlony na czerwono. Pg_lock to tabela systemowa, która informuje nas, jakie blokady są aktualnie używane w Postgres.

Jednak bardzo trudno jest mi pokazać sam pg_lock, ponieważ jest on dość skomplikowany. Stworzyłem więc widok, który pokazuje pg_locks. I to też trochę dla mnie działa, co pozwala mi lepiej zrozumieć. Oznacza to, że wyklucza moje blokady, moją własną sesję itp. To po prostu standardowy SQL, który pozwala lepiej pokazać, co się dzieje.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Kolejnym problemem jest to, że ten widok jest bardzo szeroki, więc muszę stworzyć drugi - lockview2.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana I pokazuje mi więcej kolumn z tabeli. I jeszcze jeden, który pokazuje mi resztę kolumn. Jest to dość skomplikowane, dlatego starałem się przedstawić to możliwie najprościej.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Stworzyliśmy więc tabelę o nazwie Lockdemo. I tam stworzyliśmy jedną linię. To jest nasza przykładowa tabela. Będziemy tworzyć sekcje, aby pokazać przykłady zamków.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Zatem jeden wiersz, jedna kolumna. Pierwszy typ blokady nazywa się ACCESS SHARE. Jest to najmniej restrykcyjne blokowanie. Oznacza to, że praktycznie nie koliduje z innymi zamkami.

A jeśli chcemy jawnie zdefiniować blokadę, uruchamiamy polecenie „lock table”. I oczywiście zablokuje, czyli w trybie ACCESS SHARE uruchamiamy tablicę blokującą. A jeśli uruchomię PSQL w tle, to zacznę w ten sposób drugą sesję od pierwszej sesji. To znaczy, co ja tu zrobię? Przechodzę do innej sesji i mówię „pokaż mi widok blokady dla tego żądania”. A tutaj mam AccessShareLock w tej tabeli. To jest dokładnie to, o co prosiłem. I mówi, że blok został przydzielony. Bardzo prosta.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Co więcej, jeśli spojrzymy na drugą kolumnę, to nic tam nie ma. Są puste.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A jeśli uruchomię polecenie „WYBIERZ”, będzie to ukryty (jawny) sposób żądania AccessShareLock. Zwalniam więc tabelę i uruchamiam zapytanie, które zwraca wiele wierszy. A w jednej z linii widzimy AccessShareLock. Zatem SELECT wywołuje AccessShareLock na stole. I nie koliduje to praktycznie z niczym, ponieważ jest to blokada niskiego poziomu.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Co się stanie, jeśli uruchomię SELECT i będę miał trzy różne tabele? Wcześniej korzystałem tylko z jednej tabeli, teraz mam trzy: pg_class, pg_namespace i pg_attribute.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A teraz, kiedy patrzę na zapytanie, widzę 9 AccessShareLocks w trzech tabelach. Dlaczego? Trzy tabele są podświetlone na niebiesko: pg_attribute, pg_class, pg_namespace. Ale widać również, że wszystkie indeksy zdefiniowane za pomocą tych tabel również mają funkcję AccessShareLock.

I to jest zamek, który praktycznie nie koliduje z innymi. A jedyne, co robi, to po prostu uniemożliwia nam zresetowanie tabeli podczas jej wybierania. To ma sens. Oznacza to, że jeśli wybierzemy tabelę, zniknie ona w tym momencie, to jest to błędne, tzw AccessShare to blokada niskiego poziomu, która mówi nam „nie upuszczaj tego stołu, gdy pracuję”. W zasadzie to wszystko, co ona robi.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

ROW SHARE — ta blokada jest trochę inna.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Weźmy przykład. SELECT ROW SHARE metoda blokowania każdego wiersza indywidualnie. Dzięki temu nikt nie będzie mógł ich usunąć ani zmienić podczas ich oglądania.

Odblokowanie menedżera blokad Postgres. Bruce'a MomjianaCo więc robi SHARE LOCK? Widzimy, że identyfikator transakcji to 681 dla SELECT. I to jest interesujące. Co tu się stało? Numer pojawia się po raz pierwszy w polu „Zablokuj”. Bierzemy identyfikator transakcji i wyświetla się informacja, że ​​blokuje ją w trybie wyłącznym. Jedyne, co robi, to komunikat, że mam wiersz, który jest technicznie zablokowany gdzieś w tabeli. Ale nie mówi gdzie dokładnie. Przyjrzymy się temu bardziej szczegółowo nieco później.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Tutaj mówimy, że zamek jest przez nas używany.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Zatem ekskluzywny zamek wyraźnie mówi, że jest ekskluzywny. A także, jeśli usuniesz wiersz w tej tabeli, stanie się tak, jak widzisz.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

SHARE EXCLUSIVE to dłuższy zamek.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

To jest polecenie analizatora (ANALIZA), które zostanie użyte.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

SHARE LOCK – możesz jawnie zablokować tryb udostępniania.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Możesz także utworzyć unikalny indeks. I tam możesz zobaczyć SHARE LOCK, który jest ich częścią. Blokuje stół i nakłada na niego BLOKADĘ UDOSTĘPNIANIA.

Domyślnie opcja SHARE LOCK na stole oznacza, że ​​inne osoby mogą czytać tabelę, ale nikt nie może jej modyfikować. I właśnie to się dzieje, gdy tworzysz unikalny indeks.

Jeśli utworzę unikalny indeks współbieżny, będę miał inny typ blokowania, ponieważ, jak pamiętasz, używanie indeksów współbieżnych zmniejsza wymagania dotyczące blokowania. A jeśli użyję normalnej blokady, normalnego indeksu, to w ten sposób zapobiegnę zapisowi do indeksu tabeli podczas jego tworzenia. Jeśli używam indeksu współbieżnego, muszę użyć innego rodzaju blokowania.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

SHARE ROW EXCLUSIVE – ponownie można to ustawić jawnie (jawnie).

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Albo możemy stworzyć regułę, czyli przyjąć konkretny przypadek, w którym będzie ona zastosowana.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

EKSKLUZYWNE blokowanie oznacza, że ​​nikt inny nie może zmienić stołu.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Tutaj widzimy różne typy zamków.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Na przykład ACCESS EXCLUSIVE jest poleceniem blokującym. Na przykład, jeśli to zrobisz CLUSTER table, to będzie to oznaczać, że nikt nie będzie mógł tam pisać. Blokuje nie tylko samą tabelę, ale także indeksy.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

To druga strona blokowania ACCESS EXCLUSIVE, gdzie w tabeli widzimy dokładnie co blokuje. Blokuje poszczególne wiersze tabeli, co jest dość interesujące.

To wszystkie podstawowe informacje jakie chciałem przekazać. Mówiliśmy o blokadach, identyfikatorach transakcji, rozmawialiśmy o identyfikatorach transakcji wirtualnych, identyfikatorach transakcji stałych.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A teraz omówimy kilka przykładów blokowania. To najciekawsza część. Przyjrzymy się bardzo interesującym przypadkom. Moim celem w tej prezentacji jest lepsze zrozumienie tego, co tak naprawdę robi Postgres, gdy próbuje zablokować pewne rzeczy. Myślę, że jest bardzo dobry w blokowaniu części.

Spójrzmy na kilka konkretnych przykładów.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Zaczniemy od tabel i jednego wiersza w tabeli. Kiedy coś wstawię, na stole wyświetlają się ExclusiveLock, Transaction ID i ExclusiveLock.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Co się stanie, jeśli wstawię dwa kolejne wiersze? A teraz nasz stół ma trzy rzędy. Wstawiłem jeden wiersz i otrzymałem to jako wynik. A jeśli wstawię jeszcze dwa wiersze, co w tym dziwnego? Jest tu dziwna rzecz, ponieważ dodałem trzy wiersze do tej tabeli, ale nadal mam dwa wiersze w tabeli blokady. I to jest w zasadzie podstawowe zachowanie Postgres.

Wiele osób uważa, że ​​jeśli w bazie danych zablokujesz 100 wierszy, będziesz musiał utworzyć 100 wpisów blokujących. Jeśli zablokuję 1 wierszy na raz, będę potrzebować 000 takich zapytań. A jeśli będę potrzebował miliona lub miliarda na zablokowanie. Ale jeśli to zrobimy, nie będzie to działać zbyt dobrze. Jeśli korzystałeś z systemu, który tworzy wpisy blokujące dla każdego wiersza z osobna, widzisz, że jest to skomplikowane. Ponieważ musisz natychmiast zdefiniować tabelę blokującą, która może się przepełnić, ale Postgres tego nie robi.

A naprawdę ważne w tym slajdzie jest to, że wyraźnie pokazuje, że w MVCC działa inny system, który blokuje poszczególne wiersze. Kiedy więc blokujesz miliardy wierszy, Postgres nie tworzy miliarda oddzielnych poleceń blokujących. A to ma bardzo dobry wpływ na produktywność.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A co z aktualizacją? Aktualizuję teraz wiersz i widać, że wykonał on dwie różne operacje na raz. Zablokowało to jednocześnie tabelę, ale zablokowało także indeks. Musiał także zablokować indeks, ponieważ na tej tabeli istnieją unikalne ograniczenia. A chcemy mieć pewność, że nikt tego nie zmieni, więc to blokujemy.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Co się stanie, jeśli chcę zaktualizować dwa wiersze? I widzimy, że zachowuje się w ten sam sposób. Wykonujemy dwa razy więcej aktualizacji, ale dokładnie taką samą liczbę linii blokujących.

Jeśli zastanawiasz się, jak Postgres to robi, musisz posłuchać moich wykładów na temat MVCC, aby dowiedzieć się, jak Postgres wewnętrznie zaznacza te linie, które zmienia. Postgres ma na to sposób, ale nie robi tego na poziomie blokowania tabeli, robi to na niższym i bardziej wydajnym poziomie.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A co jeśli chcę coś usunąć? Jeśli usunę na przykład jeden wiersz i nadal mam dwa wejścia blokujące, a nawet jeśli chcę je wszystkie usunąć, nadal tam są.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

I na przykład chcę wstawić 1 linii, a następnie usunąć lub dodać 000 linii, a następnie te pojedyncze linie, które dodam lub zmienię, nie będą tutaj rejestrowane. Są napisane na niższym poziomie w ramach samej serii. I podczas wystąpienia MVCC mówiłem o tym szczegółowo. Jednak bardzo ważne jest, aby podczas analizowania blokad upewnić się, że blokujesz je na poziomie tabeli i że nie widzisz, w jaki sposób rejestrowane są tutaj poszczególne wiersze.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A co z wyraźnym blokowaniem?

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Jeśli kliknę Odśwież, mam zablokowane dwa wiersze. A jeśli zaznaczę je wszystkie i kliknę „aktualizuj wszędzie”, wówczas nadal będę mieć dwa rekordy blokujące.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Nie tworzymy oddzielnych rekordów dla każdego wiersza. Ponieważ wtedy spada produktywność, może być jej za dużo. I możemy znaleźć się w nieprzyjemnej sytuacji.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

I to samo, jeśli się podzielimy, możemy to zrobić 30 razy.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Przywracamy naszą tabelę, usuwamy wszystko, a następnie ponownie wstawiamy jeden wiersz.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Innym zachowaniem, które widzisz w Postgresie, które jest bardzo dobrze znanym i pożądanym zachowaniem, jest możliwość wykonania aktualizacji lub wyboru. I możesz to zrobić w tym samym czasie. I zaznacz nie blokuje aktualizacji i to samo w odwrotnym kierunku. Mówimy czytelnikowi, żeby nie blokował pisarza, a pisarz nie blokował czytelnika.

Pokażę ci tego przykład. Teraz dokonam wyboru. Następnie wykonamy INSERT. I wtedy widzisz - 694. Możesz zobaczyć identyfikator transakcji, która dokonała tego wstawienia. I tak to działa.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A jeśli teraz spojrzę na mój identyfikator backendu, jest to teraz 695.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

I widzę, że w moim stole pojawia się 695.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A jeśli zaktualizuję tutaj w ten sposób, otrzymam inny przypadek. W tym przypadku 695 jest blokadą wyłączną, a aktualizacja zachowuje się tak samo, ale nie ma między nimi konfliktu, co jest dość niezwykłe.

I widać, że u góry jest to ShareLock, a na dole ExclusiveLock. I obie transakcje się udały.

Aby zrozumieć, jak to się dzieje, musisz posłuchać mojego wystąpienia w MVCC. Ale to jest ilustracja, że ​​możesz to zrobić w tym samym czasie, tj. jednocześnie wykonać SELECT i UPDATE.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Zresetujmy i wykonajmy jeszcze jedną operację.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Jeśli spróbujesz uruchomić dwie aktualizacje jednocześnie w tym samym wierszu, zostanie to zablokowane. I pamiętajcie, powiedziałem, że czytelnik nie blokuje pisarza, a pisarz nie blokuje czytelnika, ale jeden pisarz blokuje innego pisarza. Oznacza to, że dwie osoby nie mogą jednocześnie aktualizować tego samego wiersza. Musisz poczekać, aż któryś z nich skończy.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Aby to zilustrować, spójrzmy na tabelę Lockdemo. Przyjrzymy się jednemu rzędowi. Na transakcję 698.

Zaktualizowaliśmy to do 2. 699 to pierwsza aktualizacja. Transakcja zakończyła się sukcesem lub jest w trakcie oczekującej transakcji i czeka na potwierdzenie lub anulowanie.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Ale spójrz na coś innego – 2 lutego to nasza pierwsza transakcja, nasza pierwsza sesja. 51/3 to drugie żądanie, które przyszło od góry, które zmieniło tę wartość na 112. A jeśli zauważycie, górne żądanie samo się zablokowało, czyli 3. Ale 699/3 nie przyznało blokady. Kolumna Lock_mode mówi, na co czeka. Oczekuje 112. A jeśli spojrzysz na to, gdzie jest 699, to jest ono wyższe. A co dała pierwsza sesja? Stworzyła ekskluzywną blokadę na swoim własnym identyfikatorze transakcji. Tak to robi Postgres. Blokuje swój własny identyfikator transakcji. A jeśli chcesz poczekać, aż ktoś potwierdzi lub anuluje, musisz poczekać, aż będzie oczekująca transakcja. I dlatego widzimy dziwną linię.

Spójrzmy jeszcze raz. Po lewej stronie widzimy nasz identyfikator przetwarzania. W drugiej kolumnie widzimy nasz wirtualny identyfikator transakcji, a w trzeciej widzimy lock_type. Co to znaczy? Zasadniczo mówi, że blokuje identyfikator transakcji. Ale zauważ, że wszystkie wiersze na dole mówią o relacji. I tak masz na stole dwa rodzaje zamków. Istnieje blokada relacji. No i jeszcze blokowanie identyfikatora transakcji, gdzie blokujemy samodzielnie, czyli dokładnie to, co dzieje się w pierwszym wierszu lub na samym dole, gdzie znajduje się identyfikator transakcji, gdzie czekamy, aż 699 zakończy swoje działanie.

Zobaczę, co się tutaj stanie. I tutaj dwie rzeczy dzieją się jednocześnie. Patrzysz na blokadę identyfikatora transakcji w pierwszym wierszu, która sama się blokuje. I blokuje się, żeby ludzie czekali.

Jeśli spojrzysz na szóstą linię, jest to ten sam wpis, co pierwszy. Dlatego transakcja 6 jest zablokowana. 699 jest również samoblokujący. A potem w dolnym rzędzie zobaczysz, że czekamy, aż 700 zakończy swoje działanie.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A w lock_type, Tuple widzisz liczby.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Jak widać jest 0/10. A to jest numer strony i przesunięcie tego konkretnego wiersza.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

I widzisz, kiedy aktualizujemy, staje się 0/11.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Ale w rzeczywistości jest to 0/10, ponieważ na tę operację trzeba czekać. Mamy okazję przekonać się, że jest to serial, na który czekam na potwierdzenie.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Po potwierdzeniu i naciśnięciu przycisku zatwierdzenia i zakończeniu aktualizacji ponownie otrzymujemy to samo. Transakcja 700 jest jedyną blokadą, nie czeka na nikogo innego, ponieważ została zatwierdzona. Po prostu czeka na zakończenie transakcji. Gdy skończy się 699, nie będziemy już na nic czekać. A teraz transakcja 700 mówi, że wszystko jest w porządku, że ma wszystkie potrzebne blokady na wszystkich dozwolonych tabelach.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A żeby całość była jeszcze bardziej skomplikowana, tworzymy kolejny widok, który tym razem zapewni nam hierarchię. Nie oczekuję, że zrozumiesz tę prośbę. Ale to da nam jaśniejszy obraz tego, co się dzieje.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Jest to widok rekurencyjny, który ma również inną sekcję. A potem wszystko znów łączy się w jedną całość. Wykorzystajmy to.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Co się stanie, jeśli wykonamy trzy jednoczesne aktualizacje i powiemy, że w wierszu są teraz trzy. I zmienimy 3 na 4.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

I tutaj widzimy 4. Oraz identyfikator transakcji 702.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A potem zamienię 4 na 5. Oraz 5 na 6 i 6 na 7. Ustawię w kolejce pewną liczbę osób, które będą czekać na zakończenie tej jednej transakcji.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

I wszystko staje się jasne. Jaki jest pierwszy rząd? To jest 702. Jest to identyfikator transakcji, który pierwotnie ustawił tę wartość. Co jest napisane w mojej kolumnie Przyznane? Mam ślady f. Oto moje aktualizacje, których (5, 6, 7) nie można zatwierdzić, ponieważ czekamy na zakończenie transakcji o identyfikatorze 702. Tam mamy blokowanie identyfikatora transakcji. Efektem jest 5 transakcyjnych blokad identyfikacyjnych.

A jeśli spojrzeć na 704, na 705, to tam jeszcze nic nie napisano, bo jeszcze nie wiedzą, co się dzieje. Piszą po prostu, że nie mają pojęcia, co się dzieje. I po prostu pójdą spać, bo czekają, aż ktoś skończy i obudzą się, gdy nadarzy się okazja do zmiany rzędów.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Tak to wygląda. Oczywiste jest, że wszyscy czekają na 12. linię.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

To właśnie tutaj widzieliśmy. Oto 0/12.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Zatem po zatwierdzeniu pierwszej transakcji możesz tutaj zobaczyć, jak działa hierarchia. A teraz wszystko staje się jasne. Wszyscy stają się czyści. I właściwie nadal czekają.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Oto, co się dzieje. 702 zatwierdzeń. A teraz 703 otrzymuje tę blokadę wiersza, a następnie 704 zaczyna czekać na zatwierdzenie 703. I 705 też na to czeka. A kiedy to wszystko się zakończy, sprzątają. A chciałbym zaznaczyć, że wszyscy stoją w kolejce. A to bardzo przypomina sytuację w korku, kiedy wszyscy czekają na pierwszy samochód. Pierwszy samochód zatrzymuje się i wszyscy ustawiają się w długiej kolejce. Następnie rusza, po czym następny samochód może pojechać do przodu i zdobyć blok itp.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A jeśli nie wydawało ci się to wystarczająco skomplikowane, porozmawiamy teraz o impasach. Nie wiem, kto z Was się z nimi spotkał. Jest to dość powszechny problem w systemach bazodanowych. Ale impas ma miejsce, gdy jedna sesja czeka, aż inna sesja coś zrobi. I w tym momencie kolejna sesja czeka, aż pierwsza sesja coś zrobi.

I na przykład, jeśli Iwan powie: „Daj mi coś”, a ja powiem: „Nie, dam ci to tylko wtedy, gdy ty dasz mi coś innego”. A on na to: „Nie, nie dam ci tego, jeśli ty nie dasz mi”. I wpadamy w impas. Jestem pewien, że Ivan tego nie zrobi, ale rozumiesz, co to znaczy, że mamy dwoje ludzi, którzy chcą coś dostać i nie są gotowi tego oddać, dopóki druga osoba nie da im tego, czego chcą. I nie ma rozwiązania.

Zasadniczo Twoja baza danych musi to wykryć. A potem musisz usunąć lub zamknąć jedną z sesji, bo w przeciwnym razie pozostaną tam na zawsze. Widzimy to w bazach danych, widzimy to w systemach operacyjnych. Może się to zdarzyć wszędzie, gdzie mamy równoległe procesy.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A teraz zainstalujemy dwa impasy. Umieścimy 50 i 80. W pierwszym rzędzie zaktualizuję z 50 do 50. Otrzymam numer transakcji 710.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A potem zmienię 80 na 81 i 50 na 51.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

I tak to będzie wyglądać. I tak 710 ma zablokowany wiersz, a 711 czeka na potwierdzenie. Widzieliśmy to podczas aktualizacji. 710 jest właścicielem naszej serii. A 711 czeka, aż 710 zakończy transakcję.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Mówi nawet, w którym rzędzie występują zakleszczenia. I tu zaczyna się robić dziwnie.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Teraz aktualizujemy 80 do 80.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

I tu zaczyna się impas. 710 czeka na odpowiedź od 711, a 711 czeka na 710. A to nie skończy się dobrze. I nie ma z tego wyjścia. I będą oczekiwać wzajemnej odpowiedzi.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A to po prostu zacznie wszystko opóźniać. A tego nie chcemy.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Postgres ma sposoby, aby zauważyć, kiedy tak się dzieje. A kiedy tak się stanie, pojawi się ten błąd. I z tego jasno wynika, że ​​taki a taki proces czeka na SHARE LOCK od innego procesu, tj. który jest blokowany przez proces 711. I ten proces czekał na podanie SHARE LOCK na taki a taki identyfikator transakcji i został zablokowany przez taki a taki proces. Dlatego mamy tu do czynienia z impasem.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Czy istnieją zakleszczenia trójstronne? Czy to możliwe? Tak.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Wpisujemy te liczby do tabeli. Zmieniamy 40 na 40, robimy blokowanie.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Zmieniamy 60 na 61, 80 na 81.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A potem zmieniamy 80 i wtedy bum!

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A 714 czeka teraz na 715. 716 czeka na 715. I nic na to nie można poradzić.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Nie ma tu już dwóch osób, są już trzy osoby. Chcę czegoś od ciebie, ten chce czegoś od trzeciej osoby, a trzecia osoba chce czegoś ode mnie. I kończy się to trójstronnym oczekiwaniem, ponieważ wszyscy czekamy, aż druga osoba wykona to, co musi zrobić.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A Postgres wie, w którym wierszu to się dzieje. W rezultacie wyświetli się następujący komunikat, który pokazuje, że masz problem polegający na tym, że trzy wejścia blokują się nawzajem. I nie ma tu żadnych ograniczeń. Taka sytuacja może mieć miejsce, gdy 20 wpisów blokuje się wzajemnie.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Następnym problemem jest możliwość serializacji.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Jeśli specjalny zamek z możliwością serializacji.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

I wracamy do 719. Jego wynik jest całkiem normalny.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Możesz także kliknąć, aby transakcję można było serializować.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

I zdajesz sobie sprawę, że masz teraz inny rodzaj blokady SA - oznacza to, że można ją serializować.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

I tak mamy nowy typ zamka o nazwie SARieadLock, który jest zamkiem szeregowym i pozwala na wprowadzanie numerów seryjnych.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Możesz także wstawiać unikalne indeksy.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

W tej tabeli mamy unikalne indeksy.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Więc jeśli wstawię tutaj cyfrę 2, to mam 2. Ale na samej górze wstawiam kolejne 2. I widać, że 721 ma ekskluzywny zamek. Ale teraz 722 czeka, aż 721 zakończy operację, ponieważ nie może wstawić 2, dopóki nie będzie wiedział, co stanie się z 721.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A jeśli zrobimy podtransakcję.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Tutaj mamy 723.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A jeśli zapiszemy punkt i następnie go zaktualizujemy, to otrzymamy nowy identyfikator transakcji. To kolejny wzorzec zachowań, o którym musisz wiedzieć. Jeśli to zwrócimy, identyfikator transakcji zniknie. 724 odchodzi. Ale teraz mamy 725.

Więc co próbuję tutaj zrobić? Próbuję pokazać przykłady nietypowych blokad, które możesz znaleźć: niezależnie od tego, czy są to blokady serializowalne, czy SAVEPOINT, są to różne typy blokad, które pojawią się w tabeli blokad.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Jest to tworzenie jawnych (jawnych) blokad, które mają pg_advisory_lock.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

I widzisz, że typ blokowania jest wymieniony jako doradczy. A tutaj jest napisane „doradczo” na czerwono. I możesz jednocześnie blokować w ten sposób za pomocą pg_advisory_unlock.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Na zakończenie chciałbym pokazać jeszcze jedną zadziwiającą rzecz. Stworzę inny widok. Ale dołączę tabelę pg_locks do tabeli pg_stat_activity. A dlaczego chcę to zrobić? Ponieważ pozwoli mi to przejrzeć i zobaczyć wszystkie bieżące sesje i zobaczyć dokładnie, jakiego rodzaju blokady czekają. Jest to dość interesujące, gdy zestawimy tabelę blokad i tabelę zapytań.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

I tutaj tworzymy pg_stat_view.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

I aktualizujemy wiersz po jednym. I tutaj widzimy 724. Następnie aktualizujemy nasz wiersz do trzech. I co tu teraz widzisz? Są to żądania, tzn. widzisz całą listę żądań, które są wymienione w lewej kolumnie. A potem po prawej stronie widać blokady i to, co tworzą. Może to być dla Ciebie bardziej przejrzyste, abyś nie musiał za każdym razem wracać do każdej sesji i sprawdzać, czy chcesz do niej dołączyć, czy nie. Robią to za nas.

Kolejną bardzo przydatną funkcją jest pg_blocking_pids. Prawdopodobnie nigdy o niej nie słyszałeś. Co ona robi? To pozwala nam powiedzieć, że dla tej sesji 11740 jakie konkretne identyfikatory procesów czeka. I widać, że 11740 czeka na 724. A 724 jest na samej górze. A 11306 to identyfikator Twojego procesu. Zasadniczo ta funkcja przechodzi przez tabelę blokad. I wiem, że to trochę skomplikowane, ale udaje ci się to zrozumieć. Zasadniczo ta funkcja przegląda tę tabelę blokad i próbuje znaleźć miejsce, w którym temu procesowi podano identyfikator blokad, na które oczekuje. Próbuje także dowiedzieć się, jaki identyfikator procesu ma proces oczekujący na blokadę. Możesz więc uruchomić tę funkcję pg_blocking_pids.

A to może być bardzo przydatne. Dodaliśmy to dopiero w wersji 9.6, więc ta funkcja ma dopiero 5 lat, ale jest bardzo, bardzo przydatna. To samo tyczy się drugiego żądania. Pokazuje dokładnie to, co powinniśmy zobaczyć.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Właśnie o tym chciałem z tobą porozmawiać. I tak jak się spodziewałam, wykorzystaliśmy cały czas, bo było mnóstwo zjeżdżalni. Slajdy są dostępne do pobrania. Chciałbym podziękować za to, że tu jesteście. Jestem pewien, że będziesz zadowolony z dalszej części konferencji, dziękuję bardzo!

Pytania:

Na przykład, jeśli próbuję zaktualizować wiersze, a druga sesja próbuje usunąć całą tabelę. O ile rozumiem, powinno istnieć coś w rodzaju blokady celowej. Czy w Postgresie jest coś takiego?

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

Wróćmy do samego początku. Być może pamiętasz, że kiedy cokolwiek zrobisz, na przykład, gdy wykonasz SELECT, wystawimy blokadę AccessShareLock. Zapobiega to upuszczeniu stołu. Jeśli więc na przykład chcesz zaktualizować wiersz w tabeli lub usunąć wiersz, wówczas ktoś nie może usunąć całej tabeli w tym samym czasie, ponieważ przytrzymujesz blokadę AccessShareLock nad całą tabelą i nad wierszem. A kiedy już skończysz, będą mogli go usunąć. Ale chociaż bezpośrednio coś tam zmienisz, oni nie będą mogli tego zrobić.

Zróbmy to jeszcze raz. Przejdźmy do przykładu usuwania. I widzisz, jak istnieje ekskluzywna blokada w rzędzie nad całym stołem.

To będzie wyglądać jak ekskluzywny zamek, prawda?

Tak, na to wygląda. Rozumiem, o czym mówisz. Mówisz, że jeśli wykonam WYBÓR, to będę mieć ShareExclusive, a następnie uczynię to Row Exclusive, czy to stanie się problemem? Ale, co zaskakujące, nie stanowi to problemu. Wygląda to na zwiększenie stopnia blokady, ale zasadniczo mam blokadę, która zapobiega usunięciu. A teraz, kiedy wzmocnię tę blokadę, nadal zapobiega ona usunięciu. Więc to nie jest tak, że idę w górę. Oznacza to, że zapobiegł temu wystąpieniu również wtedy, gdy był na niższym poziomie, więc kiedy podniosę jego poziom, nadal zapobiega usunięciu tabeli.

Rozumiem, o czym mówisz. Nie ma tu przypadku eskalacji blokady, w którym próbujesz zrezygnować z jednej blokady, aby wprowadzić silniejszą. Tutaj po prostu zwiększa to zapobieganie we wszystkich obszarach, więc nie powoduje żadnego konfliktu. Ale to dobre pytanie. Dziękuję bardzo, że o to pytasz!

Co musimy zrobić, aby uniknąć sytuacji impasu, gdy mamy wiele sesji, dużą liczbę użytkowników?

Postgres automatycznie zauważa zakleszczenia. I automatycznie usunie jedną z sesji. Jedynym sposobem na uniknięcie martwego blokowania jest blokowanie osób w tej samej kolejności. Kiedy więc spojrzysz na swoją aplikację, często przyczyną zakleszczeń... Wyobraźmy sobie, że chcę zablokować dwie różne rzeczy. Jedna aplikacja blokuje tabelę 1, inna aplikacja blokuje tabelę 2, a następnie tabelę 1. Najłatwiejszym sposobem uniknięcia zakleszczeń jest sprawdzenie aplikacji i upewnienie się, że blokowanie odbywa się w tej samej kolejności we wszystkich aplikacjach. A to zwykle eliminuje 80% problemów, ponieważ różne osoby piszą te aplikacje. A jeśli zablokujesz je w tej samej kolejności, nie wystąpi sytuacja impasu.

Dziękuję bardzo za występ! Mówiłeś o pełnej próżni i, jeśli dobrze rozumiem, pełna próżnia zniekształca kolejność rekordów w oddzielnym magazynie, więc bieżące zapisy pozostają niezmienione. Dlaczego pełna próżnia wymaga wyłącznego dostępu do blokady i dlaczego koliduje z operacjami zapisu?

To dobre pytanie. Powodem jest to, że próżnia pełna zajmuje stół. Zasadniczo tworzymy nową wersję tabeli. A stół będzie nowy. Okazuje się, że będzie to zupełnie nowa wersja stołu. Problem polega na tym, że kiedy to robimy, nie chcemy, aby ludzie to czytali, ponieważ potrzebujemy, aby zobaczyli nową tabelę. A to łączy się z poprzednim pytaniem. Gdybyśmy mogli jednocześnie czytać, nie bylibyśmy w stanie go przenieść i skierować ludzi do nowego stołu. Musielibyśmy poczekać, aż wszyscy skończą czytać tę tabelę, więc jest to zasadniczo sytuacja zamknięta.
Mówimy po prostu, że blokujemy od początku, bo wiemy, że na samym końcu będzie nam potrzebny zamek ekskluzywny, aby wszyscy mogli przenieść się na nowy egzemplarz. Możemy więc potencjalnie rozwiązać ten problem. I robimy to w ten sposób przy jednoczesnym indeksowaniu. Ale jest to znacznie trudniejsze. A to w dużym stopniu wiąże się z Twoim poprzednim pytaniem dotyczącym ekskluzywnego zamka.

Czy można dodać limit czasu blokowania do Postgres? W Oracle mogę na przykład napisać „wybierz, aby zaktualizować” i poczekać 50 sekund przed aktualizacją. To było dobre dla aplikacji. Ale w Postgres albo muszę to zrobić od razu i w ogóle nie czekać, albo poczekać do pewnego czasu.

Tak, możesz wybrać limit czasu dla swoich zamków, dla swoich zamków. Możesz także wydać polecenie „nie ma mowy”, co… jeśli nie możesz od razu uzyskać blokady. Dlatego albo przekroczenie limitu czasu blokady, albo coś innego, co pozwoli ci to zrobić. Nie robi się tego na poziomie syntaktycznym. Odbywa się to jako zmienna na serwerze. Czasami nie można tego użyć.

Czy możesz otworzyć slajd 75?

Tak.

Odblokowanie menedżera blokad Postgres. Bruce'a Momjiana

A moje pytanie jest następujące. Dlaczego oba procesy aktualizacji oczekują błędu 703?

I to jest świetne pytanie. Swoją drogą nie rozumiem, dlaczego Postgres to robi. Ale kiedy stworzono 703, spodziewano się 702. A kiedy pojawiają się 704 i 705, wygląda na to, że nie wiedzą, czego się spodziewają, ponieważ jeszcze niczego nie ma. A Postgres robi to w ten sposób: gdy nie możesz dostać blokady, pisze „Po co cię przetwarzać?”, bo już na kogoś czekasz. Więc po prostu pozwolimy temu wisieć w powietrzu, w ogóle go nie zaktualizujemy. Ale co się tutaj stało? Gdy tylko 702 zakończył proces i 703 otrzymał blokadę, system powrócił. I powiedziała, że ​​teraz czekają na nas dwie osoby. A potem zaktualizujmy je razem. I zaznaczmy, że oboje oczekują.

Nie wiem, dlaczego Postgres to robi. Ale jest problem zwany f…. Wydaje mi się, że nie jest to określenie w języku rosyjskim. Dzieje się tak wtedy, gdy wszyscy czekają na jeden zamek, nawet jeśli na zamek czeka 20 władz. I nagle wszyscy budzą się w tym samym czasie. I wszyscy zaczynają próbować reagować. Ale system sprawia, że ​​wszyscy czekają na 703. Bo wszyscy czekają, a my ich wszystkich natychmiast ustawimy w kolejce. A jeśli pojawi się jakieś inne nowe żądanie, które zostało wygenerowane po tym, na przykład 707, to znowu będzie pustka.

I wydaje mi się, że tak się dzieje, że można powiedzieć, że na tym etapie 702 czeka na 703, a ci, którzy przyjdą później, nie będą mieli żadnego wpisu w tym polu. Ale gdy tylko pierwszy kelner wyjdzie, wszyscy, którzy w tym momencie czekali na aktualizację, otrzymają ten sam token. I tak myślę, że jest to zrobione po to, abyśmy mogli przetwarzać w takiej kolejności, aby były odpowiednio uporządkowane.

Zawsze uważałem to za dość dziwne zjawisko. Bo tutaj na przykład w ogóle ich nie wymieniamy. Ale wydaje mi się, że za każdym razem, gdy dajemy nowy zamek, patrzymy na wszystkich, którzy są w trakcie oczekiwania. Następnie ustawiamy je wszystkie w szeregu. A wtedy każdy nowy, który się pojawi, trafia do kolejki dopiero wtedy, gdy następna osoba zakończy przetwarzanie. Bardzo dobre pytanie. Dziękuję bardzo za pytanie!

Wydaje mi się, że dużo bardziej logiczne jest, gdy 705 oczekuje 704.

Ale problem jest następujący. Technicznie rzecz biorąc, możesz obudzić się albo jedno, albo drugie. I tak obudzimy się albo jedno, albo drugie. Ale co dzieje się w systemie? Możesz zobaczyć jak 703 na samej górze zablokował swój własny identyfikator transakcji. Tak działa Postgres. A 703 jest blokowane przez własny identyfikator transakcji, więc jeśli ktoś chce poczekać, to poczeka na 703. I w zasadzie 703 się zakończy. I dopiero po jego zakończeniu budzi się jeden z procesów. I nie wiemy, na czym dokładnie będzie polegał ten proces. Następnie wszystko przetwarzamy stopniowo. Nie jest jednak jasne, który proces zostanie obudzony jako pierwszy, ponieważ może to być którykolwiek z tych procesów. Zasadniczo mieliśmy harmonogram, który mówił, że możemy teraz obudzić dowolny z tych procesów. Po prostu wybieramy jeden losowo. Zatem należy zwrócić uwagę na oba z nich, ponieważ możemy obudzić którekolwiek z nich.

Problem w tym, że mamy CP-infinity. A zatem jest całkiem prawdopodobne, że uda nam się obudzić później. A jeśli np. obudzimy tego późniejszego, to poczekamy na tego, który właśnie otrzymał blokadę, zatem nie przesądzamy, kto dokładnie zostanie obudzony jako pierwszy. Po prostu stwarzamy taką sytuację, a system obudzi ją w losowej kolejności.

Jest artykuły o zamkach autorstwa Jegora Rogowa. Spójrz, one też są interesujące i przydatne. Temat jest oczywiście strasznie złożony. Dziękuję bardzo, Bruce!

Źródło: www.habr.com

Dodaj komentarz