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

Основна концепция за заключване на SQL Server

В тази публикация ще обсъдим механизма за заключване на SQL Server и как да наблюдавате заключването на SQL Server със стандартните динамични изгледи за управление на SQL Server. Преди да започнем да обясняваме архитектурата на заключване на SQL Server, нека отделим малко време, за да опишем какво представлява базата данни ACID (атомност, консистенция, изолация и издръжливост). Базата данни ACID може да се обясни като теория на базата данни. Ако база данни се нарича релационна база данни, тя трябва да отговаря на изискванията за атомарност, последователност, изолация и издръжливост. Сега ще обясним накратко тези изисквания.

Атомност :Той отразява принципа на неделимостта, който описваме като основна характеристика на процеса на транзакция. Един транзакционен блок не може да бъде оставен без надзор. Половината от оставащия блок за транзакции причинява несъответствие на данните. Или се изпълнява цялата транзакция, или транзакцията се връща в началото. Тоест всички промени, направени от транзакцията, се отменят и се връщат в предишното си състояние.

Последователност :Има правило, което задава подструктурата на правилото за неделимост. Данните за транзакциите трябва да осигуряват последователност. Тоест, ако операцията за актуализиране се извършва в транзакция, трябва да се извършат или всички останали транзакции, или операцията за актуализиране трябва да бъде отменена. Тези данни са много важни по отношение на последователността.

Изолация :Това е пакет заявка за всяка база данни за транзакции. Промените, направени от пакет със заявка, трябва да бъдат видими за друга транзакция, преди тя да бъде завършена. Всяка транзакция трябва да се обработва отделно. Всички транзакции трябва да бъдат видими за друга транзакция, след като се случат.

Издръжливост: Транзакциите могат да извършват сложни операции с данни. За да се осигурят всички тези транзакции, те трябва да са устойчиви на транзакционна грешка. Системните проблеми, които могат да възникнат в SQL Server, трябва да бъдат подготвени и устойчиви срещу прекъсване на захранването, операционна система или други грешки, причинени от софтуера.

Транзакция: Транзакцията е най-малкият стек от процеса, който не може да бъде разделен на по-малки парчета. Също така, някои групи транзакционни процеси могат да се изпълняват последователно, но както обяснихме в принципа на атомарността, ако дори една от транзакциите се провали, всички транзакционни блокове ще се провалят.

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

Йерархия на заключване: SQL Server има йерархия за заключване, която придобива заключващи обекти в тази йерархия. Базата данни се намира в горната част на йерархията, а редът е в долната част. Изображението по-долу илюстрира йерархията на заключването на SQL Server.

Споделени (S) ключалки: Този тип заключване възниква, когато обектът трябва да бъде прочетен. Този тип заключване не създава особени проблеми.

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

Актуализиране на (U) ключалки: Този тип заключване е подобен на изключителната ключалка, но има някои разлики. Можем да разделим операцията по актуализиране на различни фази:фаза на четене и фаза на запис. По време на фазата на четене SQL Server не иска други транзакции да имат достъп до този обект, за да бъдат променени. Поради тази причина SQL Server използва заключването на актуализацията.

Заключване на намерение: Заключването на намерението се случва, когато SQL Server иска да придобие споделено (S) заключване или изключително (X) заключване на някои от ресурсите по-долу в йерархията на заключване. На практика, когато SQL Server придобие заключване на страница или ред, заключването с намерение се изисква в таблицата.

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

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

CREATE TABLE TestBlock
(Id INT ,
Nm VARCHAR(100))

INSERT INTO TestBlock
values(1,'CodingSight')
In this step, we will create an open transaction and analyze the locked resources.
BEGIN TRAN
UPDATE TestBlock SET   Nm='NewValue_CodingSight' where Id=1
select @@SPID

Сега ще проверим изгледа sys.dm_tran_lock.

select * from sys.dm_tran_locks  WHERE request_session_id=74

Този изглед връща много информация за активните ресурси за заключване. Но не е възможно да се разберат някои от данните в този изглед. Поради тази причина трябва да се присъединим към sys.dm_tran_locks преглед на други изгледи.

SELECT dm_tran_locks.request_session_id,
       dm_tran_locks.resource_database_id,
       DB_NAME(dm_tran_locks.resource_database_id) AS dbname,
       CASE
           WHEN resource_type = 'OBJECT'
               THEN OBJECT_NAME(dm_tran_locks.resource_associated_entity_id)
           ELSE OBJECT_NAME(partitions.OBJECT_ID)
       END AS ObjectName,
       partitions.index_id,
       indexes.name AS index_name,
       dm_tran_locks.resource_type,
       dm_tran_locks.resource_description,
       dm_tran_locks.resource_associated_entity_id,
       dm_tran_locks.request_mode,
       dm_tran_locks.request_status
FROM sys.dm_tran_locks
LEFT JOIN sys.partitions ON partitions.hobt_id = dm_tran_locks.resource_associated_entity_id
LEFT JOIN sys.indexes ON indexes.OBJECT_ID = partitions.OBJECT_ID AND indexes.index_id = partitions.index_id
WHERE resource_associated_entity_id > 0
  AND resource_database_id = DB_ID()
 and request_session_id=74
ORDER BY request_session_id, resource_associated_entity_id

На горното изображение можете да видите заключените ресурси. SQL Server придобива изключителното заключване в този ред. (RID :Идентификатор на ред, използван за заключване на един ред в купчина) В същото време SQL Server придобива изключителното заключване на намерението в страницата и TestBlock маса. Това означава, че всеки друг процес не може да прочете този ресурс, докато SQL Server не освободи ключалките. Това е основният механизъм за заключване в SQL Server.

Сега ще попълним някои синтетични данни в нашата тестова таблица.

TRUNCATE TABLE 	  TestBlock
DECLARE @K AS INT=0
WHILE @K <8000
BEGIN
INSERT TestBlock VALUES(@K, CAST(@K AS varchar(10)) + ' Value' )
SET @[email protected]+1
 END
After completing this step, we will run two queries and check the sys.dm_tran_locks view.
BEGIN TRAN
 UPDATE TestBlock  set Nm ='New_Value' where Id<5000

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

BEGIN TRAN
 UPDATE TestBlock  set Nm ='New_Value' where Id<7000

В горната заявка SQL Server създава изключителното заключване на таблицата, тъй като SQL Server се опитва да придобие много RID ключалки за тези редове, които ще бъдат актуализирани. Този случай причинява много потребление на ресурси в двигателя на базата данни. Следователно SQL Server автоматично премества това изключително заключване към обект от по-високо ниво, който е в йерархията на заключването. Ние дефинираме този механизъм като ескалация на заключване. Ескалацията на заключване може да бъде променена на ниво таблица.

ALTER TABLE XX_TableName
SET
(
	LOCK_ESCALATION = AUTO -- or TABLE or DISABLE
)
GO

Бих искал да добавя някои бележки относно ескалацията на заключване. Ако имате разделена таблица, тогава можем да настроим ескалацията до нивото на дял.

В тази стъпка ще изпълним заявка, която създава заключване в таблицата на AdventureWorks HumanResources. Тази таблица има клъстерирани и неклъстерирани индекси.

BEGIN TRAN	
UPDATE 	  [HumanResources].[Department] SET Name='NewName' where DepartmentID=1

Както можете да видите в долния панел с резултати, нашата транзакция придобива изключителни заключвания в индексния ключ на клъстера PK_Department_DepartmentID и също така придобива изключителни заключвания в неклъстерния индексен ключ AK_Department_Name. Сега можем да зададем този въпрос „Защо SQL Server заключва неклъстериран индекс?“

Името колоната е индексирана в неклъстерния индекс AK_Department_Name и ние се опитваме да променим Име колона. В този случай SQL Server трябва да промени всички неклъстерирани индекси в тази колона. Нивото на неклъстерирания индекс включва всяка подредена стойност на KEY.

Заключения

В тази статия споменахме основните линии на механизма за заключване на SQL Server и разгледахме използването на sys.dm_tran_locks. Изгледът sys.dm_tran_locks връща много информация за активните в момента ресурси за заключване. Ако потърсите в Google, можете да намерите много примерни заявки за този изглед.

Препратки

Ръководство за заключване на транзакции на SQL Server и версия на редове

SQL Server, Заключва обект


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Срокове за събиране на аларми от Spotlight Cloud

  2. Разделяне на стойности, разделени със запетая, в колони на множество редове в Sql Server

  3. Експортиране на таблица от база данни в csv файл

  4. Как да конвертирате стойност на дата/час в низ в SQL Server с помощта на CONVERT()

  5. Ефективност на условно агрегиране