ABONAMENTE VIDEO REDACȚIA
RO
EN
NOU
Numărul 148
Numărul 147 Numărul 146 Numărul 145 Numărul 144 Numărul 143 Numărul 142 Numărul 141 Numărul 140 Numărul 139 Numărul 138 Numărul 137 Numărul 136 Numărul 135 Numărul 134 Numărul 133 Numărul 132 Numărul 131 Numărul 130 Numărul 129 Numărul 128 Numărul 127 Numărul 126 Numărul 125 Numărul 124 Numărul 123 Numărul 122 Numărul 121 Numărul 120 Numărul 119 Numărul 118 Numărul 117 Numărul 116 Numărul 115 Numărul 114 Numărul 113 Numărul 112 Numărul 111 Numărul 110 Numărul 109 Numărul 108 Numărul 107 Numărul 106 Numărul 105 Numărul 104 Numărul 103 Numărul 102 Numărul 101 Numărul 100 Numărul 99 Numărul 98 Numărul 97 Numărul 96 Numărul 95 Numărul 94 Numărul 93 Numărul 92 Numărul 91 Numărul 90 Numărul 89 Numărul 88 Numărul 87 Numărul 86 Numărul 85 Numărul 84 Numărul 83 Numărul 82 Numărul 81 Numărul 80 Numărul 79 Numărul 78 Numărul 77 Numărul 76 Numărul 75 Numărul 74 Numărul 73 Numărul 72 Numărul 71 Numărul 70 Numărul 69 Numărul 68 Numărul 67 Numărul 66 Numărul 65 Numărul 64 Numărul 63 Numărul 62 Numărul 61 Numărul 60 Numărul 59 Numărul 58 Numărul 57 Numărul 56 Numărul 55 Numărul 54 Numărul 53 Numărul 52 Numărul 51 Numărul 50 Numărul 49 Numărul 48 Numărul 47 Numărul 46 Numărul 45 Numărul 44 Numărul 43 Numărul 42 Numărul 41 Numărul 40 Numărul 39 Numărul 38 Numărul 37 Numărul 36 Numărul 35 Numărul 34 Numărul 33 Numărul 32 Numărul 31 Numărul 30 Numărul 29 Numărul 28 Numărul 27 Numărul 26 Numărul 25 Numărul 24 Numărul 23 Numărul 22 Numărul 21 Numărul 20 Numărul 19 Numărul 18 Numărul 17 Numărul 16 Numărul 15 Numărul 14 Numărul 13 Numărul 12 Numărul 11 Numărul 10 Numărul 9 Numărul 8 Numărul 7 Numărul 6 Numărul 5 Numărul 4 Numărul 3 Numărul 2 Numărul 1
×
▼ LISTĂ EDIȚII ▼
Numărul 113
Abonament PDF

Cum ajungem la Deadlock

Alexandru Crăciun
Senior Database Engineer @ Cognizant Softvision



PROGRAMARE

În acest articol veți deveni familiari cu nivelele de izolare din SQL Server, cu mecanismele de tip locking și blocking, cu conceptul deadlock, cu identificarea și prevenția fenomenelor deadlock în SQL Server. Un fenomen deadlock este o situație în care două sau mai multe procese așteaptă unul după celălalt să finalizeze operațiile din cauza unui locking, ceea ce duce la așteptare infinită și la faptul că niciunul din procese nu mai progresează.

Fenomenele deadlock sunt importante, deoarece, dacă se întâmplă des în cadrul unei baze de date tranzacționale, acest lucru poate duce la probleme serioase de performanță și la erori multiple.

Înainte de a aprofunda fenomenul deadlock și modul în care îl putem preveni, trebuie să înțelegem câteva concepte de bază legate de bazele de date relaționale: proprietățile ACID, nivelele de izolare, problemele de concurență, locking și blocking.

Proprietățile ACID

O tranzacție din baza de date (Database Transaction) este o unitate logică de procesare din cadrul DBMS care presupune una sau mai multe operațiuni de acces în baza de date. Pe scurt, tranzacțiile din bazele de date sunt evenimentele reale, concrete ale unei afaceri.

Toate tipurile de operațiuni de acces în baza de date care sunt cuprinse între declarațiile (statements) de început și final sunt considerate drept o singură tranzacție logică în DBMS. În timpul tranzacției, baza de date este inconsistentă. Doar după ce baza de date este comisă (committed), starea se modifică de la un nivel de consistență la altul.

Sumar: Tranzacție - unitate logică singulară de lucru din cadrul unei baze de date. Într-o RDBMS o tranzacție respectă proprietățile ACID.

Nivelele de izolare

Nivelele de izolare definesc cât de mult trebuie să fie izolată tranzacția de modificările aduse asupra datelor de alte tranzacții din SQL Server. Nivelul de izolare va izola procesul și îl va proteja de alte tranzacții. Pentru acest lucru, este nevoie de locking.

Un nivel scăzut de izolare va genera nivele crescute de concurență și de utilizare partajată a datelor, dar poate avea drept efect nivele scăzute de consistență prin generarea de citiri corupte sau fantomă (dirty / phantom reads). SQL Server va folosi nivelele de izolare pentru a controla comportamentul de citire (read) a bazei de date/tranzacției.

Problemele de concurență

Din moment ce multiple tranzacții ar putea rula simultan (în mod concurent) într-o bază de date, putem găsi tranzacții care citesc din/sau actualizează același obiect de tip dată (rând, tabelă, index). Se introduc astfel mai multe probleme la care nivelele de izolare reacționează. Nivelul de izolare a tranzacției definește cum și unde va expune baza de date celorlalte sesiuni modificările efectuate de orice tranzacție.

Pentru a selecta nivelul de izolare propice pentru fiecare tranzacție, este obligatoriu să existe o bună înțelegere a problemelor de concurență:

Tipologia nivelelor de izolare

Tranzacția Read Uncommitted

Aceasta reprezintă cele mai scăzut nivel de izolare sau cel mai puțin restrictiv nivel de izolare. O tranzacție poate citi modificări care nu sunt încă comise de altă tranzacție care le efectuează. Permite citiri corupte (dirty reads).

Tranzacția Read Committed

Aceasta reprezintă nivelul standard (default) de izolare setat în SQL Server. Acesta nu permite citirea datelor din tranzacții necomise, deci nu permite citiri corupte (dirty reads). Poate avea drept efect citiri fantomă / citiri repetabile.

Tranzacția Repeatable Read

Acest nivel permite ca, dacă datele sunt recitite în cadrul unei tranzacții, acestea să nu se modifice. Nicio tranzacție nu poate modifica datele până când tranzacția care citește datele nu este finalizată. Consecința este că toate elementele shared lock din cadrul operațiunii de citire vor aștepta ca tranzacția să fie completă. Citirile corupte și non-repetabile vor fi eliminate, dar citirile fantomă pot să persiste.

Tranzacția Serializabilă

Aceasta reprezintă nivelul de izolare cel mai restrictiv și cea mai bună metodă de a asigura respectarea proprietăților ACID. Un bloc citire/scriere va fi generat pentru toate datele afectate de tranzacție, ceea ce elimină citirile fantomă.

Tranzacția Snapshot

În cadrul acestui nivel de izolare, o tranzacție recunoaște doar datele care sunt comise înainte de începutul tranzacției. Acest lucru se realizează folosindu-se un snapshot al datelor în tempdb. Procesul folosește versiunea rândului (row version) unde o versiune separată a fiecărui rând modificat se păstrează în tempdb. Cost ridicat/utilizare ridicată în tempdb. Elimină citirile corupte, non-repetabile, fantomă dar și actualizările pierdute.

Locking și blocaj

Locking este un mecanism folosit de SQL Server Database Engine pentru a sincroniza accesul mai multor utilizatori la aceleași date în același timp. Elementele lock sunt gestionate intern de Lock Manager. Pentru a minimiza costul lockingului, SQL Server aplică automat un lock calibrat cu taskurile, asupra resurselor. A aplica un lock la un nivel mai mic de granularitate, precum rândul, crește concurența, dar are o încărcătură mai mare, deoarece trebuie păstrate mai multe elemente lock. Durata cât se păstrează un lock depinde de nivelul de izolare.

Cele două tipuri de bază ale elementelor lock sunt: read locks și write locks.

Read Locks

Shared (Partajate) - Atâta timp cât se păstrează un shared lock, alte tranzacții pot citi, dar nu pot modifica datele care sunt locked. Elementul lock este ridicat după ce datele locked au fost citite cu condiția ca nivelul de izolare să se afle la sau mai sus de valoarea Repeatable Read.

Concurrent (Concurente) - În acest context, citim datele în cadrul unui nivel de izolare Read Uncommitted sau când specificăm un indiciu (hint) NOLOCK.

Write Locks

Update (Actualizare) - Elementele update lock sunt o combinație de elemente lock shared și exclusive. Când se execută o declarație update, SQL Server trebuie să găsească datele pe care dorește să le modifice prima oară. Pentru a evita un blocaj (deadlock) de conversie al elementelor lock, se folosește un update lock. Un singur update lock poate fi menținut la nivelul datelor la un moment dat, similar unui lock exclusiv. Elementul lock update în sine nu poate modifica datele subiacente, deci când datele sunt modificate, se realizează transferul către un lock exclusiv.

Exclusive (Exclusive) - Elementele exclusive lock sunt folosite pentru a bloca datele ce sunt modificate de o tranzacție, prevenindu-se astfel modificările altor tranzacții concurente. O tranzacție primește mereu un element exclusive lock pe orice date pe care le modifică și menține acel lock până la finalizarea tranzacției, indiferent de nivelul de izolare setat pentru acea tranzacție.

Resurse ce pot fi locked

RID (Row Identifier/Identificator de rând) - un rând din cadrul unei tabele de tip heap;

Moduri Lock

Escalarea de tip Lock (Lock Escalation)

SQL Server folosește lock escalation pentru a gestiona granularitatea la care se face locking. Lock escalation este gestionată intern, fiind o tehnică de optimizare care să controleze volumul de locks păstrate în Lock Manager din cadrul SQL Server.

Când se face locking la o granularitate mai scăzută, precum rândurile, concurența crește, accesul fiind restricționat la anumite rânduri, nu la toată tabela. Un lock este o structură in-memory de 96 bytes.

Granularitatea unui lock se compune din elemente lock DATABASE, TABELĂ, PAGINĂ și RÂND (ROW). O conexiune către SQL Server va crea un shared lock la nivel de bază de date, prevenind acțiuni precum "DROP DATABASE" atâta timp cât există o conexiune.

SQL Server va aplica granularitatea la nivel de elemente lock, de sus în jos: mai întâi va verifica dacă un lock la nivel de tabelă este necesar, apoi la nivel de pagină, iar apoi la nivel de rând. Un Intent (Shared or Exclusive) este generat la nivel de tabelă și pagină, iar un Shared sau Exclusive este generat la nivel de rând.

După ce SQL Server atinge 5000 de elemente lock la nivel de rând, se va escala la nivel de lock de tabelă.

Modificarea manuală a escalării de tip Lock

Valorile standard (default) pot fi modificate, folosind indicii de interogare (query hints) precum ROWLOCK, PAGLOCK, TABLOCK

select * from tbl_test with (ROWLOCK)
 where fld_id >1000

Puteți modifica lock escalation pentru fiecare tabelă folosind sintaxa:

ALTER TABLE tbl_test 
 SET LOCK_ESCALATION = 

Aceasta nu este recomandată, deoarece este cel mai bine să se permită ca Database Engine să efectueze operațiuni de tipul escalate locks.

Deadlocks

Un deadlock apare când două procese sunt blocate, deoarece fiecare proces păstrează o resursă de care are nevoie celălalt proces.

Exemplu: Kid_1 are un lock pe Phone_1 și solicită un lock pe Headphone_2. Kid_2 are un lock pe Headphone_2 și a solicitat un lock pe Phone_1. Aceștia așteaptă unul după celălalt.

SQL Server Engine decide care dintre cei doi este victima deadlockului, din moment ce niciun proces nu poate merge mai departe.

Cum se alege victima?

SQL Server Database Engine verifică dacă există deadlock la fiecare cinci secunde. Tranzacția care cade victimă este cea care are cea mai mică PRIORITATE DEADLOCK care se poate seta explicit la nivel de sesiune. Dacă ambele tranzacții au aceeași prioritate deadlock, atunci victima va fi tranzacția pentru care se face rollbackul cel mai ieftin. Cu alte cuvinte, tranzacția care a făcut cele mai puține schimbări în baza de date (cei mai puțini bytes scriși în logul bazei de date) va fi supusă unui rollback.

Informații despre Deadlocks în SQL Server

Activați trace flag 1222 : DBCC TRACEON(1222,-1) sau setați-l drept parametru de startup în SQL Server Configuration Manager. Informațiile sunt disponibile în SQL Server Error Log.

Folosind SQL Server Profiler / realizați un server side trace adăugând evenimentul: Locks: Deadlock Graph.

Folosind Extended Events: folosind evenimentul extins system_health sau creând unul și adăugând evenimente precum: lock_deadlock, lock_deadlock_chain or xml_deadlock_report.

Iată un exemplu de deadlock din SQL Server:

Soluții comune pentru a evita fenomenele de tip deadlock

Acum că înțelegem ce este un deadlock, iată câteva scenarii care ne ajută să prevenim sau să reparăm acest deadlock:

Utilizați cod customizat pentru a rula din nou tranzacția aleasă drept victimă.

Conferință TSM

NUMĂRUL 147 - Automotive

Sponsori

  • Accenture
  • BT Code Crafters
  • Accesa
  • Bosch
  • Betfair
  • MHP
  • BoatyardX
  • .msg systems
  • P3 group
  • Ing Hubs
  • Cognizant Softvision
  • Colors in projects