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

Chốt FGCB_ADD_REMOVE

Trong bài viết trước, tôi đã bắt đầu một loạt bài mới về chốt bằng cách giải thích chúng là gì, tại sao chúng cần thiết và cơ chế hoạt động của chúng và tôi thực sự khuyên bạn nên đọc bài viết đó trước bài viết này. Trong bài viết này, tôi sẽ thảo luận về chốt FGCB_ADD_REMOVE và chỉ ra cách nó có thể là một nút thắt cổ chai.

FGCB_ADD_REMOVE Latch là gì?

Hầu hết các tên lớp chốt được gắn trực tiếp với cấu trúc dữ liệu mà chúng bảo vệ. Chốt FGCB_ADD_REMOVE bảo vệ cấu trúc dữ liệu được gọi là FGCB, hoặc Khối điều khiển nhóm tệp và sẽ có một trong các chốt này cho mỗi nhóm tệp trực tuyến của mỗi cơ sở dữ liệu trực tuyến trong phiên bản SQL Server. Bất cứ khi nào một tệp trong nhóm tệp được thêm, bỏ, phát triển hoặc thu nhỏ, chốt phải được lấy ở chế độ EX và khi tìm ra tệp tiếp theo để cấp phát, chốt phải được lấy ở chế độ SH để ngăn chặn bất kỳ thay đổi nào của nhóm tệp. (Hãy nhớ rằng phân bổ phạm vi cho một nhóm tệp được thực hiện trên cơ sở lặp lại thông qua các tệp trong nhóm tệp và cũng tính đến lấp đầy theo tỷ lệ , mà tôi giải thích ở đây.)

Làm thế nào để chốt trở thành nút cổ chai?

Tình huống phổ biến nhất khi chốt này trở thành nút cổ chai như sau:

  • Có một cơ sở dữ liệu một tệp, vì vậy tất cả các phân bổ phải đến từ một tệp dữ liệu đó
  • Cài đặt tự động duyệt cho tệp được đặt thành rất nhỏ (hãy nhớ rằng trước SQL Server 2016, cài đặt tự động duyệt mặc định cho tệp dữ liệu là 1MB!)
  • Có nhiều hoạt động đồng thời yêu cầu không gian được cấp phát (ví dụ:khối lượng công việc chèn liên tục từ nhiều kết nối máy khách)

Trong trường hợp này, mặc dù chỉ có một tệp, một chuỗi yêu cầu phân bổ vẫn phải có chốt FGCB_ADD_REMOVE trong chế độ SH mode. Sau đó, nó sẽ cố gắng phân bổ từ một tệp dữ liệu duy nhất, nhận ra không có không gian và sau đó có được chốt ở chế độ EX để sau đó nó có thể phát triển tệp.

Hãy tưởng tượng rằng tám luồng chạy trên tám bộ lập lịch riêng biệt đều cố gắng phân bổ cùng một lúc và tất cả đều nhận ra rằng không có dung lượng trong tệp nên họ cần phải phát triển nó. Họ sẽ cố gắng lấy chốt ở chế độ EX. Chỉ một trong số họ có thể lấy được nó và nó sẽ tiến hành phát triển tệp còn những người khác sẽ phải đợi, với kiểu chờ LATCH_EX và mô tả tài nguyên của FGCB_ADD_REMOVE cộng với địa chỉ bộ nhớ của chốt.

Bảy luồng chờ nằm ​​trong hàng đợi xuất trước (FIFO) của chốt. Khi luồng thực hiện quá trình tăng trưởng tệp hoàn tất, nó sẽ giải phóng chốt và cấp nó cho luồng chờ đầu tiên. Chủ sở hữu mới của chốt này đi để phát triển tệp và phát hiện ra rằng tệp đã được phát triển và không phải làm gì cả. Vì vậy, nó nhả chốt và cấp nó cho luồng chờ tiếp theo. Và như vậy.

Tất cả bảy luồng chờ đợi đều đợi chốt ở chế độ EX nhưng cuối cùng không làm gì khi chúng được cấp chốt, vì vậy cả bảy luồng về cơ bản lãng phí thời gian đã trôi qua, với lượng thời gian bị lãng phí tăng lên một chút cho mỗi luồng càng xuống sâu hàng đợi FIFO chính là nó.

Hiển thị nút cổ chai

Bây giờ tôi sẽ cho bạn thấy kịch bản chính xác ở trên, sử dụng các sự kiện mở rộng. Tôi đã tạo cơ sở dữ liệu một tệp với cài đặt tự động duyệt nhỏ và hàng trăm kết nối đồng thời chỉ cần chèn dữ liệu vào bảng.

Tôi có thể sử dụng phiên sự kiện mở rộng sau để xem điều gì đang diễn ra:

  -- Drop the session if it exists. 
IF EXISTS 
(
  SELECT * FROM sys.server_event_sessions
    WHERE [name] = N'FGCB_ADDREMOVE'
)
BEGIN
  DROP EVENT SESSION [FGCB_ADDREMOVE] ON SERVER;
END
GO
 
CREATE EVENT SESSION [FGCB_ADDREMOVE] ON SERVER
  ADD EVENT [sqlserver].[database_file_size_change]
  	(WHERE [file_type] = 0), -- data files only
  ADD EVENT [sqlserver].[latch_suspend_begin]
  	(WHERE [class] = 48 AND [mode] = 4),  -- EX mode
  ADD EVENT [sqlserver].[latch_suspend_end]
  	(WHERE [class] = 48 AND [mode] = 4) -- EX mode
  ADD TARGET [package0].[ring_buffer]
  WITH (TRACK_CAUSALITY = ON);
GO
 
-- Start the event session
ALTER EVENT SESSION [FGCB_ADDREMOVE]
  ON SERVER STATE = START;
GO

Phiên đang theo dõi khi một luồng đi vào hàng đợi của chốt, khi nào nó rời khỏi hàng (tức là khi nó được cấp chốt) và khi xảy ra tăng trưởng tệp dữ liệu. Sử dụng theo dõi quan hệ nhân quả có nghĩa là chúng ta có thể thấy tiến trình của các hành động theo từng chuỗi.

Sử dụng SQL Server Management Studio, tôi có thể chọn tùy chọn Xem dữ liệu trực tiếp cho phiên sự kiện mở rộng và xem tất cả hoạt động sự kiện mở rộng. Nếu bạn muốn làm điều tương tự, trong cửa sổ Dữ liệu Trực tiếp, hãy nhấp chuột phải vào một trong các tên cột ở trên cùng và thay đổi các cột đã chọn thành như bên dưới:

Tôi để khối lượng công việc chạy trong vài phút để đạt trạng thái ổn định và sau đó thấy một ví dụ hoàn hảo về tình huống mà tôi đã mô tả ở trên:

Sử dụng Attach_activity_id.guid để xác định các chủ đề khác nhau, chúng ta có thể thấy rằng bảy chủ đề bắt đầu chờ chốt trong vòng 61,5 micro giây. Chuỗi có giá trị GUID bắt đầu từ 8D57 có được chốt ở chế độ EX ( latch_suspend_end sự kiện) và sau đó phát triển tệp ngay lập tức ( database_file_size_change Sự kiện). Sau đó, luồng 8D57 nhả chốt và cấp nó ở chế độ EX cho luồng 6F82, chờ 85 mili giây. Nó không có gì để làm vì vậy nó cấp chốt cho luồng 672B. Và cứ tiếp tục như vậy, cho đến khi luồng EDB8 được cấp chốt, sau khi đợi 202 mili giây.

Tổng cộng, sáu luồng không chờ đợi lý do đã đợi gần 1 giây. Một phần thời gian đó là thời gian chờ tín hiệu, trong đó mặc dù luồng đã được cấp chốt, nó vẫn cần di chuyển lên đầu hàng đợi có thể chạy của bộ lập lịch trước khi có thể truy cập vào bộ xử lý và thực thi mã. Bạn có thể nói rằng đây không phải là một thước đo công bằng về thời gian dành cho việc chờ chốt, nhưng hoàn toàn là vậy, bởi vì thời gian chờ tín hiệu sẽ không phát sinh nếu luồng không phải đợi ngay từ đầu.

Hơn nữa, bạn có thể nghĩ rằng độ trễ 200 mili giây không phải là nhiều, nhưng tất cả phụ thuộc vào các thỏa thuận cấp dịch vụ hiệu suất cho khối lượng công việc được đề cập. Chúng tôi có nhiều khách hàng khối lượng lớn trong đó nếu một lô mất hơn 200 mili giây để thực thi thì điều đó không được phép trên hệ thống sản xuất!

Tóm tắt

Nếu bạn đang theo dõi các lượt chờ trên máy chủ của mình và nhận thấy LATCH_EX là một trong những lượt chờ hàng đầu, bạn có thể sử dụng mã trong bài đăng này để xem liệu FGCB_ADD_REMOVE có phải là một trong những thủ phạm hay không.

Cách dễ nhất để đảm bảo rằng khối lượng công việc của bạn không gặp phải nút thắt cổ chai FGCB_ADD_REMOVE là đảm bảo rằng không có cài đặt tự động duyệt tệp dữ liệu nào được định cấu hình bằng mặc định trước SQL Server 2016. Trong sys.master_files xem, mặc định 1MB sẽ hiển thị dưới dạng tệp dữ liệu ( type_desc được đặt thành ROWS) với is_percent_growth cột được đặt thành 0 và cột tăng trưởng được đặt thành 128.

Việc đưa ra khuyến nghị về chế độ tự động duyệt sẽ là một cuộc thảo luận hoàn toàn khác, nhưng bây giờ bạn đã biết về tác động tiềm năng về hiệu suất từ ​​việc không thay đổi giá trị mặc định trong các phiên bản trước đó.


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

  2. SQL GIỮA-Các mẹo thông minh để quét tìm một loạt các giá trị

  3. Tạo dữ liệu tổng hợp

  4. Giảm thiểu tác động của việc mở rộng cột IDENTITY - phần 4

  5. Phân tích khối lượng công việc SQL có thể giúp bạn như thế nào?