{"id":87954,"date":"2020-07-12T01:42:48","date_gmt":"2020-07-11T23:42:48","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/unlocking-the-postgres-lock-manager-bryus-momzhian"},"modified":"2020-07-12T01:42:48","modified_gmt":"2020-07-11T23:42:48","slug":"unlocking-the-postgres-lock-manager-bryus-momzhian","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/unlocking-the-postgres-lock-manager-bryus-momzhian","title":{"rendered":"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Skr\u00f3t raportu Bruce'a Momzhiana z 2020 roku \u201eOdblokowanie mened\u017cera blokad Postgresa\u201d.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/1f75fbb0cb41c306c33c823ef55f7238.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>(Uwaga: Wszystkie zapytania SQL z slajd\u00f3w mo\u017cesz uzyska\u0107 pod tym linkiem: <noindex><a rel=\"nofollow\" href=\"http:\/\/momjian.us\/main\/writings\/pgsql\/locking.sql\">http:\/\/momjian.us\/main\/writings\/pgsql\/locking.sql<\/a><\/noindex>)<\/p>\n<p><\/p>\n<p>Cze\u015b\u0107! Cudownie zn\u00f3w by\u0107 tutaj w Rosji. Przepraszam, \u017ce nie mog\u0142em przyjecha\u0107 w zesz\u0142ym roku, ale w tym roku mamy z Ivanem wielkie plany. Mam nadziej\u0119, \u017ce b\u0119d\u0119 tutaj znacznie cz\u0119\u015bciej. Uwielbiam przyje\u017cd\u017ca\u0107 do Rosji. Odwiedz\u0119 Tiume\u0144 i Twer. Bardzo si\u0119 ciesz\u0119, \u017ce b\u0119d\u0119 m\u00f3g\u0142 odwiedzi\u0107 te miasta. <\/p>\n<p><\/p>\n<p>Nazywam si\u0119 Bruce Momjian. Pracuj\u0119 w EnterpriseDB i zajmuj\u0119 si\u0119 Postgresem od ponad 23 lat. Mieszkam w Filadelfii w USA. Podr\u00f3\u017cuj\u0119 oko\u0142o 90 dni w roku i uczestnicz\u0119 w oko\u0142o 40 konferencjach. Moja <noindex><a rel=\"nofollow\" href=\"https:\/\/momjian.us\/\">strona internetowa<\/a><\/noindex>, kt\u00f3ra zawiera slajdy, kt\u00f3re teraz wam poka\u017c\u0119. Dlatego po konferencji mo\u017cecie je pobra\u0107 z mojej osobistej strony. Znajduje si\u0119 tam r\u00f3wnie\u017c oko\u0142o 30 prezentacji, a tak\u017ce filmy i wiele wpis\u00f3w na blogu, ponad 500. To do\u015b\u0107 bogate \u017ar\u00f3d\u0142o. I je\u015bli interesuj\u0105 was te materia\u0142y, serdecznie zapraszam do ich wykorzystania. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Kiedy\u015b by\u0142em wyk\u0142adowc\u0105, profesorem, zanim zacz\u0105\u0142em pracowa\u0107 z Postgreaem. I bardzo si\u0119 ciesz\u0119, \u017ce mog\u0119 teraz opowiedzie\u0107 wam to, co zamierzam przekaza\u0107. To jedna z moich najciekawszych prezentacji. Ta prezentacja zawiera 110 slajd\u00f3w. Zaczniemy od prostych rzeczy, a na koniec wyk\u0142ad stanie si\u0119 coraz trudniejszy i wystarczaj\u0105co skomplikowany.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/9c2e95851f3d8dc92d2ca40b5f29cd52.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>To do\u015b\u0107 nieprzyjemna rozmowa. Blokady nie s\u0105 najbardziej popularnym tematem. Chcemy, aby to znikn\u0119\u0142o. To jak chodzenie do dentysty. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/bbb2bf8495d458c5bc4a162880a807bb.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ol>\n<li>Blokady s\u0105 problemem dla wielu os\u00f3b pracuj\u0105cych w bazach danych, kt\u00f3re maj\u0105 jednocze\u015bnie wiele proces\u00f3w. Potrzebuj\u0105 blokady. To znaczy, \u017ce dzisiaj przeka\u017c\u0119 wam podstawow\u0105 wiedz\u0119 na temat blokad. <\/li>\n<li>Identyfikatory transakcji. To do\u015b\u0107 nudna cz\u0119\u015b\u0107 prezentacji, ale musz\u0105 by\u0107 zrozumiane.<\/li>\n<li>Nast\u0119pnie om\u00f3wimy rodzaje blokad. To do\u015b\u0107 mechaniczna cz\u0119\u015b\u0107. <\/li>\n<li>A nast\u0119pnie podamy kilka przyk\u0142ad\u00f3w blokad. I to b\u0119dzie do\u015b\u0107 trudne do zrozumienia. <\/li>\n<\/ol>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/7261d9ed162b7f582ec91d6aa98fac01.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Porozmawiajmy o blokadach.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/13664632ed5ce42ea3ae20830117931e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Terminologia jest u nas do\u015b\u0107 skomplikowana. Ile z was wie, sk\u0105d pochodzi ten fragment? Dwie osoby. To z gry zatytu\u0142owanej \u201eKolosalna przygoda w jaskini\u201d. To by\u0142a tekstowa gra komputerowa z lat 80-tych, wydaje mi si\u0119. Trzeba by\u0142o wej\u015b\u0107 do jaskini, w labirynt, a tekst si\u0119 zmienia\u0142, ale tre\u015b\u0107 by\u0142a mniej wi\u0119cej ta sama za ka\u017cdym razem. Tak pami\u0119tam t\u0119 gr\u0119. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/8e8b88cb4d3fabc9d60bacb771a6ea38.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I tutaj widzimy nazwy blokad, kt\u00f3re przysz\u0142y do nas z Oracle. U\u017cywamy ich. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/37941629c5bde0c387fcd34565e99a9e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tutaj widzimy terminy, kt\u00f3re mnie niepokoj\u0105. Na przyk\u0142ad, SHARE UPDATE EXCLUSIVE. Nast\u0119pnie SHARE RAW EXCLUSIVE. Szczerze m\u00f3wi\u0105c, te nazwy nie s\u0105 zbyt zrozumia\u0142e. Postaramy si\u0119 je przyjrze\u0107 bardziej szczeg\u00f3\u0142owo. Niekt\u00f3re zawieraj\u0105 s\u0142owo \u201eshare\u201d, kt\u00f3re znaczy - oddzieli\u0107. Niekt\u00f3re zawieraj\u0105 s\u0142owo \u201eexclusive\u201d - ekskluzywny. W niekt\u00f3rych zawarte s\u0105 oba te s\u0142owa. Chcia\u0142bym zacz\u0105\u0107 od tego, jak te blokady dzia\u0142aj\u0105. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/dffa5b94dc39bd00b5abc1ef1db9c334.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I r\u00f3wnie\u017c bardzo wa\u017cne jest s\u0142owo \u201edost\u0119p\u201d - access. I s\u0142owo \u201erow\u201d - wiersz. T. j. dystrybucja dost\u0119pu, dystrybucja wierszy. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/1caf91a69510d21c74700bfdcf6f7f46.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jeszcze jeden problem, kt\u00f3ry nale\u017cy zrozumie\u0107 w Postgres, niestety nie b\u0119d\u0119 m\u00f3g\u0142 o nim opowiedzie\u0107 podczas mojej prezentacji, to MVCC. Mam osobn\u0105 prezentacj\u0119 na ten temat na mojej stronie internetowej. I je\u015bli my\u015blisz, \u017ce ta prezentacja jest skomplikowana, to MVCC to prawdopodobnie moja najtrudniejsza tematyka. A je\u015bli jeste\u015b zainteresowany, mo\u017cesz obejrze\u0107 j\u0105 na stronie. Mo\u017cesz tak\u017ce zobaczy\u0107 wideo. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/cbaecfa1a74340ad497b080dfc577eb2.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Kolejna kwestia, kt\u00f3r\u0105 musimy zrozumie\u0107 - to identyfikatory transakcji. Wiele transakcji nie mo\u017ce dzia\u0142a\u0107 bez unikalnych identyfikator\u00f3w. I tutaj mamy wyja\u015bnienie, czym jest transakcja. W Postgres istniej\u0105 dwa systemy numeracji transakcji. Wiem, \u017ce to nie jest zbyt estetyczne rozwi\u0105zanie. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/52d603a076ce0e74f39c00bdf6b06ef5.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pami\u0119taj r\u00f3wnie\u017c, \u017ce slajdy b\u0119d\u0105 do\u015b\u0107 trudne do przyswojenia, wi\u0119c na czerwono zaznaczone elementy to te, na kt\u00f3re nale\u017cy zwr\u00f3ci\u0107 szczeg\u00f3ln\u0105 uwag\u0119.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/df937b924ec12772447269e01cdf7cf9.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/momjian.us\/main\/writings\/pgsql\/locking.sql\">http:\/\/momjian.us\/main\/writings\/pgsql\/locking.sql<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Patrzymy. Na czerwono zaznaczony jest numer transakcji. Tutaj pokazana jest funkcja SELECT pg_back. Zwraca moj\u0105 transakcj\u0119 i ID tej transakcji. <\/p>\n<p><\/p>\n<p>Jeszcze jeden moment, je\u015bli podoba Ci si\u0119 ta prezentacja i chcesz j\u0105 uruchomi\u0107 w swojej bazie danych, mo\u017cesz klikn\u0105\u0107 w ten r\u00f3\u017cowy link i pobra\u0107 SQL dla tej prezentacji. Mo\u017cesz po prostu uruchomi\u0107 go w swoim PSQL, a ca\u0142a prezentacja pojawi si\u0119 na Twoim ekranie natychmiast. Nie zawiera ona kolor\u00f3w, ale przynajmniej b\u0119dziemy mogli j\u0105 zobaczy\u0107.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/aeaeecc16029e5fa54583223069578d1.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>W tym przypadku widzimy identyfikator transakcji. To numer, kt\u00f3ry jej nadali\u015bmy. Istnieje tak\u017ce inny typ identyfikatora transakcji w Postgres, kt\u00f3ry nazywa si\u0119 wirtualnym identyfikatorem transakcji.<\/p>\n<p><\/p>\n<p>Musimy to zrozumie\u0107. To bardzo wa\u017cne, inaczej nie b\u0119dziemy mogli zrozumie\u0107 blokady w Postgres.<\/p>\n<p><\/p>\n<p>Wirtualny identyfikator transakcji to identyfikator transakcji, kt\u00f3ry nie zawiera sta\u0142ych warto\u015bci. Na przyk\u0142ad, je\u015bli uruchamiam polecenie SELECT, prawdopodobnie nie zmieni\u0119 bazy danych, nie zablokuj\u0119 niczego. Dlatego, kiedy uruchamiamy prosty SELECT, nie nadajemy tej transakcji sta\u0142ego identyfikatora. Przekazujemy jej tylko wirtualny identyfikator.<\/p>\n<p><\/p>\n<p>Zwi\u0119ksza to wydajno\u015b\u0107 Postgres, poprawiaj\u0105c mo\u017cliwo\u015bci czyszczenia, dlatego wirtualny identyfikator transakcji sk\u0142ada si\u0119 z dw\u00f3ch liczb. Pierwsza liczba przed uko\u015bnikiem to identyfikator backendu. A po prawej stronie widzimy po prostu licznik.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/8813ab1f15f71ce4fbb5448bde2cfba6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dlatego, je\u015bli uruchamiam zapytanie, m\u00f3wi, \u017ce identyfikator backendu to 2. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/b6f4e3a2ad8d6801af2716b0bd3bf75a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A je\u015bli uruchamiam seri\u0119 takich transakcji, widzimy, \u017ce licznik za ka\u017cdym razem zwi\u0119ksza si\u0119, gdy uruchamiam zapytanie. Na przyk\u0142ad, gdy uruchamiam zapytanie 2\/10, 2\/11, 2\/12 itd. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/0b5fbb897233ff3dd07b807af4d4e0d7.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pami\u0119taj, \u017ce mamy tutaj dwie kolumny. Po lewej widzimy wirtualny identyfikator transakcji \u2013 2\/12. A po prawej mamy sta\u0142y identyfikator transakcji. To pole jest puste. Ta transakcja nie modyfikuje bazy danych. Dlatego nie przypisuj\u0119 jej sta\u0142ego identyfikatora transakcji.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/e8ab3dc34ce6036eedfb87e56f41d01a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Gdy tylko uruchamiam polecenie analizowa\u0107 (ANALYZE), to samo zapytanie zwraca mi sta\u0142y identyfikator transakcji. Zobacz, jak to si\u0119 zmieni\u0142o. Wcze\u015bniej nie mia\u0142em tego identyfikatora, a teraz si\u0119 pojawi\u0142.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/ca546a3006bfc0881ef1c7e7fe878c7a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wi\u0119c, oto kolejne zapytanie, kolejna transakcja. Wirtualny identyfikator transakcji to 2\/13. Je\u015bli poprosz\u0119 o sta\u0142y identyfikator transakcji, to po uruchomieniu zapytania go otrzymam. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/69bf4082be1832504a823f6420d62609.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wi\u0119c jeszcze raz. Mamy wirtualny identyfikator transakcji i sta\u0142y identyfikator transakcji. Po prostu zrozum ten moment, aby zrozumie\u0107 zachowanie Postgres.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/ecc70c44ceee36dab9c98bcfcebf4c8f.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Przechodzimy do trzeciej sekcji. Tutaj om\u00f3wimy r\u00f3\u017cne typy blokad w Postgres. To nie jest zbyt interesuj\u0105ce. Ostatnia sekcja b\u0119dzie znacznie ciekawsza. Jednak musimy om\u00f3wi\u0107 podstawowe kwestie, aby zrozumie\u0107, co b\u0119dzie dalej. <\/p>\n<p><\/p>\n<p>Przejdziemy przez t\u0119 sekcj\u0119, przyjrzymy si\u0119 ka\u017cdemu typowi blokad. Poka\u017c\u0119 wam przyk\u0142ady, jak s\u0105 ustalane, jak dzia\u0142aj\u0105, zaprezentuj\u0119 kilka zapyta\u0144, kt\u00f3re mo\u017cna u\u017cy\u0107, aby zobaczy\u0107, jak dzia\u0142aj\u0105 blokady w Postgres.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/2074b6c82ff77525090c868d0c9f09f5.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aby stworzy\u0107 zapytanie i zobaczy\u0107, co si\u0119 dzieje w Postgres, musimy wyda\u0107 zapytanie w systemowym widoku. W tym przypadku na czerwono wyr\u00f3\u017cniony jest pg_lock. Pg_lock to tabela systemowa, kt\u00f3ra informuje nas, jakie blokady s\u0105 obecnie u\u017cywane w Postgres.<\/p>\n<p><\/p>\n<p>Jednak\u017ce trudno mi pokaza\u0107 wam pg_lock samodzielnie, poniewa\u017c jest to do\u015b\u0107 skomplikowane. Dlatego stworzy\u0142em widok, kt\u00f3ry pokazuje pg_locks. Wykonuje on r\u00f3wnie\u017c dla mnie pewne zadania, kt\u00f3re pozwalaj\u0105 lepiej zrozumie\u0107 sytuacj\u0119. To znaczy, wyklucza moje blokady, moj\u0105 w\u0142asn\u0105 sesj\u0119 itd. To po prostu standardowy SQL i pozwala lepiej pokaza\u0107, co si\u0119 dzieje. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/8372fff8ded76ace47591850b74db860.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Kolejnym problemem jest to, \u017ce ten widok jest bardzo obszerny, dlatego musz\u0119 stworzy\u0107 drugi \u2013 lockview2.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/559745d390f99d7d28199be76d3abc18.png\" style=\"display:block;margin: 0 auto;\" \/> I pokazuje mi dodatkowe kolumny z tabeli. I jeszcze jeden, kt\u00f3ry pokazuje mi pozosta\u0142e kolumny. To do\u015b\u0107 skomplikowane, wi\u0119c stara\u0142em si\u0119 to przedstawi\u0107 jak najpro\u015bciej. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/48d69895241e1f58ac5ef0e385a67644.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Zatem stworzyli\u015bmy tabel\u0119 o nazwie Lockdemo. I dodali\u015bmy tam jeden wiersz. To nasza przyk\u0142adowa tabela. Stworzymy sekcje, aby po prostu pokaza\u0107 wam przyk\u0142ady blokad. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/2c5a64d5488c1eef7def91a5e0657519.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I tak, jeden wiersz, jedna kolumna. Pierwszy typ blokady nazywa si\u0119 ACCESS SHARE. Jest to najmniej restrykcyjna blokada. Oznacza to, \u017ce praktycznie nie koliduje z innymi blokadami.<\/p>\n<p><\/p>\n<p>Je\u015bli chcemy explicite zdefiniowa\u0107 blokad\u0119, uruchamiamy polecenie \u201elock table\u201d. To wyra\u017anie zablokuje, tj. w trybie ACCESS SHARE uruchamiamy lock table. Je\u015bli uruchomi\u0119 PSQL w tle, to w ten spos\u00f3b uruchamiam drug\u0105 sesj\u0119 z mojej pierwszej sesji. Co wi\u0119c tutaj zrobi\u0119? Przechodz\u0119 do innej sesji i m\u00f3wi\u0119 jej \u201epoka\u017c mi lockview dla tego zapytania\u201d. I tutaj mam AccessShareLock w tej tabeli. To dok\u0142adnie to, o co prosi\u0142em. I on m\u00f3wi, \u017ce blokada zosta\u0142a przydzielona. Bardzo prosto. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/458adfcb7fb0de3f4b23bc703a78534e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nast\u0119pnie, je\u015bli spojrzymy na drug\u0105 kolumn\u0119, to tam nic nie ma. S\u0105 puste. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/f3b848f3c9bfaf1a41273effeb0965e1.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Je\u015bli uruchamiam polecenie \u201eSELECT\u201d, to jest to implicytna (jawna) metoda, aby za\u017c\u0105da\u0107 AccessShareLock. Dlatego wypuszczam moj\u0105 tabel\u0119 i uruchamiam zapytanie, a zapytanie zwraca kilka wierszy. W jednym z wierszy widzimy AccessShareLock. Tak wi\u0119c SELECT powoduje utworzenie AccessShareLock w tabeli. I praktycznie nie koliduje z niczym, poniewa\u017c to jest blokada niskiego poziomu. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/0d9526dbea91b5e5f4e0e05a20b16d38.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Co je\u015bli uruchomi\u0119 SELECT i b\u0119d\u0119 mia\u0142 trzy r\u00f3\u017cne tabele? Wcze\u015bniej uruchamia\u0142em tylko jedn\u0105 tabel\u0119, teraz uruchamiam trzy: pg_class, pg_namespace i pg_attribute.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/415be5bb7cb7cbbe6bbfd0ab1b9b2d3e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A teraz, kiedy patrz\u0119 na zapytanie, widz\u0119 9 AccessShareLocks w trzech tabelach. Dlaczego? Na niebiesko zaznaczone s\u0105 trzy tabele: pg_attribute, pg_class, pg_namespace. Mo\u017cesz r\u00f3wnie\u017c zauwa\u017cy\u0107, \u017ce wszystkie indeksy, kt\u00f3re s\u0105 zdefiniowane za po\u015brednictwem tych tabel, maj\u0105 r\u00f3wnie\u017c AccessShareLock.<\/p>\n<p><\/p>\n<p>I to jest blokada, kt\u00f3ra praktycznie nie koliduje z innymi. A wszystko, co robi, to po prostu nie pozwala nam zresetowa\u0107 tabeli, dop\u00f3ki jej nie wybierzemy. To ma sens. To znaczy, je\u015bli wybieramy tabel\u0119, w tym momencie znika, to by\u0142oby b\u0142\u0119dne, wi\u0119c <strong>AccessShare \u2013 to blokada niskiego poziomu, kt\u00f3ra m\u00f3wi nam \u201enie usuwaj tej tabeli, dop\u00f3ki pracuj\u0119\u201d<\/strong>. W zasadzie to wszystko, co robi. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/99c896a5a57f7d64077fad9368f9b41a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>ROW SHARE to blokada, kt\u00f3ra troch\u0119 si\u0119 r\u00f3\u017cni. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/bbd833128a83fba3b7271f89e6115425.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>We\u017amy przyk\u0142ad. <strong>SELECT ROW SHARE to spos\u00f3b blokowania ka\u017cdej wiersza osobno<\/strong>. Tak wi\u0119c nikt nie mo\u017ce ich usun\u0105\u0107 ani zmieni\u0107, dop\u00f3ki je ogl\u0105damy. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/7f7384d5c4c04ffc771192359d785c43.png\" style=\"display:block;margin: 0 auto;\" \/>C\u00f3\u017c, co robi SHARE LOCK? Widzimy, \u017ce ID transakcji 681 dla SELECT-a. I to jest interesuj\u0105ce. Co si\u0119 tutaj wydarzy\u0142o? Po raz pierwszy widzimy numer w polu \u201eLock\u201d. Bierzemy ID transakcji, a on m\u00f3wi, \u017ce blokuje go w trybie ekskluzywnym. Wszystko, co robi, to informuje, \u017ce mam wiersz, kt\u00f3ry technicznie jest zablokowany gdzie\u015b w tabeli. Ale nie wskazuje, gdzie dok\u0142adnie. Nieco p\u00f3\u017aniej przyjrzymy si\u0119 temu dok\u0142adniej.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/284a303fd34c167d453facb46e207067.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tutaj m\u00f3wimy, \u017ce blokada jest przez nas u\u017cywana.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/12a2be61a2f406fc125dcab11983e9c6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Zatem blokada ekskluzywna explicite (jawnie) oznacza, \u017ce jest ekskluzywna. I je\u015bli usuniesz wiersz w tej tabeli, to tak si\u0119 stanie, jak mo\u017cesz zobaczy\u0107. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/23ed127ff4a033a6f51c0b5566fd6a7c.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>SHARE EXCLUSIVE \u2013 to d\u0142u\u017csza blokada.<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/12e6b0217c528ef5034eb328553fefe9.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>To jest polecenie (ANALYZE) analityka, kt\u00f3re b\u0119dzie u\u017cywane.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/d11480b90b74c8165a60bd73cf24a683.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>SHARE LOCK \u2013 mo\u017cesz explicite zablokowa\u0107 w trybie share.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/ee2a5ad8d0da5fb94865abe3cfa70fa7.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Mo\u017cesz r\u00f3wnie\u017c stworzy\u0107 unikalny indeks. I tam mo\u017cesz zobaczy\u0107 SHARE LOCK, kt\u00f3ry jest jego cz\u0119\u015bci\u0105. I blokuje tabel\u0119 oraz nak\u0142ada na ni\u0105 blokad\u0119 SHARE LOCK.<\/p>\n<p><\/p>\n<p><strong>Domy\u015blnie SHARE LOCK na tabeli oznacza, \u017ce inni mog\u0105 czyta\u0107 tabel\u0119, ale nikt nie mo\u017ce jej modyfikowa\u0107. I to w\u0142a\u015bnie si\u0119 dzieje, gdy tworzysz unikalny indeks.<\/strong><\/p>\n<p><\/p>\n<p>Je\u015bli tworz\u0119 unikalny indeks r\u00f3wnocze\u015bnie, to b\u0119d\u0119 mia\u0142 inny typ blokady, poniewa\u017c, jak pami\u0119tasz, u\u017cycie r\u00f3wnoleg\u0142ych indeks\u00f3w zmniejsza zapotrzebowanie na blokady. I je\u015bli zastosuj\u0119 normaln\u0105 blokad\u0119, normalny indeks, to tym samym zapobiegam zapisywaniu w indeksie tabeli podczas jego tworzenia. Je\u015bli u\u017cywam r\u00f3wnoleg\u0142ego indeksu, to potrzebuj\u0119 u\u017cy\u0107 innego typu blokady. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/5952ba48cda26f907d0d9265a933e880.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>SHARE ROW EXCLUSIVE \u2013 zn\u00f3w mo\u017cna j\u0105 ustawi\u0107 explicite (jawnie).<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/5d780961d3a2e6aa0f82287fb4822782.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Lub mo\u017cemy stworzy\u0107 regu\u0142\u0119, tzn. wzi\u0105\u0107 jaki\u015b okre\u015blony przypadek, w kt\u00f3rym b\u0119dzie u\u017cywana.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/7b0f44c4b44426a8dd7999387b245783.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Blokada EXCLUSIVE oznacza, \u017ce nikt inny nie b\u0119dzie m\u00f3g\u0142 zmienia\u0107 tabeli. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/0b59c38455eb973a10be32c2cae0d2aa.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tutaj widzimy r\u00f3\u017cne typy blokad. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/5ec2fc9ae765dfa28285b9f025212056.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>ACCESS EXCLUSIVE, na przyk\u0142ad, to polecenie blokady. Na przyk\u0142ad, je\u015bli robisz <code>CLUSTER table<\/code>, to oznacza, \u017ce nikt nie b\u0119dzie m\u00f3g\u0142 tam zapisywa\u0107. I blokuje nie tylko sam\u0105 tabel\u0119, ale tak\u017ce indeksy.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/9290594355c0b8cef5a07be3a94f6c24.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>To jest druga strona blokady ACCESS EXCLUSIVE, gdzie widzimy konkretnie, co ona blokuje w tabeli. Blokuje pojedyncze wiersze tabeli, co jest do\u015b\u0107 interesuj\u0105ce.<\/p>\n<p><\/p>\n<p>To wszystko podstawowe informacje, kt\u00f3re chcia\u0142em poda\u0107. M\u00f3wili\u015bmy o blokadach, o identyfikatorach transakcji, rozmawiali\u015bmy o wirtualnych identyfikatorach transakcji i o sta\u0142ych identyfikatorach transakcji. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/b9bc44aa88e6760c11a7d0fe247b4b33.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A teraz przejd\u017amy do przyk\u0142ad\u00f3w blokad. To najciekawsza cz\u0119\u015b\u0107. Spojrzymy na bardzo interesuj\u0105ce przypadki. Moim zadaniem w tej prezentacji jest da\u0107 Wam lepsze zrozumienie tego, co tak naprawd\u0119 robi Postgres, gdy pr\u00f3buje blokowa\u0107 r\u00f3\u017cne rzeczy. Uwa\u017cam, \u017ce bardzo dobrze radzi sobie z blokowaniem poszczeg\u00f3lnych cz\u0119\u015bci. <\/p>\n<p><\/p>\n<p>Sp\u00f3jrzmy na konkretne przyk\u0142ady.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/566ecc5ef289e8fdfa5a96bd8b3daa80.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Zacznijmy od tabel i jednej linii w tabeli. Gdy co\u015b wstawiam, uzyskuj\u0119 ExclusiveLock, identyfikator transakcji i ExclusiveLock na tabeli. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/840b23a8b942211c93e233006fd3fe4b.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A co si\u0119 stanie, je\u015bli wstawi\u0119 jeszcze dwa wiersze? Mamy teraz trzy wiersze w naszej tabeli. Wstawi\u0142em jeden wiersz i uzyska\u0142em takie wyniki. A je\u015bli wstawiam jeszcze dwa wiersze, co jest dziwnego? Jest tu pewna dziwno\u015b\u0107, poniewa\u017c doda\u0142em trzy wiersze do tej tabeli, ale nadal mam dwa wiersze w tabeli blokad. I to jest zasadniczo podstawowe zachowanie Postgresa.<\/p>\n<p><\/p>\n<p>Wielu my\u015bli, \u017ce je\u015bli w bazie danych blokujesz 100 wierszy, b\u0119dziesz musia\u0142 stworzy\u0107 100 wpis\u00f3w blokad. Je\u015bli blokuj\u0119 od razu 1000 wierszy, to b\u0119d\u0119 potrzebowa\u0142 1000 takich zapyta\u0144. A je\u015bli potrzebuj\u0119 zablokowa\u0107 milion lub miliard. Ale je\u015bli zrobimy to w ten spos\u00f3b, to nie b\u0119dzie dobrze dzia\u0142a\u0107. Je\u015bli u\u017cywasz systemu, kt\u00f3ry tworzy wpisy blokad dla ka\u017cdego pojedynczego wiersza, widzisz, \u017ce to jest skomplikowane. Poniewa\u017c musisz okre\u015bli\u0107 tabel\u0119 blokad, kt\u00f3ra mo\u017ce si\u0119 przepe\u0142ni\u0107, ale Postgres tak nie robi. <\/p>\n<p><\/p>\n<p>Na tym slajdzie wa\u017cne jest, \u017ce wyra\u017anie pokazuje si\u0119, \u017ce istnieje jeszcze jeden system, kt\u00f3ry dzia\u0142a wewn\u0105trz MVCC, kt\u00f3ry blokuje poszczeg\u00f3lne wiersze. Dlatego, gdy blokujesz miliardy wierszy, Postgres nie tworzy miliarda oddzielnych komend blokad. I to bardzo dobrze wp\u0142ywa na wydajno\u015b\u0107. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/09ee01fffbb9bd00c84f2ebce51458cc.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A co z aktualizacj\u0105? Aktualnie aktualizuj\u0119 wiersz i mo\u017cesz zauwa\u017cy\u0107, \u017ce jednocze\u015bnie wykonuje dwie r\u00f3\u017cne operacje. Zablokowa\u0142 jednocze\u015bnie tabel\u0119, ale r\u00f3wnie\u017c zablokowa\u0142 indeks. Musia\u0142 zablokowa\u0107 indeks, poniewa\u017c na tej tabeli s\u0105 unikalne ograniczenia. Chcemy mie\u0107 pewno\u015b\u0107, \u017ce nikt go nie zmienia, dlatego go blokujemy.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/3e72d68af2d5ae3cc062b6e8b6da343b.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A co b\u0119dzie, je\u015bli chc\u0119 zaktualizowa\u0107 dwa wiersze? Widzimy, \u017ce zachowuje si\u0119 tak samo. Przeprowadzamy dwa razy wi\u0119cej aktualizacji, ale dok\u0142adnie tak\u0105 sam\u0105 liczb\u0119 blokad wierszy. <\/p>\n<p><\/p>\n<p>Je\u015bli jeste\u015b ciekawy, jak to dzia\u0142a w Postgresie, musisz przes\u0142ucha\u0107 moje wyst\u0105pienia na temat MVCC, aby dowiedzie\u0107 si\u0119, jak Postgres wewn\u0119trznie oznacza te wiersze, kt\u00f3re zmienia. Postgres ma spos\u00f3b, w jaki to robi, ale nie robi tego na poziomie blokady tabeli, lecz na ni\u017cszym i bardziej efektywnym poziomie.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/7e119822b0fb7c5aa3c4a463841bc8e1.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A co, je\u015bli chc\u0119 co\u015b usun\u0105\u0107? Je\u015bli usuwam, na przyk\u0142ad, jeden wiersz i nadal mam swoje dwa wprowadzone blokady, a nawet je\u015bli chcia\u0142bym usun\u0105\u0107 je wszystkie, to one wci\u0105\u017c tam s\u0105.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/c329f9fbc478a25396ea04102715973e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Na przyk\u0142ad, je\u015bli chc\u0119 wstawi\u0107 1 000 wierszy, a potem albo usun\u0105\u0107, albo doda\u0107 1 000 wierszy, to te poszczeg\u00f3lne wiersze, kt\u00f3re dodaj\u0119 lub zmieniam, nie s\u0105 tutaj zapisywane. Zapisuj\u0105 si\u0119 na ni\u017cszym poziomie wewn\u0105trz samego wiersza. Podczas wyst\u0105pienia o MVCC m\u00f3wi\u0142em o tym szczeg\u00f3\u0142owo. Ale bardzo wa\u017cne jest, aby przy analizowaniu blokad upewni\u0107 si\u0119, \u017ce masz blokad\u0119 na poziomie tabeli i \u017ce tutaj nie widzisz, jak zapisywane s\u0105 poszczeg\u00f3lne wiersze. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/5683ca83f5c17da7928fae96c307c2d6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A co z eksplicitn\u0105 blokad\u0105?<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/a1746f121884c898c91e3b5d2ef517b8.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Je\u015bli klikn\u0119 'zaktualizuj', to mam dwa zablokowane wiersze. A je\u015bli zaznacz\u0119 je wszystkie i klikn\u0119 'aktualizuj wsz\u0119dzie', to wci\u0105\u017c pozostaj\u0105 mi dwie blokady. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/5d5388e5d0aff39042a9cd69edc91eea.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nie tworzymy oddzielnych zapis\u00f3w dla ka\u017cdego pojedynczego wiersza. Bo wtedy spada wydajno\u015b\u0107, mo\u017ce by\u0107 ich za du\u017co. I mo\u017cemy znale\u017a\u0107 si\u0119 w nieprzyjemnej sytuacji. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/54e88ed51e705701a8b3ddaa4a784d75.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I to samo, je\u015bli zrobimy shared, mo\u017cemy zrobi\u0107 to 30 razy. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/ab9c26e9be090d85b09070ec5ba0d64d.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Przywracamy nasz\u0105 tabel\u0119, wszystko usuwamy, a potem ponownie wstawiamy jeden wiersz.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/2d0a5b75f5cd08dca97b61bbae6a6cbd.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In Postgres, another type of behavior you see is a well-known and desired one\u2014namely, that you can conduct updates or selects. And you can do this simultaneously. A select does not block an update, and the same goes in the reverse direction. We tell the reader not to block the writer, and the writer does not block the reader. <\/p>\n<p><\/p>\n<p>I'll show you an example of this. I will make a selection now. We'll then do an INSERT. And you will be able to see\u2014694. You will see the ID of the transaction that performed this insert. And that's how it works. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/f80f3b68ef43a75a9590ff200741ce83.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>And if I now look at my backend ID, it has become\u2014695. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/65bc487bbfd7b325aa5cffa7373a40a4.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>And I can see that 695 appears in my table. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/6ac586641f978615db4d021e85ef702a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>And if I perform an update like this, I get another case. In this situation, 695 is an exclusive lock, and updates exhibit the same behavior, but there is no conflict between them, which is quite unusual. <\/p>\n<p><\/p>\n<p>And you may notice that at the top there's a ShareLock, while at the bottom there's an ExclusiveLock. And both transactions were completed.<\/p>\n<p><\/p>\n<p>And you need to listen to my talk on MVCC to understand how this works. But this illustrates that you can do it simultaneously, i.e., perform SELECT and UPDATE at the same time.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/3bcf43cdb9ee72ea75e17c3bf71f3407.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Let's reset and perform one operation again. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/fdae265dbebb0fae66e47cd4eb4b1bd6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>If you try to run two updates on the same row simultaneously, it will get locked. And remember, I said that the reader does not block the writer, while the writer blocks the reader, but one writer blocks another writer. That is, we cannot have two people updating the same row at the same time. One must wait for the other to finish. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/ef9adfe81107468dfea1c5a837b28aaa.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>And to illustrate this, I will look at the Lockdemo table. And we'll examine one row. In transaction 698.<\/p>\n<p><\/p>\n<p>We updated this to 2. 699 is the first update. And it either went through successfully, or it's in a pending transaction waiting for us to confirm or cancel. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/9794811cdc204141a74f67ee98fca1f6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ale zwr\u00f3\u0107 uwag\u0119 na co\u015b innego \u2013 2\/51 \u2013 to nasza pierwsza transakcja, nasza pierwsza sesja. 3\/112 \u2013 to drugi \u017c\u0105danie, kt\u00f3re pojawi\u0142o si\u0119 na g\u00f3rze i kt\u00f3re zmieni\u0142o t\u0119 warto\u015b\u0107 na 3. Je\u015bli zauwa\u017cysz, g\u00f3rna sesja zablokowa\u0142a si\u0119 sama, kt\u00f3ra ma 699. Ale 3\/112 nie zapewni\u0142y blokady. W kolumnie Lock_mode napisano, \u017ce czeka. Czeka na 699. I je\u015bli spojrzysz, gdzie jest 699, jest wy\u017cej. A co zrobi\u0142a pierwsza sesja? Utworzy\u0142a blokad\u0119 ekskluzywn\u0105 na swoim w\u0142asnym identyfikatorze transakcyjnym. Tak dzia\u0142a Postgres. Blokuje w\u0142asny identyfikator transakcyjny. I je\u015bli chcesz poczeka\u0107, a\u017c kto\u015b potwierdzi lub wycofa, musisz czeka\u0107, a\u017c b\u0119dzie oczekuj\u0105ca transakcja. Dlatego mo\u017cemy zobaczy\u0107 dziwny wiersz. <\/p>\n<p><\/p>\n<p>Sp\u00f3jrzmy ponownie. Po lewej widzimy nasze id przetwarzania. W drugiej kolumnie widzimy nasz wirtualny identyfikator transakcji, a w trzeciej widzimy lock_type. Co to oznacza? W zasadzie m\u00f3wi, \u017ce blokuje identyfikator transakcyjny. Ale zauwa\u017c, \u017ce we wszystkich wierszach na dole napisano relation. Dlatego masz dwa rodzaje blokad w tabeli. Jest blokada relation. A tak\u017ce jest blokada transactionid, gdzie sami blokujemy, to dok\u0142adnie to, co si\u0119 dzieje w pierwszym wierszu lub na samym dole, gdzie transactionid, gdzie czekamy na zako\u0144czenie operacji 699. <\/p>\n<p><\/p>\n<p>Patrz\u0119, co si\u0119 tutaj dzieje. I jednocze\u015bnie zachodz\u0105 tutaj dwie rzeczy. Patrzysz na blokad\u0119 wed\u0142ug identyfikatora transakcyjnego w pierwszym wierszu, kt\u00f3ra blokuje sama siebie. I blokuje sama siebie, aby zmusi\u0107 ludzi do czekania. <\/p>\n<p><\/p>\n<p>Je\u015bli spojrzysz na 6. wiersz, to ta sama zapis, co pierwszy. Dlatego transakcja 699 jest blokowana. 700 r\u00f3wnie\u017c si\u0119 samoblokuje. A potem w dolnym wierszu zobaczysz, \u017ce czekamy, a\u017c 699 zako\u0144czy swoj\u0105 operacj\u0119.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/e712a48cdb9ddc496e4e196eb3bb97c3.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A w lock_type, tuple widzisz liczby. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/575245898d8455f00583659264b96ce9.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Mo\u017cesz zobaczy\u0107, \u017ce jest 0\/10. To numer strony, a tak\u017ce offset tego konkretnego wiersza. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/7059c7661fc81a7101b2d92d38b6f64c.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I widzisz, \u017ce zmienia si\u0119 na 0\/11, gdy aktualizujemy. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/4572ef7afc0ba8c8bbf5706ce9415d65.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ale tak naprawd\u0119 \u2013 to 0\/10, poniewa\u017c wyst\u0119puje oczekiwanie na t\u0119 operacj\u0119. Mo\u017cemy zobaczy\u0107, \u017ce to ten wiersz, kt\u00f3ry czekam, aby potwierdzi\u0107. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/9dc6fb0e3dee8c0b1ccbb724d0bb6c75.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Gdy tylko to potwierdzimy i naci\u015bniemy commit, a aktualizacja si\u0119 zako\u0144czy, to co dostajemy z powrotem. Transakcja 700 to jedyne zablokowanie, nie czeka ju\u017c na nikogo, poniewa\u017c zosta\u0142a zakomitowana. Po prostu czeka na zako\u0144czenie transakcji. Gdy tylko 699 si\u0119 ko\u0144czy, nie czekamy ju\u017c na nic. A teraz transakcja 700 m\u00f3wi, \u017ce wszystko jest w porz\u0105dku, \u017ce wszystkie blokady, kt\u00f3re s\u0105 potrzebne, ma we wszystkich dozwolonych tabelach. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/42bc10a0c5bbda9bcf3a40f0dd87bc6b.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aby jeszcze bardziej skomplikowa\u0107 t\u0119 spraw\u0119, tworzymy kolejny widok, kt\u00f3ry tym razem dostarczy nam hierarchi\u0119. Nie oczekuj\u0119, \u017ce zrozumiecie ten zapytanie. Ale to da nam ja\u015bniejszy obraz tego, co si\u0119 dzieje. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/855f6dd22cba114b051e4eaac106c0ea.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>To jest rekurencyjny widok, kt\u00f3ry ma tak\u017ce dodatkow\u0105 sekcj\u0119. A nast\u0119pnie znowu zwraca wszystko razem. U\u017cyjmy tego. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/fdb54fae54fb87131c13d67a2f66fae2.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Co je\u015bli zrobimy trzy r\u00f3wnoczesne aktualizacje i powiemy, \u017ce rz\u0105d teraz wynosi trzy. I zmienimy 3 na 4. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/f28e0d58e223ef9ccca9ba0acab5b0ce.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I oto widzimy 4. A identyfikator transakcji 702. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/49553b4dc4bb4c07db099fd26a6da22c.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nast\u0119pnie zmieni\u0119 4 na 5. A 5 na 6, a 6 na 7. I kolejkuj\u0119 rz\u0105d ludzi, kt\u00f3rzy b\u0119d\u0105 czeka\u0107, a\u017c ta jedna transakcja si\u0119 zako\u0144czy.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/7f4a4fef1745ad9cdcd602aa0474f6ec.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I wszystko staje si\u0119 jasne. Jaka jest pierwsza kolejka? To 702. To identyfikator transakcji, kt\u00f3ry pocz\u0105tkowo ustawi\u0142 t\u0119 warto\u015b\u0107. A co mam zapisane w kolumnie Granted? Mam oznaczenia <code>f<\/code>. To s\u0105 moje aktualizacje, kt\u00f3re (5, 6, 7) nie mog\u0105 by\u0107 zatwierdzone, poniewa\u017c czekamy, a\u017c identyfikator transakcji 702 si\u0119 zako\u0144czy. Mamy blokad\u0119 identyfikatora transakcji. I dostajemy 5 blokad transakcyjnych ID.<\/p>\n<p><\/p>\n<p>A je\u015bli spojrzysz na 704, na 705, to tam jeszcze nic nie jest napisane, poniewa\u017c jeszcze nie wiedz\u0105, co si\u0119 dzieje. Po prostu pisz\u0105, \u017ce nie maj\u0105 poj\u0119cia, co si\u0119 dzieje. I po prostu zasn\u0105, poniewa\u017c czekaj\u0105, a\u017c kto\u015b zako\u0144czy i obudzi ich, gdy b\u0119dzie mo\u017cliwo\u015b\u0107 zmiany rz\u0119du. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/af97313e395a47e43d5ca9e6c78271af.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tak to wygl\u0105da. Jasne, \u017ce wszyscy czekaj\u0105 na 12-\u0105 lini\u0119. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/611f2d09dfbf78abe6659f794d4ad4f6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>To, co widzieli\u015bmy tutaj. Oto 0\/12. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/738d1d9b272c6ef2f6e8dffd9cd9c061.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I tak, gdy pierwsza transakcja zostanie zatwierdzona, mo\u017cesz zobaczy\u0107, jak dzia\u0142a hierarchia. I teraz wszystko staje si\u0119 jasne. Wszyscy s\u0105 czystymi. I oni tak naprawd\u0119 wci\u0105\u017c czekaj\u0105. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/7f53df10dd5de8776a07094e68acd195.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Oto, co si\u0119 dzieje. 702 zostaje zatwierdzone. A teraz 703 otrzymuje blokad\u0119 wiersza, a nast\u0119pnie 704 zaczyna czeka\u0107, a\u017c 703 zostanie zatwierdzone. I 705 r\u00f3wnie\u017c na to czeka. A gdy wszystko to si\u0119 ko\u0144czy, same si\u0119 oczyszczaj\u0105. Chcia\u0142bym wskaza\u0107, \u017ce wszyscy ustawiaj\u0105 si\u0119 w kolejce. To bardzo przypomina sytuacj\u0119 z korkiem, gdy wszyscy czekaj\u0105 na pierwsze auto. Pierwsze auto zatrzyma\u0142o si\u0119, a wszyscy ustawiaj\u0105 si\u0119 w d\u0142ugiej linii. Potem ono rusza, nast\u0119pne auto mo\u017ce przejecha\u0107 do przodu i uzyska\u0107 swoj\u0105 blokad\u0119 i tak dalej. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/44d6e80e90fbaa3c726bec204ee10f1b.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A je\u015bli uznali\u015bcie, \u017ce to niewystarczaj\u0105co skomplikowane, to teraz porozmawiamy o deadlockach. Nie wiem, kto z was z nimi si\u0119 spotka\u0142. To do\u015b\u0107 powszechny problem w systemach baz danych. Ale deadlock to sytuacja, w kt\u00f3rej jedna sesja czeka, aby co\u015b wykona\u0142a inna sesja. A w tym czasie inna sesja czeka, \u017ceby pierwsza sesja co\u015b wykona\u0142a. <\/p>\n<p><\/p>\n<p>Na przyk\u0142ad, je\u015bli Ivan m\u00f3wi: \u201eDaj mi co\u015b\u201d, a ja m\u00f3wi\u0119: \u201eNie, dam ci to tylko, je\u015bli mi dasz co\u015b innego\u201d. A on m\u00f3wi: \u201eNie, nie dam ci tego, je\u015bli mi nie dasz\u201d. I w tej sytuacji mamy deadlock. Jestem pewien, \u017ce Ivan tak nie zrobi, ale rozumiesz sens, \u017ce mamy dw\u00f3ch ludzi, kt\u00f3rzy chc\u0105 co\u015b uzyska\u0107, i nie s\u0105 gotowi tego odda\u0107, dop\u00f3ki nie dostan\u0105 tego, czego chc\u0105 od drugiej osoby. I tu nie ma rozwi\u0105zania. <\/p>\n<p><\/p>\n<p>W zasadzie twoja baza danych musi to wykrywa\u0107. A nast\u0119pnie nale\u017cy usun\u0105\u0107 lub zamkn\u0105\u0107 jedn\u0105 z sesji, poniewa\u017c w przeciwnym razie pozostan\u0105 tam na zawsze. Widzimy to w bazach danych, widzimy to w systemach operacyjnych. I wsz\u0119dzie tam, gdzie mamy r\u00f3wnoleg\u0142e procesy, co\u015b takiego mo\u017ce mie\u0107 miejsce. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/6acee6bc304593cdd9e411882b5e3406.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Teraz ustawimy dwa deadlocki. Ustawimy 50 i 80. W pierwszym wierszu wykona\u0142em aktualizacj\u0119 z 50 na 50. Otrzymam numer transakcji 710. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/28a2a7fb4f91b8f8c6c78affb32d249c.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A nast\u0119pnie zmieni\u0119 80 na 81, a 50 na 51. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/f6653c36f5a09934035f4838ff0fa380.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I tak to b\u0119dzie wygl\u0105da\u0107. Dlatego 710 ma blokad\u0119 wiersza, a 711 czeka na potwierdzenie. Widzieli\u015bmy to, gdy aktualizowali\u015bmy. 710 jest w\u0142a\u015bcicielem naszego wiersza. A 711 czeka, a\u017c 710 zako\u0144czy transakcj\u0119.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/99718717ffb2024f4cb92509c2f2b878.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A tam nawet jest napisane, na kt\u00f3rym dok\u0142adnie wierszu mamy deadlock. I tutaj zaczyna si\u0119 to robi\u0107 dziwne.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/423fc8973c29be1504d5bf8828beaa71.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Teraz aktualizujemy 80 na 80. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/3a4b24e58f96205dbdfa8480fac2262a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I tutaj zaczynaj\u0105 si\u0119 deadlocki. 710 oczekuje na odpowied\u017a od 711, a 711 oczekuje na 710. To si\u0119 \u017ale sko\u0144czy. I nie ma z tego wyj\u015bcia. B\u0119d\u0105 oczekiwa\u0107 na siebie nawzajem. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/19394fa0b4a19991a4a4cc1e181c47e8.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I to po prostu zacznie wszystko op\u00f3\u017ania\u0107. A tego nie chcemy. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/94c86723b8b42861d682c75f0c54b552.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I w Postgres s\u0105 sposoby, aby zauwa\u017cy\u0107, kiedy to si\u0119 dzieje. A kiedy to si\u0119 dzieje, otrzymasz taki b\u0142\u0105d. Z tego wida\u0107, \u017ce dany proces oczekuje na SHARE LOCK od innego procesu, czyli kt\u00f3ry jest zablokowany przez proces 711. A ten proces oczekiwa\u0142 na SHARE LOCK na danym ID transakcji i zosta\u0142 zablokowany przez inny proces. Dlatego mamy tutaj sytuacj\u0119 deadlocku.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/88a499d8f03be3c9f5bc6c93aa39c9a6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A czy zdarzaj\u0105 si\u0119 deadlocki trzypodmiotowe? Czy to mo\u017cliwe? Tak. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/20fae4c504b794b678d265a0b1e9e33d.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wprowadzamy te liczby do tabeli. Zmieniamy 40 na 40, wprowadzamy blokad\u0119. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/67b7302545781681b182d4f6ddc93d9f.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Zmieniamy 60 na 61, 80 na 81. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/87aa9680b0160be0d798b2697a0f425d.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A nast\u0119pnie zmieniamy 80, a potem \u2013 bum! <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/dc6179e048dfb42e1e11b75f956182c1.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I 714 teraz oczekuje na 715. 716 oczekuje na 715. I nic z tym nie mo\u017cna zrobi\u0107.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/e5e190437f420783f4fca26f4f04ecd3.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tutaj ju\u017c nie ma dw\u00f3ch os\u00f3b, jest ju\u017c trzy osoby. Chc\u0119 czego\u015b od ciebie, ten chce czego\u015b od trzeciej osoby, a trzecia osoba chce czego\u015b ode mnie. I dostajemy si\u0119 w tr\u00f3jstronne oczekiwanie, poniewa\u017c wszyscy czekamy, a\u017c inna osoba zako\u0144czy to, co ma do zrobienia. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/fde8e3cb14dc05c520693ca2a99cf5f1.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I Postgres wie, w kt\u00f3rym wierszu to si\u0119 dzieje. Dlatego wyda ci nast\u0119puj\u0105ce powiadomienie, kt\u00f3re pokazuje, \u017ce masz problem, gdzie trzy procesy blokuj\u0105 si\u0119 nawzajem. I nie ma ogranicze\u0144. Mo\u017ce to mie\u0107 miejsce tam, gdzie 20 wpis\u00f3w blokuje si\u0119 nawzajem. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/a3dde7b6092b3d2e93c4927b6b42d795.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nast\u0119pnym problemem jest serializable. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/9bff965bafaa03a160c0787bfa8606fb.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Je\u015bli specjalna blokada serializable.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/db310da4461e647ed498e58b1e878fda.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I wracamy do 719. Ma ca\u0142kiem normalne wydanie. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/e7eca0a2191a62014ad949583a45bf2f.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I mo\u017cesz klikn\u0105\u0107, aby wykona\u0107 transakcj\u0119 z serializable.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/4aa78f3e4d07b8ca48d860e8df2dacda.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I rozumiesz, \u017ce masz teraz inny rodzaj blokady SA \u2013 to oznacza serializable. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/f9e79b9b6b1cc581b2178b0285bd3213.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/603dc15cdda0a128c82e87275ca8ba85.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I dlatego mamy nowy rodzaj blokady, kt\u00f3r\u0105 nazywamy SARieadLock, kt\u00f3ra jest blokad\u0105 serii i pozwala na wprowadzanie numer\u00f3w seryjnych.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/ce2644b0e8d8b71035044c56a94621f4.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Mo\u017cesz r\u00f3wnie\u017c wstawia\u0107 unikalne indeksy. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/053a37128688fe22040a2c5a3d5ad477.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>W tej tabeli mamy unikalne indeksy.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/284e50ea2b0b64a9efda8b9224f466ae.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dlatego je\u015bli wprowadz\u0119 tutaj liczb\u0119 2, mam 2. Ale na samej g\u00f3rze wprowadzam jeszcze jedno 2. Widzisz, \u017ce 721 ma ekskluzywn\u0105 blokad\u0119. Ale teraz 722 oczekuje, a\u017c 721 zako\u0144czy swoj\u0105 operacj\u0119, poniewa\u017c nie mo\u017ce wstawi\u0107 2, dop\u00f3ki nie wie, co si\u0119 stanie z 721. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/ee01a45e1e16fe0ab10f5d172048f35f.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A je\u015bli robimy subtransaction.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/58a67f29a50c5e90d3770492eb7a8fc4.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Oto mamy 723.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/6684b92639d48e62b6abf55bea86a951.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Je\u015bli zatrzymujemy punkt, a nast\u0119pnie go aktualizujemy, otrzymujemy nowy identyfikator transakcji. To kolejny rodzaj zachowania, kt\u00f3ry warto zna\u0107. Je\u015bli to zwr\u00f3cimy, identyfikator transakcji znika. 724 znika. Ale teraz pojawia si\u0119 725. <\/p>\n<p><\/p>\n<p>I co pr\u00f3buj\u0119 tutaj zrobi\u0107? Pr\u00f3buj\u0119 pokaza\u0107 wam przyk\u0142ady nietypowych blokad, kt\u00f3re mo\u017cecie napotka\u0107: czy to blokady serializable, czy SAVEPOINT \u2013 to r\u00f3\u017cne rodzaje blokad, kt\u00f3re b\u0119d\u0105 si\u0119 pojawia\u0107 w tabeli blokad. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/3e0b5d4b4e84ca18e0e33cb46013cd70.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>To tworzenie eksplicytnych blokad, kt\u00f3re maj\u0105 pg_advisory_lock. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/2ce5ecd96cec5bcf0f757eb0093759c3.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I widzicie, \u017ce typ blokady jest tu okre\u015blony jako advisory. I jest tu napisane na czerwono \"advisory\". Mo\u017cecie jednocze\u015bnie zablokowa\u0107 to za pomoc\u0105 pg_advisory_unlock.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/5b5ae66d50ce9aaa779bbf47de00b1d7.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ko\u0144cz\u0105c, chcia\u0142bym pokaza\u0107 wam jeszcze jedn\u0105 bardzo ciekaw\u0105 rzecz. Stworz\u0119 inny typ. Ale po\u0142\u0105cz\u0119 tabel\u0119 pg_locks z tabel\u0105 pg_stat_activity. I dlaczego chc\u0119 to zrobi\u0107? Poniewa\u017c pozwoli mi to zobaczy\u0107 i zrozumie\u0107 wszystkie bie\u017c\u0105ce sesje oraz to, jakich blokad oczekuj\u0105. To jest do\u015b\u0107 interesuj\u0105ce, kiedy zbieramy razem tabel\u0119 blokad i tabel\u0119 zapyta\u0144. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/3949e48d9626a7a030b033dd05e7f042.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I tutaj tworzymy pg_stat_view. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/2b3b7b34bb35f5a67ac5d4ed1328a910.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aktualizujemy wiersz o jeden. I widzimy 724. Nast\u0119pnie aktualizujemy nasz wiersz do trzech. Co widzicie tutaj teraz? To s\u0105 zapytania, tzn. widzicie ca\u0142y list\u0119 zapyta\u0144, kt\u00f3re s\u0105 wymienione w lewej kolumnie. A po prawej stronie mo\u017cecie zauwa\u017cy\u0107 blokady i to, co tworz\u0105. Mo\u017ce to by\u0107 bardziej zrozumia\u0142e dla was, aby nie by\u0142o potrzeby co chwil\u0119 wraca\u0107 do ka\u017cdej sesji i sprawdza\u0107 \u2013 czy trzeba do niej do\u0142\u0105czy\u0107, czy nie. Zrobi\u0105 to za nas. <\/p>\n<p><\/p>\n<p>Kolejna bardzo przydatna funkcja to <code>pg_blocking_pids<\/code>Pewnie nigdy o tym nie s\u0142yszeli\u015bcie. Co ona robi? Pozwala nam powiedzie\u0107, jakie dok\u0142adnie ID proces\u00f3w dla tej sesji 11740 ona oczekuje. Mo\u017cecie zobaczy\u0107, \u017ce 11740 oczekuje na 724, a 724 znajduje si\u0119 na samej g\u00f3rze. A 11306 to wasz ID procesu. W\u0142a\u015bciwie ta funkcja przechodzi przez wasz\u0105 tabel\u0119 blokad. Wiem, \u017ce to troch\u0119 skomplikowane, ale udaje wam si\u0119 to zrozumie\u0107. W zasadzie ta funkcja przeszukuje t\u0119 tabel\u0119 blokad i stara si\u0119 znale\u017a\u0107, gdzie znajduje si\u0119 ten ID procesu, bior\u0105c pod uwag\u0119 blokady, na kt\u00f3re czeka. R\u00f3wnie\u017c pr\u00f3buje obliczy\u0107, jaki dok\u0142adnie ID procesu ma ten proces, kt\u00f3ry czeka na blokady. Dlatego mo\u017cecie uruchomi\u0107 t\u0119 funkcj\u0119. <code>pg_blocking_pids<\/code>.<\/p>\n<p><\/p>\n<p>I to bywa bardzo przydatne. Dodali\u015bmy to dopiero w wersji 9.6, wi\u0119c ta funkcja ma zaledwie 5 lat, ale jest bardzo, bardzo u\u017cyteczna. To samo dotyczy drugiego zapytania. Pokazuje dok\u0142adnie to, co musimy zobaczy\u0107. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/d1975be02ba0cf516ba7bce400228e08.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>To jest to, o czym chcia\u0142em z wami porozmawia\u0107. I jak si\u0119 spodziewa\u0142em, wykorzystali\u015bmy ca\u0142y nasz czas, poniewa\u017c by\u0142o tak wiele slajd\u00f3w. Slajdy s\u0105 dost\u0119pne do pobrania. Chcia\u0142bym wam podzi\u0119kowa\u0107 za obecno\u015b\u0107. Jestem pewien, \u017ce spodoba wam si\u0119 reszta konferencji, dzi\u0119kuj\u0119 bardzo!<\/p>\n<p><\/p>\n<p>Pytania:<\/p>\n<p><\/p>\n<p><em>Na przyk\u0142ad, je\u015bli pr\u00f3buj\u0119 zaktualizowa\u0107 wiersze, a druga sesja stara si\u0119 usun\u0105\u0107 ca\u0142\u0105 tabel\u0119. Z tego, co rozumiem, powinno by\u0107 co\u015b takiego jak intent lock. Czy co\u015b takiego istnieje w Postgresie?<\/em><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/ffe86d27f8bc467aeb3884320258d032.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wracaj\u0105c do pocz\u0105tku. Mo\u017cecie pami\u0119ta\u0107, \u017ce kiedy robicie cokolwiek, na przyk\u0142ad wykonujecie SELECT, przyznajemy AccessShareLock. I to zapobiega usuwaniu tabeli. Dlatego je\u015bli na przyk\u0142ad chcecie zaktualizowa\u0107 wiersz w tabeli lub usun\u0105\u0107 wiersz, to nikt nie mo\u017ce usun\u0105\u0107 ca\u0142ej tabeli jednocze\u015bnie, poniewa\u017c utrzymujecie ten AccessShareLock nad ca\u0142\u0105 tabel\u0105 i nad wierszem. A kiedy sko\u0144czycie, mog\u0105 to usun\u0105\u0107. Ale dop\u00f3ki co\u015b zmieniacie, nie b\u0119d\u0105 mogli tego zrobi\u0107.<\/p>\n<p><\/p>\n<p>Zr\u00f3bmy to jeszcze raz. Przejd\u017amy do przyk\u0142adu z usuni\u0119ciem. I widzicie, jak na wierszu jest ekskluzywna blokada nad ca\u0142\u0105 tabel\u0105. <\/p>\n<p><\/p>\n<p><em>B\u0119dzie to wygl\u0105da\u0107 jak blokada ekskluzywna, prawda?<\/em><\/p>\n<p><\/p>\n<p>Tak, to wygl\u0105da na to. Rozumiem, o czym m\u00f3wisz. M\u00f3wisz, \u017ce je\u015bli wykonam SELECT, to b\u0119d\u0119 mia\u0142 ShareExclusive, a potem przekszta\u0142cam to w stan Row Exclusive, czy to staje si\u0119 problemem? Ale co zaskakuj\u0105ce, nie stwarza to problemu. To przypomina zwi\u0119kszenie poziomu blokady, ale w rzeczywisto\u015bci mam blokad\u0119, kt\u00f3ra zapobiega usuni\u0119ciu. I teraz, gdy wzmacniam t\u0119 blokad\u0119, nadal zapobiega ona usuni\u0119ciu. Wi\u0119c to nie jest tak, \u017ce podnosz\u0119 j\u0105 w g\u00f3r\u0119. Tzn. zapobiega\u0142a temu nawet na ni\u017cszym poziomie, wi\u0119c kiedy podnosz\u0119 jej poziom, nadal zapobiega usuni\u0119ciu tabeli. <\/p>\n<p><\/p>\n<p>Rozumiem, o czym m\u00f3wisz. Nie ma tu przypadku zwi\u0119kszania poziomu blokady, gdzie pr\u00f3bujesz zrezygnowa\u0107 z jednej blokady, aby wprowadzi\u0107 mocniejsz\u0105. Tutaj po prostu powszechnie zwi\u0119ksza to zapobieganie, wi\u0119c nie powoduje to \u017cadnych konflikt\u00f3w. Ale to dobre pytanie. Bardzo dzi\u0119kuj\u0119, \u017ce je zada\u0142e\u015b!<\/p>\n<p><\/p>\n<p><em>Co musimy zrobi\u0107, aby unikn\u0105\u0107 sytuacji deadlocka, gdy mamy wiele sesji, du\u017c\u0105 liczb\u0119 u\u017cytkownik\u00f3w?<\/em><\/p>\n<p><\/p>\n<p>Postgres automatycznie wykrywa sytuacje deadlocka. I automatycznie usunie jedn\u0105 z sesji. Jedynym sposobem, aby unikn\u0105\u0107 sytuacji z martwymi blokadami, jest blokowanie ludzi w tej samej kolejno\u015bci. Dlatego, gdy spojrzysz na swoje aplikacje, cz\u0119sto powodem deadlock\u00f3w\u2026 Za\u0142\u00f3\u017cmy, \u017ce chc\u0119 zablokowa\u0107 dwie r\u00f3\u017cne rzeczy. Jedna aplikacja blokuje tabel\u0119 1, a inna aplikacja blokuje tabel\u0119 2, a nast\u0119pnie tabel\u0119 1. A naj\u0142atwiejszym sposobem na unikni\u0119cie deadlock\u00f3w jest spojrzenie na swoje aplikacje i upewnienie si\u0119, \u017ce blokowanie odbywa si\u0119 w tej samej kolejno\u015bci we wszystkich aplikacjach. I to zwykle eliminuje 80% problem\u00f3w, poniewa\u017c r\u00f3\u017cni ludzie pisz\u0105 te aplikacje. A je\u015bli blokujesz je w tej samej kolejno\u015bci, to nie napotykasz sytuacji deadlocka.<\/p>\n<p><\/p>\n<p><em>Dzi\u0119kuj\u0119 bardzo za twoje wyst\u0105pienie! M\u00f3wi\u0142e\u015b o vacuum full i, je\u015bli dobrze rozumiem, to vacuum full przekszta\u0142ca porz\u0105dek zapis\u00f3w w osobnym przechowywaniu, dlatego zachowuje bie\u017c\u0105ce zapisy bez zmian. A dlaczego vacuum full wymaga wy\u0142\u0105cznej blokady dost\u0119pu i dlaczego koliduje z operacjami zapisu?<\/em><\/p>\n<p><\/p>\n<p>To dobre pytanie. Pow\u00f3d jest taki, \u017ce vacuum full zajmuje tabel\u0119. I w zasadzie tworzymy now\u0105 wersj\u0119 tabeli. Tabela b\u0119dzie nowa. Oznacza to, \u017ce b\u0119dzie to zupe\u0142nie nowa wersja tabeli. Problem polega na tym, \u017ce kiedy to robimy, nie chcemy, by ludzie j\u0105 czytali, poniewa\u017c potrzebujemy, aby zobaczyli now\u0105 tabel\u0119. Dlatego to si\u0119 wi\u0105\u017ce z poprzednim pytaniem. Gdyby\u015bmy mogli czyta\u0107 jednocze\u015bnie, nie mogliby\u015bmy przenie\u015b\u0107 i skierowa\u0107 ludzi do nowej tabeli. Musieliby\u015bmy poczeka\u0107, a\u017c wszyscy sko\u0144cz\u0105 czytanie tej tabeli, a wi\u0119c w zasadzie mamy do czynienia z sytuacj\u0105 lock exclusive.<br \/>\nPo prostu m\u00f3wimy, \u017ce blokujemy od samego pocz\u0105tku, poniewa\u017c wiemy, \u017ce na ko\u0144cu potrzebujemy ekskluzywnej blokady, aby przenie\u015b\u0107 wszystkich na now\u0105 kopi\u0119. Dlatego potencjalnie mo\u017cemy to rozwi\u0105za\u0107. I robimy to z r\u00f3wnoczesnym indeksowaniem. Ale jest to znacznie trudniejsze do osi\u0105gni\u0119cia. I to bardzo odnosi si\u0119 do twojego poprzedniego pytania o lock exclusive.<\/p>\n<p><\/p>\n<p><em>Czy mo\u017cliwe jest dodanie locking timeout w Postgres? W Oracle mog\u0119 na przyk\u0142ad napisa\u0107 \u201ewybierz do aktualizacji\u201d i czeka\u0107 50 sekund na aktualizacj\u0119. By\u0142o to dobre dla aplikacji. Ale w Postgres musz\u0119 to zrobi\u0107 od razu i wcale nie czeka\u0107, albo czeka\u0107 do jakiego\u015b momentu.<\/em> <\/p>\n<p><\/p>\n<p>Tak, mo\u017cesz ustawi\u0107 timeout dla swoich blokad, swoich locks. Mo\u017cesz tak\u017ce wyda\u0107 polecenie no way, kt\u00f3re b\u0119dzie \u2026, je\u015bli nie mo\u017cesz od razu uzyska\u0107 blokady. Wi\u0119c albo lock timeout, albo co\u015b innego, co pozwoli ci to zrobi\u0107. Nie jest to realizowane na poziomie sk\u0142adniowym. Robi si\u0119 to jako zmienna na serwerze. Czasami nie mo\u017cna tego u\u017cywa\u0107.<\/p>\n<p><\/p>\n<p><em>Czy mo\u017cesz otworzy\u0107 75 slajd?<\/em> <\/p>\n<p><\/p>\n<p>Tak.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian\" src=\"\/wp-content\/uploads\/2020\/07\/5f0f3ee9ba29e0c231dd6e0eb66b4f6c.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><em>A moje pytanie brzmi nast\u0119puj\u0105co. Dlaczego oba procesy aktualizacji czekaj\u0105 na 703?<\/em><\/p>\n<p><\/p>\n<p>To jest wspania\u0142e pytanie. Nie rozumiem, dlaczego Postgres tak robi. Kiedy 703 zosta\u0142 utworzony, oczekiwa\u0142 na 702. A gdy pojawiaj\u0105 si\u0119 704 i 705, wydaje si\u0119, \u017ce nie wiedz\u0105, na co czekaj\u0105, poniewa\u017c nic jeszcze nie jest dost\u0119pne. Postgres dzia\u0142a w ten spos\u00f3b: gdy nie mo\u017cesz uzyska\u0107 blokady, m\u00f3wi: \u201ePo co ci\u0119 obs\u0142ugiwa\u0107?\u201d, bo i tak czekasz na kogo\u015b. Dlatego po prostu sprawmy, by wisia\u0142 w powietrzu, nie aktualizuje tego w og\u00f3le. Ale co si\u0119 tutaj wydarzy\u0142o? Gdy 702 zako\u0144czy\u0142 proces, a 703 uzyska\u0142 swoj\u0105 blokad\u0119, system powr\u00f3ci\u0142 z powrotem. I oznajmi\u0142, \u017ce teraz mamy dwie osoby w oczekiwaniu. A teraz zaktualizujmy je razem. I wska\u017cmy, \u017ce obie czekaj\u0105. <\/p>\n<p><\/p>\n<p>Nie wiem, dlaczego Postgres tak post\u0119puje. Ale jest problem, kt\u00f3ry nazywa si\u0119 f\u2026. Wydaje mi si\u0119, \u017ce to nie jest termin w j\u0119zyku rosyjskim. To wtedy wszyscy czekaj\u0105 na jedn\u0105 blokad\u0119, nawet je\u015bli jest 20 instancji, kt\u00f3re czekaj\u0105 na blokad\u0119. I nagle wszyscy budz\u0105 si\u0119 jednocze\u015bnie. I wszyscy zaczynaj\u0105 pr\u00f3bowa\u0107 reagowa\u0107. Ale system dzia\u0142a tak, \u017ce wszyscy czekaj\u0105 na 703. Poniewa\u017c wszyscy czekaj\u0105, natychmiast ustawiamy ich wszystkich w kolejce. A je\u015bli pojawia si\u0119 jakiekolwiek inne nowe zapytanie, kt\u00f3re zosta\u0142o utworzone po tym, na przyk\u0142ad 707, to zn\u00f3w b\u0119dzie pustka. <\/p>\n<p><\/p>\n<p>I my\u015bl\u0119, \u017ce to robi si\u0119 po to, by mo\u017cna by\u0142o powiedzie\u0107, \u017ce na tym etapie 702 czeka na 703, a wszyscy ci, kt\u00f3rzy przyjd\u0105 p\u00f3\u017aniej, nie b\u0119d\u0105 mieli \u017cadnego zapisu w tym polu. Ale gdy pierwszy oczekuj\u0105cy opuszcza, to wszyscy ci, kt\u00f3rzy w tym momencie czekali na aktualizacj\u0119, dostaj\u0105 ten sam znacznik. I dlatego wydaje mi si\u0119, \u017ce to zrobiono, aby m\u00f3c obs\u0142ugiwa\u0107 je w kolejno\u015bci, tak aby by\u0142y poprawnie uporz\u0105dkowane. <\/p>\n<p><\/p>\n<p>Zawsze patrzy\u0142em na to jako na do\u015b\u0107 dziwny fenomen. Poniewa\u017c tutaj, na przyk\u0142ad, w og\u00f3le ich nie wymieniamy. Ale wydaje mi si\u0119, \u017ce za ka\u017cdym razem, gdy dajemy now\u0105 blokad\u0119, przygl\u0105damy si\u0119 wszystkim, kt\u00f3rzy s\u0105 w procesie oczekiwania. Wtedy ustawiamy ich wszystkich w kolejce. A nast\u0119pnie jakiekolwiek nowe zapytanie, kt\u00f3re nadchodzi, trafia do kolejki dopiero wtedy, gdy nast\u0119pna osoba zako\u0144czy przetwarzanie. Bardzo dobre pytanie. Dzi\u0119kuj\u0119 bardzo za pytanie!<\/p>\n<p><\/p>\n<p><em>Wydaje mi si\u0119, \u017ce znacznie logiczniej jest, gdy 705 czeka na 704.<\/em> <\/p>\n<p><\/p>\n<p>Ale problem jest nast\u0119puj\u0105cy. Technicznie mo\u017cesz obudzi\u0107 ten lub ten. I dlatego obudzimy ten lub inny. Ale co si\u0119 dzieje w dzia\u0142aniu systemu? Widzisz, jak 703 na samym szczycie zablokowa\u0142 sw\u00f3j w\u0142asny identyfikator transakcji. Tak dzia\u0142a Postgres. I 703 jest zablokowany swoim w\u0142asnym identyfikatorem transakcji, wi\u0119c je\u015bli kto\u015b chce poczeka\u0107, b\u0119dzie czeka\u0142 na 703. A w zasadzie, 703 ko\u0144czy. I dopiero po jego zako\u0144czeniu jaki\u015b proces si\u0119 budzi. I nie wiemy, kt\u00f3ry to b\u0119dzie proces. Nast\u0119pnie stopniowo wszystko przetwarzamy. Ale nie jest jasne, kt\u00f3ry proces budzi si\u0119 pierwszy, poniewa\u017c mo\u017ce to by\u0107 dowolny z tych proces\u00f3w. W zasadzie mieli\u015bmy harmonogram, kt\u00f3ry m\u00f3wi\u0142, \u017ce teraz mo\u017cemy budzi\u0107 dowolny z tych proces\u00f3w. Po prostu wybieramy jeden losowo. Dlatego oba musz\u0105 by\u0107 oznaczone, poniewa\u017c mo\u017cemy budzi\u0107 ka\u017cdy z nich. <\/p>\n<p><\/p>\n<p>A problem polega na tym, \u017ce mamy CP-niesko\u0144czono\u015b\u0107. I dlatego mo\u017cemy obudzi\u0107 p\u00f3\u017aniejszy. I je\u015bli na przyk\u0142ad obudzimy p\u00f3\u017aniejszy, to b\u0119dziemy czeka\u0107 na tego, kt\u00f3ry w\u0142a\u015bnie uzyska\u0142 blokad\u0119, wi\u0119c nie okre\u015blamy, kto dok\u0142adnie b\u0119dzie obudzony pierwszy. Tworzymy po prostu tak\u0105 sytuacj\u0119, a system b\u0119dzie je budzi\u0142 w losowej kolejno\u015bci. <\/p>\n<p><\/p>\n<p><em>Tak <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/erogov\/posts\/\">artyku\u0142y o blokadach Egora Rogova<\/a><\/noindex>. Zobacz, s\u0105 r\u00f3wnie\u017c interesuj\u0105ce i przydatne. Temat jest oczywi\u015bcie przera\u017caj\u0105co skomplikowany. Bardzo dzi\u0119kuj\u0119, Bruce!<\/em><\/p>\n<p>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/510322\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 2020 \u0433\u043e\u0434\u0430 \u0411\u0440\u044e\u0441\u0430 \u041c\u043e\u043c\u0436\u0438\u0430\u043d\u0430 &quot;Unlocking the Postgres Lock Manager&quot;. (\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0412\u0441\u0435 SQL \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0438\u0437 \u0441\u043b\u0430\u0439\u0434\u043e\u0432 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e \u044d\u0442\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0435: http:\/\/momjian.us\/main\/writings\/pgsql\/locking.sql) \u041f\u0440\u0438\u0432\u0435\u0442! \u0417\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043d\u043e\u0432\u0430 \u0431\u044b\u0442\u044c \u0437\u0434\u0435\u0441\u044c \u0432 \u0420\u043e\u0441\u0441\u0438\u0438. \u042f \u043f\u0440\u043e\u0448\u0443 \u043f\u0440\u043e\u0449\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u044f \u043d\u0435 \u0441\u043c\u043e\u0433 \u043f\u0440\u0438\u0435\u0445\u0430\u0442\u044c \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u0433\u043e\u0434\u0443, \u043d\u043e \u0432 \u044d\u0442\u043e\u043c \u0433\u043e\u0434\u0443 \u0443 \u0418\u0432\u0430\u043d\u0430 \u0438 \u0443 \u043c\u0435\u043d\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043f\u043b\u0430\u043d\u044b. \u042f, \u043d\u0430\u0434\u0435\u044e\u0441\u044c, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":87955,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-87954","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 2020 \u0433\u043e\u0434\u0430 \u0411\u0440\u044e\u0441\u0430 \u041c\u043e\u043c\u0436\u0438\u0430\u043d\u0430 &quot;Unlocking the Postgres Lock Manager&quot;.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/unlocking-the-postgres-lock-manager-bryus-momzhian\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47Unlocking the Postgres Lock Manager. \u0411\u0440\u044e\u0441 \u041c\u043e\u043c\u0436\u0438\u0430\u043d | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 2020 \u0433\u043e\u0434\u0430 \u0411\u0440\u044e\u0441\u0430 \u041c\u043e\u043c\u0436\u0438\u0430\u043d\u0430 &quot;Unlocking the Postgres Lock Manager&quot;.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/unlocking-the-postgres-lock-manager-bryus-momzhian\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-07-11T23:42:48+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-07-11T23:42:48+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Odblokowanie mened\u017cera blokad Postgresa. Bruce Momjian | ProHoster","description":"Transkrypt raportu Bruce'a Momziana z 2020 roku \"Odblokowanie mened\u017cera blokad Postgresa\".","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/unlocking-the-postgres-lock-manager-bryus-momzhian","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47Unlocking the Postgres Lock Manager. \u0411\u0440\u044e\u0441 \u041c\u043e\u043c\u0436\u0438\u0430\u043d | ProHoster","og:description":"\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 2020 \u0433\u043e\u0434\u0430 \u0411\u0440\u044e\u0441\u0430 \u041c\u043e\u043c\u0436\u0438\u0430\u043d\u0430 &quot;Unlocking the Postgres Lock Manager&quot;.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/unlocking-the-postgres-lock-manager-bryus-momzhian","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-07-11T23:42:48+00:00","article:modified_time":"2020-07-11T23:42:48+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"87954","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 13:40:34","updated":"2022-09-27 23:56:25","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/87954","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=87954"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/87954\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/87955"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=87954"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=87954"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=87954"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}