Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Ескалация на заключване на SQL сървър

Въведение

Релационните бази данни следват свойствата на ACID в начина, по който изпълняват транзакции – атомарност, последователност, изолация и издръжливост. Изолацията е необходима, за да се гарантира, че множество транзакции не могат да причинят промени в данните и да оставят евентуалните резултати непоследователни. За да гарантира, че операциите остават изолирани, SQL Server прилага механизми за заключване.

Режими на заключване и йерархия

Включен е механизмът на SQL Server за контрол на паралелност. За да оптимизирате производителността по отношение на изчакване на заключване, блокиране и други подобни, трябва да вземете решение въз основа на конкретния сценарий.

В SQL Server заключванията могат да се държат по различни начини и на няколко нива на детайлност. Режимите на заключване са специфичните начини за това и техните нива са йерархия на заключване.

Фигура 1 показва режимите на заключване, налични в SQL Server за нивото на изолация на транзакциите по подразбиране (ЗА ПРОЧЕТЕНЕ НА ЗАДАВАНЕ):

Преглед на ескалацията на заключване

SQL Server може да заключи ресурси на няколко нива. Зависи от най-ефективните действия според естеството на натоварването. Таблица 1 показва ресурсите, които могат да бъдат заключени.

  • Заключванията на по-подробно ниво (напр. заключвания на ниво ред) позволяват по-висок паралелизъм и по-малко блокиране.
  • Заключването на по-високо ниво (напр. заключване на ниво таблица) намалява едновременността. Те могат да причинят повече блокиране в зависимост от това колко дълго продължава действителното изявление.

SQL Server избира необходимото ниво на заключване според вътрешните показатели.

Ескалация на заключване се случва, когато заключване се преобразува от по-фино ниво на детайлност към по-грубо ниво.

Например, преобразуване на заключване на ред в заключване на таблица (вижте таблица 1).

Ресурс Описание
RID Идентификаторът на ред, използван за заключване на един ред в купчина.
КЛЮЧ Заключването на ред в индекс, използван за защита на диапазони от ключове в сериализиращи се транзакции.
СТРАНИЦА 8-килобайтовата (KB) страница в база данни, като например страници с данни или индекси.
ОБСТЪПНОСТ Следващата група от осем страници, като например страници с данни или индекси.
HoBT Купата или B-дървото. Заключването защитава B-дърво (индекс) или страниците с данни на купчина в таблица, която няма клъстериран индекс.
ТАБЛИЦА Цялата таблица, включително всички данни и индекси.
ФАЙЛ Файлът на базата данни.
ПРИЛОЖЕНИЕ Ресурсът, определен от приложението.
МЕТАДАННИ Заключване на метаданни.
ALLOCATION_UNIT Единицата за разпределение.
БАЗА ДАННИ Цялата база данни.

Обосновката за ескалация на заключване

Ключалките в SQL Server могат да бъдат доста скъпи. За всяко заключване, което Lock Manager придобие, SQL Server трябва да резервира памет – 64 байта или 128 байта. Сумата зависи от това дали имаме работа съответно с 32-битова или 64-битова система.

Тъй като броят на заключванията на редове в таблица се увеличава, SQL Server трябва да придобива все повече и повече памет. Следователно други процеси са гладни, без памет.

Има смисъл да преобразувате заключванията на редове и заключване на страници в заключване на ниво една таблица (обект). Това се случва, когато броят на заключванията за тази таблица надвиши 5000.

Компромисът възниква, когато цялата таблица вече не е достъпна за други сесии в процеса на транзакция.

Демонстриране на ескалация на заключване

Можем да демонстрираме ескалация на заключване с помощта на кода в листинг 1.

Нека първо опишем малко таблицата. Производство.ПродуктиI е сравнително малка таблица, носеща около 7777 реда. Сградните елементи са един и същ набор от 77 реда, дублирани 101 пъти. Кодът в листинг 1 се състои от три версии на една и съща декларация за актуализиране, всяка от които е включена в транзакция.

-- Listing 1: Demonstrating Lock Escalation

-- Update very few rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00'
WHERE unitprice='18.00';

ROLLBACK

-- Update a large number of rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00'
WHERE unitprice>'18.00';

ROLLBACK

-- Update over 5000 rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00';

ROLLBACK 

За повече яснота ще разбием съдържанието на листинг 1.

Преди това нека разгледаме листинг 2 – заявка за показване на заключванията, съхранявани в базата данни TSQLV4.

Първото ни действие е да изпълним листинг 1а. След това използваме листинг 2, за да проучим как Мениджърът на заключване извършва заключване в сценария. Ние изпълняваме листинг 1а, без да издаваме оператора за връщане назад. По този начин запазваме ключалките достатъчно дълго, така че заявката в листинг 2 да може да ги улови.

-- Listing 1a: Demonstrating Lock Escalation
-- Update very few rows

BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00'
WHERE unitprice='18.00';

ROLLBACK

-- Listing 2: Displaying Locks Held in Database TSQLV4

USE TSQLV4
GO
SELECT 
resource_type
, DB_NAME (resource_database_id) database_name
--, OBJECT_NAME(resource_associated_entity_id) resource_name
, request_mode
, request_type
, request_status
, request_reference_count
, request_session_id
, resource_associated_entity_id
, OBJECT_NAME(resource_associated_entity_id) [object_name] --small obj ids
, getuser.login_name
FROM sys.dm_tran_locks
CROSS APPLY dmv.dbo.getuser(request_session_id) as getuser
WHERE DB_NAME (resource_database_id)='TSQLV4';

Когато изпълним заявката в листинг 1а и след това проверим заключванията с помощта на заявката в листинг 2, SQL Server връща резултата, показан на фигура 2.

404 реда в таблицата имат unitprice=’18.00’ . Мениджърът на заключване заключва тези редове заедно с другите ключалки от всяко необходимо ниво. Това довежда броя на редовете на фигура 2 до 467.

-- Listing 1b: Demonstrating Lock Escalation
-- Update a large number of rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00'
WHERE unitprice>'18.00';

ROLLBACK

Наблюдаваме подобно поведение, когато изпълняваме заявката в листинг 1b. Този път имаме работа с 4406 реда. Той отразява броя на редовете в таблицата Production.ProductI с единична цена>18,00.

-- Listing 1c: Demonstrating Lock Escalation
-- Update over 5000 rows
BEGIN TRAN

use TSQLV4
GO
UPDATE Production.ProductsI SET unitprice='100.00';

ROLLBACK

Когато отидем по-нататък и изпълним кода в листинг 1c, виждаме различно поведение (вижте фигура 4).

Списък 1c се опитва да актуализира всички 7777 реда в таблицата Production.ProductI. SQL Server определя, че заключването на толкова много редове вече не е ефективно за гарантиране на изолация. Вместо това цялата маса е заключена.

Още за ескалацията на заключване

Заключването на таблицата предполага, че никоя друга сесия не може да промени своите редове за продължителността на транзакцията, което може да се случи дори когато блокираща сесия не манипулира всички редове в таблицата.

Също така си струва да се спомене, че други фактори могат да повлияят на това как се придобиват и ескалират заключванията в SQL Server. Това са конфигурирано ниво на изолация, флагове за индексиране и проследяване.

Флаговете за проследяване T1211 и T1224 могат да се прилагат за пълно деактивиране на ескалацията на заключване. Ескалацията на заключване може също да бъде деактивирана и активирана за конкретна таблица със следния код:

-- Listing 5: Disable and Enable Lock Escalation

ALTER TABLE Production.ProductsI SET (LOCK_ESCALATION=DISABLE);

ALTER TABLE Production.ProductsI SET (LOCK_ESCALATION=TABLE);

Може да искате да го направите, за да намалите блокирането, свързано със заключване на цялата таблица. Поради въздействието върху паметта, трябва да се обмисли като временна мярка.

Заключение

SQL Server използва ескалация на заключване, за да контролира въздействието на по-детайлното заключване върху ресурсите на сървъра. За да покажете начина на възникване на тези ключалки – заключвания на редове, заключване на страници, заключвания на обекти и т.н. – потърсете изгледа за динамично управление sys.dm_tran_locks. Той предоставя много информация за заключването, освен ескалацията на заключване.

Въпреки че е възможно да се манипулира поведението на Мениджъра на заключване, важно е да го правите с голямо внимание. Също така е от решаващо значение да се знае точното въздействие върху производителността на всяко усилие, насочено към извършване на такива модификации.

Препратки

  1. Короткевич, Д., 2016. Pro SQL Server Internals. Флорида:Дмитрий Короткевич
  2. Сценарии за заключване с помощта на Sys.dm_tran_locks
  3. Ръководство за заключване на транзакции и версия на ред


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL групово импортиране от CSV

  2. Как да избягам от знак за процент в T-SQL?

  3. Как да промените име на база данни в SQL Server с помощта на T-SQL

  4. СЪЗДАЙТЕ ТАБЛИЦА, АКО НЕ СЪЩЕСТВУВА, еквивалент в SQL Server

  5. Как да преглеждате множество заявки и резултати една до друга в SQL Server Management Studio (SSMS) - SQL Server / TSQL урок, част 14