Categories: Security

MySQL Aklavietės 101

Kartais dirbdami su MySQL galite pamatyti šią keistoką klaidą:

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

Ši klaida praneša apie aklavietę – tai mes bandysime aptarti šiame įraše.

Kas yra Aklavietė?

Aklavietė atsiranda tada, kai nei viena iš skirtingų MySQL užklausų negali įvykti, nes abi iš jų turi po užraktą, reikalingą kitai užklausai. Šis paveiksliukas iliustruoja aklavietę:

Aklavietės Iliustracija

Verta paminėti, kad aklavietės nereikėtų painioti su užraktu – įrašai yra užrakinami tada, kai išteklius bando pasiekti keli procesai tuo pačiu metu, tačiau aklavietė atsiranda tada, kai dvi ar daugiau užklausų laukia kol viena kitos pabaigos.

Aklaviečių Aptikimas

Naudojant InnoDB variklį aklavietės aptinkamos automatiškai – kai aklavietė aptinkama, variklis automatiškai grąžina užklausą į buvusią vietą tam, kad ši nepapultų į aklavietę. Tikslų atšauktų operacijų kiekį yra sunku nustatyti, nes variklis pasirenka operacijas kurios turi būti atšauktos pagal tai, kiek įrašų paveikia INSERT, UPDATE ar DELETE užklausos.

Aklaviečių Pavyzdžiai

Tam, kad sumodeliuotume aklavietės situaciją, panaudosime dvi lenteles su dviejomis sesijomis toje pačioje duomenų bazėje.

Vienoje sesijoje mes paleisime šias užklausas:

START TRANSACTION;
UPDATE `table_1` SET `id` = ID WHERE `id` = 1;

Kitoje sesijoje mes taip pat paleisime panašias užklausas:

START TRANSACTION;
UPDATE `table_2` SET `id` = ID WHERE `id` = 1;

Tada vienu metu paleisime žemiau esančias užklausas. Pirmoje lentelėje paleisime šią užklausą:

UPDATE `table_1` SET `id` = ID WHERE `id` = 1;

Antroje lentelėje paleisime šią užklausą:

UPDATE `table_2` SET `id` = ID WHERE `id` = 1;

Įvykdę šias užklausas MySQL turėtume gauti tokią klaidą:

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

Kitokį aklavietės pavyzdį galite rasti InnoDB dokumentacijoje.

Ar Aklavietės Pavojingos?

Kai kurie žmonės gali manyti, kad aklavietės yra pavojingos todėl, kad aklavietės gali neigiamai paveikti programos našumą, o tai gali tapti tiesiogine vartotojų skundų priežastimi: vartotojai ir MySQL duomenų bazių administratoriai dėl šios problemos gali kaltinti programuotojus, o programuotojai gali kaltinti duomenų bazių administratorius.

Tačiau aklaviečių neturėtume laikyti pavojingomis – net MySQL dokumentacijoje teigiama, kad aklavietės nėra pavojingos. Atsidūrus aklavietėje operacija gali būti papraščiausiai paleista iš naujo – operacijos paleidimas iš naujo yra vienas iš būdų, padedančių susidoroti su aklavietėmis MySQL ekosistemoje.

Kaip Išvengti Aklaviečių MySQL?

Išvengti MySQL aklaviečių nėra tik duomenų bazių administratorių darbas – gali atsitikti ir taip, kad į šį procesą reiks įsitraukti ir programuotojams. Aklavietės atsiranda tada, kai atsiranda kelios Coffman’o sąlygos – norint išvengti aklaviečių reiktų vengti šių sąlygų. Šias sąlygas sudaro:

  1. Tarpusavio atskirtis: bent viena iš užklausų turi būti atskirta nuo kitų užklausų;
  2. Resursų užklaikymas: viena užklausa turi užlaikyti bent vieną užklausą ir reikalauti papildomų išteklių, kuriuos užlaiko kiti procesai;
  3. Jokių išimčių (laikinų pertraukimų): užklausą gali būti “paleista” tik tos užklausos, kuri jį užlaiko;
  4. Apskritasis laukimas: kiekvienas procesas turi laukti resurso, kurį laiko kitas procesas, kuris laukia, kol bus paleistas pirmasis procesas.

Kitaip tariant, turime kelis variantus. Galime:

  • Padalinti ilgas transakcijas į trumpesnes. Tai darydami galėsime leisti užraktams greičiau atsilaisvinti;
  • Peržiūrėti užklausas, dirbančias su tais pačiais duomenimis – galbūt galite išvengti tų pačių dalykų prašymo tuo pačiu metu?
  • Optimizuoti savo užklausas taip, kad jos prieitų prie mažiau duomenų – gerai optimizuotos užklausos gali baigtis greičiau, ir, savo ruožtu, nesudaryti aklavietės;
  • Padaryti pertrauką prieš iš naujo paleisdami užklausą – aklavietėje esančios užklausos gali baigtis mums belaukiant;
  • Visiškai išjungti aklavietes – MySQL užraktai ir aklavietės yra mechanizmai, kurie mums padeda išlaikyti turimų duomenų nuoseklumą ir jie neturėtų būti apeinami nebent mes norime pakenkti savo duomenims, nors kai kuriuose scenarijuose juos išjungti gali būti prasminga, nes tai padarius paspartintume savo užklausas (kai kur gali būti išvengta užklausų, kurios laukia to paties užrakto “paleidimo”) – MySQL turi parinktį, leidžiančią išjungti aklavietes: aklaviečių aptikimą galima išjungti nustatant kintamąjį innodb_deadlock_detect į OFF. Aklavietes taip pat galima išjungti per komandinę eilutę, tokiu atveju reiktų naudoti --innodb-deadlock-detect komandą. Šios komandos priimtinos reikšmės yra ON ir OFF.

Santrauka

Kaip ir minėta ankščiau, užraktai ir aklavietės yra mechanizmai, skirti užtikrinti mūsų turimų duomenų saugumą – šių mechanizmų išjungimas yra naudingas tik labai retais atvejais. Į aklavietę turėtų būti žiūrima kaip į pagalbininkę, kuri padeda mums padaryti mūsų aplikacijas efektyvesnimėmis. Norėdami užkirsti kelią aklavietėms programuotojai turėti vengti Coffmano sąlygų – jei bent vienos iš šių sąlygų bus išvengta, aklavietės neturėtų būti problema.

Nirium

Recent Posts

Schneider Electric: JIRA Server Breached

There have been rumors about a data breach targeting Schneider Electric. Did a data breach…

6 days ago

The Makers of Fiskars Scissors Got Breached: What’s Known

There have been rumors about the Fiskars Group – the company behind Fiskars scissors and…

6 days ago

Russia Fines Google for $20,000,000,000,000,000,000,000,000,000,000,000

Russia has fined Google more than two undecillion roubles because Google has refused to pay…

1 week ago

RockYou 2024.txt Looks Like a Binary File – Here’s Why

Why does RockYou 2024.txt look like a binary file when you open it up? Find…

1 week ago

Duolicious Data Leak: What You Need to Know

Duolicious is a dating app that connects people who are “chronically online.” Did the Duolicious…

2 weeks ago

What is RockYou 2024.txt and How Did RockYou 2024 Come to Be?

This blog will tell you what RockYou 2024 is, how RockYou 2024.txt came to be,…

2 weeks ago