Deadlock Graph در SQL Server؛ آموزش کامل، مثال و نکات Performance

آموزش Deadlock Graph در SQL Server؛ خواندن و رفع Deadlock Graph

توسط admin | گروه SQL Server | 1405/04/31

نظرات 0

آموزش Deadlock Graph در SQL Server؛ خواندن و رفع Deadlock Graph

مقدمه

Deadlock Graph یک سند XML از چرخه وابستگی منابع است که قربانی انتخاب‌شده، Processها، قفل‌های نگه‌داشته و درخواستی و Batchهای درگیر را نشان می‌دهد. در عیب‌یابی Blocking و Deadlock، ارزش داده زمانی بیشتر می‌شود که آن را با یک Timeline دقیق، مشخصات Client و وضعیت Transaction مرتبط کنیم. این مقاله از خواندن پایه شروع می‌کند و تا الگوهای امن Production، خطاهای رایج و ملاحظات کارایی پیش می‌رود.

برای دیدن جایگاه این ابزار در کل فرایند، راهنمای جامع پایش Blocking و Deadlock در SQL Server را نیز مطالعه کنید. لینک‌ها Root-relative هستند و مقاله حاضر مستقل از دامنه قابل انتشار است.

دسترسی سریع

  1. تعریف، Syntax و مجوزهای مورد نیاز
  2. پارامترها، ستون‌ها و نوع خروجی
  3. ده مثال مستقل از مقدماتی تا Production
  4. خطاهای رایج، Performance و Best Practice
  5. ده پرسش متداول، سؤالات مصاحبه و چک‌لیست

تعریف Deadlock Graph و جایگاه آن

Deadlock Graph یک سند XML از چرخه وابستگی منابع است که قربانی انتخاب‌شده، Processها، قفل‌های نگه‌داشته و درخواستی و Batchهای درگیر را نشان می‌دهد. این داده نباید به شکل جدا از Context تفسیر شود؛ Session ID تنها یک شناسه موقت است و بدون Login، Host، زمان اتصال، Database و متن فرمان می‌تواند تحلیل را منحرف کند.

Blocked Process یک انتظار یک‌طرفه و قابل ادامه است؛ Deadlock یک چرخه است که موتور برای شکستن آن یک Transaction را قربانی می‌کند.

در فرایند حرفه‌ای، مرحله نخست مشاهده و ثبت شواهد است، مرحله دوم تعیین اثر بر SLA، و مرحله سوم انتخاب اصلاح پایدار. اقداماتی مانند KILL، تغییر Threshold یا ساخت Event Session باید از Queryهای فقط‌خواندنی جدا و تحت Change یا Incident ثبت شوند.

Syntax

قالب پایه زیر نقطه شروع است. نام ستون‌ها یا گزینه‌ها را مطابق نسخه مقصد و مجوز حساب مانیتورینگ کنترل کنید.

SELECT CAST(event_data AS xml) AS DeadlockEvent
    FROM sys.fn_xe_file_target_read_file(N'system_health*.xel', NULL, NULL, NULL);
    

پارامترها و اجزای ورودی

  • victim-list: Process انتخاب‌شده برای دریافت خطای 1205.
  • process-list: Session، Transaction، Batch، Priority و منبع انتظار هر عضو چرخه.
  • resource-list: Owner و Waiterهای Lock، Exchange یا دیگر منابع چرخه.

در تمام حالت‌ها از مقدار هدف صریح استفاده کنید و از حلقه‌ای که بدون فیلتر همه Sessionها، Planها یا XMLها را می‌خواند بپرهیزید. مقدارهای ورودی را پیش از ساخت SQL پویا اعتبارسنجی کنید.

نوع خروجی و ستون‌های مهم

XML قابل نمایش گرافیکی با پسوند xdl یا قابل تجزیه با XQuery. به همین دلیل خروجی باید همراه Timestamp ثبت شود و نتیجه قدیمی برای تصمیم مخرب دوباره اعتبارسنجی گردد.

ستون یا بخشمعنا و کاربرد
victim-listقربانی انتخاب‌شده
process-listاعضای چرخه و Batchها
resource-listمنابع، Ownerها و Waiterها
executionStack / inputbufContext اجرای رخداد

مجوزها و ملاحظات امنیتی

خواندن system_health و فایل‌های XE به مجوز مشاهده وضعیت و دسترسی سرویس SQL Server به مسیر مربوط وابسته است. متن Batch، نام Login و Host می‌تواند داده حساس باشد؛ دسترسی به آرشیو مانیتورینگ را محدود، دوره نگهداری را مشخص و خروجی ارسالی به Ticket را پالایش کنید.

اصل Least Privilege یعنی حساب مشاهده‌گر به طور پیش‌فرض حق خاتمه Session، تغییر تنظیمات سرور یا حذف فایل Event را نداشته باشد. اختیار اقدام اضطراری باید جدا، زمان‌دار و ممیزی‌پذیر باشد.

مثال‌های عملی

مثال 1: گرفتن Deadlock XML از Ring Buffer

در این سناریو هدف، دریافت سریع Graphهای اخیر بدون ساخت Collector تازه است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه می‌کند؛ فرمان‌های تغییردهنده باید ابتدا در Lab و با مجوز کنترل‌شده آزموده شوند.

;WITH system_health AS
    (
        SELECT CAST(t.target_data AS xml) AS target_xml
        FROM sys.dm_xe_session_targets AS t
        JOIN sys.dm_xe_sessions AS s ON s.address = t.event_session_address
        WHERE s.name = N'system_health'
          AND t.target_name = N'ring_buffer'
    )
    SELECT
        n.e.value('@timestamp', 'datetime2') AS event_utc,
        n.e.query('(data/value/deadlock)[1]') AS deadlock_xml
    FROM system_health AS sh
    CROSS APPLY sh.target_xml.nodes('/RingBufferTarget/event[@name="xml_deadlock_report"]') AS n(e)
    ORDER BY event_utc DESC;
    
خروجی نمونهتفسیر
2026-07-22 03:31:04 | <deadlock>...</deadlock>نتیجه نمایشی مثال 1؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است.

Retention محدود است؛ رخداد مهم را زود به مخزن Incident منتقل کنید. این نتیجه نمونه کمک می‌کند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمی‌گیرد.

مثال 2: استخراج قربانی Deadlock

در این سناریو هدف، آموزش مسیر victim-list با یک XML کوچک و قابل اجرا است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه می‌کند؛ فرمان‌های تغییردهنده باید ابتدا در Lab و با مجوز کنترل‌شده آزموده شوند.

DECLARE @Deadlock xml = N'<deadlock><victim-list><victimProcess id="processA" /></victim-list></deadlock>';
    
    SELECT v.p.value('@id', 'nvarchar(100)') AS victim_process_id
    FROM @Deadlock.nodes('/deadlock/victim-list/victimProcess') AS v(p);
    
خروجی نمونهتفسیر
processAنتیجه نمایشی مثال 2؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است.

شناسه Process داخل Graph با SPID یکسان نیست؛ آن را به node متناظر در process-list متصل کنید. این نتیجه نمونه کمک می‌کند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمی‌گیرد.

مثال 3: خواندن Process List و Input Buffer

در این سناریو هدف، تجزیه مشخصات هر Process از Graph با XQuery است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه می‌کند؛ فرمان‌های تغییردهنده باید ابتدا در Lab و با مجوز کنترل‌شده آزموده شوند.

DECLARE @Deadlock xml = N'<deadlock><process-list><process id="processA" spid="64" waitresource="KEY: 7:1" lockMode="X"><inputbuf>UPDATE dbo.Orders SET Status=2</inputbuf></process></process-list></deadlock>';
    
    SELECT
        p.n.value('@id', 'nvarchar(100)') AS process_id,
        p.n.value('@spid', 'int') AS spid,
        p.n.value('@waitresource', 'nvarchar(256)') AS wait_resource,
        p.n.value('@lockMode', 'nvarchar(30)') AS lock_mode,
        p.n.value('(inputbuf/text())[1]', 'nvarchar(4000)') AS input_buffer
    FROM @Deadlock.nodes('/deadlock/process-list/process') AS p(n);
    
خروجی نمونهتفسیر
processA | 64 | KEY: 7:1 | X | UPDATE dbo.Orders ...نتیجه نمایشی مثال 3؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است.

Input Buffer را برای Parameterها و Plan زمان رخداد با Query Store یا Actionهای XE غنی کنید. این نتیجه نمونه کمک می‌کند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمی‌گیرد.

مثال 4: خواندن Resource List

در این سناریو هدف، تبدیل انواع پویا در resource-list به ردیف قابل گزارش است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه می‌کند؛ فرمان‌های تغییردهنده باید ابتدا در Lab و با مجوز کنترل‌شده آزموده شوند.

DECLARE @Deadlock xml = N'<deadlock><resource-list><keylock hobtid="7205" dbid="7" objectname="Sales.dbo.Orders" indexname="PK_Orders" mode="X"><owner-list><owner id="processA" mode="X" /></owner-list><waiter-list><waiter id="processB" mode="S" requestType="wait" /></waiter-list></keylock></resource-list></deadlock>';
    
    SELECT
        r.n.value('local-name(.)', 'nvarchar(60)') AS resource_type,
        r.n.value('@objectname', 'nvarchar(512)') AS object_name,
        r.n.value('@indexname', 'nvarchar(512)') AS index_name,
        r.n.value('@mode', 'nvarchar(30)') AS resource_mode
    FROM @Deadlock.nodes('/deadlock/resource-list/*') AS r(n);
    
خروجی نمونهتفسیر
keylock | Sales.dbo.Orders | PK_Orders | Xنتیجه نمایشی مثال 4؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است.

نام شیء لحظه رخداد را نگه دارید؛ پس از Deploy ممکن است Index یا Object تغییر کرده باشد. این نتیجه نمونه کمک می‌کند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمی‌گیرد.

مثال 5: اتصال Owner و Waiter به Process

در این سناریو هدف، بازسازی Edge مالک و منتظر روی هر Resource است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه می‌کند؛ فرمان‌های تغییردهنده باید ابتدا در Lab و با مجوز کنترل‌شده آزموده شوند.

DECLARE @Deadlock xml = N'<deadlock><resource-list><keylock objectname="Sales.dbo.Orders"><owner-list><owner id="processA" mode="X" /></owner-list><waiter-list><waiter id="processB" mode="S" /></waiter-list></keylock></resource-list></deadlock>';
    
    SELECT
        r.n.value('@objectname', 'nvarchar(512)') AS object_name,
        r.n.value('(owner-list/owner/@id)[1]', 'nvarchar(100)') AS owner_process,
        r.n.value('(owner-list/owner/@mode)[1]', 'nvarchar(30)') AS owner_mode,
        r.n.value('(waiter-list/waiter/@id)[1]', 'nvarchar(100)') AS waiter_process,
        r.n.value('(waiter-list/waiter/@mode)[1]', 'nvarchar(30)') AS waiter_mode
    FROM @Deadlock.nodes('/deadlock/resource-list/*') AS r(n);
    
خروجی نمونهتفسیر
Sales.dbo.Orders | processA | X | processB | Sنتیجه نمایشی مثال 5؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است.

چرخه را در سطح همه منابع ببینید؛ تمرکز روی یک Edge ممکن است ترتیب متضاد را پنهان کند. این نتیجه نمونه کمک می‌کند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمی‌گیرد.

مثال 6: بررسی اثر DEADLOCK_PRIORITY

در این سناریو هدف، نشان دادن تنظیم سطح Session برای Job کم‌اهمیت‌تر است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه می‌کند؛ فرمان‌های تغییردهنده باید ابتدا در Lab و با مجوز کنترل‌شده آزموده شوند.

SET DEADLOCK_PRIORITY LOW;
    SELECT N'این Session در تساوی هزینه Rollback، اولویت قربانی شدن بیشتری دارد.' AS note;
    SET DEADLOCK_PRIORITY NORMAL;
    
خروجی نمونهتفسیر
این Session ... اولویت قربانی شدن بیشتری دارد.نتیجه نمایشی مثال 6؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است.

Priority علت Deadlock را رفع نمی‌کند؛ فقط انتخاب قربانی را تحت تأثیر قرار می‌دهد. این نتیجه نمونه کمک می‌کند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمی‌گیرد.

مثال 7: بازسازی Deadlock دو پنجره‌ای

در این سناریو هدف، نمایش اصل ترتیب متضاد دسترسی در یک آزمایش کنترل‌شده است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه می‌کند؛ فرمان‌های تغییردهنده باید ابتدا در Lab و با مجوز کنترل‌شده آزموده شوند.

-- Window A
    BEGIN TRANSACTION;
    UPDATE dbo.DeadlockLab SET ValueText = N'A1' WHERE Id = 1;
    -- سپس در Window B ردیف 2 و بعد در A ردیف 2 را به ترتیب معکوس Update کنید.
    
    -- پاک‌سازی Window A پس از آزمایش:
    ROLLBACK TRANSACTION;
    
خروجی نمونهتفسیر
یکی از دو Transaction با خطای 1205 قربانی می‌شودنتیجه نمایشی مثال 7؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است.

سناریو نیازمند دو Connection است؛ فقط روی جدول Lab و با برنامه Rollback اجرا شود. این نتیجه نمونه کمک می‌کند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمی‌گیرد.

مثال 8: یکسان‌سازی ترتیب دسترسی برای پیشگیری

در این سناریو هدف، رفع چرخه با قرارداد ثابت ترتیب دسترسی به منابع است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه می‌کند؛ فرمان‌های تغییردهنده باید ابتدا در Lab و با مجوز کنترل‌شده آزموده شوند.

BEGIN TRANSACTION;
    
    UPDATE dbo.DeadlockLab
    SET ValueText = N'first'
    WHERE Id = 1;
    
    UPDATE dbo.DeadlockLab
    SET ValueText = N'second'
    WHERE Id = 2;
    
    COMMIT TRANSACTION;
    
خروجی نمونهتفسیر
هر مسیر برنامه باید ردیف‌های 1 و 2 را با همین ترتیب بگیردنتیجه نمایشی مثال 8؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است.

ترتیب یکسان اغلب مؤثرتر از Retry بی‌حد است و باید در همه Code Pathها رعایت شود. این نتیجه نمونه کمک می‌کند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمی‌گیرد.

مثال 9: Retry محدود برای خطای 1205

در این سناریو هدف، افزودن Retry محدود و مخصوص 1205 در کنار اصلاح علت ریشه‌ای است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه می‌کند؛ فرمان‌های تغییردهنده باید ابتدا در Lab و با مجوز کنترل‌شده آزموده شوند.

DECLARE @Attempt int = 1;
    DECLARE @MaxAttempts int = 3;
    
    WHILE @Attempt <= @MaxAttempts
    BEGIN
        BEGIN TRY
            BEGIN TRANSACTION;
            UPDATE dbo.DeadlockLab SET ValueText = N'processed' WHERE Id = 1;
            COMMIT TRANSACTION;
            BREAK;
        END TRY
        BEGIN CATCH
            IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
            IF ERROR_NUMBER() <> 1205 OR @Attempt = @MaxAttempts THROW;
            SET @Attempt += 1;
        END CATCH;
    END;
    
خروجی نمونهتفسیر
موفقیت یا حداکثر سه تلاش؛ خطاهای دیگر دوباره پرتاب می‌شوندنتیجه نمایشی مثال 9؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است.

در Application از Backoff و Jitter استفاده کنید و عملیات را Idempotent طراحی کنید. این نتیجه نمونه کمک می‌کند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمی‌گیرد.

مثال 10: شاخص‌گذاری هدفمند بر اساس Graph

در این سناریو هدف، کاهش دامنه و مدت Lock با Index پشتیبان Predicate نمونه است. Query زیر یک نمونه مستقل و قابل اجرا برای محیط مناسب ارائه می‌کند؛ فرمان‌های تغییردهنده باید ابتدا در Lab و با مجوز کنترل‌شده آزموده شوند.

IF NOT EXISTS
    (
        SELECT 1 FROM sys.indexes
        WHERE object_id = OBJECT_ID(N'dbo.Orders')
          AND name = N'IX_Orders_CustomerId'
    )
    BEGIN
        CREATE INDEX IX_Orders_CustomerId
        ON dbo.Orders(CustomerId)
        INCLUDE (Status, OrderDate);
    END;
    
خروجی نمونهتفسیر
Index فقط در صورت نبودن ساخته می‌شودنتیجه نمایشی مثال 10؛ مقدار واقعی به بارکاری و نسخه سرور وابسته است.

Index را از روی Plan و بار نوشتن تأیید کنید؛ افزودن کورکورانه Index هزینه DML و فضا دارد. این نتیجه نمونه کمک می‌کند پیش از اجرا شکل خروجی را بشناسید، اما جای مشاهده داده واقعی همان Incident را نمی‌گیرد.

خطاهای رایج

  • فرایند Victim الزاماً مقصر اصلی نیست؛ هزینه Rollback و DEADLOCK_PRIORITY در انتخاب قربانی اثر دارند.
  • نتیجه‌گیری از یک Snapshot بدون Timestamp، Baseline یا تکرار رخداد.
  • اشتباه گرفتن Session خواب، Wait طبیعی یا Victim با علت ریشه‌ای.
  • اجرای Query سنگین متن و Plan برای تمام Sessionها با فاصله بسیار کوتاه.
  • ثبت نکردن نسخه SQL Server، مجوز حساب و تنظیمات Collector در گزارش Incident.

اگر خروجی خالی بود، ابتدا مجوز، Scope، Started بودن Session و زمان نمونه‌برداری را بررسی کنید. خالی بودن یک DMV یا Target دلیل قطعی نبود مشکل در چند دقیقه قبل نیست.

ملاحظات Performance

به جای جمع‌آوری Plan و متن سنگین برای همه Queryها، Deadlock XML را نگه دارید و تنها رخدادهای مرتبط را غنی‌سازی کنید. برای Collector، مدت اجرای خود Query، تعداد ردیف، اندازه XML و تعداد رخداد ازدست‌رفته را نیز به‌عنوان Telemetry ثبت کنید.

ابتدا روی داده‌های ارزان مانند Session ID، زمان و Wait فیلتر کنید و سپس برای نامزدهای محدود متن SQL، Input Buffer یا Query Plan را بگیرید. این الگو هم سربار را کم می‌کند و هم اطلاعات حساس غیرمرتبط را وارد آرشیو نمی‌کند.

بهترین روش‌ها در محیط واقعی

  1. برای هر هشدار سؤال و آستانه‌ای مرتبط با SLA تعریف کنید.
  2. Timestamp را در UTC یا datetimeoffset ذخیره و زمان محلی را فقط برای نمایش تبدیل کنید.
  3. شناسه Session را با Login، Host، Program، Database و زمان اتصال تثبیت کنید.
  4. قبل از KILL یا تغییر تنظیمات، Transaction و هزینه Rollback را بسنجید.
  5. شواهد خام را حفظ و تفسیر و تصمیم را جداگانه در Incident ثبت کنید.
  6. Query جمع‌آوری را Load Test و Retention و پاک‌سازی را خودکار کنید.

هدف نهایی حذف کورکورانه Wait نیست؛ باید تراکنش کوتاه‌تر، ترتیب دسترسی ثابت‌تر، ایندکس مناسب‌تر یا Retry محدود در لایه درست ایجاد شود. مشاهده دقیق تنها راه رسیدن به چنین اصلاح پایداری است.

کاربرد سازمانی و سناریوی واقعی

فرض کنید API سفارش در ساعت اوج با Timeout روبه‌رو شده است. تیم ابتدا با Deadlock Graph شواهد مرتبط را می‌گیرد، آن را به Correlation ID و مالک سرویس متصل می‌کند و اثر روی تعداد درخواست‌های مشتری را می‌سنجد. اگر Head Blocker یا Deadlock اثبات شد، اقدام کوتاه‌مدت کنترل‌شده و سپس اصلاح کد یا Index در Backlog قرار می‌گیرد.

در گزارش نهایی باید زمان شروع و پایان، Database، Query Hash در صورت دسترس، تعداد کاربران متأثر، تصمیم‌ها، مجوز اقدام و نتیجه Deploy ثبت شود. این ساختار داده فنی را به زبان قابل فهم برای عملیات و کسب‌وکار تبدیل می‌کند.

سؤالات متداول

پرسش 1: Deadlock Graph دقیقاً چه مسئله‌ای را در SQL Server حل می‌کند؟

Deadlock Graph یک سند XML از چرخه وابستگی منابع است که قربانی انتخاب‌شده، Processها، قفل‌های نگه‌داشته و درخواستی و Batchهای درگیر را نشان می‌دهد. ارزش اصلی آن زمانی آشکار می‌شود که سؤال عملیاتی مشخص باشد؛ مثلاً شناسایی Head Blocker، تعیین منبع انتظار یا حفظ شواهد Deadlock. خروجی باید کنار زمان رخداد و مشخصات Application نگهداری شود تا از یک Snapshot خام به پاسخ قابل اقدام برسیم.

پرسش 2: برای شروع کار با Deadlock Graph چه پیش‌نیازی لازم است؟

ابتدا در محیط آزمایش Syntax و ستون‌های نسخه نصب‌شده را بررسی کنید، سپس مجوز حداقلی مشاهده وضعیت را در نظر بگیرید. خواندن system_health و فایل‌های XE به مجوز مشاهده وضعیت و دسترسی سرویس SQL Server به مسیر مربوط وابسته است. اجرای Query با حساب Production پرقدرت راه‌حل مناسبی نیست و بهتر است نقش مانیتورینگ مشخص و ممیزی‌شده ساخته شود.

پرسش 3: استفاده از Deadlock Graph چه ارزش تجاری برای سامانه پرتراکنش دارد؟

کاهش زمان تشخیص Incident، جلوگیری از تصمیم عجولانه و کوتاه‌شدن اختلال مستقیم‌ترین ارزش‌ها هستند. وقتی داده این ابزار با SLA و مالک سرویس پیوند بخورد، تیم می‌تواند بین کندی عادی، Blocking زیان‌آور و Deadlock تکرارشونده تفاوت بگذارد و هزینه توقف را کم کند.

پرسش 4: چه زمانی برای پیاده‌سازی مانیتورینگ Deadlock Graph به مشاوره تخصصی نیاز داریم؟

اگر رخدادها تکراری، چندپایگاه‌داده‌ای، حساس به امنیت یا دارای حجم Event بالا هستند، طراحی Baseline، Retention و Runbook تخصصی مفید است. مشاوره SQL Server باید در کنار جمع‌آوری داده، Query Plan، تراکنش، ایندکس و رفتار کد Application را نیز بررسی کند؛ خرید ابزار بدون فرایند پاسخ‌گویی کافی نیست.

پرسش 5: تفاوت Deadlock Graph با ابزار نزدیک آن چیست؟

Blocked Process یک انتظار یک‌طرفه و قابل ادامه است؛ Deadlock یک چرخه است که موتور برای شکستن آن یک Transaction را قربانی می‌کند. انتخاب درست به این بستگی دارد که داده لحظه‌ای، تاریخچه XML، مشخصات Session یا امکان اقدام مدیریتی لازم باشد. در عیب‌یابی حرفه‌ای معمولاً چند منبع مکمل کنار هم استفاده می‌شوند، نه اینکه یک خروجی به تنهایی حقیقت کامل فرض شود.

پرسش 6: آیا می‌توان پیاده‌سازی داشبورد یا پروژه Deadlock Graph را به تیم متخصص سپرد؟

بله؛ تحویل حرفه‌ای باید شامل تعریف نیاز، Queryهای کم‌هزینه، کنترل مجوز، ذخیره UTC، سیاست Retention، هشدار قابل تنظیم، داشبورد و Runbook اعتبارسنجی‌شده باشد. پیش از پذیرش پروژه، اثر مانیتورینگ روی Production و روش تست خطا نیز باید مستند شود.

پرسش 7: رایج‌ترین خطا هنگام تحلیل Deadlock Graph چیست؟

فرایند Victim الزاماً مقصر اصلی نیست؛ هزینه Rollback و DEADLOCK_PRIORITY در انتخاب قربانی اثر دارند. خطای دوم تصمیم‌گیری از روی یک Snapshot بدون Baseline است. زمان رخداد، Login، Host، Database، Transaction و Query متناظر را کنار هم قرار دهید و هر مقدار NULL یا نامشخص را صادقانه حفظ کنید.

پرسش 8: آیا Query گرفتن از Deadlock Graph روی Performance اثر می‌گذارد؟

به جای جمع‌آوری Plan و متن سنگین برای همه Queryها، Deadlock XML را نگه دارید و تنها رخدادهای مرتبط را غنی‌سازی کنید. خود مشاهده نیز رایگان نیست، به‌ویژه وقتی XML، Plan یا Text برای تعداد زیادی Session استخراج شود. Period نمونه‌برداری، فیلتر، سقف نگهداری و مانیتور Dropped Event باید بخشی از طراحی باشد.

پرسش 9: بهترین روش استفاده Production از Deadlock Graph چیست؟

پرسش عملیاتی را از قبل تعریف کنید، کمترین ستون و Scope لازم را جمع کنید، Timestamp UTC و شناسه Incident بسازید و اقدام مخرب را از جمع‌آوری شواهد جدا نگه دارید. Runbook باید مرحله تأیید هویت Session، اثر Rollback، تماس با مالک سرویس و معیار پایان Incident را روشن کند.

پرسش 10: Deadlock Graph در کدام نسخه‌های SQL Server قابل استفاده است؟

جزئیات ستون، مجوز و Eventها با نسخه و Azure SQL تفاوت دارد؛ بنابراین metadata و مستندات همان نسخه باید مرجع نهایی باشد. خواندن system_health و فایل‌های XE به مجوز مشاهده وضعیت و دسترسی سرویس SQL Server به مسیر مربوط وابسته است. در ارتقا، Queryها را روی محیط Stage اجرا کنید و به‌ویژه قابلیت‌های Undocumented یا Deprecated را با جایگزین مستند عوض کنید.

سؤالات مصاحبه تخصصی

سؤال 1: چگونه با Deadlock Graph بین علامت و علت ریشه‌ای تفاوت می‌گذارید؟

ابتدا داده آن را با Request، Session، Transaction و Timeline مرتبط می‌کنم؛ سپس Head Blocker یا چرخه Resource را اثبات و فقط پس از آن راهکار ایندکس، ترتیب دسترسی یا کنترل Transaction پیشنهاد می‌دهم.

سؤال 2: چرا یک Snapshot از Deadlock Graph کافی نیست؟

زیرا وضعیت قفل و Wait پویاست. حداقل دو نمونه زمان‌دار، شواهد تاریخی Extended Events و Context برنامه برای تشخیص تداوم، نرخ و اثر لازم است.

سؤال 3: چه کنترل امنیتی برای Deadlock Graph تعریف می‌کنید؟

نقش Read-only با کمترین مجوز، ثبت اجرا، محدودکردن دسترسی به متن Query و جداکردن اختیار KILL یا ALTER EVENT SESSION از مشاهده معمول را در نظر می‌گیرم.

سؤال 4: در طراحی Collector برای Deadlock Graph چه معیارهایی دارید؟

هزینه Query، دوره نمونه‌برداری، حداکثر حجم، Retention، Dropped Event، Timestamp UTC، حذف داده حساس و امکان Correlation با Incident را اندازه می‌گیرم.

سؤال 5: اگر خروجی Deadlock Graph NULL یا خالی باشد چه می‌کنید؟

خالی بودن را به نبود مشکل تعمیم نمی‌دهم؛ مجوز، Started بودن Collector، threshold، زمان Snapshot و منبع مکمل مانند system_health یا Query Store را بررسی می‌کنم.

چک‌لیست نهایی

  • هدف Query و Scope پایگاه داده مشخص است.
  • نسخه SQL Server و مجوز لازم تأیید شده است.
  • Timestamp UTC، Session، Login، Host و Program ثبت می‌شود.
  • خروجی با DMV یا Event مکمل اعتبارسنجی شده است.
  • اقدام مخرب از مشاهده جدا و دارای تأیید است.
  • هزینه Collector، Retention و Dropped Event پایش می‌شود.
  • علت ریشه‌ای و اصلاح دائمی در Incident مستند شده است.

جمع‌بندی

Deadlock Graph زمانی بیشترین ارزش را دارد که با پرسش درست، فیلتر هدفمند و Timeline قابل اعتماد استفاده شود. Deadlock Graph یک سند XML از چرخه وابستگی منابع است که قربانی انتخاب‌شده، Processها، قفل‌های نگه‌داشته و درخواستی و Batchهای درگیر را نشان می‌دهد. با این حال خروجی لحظه‌ای جای تحلیل Transaction، Query Plan و رفتار Application را نمی‌گیرد.

برای مرور ابزارهای مکمل، مسیر تشخیص و لینک همه مقاله‌ها به مقاله مادر پایش Blocking و Deadlock در SQL Server بازگردید. در Production ابتدا شواهد را حفظ کنید، سپس اثر اقدام را بسنجید و اصلاح پایدار را به جای درمان موقت در اولویت بگذارید.

 

0 نظر

نظر محترم شما در مورد مقاله های وب سایت برنامه نویسی و پایگاه داده

نظرات محترم شما در خدمات رسانی بهتر ما را یاری می نمایند. لطفا اگر مایل بودید یک نظر ما را مهمان فرمائید. آدرس ایمیل و وب سایت شما نمایش داده نخواهد شد.

حرف 500 حداکثر