Ce consecințe poate avea slăbirea nivelului de izolare a tranzacțiilor în bazele de date

Bună ziua tuturor. Vladislav Rodin la datorie. În prezent, sunt conducătorul cursului „Arhitect de înaltă încărcare” la OTUS și predau de asemenea cursuri dedicate arhitecturii software-ului.

Pe lângă predare, după cum ați observat, mă ocup de scrierea de materiale originale pentru blogul OTUS pe Habr și vreau să dedic articolul de astăzi lansării cursului «PostgreSQL», pentru care înscrierile sunt deschise chiar acum.

Ce consecințe poate avea slăbirea nivelului de izolare a tranzacțiilor în bazele de date

Introducere

În ultima dată Am discutat despre cum tranzacțiile în bazele de date servesc pentru a rezolva două sarcini: asigurarea rezilienței și accesul la date într-un mediu concurențial. Pentru a îndeplini aceste sarcini complet, o tranzacție trebuie să aibă proprietățile ACID. Astăzi vom vorbi în detaliu despre litera I (izolare) din această abreviere.

Izolare

Izolarea adresează problema accesului la date într-un mediu concurențial, oferind efectiv protecție împotriva condițiilor de competiție. În ideal, izolarea înseamnă serializare, adică proprietatea care asigură că rezultatul execuției tranzacțiilor paralele este același cu cel dacă ar fi fost executate secvențial. Problema principală a acestei proprietăți este că este foarte greu de asigurat din punct de vedere tehnic și, ca urmare, afectează semnificativ performanța sistemului. De aceea, izolarea este adesea slăbită, asumându-și riscurile apariției unor anomalii despre care vom discuta mai jos. Posibilitatea apariției anumitor anomalii caracterizează exact nivelul de izolare al tranzacțiilor.

Cele mai cunoscute anomalii sunt: lectura murdară, lectura non-repetabilă, lectura fantomă, dar, de fapt, există încă 5: scrierea murdară, actualizarea pierdută a cursorului, actualizarea pierdută, citirea skew, scrierea skew.

Scrierea murdară

Esenta anomaliilor constă în faptul că tranzacțiile pot suprascrie date necomise.

Ce consecințe poate avea slăbirea nivelului de izolare a tranzacțiilor în bazele de date

Această anomalie este periculoasă nu doar pentru că datele pot intra în conflict după confirmarea ambelor tranzacții (așa cum se vede în imagine), ci și pentru că afectează atomicitatea: deoarece vom permite suprascrierea datelor necomise, nu este clar cum să revenim asupra unei tranzacții fără a afecta alta.

Anomalia se repară destul de simplu: punem un blocaj pe scriere înainte de a începe scrierea, interzicând altor tranzacții să schimbe înregistrarea până când blocajul este ridicat.

Lectura murdară

Lectura murdară înseamnă citirea unor date necomise.

Ce consecințe poate avea slăbirea nivelului de izolare a tranzacțiilor în bazele de date

Problemele apar atunci când este necesar să se realizeze acțiuni sau să se ia decizii pe baza unui eșantion.

Pentru a corecta anomalia, se poate aplica o blocare de citire, dar asta va afecta semnificativ performanța. Mult mai simplu este să spunem că, pentru rollback-ul tranzacției, starea inițială a datelor (înainte de începutul scrierii) trebuie să fie neapărat păstrată în sistem. De ce să nu citim de acolo? Este suficient de ieftin, așa că majoritatea bazelor de date dezactivează citirea murdară în mod implicit.

Actualizare pierdută

Actualizare pierdută înseamnă actualizări pierdute, iar traducerea reflectă destul de bine esența problemei:

Ce consecințe poate avea slăbirea nivelului de izolare a tranzacțiilor în bazele de date

Practically, the result of transaction T2 has been canceled. This situation is corrected by explicit or implicit record locks. That is, we either simply update the record, which causes an implicit lock, or we perform select for update, causing both read and write locks to occur. Note that this operation is quite dangerous: by our 'innocent' reading, we block other readings. Some databases offer a safer select for share, allowing data to be read but not modified.

Actualizarea pierdută a cursorului

Pentru un control mai detaliat, bazele de date pot oferi alte instrumente, cum ar fi cursorii. Un cursor este o structură care conține un set de rânduri și permite iterarea prin ele. declare cursor_name for select_statement. Conținutul cursorului este descris de select.

De ce este nevoie de un cursor? Problema este că unele baze de date oferă blocări pentru toate înregistrările selectate de select (stabilitate în citire), sau doar pentru înregistrarea pe care se află în acel moment cursorul (stabilitate a cursorului). La stabilitatea cursorului se realizează o blocare scurtă, ceea ce permite reducerea numărului de blocări în cazul în care iterăm printr-un eșantion mare de date. De aceea, anomalia actualizării pierdute este evidențiată pentru cursor separat.

Citire non-repetabilă

Citirea non-repetabilă constă în faptul că, în timpul executării tranzacției noastre, 2 citiri succesive ale aceleași înregistrări vor duce la obținerea unor rezultate diferite, deoarece o altă tranzacție a intervenit între aceste două citiri, a modificat datele noastre și a fost confirmată.

Ce consecințe poate avea slăbirea nivelului de izolare a tranzacțiilor în bazele de date

De ce este aceasta o problemă? Imaginați-vă că scopul tranzacției T2 din imagine este de a selecta toate produsele a căror preț este mai mic de 150 u.e. Cineva a actualizat prețul la 200 u.e. Astfel, filtrul stabilit nu a funcționat.

Aceste anomalii încetează să apară prin adăugarea de blocări în două etape sau prin utilizarea mecanismului MVCC, despre care dorim să discutăm separat.

Citire fantomă

Citirea fantomă se referă la citirea datelor care au fost adăugate de o altă tranzacție.

Ce consecințe poate avea slăbirea nivelului de izolare a tranzacțiilor în bazele de date

Ca exemplu, putem observa selecția incorectă a celui mai ieftin produs în cazul apariției acestei anomalii.

Eliminarea citirilor fantomă este deja destul de complicată. O simplă blocare nu este suficientă, deoarece nu putem bloca ceea ce nu există încă. Sistemele 2PL folosesc blocări predictive, în timp ce sistemele MVCC rețin tranzacțiile care pot fi afectate de inserții. Atât primul, cât și al doilea mecanism sunt destul de greoaie.

Citire distorsionată

Citirea distorsionată apare atunci când lucrăm cu mai multe tabele, ale căror conținuturi ar trebui să se schimbe în mod coerent.

Să presupunem că avem tabele care reprezintă postări și metainformațiile acestora:

Ce consecințe poate avea slăbirea nivelului de izolare a tranzacțiilor în bazele de date

O tranzacție citește din tabele, alta le modifică:

Ce consecințe poate avea slăbirea nivelului de izolare a tranzacțiilor în bazele de date

Ca rezultat al executării tranzacției T1, postarea cu titlul = Good, iar updated_by = T2, ceea ce reprezintă o anumită incongruență.

De fapt, aceasta este o citire non-repetabilă, dar în cadrul mai multor tabele.

Pentru a remedia situația, T1 poate impune blocări asupra tuturor rândurilor pe care le va citi, ceea ce nu va permite tranzacției T2 să modifice informația. În cazul MVCC, tranzacția T2 va fi anulată. Protecția împotriva acestei anomalii poate deveni importantă dacă folosim cursori.

Scriere distorsionată

Această anomalie este de asemenea mai ușor de explicat prin exemplu: să presupunem că în sistemul nostru trebuie să fie cel puțin un doctor de gardă, dar ambii doctori au decis să-și anuleze serviciul:

Ce consecințe poate avea slăbirea nivelului de izolare a tranzacțiilor în bazele de date

Ce consecințe poate avea slăbirea nivelului de izolare a tranzacțiilor în bazele de date

Anomalia a dus la faptul că niciunul dintre doctori nu va veni la serviciu. De ce s-a întâmplat asta? Pentru că tranzacția a verificat o condiție care ar putea fi afectată de o altă tranzacție, iar din cauza izolării nu am văzut această modificare.

Este aceeași citire non-repetabilă. Ca variantă, selectările pot impune blocări asupra acestor înregistrări.

Scrierea skew și citirea skew sunt combinații ale anomaliilor anterioare. Putem considera scrierea skew, care este în esență o citire fantomă. Să luăm în considerare un tabel în care sunt numele angajaților, salariul lor și proiectul pe care lucrează:

Ce consecințe poate avea slăbirea nivelului de izolare a tranzacțiilor în bazele de date

Ce consecințe poate avea slăbirea nivelului de izolare a tranzacțiilor în bazele de date

În cele din urmă, obținem următoarea imagine: fiecare manager credea că modificarea sa nu va duce la depășirea bugetului, așa că au făcut modificări de personal, care au dus la un surplus total.

Cauza problemei este exact aceeași ca și în cazul citirii fantome.

Conclusions

Slăbirea nivelului de izolare a tranzacțiilor în baza de date este un compromis între securitate și performanță, iar alegerea acestui nivel ar trebui să se facă în funcție de riscurile potențiale pentru afacere în cazul apariției anumitor anomalii.

Află mai multe despre curs.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster