Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

SQL Server Lock Escalation

Giới thiệu

Cơ sở dữ liệu quan hệ tuân theo các thuộc tính ACID trong cách chúng thực hiện các giao dịch - Tính nguyên tử, Tính nhất quán, Tính cô lập và Độ bền. Cô lập là cần thiết để đảm bảo rằng nhiều giao dịch không thể gây ra thay đổi đối với dữ liệu và khiến kết quả cuối cùng không nhất quán. Để đảm bảo rằng các hoạt động vẫn bị cô lập, SQL Server áp dụng cơ chế Khóa.

Chế độ khóa và cấu trúc phân cấp

Cơ chế của SQL Server để kiểm soát đồng thời có liên quan. Để tối ưu hóa hiệu suất về thời gian chờ khóa, bế tắc và những thứ tương tự, bạn phải đưa ra quyết định dựa trên tình huống cụ thể.

Trong SQL Server, các khóa có thể được tổ chức theo nhiều cách khác nhau và ở một số cấp độ chi tiết. Chế độ Khóa là những cách cụ thể để thực hiện và cấp độ của chúng là Hệ thống phân cấp khóa.

Hình 1 cho thấy các Chế độ khóa có sẵn trong SQL Server cho mức Cách ly Giao dịch mặc định (ĐỌC CAM KẾT):

Tổng quan về Khóa nâng cấp

SQL Server có thể khóa tài nguyên ở một số cấp độ. Nó phụ thuộc vào các hành vi hiệu quả nhất theo bản chất của khối lượng công việc. Bảng 1 cho thấy các tài nguyên có thể bị khóa.

  • Các khóa ở cấp độ chi tiết hơn (ví dụ:khóa Cấp hàng) cho phép đồng thời cao hơn và ít chặn hơn.
  • Các khóa ở cấp độ cao hơn (ví dụ:Khóa cấp bảng) làm giảm tính đồng thời. Chúng có thể gây ra nhiều chặn hơn, tùy thuộc vào thời gian tồn tại của câu lệnh thực tế.

SQL Server chọn mức khóa cần thiết theo số liệu nội bộ.

Nâng cấp khóa xảy ra khi một khóa được chuyển đổi từ cấp độ chi tiết tốt hơn sang cấp độ thô hơn.

Ví dụ:chuyển đổi một khóa hàng thành một khóa bảng (Xem Bảng 1).

Resource Mô tả
RID Mã định danh hàng được sử dụng để khóa một hàng trong một đống.
KEY Khóa hàng trong một chỉ mục được sử dụng để bảo vệ các phạm vi khóa trong các giao dịch có thể tuần tự hóa.
TRANG Trang 8 kilobyte (KB) trong cơ sở dữ liệu, chẳng hạn như dữ liệu hoặc trang chỉ mục.
EXTENT Nhóm tám trang liền kề, chẳng hạn như dữ liệu hoặc trang chỉ mục.
HoBT heap hoặc B-tree. Khóa đang bảo vệ cây B (chỉ mục) hoặc các trang dữ liệu đống trong bảng không có chỉ mục được phân nhóm.
BẢNG Toàn bộ bảng, bao gồm tất cả dữ liệu và chỉ mục.
TẬP TIN Tệp cơ sở dữ liệu.
ỨNG DỤNG Tài nguyên do ứng dụng chỉ định.
METADATA Khóa siêu dữ liệu.
ALLOCATION_UNIT Đơn vị phân bổ.
CƠ SỞ DỮ LIỆU Toàn bộ cơ sở dữ liệu.

Cơ sở lý luận cho việc khóa leo thang

Các khóa trong SQL Server có thể khá tốn kém. Đối với mỗi khóa mà Trình quản lý khóa có được, SQL Server phải dự trữ bộ nhớ - 64 byte hoặc 128 byte. Số tiền phụ thuộc vào việc chúng ta đang xử lý hệ thống 32 bit hay 64 bit tương ứng.

Khi số lượng hàng khóa trên một bảng tăng lên, SQL Server ngày càng phải có nhiều bộ nhớ hơn. Do đó, các quy trình khác đang chết đói, hết bộ nhớ.

Nó có ý nghĩa khi chuyển đổi các khóa hàng và khóa trang thành một khóa cấp bảng (đối tượng) duy nhất. Điều này xảy ra khi số lượng khóa cho bảng đó vượt quá 5000.

Thỏa hiệp xảy ra khi toàn bộ bảng không còn khả dụng cho các phiên khác trong quá trình giao dịch.

Thể hiện Nâng cấp Khóa

Chúng tôi có thể chứng minh Lock Escalation bằng cách sử dụng mã trong Liệt kê 1.

Đầu tiên chúng ta hãy mô tả một chút về bảng này. Sản xuất. Sản phẩmI là một bảng tương đối nhỏ với khoảng 7777 hàng. Các phần tử của tòa nhà là cùng một tập hợp gồm 77 hàng được nhân đôi 101 lần. Mã trong Liệt kê 1 bao gồm ba phiên bản của cùng một câu lệnh cập nhật, mỗi phiên bản được đính kèm trong một giao dịch.

-- 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 

Để rõ ràng hơn, chúng tôi sẽ chia nhỏ nội dung của Liệt kê 1.

Trước đó, hãy quan sát Liệt kê 2 - một truy vấn để hiển thị các ổ khóa được giữ trong cơ sở dữ liệu TSQLV4.

Hành động đầu tiên của chúng tôi là thực thi Liệt kê 1a. Sau đó, chúng tôi sử dụng Liệt kê 2 để kiểm tra cách Trình quản lý khóa thực hiện khóa trong kịch bản. Chúng tôi thực thi Liệt kê 1a mà không đưa ra câu lệnh khôi phục. Bằng cách này, chúng tôi duy trì các khóa đủ lâu để truy vấn trong Liệt kê 2 có thể nắm bắt chúng.

-- 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';

Khi chúng tôi chạy truy vấn trong Liệt kê 1a, sau đó kiểm tra các khóa bằng cách sử dụng truy vấn trong Liệt kê 2, SQL Server trả về kết quả được hiển thị trong Hình 2.

404 hàng trong bảng có unitprice =’18 .00 ’ . Trình quản lý khóa khóa các hàng này cùng với các khóa khác ở bất kỳ cấp độ nào cần thiết. Nó đưa số hàng trong Hình 2 lên 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

Chúng tôi quan sát thấy hành vi tương tự khi chúng tôi thực hiện truy vấn trong Liệt kê 1b. Lần này, chúng tôi đang xử lý 4406 hàng. Nó phản ánh số hàng trên bảng Sản phẩm. Sản phẩm Tôi có đơn giá> 18,00.

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

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

ROLLBACK

Khi chúng ta đi xa hơn và thực thi mã trong Liệt kê 1c, chúng ta thấy một hành vi khác (xem Hình 4).

Liệt kê 1c cố gắng cập nhật tất cả 7777 hàng trong bảng Production.ProductI. SQL Server xác định rằng việc khóa quá nhiều hàng không còn hiệu quả để đảm bảo sự cô lập. Thay vào đó, toàn bộ bảng đã bị khóa.

Thông tin thêm về Khóa nâng cấp

Khóa bảng ngụ ý rằng không phiên nào khác có thể sửa đổi các hàng của nó trong thời lượng giao dịch, điều này có thể xảy ra ngay cả khi phiên chặn không thao tác tất cả các hàng trong bảng.

Cũng cần nhắc lại rằng các yếu tố khác có thể ảnh hưởng đến cách các khóa được thu thập và nâng cấp trong SQL Server. Đó là các cờ mức cô lập được định cấu hình, lập chỉ mục và theo dõi.

Cờ theo dõi T1211 và T1224 có thể được áp dụng để vô hiệu hóa hoàn toàn Lock Escalation. Khóa Escalation cũng có thể bị vô hiệu hóa và được bật cho một bảng cụ thể bằng mã sau:

-- Listing 5: Disable and Enable Lock Escalation

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

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

Người ta có thể muốn làm điều đó để giảm chặn liên quan đến việc khóa toàn bộ bảng. Vì ảnh hưởng đến trí nhớ, nên xem xét nó trên một biện pháp tạm thời.

Kết luận

SQL Server sử dụng Lock Escalation để kiểm soát tác động của việc khóa chi tiết hơn đối với tài nguyên máy chủ. Để hiển thị cách xuất hiện của các khóa này - khóa hàng, khóa trang, khóa đối tượng, v.v. - hãy truy vấn chế độ xem quản lý động sys.dm_tran_locks. Nó cung cấp rất nhiều thông tin về khóa, bên cạnh Lock Escalation.

Mặc dù có thể điều khiển hành vi của Trình quản lý khóa, nhưng điều cần thiết là phải thực hiện nó một cách cẩn thận. Điều quan trọng nữa là phải biết tác động hiệu suất chính xác của bất kỳ nỗ lực nào nhằm vào việc thực hiện các sửa đổi như vậy.

Tài liệu tham khảo

  1. Korotkevitch, D., 2016. Pro SQL Server Internals. Florida:Dmitri Korotkevitch
  2. Các tình huống khóa bằng Sys.dm_tran_locks
  3. Hướng dẫn tạo phiên bản hàng và khóa giao dịch


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. @@ DATEFIRST - Ngày đầu tiên trong tuần trong SQL Server

  2. Chạy tất cả các tệp SQL trong một thư mục

  3. Tại sao truy vấn T-SQL thứ 2 chạy nhanh hơn nhiều so với truy vấn đầu tiên khi được gọi bởi Reporting Services 2005 trong một ứng dụng web

  4. Sửa lỗi Msg 512 “Truy vấn con trả về nhiều hơn 1 giá trị” trong SQL Server

  5. Chọn dữ liệu từ hai máy chủ khác nhau trong SQL Server