مثالهای عملی
مثال 1: اجرای پایه sp_who
در این سناریو هدف، دریافت فهرست سریع Processهای شناختهشده برای SQL Server است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
EXEC sys.sp_who;
| خروجی نمونه | تفسیر |
|---|
| spid 57 | sleeping | app_user | WEB-02 | SalesDb | نتیجه نمایشی مثال 1؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
خروجی را Snapshot اولیه بدانید و برای Wait و متن Query به DMVهای جدید بروید. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 2: نمایش فقط فعالیتهای Active
در این سناریو هدف، کاهش خروجی به Processهایی است که Active تشخیص داده شدهاند. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
EXEC sys.sp_who @loginame = N'active';
| خروجی نمونه | تفسیر |
|---|
| spid 63 | runnable | report_user | REPORT-01 | SELECT | نتیجه نمایشی مثال 2؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
Active تعریف قدیمی رویه است و با status دقیق dm_exec_requests یا مصرف واقعی CPU یکسان نیست. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 3: بررسی یک SPID مشخص
در این سناریو هدف، تمرکز بررسی دستی بر یک Session شناختهشده است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
DECLARE @SessionId char(5) = '57';
EXEC sys.sp_who @loginame = @SessionId;
| خروجی نمونه | تفسیر |
|---|
| spid 57 | sleeping | app_user | WEB-02 | AWAITING COMMAND | نتیجه نمایشی مثال 3؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
پس از پایان اتصال، SPID قابل استفاده مجدد است؛ زمان و Login را نیز تطبیق دهید. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 4: ذخیره خروجی در جدول موقت
در این سناریو هدف، تبدیل Result Set رویه به داده قابل Query در همان Session است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
CREATE TABLE #Who
(
spid smallint,
ecid smallint,
status nchar(30),
loginame nvarchar(128),
hostname nchar(128),
blk char(5),
dbname nvarchar(128),
cmd nchar(16),
request_id int
);
INSERT INTO #Who
EXEC sys.sp_who;
SELECT * FROM #Who;
| خروجی نمونه | تفسیر |
|---|
| ۹ ستون خروجی در #Who برای فیلتر بعدی ثبت میشود | نتیجه نمایشی مثال 4؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
Schema را روی نسخه مقصد آزمایش کنید؛ کد Production بهتر است مستقیماً از DMVهای مستند بخواند. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 5: فیلتر نشستهای Blocked از خروجی
در این سناریو هدف، استخراج Blockedهایی است که ستون blk آنها SPID مثبت دارد. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
CREATE TABLE #Who
(
spid smallint, ecid smallint, status nchar(30),
loginame nvarchar(128), hostname nchar(128), blk char(5),
dbname nvarchar(128), cmd nchar(16), request_id int
);
INSERT INTO #Who EXEC sys.sp_who;
SELECT spid, loginame, hostname, blk, dbname, cmd
FROM #Who
WHERE TRY_CONVERT(int, NULLIF(LTRIM(RTRIM(blk)), '0')) > 0;
| خروجی نمونه | تفسیر |
|---|
| 64 | app_user | WEB-03 | 57 | SalesDb | UPDATE | نتیجه نمایشی مثال 5؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
برای زنجیره کامل و wait_resource از dm_exec_requests استفاده کنید؛ blk تنها رابطه مستقیم را میدهد. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 6: فیلتر بر اساس Login
در این سناریو هدف، بررسی تمام Sessionهای یک حساب Application است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
EXEC sys.sp_who @loginame = N'app_user';
| خروجی نمونه | تفسیر |
|---|
| spid 57 | sleeping | app_user | WEB-02 | AWAITING COMMAND | نتیجه نمایشی مثال 6؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
اگر چند سرویس Login مشترک دارند، ProgramName و IP برای تفکیک لازم است. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 7: مقایسه خروجی با DMV مدرن
در این سناریو هدف، نمایش عملی فاصله اطلاعاتی رویه قدیمی و DMVها است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
EXEC sys.sp_who @loginame = N'active';
SELECT
r.session_id,
r.status,
s.login_name,
s.host_name,
r.blocking_session_id,
DB_NAME(r.database_id) AS database_name,
r.command,
r.wait_type
FROM sys.dm_exec_requests AS r
JOIN sys.dm_exec_sessions AS s ON s.session_id = r.session_id
WHERE r.session_id > 50;
| خروجی نمونه | تفسیر |
|---|
| DMV علاوه بر ستونهای پایه، wait_type را نیز نشان میدهد | نتیجه نمایشی مثال 7؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
برای Runbook جدید Query DMV را نسخهبندی کنید و sp_who را ابزار بررسی سریع نگه دارید. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 8: افزودن تعداد تراکنش باز
در این سناریو هدف، تکمیل چیزی است که sp_who درباره تراکنش باز آشکار نمیکند. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
SELECT
s.session_id,
s.login_name,
s.status,
s.open_transaction_count,
r.blocking_session_id,
r.command
FROM sys.dm_exec_sessions AS s
LEFT JOIN sys.dm_exec_requests AS r ON r.session_id = s.session_id
WHERE s.is_user_process = 1
AND (s.open_transaction_count > 0 OR r.blocking_session_id > 0);
| خروجی نمونه | تفسیر |
|---|
| 57 | app_user | sleeping | 1 | NULL | NULL | نتیجه نمایشی مثال 8؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
نشست Sleeping دارای Transaction باز میتواند Head Blocker باشد حتی وقتی در sp_who Active نیست. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 9: مدیریت نامهای تهی Client
در این سناریو هدف، ساخت نسخه قابل گزارش با اطلاعات Client کاملتر از sp_who است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
SELECT
s.session_id,
s.login_name,
COALESCE(s.host_name, N'(host unknown)') AS host_name,
COALESCE(s.program_name, N'(program unknown)') AS program_name,
s.status
FROM sys.dm_exec_sessions AS s
WHERE s.is_user_process = 1;
| خروجی نمونه | تفسیر |
|---|
| 57 | app_user | WEB-02 | OrderApi | sleeping | نتیجه نمایشی مثال 9؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
مقادیر ناشناخته را به نام سرور نسبت ندهید؛ این فیلدها ممکن است از Client ارسال نشده باشند. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
مثال 10: جایگزین هدفمند برای مانیتورینگ
در این سناریو هدف، ساخت خروجی شبیه sp_who با ستونهای لازم برای عملیات مدرن است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه میکند؛ فرمانهای تغییردهنده باید ابتدا در Lab و با مجوز کنترلشده آزموده شوند.
SELECT
s.session_id AS spid,
r.status,
s.login_name,
s.host_name,
r.blocking_session_id AS blk,
DB_NAME(r.database_id) AS dbname,
r.command,
r.wait_type,
r.total_elapsed_time
FROM sys.dm_exec_requests AS r
JOIN sys.dm_exec_sessions AS s ON s.session_id = r.session_id
WHERE s.is_user_process = 1
AND (r.blocking_session_id > 0 OR r.total_elapsed_time >= 5000);
| خروجی نمونه | تفسیر |
|---|
| 64 | suspended | app_user | WEB-03 | 57 | SalesDb | UPDATE | LCK_M_X | 8120 | نتیجه نمایشی مثال 10؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است. |
انتخاب ستون صریح، قرارداد گزارش را پایدارتر و هزینه ثبت را کمتر میکند. این نتیجه نمونه کمک میکند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمیگیرد.
سؤالات متداول
پرسش 1: sp_who دقیقاً چه مسئلهای را در SQL Server حل میکند؟
رویه سیستمی sp_who فهرستی فشرده از Sessionها، وضعیت، Login، میزبان، پایگاه داده، فرمان و شناسه Blocker ارائه میکند و برای بررسی سریع خط فرمان مناسب است. ارزش اصلی آن زمانی آشکار میشود که سؤال عملیاتی مشخص باشد؛ مثلاً شناسایی Head Blocker، تعیین منبع انتظار یا حفظ شواهد Deadlock. خروجی باید کنار زمان رخداد و مشخصات Application نگهداری شود تا از یک Snapshot خام به پاسخ قابل اقدام برسیم.
پرسش 2: برای شروع کار با sp_who چه پیشنیازی لازم است؟
ابتدا در محیط آزمایش Syntax و ستونهای نسخه نصبشده را بررسی کنید، سپس مجوز حداقلی مشاهده وضعیت را در نظر بگیرید. هر کاربر بخشی از اطلاعات را میبیند و مشاهده کامل فعالیتها به مجوزهای مدیریتی وابسته است. اجرای Query با حساب Production پرقدرت راهحل مناسبی نیست و بهتر است نقش مانیتورینگ مشخص و ممیزیشده ساخته شود.
پرسش 3: استفاده از sp_who چه ارزش تجاری برای سامانه پرتراکنش دارد؟
کاهش زمان تشخیص Incident، جلوگیری از تصمیم عجولانه و کوتاهشدن اختلال مستقیمترین ارزشها هستند. وقتی داده این ابزار با SLA و مالک سرویس پیوند بخورد، تیم میتواند بین کندی عادی، Blocking زیانآور و Deadlock تکرارشونده تفاوت بگذارد و هزینه توقف را کم کند.
پرسش 4: چه زمانی برای پیادهسازی مانیتورینگ sp_who به مشاوره تخصصی نیاز داریم؟
اگر رخدادها تکراری، چندپایگاهدادهای، حساس به امنیت یا دارای حجم Event بالا هستند، طراحی Baseline، Retention و Runbook تخصصی مفید است. مشاوره SQL Server باید در کنار جمعآوری داده، Query Plan، تراکنش، ایندکس و رفتار کد Application را نیز بررسی کند؛ خرید ابزار بدون فرایند پاسخگویی کافی نیست.
پرسش 5: تفاوت sp_who با ابزار نزدیک آن چیست؟
sp_who مستند و پایدار است، اما DMVها ستونهای کارایی، Wait و متن Query را دقیقتر و قابل ترکیبتر ارائه میکنند. انتخاب درست به این بستگی دارد که داده لحظهای، تاریخچه XML، مشخصات Session یا امکان اقدام مدیریتی لازم باشد. در عیبیابی حرفهای معمولاً چند منبع مکمل کنار هم استفاده میشوند، نه اینکه یک خروجی به تنهایی حقیقت کامل فرض شود.
پرسش 6: آیا میتوان پیادهسازی داشبورد یا پروژه sp_who را به تیم متخصص سپرد؟
بله؛ تحویل حرفهای باید شامل تعریف نیاز، Queryهای کمهزینه، کنترل مجوز، ذخیره UTC، سیاست Retention، هشدار قابل تنظیم، داشبورد و Runbook اعتبارسنجیشده باشد. پیش از پذیرش پروژه، اثر مانیتورینگ روی Production و روش تست خطا نیز باید مستند شود.
پرسش 7: رایجترین خطا هنگام تحلیل sp_who چیست؟
ستون blk فقط سرنخ Blocker است و علت ریشهای، متن فرمان و نوع منبع را بهتنهایی توضیح نمیدهد. خطای دوم تصمیمگیری از روی یک Snapshot بدون Baseline است. زمان رخداد، Login، Host، Database، Transaction و Query متناظر را کنار هم قرار دهید و هر مقدار NULL یا نامشخص را صادقانه حفظ کنید.
پرسش 8: آیا Query گرفتن از sp_who روی Performance اثر میگذارد؟
برای بررسی دستی سبک است؛ برای مانیتورینگ خودکار بهتر است DMVهای مستند با ستونهای صریح استفاده شوند. خود مشاهده نیز رایگان نیست، بهویژه وقتی XML، Plan یا Text برای تعداد زیادی Session استخراج شود. Period نمونهبرداری، فیلتر، سقف نگهداری و مانیتور Dropped Event باید بخشی از طراحی باشد.
پرسش 9: بهترین روش استفاده Production از sp_who چیست؟
پرسش عملیاتی را از قبل تعریف کنید، کمترین ستون و Scope لازم را جمع کنید، Timestamp UTC و شناسه Incident بسازید و اقدام مخرب را از جمعآوری شواهد جدا نگه دارید. Runbook باید مرحله تأیید هویت Session، اثر Rollback، تماس با مالک سرویس و معیار پایان Incident را روشن کند.
پرسش 10: sp_who در کدام نسخههای SQL Server قابل استفاده است؟
جزئیات ستون، مجوز و Eventها با نسخه و Azure SQL تفاوت دارد؛ بنابراین metadata و مستندات همان نسخه باید مرجع نهایی باشد. هر کاربر بخشی از اطلاعات را میبیند و مشاهده کامل فعالیتها به مجوزهای مدیریتی وابسته است. در ارتقا، Queryها را روی محیط Stage اجرا کنید و بهویژه قابلیتهای Undocumented یا Deprecated را با جایگزین مستند عوض کنید.