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

Thống kê chờ Knee-Jerk:SOS_SCHEDULER_YIELD

Trong bài viết trước của tôi, tôi đã thảo luận về LCK_M_XX, ASYNC_NETWORK_IO, và OLEDB chờ đợi và phản ứng đầu gối với chúng. Trong bài đăng này, tôi sẽ tiếp tục với chủ đề thống kê chờ và thảo luận về sự chờ đợi của SOS_SCHEDULER_YIELD.

Khi SOS_SCHEDULER_YIELD phổ biến nhất trên máy chủ, chúng ta thường thấy mức sử dụng CPU cao và bền vững. Phản ứng giật gân ở đây là máy chủ phải chịu áp lực của CPU hoặc spinlock là vấn đề.

Chúng tôi cần một chút kiến ​​thức nền ở đây để hiểu hai phản ứng này.

Lập lịch chuỗi

Lập lịch luồng trong SQL Server được quản lý bởi chính SQL Server, không phải bởi Windows (tức là nó không được ưu tiên). Phần SQL OS của Storage Engine cung cấp chức năng lập lịch và luồng chuyển đổi từ chạy trên Bộ xử lý (trong đó trạng thái luồng là RUNNING) sang nằm trong Danh sách người chờ đợi cho đến khi có sẵn tài nguyên (trạng thái là TẠM NGỪNG) sang có thể chạy được Hàng đợi khi tài nguyên trở nên khả dụng (trạng thái là RUNNABLE) đang đợi để lên đầu hàng đợi và quay lại Bộ xử lý một lần nữa (trở lại trạng thái đang CHẠY). Tôi đã viết hoa Bộ xử lý, Danh sách người chờ và Hàng đợi có thể chạy được để xác định chúng là các phần của bộ lập lịch.

Bất cứ khi nào một chuỗi cần một tài nguyên mà nó không thể có được ngay lập tức, nó sẽ bị tạm ngưng và chờ trên Danh sách người chờ để được thông báo (báo hiệu) rằng tài nguyên của nó có sẵn. Thời gian dành cho Danh sách Người chờ đợi là thời gian chờ tài nguyên và thời gian dành cho Hàng đợi Chạy được là thời gian chờ tín hiệu. Chúng kết hợp với nhau để trở thành thời gian chờ tổng thể. Hệ điều hành SQL theo dõi thời gian chờ và thời gian chờ tín hiệu, vì vậy chúng tôi phải thực hiện một số phép toán trên đầu ra từ sys.dm_os_wait_stats để tính thời gian chờ tài nguyên (xem tập lệnh của tôi tại đây).

Danh sách Người chờ đợi không có thứ tự (bất kỳ chuỗi nào trên đó có thể được báo hiệu bất kỳ lúc nào và chuyển đến Hàng đợi Chạy được) và Hàng đợi Chạy được là Đầu tiên - Vào trước - Xuất ra (FIFO) gần như 100% thời gian. Ngoại lệ duy nhất đối với Hàng đợi Runnable là FIFO là nơi nhiều nhóm khối lượng công việc Resource Governor đã được định cấu hình trong cùng một nhóm tài nguyên và chúng có các mức độ ưu tiên khác nhau liên quan đến nhau. Tôi chưa bao giờ thấy điều này được sử dụng thành công trong quá trình sản xuất nên tôi sẽ không thảo luận thêm.

Có một lý do khác tại sao một luồng có thể cần phải di chuyển khỏi Bộ xử lý - nó làm cạn kiệt lượng tử của nó. Lượng tử luồng trong SQL OS được cố định ở 4 mili giây. Bản thân luồng chịu trách nhiệm xác định rằng lượng tử của nó đã hết (bằng cách gọi các quy trình của trình trợ giúp trong SQL OS) và tự nguyện từ bỏ bộ xử lý (được gọi là năng suất). Khi điều này xảy ra, luồng sẽ di chuyển trực tiếp đến cuối Hàng đợi Runnable, vì không có gì để nó chờ. Tuy nhiên, hệ điều hành SQL phải đăng ký kiểu chờ cho quá trình chuyển đổi này khỏi Bộ xử lý và đăng ký SOS_SCHEDULER_YIELD.

Hành vi này thường bị nhầm với áp suất CPU, nhưng không phải vậy - nó chỉ là việc sử dụng CPU liên tục. Áp lực CPU, và nhận biết nó, là một chủ đề hoàn toàn khác cho một bài viết trong tương lai. Theo như bài đăng này có liên quan, miễn là thời gian chờ tín hiệu trung bình thấp (0-0,1-0,2 mili giây), đặt cược khá an toàn rằng áp suất CPU không phải là vấn đề.

Spinlocks

Một spinlock là một nguyên thủy đồng bộ hóa mức rất thấp được sử dụng để cung cấp quyền truy cập an toàn theo luồng vào các cấu trúc dữ liệu trong SQL Server cực kỳ nóng (rất dễ bay hơi và được nhiều luồng truy cập và thay đổi thường xuyên đến mức khó tin). Ví dụ về cấu trúc như vậy là danh sách không có bộ đệm trong mỗi phần của vùng đệm và mảng trọng số điền theo tỷ lệ cho các tệp dữ liệu trong một nhóm tệp.

Khi một luồng cần có được một spinlock, nó sẽ xem liệu spinlock đó có rảnh không và nếu có thì ngay lập tức có được nó (sử dụng một ngôn ngữ hợp ngữ nguyên thủy được lồng vào nhau như ‘test bit clear and set’). Nếu không thể lấy được spinlock, chuỗi ngay lập tức cố gắng lấy lại nó, lặp đi lặp lại, lên đến hàng nghìn lần lặp, cho đến khi nó tắt (ngủ một chút). Điều này không đăng ký dưới dạng bất kỳ kiểu chờ nào, vì luồng chỉ đơn giản gọi hàm Windows sleep (), nhưng có thể làm cho các luồng khác đang chờ có thời gian chờ tín hiệu lớn (10-20ms +) vì luồng ngủ vẫn ở trên bộ xử lý cho đến khi nó lấy spinlock.

Tại sao tôi lại nói về spinlock? Bởi vì chúng cũng có thể là nguyên nhân gây ra việc sử dụng CPU cao và có một quan niệm sai lầm rằng spinlock là nguyên nhân gây ra các lần chờ SOS_SCHEDULER_YIELD. Họ không.

SOS_SCHEDULER_YIELD Nguyên nhân

Vì vậy, có một nguyên nhân dẫn đến SOS_SCHEDULER_YIELD:một luồng sử dụng hết lượng tử lập lịch của nó và các trường hợp lặp lại nhiều lần có thể dẫn đến SOS_SCHEDULER_YIELD là lượt chờ phổ biến nhất cùng với mức sử dụng CPU cao.

Bạn sẽ không thấy các lượt chờ SOS_SCHEDULER_YIELD hiển thị trong đầu ra từ sys.dm_os_waiting_tasks, vì chuỗi không chờ đợi. Bạn có thể xem truy vấn nào đang tạo ra SOS_SCHEDULER_YIELD chờ bằng cách truy vấn sys.dm_exec_requests và lọc trên cột last_wait_type.

Điều này cũng có nghĩa là khi bạn nhìn thấy SOS_SCHEDULER_YIELD trong đầu ra của sys.dm_os_wait_stats, thời gian chờ tài nguyên sẽ bằng 0, vì nó không thực sự đợi. Nhưng hãy nhớ rằng mỗi 'lần chờ' này tương đương với 4 mili thời gian CPU được tích lũy cho truy vấn.

Cách duy nhất để chứng minh điều gì gây ra SOS_SCHEDULER_YIELD chờ đợi là nắm bắt các ngăn xếp cuộc gọi SQL Server khi kiểu chờ đó xảy ra, sử dụng Sự kiện mở rộng và ký hiệu gỡ lỗi từ Microsoft. Tôi có một bài đăng trên blog mô tả và chỉ ra cách thực hiện cuộc điều tra đó và có một sách trắng tuyệt vời về spinlock và điều tra spinlock rất đáng đọc nếu bạn quan tâm đến nội dung chuyên sâu đó.

Đối với trường hợp cạn kiệt lượng tử, đó không phải là nguyên nhân gốc rễ. Đó là một triệu chứng khác. Bây giờ chúng ta cần xem xét lý do tại sao một luồng có thể liên tục cạn kiệt lượng tử của nó.

Một luồng chỉ có thể cạn kiệt lượng tử của nó khi nó có thể tiếp tục xử lý mã SQL Server trong 4ms mà không cần tài nguyên mà một luồng khác sở hữu - không phải chờ khóa, chốt trang, trang tệp dữ liệu được đọc từ đĩa, phân bổ bộ nhớ, tăng trưởng tệp, ghi nhật ký hoặc vô số tài nguyên khác mà một chuỗi có thể cần.

Đoạn mã phổ biến nhất mà ở đó lượng tử cạn kiệt có thể xảy ra và chứa một lượng lớn SOS_SCHEDULER_YIELD chờ đợi là quét một chỉ mục / bảng trong đó tất cả các trang tệp dữ liệu cần thiết đều nằm trong bộ nhớ và không có tranh chấp để truy cập vào các trang đó và vì vậy đó là điều Tôi khuyến khích bạn tìm kiếm các kế hoạch truy vấn khi bạn thấy SOS_SCHEDULER_YIELD là loại chờ đợi hàng đầu - quét chỉ mục / bảng lớn và / hoặc lặp lại.

Điều này không có nghĩa là tôi nói rằng quá trình quét lớn là không tốt, vì có thể cách hiệu quả nhất để xử lý khối lượng công việc của bạn là thông qua quá trình quét. Tuy nhiên, nếu các lần chờ SOS_SCHEDULER_YIELD là mới và không bình thường và do quá trình quét lớn gây ra, bạn nên điều tra lý do tại sao các kế hoạch truy vấn đang sử dụng các lần quét. Có thể ai đó đã đánh rơi một chỉ mục không hợp lệ quan trọng hoặc thống kê đã lỗi thời và do đó, một kế hoạch truy vấn không chính xác đã được chọn hoặc có thể một giá trị tham số bất thường đã được chuyển cho một quy trình được lưu trữ và kế hoạch truy vấn được yêu cầu quét hoặc thay đổi mã đã xảy ra mà không hỗ trợ bổ sung chỉ mục.

Tóm tắt

Cũng giống như các kiểu chờ khác, hiểu chính xác ý nghĩa của SOS_SCHEDULER_YIELD là chìa khóa để hiểu cách khắc phục sự cố và liệu hành vi có được mong đợi do khối lượng công việc đang được xử lý hay không.

Về số liệu thống kê chờ chung có liên quan, bạn có thể tìm thêm thông tin về việc sử dụng chúng để khắc phục sự cố hiệu suất trong:

  • Loạt bài đăng trên blog SQLskills của tôi, bắt đầu với số liệu thống kê Chờ hoặc vui lòng cho tôi biết mức độ ảnh hưởng của nó
  • Thư viện Các loại Chờ đợi và Lớp Chốt của tôi tại đây
  • Khóa học đào tạo trực tuyến Pluralsight của tôi SQL Server:Khắc phục sự cố về hiệu suất sử dụng thống kê chờ
  • Cố vấn Hiệu suất SQL Sentry

Trong phần tiếp theo của loạt bài này, tôi sẽ thảo luận về một kiểu chờ đợi khác là nguyên nhân phổ biến của phản ứng giật đầu gối. Cho đến lúc đó, chúc bạn khắc phục sự 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. Cách đọc và diễn giải lỗi SQL

  2. Mô hình dữ liệu

  3. Tầm quan trọng của việc chọn kích thước máy ảo Azure thích hợp

  4. Toán tử SQL VÀ cho người mới bắt đầu

  5. Bảng thứ nguyên:Xem xét các loại bảng kích thước phổ biến nhất của Kho dữ liệu