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.
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ę:
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.
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.
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.
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.
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:
Kitaip tariant, turime kelis variantus. Galime:
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
.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.
Dive deep into ways to best index your data and learn how to mysql if…
Dive deep into ways to load big data sets into MySQL with BreachDirectory. From MySQL…
Can the SQL EXPLAIN statement be a DoS vector and how to mitigate this threat?…
What is Cross Site Scripting, how does it work, and how can developers prevent it?…
BreachDirectory explains the risks of compressed files with a password on them for your infrastructure…
There have been rumors about a data breach targeting Schneider Electric. Did a data breach…