مثالهای عملی و قابل اجرا
مثال 1: فهرست Schedulerهای قابل مشاهده و آنلاین
در نخستین بررسی باید Schedulerهای مربوط به درخواستهای عادی کاربر از Schedulerهای مخفی جدا شوند. این کوئری فقط ردیفهای VISIBLE ONLINE را برمیگرداند و وضعیت صف اجرا، Workerهای فعال و کارهای منتظر Worker را در همان لحظه نشان میدهد.
SELECT scheduler_id, cpu_id, parent_node_id, status,
runnable_tasks_count, active_workers_count, work_queue_count
FROM sys.dm_os_schedulers
WHERE status = N'VISIBLE ONLINE'
ORDER BY scheduler_id;
| خروجی نمونه | مقدار نمایشی | برداشت سریع |
|---|
| مثال 1 | Scheduler 2؛ runnable=0؛ work queue=0 | در نمونه، Scheduler دوم صف CPU یا کمبود Worker ندارد. عدد صفر در یک Snapshot کافی نیست؛ همین خروجی باید در چند نوبت و هنگام کندی واقعی جمعآوری شود. |
در نمونه، Scheduler دوم صف CPU یا کمبود Worker ندارد. عدد صفر در یک Snapshot کافی نیست؛ همین خروجی باید در چند نوبت و هنگام کندی واقعی جمعآوری شود.
مثال 2: شناسایی فشار پایدار CPU
وقتی runnable_tasks_count در چند نمونه متوالی بزرگتر از صفر باشد، Workerهایی آماده اجرا هستند اما نوبت CPU نگرفتهاند. فیلتر زیر Schedulerهای دارای صف Runnable را مشخص میکند تا بررسی پلنهای پرمصرف و انتظارهای مرتبط هدفمند شود.
SELECT scheduler_id, cpu_id, runnable_tasks_count,
current_tasks_count, total_cpu_usage_ms
FROM sys.dm_os_schedulers
WHERE status = N'VISIBLE ONLINE'
AND runnable_tasks_count > 0
ORDER BY runnable_tasks_count DESC;
| خروجی نمونه | مقدار نمایشی | برداشت سریع |
|---|
| مثال 2 | Scheduler 5؛ runnable=4؛ current tasks=19 | وجود چهار کار Runnable یک علامت لحظهای است، نه حکم قطعی کمبود CPU. اگر مقدار در نمونههای پیاپی حفظ شود و مصرف CPU سیستم نیز بالا باشد، فرضیه فشار پردازنده تقویت میشود. |
وجود چهار کار Runnable یک علامت لحظهای است، نه حکم قطعی کمبود CPU. اگر مقدار در نمونههای پیاپی حفظ شود و مصرف CPU سیستم نیز بالا باشد، فرضیه فشار پردازنده تقویت میشود.
مثال 3: تشخیص انتظار برای Worker
work_queue_count تعداد Taskهایی را نشان میدهد که هنوز Worker دریافت نکردهاند. این وضعیت با صف Runnable فرق دارد و میتواند به اشباع Worker Pool، کوئریهای موازی فراوان یا Block شدن طولانی تعداد زیادی Session مربوط باشد.
SELECT scheduler_id, current_workers_count,
active_workers_count, work_queue_count
FROM sys.dm_os_schedulers
WHERE status = N'VISIBLE ONLINE'
AND work_queue_count > 0
ORDER BY work_queue_count DESC;
| خروجی نمونه | مقدار نمایشی | برداشت سریع |
|---|
| مثال 3 | Scheduler 1؛ workers=512؛ work queue=7 | در نتیجه فرضی، هفت Task هنوز Worker ندارند. باید همزمان درخواستها، Parallelism و انتظار THREADPOOL بررسی شود؛ افزایش کورکورانه max worker threads معمولاً نخستین راهحل مناسبی نیست. |
در نتیجه فرضی، هفت Task هنوز Worker ندارند. باید همزمان درخواستها، Parallelism و انتظار THREADPOOL بررسی شود؛ افزایش کورکورانه max worker threads معمولاً نخستین راهحل مناسبی نیست.
مثال 4: مقایسه بار میان NUMA Nodeها
توزیع نامتوازن کار میان Nodeها ممکن است از Affinity، Soft-NUMA یا الگوی اتصال ناشی شود. تجمیع Schedulerهای آنلاین بر اساس parent_node_id تصویری سریع از صف Runnable و Workerهای فعال هر Node ارائه میکند.
SELECT parent_node_id,
SUM(runnable_tasks_count) AS runnable_tasks,
SUM(active_workers_count) AS active_workers,
SUM(work_queue_count) AS queued_work
FROM sys.dm_os_schedulers
WHERE status = N'VISIBLE ONLINE'
GROUP BY parent_node_id
ORDER BY parent_node_id;
| خروجی نمونه | مقدار نمایشی | برداشت سریع |
|---|
| مثال 4 | Node 0؛ runnable=1، Node 1؛ runnable=9 | اختلاف بزرگ و پایدار میان Nodeها ارزش بررسی دارد. یک اختلاف کوتاه طبیعی است، اما تداوم آن همراه با Affinity نامناسب یا تعداد اتصال نامتوازن میتواند ظرفیت CPU را هدر دهد. |
اختلاف بزرگ و پایدار میان Nodeها ارزش بررسی دارد. یک اختلاف کوتاه طبیعی است، اما تداوم آن همراه با Affinity نامناسب یا تعداد اتصال نامتوازن میتواند ظرفیت CPU را هدر دهد.
مثال 5: مرور I/Oهای معلق هر Scheduler
pending_disk_io_count شمار درخواستهای I/O ثبتشده در Scheduler است که هنوز تکمیل نشدهاند. این شمارنده وضعیت خود I/O را توضیح نمیدهد، اما برای یافتن Schedulerهایی که همزمان با کندی ذخیرهساز فعالیت بیشتری دارند مفید است.
SELECT scheduler_id, pending_disk_io_count,
runnable_tasks_count, current_tasks_count
FROM sys.dm_os_schedulers
WHERE status = N'VISIBLE ONLINE'
ORDER BY pending_disk_io_count DESC;
| خروجی نمونه | مقدار نمایشی | برداشت سریع |
|---|
| مثال 5 | Scheduler 7؛ pending I/O=12 | عدد بالا باید با sys.dm_io_pending_io_requests، آمار فایل و Latency ذخیرهساز تطبیق داده شود. از pending_disk_io_count بهتنهایی نمیتوان نوع یا علت کندی I/O را نتیجه گرفت. |
عدد بالا باید با sys.dm_io_pending_io_requests، آمار فایل و Latency ذخیرهساز تطبیق داده شود. از pending_disk_io_count بهتنهایی نمیتوان نوع یا علت کندی I/O را نتیجه گرفت.
مثال 6: کنترل شکست ساخت Worker
ستون failed_to_create_worker در شرایطی مانند فشار حافظه میتواند مقدار یک بگیرد. کوئری زیر علاوه بر این پرچم، Workerهای جاری و حد ایدهآل را نمایش میدهد تا کمبود منابع از صف معمول CPU جدا شود.
SELECT scheduler_id, failed_to_create_worker,
current_workers_count, ideal_workers_limit
FROM sys.dm_os_schedulers
WHERE status = N'VISIBLE ONLINE'
AND (failed_to_create_worker = 1
OR current_workers_count > ideal_workers_limit);
| خروجی نمونه | مقدار نمایشی | برداشت سریع |
|---|
| مثال 6 | هیچ ردیفی بازگردانده نشد | خروجی خالی نتیجه مطلوب است. ideal_workers_limit در نسخههای جدیدتر ارائه میشود و ستونهای اطلاعاتی یا نسخهمحور باید پیش از استفاده در اسکریپتهای چندنسخهای کنترل شوند. |
خروجی خالی نتیجه مطلوب است. ideal_workers_limit در نسخههای جدیدتر ارائه میشود و ستونهای اطلاعاتی یا نسخهمحور باید پیش از استفاده در اسکریپتهای چندنسخهای کنترل شوند.
مثال 7: پیوند Scheduler با Taskهای فعال
برای عبور از شمارنده کلی به Task مشخص میتوان scheduler_id را با sys.dm_os_tasks پیوند داد. این نمونه فقط Sessionهای کاربری را نگه میدارد و تعداد Taskهای RUNNABLE یا SUSPENDED هر Scheduler را گزارش میکند.
SELECT s.scheduler_id, t.task_state, COUNT_BIG(*) AS task_count
FROM sys.dm_os_schedulers AS s
JOIN sys.dm_os_tasks AS t
ON t.scheduler_id = s.scheduler_id
WHERE s.status = N'VISIBLE ONLINE'
AND t.session_id > 50
GROUP BY s.scheduler_id, t.task_state
ORDER BY s.scheduler_id, t.task_state;
| خروجی نمونه | مقدار نمایشی | برداشت سریع |
|---|
| مثال 7 | Scheduler 3؛ RUNNABLE=3، SUSPENDED=8 | پیوند نشان میدهد فشار مشاهدهشده از چه وضعیت Taskی میآید. برای رسیدن به متن SQL، session_id و request_id را با DMVهای اجرایی تکمیل کنید و دسترسی به داده دیگر Sessionها را در نظر بگیرید. |
پیوند نشان میدهد فشار مشاهدهشده از چه وضعیت Taskی میآید. برای رسیدن به متن SQL، session_id و request_id را با DMVهای اجرایی تکمیل کنید و دسترسی به داده دیگر Sessionها را در نظر بگیرید.
مثال 8: محاسبه سهم مصرف CPU Schedulerها
total_cpu_usage_ms شمارنده تجمعی مصرف CPU Workerهای Non-preemptive است. تبدیل مقدار هر Scheduler به درصدی از مجموع، Schedulerهای داغ را آشکار میکند؛ این درصد از زمان شروع سرویس تا لحظه نمونهبرداری محاسبه میشود.
WITH s AS
(
SELECT scheduler_id, total_cpu_usage_ms,
SUM(total_cpu_usage_ms) OVER () AS all_cpu_ms
FROM sys.dm_os_schedulers
WHERE status = N'VISIBLE ONLINE'
)
SELECT scheduler_id, total_cpu_usage_ms,
CAST(100.0 * total_cpu_usage_ms / NULLIF(all_cpu_ms, 0)
AS decimal(6,2)) AS cpu_share_pct
FROM s
ORDER BY cpu_share_pct DESC;
| خروجی نمونه | مقدار نمایشی | برداشت سریع |
|---|
| مثال 8 | Scheduler 4؛ سهم تجمعی CPU برابر 18.42٪ | این سهم تجمعی لزوماً بار جاری را نشان نمیدهد. برای تحلیل بازهای، دو Snapshot بگیرید و Delta شمارنده را محاسبه کنید تا فعالیت جدید از تاریخچه سرویس جدا شود. |
این سهم تجمعی لزوماً بار جاری را نشان نمیدهد. برای تحلیل بازهای، دو Snapshot بگیرید و Delta شمارنده را محاسبه کنید تا فعالیت جدید از تاریخچه سرویس جدا شود.
مثال 9: اندازهگیری Delta در یک بازه کوتاه
یک Snapshot قبل و بعد از فاصله یکثانیهای، تغییر yield_count و total_cpu_usage_ms را نشان میدهد. این روش بهجای تفسیر مقدار تجمعی، فعالیت همان بازه را بررسی میکند و برای ساخت Collector نیز الگوی مناسبی است.
SELECT scheduler_id, yield_count, total_cpu_usage_ms
INTO #scheduler_before
FROM sys.dm_os_schedulers
WHERE status = N'VISIBLE ONLINE';
WAITFOR DELAY '00:00:01';
SELECT s.scheduler_id,
s.yield_count - b.yield_count AS yield_delta,
s.total_cpu_usage_ms - b.total_cpu_usage_ms AS cpu_ms_delta
FROM sys.dm_os_schedulers AS s
JOIN #scheduler_before AS b
ON b.scheduler_id = s.scheduler_id
ORDER BY cpu_ms_delta DESC;
DROP TABLE #scheduler_before;
| خروجی نمونه | مقدار نمایشی | برداشت سریع |
|---|
| مثال 9 | Scheduler 0؛ cpu delta=312ms؛ yield delta=84 | فاصله یک ثانیه برای آموزش است. در مانیتورینگ واقعی، Interval ثابت و Timestamp ثبت کنید و اثر خود Collector را با انتخاب ستونهای محدود و تناوب منطقی کاهش دهید. |
فاصله یک ثانیه برای آموزش است. در مانیتورینگ واقعی، Interval ثابت و Timestamp ثبت کنید و اثر خود Collector را با انتخاب ستونهای محدود و تناوب منطقی کاهش دهید.
مثال 10: اصلاح روش پرهزینه SELECT ستاره
برداشت همه ستونها در نمونهبرداری پرتکرار حجم ذخیرهسازی و وابستگی به تغییرات نسخه را زیاد میکند. نمونه اصلاحشده فقط ستونهای لازم برای تشخیص فشار CPU و Worker را انتخاب میکند و Schedulerهای داخلی را کنار میگذارد.
-- روش نامناسب برای Collector دائمی:
-- SELECT * FROM sys.dm_os_schedulers;
-- نسخه کنترلشده و کمحجم:
SELECT scheduler_id, parent_node_id,
runnable_tasks_count, work_queue_count,
active_workers_count
FROM sys.dm_os_schedulers
WHERE status = N'VISIBLE ONLINE';
| خروجی نمونه | مقدار نمایشی | برداشت سریع |
|---|
| مثال 10 | بهجای دهها ستون، پنج شاخص هدفمند ذخیره میشود | بهینهسازی اینجا به معنای Index روی DMV نیست؛ DMV قابل ایندکسگذاری توسط کاربر نیست. کاهش ستون، نرخ نمونهبرداری مناسب و نگهداری تاریخچه در جدول جداگانه روش صحیح است. |
بهینهسازی اینجا به معنای Index روی DMV نیست؛ DMV قابل ایندکسگذاری توسط کاربر نیست. کاهش ستون، نرخ نمونهبرداری مناسب و نگهداری تاریخچه در جدول جداگانه روش صحیح است.
سؤالات متداول
sys.dm_os_schedulers دقیقاً چه چیزی را نشان میدهد؟
sys.dm_os_schedulers برای هر Scheduler یک ردیف ارائه میکند و صف Runnable، Workerها، I/O معلق و بار ادراکشده SQLOS را نشان میدهد. خروجی یک Snapshot زنده است و برای نتیجهگیری باید با زمان Capture، Uptime و DMVهای مکمل تفسیر شود.
چطور نخستین گزارش آموزشی از sys.dm_os_schedulers بسازیم؟
از انتخاب ستونهای کلیدی، فیلتر Session یا وضعیت مرتبط و ثبت Timestamp UTC شروع کنید. سپس نتیجه نمونه را با Baseline محیط سالم مقایسه کنید و معنی هر ستون را پیش از تعریف Alert مستند سازید.
آیا داده sys.dm_os_schedulers برای تصمیم خرید CPU یا حافظه کافی است؟
خیر. تصمیم تجاری خرید سختافزار به روند بلندمدت، SLA، رشد بار، Waitها و داده سیستمعامل نیاز دارد. این DMV یکی از شواهد است و مشاوره ظرفیتسنجی میتواند از هزینه خرید اشتباه جلوگیری کند.
چگونه پایش sys.dm_os_schedulers هزینه عملیاتی را کاهش میدهد؟
Collector کمحجم میتواند نشانههای فشار را پیش از Incident ثبت کند و زمان عیبیابی را کاهش دهد. ارزش اقتصادی زمانی ایجاد میشود که داده با Runbook، Alert قابل اقدام و مسئول مشخص همراه باشد.
تفاوت sys.dm_os_schedulers با DMV مکمل آن چیست؟
این DMV نمای صفبندی در سطح Scheduler است؛ sys.dm_os_tasks واحدهای کار و sys.dm_os_workers مجریان آن واحدها را نشان میدهند. ترکیب لایهها مانع میشود یک شمارنده منفرد به علت قطعی تبدیل شود.
چه زمانی برای تحلیل sys.dm_os_schedulers از خدمات تخصصی استفاده کنیم؟
وقتی مشکل گذرا، چندلایه یا Production است و تیم نمیتواند Snapshot را دوباره تولید کند، طراحی Session جمعآوری شواهد و تحلیل حرفهای مفید است. آموزش هدفمند نیز به تیم کمک میکند Queryها را ایمن و تکرارپذیر اجرا کند.
رایجترین خطا هنگام خواندن sys.dm_os_schedulers چیست؟
رایجترین خطا تفسیر مقدار لحظهای یا تجمعی بدون Baseline و بدون توجه به Restart است. خطای دیگر استفاده از SELECT ستاره در Collector پرتکرار و فرض ثبات همه ستونهای داخلی در نسخههای مختلف است.
اجرای sys.dm_os_schedulers چه اثر Performance دارد؟
یک SELECT محدود و موردی معمولاً سبک است، اما Polling بسیار پرتکرار، پردازش XML یا ذخیره همه ستونها هزینه ایجاد میکند. ستونهای لازم، TOP، فیلتر زودهنگام و تناوب متناسب با هدف را انتخاب کنید.
Best Practice ذخیره تاریخچه sys.dm_os_schedulers چیست؟
Timestamp UTC، sqlserver_start_time، شناسه Instance و فقط شاخصهای لازم را ذخیره کنید. جدول تاریخچه باید Retention، Index متناسب با Query گزارش و جداسازی دسترسی امنیتی داشته باشد.
sys.dm_os_schedulers در کدام نسخههای SQL Server قابل استفاده است؟
این DMV در نسخههای پشتیبان SQL Server ارائه میشود، اما ستونها و مجوزها میتوانند با نسخه و Platform فرق کنند. در SQL Server 2022 و جدیدتر برای بسیاری از DMVهای Performance مجوز VIEW SERVER PERFORMANCE STATE لازم است؛ اسکریپت چندنسخهای باید این تفاوت را کنترل کند.