KB3067257 - تصحيح: نتائج جزئية في استعلام فهرس مخزن الأعمدة متفاوت المسافات في SQL Server 2014

ينطبق على
SQL Server 2014 Developer - duplicate (do not use) SQL Server 2014 Enterprise - duplicate (do not use) SQL Server 2014 Standard - duplicate (do not use)

تتناول هذه المقالة المشكلة التي تحدث أثناء استعلام فهرس Columnstore متفاوت المسافات في Microsoft SQL Server 2014. توفر هذه المقالة حلا لهذه المشكلة.

الملخص

عند استخدام استعلام يقوم بفحص فهرس مخزن أعمدة مجمع في Microsoft SQL Server 2014، قد تتلقى نتائج استعلام جزئية في حالات نادرة.

تحدث هذه المشكلة عند تشغيل العملية التالية.

الخطوة 1

تقوم جملة Transact-SQL [INSERT أو BULK-INSERT] بإدراج البيانات في جدول يحتوي على فهرس Columnstore متفاوت المسافات. أثناء هذه العملية، يتم تطبيق الشروط التالية:

  • عندما تصل عبارة Transact-SQL إلى حد مجموعة الصفوف، فإنها تغلق مجموعة الصفوف R1 التي تحتوي على المقطع S1.
  • يشير المقطع S1 إلى القاموس المحلي D1.
  • تستمر العبارة في إدراج صفوف إلى مجموعة صفوف جديدة R2.
  • عند إغلاق مجموعة الصف R1، لا يلزم أيضا إغلاق القاموس المحلي D1. إذا كانت القاموس D1 لا تزال به مساحة متوفرة، يمكنك تركه مفتوحا وإعادة استخدامه لمجموعة الصفوف الجديدة R2.

الخطوة 2

إذا تم إنهاء عبارة Transact-SQL بشكل غير طبيعي أو تم إلغاؤها قبل إغلاق مجموعة الصفوف الجديدة R2، فسيتم تطبيق الشروط التالية:

  • تحدث تغييرات بيانات تعريف Columnstore في المعاملات الفرعية التي يتم تنفيذها بشكل مستقل عن المعاملة الخارجية.
  • عند هذه النقطة، تستمر مجموعة الصف R1 في جدول النظام في حالة "تحت الإنشاء" أو غير مرئية، ويشير المقطع S1 إلى القاموس D1.
  • لم يتم إنشاء صف في جدول النظام للقاموس D1. وذلك لأن جملة Transact-SQL ليس لديها فرصة لإغلاق الصف الموجود. لذلك، يستمر الصف الموجود.

الخطوة 3

في حالة نموذجية، إذا بدأت مهمة خلفية المحرك بعد انتهاء عبارة Transact-SQL، فإن مهمة الخلفية تزيل مجموعة الصفوف غير المرئية R1 والمقطع S1. إذا تم بدء استخدام عبارة Transact-SQL جديدة الآن وأنشأت مجموعة صفوف R3 تحتوي على مقطع جديد S3 يتطلب قاموس محلي جديد، فلا يمكنك إعادة استخدام المعرف الداخلي للقاموس D1. وذلك لأن حالة ذاكرة متجر الأعمدة تتعقب معرفات القواميس المستخدمة. وبالتالي، سيشير المقطع S3 إلى القاموس الجديد D2.

ملاحظة: الشرط في هذه الخطوة هو شرط شائع. وبالتالي، لا يحدث أي تلف.

الخطوة 4

إذا فقد SQL Server حالة ذاكرة القاموس D1 قبل أن تدخل مهمة محرك المجموعة حيز التنفيذ (ونفذت كما هو موضح في الخطوة 3)، فستحدث المشكلة الموضحة في هذه المقالة.

ملاحظات

  • يقع هذا الحدث لأي من الأسباب التالية:

    • يواجه SQL Server التحميل الزائد للذاكرة، ويتم إخراج المحتويات الموجودة في الذاكرة في القاموس D1 من الذاكرة.
    • تتم إعادة تشغيل مثيل SQL Server.
    • تدخل قاعدة البيانات التي تحتوي على فهرس Columnstore متفاوت المسافات دون اتصال ثم تعود إلى الاتصال.
  • بعد وقوع أي من هذه الأحداث وقيام SQL Server بإعادة تحميل الهياكل الموجودة في الذاكرة، لا يوجد سجل يشير إلى وجود قاموس D1 والمعرف الداخلي الخاص به. وذلك لأنه لم يتم الاحتفاظ بالقاموس D1 في جداول النظام عند إنهاء عبارة Transact-SQL أو التنازل عنها.

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

  • إذا تم إنشاء مجموعة صفوف جديدة R3 قبل بدء مهمة خلفية محرك المجموعة (حسب عنصر التعداد النقطي السابق)، يقوم SQL Server بتعيين المعرف الداخلي نفسه للقاموس الجديد D1، ويشير إلى القاموس D1 للمقطع S3 في مجموعة الصفوف R3.

  • عندما تبدأ المهمة الخلفية لمحرك المجموعة بعد الإجراء السابق، فإنها تسقط مجموعة الصفوف غير المرئية R1 وقطعها S1 مع القاموس الجديد D1. يحدث ذلك لأن المحرك يعتبر أن القاموس الجديد D1 والقاموس الأصلي D1 الذي يشير إليه S1 هما القاموس نفسه.

    ملاحظة عند حدوث هذه الحالة، لا يمكنك الاستعلام عن محتويات مجموعة الصفوف R3.

الدقة

تم إصلاح المشكلة أولا في التحديثات التراكمية التالية ل SQL Server:

التحديث التراكمي 1 ل SQL Server 2014 SP1
        
         التحديث التراكمي 8 ل SQL Server 2014
تم تضمين تصحيح لهذه المشكلة أيضا في تحديثات إصدار التوزيع العام (GDR) التالية:

تحديث الأمان ل SQL Server 2014 QFE  
يتضمن هذا التحديث التحديث التراكمي 8 وهذا الإصلاح المهم وتحديثات الأمان MS15-058 المطلوبة.

تحديث الأمان ل SQL Server 2014 GDR  
يتضمن هذا التحديث هذا الإصلاح المهم وإصلاحات الأمان التراكمي من خلال MS15-058.

تحديث غير متعلق بالأمان ل SQL Server 2014 Service Pack 1 GDR  
يتضمن هذا التحديث هذا الإصلاح المهم فقط.

حول التحديثات التراكمية ل SQL Server

يحتوي كل تحديث تراكمي جديد ل SQL Server على جميع الإصلاحات العاجلة وجميع إصلاحات الأمان التي كانت مضمنة في التحديث التراكمي السابق. اطلع على آخر التحديثات التراكمية ل SQL Server:

      

المزيد من المعلومات

رسائل الخطأفي قاعدة البيانات المتأثرة حاليا، إذا قمت بتشغيل DBCC CHECKDB بعد تطبيق هذا التصحيح، فستتلقى رسالة الخطأ التالية:

ملاحظة

الرسالة 5289، المستوى 16، الحالة 1، السطر 1
يحتوي فهرس مخزن الأعمدة متفاوت المسافات 'cci' في الجدول 't' على قيمة بيانات واحدة أو أكثر لا تتطابق مع قيم البيانات الموجودة في القاموس. استعادة البيانات من نسخة احتياطية.

في قاعدة بيانات متأثرة حاليا، عندما تقوم بتشغيل استعلام يفحص الجداول المتأثرة بعد تطبيق هذا التصحيح، تتلقى رسالة الخطأ التالية:

ملاحظة

الرسالة 5288، المستوى 16، الحالة 1، السطر 1
يحتوي فهرس Columnstore على قيمة بيانات واحدة أو أكثر لا تتطابق مع قيم البيانات الموجودة في القاموس. الرجاء تشغيل DBCC CHECKDB لمزيد من المعلومات.

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

ملاحظة: يتم إنشاء رسالتي الخطأ 5288 و5289 لمجموعة الصفوف R3 هذه التي تتضمن المقطع S3. يتم استخدام علامة التتبع 10207 لاستخراج مقاطع مجموعة الصفوف R3 التي لا تتأثر بالقاموس D1 المفقود.

الاستعلام عن قواعد البيانات المتأثرةلتحديد ما إذا كانت قاعدة البيانات التي تحتوي على فهارس columnstore متأثرة بالفعل بهذه المشكلة، قم بتشغيل الاستعلام التالي:

select  
       object_name(i.object_id) as table_name, 
       i.name as index_name, 
       p.partition_number, 
       count(distinct s.segment_id) as damaged_rowgroups 
from 
       sys.indexes i 
       join sys.partitions p on p.object_id = i.object_id and p.index_id = i.index_id 
       join sys.column_store_row_groups g on g.object_id = i.object_id and g.index_id = i.index_id and g.partition_number = p.partition_number 
       join sys.column_store_segments s on s.partition_id = p.partition_id and s.segment_id = g.row_group_id 
where  
       i.type in (5, 6) 
       and s.secondary_dictionary_id <> -1  
       and g.state_description = 'COMPRESSED' 
       and s.secondary_dictionary_id not in 
       ( 
              select dictionary_id from sys.column_store_dictionaries d 
              where d.hobt_id = p.hobt_id and d.column_id = s.column_id 
       ) 
group by  
       object_name(i.object_id), 
       i.name, 
       p.partition_number 

ملاحظات

  • يجب تشغيل هذا الاستعلام مقابل كل قاعدة بيانات تحتوي على فهارس columnstore على الخادم الذي يقوم بتشغيل SQL Server. تشير مجموعة النتائج الفارغة إلى أن قاعدة البيانات غير متأثرة.

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

    قبل تنفيذ الاستعلام، يمكنك تعطيل مهمة محرك مجموعة الخلفية باستخدام علامة التتبع 634. استخدم هذا الأمر لتعطيل مهمة الخلفية: DBCC TRACEON ( 634 ، -1 ). بعد الانتهاء من تنفيذ الاستعلام، تذكر إعادة تمكين المهمة الخلفية باستخدام الأمر: DBCC TRACEOFF ( 634 , -1 ).

    تأكد أيضا من عدم وجود أوامر BULK INSERT/BCP/SELECT-INTO لإدراج البيانات في الجداول التي تستخدم فهرس Columnstore أثناء تشغيل هذا الاستعلام.

    يوصى باستخدام هذه الخطوات لمنع الاستعلام من إرجاع النتائج الخاطئة.

الحالة

لقد أكدت Microsoft على أن هذه مشكلة في منتجات Microsoft المُدرجة في القسم "ينطبق على".