Postgres Lock Manageri avamine. Bruce Momjian

Transkriptsioon Bruce Momjiani 2020. aasta kõnest "Postgresi lukuhalduri avamine".

Postgres Lock Manageri avamine. Bruce Momjian

(Märkus. Kõik SQL-päringud saate slaididelt sellelt lingilt: http://momjian.us/main/writings/pgsql/locking.sql)

Tere! Tore on jälle siin Venemaal olla. Mul on kahju, et eelmisel aastal ei saanud tulla, aga sel aastal on meil Ivaniga suured plaanid. Loodan siin palju sagedamini olla. Mulle meeldib Venemaale tulla. Ma külastan Tjumenit, Tverit. Mul on väga hea meel, et saan neid linnu külastada.

Minu nimi on Bruce Momjian. Töötan ettevõttes EnterpriseDB ja olen töötanud Postgresiga üle 23 aasta. Tähemärgilt olen kaksikud ja mu elukoht on Philadelphia, USA. Reisin umbes 90 päeva aastas. Ja ma osalen umbes 40 konverentsil. Minu veebisait, mis sisaldab slaide, mida ma teile nüüd näitan. Seetõttu saate need pärast konverentsi alla laadida minu isiklikult saidilt. See sisaldab ka umbes 30 ettekannet. Ja seal on ka videod ja suur hulk ajaveebi sissekandeid, üle 500. See on üsna informatiivne allikas. Ja kui olete sellest materjalist huvitatud, kutsun teid seda kasutama.

Olin enne Postgresiga töötamist õpetaja, professor. Ja mul on väga hea meel, et saan nüüd teile öelda, mida ma teile ütlen. See on üks minu huvitavamaid esitlusi. Ja see esitlus sisaldab 110 slaidi. Hakkame rääkima lihtsatest asjadest ja lõpuks muutub aruanne üha keerulisemaks ja muutub üsna keeruliseks.

Postgres Lock Manageri avamine. Bruce Momjian

See on üsna ebameeldiv vestlus. Blokeerimine ei ole kõige populaarsem teema. Tahame, et see kuhugi kaoks. See on nagu hambaarsti juures käimine.

Postgres Lock Manageri avamine. Bruce Momjian

  1. Lukustamine on probleem paljudele inimestele, kes töötavad andmebaasidega ja kellel on korraga mitu protsessi. Nad vajavad blokeerimist. See tähendab, et täna annan teile põhiteadmised blokeerimisest.
  2. Tehingu ID-d. See on esitluse üsna igav osa, kuid neist tuleb aru saada.
  3. Järgmisena räägime blokeerimise tüüpidest. See on üsna mehaaniline osa.
  4. Ja siis toome mõned näited blokeerimisest. Ja seda on üsna raske mõista.

Postgres Lock Manageri avamine. Bruce Momjian

Räägime blokeerimisest.

Postgres Lock Manageri avamine. Bruce Momjian

Meie terminoloogia on üsna keeruline. Kui paljud teist teavad, kust see lõik pärit on? Kaks inimest. See on pärit mängust nimega Colossal Cave Adventure. Ma arvan, et see oli 80ndatel tekstipõhine arvutimäng. Seal oli vaja minna koopasse, labürinti ja tekst muutus, aga sisu oli iga kord ligikaudu sama. Nii mäletan seda mängu.

Postgres Lock Manageri avamine. Bruce Momjian

Ja siin näeme nende lukkude nimesid, mis meile Oracle'ist tulid. Me kasutame neid.

Postgres Lock Manageri avamine. Bruce Momjian

Siin näeme termineid, mis mind segadusse ajavad. Näiteks SHARE UPDATE ECXLUSIVE. Järgmine JAGA RAW EXLUSIVE. Ausalt öeldes pole need nimed väga selged. Püüame neid üksikasjalikumalt kaaluda. Mõned sisaldavad sõna "jagama", mis tähendab eraldamist. Mõned sisaldavad sõna "eksklusiivne" - eksklusiivne. Mõned sisaldavad neid mõlemaid sõnu. Tahaksin alustada sellest, kuidas need lukud töötavad.

Postgres Lock Manageri avamine. Bruce Momjian

Ja sõna "juurdepääs" on samuti väga oluline. Ja sõnad "rida" - rida. See tähendab, juurdepääsu jaotus, ridade jaotus.

Postgres Lock Manageri avamine. Bruce Momjian

Teine probleem, millest tuleb Postgresis aru saada, mida ma kahjuks oma jutus käsitleda ei saa, on MVCC. Minu veebisaidil on sellel teemal eraldi ettekanne. Ja kui te arvate, et see esitlus on raske, siis MVCC on minu jaoks ilmselt kõige raskem. Ja kui olete huvitatud, näete seda saidil. Saate videot vaadata.

Postgres Lock Manageri avamine. Bruce Momjian

Teine asi, mida peame mõistma, on tehingu ID-d. Paljud tehingud ei saa toimida ilma kordumatute identifikaatoriteta. Ja siin on meil selgitus, mis on tehing. Postgresil on kaks tehingute nummerdamissüsteemi. Ma tean, et see pole eriti ilus lahendus.

Postgres Lock Manageri avamine. Bruce Momjian

Samuti pidage meeles, et slaide on üsna raske lugeda, nii et punasega esile tõstetud on see, millele peate tähelepanu pöörama.

Postgres Lock Manageri avamine. Bruce Momjian

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

Me vaatame. Tehingu number on punasega esile tõstetud. Siin on näidatud funktsioon SELECT pg_back. See tagastab minu tehingu ja selle tehingu ID.

Veel üks asi, kui teile meeldib see esitlus ja soovite seda oma andmebaasis käivitada, võite järgida seda roosaga esiletõstetud linki ja laadida alla selle esitluse SQL. Ja saate selle lihtsalt oma PSQL-is käivitada ja kogu esitlus kuvatakse kiiresti teie ekraanil. See ei sisalda lilli, aga vähemalt näeme seda.

Postgres Lock Manageri avamine. Bruce Momjian

Sel juhul näeme tehingu ID-d. See on number, mille me talle määrasime. Ja Postgresis on teist tüüpi tehingu ID, mida nimetatakse virtuaalseks tehingu ID-ks

Ja me peame sellest aru saama. See on väga oluline, vastasel juhul ei saa me Postgresis lukustamisest aru.

Virtuaalne tehingu ID on tehingu ID, mis ei sisalda püsivaid väärtusi. Näiteks kui ma käivitan käsu SELECT, siis ma suure tõenäosusega ei muuda andmebaasi, ma ei lukusta midagi. Nii et kui käivitame lihtsa SELECTi, ei anna me sellele tehingule püsivat ID-d. Anname talle seal ainult virtuaalse ID.

Ja see parandab Postgresi jõudlust, parandab puhastusvõimalusi, nii et virtuaalse tehingu ID koosneb kahest numbrist. Esimene number enne kaldkriipsu on taustaprogrammi ID. Ja paremal näeme lihtsalt loendurit.

Postgres Lock Manageri avamine. Bruce Momjian

Seega, kui käivitan päringu, ütleb see, et taustaprogrammi ID on 2.

Postgres Lock Manageri avamine. Bruce Momjian

Ja kui käitan selliseid tehinguid, siis näeme, et loendurit suurendatakse iga kord, kui päringut käivitan. Näiteks kui käivitan päringu 2/10, 2/11, 2/12 jne.

Postgres Lock Manageri avamine. Bruce Momjian

Pidage meeles, et siin on kaks veergu. Vasakul näeme virtuaalset tehingu ID-d – 2/12. Ja paremal on meil püsiv tehingu ID. Ja see väli on tühi. Ja see tehing ei muuda andmebaasi. Seetõttu ei määra ma sellele püsivat tehingu ID-d.

Postgres Lock Manageri avamine. Bruce Momjian

Niipea, kui käivitan analüüsikäsu ( (ANALÜÜSI)), annab sama päring mulle püsiva tehingu ID. Vaata, kuidas oleme muutunud. Varem mul seda ID-d ei olnud, nüüd on.

Postgres Lock Manageri avamine. Bruce Momjian

Nii et siin on veel üks taotlus, järjekordne tehing. Virtuaalne tehingunumber on 2/13. Ja kui ma küsin püsivat tehingu ID-d, siis päringu käivitamisel saan selle.

Postgres Lock Manageri avamine. Bruce Momjian

Niisiis, veel üks kord. Meil on virtuaalne tehingu ID ja püsiv tehingu ID. Lihtsalt mõista seda punkti, et mõista Postgresi käitumist.

Postgres Lock Manageri avamine. Bruce Momjian

Liigume edasi kolmanda sektsiooni juurde. Siin me lihtsalt jalutame läbi Postgresi erinevat tüüpi lukud. See ei ole väga huvitav. Viimane osa on palju huvitavam. Peame aga arvestama elementaarsete asjadega, sest muidu ei saa aru, mis edasi saab.

Vaatame selle jaotise läbi ja vaatame igat tüüpi blokeerimist. Ja ma näitan teile näiteid selle kohta, kuidas need installitakse, kuidas need töötavad, näitan teile mõningaid päringuid, mida saate kasutada, et näha, kuidas blokeerimine Postgresis töötab.

Postgres Lock Manageri avamine. Bruce Momjian

Päringu loomiseks ja Postgresis toimuva nägemiseks peame päringu esitama süsteemivaates. Sel juhul on pg_lock punasega esile tõstetud. Pg_lock on süsteemitabel, mis ütleb meile, millised lukud on praegu Postgresis kasutusel.

Siiski on mul väga raske teile pg_locki iseenesest näidata, kuna see on üsna keeruline. Seega lõin vaate, mis näitab pg_locks. Ja see teeb minu jaoks ka tööd, mis võimaldab mul paremini mõista. See tähendab, et see välistab minu lukud, minu enda seansi jne. See on lihtsalt tavaline SQL ja see võimaldab teil paremini näidata, mis toimub.

Postgres Lock Manageri avamine. Bruce Momjian

Teine probleem on see, et see vaade on väga lai, seega pean looma teise - lockview2.

Postgres Lock Manageri avamine. Bruce Momjian Ja see näitab mulle tabelist rohkem veerge. Ja veel üks, mis näitab mulle ülejäänud veerge. See on üsna keeruline, nii et püüdsin seda võimalikult lihtsalt esitada.

Postgres Lock Manageri avamine. Bruce Momjian

Niisiis, oleme loonud tabeli nimega Lockdemo. Ja me lõime sinna ühe rea. See on meie näidistabel. Ja me loome jaotised lihtsalt selleks, et näidata teile blokeerimise näiteid.

Postgres Lock Manageri avamine. Bruce Momjian

Niisiis, üks rida, üks veerg. Esimest tüüpi lukud nimetatakse ACCESS SHARE. See on kõige vähem piirav blokeerimine. See tähendab, et see praktiliselt ei ole vastuolus teiste lukkudega.

Ja kui tahame luku selgesõnaliselt määratleda, käivitame käsu "lukutabel". Ja see blokeerib selgesõnaliselt, st režiimis ACCESS SHARE käivitame lukustabeli. Ja kui ma käivitan PSQL-i taustal, siis alustan teist seanssi oma esimesest seansist sel viisil. See tähendab, mida ma siin teen? Lähen teisele seansile ja ütlen, et "näita mulle selle päringu lukustusvaadet". Ja siin on mul sellel laual AccessShareLock. See on just see, mida ma taotlesin. Ja ta ütleb, et lukk on määratud. Väga lihtne.

Postgres Lock Manageri avamine. Bruce Momjian

Lisaks, kui vaatame teist veergu, siis pole seal midagi. Need on tühjad.

Postgres Lock Manageri avamine. Bruce Momjian

Ja kui ma käivitan käsu "SELECT", on see kaudne (selge) viis AccessShareLocki taotlemiseks. Seega vabastan tabeli ja käivitan päringu ning päring tagastab mitu rida. Ja ühel real näeme AccessShareLocki. Nii et SELECT kutsub lauale AccessShareLocki. Ja see ei lähe vastuollu peaaegu millegagi, sest tegu on madala tasemega lukuga.

Postgres Lock Manageri avamine. Bruce Momjian

Mis siis, kui käivitan SELECTi ja mul on kolm erinevat tabelit? Varem kasutasin ainult ühte tabelit, nüüd aga kolme: pg_class, pg_namespace ja pg_attribute.

Postgres Lock Manageri avamine. Bruce Momjian

Ja nüüd, kui ma vaatan päringut, näen 9 AccessShareLocki kolmes tabelis. Miks? Kolm tabelit on sinisega esile tõstetud: pg_attribute, pg_class, pg_namespace. Kuid näete ka seda, et kõigil nende tabelite kaudu määratletud indeksitel on ka AccessShareLock.

Ja see on blokeerimine, mis praktiliselt ei lähe vastuollu teistega. Ja see ei lase meil tabeli valimise ajal tabelit maha jätta. See on loogiline. See tähendab, et kui valime tabeli, siis see kaob sel hetkel, siis on see vale AccessShare on madala taseme lukk, mis ütleb meile: "Ära kukuta seda lauda, ​​kui ma töötan". Põhimõtteliselt on see kõik, mida ta teeb.

Postgres Lock Manageri avamine. Bruce Momjian

ROW SHARE – see lukk on veidi erinev.

Postgres Lock Manageri avamine. Bruce Momjian

Võtame näite. SELECT ROW SHARE viis iga rea ​​eraldi lukustamiseks. Nii ei saa keegi neid vaatamise ajal kustutada ega muuta.

Postgres Lock Manageri avamine. Bruce MomjianNiisiis, mida SHARE LOCK teeb? Näeme, et SELECT tehingu ID on 681. Ja see on huvitav. Mis siin juhtus? Esimest korda näeme numbrit väljal "Lukusta". Võtame tehingu ID ja ta ütleb, et blokeerib selle eksklusiivses režiimis. See ütleb vaid, et mul on rida, mis on tehniliselt kuskil tabelis lukus. Aga kus täpselt, ta ei ütle. Vaatame seda üksikasjalikumalt veidi hiljem.

Postgres Lock Manageri avamine. Bruce Momjian

Siinkohal ütleme, et lukk on meie kasutuses.

Postgres Lock Manageri avamine. Bruce Momjian

Niisiis, eksklusiivne lukk ütleb selgesõnaliselt, et see on eksklusiivne. Ja ka siis, kui kustutate sellest tabelist rea, siis see juhtub, nagu näete.

Postgres Lock Manageri avamine. Bruce Momjian

SHARE EXCLUSIVE on pikem lukk.

Postgres Lock Manageri avamine. Bruce Momjian

See on (ANALÜÜS) kasutatav analüsaatori käsk.

Postgres Lock Manageri avamine. Bruce Momjian

JAGAMISLUKK – saate jagamisrežiimis selgesõnaliselt lukustada.

Postgres Lock Manageri avamine. Bruce Momjian

Samuti saate luua ainulaadse indeksi. Ja seal on näha SHARE LOCK, mis on osa nendest. Ja see lukustab laua ja seab sellele SHARE LOCK luku.

Tabeli vaikeseade SHARE LOCK tähendab, et teised inimesed saavad tabelit lugeda, kuid keegi ei saa seda muuta. Ja täpselt see juhtub, kui loote ainulaadse indeksi.

Kui loon kordumatu samaaegse indeksi, on mul teist tüüpi lukk, sest pidage meeles, et samaaegsete indeksite kasutamine vähendab lukustamise nõuet. Ja kui ma kasutan tavalist lukku, tavalist indeksit, siis takistan seega tabeli indeksisse kirjutamist selle loomise ajal. Kui kasutan samaaegselt indeksit, pean kasutama teist tüüpi lukku.

Postgres Lock Manageri avamine. Bruce Momjian

SHARE ROW EXCLUSIVE – jällegi saab seda määrata eksplitsiitselt (eksplitsiitselt).

Postgres Lock Manageri avamine. Bruce Momjian

Või saame luua reegli, st võtta konkreetse juhtumi, mil seda kasutatakse.

Postgres Lock Manageri avamine. Bruce Momjian

EKSKLUSIIVNE lukk tähendab, et keegi teine ​​ei saa lauda vahetada.

Postgres Lock Manageri avamine. Bruce Momjian

Siin näeme erinevat tüüpi lukke.

Postgres Lock Manageri avamine. Bruce Momjian

ACCESS EXCLUSIVE on näiteks lukustuskäsk. Näiteks kui teete CLUSTER table, siis see tähendab, et keegi ei saa sinna kirjutada. Ja see ei lukusta mitte ainult tabelit ennast, vaid ka indekseid.

Postgres Lock Manageri avamine. Bruce Momjian

See on ACCESS EXCLUSIVE luku teine ​​leht, kus näeme konkreetselt, mida see tabelis lukustab. See lukustab üksikud tabeliread, mis on piisavalt huvitav.

See on kogu põhiteave, mida ma tahtsin anda. Rääkisime lukkudest, tehingu ID-dest, rääkisime virtuaalsetest tehingu ID-dest, püsitehingute ID-dest.

Postgres Lock Manageri avamine. Bruce Momjian

Ja nüüd vaatame läbi blokeerivad näited. See on kõige huvitavam osa. Näeme väga huvitavaid juhtumeid. Ja minu eesmärk selles esitluses on anda teile parem ülevaade sellest, mida Postgres tegelikult teeb, kui ta üritab asju blokeerida. Mulle tundub, et ta oskab väga hästi üksikuid osi blokeerida.

Vaatame mõnda konkreetset näidet.

Postgres Lock Manageri avamine. Bruce Momjian

Alustame tabelitega ja ühe reaga tabeli kohta. Kui ma midagi sisestan, kuvatakse tabelis ExclusiveLock, tehingu ID ja ExclusiveLock.

Postgres Lock Manageri avamine. Bruce Momjian

Mis juhtub, kui lisan veel kaks rida? Ja nüüd on meie tabelis kolm rida. Ja ma sisestasin ühe rea ja sain selle väljundiks. Ja kui ma lisan veel kaks rida, siis mis selles imelikku on? Siin on üks veider asi, sest olen lisanud sellele tabelisse kolm rida, aga mul on lukutabelis siiski kaks rida. Ja see on sisuliselt Postgresi põhikäitumine.

Paljud inimesed arvavad, et kui lukustate andmebaasis 100 rida, peate looma 100 lukustuskirjet. Kui blokeerin korraga 1 rida, siis on mul vaja 000 sellist taotlust. Ja kui mul on vaja miljonit või miljardit blokeerida. Aga kui me seda teeme, ei tööta see kuigi hästi. Kui olete kasutanud süsteemi, mis loob iga üksiku rea jaoks blokeerivad kirjed, näete, et see on keeruline. Sest tuleb kohe defineerida lukutabel, mis võib üle voolata, aga Postgres seda ei tee.

Ja sellel slaidil on väga oluline, et see näitaks selgelt, et MVCC sees töötab veel üks süsteem, mis blokeerib üksikuid ridu. Nii et kui lukustate miljardeid ridu, ei loo Postgres miljardit eraldi lukustusjuhist. Ja see on jõudluse jaoks väga hea.

Postgres Lock Manageri avamine. Bruce Momjian

Aga uuendus? Uuendan praegu seeriat ja näete, et see on teinud kaks erinevat toimingut korraga. See lukustas samal ajal tabeli, kuid lukustas ka indeksi. Ja tal oli vaja indeks lukustada, kuna sellel tabelis on ainulaadsed piirangud. Ja me tahame olla kindlad, et keegi seda ei muudaks, seega blokeerime selle.

Postgres Lock Manageri avamine. Bruce Momjian

Mis juhtub, kui soovin värskendada kahte rida? Ja me näeme, et ta käitub samamoodi. Me teeme kaks korda rohkem uuendusi, kuid täpselt sama palju blokeerimisridu.

Kui soovite teada, kuidas Postgres seda teeb, peaksite kuulama minu kõnesid MVCC kohta, et teada saada, kuidas Postgres sisemiselt märgib neid ridu, mida ta muudab. Ja Postgresil on oma viis seda teha, kuid ta ei tee seda laua lukustamise tasemel, vaid madalamal ja tõhusamal tasemel.

Postgres Lock Manageri avamine. Bruce Momjian

Mis siis, kui ma tahan midagi kustutada? Kui ma kustutan näiteks ühe rea ja mul on endiselt kaks sisendit lukus ja isegi kui ma tahan need kõik kustutada, on need alles.

Postgres Lock Manageri avamine. Bruce Momjian

Ja näiteks tahan lisada 1 rida ja siis kas kustutada või lisada 000 rida, siis üksikuid ridu, mida lisan või muudan, neid siia ei salvestata. Need on kirjutatud reas endas madalamal tasemel. Ja MVCC kõne ajal rääkisin sellest üksikasjalikult. Kuid lukkude analüüsimisel on väga oluline veenduda, et teil on tabelitaseme lukk ja et te ei näeks, kuidas siin üksikuid ridu kirjutatakse.

Postgres Lock Manageri avamine. Bruce Momjian

Aga selgesõnaline blokeerimine?

Postgres Lock Manageri avamine. Bruce Momjian

Kui klõpsan "värskenda", on mul kaks rida lukustatud. Ja kui ma valin need kõik välja ja vajutan "uuenda kõikjal", siis on mul ikkagi kaks lukukirjet.

Postgres Lock Manageri avamine. Bruce Momjian

Me ei loo iga üksiku rea jaoks eraldi kirjeid. Kuna siis jõudlus langeb, võib seda olla liiga palju. Ja me võime sattuda ebameeldivasse olukorda.

Postgres Lock Manageri avamine. Bruce Momjian

Ja sama asi, kui me jagame, saame seda teha kõik 30 korda.

Postgres Lock Manageri avamine. Bruce Momjian

Taastame oma tabeli, kustutame kõik, seejärel sisestame uuesti ühe rea.

Postgres Lock Manageri avamine. Bruce Momjian

Teine käitumine, mida näete Postgresis, on väga tuntud ja soovitud käitumine, on see, et saate teha värskendamise või valiku. Ja saate seda teha samal ajal. Ja valige ei blokeeri värskendust ja sama asi vastupidises suunas. Me ütleme lugejale, et ta ei blokeeriks kirjanikku ja kirjanik ei ole lugejat blokeerinud.

Toon teile selle näite. Ma teen nüüd valiku. Seejärel teeme INSERTi. Ja siis on näha - 694. Näete selle vahetüki teinud tehingu ID-d. Ja nii see toimib.

Postgres Lock Manageri avamine. Bruce Momjian

Ja kui ma nüüd vaatan oma taustaprogrammi ID-d, siis on see saanud - 695.

Postgres Lock Manageri avamine. Bruce Momjian

Ja ma näen, et minu tabelis on 695.

Postgres Lock Manageri avamine. Bruce Momjian

Ja kui ma siin niimoodi värskendan, siis saan teistsuguse juhtumi. Sel juhul on 695 eksklusiivne lukk ja värskenduse käitumine on sama, kuid nende vahel pole konflikti, mis on üsna ebatavaline.

Ja võite märgata, et ülaosas on ShareLock ja all ExclusiveLock. Ja mõlemad tehingud õnnestusid.

Ja peate kuulama minu juttu MVCC-s, et mõista, kuidas see juhtub. Kuid see on näide sellest, et saate seda teha samal ajal, st teha SELECT ja UPDATE korraga.

Postgres Lock Manageri avamine. Bruce Momjian

Lähtestame ja teeme ühe toimingu uuesti.

Postgres Lock Manageri avamine. Bruce Momjian

Kui proovite samal real käivitada korraga kahte värskendust, siis see blokeeritakse. Ja pidage meeles, ma ütlesin, et lugeja ei blokeeri kirjanikku ja kirjanik ei blokeeri lugejat, vaid üks kirjanik blokeerib teist kirjanikku. See tähendab, et kaks inimest ei saa korraga sama rida värskendada. Peate ootama, kuni üks neist lõpetab.

Postgres Lock Manageri avamine. Bruce Momjian

Ja selle illustreerimiseks vaatan Lockdemo tabelit. Ja me vaatame ühte rida. Tehingu jaoks 698.

Täiendasime selle versioonile 2. 699 on esimene värskendus. Ja see õnnestus või on pooleliolevas tehingus, mis ootab meid siduma või tühistama.

Postgres Lock Manageri avamine. Bruce Momjian

Kuid vaadake midagi muud – 2/51 on meie esimene tehing, meie esimene seanss. 3/112 on teine ​​päring, mis tuli ülevalt ja muutis selle väärtuse 3-ks. Ja kui märkate, siis ülemine on end lukustanud, mis on 699. Kuid 3/112 ei andnud lukku. Veerg Lock_mode ütleb, et see ootab. Ta ootab 699. Ja kui vaadata, kus on 699, siis on ta kõrgem. Ja mida tegi esimene seanss? Ta lõi oma tehingu ID-le eksklusiivse luku. Postgres teeb seda nii. See blokeerib oma tehingu ID. Ja kui soovite oodata, kuni keegi võtab kohustuse või tühistab, peate ootama, kuni on pooleli tehing. Ja nii võime näha kummalist joont.

Vaatame uuesti. Vasakul näeme oma töötlemise ID-d. Teises veerus näeme oma virtuaalset tehingu ID-d ja kolmandas lock_type. Mida see tähendab? Põhimõtteliselt öeldakse, et see blokeerib tehingu ID. Kuid pange tähele, et kõik allosas olevad read ütlevad seost. Ja nii on teil laual kahte tüüpi lukke. Seal on suhte lukk. Ja siis on transaktsiooni ID blokeerimine, kus blokeerite ise, mis toimub täpselt esimeses reas või päris allosas, kus on tehingu ID, kus me ootame 699, et see toimiks.

Ma näen, mis siin toimub. Ja siin toimub kaks asja korraga. Vaatate tehingu ID lukku esimeses reas, mis lukustub ise. Ja ta blokeerib end, et inimesed ootaksid.

Kui vaatate 6. rida, on see sama kirje, mis esimene. Ja seetõttu on tehing 699 blokeeritud. 700 on ka iselukustuv. Ja siis alumisel real näete, et me ootame, kuni 699 oma töö lõpetab.

Postgres Lock Manageri avamine. Bruce Momjian

Ja lock_type korral näete numbreid.

Postgres Lock Manageri avamine. Bruce Momjian

Näete, et see on 0/10. Ja see on lehekülje number ja ka selle konkreetse rea nihe.

Postgres Lock Manageri avamine. Bruce Momjian

Ja näete, mis muutub 0/11, kui värskendame.

Postgres Lock Manageri avamine. Bruce Momjian

Aga tegelikult on see 0/10, sest sellele operatsioonile on ootus. Meil on võimalus näha, et see on rida, mille kinnitamist ootan.

Postgres Lock Manageri avamine. Bruce Momjian

Kui me selle kinnitasime ja kinnitasime, ja kui värskendus on lõppenud, saame seda uuesti. Tehing 700 on ainuke lukk, see ei oota kedagi teist, sest see pandi toime. See lihtsalt ootab tehingu lõpuleviimist. Kui 699 saab otsa, ei oota me enam midagi. Ja nüüd tehing 700 ütleb, et kõik on korras, et tal on kõik vajalikud lukud kõikides lubatud tabelites.

Postgres Lock Manageri avamine. Bruce Momjian

Ja et kogu see asi veelgi keerulisemaks muuta, loome teise vaate, mis seekord annab meile hierarhia. Ma ei eelda, et te seda palvet mõistate. Kuid see annab meile toimuvast selgema ülevaate.

Postgres Lock Manageri avamine. Bruce Momjian

See on rekursiivne vaade, millel on veel üks jaotis. Ja siis toob see kõik uuesti kokku. Kasutame seda.

Postgres Lock Manageri avamine. Bruce Momjian

Mis siis, kui teeme kolm samaaegset värskendust ja ütleme, et rida on nüüd kolm. Ja me muudame 3 vastu 4.

Postgres Lock Manageri avamine. Bruce Momjian

Ja siin näeme 4. Ja tehingu ID 702.

Postgres Lock Manageri avamine. Bruce Momjian

Ja siis vahetan 4 5 vastu. Ja 5 6 vastu ja 6 7 vastu. Ja panen hulga inimesi ritta ootama, kuni see üks tehing lõpule jõuab.

Postgres Lock Manageri avamine. Bruce Momjian

Ja kõik saab selgeks. Mis on esimene rida? See on 702. See on tehingu ID, mis selle väärtuse algselt määras. Mis on mul veerus antud? Mul on märgid f. Need on minu värskendused, mida (5, 6, 7) ei saa kinnitada, kuna ootame tehingu ID 702 lõppu. Seal on meil tehingu ID blokeerimine. Selle tulemuseks on 5 tehingu ID lukku.

Ja kui vaadata 704, siis 705, siis seal pole veel midagi kirjas, sest nad ei tea veel, mis toimub. Nad lihtsalt kirjutavad, et neil pole õrna aimugi, mis toimub. Ja nad lähevad lihtsalt magama, sest nad ootavad, et keegi lõpetaks ja nad äratatakse, kui on võimalik rida vahetada.

Postgres Lock Manageri avamine. Bruce Momjian

See näeb välja selline. Selge see, et nad kõik ootavad 12. rida.

Postgres Lock Manageri avamine. Bruce Momjian

Seda me siin nägime. Siin on 0/12.

Postgres Lock Manageri avamine. Bruce Momjian

Nii et kui esimene tehing on kinnitatud, näete siin, kuidas hierarhia töötab. Ja nüüd on kõik selge. Nad kõik saavad puhtaks. Ja tegelikult nad ootavad endiselt.

Postgres Lock Manageri avamine. Bruce Momjian

Siin on, mis toimub. 702 on toime pandud. Ja nüüd saab 703 selle rea lukustuse ja siis hakkab 704 ootama, kuni 703 kinnitub. Ja seda ootab ka 705. Ja kui see kõik on tehtud, koristavad nad end. Ja tahaksin märkida, et kõik on rivis. Ja see on väga sarnane liiklusummiku olukorraga, kus kõik ootavad esimest autot. Esimene auto on seisma jäänud ja kõik rivistuvad pikas järjekorras. Siis see liigub, siis saab järgmine auto ette tulla ja oma ploki kätte saada jne.

Postgres Lock Manageri avamine. Bruce Momjian

Ja kui see teile ei tundunud piisavalt keeruline, siis räägime nüüd teiega ummikseisudest. Ma ei tea, kes teist on neid kogenud. See on andmebaasisüsteemides üsna levinud probleem. Kuid ummikseisud on siis, kui üks seanss ootab, et teine ​​seanss midagi ära teeks. Ja sel hetkel ootab järjekordne seanss esimest seanssi, et midagi ära teha.

Ja näiteks kui Ivan ütleb: "Anna mulle midagi," ja mina ütlen: "Ei, ma annan selle teile ainult siis, kui annate mulle midagi muud." Ja ta ütleb: "Ei, ma ei anna seda sulle, kui sa seda mulle ei anna." Ja me satume ummikseisu. Olen kindel, et Ivan seda ei tee, kuid te mõistate, mis tähendab, et meil on kaks inimest, kes tahavad midagi saada ja nad ei ole valmis seda ära andma enne, kui teine ​​​​on neile seda, mida nad tahavad. Ja lahendust pole.

Ja tegelikult peab teie andmebaas selle tuvastama. Ja siis tuleb üks seanss kustutada või sulgeda, sest muidu jäävad need sinna igaveseks. Ja me näeme seda andmebaasides, me näeme seda operatsioonisüsteemides. Ja kõigis kohtades, kus meil on paralleelsed protsessid, võib see juhtuda.

Postgres Lock Manageri avamine. Bruce Momjian

Ja nüüd paigaldame kaks ummikseisu. Paneme 50 ja 80. Esimeses reas värskendan 50-lt 50-le. Saan tehingunumbri 710.

Postgres Lock Manageri avamine. Bruce Momjian

Ja siis muudan 80 81-ks ja 50 51-ks.

Postgres Lock Manageri avamine. Bruce Momjian

Ja siin on see, kuidas see välja näeb. Ja nii on 710-l rea lukk ja 711 ootab kinnitust. Nägime seda värskendamisel. 710 - on meie sarja omanik. Ja 711 ootab, et 710 saaks tehingu lõpule viia.

Postgres Lock Manageri avamine. Bruce Momjian

Ja seal on isegi kirjas, millisel real meil ummikseisud on. Ja siin hakkabki imelikuks minema.

Postgres Lock Manageri avamine. Bruce Momjian

Nüüd värskendame 80 kuni 80.

Postgres Lock Manageri avamine. Bruce Momjian

Ja siit algavad ummikseisud. 710 ootab vastust numbrilt 711 ja 711 ootab 710. Ja see ei lõpe hästi. Ja sellest pole pääsu. Ja nad ootavad üksteiselt vastust.

Postgres Lock Manageri avamine. Bruce Momjian

Ja see lihtsalt hakkab kõike edasi lükkama. Ja me ei taha seda.

Postgres Lock Manageri avamine. Bruce Momjian

Ja Postgresil on viise, kuidas seda märgata. Ja kui see juhtub, kuvatakse see viga. Ja sellest on selge, et selline ja selline protsess ootab SHARE LOCK'i mõnelt teiselt protsessilt, st mis on blokeeritud 711 protsessi poolt. Ja see protsess ootas, et sellisele ja sellisele tehingu ID-le antakse SHARE LOCK ja see blokeeritakse sellise ja sellise protsessiga. Seetõttu on surnud blokeeringu olukord.

Postgres Lock Manageri avamine. Bruce Momjian

Kas on kolmesuunalisi ummikseisu? Kas see on võimalik? Jah.

Postgres Lock Manageri avamine. Bruce Momjian

Me juhime need numbrid tabelisse. Vahetame 40 vastu 40, teeme luku.

Postgres Lock Manageri avamine. Bruce Momjian

Muudame 60 vastu 61, 80 vastu 81.

Postgres Lock Manageri avamine. Bruce Momjian

Ja siis vahetame 80 ja siis buum!

Postgres Lock Manageri avamine. Bruce Momjian

Ja 714 ootab nüüd 715. 716 ootab 715. Ja sellega pole midagi teha.

Postgres Lock Manageri avamine. Bruce Momjian

Ei ole enam kahte inimest, on juba kolm inimest. Ma tahan sinult midagi, see tahab midagi kolmandalt inimeselt ja kolmas inimene tahab midagi minult. Ja me lõpetame kolmepoolse ootamise, sest me kõik ootame, et teine ​​​​inimene lõpetaks selle, mida ta peab tegema.

Postgres Lock Manageri avamine. Bruce Momjian

Ja Postgres teab, millisel real see juhtub. Ja see annab teile järgmise teate, mis näitab, et teil on probleem, kus kolm sisendit blokeerivad üksteist. Ja siin pole piiranguid. See võib juhtuda juhul, kui 20 kirjet blokeerivad üksteist.

Postgres Lock Manageri avamine. Bruce Momjian

Järgmine probleem on seeriatav.

Postgres Lock Manageri avamine. Bruce Momjian

Kui spetsiaalne serialiseeritav lukk.

Postgres Lock Manageri avamine. Bruce Momjian

Ja me pöördume tagasi numbri 719 juurde. Tal on täiesti tavaline probleem.

Postgres Lock Manageri avamine. Bruce Momjian

Ja saate tõuke teha, et tehing oleks järjestatav.

Postgres Lock Manageri avamine. Bruce Momjian

Ja mõistate, et teil on nüüd teistsugune SA lukk - see tähendab jadatav.

Postgres Lock Manageri avamine. Bruce Momjian

Postgres Lock Manageri avamine. Bruce Momjian

Ja nii on meil uut tüüpi lukk nimega SARieadLock, mis on seerialukk ja võimaldab sisestada seerianumbreid.

Postgres Lock Manageri avamine. Bruce Momjian

Samuti saate sisestada ainulaadseid indekseid.

Postgres Lock Manageri avamine. Bruce Momjian

Selles tabelis on meil ainulaadsed indeksid.

Postgres Lock Manageri avamine. Bruce Momjian

Nii et kui ma panen siia numbri 2, on mul 2. Aga kõige ülaossa panen veel 2. Ja näete, et 721-l on eksklusiivne lukk. Kuid nüüd ootab 722, et 721 saaks oma töö lõpule viia, sest ta ei saa sisestada numbrit 2 enne, kui ta teab, mis 721-ga juhtub.

Postgres Lock Manageri avamine. Bruce Momjian

Ja kui teeme alltehinguid.

Postgres Lock Manageri avamine. Bruce Momjian

Siin on meil 723.

Postgres Lock Manageri avamine. Bruce Momjian

Ja kui salvestame punkti ja seejärel värskendame, saame uue tehingu ID. See on veel üks käitumine, millest peate teadlik olema. Kui me selle tagastame, on tehingu ID kadunud. 724 lahkub. Aga nüüd on meil 725.

Ja mida ma siin teha üritan? Püüan teile näidata näiteid ebatavalistest lukkudest, mida võite leida: olgu need siis järjestatavad lukud või SAVEPOINTi lukud, need on erinevat tüüpi lukud, mis ilmuvad lukutabelisse.

Postgres Lock Manageri avamine. Bruce Momjian

See on selgesõnaliste (selgesõnaliste) lukkude loomine, millel on pg_advisory_lock.

Postgres Lock Manageri avamine. Bruce Momjian

Ja näete, et luku tüüp on siin loetletud soovituslikuna. Ja siin on punasega kirjas "soovitav". Ja saate samaaegselt blokeerida pg_advisory_unlock.

Postgres Lock Manageri avamine. Bruce Momjian

Ja lõpetuseks tahaksin teile näidata veel üht meeleheitlikku asja. Loon teise vaate. Kuid ma ühendan tabeli pg_locks tabeliga pg_stat_activity. Ja miks ma tahan seda teha? Sest see võimaldab mul vaadata ja näha kõiki praeguseid seansse ja näha, milliseid lukke nad ootavad. Ja see on piisavalt huvitav, kui paneme kokku lukutabeli ja päringutabeli.

Postgres Lock Manageri avamine. Bruce Momjian

Ja siin loome pg_stat_view.

Postgres Lock Manageri avamine. Bruce Momjian

Ja värskendame rida ükshaaval. Ja siin näeme 724. Ja siis värskendame oma rida kolmeks. Ja mida sa siin praegu näed? Need on päringud, st näete kogu taotluste loendit, mis on loetletud vasakpoolses veerus. Ja siis paremal pool näete lukke ja seda, mida need loovad. Ja see võib olla teile arusaadavam, et te ei peaks iga kord iga seansi juurde tagasi minema ja vaatama, kas teil on vaja sellega liituda või mitte. Nad teevad seda meie eest.

Teine väga kasulik funktsioon on pg_blocking_pids. Tõenäoliselt pole te temast kuulnud. Mida ta teeb? See võimaldab meil öelda, et selle seansi 11740 jaoks, milliseid protsessi ID-sid see ootab. Ja näete, et 11740 ootab 724. Ja 724 on kõige tipus. Ja 11306 on teie protsessi ID. Põhimõtteliselt läheb see funktsioon üle teie lukustuslaua. Ja ma tean, et see on natuke keeruline, aga saate aru. Põhimõtteliselt läbib see funktsioon seda lukutustabelit ja püüab leida, kus see protsessi ID asub, arvestades lukke, mida see ootab. Samuti proovib see välja selgitada, milline protsessi ID on lukku ootaval protsessil. Nii et saate seda funktsiooni käivitada pg_blocking_pids.

Ja see on väga kasulik. Oleme selle lisanud alles alates versioonist 9.6, seega on see funktsioon vaid 5 aastat vana, kuid see on väga-väga kasulik. Ja sama kehtib ka teise taotluse kohta. See näitab täpselt seda, mida me nägema peame.

Postgres Lock Manageri avamine. Bruce Momjian

Sellest ma tahtsin teiega rääkida. Ja nagu ma eeldasin, kulutasime kogu oma aja ära, sest liumägesid oli nii palju. Ja slaidid on allalaadimiseks saadaval. Tahaksin teid tänada, et olete siin. Olen kindel, et naudite konverentsi ülejäänud osa, tänan teid väga!

Küsimused:

Näiteks kui proovin ridu värskendada ja teine ​​seanss üritab kogu tabelit kustutada. Niipalju kui ma aru saan, peaks seal olema midagi kavatsusluku taolist. Kas Postgres on selline asi?

Postgres Lock Manageri avamine. Bruce Momjian

Lähme tagasi päris algusesse. Võib-olla mäletate, et kui teete midagi, näiteks kui teete SELECTi, väljastame AccessShareLocki. Ja see hoiab ära laua maha kukkumise. Nii et kui soovite näiteks tabeli rida värskendada või rida kustutada, ei saa keegi kogu tabelit korraga kustutada, kuna hoiate seda AccessShareLocki kogu tabeli ja rea ​​kohal. Ja kui olete lõpetanud, saavad nad selle kustutada. Aga kui te seal midagi otseselt muudate, ei saa nad seda teha.

Teeme seda uuesti. Liigume edasi kustutamise näite juurde. Ja näete, kuidas real on kogu tabelil eksklusiivne lukk.

See näeb välja nagu eksklusiivne lukk, eks?

Jah, see näeb välja. Ma saan aru, millest sa räägid. Kas soovite öelda, et kui ma teen SELECT-i, siis on mul ShareExclusive ja seejärel panen selle olekusse Row Exclusive, kas see muutub probleemiks? Kuid üllataval kombel ei tekita see probleeme. See on nagu luku astme suurendamine, kuid sisuliselt on mul lukk, mis takistab selle kustutamist. Ja nüüd, kui ma selle luku võimsamaks muudan, takistab see ikkagi kustutamist. Nii et ma ei lähe üles. See tähendab, et see takistas seda ka siis, kui see oli madalamal tasemel, nii et kui ma seda tõstan, hoiab see endiselt ära laua maha kukkumise.

Ma saan aru, millest sa räägid. Blokeerimisastme suurendamise juhtumit, kus proovite loobuda ühest blokist, et kasutusele võtta võimsam, ei ole. Siin see lihtsalt suurendab seda vältimist kõikjal, nii et see ei tekita konflikte. Aga see on hea küsimus. Suur aitäh küsimast!

Mida me peame tegema, et vältida ummikseisu, kui meil on palju seansse ja palju kasutajaid?

Postgres märkab automaatselt ummikseisu. Ja see kustutab automaatselt ühe seansi. Ainus viis ummikseisu vältimiseks on blokeerida inimesi samas järjekorras. Nii et kui vaatate oma rakendust, on see sageli ummikseisu põhjus... Oletame, et ma tahan blokeerida kaks erinevat asja. Üks rakendus lukustab tabeli 1 ja teine ​​rakendus lukustab tabeli 2 ja seejärel tabeli 1. Ja kõige lihtsam viis ummikseisu vältimiseks on vaadata oma rakendust ja püüda veenduda, et lukustamine toimub kõigis rakendustes samas järjekorras. Ja see eemaldab tavaliselt 80% probleemidest, sest neid rakendusi kirjutavad igasugused inimesed. Ja kui blokeerite need samas järjekorras, siis ei satu te ummikseisu.

Suur tänu esinemise eest! Rääkisite vaakumtäiest ja kui ma õigesti aru saan, siis vaakumtäis moonutab eraldi poe kirjete järjekorda, nii et see hoiab praegused kirjed muutumatuna. Miks võtab vaakum täielik juurdepääsu lukustusele ja miks on see vastuolus kirjutamistoimingutega?

See on hea küsimus. Põhjus on selles, et vaakum täis võtab laua. Ja sisuliselt loome tabeli uue versiooni. Ja laud saab olema uus. Selgub, et see on tabeli täiesti uus versioon. Ja probleem on selles, et kui me seda teeme, siis me ei taha, et inimesed seda loeksid, sest me tahame, et nad näeksid uut tabelit. Ja see on seotud eelmise küsimusega. Kui me saaksime samal ajal lugeda, siis me ei saaks seda liigutada ja inimesi uue laua juurde suunata. Peaksime ootama, kuni kõik selle tabeli lugemise lõpetavad, ja seega on sisuliselt tegemist luku eksklusiivse olukorraga.
Ütleme lihtsalt, et lukustame algusest peale, sest teame, et vajame eksklusiivset lukku päris lõpus, et kõik uude eksemplari üle viia. Nii et potentsiaalselt saame selle lahendada. Ja nii teeme seda samaaegse indekseerimisega. Kuid seda on palju keerulisem teha. Ja see kehtib väga tugevalt teie eelmise küsimuse kohta, mis puudutab lukustusvõimalusi.

Kas Postgresis on võimalik lisada lukustamise ajalõpu? Oracle'is saan näiteks kirjutada "select to update" ja oodata 50 sekundit enne värskendamist. See oli rakenduse jaoks hea. Kuid Postgresis pean ma seda tegema kohe ja mitte üldse ootama või ootama mõnda aega.

Jah, saate valida oma lukkudele ajalõpu. Võite anda ka käskluse "ei tee", mis... kui te ei saa kohe lukku hankida. Seetõttu kas luku ajalõpp või midagi muud, mis võimaldab teil seda teha. Seda ei tehta süntaktilisel tasandil. Seda tehakse serveris muutujana. Mõnikord ei saa seda kasutada.

Kas saate slaidi 75 avada?

Jah.

Postgres Lock Manageri avamine. Bruce Momjian

Ja minu küsimus on järgmine. Miks mõlemad värskendusprotsessid ootavad 703?

Ja see on suurepärane küsimus. Muide, ma ei saa aru, miks Postgres seda teeb. Aga kui 703 loodi, ootas see numbrit 702. Ja kui 704 ja 705 ilmuvad, ei paista nad teadvat, mida nad ootavad, sest seal pole veel midagi. Ja Postgres teeb seda nii: kui sa ei saa lukku, siis ütleb "Mis mõtet on sind töödelda?", Sest sa juba ootad kedagi. Nii et me laseme sellel lihtsalt õhus rippuda, see ei värskenda seda üldse. Aga mis siin juhtus? Niipea kui 702 protsessi lõpetas ja 703 lukustuse sai, naasis süsteem tagasi. Ja ta ütles, et nüüd on meil kaks inimest, kes ootavad. Ja siis värskendame neid koos. Ja andkem märku, et mõlemad ootavad.

Ma ei tea, miks Postgres seda teeb. Kuid on probleem nimega f…. Mulle tundub, et see pole venekeelse termin. See on siis, kui kõik ootavad ühte lossi, isegi kui lossi ootavad 20 võimu. Ja äkki ärkavad nad kõik samal ajal. Ja kõik hakkavad proovima reageerida. Aga süsteem teeb nii, et kõik ootavad 703. Sest nad kõik ootavad ja me paneme nad kõik kohe ritta. Ja kui ilmub mõni muu uus päring, mis genereeriti pärast seda, näiteks 707, siis on jälle tühjus.

Ja mulle tundub, et seda tehakse selleks, et saaks öelda, et praegusel etapil ootab 702 703 ja kõik need, kes tulevad pärast seda, neil ei ole sellesse väljale sissekannet. Kuid niipea, kui esimene kelner lahkub, ja kõik need, kes sel hetkel enne värskendust ootasid, saavad sama märgi. Ja nii mulle tundub, et seda tehakse selleks, et saaksime järjekorras töödelda, et need oleksid korralikult tellitud.

Ma vaatasin seda alati kui üsna kummalist nähtust. Sest siin pole neid näiteks üldse kirjas. Kuid mulle tundub, et iga kord, kui anname uue luku, vaatame kõiki neid, kes ootavad. Siis paneme need kõik ritta. Ja siis iga uus, mis saabub, pannakse järjekorda alles siis, kui järgmine inimene on töötlemise lõpetanud. Väga hea küsimus. Tänan teid väga teie küsimuse eest!

Mulle tundub palju loogilisem, kui 705 ootab 704.

Kuid probleem on siin järgmine. Tehniliselt võite äratada kas ühe või teise. Ja nii me äratame üht-teist. Aga mis juhtub süsteemi töös? Näete, kuidas ülaosas asuv 703 on blokeerinud tema enda tehingu ID. Nii töötab Postgres. Ja 703 on blokeeritud tema enda tehingu ID-ga, nii et kui keegi tahab oodata, siis ta ootab 703. Ja tegelikult saab 703 valmis. Ja alles pärast selle lõppemist ärkab üks protsessidest. Ja me ei tea, milline see protsess on. Seejärel töötleme kõike järk-järgult. Kuid pole selge, milline protsess ärkab esimesena, sest see võib olla ükskõik milline neist protsessidest. Sisuliselt oli meil planeerija, mis ütles, et me võime nüüd kõik need protsessid äratada. Valime ühe juhuslikult. Seetõttu tuleks neid mõlemaid tähele panna, sest me võime neist üles äratada ükskõik millise.

Ja probleem on selles, et meil on CP-infinity. Ja seetõttu on üsna tõenäoline, et saame hilisema üles äratada. Ja kui me ärkame näiteks hiljem, siis ootame seda, kes just luku sai, nii et me ei määra, kes täpselt esimesena äratatakse. Me loome just sellise olukorra ja süsteem äratab nad juhuslikult üles.

On artiklid Egor Rogovi lukkude kohta. Vaata, need on ka huvitavad ja kasulikud. Teema on muidugi kohutavalt keeruline. Suur tänu Bruce!

Allikas: www.habr.com

Lisa kommentaar