فهم مشاكل منع قاعدة عبارات Azure SQL وحلها

ينطبق على: قاعدة بيانات Azure SQL

الهدف

توضح المقالة المنع في قواعد عبارات Azure SQL وتوضح كيفية استكشاف أسباب المنع وحلها.

في هذه المقالة، يشير المصطلح اتصال إلى جلسة تسجيل دخول واحدة لقاعدة العبارات. يظهر كل اتصال كمعرف جلسة (SPID) أو session_id في العديد من DMVs. غالبًا ما يشار إلى كل من معرفات SPID هذه على أنها عملية، على الرغم من أنها ليست سياق عملية منفصل بالمعنى المعتاد. بدلاً من ذلك، يتكون كل SPID من موارد الخادم وهياكل العبارات اللازمة لخدمة طلبات اتصال واحد من عميل معين. قد يحتوي تطبيق عميل واحد على اتصال واحد أو أكثر. من منظور قاعدة عبارات Azure SQL، لا يوجد فرق بين الاتصالات المتعددة من تطبيق عميل واحد على كمبيوتر عميل واحد واتصالات متعددة من تطبيقات عميل متعددة أو أجهزة كمبيوتر عميل متعددة؛ كل منهم يتعامل ذرياً. يمكن لاتصال واحد منع اتصال آخر، بغض النظر عن العميل المصدر.

للحصول على معلومات عن استكشاف الأخطاء وإصلاحها، راجع تحليل ومنع حالات التوقف التام في Azure SQL Database.

ملاحظة

يركز هذا المحتوى على قاعدة عبارات Azure SQL. تستند قاعدة عبارات Azure SQL إلى أحدث إصدار ثابت من محرك قاعدة عبارات Microsoft SQL Server، لذا فإن الكثير من المحتوى متشابه على الرغم من اختلاف خيارات وأدوات استكشاف الأخطاء وإصلاحها. لمزيد من المعلومات حول المنع في SQL Server، راجع التعرف على مشكلات منع SQL Server وحلها .

فهم المنع

يعد المنع خاصية لا مفر منها وتصميمها حسب التصميم لأي نظام إدارة قواعد العبارات الارتباطية مع التزامن المستند إلى التأمين. يحدث المنع في قاعدة البيانات في Azure SQL Database عندما تحتفظ جلسة واحدة بقفل على مورد معين ويحاول SPID آخر الحصول على نوع قفل متعارض على نفس المورد. عادةً ما يكون الإطار الزمني الذي يقوم SPID الأول بتأمين المورد له صغيرًا. عندما تصدر الجلسة المالكة التأمين، يكون الاتصال الثاني مجانيًا للحصول على التأمين الخاص به على المورد ومتابعة المعالجة. يعد هذا سلوكًا طبيعيًا وقد يحدث عدة مرات على مدار اليوم دون أي تأثير ملحوظ على أداء النظام.

تحتوي كل قاعدة بيانات جديدة في Azure SQL Database على تمكين إعداد قاعدة البيانات (RCSI) النسخة المطابقة المثبتة للقراءة افتراضياً. يتم تقليل عنصر حظر المستوى بين جلسات قراءة البيانات وبيانات كتابة الجلسات إلى الحد الأدنى في إطار RCSI، والذي يستخدم تعيين إصدار الصفوف لزيادة التزامن. ومع ذلك، قد يستمر حدوث الحظر وحالات التوقف التام في قواعد البيانات في Azure SQL Database للأسباب التالية:

  • الاستعلامات التي تقوم بتعديل البيانات قد يمنع بعضها بعضاً.
  • قد تعمل الاستعلامات ضمن مستويات العزل التي تزيد من عناصر حظر المستوى. يمكن تحديد مستويات العزل في سلاسل اتصال التطبيق، أو تلميحات الاستعلام، أو عبارات SET في Transact-SQL.
  • قد يتم تعطيل RCSI، ما يتسبب في استخدام قاعدة البيانات لأقفال (S) مشتركة لحماية عبارات SELECT التي يتم تشغيلها ضمن مستوى العزل المثبت للقراءة. قد يؤدي هذا إلى زيادة المنع وحالة التوقف التام.

يتم أيضاً تمكين مستوى عزل النسخة المطابقة افتراضياً لقواعد البيانات الجديدة في Azure SQL Database. عزل اللقطة هو مستوى عزل إضافي قائم على الصف يوفر تناسقاً على مستوى المعاملة للبيانات ويستخدم إصدارات الصف لتحديد الصفوف لتحديثها. لاستخدام عزل اللقطة، يجب أن تحدد الاستعلامات أو الاتصالات مستوى عزل المعاملة بشكل صريح إلى SNAPSHOT. يمكن القيام بذلك فقط عندما يتم تمكين عزل اللقطة لقاعدة البيانات.

يمكنك تحديد ما إذا كان يتم تمكين عزل اللقطة و/ أو RCSI باستخدام Transact-SQL. اتصل بقاعدة البيانات في Azure SQL Database وقم بتشغيل الاستعلام التالي:

SELECT name, is_read_committed_snapshot_on, snapshot_isolation_state_desc
FROM sys.databases
WHERE name = DB_NAME();
GO

إذا تم تمكين RCSI، فسيرجع العمود is_read_committed_snapshot_on القيمة 1. إذا تم تمكين عزل النسخة المطابقة، فسيرجع العمود snapshot_isolation_state_desc القيمة تشغيل.

تحدد المدة وسياق المعاملة الخاصة باستعلام ما مدة الاحتفاظ بتأمينه، وبالتالي تأثيرها على الاستعلامات الأخرى. عبارات SELECT التي يتم تشغيلها ضمن RCSI لا تحصل على أقفال (S) مشتركة على البيانات التي تتم قراءتها، وبالتالي لا تمنع العمليات التي تعدل البيانات. بالنسبة إلى عبارات INSERT و UPDATE و DELETE، يتم حفظ التأمين أثناء الاستعلام، سواء لتناسق العبارات والسماح للاستعلام بالعودة إلى الحالة السابقة إذا لزم الأمر.

بالنسبة إلى الاستعلامات التي يتم تنفيذها ضمن المعاملة الصريحة، يتم تحديد نوع التأمين والمدة التي تم خلالها تعليق الأقفال حسب نوع الاستعلام ومستوى عزل المعاملة وما إذا كانت تلميحات التأمين مستخدمة في الاستعلام أم لا. للحصول على وصف للتأمين وتلميحات التأمين ومستويات عزل المعاملات، راجع المقالات التالية:

عندما يستمر التأمين والمنع إلى الحد الذي يوجد فيه تأثير ضار على أداء النظام، فإن ذلك يرجع إلى أحد الأسباب التالية:

  • يحتفظ SPID بالتأمينات على مجموعة من الموارد لفترة طويلة من الوقت قبل تحريرها. هذا النوع من المنع يحل نفسه بمرور الوقت ولكن يمكن أن يتسبب في انخفاض الأداء.

  • يحتفظ SPID بالتأمين على مجموعة من الموارد ولا يطلقها أبدًا. هذا النوع من المنع لا يحل نفسه ويمنع الوصول إلى الموارد المتأثرة إلى أجل غير مسمى.

في السيناريو الأول، يمكن أن يكون الموقف مرنًا للغاية حيث تتسبب معرفات SPID المختلفة في منع موارد مختلفة بمرور الوقت، مما يؤدي إلى إنشاء هدف متحرك. هذه المواقف يصعب استكشافها وإصلاحها باستخدام Management Studio لتضييق نطاق المشكلة على الاستعلامات الفردية. في المقابل، ينتج عن الحالة الثانية حالة ثابتة يمكن تشخيصها بسهولة.

التطبيقات والمنع

قد يكون هناك اتجاه للتركيز على الضبط من جانب الخادم ومشكلات النظام الأساسي عند مواجهة مشكلة المنع. ومع ذلك، فإن الاهتمام بقاعدة العبارات فقط قد لا يؤدي إلى الدقة، ويمكن أن يمتص الوقت والطاقة الموجهة بشكل أفضل لفحص تطبيق العميل والاستفسارات التي يقدمها. بغض النظر عن مستوى الرؤية الذي يعرضه التطبيق فيما يتعلق باستدعاءات قاعدة العبارات التي يتم إجراؤها، إلا أن مشكلة المنع تتطلب في كثير من الأحيان فحص عبارات SQL الدقيقة المقدمة من التطبيق وسلوك التطبيق الدقيق فيما يتعلق بإلغاء الاستعلام وإدارة الاتصال وإحضار جميع سجلات النتائج، وما إلى ذلك. إذا كانت أداة التطوير لا تسمح بالتحكم الصريح في إدارة الاتصال، وإلغاء الاستعلام، وانتهاء مهلة الاستعلام، وجلب النتيجة، وما إلى ذلك، فقد يتعذر حل مشكلات المنع. يجب فحص هذه الإمكانات عن كثب قبل تحديد أداة تطوير تطبيق لقاعدة عبارات Azure SQL، خاصة لبيئات OLTP الحساسة للأداء.

انتبه لأداء قاعدة العبارات أثناء مرحلة التصميم والبناء لقاعدة العبارات والتطبيق. على وجه الخصوص، يجب تقييم استهلاك المورد ومستوى العزل وطول مسار المعاملة لكل استعلام. يَجب أن يكون كل استعلام ومعاملة خفيفة الوزن قدر الإمكان. يجب ممارسة الانضباط الجيد في إدارة الاتصال، وبدون ذلك، قد يبدو أن التطبيق يتمتع بأداء مقبول عند عدد قليل من المستخدمين، ولكن قد يتدهور الأداء بشكل كبير مع تزايد عدد المستخدمين.

بفضل التصميم المناسب للتطبيق والاستعلام، فإن قاعدة عبارات Azure SQL قادرة على دعم عدة آلاف من المستخدمين المتزامنين على خادم واحد، مع القليل من مرات المنع.

استكشاف أخطاء المنع وإصلاحها

بغض النظر عن موقف المنع الذي نتواجد فيه، فإن منهجية استكشاف الأخطاء وإصلاحها للمنع هي نفسها. هذه الفواصل المنطقية هي التي تملي بقية تكوين هذه المقالة. يتمثل المفهوم في العثور على مانع الرأس وتحديد ما يفعله هذا الاستعلام ولماذا يتم منعه. بمجرد تحديد الاستعلام الإشكالي (أي ما الذي يحمل التأمين لفترة طويلة)، فإن الخطوة التالية هي تحليل وتحديد سبب حدوث المنع. بعد أن نفهم السبب، يُمكننا بعد ذلك إجراء تغييرات عن طريق إعادة تصميم الاستعلام والمعاملة.

خطوات في استكشاف الأخطاء وإصلاحها:

  1. تحديد جلسة المنع الرئيسية (منع العنوان)

  2. ابحث عن الاستعلام والمعاملة التي تسببت في المنع (ما الذي يحتفظ بالتأمين لفترة طويلة)

  3. تحليل/فهم سبب حدوث المنع المطول

  4. حل مشكلة المنع عن طريق إعادة تصميم الاستعلام والمعاملة

الآن دعنا نتعمق لمناقشة كيفية تحديد جلسة المنع الرئيسية بالتقاط العبارات المناسبة.

جَمع معلومات المنع

لمواجهة صعوبة استكشاف مشكلات المنع وإصلاحها، يمكن لمسؤول قاعدة البيانات استخدام برامج SQL النصية التي تراقب باستمرار حالة القفل والمنع في قاعدة البيانات في Azure SQL Database. لجمع هذه العبارات، هناك طريقتان أساسيتان.

الأول هو الاستعلام عن عناصر الإدارة الديناميكية (DMOs) وتخزين النتائج للمقارنة مع مرور الوقت. بعض العناصر المشار إليها في هذه المقالة هي عروض الإدارة الديناميكية (DMVs) وبعضها عبارة عن وظائف الإدارة الديناميكية (DMFs). الطريقة الثانية هي استخدام XEvents لالتقاط ما يتم تنفيذه.

جَمع المعلومات من DMVs

تهدف الإشارة إلى DMVs لاستكشاف أخطاء المنع وإصلاحها إلى تحديد SPID (معرّف الجلسة) في عنوان سلسلة المنع وكشف SQL. ابحث عن الضحية SPIDs التي يتم منعها. إذا تم منع أي SPID بواسطة SPID آخر، فابحث عن SPID الذي يمتلك المورد (SPID الممنوع). هل يتم أيضاً منع هذا المالك SPID؟ يمكنك السير في السلسلة للعثور على مانع العنوان ثم التحقق من سبب احتفاظه بتأمينه.

تذكر تشغيل كل من هذه البرامج النصية في قاعدة البيانات الهدف في Azure SQL Database.

  • أوامر sp_who و sp_who2 هي أوامر أقدم لإظهار كافة جَلسات العمل الحالية. يعرض DMVsys.dm_exec_sessions المزيد من العبارات في مجموعة النتائج التي يسهل الاستعلام عنها وتصفيتها. ستجد sys.dm_exec_sessions في الذاكرة الأساسية للاستعلامات الأخرى.

  • إذا تم تحديد جلسة معينة بالفعل، يمكنك استخدام DBCC INPUTBUFFER(<session_id>) للعثور على آخر عبارة تم إرساله بواسطة الجلسة. يمكن إرجاع نتائج مماثلة باستخدام sys.dm_exec_input_buffer وظيفة الإدارة الديناميكية (DMF)، في مجموعة نتائج يسهل الاستعلام عنها وتصفيتها، مما يوفر معرِّف الجلسة ومعرِّف الطلب. على سبيل المثال، لعرض أحدث استعلام تم إرساله بواسطة session_id 66 و request_id 0:

SELECT * FROM sys.dm_exec_input_buffer (66,0);
  • الرجوع إلى blocking_session_idالعمود فيsys.dm_exec_requests. عندما يكون blocking_session_id = 0، لا يتم منع الجلسة. بينما يسرد sys.dm_exec_requests الطلبات قيد التنفيذ حاليًا فقط، سيتم إدراج أي اتصال (نشط أم لا) في sys.dm_exec_sessions. بناء على هذه الصلة المشتركة بين sys.dm_exec_requests و sys.dm_exec_sessions في الاستعلام التالي.

  • قم بتشغيل نموذج الاستعلام هذا للعثور على الاستعلامات التي يتم تنفيذها بشكل نشط ونص حزمة SQL الحالية أو نص المخزن المؤقت للإدخال، باستخدام sys.dm_exec_sql_text أو sys.dm_exec_input_buffer DMVs. إذا كانت العبارات التي تم إرجاعها بواسطة الحقل text في sys.dm_exec_sql_text تكون NUL، فإن الاستعلام لا يتم تنفيذه حاليًا. في هذه الحالة، سيحتوي الحقل event_info في sys.dm_exec_input_buffer على سلسلة الأمر الأخيرة التي تم تمريرها إلى محرك SQL. يمكن أيضًا استخدام هذا الاستعلام لتحديد الجلسات التي تمنع الجلسات الأخرى، بما في ذلك قائمة معرفات الجلسات الممنوعة لكل جلسة معرف.

WITH cteBL (session_id, blocking_these) AS 
(SELECT s.session_id, blocking_these = x.blocking_these FROM sys.dm_exec_sessions s 
CROSS APPLY    (SELECT isnull(convert(varchar(6), er.session_id),'') + ', '  
                FROM sys.dm_exec_requests as er
                WHERE er.blocking_session_id = isnull(s.session_id ,0)
                AND er.blocking_session_id <> 0
                FOR XML PATH('') ) AS x (blocking_these)
)
SELECT s.session_id, blocked_by = r.blocking_session_id, bl.blocking_these
, batch_text = t.text, input_buffer = ib.event_info, * 
FROM sys.dm_exec_sessions s 
LEFT OUTER JOIN sys.dm_exec_requests r on r.session_id = s.session_id
INNER JOIN cteBL as bl on s.session_id = bl.session_id
OUTER APPLY sys.dm_exec_sql_text (r.sql_handle) t
OUTER APPLY sys.dm_exec_input_buffer(s.session_id, NULL) AS ib
WHERE blocking_these is not null or r.blocking_session_id > 0
ORDER BY len(bl.blocking_these) desc, r.blocking_session_id desc, r.session_id;
  • قم بتشغيل نموذج الاستعلام الأكثر تفصيلاً هذا، المقدم من دعم Microsoft، لتحديد رئيس سلسلة منع الجلسات المتعددة، بما في ذلك نص الاستعلام الخاص بالجلسات المتضمنة في سلسلة المنع.
WITH cteHead ( session_id,request_id,wait_type,wait_resource,last_wait_type,is_user_process,request_cpu_time
,request_logical_reads,request_reads,request_writes,wait_time,blocking_session_id,memory_usage
,session_cpu_time,session_reads,session_writes,session_logical_reads
,percent_complete,est_completion_time,request_start_time,request_status,command
,plan_handle,sql_handle,statement_start_offset,statement_end_offset,most_recent_sql_handle
,session_status,group_id,query_hash,query_plan_hash) 
AS ( SELECT sess.session_id, req.request_id, LEFT (ISNULL (req.wait_type, ''), 50) AS 'wait_type'
    , LEFT (ISNULL (req.wait_resource, ''), 40) AS 'wait_resource', LEFT (req.last_wait_type, 50) AS 'last_wait_type'
    , sess.is_user_process, req.cpu_time AS 'request_cpu_time', req.logical_reads AS 'request_logical_reads'
    , req.reads AS 'request_reads', req.writes AS 'request_writes', req.wait_time, req.blocking_session_id,sess.memory_usage
    , sess.cpu_time AS 'session_cpu_time', sess.reads AS 'session_reads', sess.writes AS 'session_writes', sess.logical_reads AS 'session_logical_reads'
    , CONVERT (decimal(5,2), req.percent_complete) AS 'percent_complete', req.estimated_completion_time AS 'est_completion_time'
    , req.start_time AS 'request_start_time', LEFT (req.status, 15) AS 'request_status', req.command
    , req.plan_handle, req.[sql_handle], req.statement_start_offset, req.statement_end_offset, conn.most_recent_sql_handle
    , LEFT (sess.status, 15) AS 'session_status', sess.group_id, req.query_hash, req.query_plan_hash
    FROM sys.dm_exec_sessions AS sess
    LEFT OUTER JOIN sys.dm_exec_requests AS req ON sess.session_id = req.session_id
    LEFT OUTER JOIN sys.dm_exec_connections AS conn on conn.session_id = sess.session_id 
    )
, cteBlockingHierarchy (head_blocker_session_id, session_id, blocking_session_id, wait_type, wait_duration_ms,
wait_resource, statement_start_offset, statement_end_offset, plan_handle, sql_handle, most_recent_sql_handle, [Level])
AS ( SELECT head.session_id AS head_blocker_session_id, head.session_id AS session_id, head.blocking_session_id
    , head.wait_type, head.wait_time, head.wait_resource, head.statement_start_offset, head.statement_end_offset
    , head.plan_handle, head.sql_handle, head.most_recent_sql_handle, 0 AS [Level]
    FROM cteHead AS head
    WHERE (head.blocking_session_id IS NULL OR head.blocking_session_id = 0)
    AND head.session_id IN (SELECT DISTINCT blocking_session_id FROM cteHead WHERE blocking_session_id != 0)
    UNION ALL
    SELECT h.head_blocker_session_id, blocked.session_id, blocked.blocking_session_id, blocked.wait_type,
    blocked.wait_time, blocked.wait_resource, h.statement_start_offset, h.statement_end_offset,
    h.plan_handle, h.sql_handle, h.most_recent_sql_handle, [Level] + 1
    FROM cteHead AS blocked
    INNER JOIN cteBlockingHierarchy AS h ON h.session_id = blocked.blocking_session_id and h.session_id!=blocked.session_id --avoid infinite recursion for latch type of blocking
    WHERE h.wait_type COLLATE Latin1_General_BIN NOT IN ('EXCHANGE', 'CXPACKET') or h.wait_type is null
    )
SELECT bh.*, txt.text AS blocker_query_or_most_recent_query 
FROM cteBlockingHierarchy AS bh 
OUTER APPLY sys.dm_exec_sql_text (ISNULL ([sql_handle], most_recent_sql_handle)) AS txt;
SELECT [s_tst].[session_id],
[database_name] = DB_NAME (s_tdt.database_id),
[s_tdt].[database_transaction_begin_time], 
[sql_text] = [s_est].[text] 
FROM sys.dm_tran_database_transactions [s_tdt]
INNER JOIN sys.dm_tran_session_transactions [s_tst] ON [s_tst].[transaction_id] = [s_tdt].[transaction_id]
INNER JOIN sys.dm_exec_connections [s_ec] ON [s_ec].[session_id] = [s_tst].[session_id]
CROSS APPLY sys.dm_exec_sql_text ([s_ec].[most_recent_sql_handle]) AS [s_est];
  • مَرجع sys.dm_os_waiting_tasks في طبقة مؤشر الترابط/المهمة من SQL. يؤدي هذا إلى إرجاع معلومات حول نوع انتظار SQL الذي يواجهه الطلب حاليًا. مثلاً sys.dm_exec_requests، يتم إرجاع الطلبات النشطة فقط بواسطة sys.dm_os_waiting_tasks.

ملاحظة

لمزيد من المعلومات حول أنواع الانتظار بما في ذلك إحصاءات الانتظار المجمعة بمرور الوقت، راجع DMV sys.dm_db_wait_stats . يعرض DMV إحصائيات الانتظار المجمعة لقاعدة العبارات الحالية فقط.

  • استخدم sys.dm_tran_locks DMV لمزيد من المعلومات الدقيقة حول التأمينات التي وضعتها طلبات البحث. يمكن لـDMV هذا إرجاع كميات كبيرة من البيانات في قاعدة بيانات الإنتاج، وهو مفيد لتشخيص الأقفال الموجودة حالياً.

نظرًا لـ INNER JOIN على sys.dm_os_waiting_tasks، يقيد الاستعلام التالي الإخراج من sys.dm_tran_locks فقط للطلبات الممنوعة حاليًا وحالة انتظارها وتأميناتها:

SELECT table_name = schema_name(o.schema_id) + '.' + o.name
, wt.wait_duration_ms, wt.wait_type, wt.blocking_session_id, wt.resource_description
, tm.resource_type, tm.request_status, tm.request_mode, tm.request_session_id
FROM sys.dm_tran_locks AS tm
INNER JOIN sys.dm_os_waiting_tasks as wt ON tm.lock_owner_address = wt.resource_address
LEFT OUTER JOIN sys.partitions AS p on p.hobt_id = tm.resource_associated_entity_id
LEFT OUTER JOIN sys.objects o on o.object_id = p.object_id or tm.resource_associated_entity_id = o.object_id
WHERE resource_database_id = DB_ID()
AND object_name(p.object_id) = '<table_name>';
  • مع DMVs، تخزين نتائج الاستعلام مع مرور الوقت سوف توفر نقاط العبارات التي سوف تسمح لك لمراجعة منع على مدى فترة زمنية محددة لتحديد منع المستمر أو الاتجاهات.

جمع المعلومات من الأحداث الممتدة

بالإضافة إلى المعلومات السابقة، غالبًا ما يكون من الضروري التقاط تتبع للأنشطة على الخادم لإجراء تحقيق شامل في مشكلة المنع في قاعدة عبارات Azure SQL. على سبيل المثال، إذا نفذت جلسة ما عدة عبارات في إحدى المعاملات، فسيتم تمثيل العبارة الأخيرة التي تم تقديمها فقط. ومع ذلك، قد يكون أحد العبارات السابقة هو السبب في استمرار الاحتفاظ بالتأمينات. يمكنك التتبع من رؤية جَميع الأوامر التي نفذتها الجلسة ضمن المعاملة الحالية.

هناك طريقتان لالتقاط التعقّب في SQL Server؛ الأحداث الممتدة (XEvents) وآثار ملف التعريف. ومع ذلك، فإن SQL Server Profiler هو تقنية تتبع قديمة، لا تدعمها قاعدة بَيانات SQL Azure. تُعد الأحداث الممتدة تقنية تتبع حديثة تسمح بمزيد من التنوع ولها تأثير منخفض على النظام الخاضع للملاحظة، وتم دَمج واجهته في Management Studio (SSMS).

راجع المستند الذي يشرح كيفية استخدام Extended Events New Session Wizard في Management Studio. ومع ذلك، بالنسبة لقواعد عبارات Azure SQL، يوفر SSMS مجلدًا فرعيًا للأحداث الموسعة تحت كل قاعدة عبارات في مستكشف عناصر SQL Server. استخدم معالج جلسة عمل الأحداث المُوسعة لالتقاط هذه الأحداث المفيدة:

  • أخطاء الفِئة:

    • انتِباه
    • Error_reported
    • Execution_warning
  • تَحذيرات الفئة:

    • Missing_join_predicate
  • تَنفيذ الفئة:

    • Rpc_completed
    • Rpc_starting
    • Sql_batch_completed
    • Sql_batch_starting
  • Category deadlock_monitor

    • database_xml_deadlock_report
  • فئة الجلسة

    • Existing_connection
    • تسجيل الدخول
    • تسجيل الخروج

ملاحظة

للحصول على معلومات تفصيلية عن حالات التوقف التام، راجع تحليل ومنع حالات التوقف التام في Azure SQL Database.

تحديد سيناريوهات المنع الشائعة وحلها

من خلال تحديد المعلومات السابقة، يمكنك تحديد سبب معظم مشاكل المنع. بقية هذه المقالة هو مناقشة كيفية استخدام هذه المعلومات لتعريف وحل بعض سيناريوهات المنع الشائعة. تفترض هذه المناقشة استخدام البرامج النصية منع (المشار إليها سابقا) لالتقاط معلومات حول منع SPIDs وقد التقاط نشاط التطبيق باستخدام جلسة عمل XEvent.

تحليل عبارات المنع

  • افحص إخراج DMVs sys.dm_exec_requests و sys.dm_exec_sessions لتحديد عناوين سلاسل الحظر، باستخدام blocking_these وsession_id. سيؤدي هذا إلى تحديد أي الطلبات ممنوعة وأيها جاري منعه. انظر أكثر في الجلسات التي تم منعها والجاري منعها. هل هناك مشترك أو الجذر لسلسلة المنع؟ من المحتمل أن يشتركوا في جدول مشترك، وتقوم جلسة واحدة أو أكثر من الجلسات المشاركة في سلسلة المنع بإجراء عملية كتابة.

  • افحص إخراج DMVs sys.dm_exec_requests وsys.dm_exec_sessions للحصول على معلومات حول SPID في عنوان سلسلة الحظر. ابحث عن الحقُول التالية:

    • sys.dm_exec_requests.status
      يعرض هذا العمود حالة طَلب معين. بشكل عام، يشير وضع السكون إلى أن SPID قد أكمل التنفيذ وينتظر التطبيق لإرسال استعلام أو دفعة أخرى. تشير حالة القابلية للتشغيل أو قابلية التشغيل إلى أن SPID يقوم حالياً بمعالجة الاستعلام. يقدم الجدول التالي شرحا مُختصرا لقيم الحالة المختلفة.
    الحالة المعنى
    الخلفية يقوم SPID بتشغيل مهمة في الخلفية، مثل الكشف عن حالة توقف تام أو كاتب السجل أو نقطة تحقق.
    التَسكين لا يتم تنفيذ SPID حاليًا. يُشير هذا عادة إلى أن SPID ينتظر الأمر من التطبيق.
    قيد التشغيل يتم تشغيل SPID حاليًا على برنامج جدولة.
    قابلية الَتشغيل SPID موجود في قائمة الانتظار القابلة للتشغيل لجدول وينتظر الحصول على وقت الجدولة.
    موقوف مؤقتاً ينتظر SPID موردًا، مثل تأمين أو حماية مؤقتة.
    • sys.dm_exec_sessions.open_transaction_count
      يخبرك هذا الحقل بعدد الحركات المَفتوحة في جلسة العمل هذه. إذا كانت هذه القيمة أكبر من 0، فإن SPID يكون ضمن معاملة مفتوحة وقد يحتفظ بتأمينات تم الحصول عليها بواسطة أي عبارة داخل المعاملة.

    • sys.dm_exec_requests.open_transaction_count
      وبالمثل، يخبرك هذا الحقل بعدد المعاملات المفتوحة في هذا الطلب. إذا كانت هذه القيمة أكبر من 0، فإن SPID يكون ضمن معاملة مفتوحة وقد يحتفظ بتأمينات تم الحصول عليها بواسطة أي عبارة داخل المعاملة.

    • sys.dm_exec_requests.wait_type وwait_time وlast_wait_type
      إذا كان sys.dm_exec_requests.wait_type NULL، فإن الطلب لا ينتظر حالياً أي شيء وتشير القيمة last_wait_type إلى آخر wait_type واجهه الطلب. لمزيدٍ من المعلومات حول sys.dm_os_wait_stats ووصف أكثر أنواع الانتظار شيوعاً، راجع sys.dm_os_wait_stats. يمكن استخدام القيمة wait_time لتحديد ما إذا كان الطلب يحرز تقدماً. عندما يقوم استعلام مقابل الجدول sys.dm_exec_requests بإرجاع قيمة في العمود wait_time أقل من القيمة wait_time من استعلام سابق لـ sys.dm_exec_requests، فإن هذا يشير إلى الحصول على التأمين السابق وتحريره وهو قيد الانتظار الآن على تأمين جديد (بافتراض أنه غير صفري wait_time). يمكن التحقق من ذلك بمقارنة المخرجات wait_resource بين sys.dm_exec_requests، والتي تعرض المورد الذي ينتظره الطلب.

    • sys.dm_exec_requests.wait_resource يشير هذا الحقل إلى المورد الذي ينتظره طلب ممنوع. يسرد الجدول التالي التنسيقات الشائعة wait_resource ومعناها:

    المورد تنسيق مثال التفسير
    الجدول معرف قاعدة العبارات: معرف العنصر: معرف الفهرس علامة تبويب: 5:261575970:1 في هذه الحالة، معرف قاعدة البيانات 5 هو قاعدة بيانات نموذج النشر ومعرف العنصر 261575970 هو جدول العناوين و1 هو فهرس نظام المجموعة.
    الصفحة معرّف قاعدة العبارات: معرّف الملف: معرّف الصفحة صفحة: 5:1:104 في هذه الحالة، معرف قاعدة البيانات 5 هو عمليات النشر، ومعرف الملف 1 هو ملف البيانات الأساسي، والصفحة 104 هي صفحة تنتمي إلى جدول العناوين. لتحديد معرّف العنصر الذي تنتمي إليه الصفحة، استخدم وظيفة الإدارة الديناميكية sys.dm_db_page_info، مروراً بمعرّف قاعدة العبارات ومعرّف الملف ومعرّف الصفحة من wait_resource.
    المفتاح معرّف قاعدة العبارات:Hobt_id (قيمة التجزئة لمفتاح الفهرس) المُفتاح: 5:72057594044284928 (3300a4f361aa) في هذه الحالة، معرف قاعدة البيانات 5 هو عمليات النشر، وHobt_ID 72057594044284928 يتوافق مع index_id 2 لـ object_id 261575970 (جدول العناوين). استَخدم sys.partitions طريقة عرض الكتالوج لربط hobt_id ب معين index_id و object_id. لا توجد طريقة لإلغاء تجزئة مفتاح الفهرس إلى قيمة مفتاح محددة.
    الصف معرّف قاعدة العبارات: معرّف الملف: معرّف الصفحة فتحة(صف) RID: 5:1:104:3 في هذه الحالة، معرف قاعدة العبارات 5 هو pubs (الناشر)، ومعرف الملف 1 هو ملف العبارات الأساسي، والصفحة 104 هي صفحة تنتمي إلى جدول العناوين، وتشير الفتحة 3 إلى موضع الصف على الصفحة.
    التحويل برمجياً معرّف قاعدة العبارات: معرّف الملف: معرّف الصفحة فتحة(صف) RID: 5:1:104:3 في هذه الحالة، معرف قاعدة العبارات 5 هو pubs (الناشر)، ومعرف الملف 1 هو ملف العبارات الأساسي، والصفحة 104 هي صفحة تنتمي إلى جدول العناوين، وتشير الفتحة 3 إلى موضع الصف على الصفحة.
    • sys.dm_tran_active_transactions يحتوي sys.dm_tran_active_transactions DMV على عبارات حول المعاملات المفتوحة التي يمكن ضمها إلى DMVs الأخرى للحصول على صورة كاملة للمعاملات التي تنتظر الالتزام أو العودة إلى الحالة السابقة. استخدم الاستعلام التالي لعرض معلومات عن المعاملات المفتوحة، المنضمة إلى DMVs الأخرى بما في ذلك sys.dm_tran_session_transactions . ضع في اعتبارك الحالة الحالية للمعاملة، transaction_begin_time، وغيرها من بيانات الموقف لتقييم ما إذا كان يمكن أن تكون مصدرًا للمنع.
    SELECT tst.session_id, [database_name] = db_name(s.database_id)
    , tat.transaction_begin_time
    , transaction_duration_s = datediff(s, tat.transaction_begin_time, sysdatetime()) 
    , transaction_type = CASE tat.transaction_type  WHEN 1 THEN 'Read/write transaction'
                                                    WHEN 2 THEN 'Read-only transaction'
                                                    WHEN 3 THEN 'System transaction'
                                                    WHEN 4 THEN 'Distributed transaction' END
    , input_buffer = ib.event_info, tat.transaction_uow     
    , transaction_state  = CASE tat.transaction_state    
                WHEN 0 THEN 'The transaction has not been completely initialized yet.'
                WHEN 1 THEN 'The transaction has been initialized but has not started.'
                WHEN 2 THEN 'The transaction is active - has not been committed or rolled back.'
                WHEN 3 THEN 'The transaction has ended. This is used for read-only transactions.'
                WHEN 4 THEN 'The commit process has been initiated on the distributed transaction.'
                WHEN 5 THEN 'The transaction is in a prepared state and waiting resolution.'
                WHEN 6 THEN 'The transaction has been committed.'
                WHEN 7 THEN 'The transaction is being rolled back.'
                WHEN 8 THEN 'The transaction has been rolled back.' END 
    , transaction_name = tat.name, request_status = r.status
    , azure_dtc_state = CASE tat.dtc_state 
                        WHEN 1 THEN 'ACTIVE'
                        WHEN 2 THEN 'PREPARED'
                        WHEN 3 THEN 'COMMITTED'
                        WHEN 4 THEN 'ABORTED'
                        WHEN 5 THEN 'RECOVERED' END
    , tst.is_user_transaction, tst.is_local
    , session_open_transaction_count = tst.open_transaction_count  
    , s.host_name, s.program_name, s.client_interface_name, s.login_name, s.is_user_process
    FROM sys.dm_tran_active_transactions tat 
    INNER JOIN sys.dm_tran_session_transactions tst  on tat.transaction_id = tst.transaction_id
    INNER JOIN sys.dm_exec_sessions s on s.session_id = tst.session_id 
    LEFT OUTER JOIN sys.dm_exec_requests r on r.session_id = s.session_id
    CROSS APPLY sys.dm_exec_input_buffer(s.session_id, null) AS ib;
    
    • أعمِدة أخرى

      يمكن أن توفر الأعمدة المتبقية في sys.dm_exec_sessions وsys.dm_exec_request نظرة ثاقبة حول جذر المشكلة أيضاً. تختلف فائدتها حسب ظروف المشكلة. على سبيل المثال، يمكنك تحديد ما إذا كانت المشكلة تحدث فقط من عملاء معينين (اسم المضيف)، في بعض مكتبات الشبكة (net_library)، عندما كانت آخر دفعة تم إرسالها بواسطة SPID last_request_start_time في sys.dm_exec_sessions، ومدة تشغيل الطلب باستخدام start_time في sys.dm_exec_requests، وهكذا.

سيناريوهات المنع الشائعة

يوضح الجدول أدناه الأعراض الشائعة لأسبابها المُحتملة.

تُشير أعمدة Waittype و Open_Tran و Status إلى المعلومات التي تم إرجاعها بواسطة sys.dm_exec_request، وقد يتم إرجاع أعمدة أخرى بواسطة sys.dm_exec_sessions. يشير العمود "الحل؟" إلى ما إذا كان سيتم حل الحظر من تلقاء نفسه أم لا، أو ما إذا كان يجب إنهاء الجلسة عن طريق الأمر KILL. للحصول على مزيدٍ من المعلومات، راجع KILL (Transact-SQL).

السيناريو Waittype Open_Tran الحالة الحلول؟ أعراض أُخرى
1 NOT NULL >= 0 قابلية الَتشغيل نعم، عند انتِهاء الاستعلام. في sys.dm_exec_sessions وreads وcpu_time و/أو memory_usage تزداد الأعمدة بمرور الوقت. ستكون مدة الاستعلام طويلة عند الانتهاء.
2 NULL >0 التَسكين لا، لكن يمكن إنهاء SPID. قد تظهر إشارة انتباه في جلسة الأحداث الموسعة لـ SPID هذا، مما يشير إلى انتهاء مهلة الاستعلام أو الإلغاء.
3 NULL >= 0 قابلية الَتشغيل كلا. لن يتم حلها حتى يجلب العميل جميع الصفوف أو يغلق الاتصال. يمكن إنهاء SPID، ولكن قد يستغرق الأمر ما يصل إلى 30 ثانية. إذا open_transaction_count = 0، و SPID يحفظ التأمين أثناء مستوى عزل المعاملة الافتراضي (READ COMMMITTED)، وهذا هو سبب محتمل.
4 يتفاوت >= 0 قابلية الَتشغيل كلا. لن يتم حلها حتى يقوم العميل بإلغاء الاستعلامات أو إغلاق الاتِصالات. يمكن إيقاف SPIDs، ولكن قد يستغرق ما يصل إلى 30 ثانية. سيكون العمود hostname الموجود في sys.dm_exec_sessions لـ SPID في عنوان سلسلة المنع هو نفس العمود الذي يمنعه SPID.
5 NULL >0 العودة_إلى_الحالة_السابقة نعم. يمكن رؤية إشارة انتباه في جلسة الأحداث الممتدة لـ SPID، مما يشير إلى انتهاء مهلة الاستعلام أو الإلغاء، أو أنه تم إصدار بيان التراجع.
6 NULL >0 التَسكين في النهاية. عندما يحدد Windows NT أن الجلسة لم تعد نشطة، سيتم قطع اتصال قاعدة بيانات Azure SQL. last_request_start_time القيمة sys.dm_exec_sessions أقدم بكثير من الوقت الحالي.

سيناريوهات المنع المفصلة

  1. المنع ناتج عن استعلام يعمل بشكل طبيعي مع وقت تنفيذ طويل

    الحل: يتمثل حل هذا النوع من مشاكل المنع في البحث عن طرق لتحسين الاستعلام. في الواقع، قد تكون مشكلة المنع هذه مجرد مشكلة في الأداء، وتتطلب منك متابعتها على هذا النحو. للحصول على معلومات حول استكشاف أخطاء استعلام معين بطيء التشغيل وإصلاحها، راجع كيفية استكشاف أخطاء الاستعلامات التي تعمل ببطء في SQL Server وإصلاحها. للحصول على مزيدٍ من المعلومات، راجع مراقبة أداء الشبكة.

    التقارير من Query Store في Management Studio هي أيضًا أداة موصى بها للغاية وقيمة لتحديد الاستعلامات الأكثر تكلفة، وخطط التنفيذ دون المستوى الأمثل. راجع أيضا قسم الأداء الذكي في مدخل Microsoft Azure لقاعدة بيانات Azure SQL، بما في ذلك "نظرة أداء الاستعلام".

    إذا كان الاستعلام ينفذ عمليات SELECT فقط، فضع في اعتبارك تشغيل العبارة تحت عزل النسخة المطابقة إذا تم تمكينها في قاعدة البيانات الخاصة بك، خاصةً إذا تم تعطيل RCSI. كما هو الحال عند تمكين RCSI، لا تتطلب استعلامات قراءة البيانات تأميناً مشتركاً (S) ضمن مستوى عزل النسخة المطابقة. بالإضافة إلى ذلك، يوفر عزل النسخة المطابقة اتساقاً على مستوى العملية لجميع البيانات في معاملة صريحة متعددة كشوف الحساب. ربما تم تمكين عزل النسخة المطابقة بالفعل في قاعدة البيانات الخاصة بك. يمكن أيضاً استخدام عزل النسخة المطابقة مع الاستعلامات التي تقوم بإجراء تعديلات، ولكن يجب التعامل مع تعارضات التحديث.

    إذا كان لديك استعلام طويل الأمد يمنع مستخدمين آخرين ولا يمكن تحسينه، ففكر في نقله من بيئة OLTP إلى نظام تقارير مخصص، وهو نسخة متماثلة متزامنة للقراءة فقط من قاعدة البيانات.

  2. سبب المنع هو SPID الساكن الذي يحتوي على معاملة غير ملتزم بها

    يمكن التعرف على هذا النوع من المنع غالبًا بواسطة SPID الذي يسكن أو ينتظر الأمر، ومع ذلك فإن مستوى تداخل المعاملات (@@TRANCOUNT، open_transaction_count من sys.dm_exec_requests) أكبر من الصفر. يمكن أن يحدث هذا إذا واجه التطبيق مهلة استعلام أو أصدر إلغاء بدون إصدار العدد المطلوب من عبارات ROLLBACK و/أو COMMIT. عندما يتلقى SPID مهلة استعلام أو إلغاء، فإنه سينهي الاستعلام والدُفعة الحاليين، لكنه لا يتراجع أو يلتزم بالمعاملة تلقائيًا. التطبيق مسؤول عن ذلك، حيث لا يمكن لقاعدة بيانات Azure SQL أن تفترض أنه يجب التراجع عن المعاملة بأكملها بسبب إلغاء استعلام واحد. ستظهر مهلة الاستعلام أو الإلغاء كحدث إشارة تنبيه لـ SPID في جلسة "الأحداث الموسعة".

    لتوضيح معاملة صريحة غير ملتزمة، قم بإصدار الاستعلام التالي:

    CREATE TABLE #test (col1 INT);
    INSERT INTO #test SELECT 1;
    BEGIN TRAN
    UPDATE #test SET col1 = 2 where col1 = 1;
    

    ثم قم بتنفيذ هذا الاستعلام في نفس النافذة:

    SELECT @@TRANCOUNT;
    ROLLBACK TRAN
    DROP TABLE #test;
    

    يشير ناتج الاستعلام الثاني إلى أن مستوى تداخل المعاملة واحد. لا تزال جميع الأقفال التي تم الحصول عليها في المعاملة معلقة حتى يتم تنفيذ المعاملة أو التراجع عنها. إذا فتحت التطبيقات المعاملات بشكل صريح وتلتزم بها، فقد يؤدي الاتصال أو أي خطأ آخر إلى ترك الجلسة ومعاملتها في حالة مفتوحة.

    استخدم النص السابق في هذه المقالة استنادًا إلى sys.dm_tran_active_transactions لتحديد المعاملات غير الملتزم بها حاليًا عبر المثيل.

    درجات الدقة:

    • بالإضافة إلى ذلك، قد تكون مشكلة المنع هذه أيضًا مشكلة في الأداء، وتتطلب منك متابعتها على هذا النحو. إذا كان من الممكن تقليل وقت تنفيذ الاستعلام، فلن تحدث مهلة الاستعلام أو الإلغاء. من المهم أن يكون التطبيق قادرًا على التعامل مع المهلة أو إلغاء السيناريوهات في حالة ظهورها، ولكن يمكنك أيضًا الاستفادة من تحديد أداء الاستعلام.

    • يجب أن تدير التطبيقات مستويات تضمين المعاملات بشكل صحيح، أو قد تتسبب في مشكلة منع بعد إلغاء الاستعلام بهذه الطريقة. ضع في اعتبارك ما يلي:

      • في معالج الأخطاء لتطبيق العميل، قم بتنفيذ IF @@TRANCOUNT > 0 ROLLBACK TRAN بعد أي خطأ، حتى إذا كان تطبيق العميل لا يعتقد أن المعاملة مفتوحة. التحقق من وجود حركات مفتوحة مطلوب، لأن إجراء مخزن تم استدعاؤه أثناء الدفعة قد يكون بدأ معاملة دون مَعرفة تطبيق العميل. تمنع بعض الشروط، مثل إلغاء الاستعلام، تنفيذ الإجراء بعد العبارة الحالية، لذلك حتى إذا كان للإجراء منطق للتحقق IF @@ERROR <> 0 وإحباط المعاملة، فلن يتم تنفيذ التعليمة البرمجية للعودة إلى الحالة السابقة في مثل هذه الحالات.
      • إذا تم استخدام تجمع الاتصالات في تطبيق يفتح الاتصال ويقوم بتشغيل عدد صغير من الاستعلامات قبل تحرير الاتصال مرة أخرى إلى التجمع، مثل تطبيق مستند إلى الويب، فقد يساعد تعطيل تجمع الاتصالات مؤقتًا في تخفيف المشكلة حتى تطبيق العميل تم تعديله لمعالجة الأخطاء بشكل مناسب. من خلال تعطيل تجمع الاتصالات، سيؤدي تحرير الاتصال إلى قطع اتصال فعلي لاتصال قاعدة بيانات Azure SQL، مما يؤدي إلى تراجع الخادم عن أي معاملات مفتوحة.
      • استخدم SET XACT_ABORT ON للاتصال، أو في أي إجراءات مخزنة تبدأ المعاملات ولا يتم تنظيفها بعد حدوث خطأ. في حالة حدوث خطأ في وقت التشغيل، سيؤدي هذا الإعداد إلى إجهاض أي معاملات مفتوحة وإعادة التحكم إلى العميل. لمزيد من المعلومات، راجع SET XACT_ABORT (Transact-SQL).

    ملاحظة

    لا يتم إعادة تعيين الاتصال حتى يتم إعادة استخدامه من تجمع الاتصالات، لذلك من الممكن أن يقوم المستخدم بفتح معاملة ثم تحرير الاتصال بتجمع الاتصال، ولكن قد لا يتم إعادة استخدامه لعدة ثوانٍ، وخلال هذه الفترة يتم إجراء المعاملة ستبقى مفتوحة. إذا لم يتم إعادة استخدام الاتصال، فسيتم إلغاء المعاملة عند انتهاء مهلة الاتصال وإزالته من تجمع الاتصال. وبالتالي، فمن الأفضل لتطبيق العميل إجهاض المعاملات في معالج الأخطاء الخاص به أو استخدام SET XACT_ABORT ON لتجنب هذا التأخير المحتمل.

    تنبيه

    بعد SET XACT_ABORT ON، لن يتم تنفيذ جمل T-SQL التي تتبع عبارة تسبب خطأ. قد يؤثر هذا على التدفق المقصود من التعليمات البَرمجية الموجودة.

  3. سبب المنع هو SPID الذي لم يقم تطبيق العميل المطابق الخاص به بإحضار كافة صفوف النتائج حتى الاكتمال

    بعد إرسال استعلام إلى الخادم، يجب على جميع التطبيقات إحضار جميع صفوف النتائج على الفور حتى الاكتمال. إذا لم يجلب أحد التطبيقات جميع صفوف النتائج، فيمكن ترك الأقفال على الجداول، مما يؤدي إلى منع المستخدمين الآخرين. إذا كنت تستخدم تطبيقًا يرسل عبارات SQL بشفافية إلى الخادم، فيجب أن يجلب التطبيق جميع صفوف النتائج. إذا لم يحدث ذلك (وإذا تعذر تكوينه للقيام بذلك)، فقد لا تتمكن من حل مشكلة المنع. لتجنب المشكلة، يمكنك تقييد التطبيقات ذات السلوك السيئ إلى قاعدة بيانات لإعداد التقارير أو دعم القرار، منفصلة عن قاعدة بيانات OLTP الرئيسية.

    يتم تقليل تأثير هذا السيناريو عند تمكين قراءة النسخة المطابقة المثبتة في قاعدة البيانات، وهو التكوين الافتراضي في Azure SQL Database. تعرف على مزيد من المعلومات في قسم فهم المنع في هذه المقالة.

    ملاحظة

    راجع إرشادات منطق إعادة المحاولة للتطبيقات المتصلة بقاعدة بَيانات azure SQL.

    الدقة: يجب إعادة كتابة التطبيق لجلب جميع صفوف النتيجة حتى الاكتمال. هذا لا يستبعد استخدام OFFSET و FETCH في جملة ORDER BY من استعلام لتنفيذ ترحيل الصفحات من جانب الخَادم.

  4. المنع بسبب جلسة عمل في حالة العودة إلى الحالة السابقة

    العودة إلى الحالة السابقة بالنسبة لاستعلام تعديل البيانات الذي تم إيقافه أو إلغاؤه خارج المعاملة المحددة بواسطة المستخدم. يمكن أن يحدث هذا أيضًا كأثر جانبي لفصل جلسة شبكة العميل، أو عند تحديد طلب باعتباره ضحية حالة التوقف التام. يمكن تحديد ذلك غالبًا من خلال مراقبة إخراج sys.dm_exec_requests، والذي قد يشير إلى الأمر ROLLBACK، وقد يُظهر العمود percent_complete تقدمًا.

    بفضل ميزة استرداد قاعدة البيانات المتسارعة التي تم تقديمها في عام 2019، يجب أن تكون عمليات العودة إلى الحالة السابقة الطويلة نادرة.

    الدقة: انتظر حتى ينتهي SPID من التراجع عن التغييرات التي تم إجراؤها.

    لتجنب هذا الموقف، لا تقم بإجراء عمليات كتابة دفعة كبيرة أو إنشاء فهرس أو عمليات صيانة أثناء ساعات الانشغال على أنظمة OLTP. إذا أمكن، قم بإجراء مثل هذه العمليات خلال فترات النشاط المنخفض.

  5. المنع بسبب الاتصال المعزول

    إذا كان تطبيق العميل يعوض الأخطاء أو تم إعادة تشغيل محطة عمل العميل، فقد لا يتم إلغاء جلسة الشبكة إلى الخادم فورًا في ظل بعض الشروط. من منظور قاعدة بيانات Azure SQL، لا يزال يبدو أن العميل موجود، وقد يتم الاحتفاظ بأي تأمينات تم الحصول عليها. للحصول على مزيدٍ من المعلومات، راجع كيفية استكشاف أخطاء الاتصالات المعزولة وإصلاحها في SQL Server.

    الدقة: إذا تم قطع اتصال تطبيق العميل دون تنظيف موارده بشكل مناسب، يمكنك إنهاء SPID باستخدام الأمر KILL. يأخذ الأمر KILL قيمة SPID كإدخال. على سبيل المثال، لإلغاء SPID 99، قم بإصدار الأمر التالي:

    KILL 99
    

راجع أيضًا

الخطوات التالية