INF: تحليل و تجنب Deadlocks في SQL Server

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

اضغط هنا لرابط المقالة باللغة الانجليزية169960
تمت أرشفة هذه المقالة. وتظهر "كما هي" ولن يتم تحديثها بعد الآن.
الموجز
يحتفظ Microsoft SQL Server تناسق قاعدة البيانات وتكامل المعاملات بواسطة استخدام التأمين. الإصدار 6.5 من SQL Server بشكل اختياري يستخدم التأمين على مستوى الصف لعمليات الإدراج ويستخدم التأمين على مستوى الصفحة للحصول على عمليات أخرى. كما هو الحال مع أي نظام قاعدة بيانات علائقية تأمين قد يؤدي إلى deadlocks بين المستخدمين.

على سبيل المثال، بفرض المستخدم1 (أو Connection1) لديه تأمين على البيانات العنصر "A" ويريد تأمين على عنصر بيانات "ب" لديه تأمين على عنصر بيانات "B" User2 ويريد تأمين على عنصر بيانات "أ" الآن في هذا السيناريو SQL Server المستخدم1 أو User2 يكون الضحية حالة توقف تام ثم سيتم منح التأمين المطلوب المستخدم الآخر.

في SQL Server، يمكن تحديد مطور التطبيق الاتصال الذي سيتم الترشيح الضحية حالة توقف تام باستخدام DEADLOCK_PRIORITY SET. إذا لم المطور تعيين أولوية deadlocks, يحدد SQL Server الضحية حالة توقف تام عن طريق اختيار عملية إكمال سلسلة دائرية التأمينات.

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

يتم إرسال نتائج التتبع إلى إطار وحدة التحكم إلا إذا تم تعيين إشارة تتبع T3605 ، التي ترسل إخراج التتبع إلى سجل الأخطاء.

قد تحدث deadlocks اتصالين تحديث الجداول في ترتيب عكسي. على سبيل المثال، اتصال واحد إدراج في جدول "example1" أولاً ثم إلى "example2" أثناء إدراج اتصال آخر في جدول "example2" أولاً ثم إلى "example1" داخل معاملة. سيناريو مثال مفيداً لتوضيح كيفية تجنب deadlocks.

فيما يلي عبارات SQL المستخدمة في إنشاء جدول المستخدمة في هذا المثال:
   create table example1 (column1 int, column2 char(20), column3 char(50))   go   create table example2 (column1 int, column2 char(20), column3 char(50))   go   declare @lvar int   select @lvar = 0   while @lvar < 500   begin   insert into example1 values (@lvar, 'AAA', 'CCC')   insert into example2 values (@lvar, 'AAA', 'CCC')   select @lvar = @lvar + 1   end   go   create unique clustered index ex1ind1 on example1 (column1, column2)   with fill factor = 90, PAD_INDEX   go   create unique clustered index ex2ind1 on example2 (column1, column2)   with fill factor = 90, PAD_INDEX   go				

مثال 1: عمليات إدراج جدول في ترتيب عكسي

في هذا المثال، تم إدراجها جدولين بالترتيب المعاكس ثم حدث حالة توقف تام. يمكن أيضاً أن تحدث deadlocks عند جهازي أو مزيد من الاتصالات تنفيذ تحديثات أو حذف على جداول بالترتيب المعاكس.
   Connection1 > BEGIN TRANSACTION   Connection2 > BEGIN TRANSACTION   Connection1 > INSERT INTO example1 VALUES (100, 'AAAA', 'CCC')   Connection2 > INSERT INTO example2 VALUES (200, 'AAAB', 'CCC')   Connection2 > INSERT INTO example1 VALUES (200, 'AAAB', 'CCC')				

في هذه المرحلة، قد يمنع Connection1 Connection2 لأنه قد يكون صف إدراج Connection2 على نفس الصفحة حيث Connection1 لقد مسبقاً إدراج صف و الضغط تأمين.
   Connection1 > INSERT INTO example2 VALUES (100, 'AAAA', 'CCC')				

في هذه المرحلة، قد يمنع Connection2 Connection1 ، لأنه قد يكون صف إدراج Connection1 على نفس الصفحة حيث تم مسبقاً إدراج صف Connection2 و تحتضن تأمين. ويتسبب هذا في حالة توقف تام.

التالي هو الإخراج إشارة تتبع 1204 حدث في حالة توقف تام:
97/04/20 11:51:57.88 spid13   *** DEADLOCK DETECTED with spid 14 ***   spid 13 requesting EX_PAGE (waittype 0x8005), blocked by:     EX_PAGE: spid 14, dbid 6, page 0x188, table example2, indid 0x1     pcurcmd INSERT(0xc3), input buffer: INSERT INTO example2 VALUES (100,     'AAAA', 'CCC')   spid 14 waiting for EX_PAGE (waittype 0x8005), blocked by:     EX_PAGE: spid 13, dbid 6, page 0x180, table example1, indid 0x1     pcurcmd INSERT(0xc3), input buffer: INSERT INTO example1 VALUES (200,   'AAAB', 'CCC')   VICTIM: spid 13, pstat 0x0000 , cputime 30				

يمكن لكل سطر من تتبع حالة توقف تام أخبر المستخدمين المزيد حول حالة توقف تام. Connection1 spid 13 وهو Connection2 spid 14 (يمكنك تحديد spid المقترنة اتصال باستخدام إجراء النظام المخزن sp_who).
   >> 97/04/20 11:51:57.88 spid13   *** DEADLOCK DETECTED with spid 14 ***   The deadlock was detected between spid 13 and spid 14.   >> spid 13 requesting EX_PAGE (waittype 0x8005), blocked by:   >>   EX_PAGE: spid 14, dbid 6, page 0x188, table example2, indid 0x1   >>   pcurcmd INSERT(0xc3), input buffer: INSERT INTO example2 VALUES   (100, 'AAAA', 'CCC')				

تم طلب تأمين EX_PAGE 13 Spid ثم تم حظر قبل spid 14, الذي بالفعل تأمين EX_PAGE صفحة 0x188 على example2 الجدول في dbid 6. يتم تعليق التأمين على الصفحة التي تنتمي إلى فهرس متفاوت المسافات.
      Indid Value         Description-------------------------------------         0                Data page if there is no clustered index, or the                          leaf page of a clustered index if there is one         1                Non-leaf page of the clustered index page       255                Text/image page    Any other value       Non-clustered secondary index				

يتم تنفيذها بواسطة spid 13 في الأمر الحالي INSERT وإعطاء التتبع جزء من مخزن الإدخال المؤقت.
   >> spid 14 waiting for EX_PAGE (waittype 0x8005), blocked by:   >>   EX_PAGE: spid 13, dbid 6, page 0x180, table example1, indid 0x1   >>   pcurcmd INSERT(0xc3), input buffer: INSERT INTO example1 VALUES   (200, 'AAAB', 'CCC')				

14 Spid بانتظار تأمين EX_PAGE و حظر بواسطة spid 13, التي تتضمن تأمين EX_PAGE بالفعل على نفس الصفحة.
   >> VICTIM: spid 13, pstat 0x0000 , cputime 30   SQL Server has chosen spid 13 as the deadlock victim.				

التالي شرح ماذا تعني تأمين المختلفة في التتبع:

SH_INT و EX_INT
تأمين هدف يتم أخذ على عنصر المستوى أعلى (على سبيل المثال، جدول) قبل تأمين المستوى الأدنى (على سبيل المثال، صفحة) يمكنك أخذه ، لأن إدارة تأمين معرفة بأي من العلاقة بين أنواع مختلفة من العناصر (في هذه الحالة, الصفحات والجداول). إذا تم تأمين EX_INT من التقاط لا على الجدول قبل اتخاذ تأمين EX_PAG على الصفحات مستخدم آخر الحصول على تأمين EX_TAB في نفس الجدول ثم قد لا تعرف مدير تأمين وجود تعارض. حالياً، له SQL Server تأمين هدف فقط على الجداول. هناك نوعان من تأمين هدف: تأمين حصري (EX_INT) "و" مشترك (SH_INT).

ex_page
هذا هو تأمين صفحة خاص تؤخذ عند تحديث صفحة تبعاً DELETE UPDATE, أو إدخال عبارة INSERT مع تأمين مستوى الصفوف (IRL) تعطيل.

up_page
هذا هو تأمين صفحة تحديث التي تم التقاطها بدلاً من تأمين الصفحة المشتركة عند فحص صفحة للمحسن يعرف سيتم تحديث الصفحة (أو استخدام تلميح UPDLOCK).

PR_EXT و NX_EXT UPD_EXT و EX_EXT
يتم أخذ هذه التأمينات عند تخصيص أو إلغاء تخصيص مساحة القرص. تؤخذ UPD_EXT عند تخصيص أو إلغاء تخصيص صفحة من مدى موجودة وتستخدم الأخرى عند تخصيص أو إلغاء تخصيص نطاقات بأكمله.

IX_PAGE و LN_PAGE
هذه هي IRL التأمين. IX_PAGE تأمين هدف - إلى - - الصف - التأمين على صفحة. يتم أخذ LN_PAGE عند الصفحة الذي IRL كان يتم تنفيذه احتياجات يمكن تقسيم.

RLOCK و XRLOCK
يتم أخذ هذه تأمين قصيرة الأجل عند العبور b فهرس - شجرة. هناك نوعين من هذا النوع من تأمين: المشترك (RLOCK) و حصري (XRLOCK). يتم أخذ تأمين المشتركة أثناء الفحص, بينما يتم التقاطها عمليات التأمين الحصري على صفحات فهرس أثناء تحديث.

ex_tab
هذا هو تأمين جدول خاص يحدث عندما يحدد للمحسن ملقم SQL أن تفحص جدول هو الطريقة الأكثر كفاءة على حل استعلام تحديث (على سبيل المثال، عند وجود لم فهارس في جدول). تظهر عمليات التأمين EX_TAB أيضاً عند تأمين الجدول مع تلميح TABLOCKX أو SQL Server escalates تأمين الصفحة على جدول إلى تأمين جدول.

sh_tab
هذا هو المشتركة سيتم تفحص تأمين الجدول المستخدم عند للمحسن تفترض أن معظم الجدول (أو تأمين الصفحة escalates) أو يتم استخدام تلميح TABLOCK.

يمكن أن يتم تجنب المثال حالة توقف تام السابق إذا بتحديث الاتصالات بين الجداول في التسلسل التالي:
   Connection1 > BEGIN TRANSACTION   Connection2 > BEGIN TRANSACTION   Connection1 > INSERT INTO example1 VALUES (100, 'AAAA', 'CCC')   Connection2 > INSERT INTO example1 VALUES (200, 'AAAB', 'CCC')   Connection2 > INSERT INTO example2 VALUES (200, 'AAAB', 'CCC')   Connection1 > INSERT INTO example2 VALUES (100, 'AAAA', 'CCC')				

مثال 2: عمليات الإدراج إلى أجزاء مختلفة من نفس الجدول

يمكن أن يحدث هذا حالة توقف تام أيضاً عند إدراج اتصالين في أجزاء مختلفة من نفس الجدول بالترتيب المعاكس عند مشاركة صفوف الصفحات. على سبيل المثال:
   Connection1 > BEGIN TRANSACTION   Connection2 > BEGIN TRANSACTION   Connection1 > INSERT INTO example1 VALUES (100, 'AAAA', 'CCC')   Connection2 > INSERT INTO example1 VALUES (400, 'AAAB', 'CCC')   Connection1 > INSERT INTO example1 VALUES (400, 'AAAA', 'CCC')				

في هذا المثال الجدول، يوجد فهرس متفاوت المسافات على العمود الأول من الجدول example1. سوف تميل الصفوف بنفس قيم للعمود الأول إلى تقع في نفس الصفحة. في المثال، الصف الثاني المدرج بواسطة Connection1 سوف المحتمل أن تقع على نفس الصفحة مثل الصف الأول المدرج بواسطة Connection2 ، لأن كلا لديهم قيمة فهرس متفاوت المسافات من 400. يؤدي هذا Connection2 إلى كتلة Connection1.
   Connection2 > INSERT INTO example1 VALUES (100, 'AAAB', 'CCC')				

الآن Connection2 فقد أيضاً يكون قد تم حظره بواسطة Connection1 تصل إلى حالة توقف تام. التالي هو تتبع حالة توقف تام:
   97/04/20 12:56:01.40 spid16   *** DEADLOCK DETECTED with spid 15 ***   spid 16 requesting EX_PAGE (waittype 0x8005), blocked by:     EX_PAGE: spid 15, dbid 6, page 0x2c5, table example1, indid 0     pcurcmd INSERT(0xc3), input buffer: INSERT INTO example1 VALUES (100,   'AAAB', 'CCC')   spid 15 waiting for EX_PAGE (waittype 0x8005), blocked by:     EX_PAGE: spid 16, dbid 6, page 0x8bd, table example1, indid 0     pcurcmd INSERT(0xc3), input buffer: INSERT INTO example1 VALUES (400,   'AAAA', 'CCC')   VICTIM: spid 16, pstat 0x0000 , cputime 130				

تم منع طلب spid 16 تأمين EX_PAGE لصفحة 0x2c5 قبل spid 15, التي تتضمن تأمين EX_PAGE لصفحة 0x2c5 مسبقاً بعد ظهر إدراج الأول. ثم الحصول على حظر spid 15 أيضاً بواسطة spid 16 في انتظار تأمين EX_PAGE بادئة الصفحة 0x8db إلى حالة توقف تام.

يمكن أن يتم تجنب هذا حالة توقف تام باستخدام الأمر التالي لتمكين IRL example1 الجدول:
   sp_tableoption 'example1', 'insert row lock', true				

مثال 3: عمليات الإدراج استخدام IRL

يسمح IRL للمستخدمين اثنين أو أكثر من مشاركة صفحة عند فقط إدراج عمليات الذي ينتج عادةً الإنتاجية بشكل أفضل. ومع ذلك، تمكين IRL لا دوماً سيقلل deadlocks. في بعض الحالات، قد يقدم IRL deadlocks.
   Connection1 > BEGIN TRANSACTION   Connection2 > BEGIN TRANSACTION   Connection1 > INSERT INTO example1 VALUES (100, 'AAAA', 'CCC')   Connection2 > INSERT INTO example1 VALUES (105, 'AAAB', 'CCC')				

مع تمكين IRL ، كلا اتصالات سيحتوي على تأمين IX_PAGE على الصفحة التي تحتوي على صفين جديد. إذا تم تعطيل IRL Connection1 تم الحصول على تأمين EX_PAGE ثم Connection2 قد تم حظر فوراً.
   Connection2 > UPDATE example1 SET column3 = 'CCCB' where column1 = 105   and column2 = 'AAAB'				

عند هذه النقطة، يحتاج Connection2 على تأمين صفحة خاص للقيام عبارة UPDATE غير متوافقة مع تأمين IX_PAGE الخاص Connection1. لذلك، ينتظر Connection2.
   Connection1 > UPDATE example1 SET column3 = 'CCCA' where column1 = 100   and column2 = 'AAAA'				

الآن Connection1 فقد يكون قد تم حظره بواسطة Connection2 تصل إلى حالة توقف تام. التالي هو تتبع حالة توقف تام:
   97/04/20 15:13:50.07 spid17   *** DEADLOCK DETECTED with spid 18 ***   spid 17 requesting UP_PAGE (waittype 0x8007), blocked by:     IX_PAGE: spid 18, dbid 6, page 0x2c5, table example1, indid 0     pcurcmd UPDATE(0xc5), input buffer: UPDATE example1 SET column3 =   'CCCA' where column1 = 100 and column2 = 'AAAA'   spid 18 waiting for UP_PAGE (waittype 0x8007), blocked by:     IX_PAGE: spid 17, dbid 6, page 0x2c5, table example1, indid 0     pcurcmd UPDATE(0xc5), input buffer: UPDATE example1 SET column3 =   'CCCB' where column1 = 105 and column2 = 'AAAB'   VICTIM: spid 17, pstat 0x0000 , cputime 20				

قيد انتظار 17 Spid (اتصال أحد) تأمين UP_PAGE والذي هو الخطوة الأولى إلى الحصول على تأمين صفحة خاص. تم الآن منع قبل spid 18 ، التي تتضمن تأمين IX_PAGE على الصفحة 0x2c5. 18 Spid بانتظار تأمين UP_PAGE على نفس الصفحة و حظر بواسطة تأمين IX_PAGE يتضمنها spid 17. ويوجهنا ذلك إلى حالة توقف تام لأن تأمين IX_PAGE غير قابل للمشاركة ، بينما لم يكن UP_LOCK. أثناء إدراج الأول كل spids الحصول على تأمين IX_PAGE على نفس الصفحة و فيما بعد قيامهم حاولت الترقية التأمين إلى تأمين UP_PAGE غير ممكن بسبب تأمين UP_PAGE خاص.

إحدى طرق تجنب في حالة توقف تام في إدراج القيمة التي تم تحديثها مباشرة في جدول بدلاً من إدراج وتحديث الصف في المعاملة نفسها. إذا لم يكن هذا ممكن, باستخدام الأمر التالي لتعطيل IRL تساعد لتجنب حالة توقف تام:
   sp_tableoption 'example1', 'insert row lock', false				

مثال 4: عمليات الإدراج إلى الصفوف الموجودة على نفس صفحة

أيضاً قد يؤدي حالة توقف تام عند الصفوف العمل spids اثنين على مختلفة ولكن تنتمي إلى نفس الصفحة.
   Connection1 > BEGIN TRANSACTION   Connection2 > BEGIN TRANSACTION   Connection1 > INSERT INTO example1 VALUES (100, 'AAAA', 'CCC')   Connection2 > INSERT INTO example1 VALUES (400, 'AAAB', 'CCC')   Connection1 > UPDATE example1 SET column3 = 'CCCA' where column1 = 405   and column2 = 'AAAA'				

في هذه المرحلة، Connection1 فقد يكون قد تم حظره بواسطة Connection2. قد يحدث هذا الموقف بسبب يريد Connection1 بتحديث صف في صفحة حيث تحتوي Connection2 إدراج صف لها بالفعل.
   Connection2 > UPDATE example1 SET column3 = 'CCCB' where column1 = 105   and column2 = 'AAAB'				

في هذه المرحلة، Connection2 فقد أيضاً يكون قد تم حظره بواسطة Connection1 سوف يؤدي إلى حالة توقف تام. قد يحدث هذا الموقف عندما يرغب Connection2 بتحديث صف في صفحة حيث تحتوي Connection1 إدراج صف. التالي هو تتبع حالة توقف تام:
   97/04/20 15:48:21.18 spid20   *** DEADLOCK DETECTED with spid 19 ***   spid 20 requesting UP_PAGE (waittype 0x8007), blocked by:     EX_PAGE: spid 19, dbid 6, page 0x2c4, table example1, indid 0     pcurcmd UPDATE(0xc5), input buffer: UPDATE example1 SET column3 =   'CCCB' where column1 = 105 and column2 = 'AAAB'   spid 19 waiting for UP_PAGE (waittype 0x8007), blocked by:     EX_PAGE: spid 20, dbid 6, page 0xc48, table example1, indid 0     pcurcmd UPDATE(0xc5), input buffer: UPDATE example1 SET column3 =   'CCCA' where column1 = 405 and column2 = 'AAAA'   VICTIM: spid 20, pstat 0x0000 , cputime 60				

يمكن أن يتم تجنب هذا حالة توقف تام بواسطة الانتشار خارج الصفوف على صفحات مختلفة. أسلوب واحد للقيام بذلك هي إعادة إنشاء فهرس متفاوت المسافات في هذا الجدول مع عامل تعبئة كبيرة. التالي هو عبارة إنشاء فهرس متفاوت المسافات مع عامل تعبئة لـ 50 في المائة:
   create unique clustered index ex1ind1 on example1 (column1, column2)   with fill factor = 50, PAD_INDEX				

بيان الخصوصية هذا إلى إنشاء فهرس متفاوت المسافات ترك نصف الصفحات الفارغة بما فيها المستويات غير طرفية فهرس متفاوت المسافات (لوجود خيار PAD_INDEX). الجدول يحتل الحجم الفعلي مزدوج وتكون عدد الصفوف لكل صفحة نصف التي كانت.

لا يتم الاحتفاظ عامل التعبئة على جدول; re-organized مع عامل التعبئة المحدد الجدول فقط أثناء إنشاء الفهرس. مع مرور الوقت، سيتم تغيير الصفوف لكل صفحة من عامل التعبئة المحدد أثناء إنشاء الفهرس. عند حدوث ذلك، قد يكون المستحسن إعادة إنشاء فهرس متفاوت المسافات مع عامل التعبئة المطلوب.

يتم حل آخر تجنب الموقف حالة توقف تام السابقة في لوح الجدول مع الأعمدة وهمية (على سبيل المثال، char(255)) dummy1. هذا يؤدي إلى زيادة حجم الصف كما يؤدي إلى صفوف أقل لكل صفحة (القليل صف واحد لكل صفحة). بسبب هذا النوع من الحشو بمرور الوقت لا تحتاج إلى إعادة إنشاء فهرس متفاوت المسافات للاحتفاظ الحشو (رغم أن ذلك قد تحتاج إلى إعادة إنشاء فهرس متفاوت المسافات لأسباب أخرى). عيوب هذا الأسلوب غير الضائعة مساحة التخزين على حقول وهمية.

على سبيل المثال 5: البادئة الصفوف

نطاق الصفوف يؤدي إلى صفوف أقل لكل صفحة (وبالتالي deadlocks أقل) ، إلا أنه سوف لا بالكامل التخلص deadlocks.

في هذا المثال الجدول، يتم تعبئة example1 ليشغل صف واحد لكل صفحة. فيما يلي عبارات المستخدم في إنشاء الجدول من أجل هذا المثال:
   create table example1 (column1 int, column2 char(20), column3 char(50),   dummy_column4 char (255), dummy_column5 char (255), dummy_column6 char   (255))   go   create unique index ex1ind5 on example1 (column3, column2, column1,   dummy_column4, dummy_column5, dummy_column6) with fill factor = 85   go   Connection1 > BEGIN TRANSACTION   Connection2 > BEGIN TRANSACTION   Connection1 > INSERT INTO example1 VALUES (100, 'AAAA', 'CCC', ' ', ' ',   ' ', ' ')   Connection2 > INSERT INTO example1 VALUES (400, 'AAAB', 'CCC', ' ', ' ',   ' ', ' ')   Connection1 > UPDATE example1 SET column3 = 'CCCA' where column1 = 401   and column2 = 'AAAA'				

عند هذه النقطة، يتم حظر Connection1 بواسطة Connection2 أثناء تحديث الصف. لأنه يجب أن SQL Server من المحافظة على مؤشرات سلسلة صفحة تأمين الصفحة السابقة "و" الصفحة التالية "و" صفحة الذي يتم تحديثه. لأن يحتفظ Connection2 تأمين على الصفحة السابقة "، يجب الانتظار Connection1 حتى Connection2 تحويل المعاملة.
   Connection2 > UPDATE example1 SET column3 = 'CCCB' where column1 = 101   and column2 = 'AAAB'				

عند هذه النقطة، يتم حظر Connection2 بواسطة Connection1 لأنه يجب تأمين الصفحة السابقة التي تم التأمين حالياً من قبل Connection1. تكون النتيجة حالة توقف تام. التالي هو تتبع حالة توقف تام:
   spid 20 requesting UP_PAGE (waittype 0x8007), blocked by:     EX_PAGE: spid 19, dbid 6, page 0x12b5, table example1, indid 0     pcurcmd UPDATE(0xc5), input buffer: UPDATE example1 SET column3 =   'CCCB' where column1 = 101 and column2 = 'AAAB'   spid 19 waiting for UP_PAGE (waittype 0x8007), blocked by:     EX_PAGE: spid 20, dbid 6, page 0x1531, table example1, indid 0     pcurcmd UPDATE(0xc5), input buffer: UPDATE example1 SET column3 =   'CCCA' where column1 = 401 and column2 = 'AAAA'   VICTIM: spid 20, pstat 0x0000 , cputime 300				

يمكن أن يتم تجنب هذا حالة توقف تام عن طريق إدراج صفوف وهمية بين الصفوف التي يتم إدراج ، تحديثها أو حذفها. على سبيل المثال، إذا كانت تعمل Connection1 (إدراج أو تحديثات أو الحذف) باستخدام pk الصف = 1 و Connection2 يعمل مع pk الصف = 5 إدراج صف بين صفين هذه (مثل صف يحتوي على pk = 3) سوف تجنب deadlocks. هذا الأسلوب أيضًا تكبير حجم الجدول ولكن قد يكون أفضل حل هذه الجداول قائمة انتظار الهامة إلى التطبيق.

مثال 6: فهارس Nonclustered

في بعض الحالات، قد يقدم فهارس غير متفاوتة المسافات الثانوي deadlocks. في هذا المثال، يقدم الصيانة فهرس الثانوي حالة توقف تام.

التالي هو عبارة المستخدمة في إنشاء الفهرس الثانوي المستخدم في هذا المثال:
   create index ex1ind2 on example1 (column3) with fill factor = 90,   PAD_INDEX   Connection1 > BEGIN TRANSACTION   Connection2 > BEGIN TRANSACTION   Connection1 > INSERT INTO example1 VALUES (100, 'AAAA', 'CCBA', ' ', '   ', ' ', ' ')   Connection2 > INSERT INTO example1 VALUES (300, 'AAAB', 'CCCZ', ' ', '   ', ' ', ' ')   Connection2 > UPDATE example1 SET column3 = 'CCBA' where column1 = 105				

في هذه المرحلة، Connection2 فقد يكون قد تم حظره بواسطة Connection1 لأن Connection1 قد تكون الضغط تأمين في صفحة الفهرس غير متفاوت الثانوي حيث Connection2 يحتاج إلى تحديث.
   Connection1 > UPDATE example1 SET column3 = 'CCCZ' where column1 = 305				

في هذه المرحلة، Connection1 فقد يكون قد تم حظره بواسطة Connection2 الناتجة في حالة توقف تام. يمكن أن يحدث هذا الموقف عند انتظار Connection1 تأمين لتحديث غير متفاوتة المسافات الثانوي الفهرس حيث قد أدرجت مسبقاً Connection2 و يحتفظ تأمين على تلك الصفحة. التالي هو تتبع حالة توقف تام للحصول على هذا المثال حالة توقف تام:
   97/04/20 19:05:38.75 spid11   *** DEADLOCK DETECTED with spid 12 ***   spid 11 requesting EX_PAGE (waittype 0x8005), blocked by:     EX_PAGE: spid 12, dbid 6, page 0x112f, table example1, indid 0x2     pcurcmd UPDATE(0xc5), input buffer: UPDATE example1 SET column3 =   'CCCZ' where column1 = 305   spid 12 waiting for EX_PAGE (waittype 0x8005), blocked by:     EX_PAGE: spid 11, dbid 6, page 0x1108, table example1, indid 0x2     pcurcmd UPDATE(0xc5), input buffer: UPDATE example1 SET column3 =   'CCBA' where column1 = 105   VICTIM: spid 11, pstat 0x0000 , cputime 50				

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

قد تحدث deadlocks مع اتصالات أكثر من جهازي وفي هذه الحالة يسرد تتبع حالة توقف تام spids المتضمنة في حالة توقف تام في وأيضاً تأمين المتعارضة. قد تحدث deadlocks مع عمليات التأمين RLOCK و XRLOCK التي حصلت أثناء العبور الفهرس. قد تحدث deadlocks أيضاً بسبب تأمين النطاق (PR_EXT NX_EXT ، UPD_EXT & EX_EXT).

للحصول على معلومات إضافية حول تحليل deadlocks يمكنك تمكين العلامات التتبع التالية:

t1200
طباعة كافة معلومات الطلب/تحرير التأمين عند حدوث ذلك، ما إذا كانت حالة توقف تام الموجود أم لا. هذا تكلفة من أداء ولكن يمكن أن يكون مفيداً من أجل التحليل.

t1206
طباعة كافة التأمينات التي تم إجراؤها من قبل spids المشاركة في حالة توقف تام.

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

تحذير: تمت ترجمة هذه المقالة تلقائيًا

خصائص

رقم الموضوع: 169960 - آخر مراجعة: 12/04/2015 17:12:21 - المراجعة: 3.0

Microsoft SQL Server 6.5 Standard Edition

  • kbnosurvey kbarchive kbmt kbhowto kbusage KB169960 KbMtar
تعليقات