Để kết thúc loạt bài viết ngắn của tôi về chốt, lần này tôi sẽ thảo luận về một số chốt khác trong SQL Server mà bạn có thể thỉnh thoảng thấy nhưng không xứng đáng với một bài viết hoàn chỉnh. Như thường lệ, tôi thực sự khuyên bạn nên đọc bài đầu tiên trong loạt bài trước bài này, để bạn có tất cả kiến thức nền tảng chung về chốt.
Chốt LOG_MANAGER
Chốt LOG_MANAGER được sử dụng để đồng bộ hóa trong một số hoạt động liên quan đến nhật ký giao dịch và có một chốt LOG_MANAGER cho mỗi cơ sở dữ liệu (vì mỗi cơ sở dữ liệu có trình quản lý nhật ký riêng). Nó chỉ có thể được mua ở chế độ độc quyền và có thể là một nút thắt cổ chai trong quá trình phát triển tệp nhật ký giao dịch. Tình huống mà nó sẽ trở nên hiển nhiên khi có vấn đề là:
- Tệp nhật ký có một tập hợp tự động phát triển nhỏ
- Có nhiều kết nối đồng thời tạo ra các bản ghi nhật ký giao dịch
- Tệp nhật ký tiếp tục phải phát triển
Khi tệp nhật ký hết dung lượng, nó sẽ cần phải phát triển. Luồng đầu tiên để nhận ra nhiều không gian nhật ký hơn là bắt buộc phải có chốt LOG_MANAGER ở chế độ EX và tiến hành phát triển tệp nhật ký. Nhiều luồng khác tiếp tục cố gắng tạo bản ghi nhật ký và đưa vào hàng đợi cho chốt LOG_MANAGER, để chúng có thể phát triển tệp nhật ký. Khi luồng đầu tiên giải phóng chốt, luồng tiếp theo nhận được nó và nhận ra nhật ký đã phát triển, vì vậy hãy thả nó xuống và tiếp tục. Và vân vân. Ngẫu nhiên, mô hình nút cổ chai này được gọi là đoàn xe chốt .
Bạn có thể nghĩ nó giống hệt như nút cổ chai như với chốt FGCB_ADD_REMOVE mà tôi đã thảo luận trước đó trong loạt bài, nhưng với sự tăng trưởng tệp nhật ký thay vì tăng trưởng tệp dữ liệu. Tuy nhiên, với chốt FGCB_ADD_REMOVE, thường phiên bản đã bật khởi tạo tệp tức thì, do đó tốc độ tăng tệp rất nhanh, nhưng với chốt LOG_MANAGER, nhật ký * phải * không được khởi tạo và thời gian lãng phí trong hàng đợi chốt lâu hơn .
Giải pháp cho nút thắt cổ chai này có ba phần:
- Đặt tự động phát triển của tệp nhật ký một cách chính xác, do đó, nhật ký không phát triển thường xuyên
- Định kích thước nhật ký chính xác cho khối lượng công việc, vì vậy nhật ký sẽ không phát triển chút nào
- Đảm bảo rằng nhật ký được xóa chính xác, do đó, nhật ký không cần phải phát triển
Nếu tất cả những điều này đều đúng chỗ, bạn sẽ không thấy chốt LOG_MANAGER là một nút thắt cổ chai thường xuyên và tôi sẽ nói thêm về điều này trong bài đăng của mình tại đây.
Chốt ACCESS_METHODS_DATASET_PARENT
Khi một heap hoặc một chỉ mục đang được truy cập, bên trong có một đối tượng được gọi là HeapDataSetSession hoặc IndexDataSetSession, tương ứng. Khi quá trình quét song song đang được thực hiện, các luồng thực hiện công việc thực sự của quá trình quét đều có một tập dữ liệu “con” (một phiên bản khác của hai đối tượng mà tôi vừa mô tả) và tập dữ liệu chính, thực sự kiểm soát quá trình quét, được gọi là "cha mẹ".
Khi một trong các chuỗi của nhân viên quét đã sử dụng hết tập hợp các hàng mà nó phải quét, nó cần có một phạm vi mới bằng cách truy cập vào tập dữ liệu mẹ, có nghĩa là có được chốt ACCESS_METHODS_DATASET_PARENT ở chế độ độc quyền. Mặc dù điều này có vẻ như là một nút thắt cổ chai nhưng thực ra không phải vậy và bạn không thể làm gì để ngăn các chuỗi thực hiện quét song song thỉnh thoảng hiển thị LATCH_EX chờ chốt này.
Câu hỏi bạn nên tự hỏi mình là:truy vấn này có nên thực hiện quét song song ngay từ đầu không? Hoàn toàn có thể có điều gì đó đã xảy ra buộc kế hoạch truy vấn bao gồm quét song song khi đó có thể không phải là cách hiệu quả nhất để truy vấn chạy. Ví dụ về những điều có thể khiến kế hoạch thay đổi thành quét song song bao gồm:
- Số liệu thống kê lỗi thời
- Một chỉ mục không hợp nhất bị thiếu hoặc bị giảm
- Mã mới buộc phải quét vì chuyển đổi ngầm định — kiểu dữ liệu không khớp giữa cột và biến / tham số, điều này ngăn cản việc sử dụng chỉ mục không phân biệt
- Mã mới buộc phải quét vì số học đang được thực hiện trên một cột của bảng thay vì một biến / tham số, điều này lại ngăn cản việc sử dụng chỉ mục không phân biệt
- Tăng trưởng dữ liệu đang diễn ra và quá trình quét thực sự là kế hoạch hiệu quả nhất
Hoặc có thể truy vấn này yêu cầu quét, trong trường hợp đó, LATCH_EX chờ ACCESS_METHODS_DATASET_PARENT chỉ là một phần trong môi trường của bạn.
Chốt ACCESS_METHODS_HOBT_VIRTUAL_ROOT
Mỗi phiên bản của chốt này bảo vệ một mục nhập trong siêu dữ liệu của Storage Engine cho cây b, cụ thể là ID trang của trang gốc của cây b (trang ở trên cùng của hình tam giác mà chúng ta thường coi là một chỉ mục) . Tôi đang nói cụ thể là b-tree và không phải chỉ mục , vì một chỉ mục có thể có nhiều phân vùng, mỗi phân vùng có một cây b (về cơ bản là một phần của chỉ mục tổng thể, nhưng với các ràng buộc khóa giá trị thấp và giá trị cao).
Mỗi khi một luồng cần đi ngang qua cây b, nó phải bắt đầu ở trang gốc và hoạt động theo cách của nó xuống mức lá. Để đọc siêu dữ liệu có chứa ID trang của trang gốc, chuỗi phải có được chốt ACCESS_METHODS_HOBT_VIRTUAL_ROOT ở chế độ SH mode, để đảm bảo rằng ID trang không đang trong quá trình thay đổi. Khi một luồng cần thay đổi ID trang của trang gốc, nó phải có chốt ở chế độ EX.
Tại sao trang gốc của cây b luôn thay đổi? Khi số lượng bản ghi chỉ mục trong trang gốc tăng lên, cuối cùng nó sẽ đầy và hiện tượng tách trang sẽ xảy ra. Khi điều đó xảy ra, trang gốc hiện tại và trang mà nó tách ra trở thành một cấp mới trong b-tree, và một trang gốc hoàn toàn mới được tạo, với hai bản ghi chỉ mục, trỏ vào trang gốc cũ và trang đó. chia thành. ID trang gốc mới phải được nhập vào siêu dữ liệu, do đó, chốt được lấy ở chế độ EX. Điều này sẽ xảy ra nhanh chóng một vài lần khi một chỉ mục trên một bảng trống bắt đầu được điền bởi các lần chèn nhưng không phải là điều bạn sẽ thấy như một vấn đề tắc nghẽn hiệu suất đang diễn ra.
Tóm tắt
Như tôi chắc chắn bạn đã thu thập được từ loạt bài này, việc hiểu các chốt và nút thắt cổ chai liên quan đến việc biết nhiều hơn một chút về những gì đang diễn ra bên trong Công cụ lưu trữ hơn là phân tích thống kê chờ chung.
Tôi thường khuyên mọi người * không * bắt đầu khắc phục sự cố hiệu suất bằng cách xem số liệu thống kê chốt (thông qua sys.dm_os_latch_stats ) nhưng thay vào đó, luôn bắt đầu với số liệu thống kê chờ (xem bài đăng của tôi tại đây) và chỉ đi sâu vào các chốt nếu LATCH_EX hoặc LATCH_SH là một trong số ít các lần chờ hàng đầu trên phiên bản SQL Server.
Nếu bạn có bất kỳ câu hỏi nào về chốt, vui lòng gửi cho tôi một dòng.