Extinderea blocării (componenta motorului de bază de date)

Blocarea este un proces de transformare a multor blocări cu granulație fină într-un număr mai mic de încuietori cu granulație mare, cu o posibilă creștere a concurenței concurenței.







Dat fiind că motorul de bază de date SQL Server primește încuietori de nivel scăzut, acesta blochează intențiile de blocare pe obiecte care conțin obiecte de nivel inferior.

Când blocați rânduri sau indexați intervalele de taste, motorul de baze de date blochează intenția de blocare pe paginile care conțin aceste linii sau chei.

Când paginile sunt blocate, motorul bazei de date plasează blocarea obiectelor de nivel superior care conțin aceste pagini. În plus față de blocarea intențiilor obiectului, sunt create încuietori de pagină pentru următoarele obiecte.

Indice nespecificate de punct final

Pagini ale datelor din indexul grupat

Pagini de date cu morminte

Motorul bazei de date poate, pentru aceeași instrucțiune, să fixeze o blocare pe ambele rânduri și pe pagini pentru a minimiza numărul de încuietori și a exclude necesitatea de a mări această blocare. De exemplu, componenta motorului Baza de date poate seta blocarea într-un index de pagini non-cluster (în cazul în care un număr suficient de cheie selectate consecutiv în nodul index pentru a îndeplini criteriile de interogare) și rândurile de blocare în paginile de date.

Pentru a mări blocare, motorul bazei de date încearcă să schimbe componenta de blocare cu un plan în tabelul de blocare completă corespunzătoare, cum ar fi blocarea cu schimbare intenție exclusivă (IX) într-o combinație exclusivă (X) sau un sistem de blocare, cu scopul de a combina accesul (IS) pe un comun (S). Dacă această încercare de blocare escaladare a avut succes, și a primit un sistem de blocare de masă completă, se elibereaza gramada încuietori, pagini arbore echilibrat (PAGE), și de blocare la nivelul rând (RID), care au avut loc la o grămadă de tranzacție sau index. Dacă nu puteți obține o blocare completă, în acest moment, blocarea nu este mărită, iar motorul de bază de date continuă să primească blocări de șiruri de caractere, chei sau pagini.

Închiderea la nivelul HoBT crește în mod obișnuit concurența, dar creează un risc potențial de blocare atunci când tranzacțiile blochează secțiuni diferite și încearcă să extindă blocarea exclusivă în alte secțiuni. În cazuri rare, granularitatea unei blocări TABLE poate fi o soluție mai bună.

Dacă încercarea de escaladare a blocării nu reușește din cauza blocărilor conflictuale deținute de tranzacțiile paralele, motorul de bază de date se reînnoiește pentru fiecare suplimentare de 1250 de blocări primite de tranzacție.

Fiecare eveniment de consolidare are loc în primul rând la nivelul unei instrucțiuni pentru o componentă Transact-SQL. La începutul evenimentului Database Engine este încercarea de a mări încuietorile care au fost deținute de tranzacție, toate tabelele care se face referire de instrucțiunea activă, cu condiția ca acestea să îndeplinească cerințele de la ridicarea pragului. Dacă evenimentul de extindere începe înainte ca instrucțiunea să aibă acces la masă, nu există încercări de mărire a încuietorilor pentru acest tabel. În cazul în care blocarea este escaladarea cu succes, toate încuietorile dobândite în tranzacție a instrucțiunii anterioare și încă a avut loc la momentul de începere a evenimentului, a crescut, în cazul în care tabelul de referință de tranzacție curentă și este inclusă în tabelul eveniment creșterea.







Să presupunem că o sesiune efectuează următoarele operații:

Actualizează tabelul TableA. Aceasta generează încuietori exclusive în tabelul TableA. care sunt păstrate până la finalizarea tranzacției.

Actualizează tabelul TableB. Acest lucru generează încuietori exclusive în tabelul TableB. care sunt păstrate până la finalizarea tranzacției.

Execută o instrucțiune SELECT care conectează tabelele TableA și TableC. Planul de executare a interogării implică recuperarea rândurilor din tabelul TableA înainte de a prelua rânduri din tabelul TableC.

Instrucțiunea SELECT provoacă mărirea blocării atunci când preluați rânduri din tabelul TableA înainte de a accesa tabelul TableC.

Dacă consolidarea blocării este reușită, sunt agregate numai blocările deținute de sesiunea de pe tabelul A. Acestea includ atât încuietorile combinate ale instrucțiunii SELECT, cât și blocarea exclusivă a instrucțiunii UPDATE anterioare. În timp ce pentru a determina necesitatea consolidării, sunt luate în considerare numai blocările pe care le-a primit sesiunea pentru instrucțiunea SELECT din TableA. după ce blocarea a fost lărgită cu succes, toate blocările ținute de sesiune în tabelul TableA. Măriți la blocarea exclusivă a mesei și toate celelalte încuietori cu granularitate mai mică, inclusiv încuietori cu intenție în tabelul A. sunt exceptate.

Încercările de a mări încuietorile din tabelul TableB nu sunt luate, deoarece nu există referințe active la TableB în instrucțiunea SELECT. În mod similar, nu au existat încercări de extindere a încuietorilor în tabelul TableC. deoarece la momentul extinderii accesul nu a fost obținut.

Blocarea este activată dacă tabela nu este oprită pentru parametrul ALTER TABLE SET LOCK_ESCALATION și dacă una dintre următoarele condiții este adevărată:

O instrucțiune Transact-SQL primește mai mult de 5.000 de încuietori într-un tabel sau index indexat.

O instrucțiune Transact-SQL primește mai mult de 5.000 de încuietori într-o singură secțiune a unei tabele partiționate, iar parametrul ALTER TABLE SET LOCK_ESCALATION este setat la AUTO.

Numărul de încuietori din instanța Engine Database depășește cantitatea de memorie sau pragurile specificate.

Dacă blocările nu pot fi agregate din cauza conflictelor de blocare, motorul bazei de date inițiază periodic escalarea blocării primind la fiecare 1250 de încuietori noi.

Praguri pentru instruciunea Transact-SQL

Blocarea este aplicată numai pentru tabelele accesate după pornirea actualizării. Să presupunem că o instrucțiune SELECT este o conexiune care accesează trei tabele în următoarea secvență: TableA. TableB și TableC. Această declarație primește 3 000 de încuietori de linie în indexul grupat al tabelului TableA și cel puțin 5 000 de blocări în rândul indexului grupat al tabelului TableB. dar nu a accesat încă tabelul TableC. Dacă motorul de baze de date detectează că instrucțiunea a primit cel puțin 5000 de încuietori în tabelul TableB. încearcă să consolideze toate blocările deținute de tranzacția curentă în tabelul TableB. De asemenea, această componentă încearcă să consolideze toate blocările deținute de tranzacția curentă în tabelul TableA. dar deoarece numărul de încuietori din tabelul A este mai mic de 5000, încercarea nu reușește. În tabelul TableC, nu se încearcă astfel de încercări, deoarece accesul la timpul de blocare nu a fost accesat.

Pragul de extindere pentru instanța motorului bazei de date

De fiecare dată când numărul de încuietori depășește pragul de memorie pentru consolidarea blocării, motorul de bază de date inițiază blocarea în sus. Pragul de memorie depinde de parametrul de configurare al încuietorilor:

Dacă parametrul de blocare este setat implicit la 0, pragul de escaladare a blocării este atins dacă memoria utilizată de obiectele de blocare este de 24% din memoria motorului bazei de date, excluzând memoria AWE. Structura de date care reprezintă blocarea are o lungime de aproximativ 100 de octeți. Acest prag este dinamic, deoarece motorul bazei de date primește dinamic și eliberează memoria dinamic pentru a compensa volumul de lucru în schimbare.

Dacă parametrul de blocare are o valoare diferită de 0, pragul de escaladare a blocării este de 40% (sau mai mic dacă memoria este mică) a valorii parametrului de blocare.

Componenta Baza de date de motor poate selecta pentru instrucțiuni de extindere de la orice sesiune activă, și blochează noul 1250 el selectează instrucțiuni pentru creșterea, dacă este utilizat într-un caz de blocare memoria depășește creșterea pragului.







Trimiteți-le prietenilor: