บทความนี้จะอธิบายปัญหาที่เกิดขึ้นระหว่างคิวรีของดัชนีคลัสเตอร์ columnstore ใน Microsoft SQL Server ๒๐๑๔ บทความนี้จะมี วิธีแก้ไข ปัญหานี้
สรุป
เมื่อคุณใช้คิวรีที่สแกนดัชนีคลัสเตอร์ columnstore ใน Microsoft SQL Server ๒๐๑๔คุณอาจอยู่ภายใต้เงื่อนไขที่ไม่ค่อยได้รับผลลัพธ์ของคิวรีบางส่วน ปัญหานี้เกิดขึ้นเมื่อมีการเรียกใช้การดำเนินการต่อไปนี้
ขั้นตอนที่1
คำสั่ง Transact SQL [แทรกหรือแทรกเป็นกลุ่ม] จะแทรกข้อมูลลงในตารางที่มีดัชนีคลัสเตอร์ columnstore ในระหว่างการดำเนินการนี้เงื่อนไขต่อไปนี้จะนำไปใช้:
-
เมื่อคำสั่ง Transact SQL ถึงเกณฑ์ rowgroup จะปิด rowgroup R1 ที่มีเซกเมนต์ S1
-
ส่วนของ S1 point ไปยังพจนานุกรมภายในเครื่อง D1
-
คำสั่งยังคงแทรกแถวไปยังใหม่ rowgroup R2
-
เมื่อ rowgroup R1 ปิดอยู่จะไม่มีการปิดพจนานุกรมภายในเครื่อง D1 ถ้าพจนานุกรม D1 ยังมีช่องว่างที่พร้อมใช้งานคุณสามารถเปิดใช้งานและนำไปใช้ใหม่สำหรับ rowgroup R2 ใหม่ได้
ขั้นตอนที่2
ถ้าคำสั่ง Transact SQL สิ้นสุดลงอย่างผิดปกติหรือถูกยกเลิกก่อนที่จะปิดใหม่ rowgroup R2 เงื่อนไขต่อไปนี้จะนำไปใช้:
-
การเปลี่ยนแปลง metadata ของ Columnstore เกิดขึ้นในย่อยที่ยอมรับได้อย่างอิสระจากทรานแซคชันภายนอก
-
ณจุดนี้ rowgroup R1 จะยังคงอยู่ในตารางระบบใน "ภายใต้การก่อสร้าง" หรือสถานะที่มองไม่เห็นและการอ้างอิงถึงส่วนของการอ้างอิง S1
-
ไม่มีแถวที่สร้างขึ้นในตารางระบบสำหรับพจนานุกรม D1 นี่คือเนื่องจากคำสั่ง Transact SQL ไม่มีโอกาสในการปิดแถวที่มีอยู่ ดังนั้นแถวที่มีอยู่จะยังคงอยู่
ขั้นตอนที่3
ในสถานการณ์ปกติถ้างานพื้นหลังของทูเปิลผู้นำเสนอจะเริ่มต้นหลังคำสั่ง Transact SQL สิ้นสุดแล้วงานพื้นหลังจะเอาออก rowgroup R1 ที่มองไม่เห็นและเซกเมนต์ S1 ถ้ามีการเริ่มคำสั่ง Transact SQL ใหม่ในตอนนี้และสร้าง rowgroup R3 ที่มีการตั้งค่าใหม่ที่จำเป็นต้องใช้พจนานุกรมภายในเครื่องใหม่คุณจะไม่สามารถนำรหัสภายในของพจนานุกรม D1 มาใช้ใหม่ได้ นี่คือเนื่องจากสถานะในหน่วยความจำของ columnstore คอยติดตาม Id ของพจนานุกรมที่ใช้งานอยู่ ดังนั้นส่วนที่ S3 จะอ้างอิงพจนานุกรมใหม่ D2หมายเหตุ เงื่อนไขในขั้นตอนนี้เป็นเงื่อนไขทั่วไป ดังนั้นจึงไม่มีการทุจริตเกิดขึ้น
ขั้นตอนที่4
ถ้า SQL Server สูญเสียสถานะในหน่วยความจำของพจนานุกรม D1 ก่อนที่งานของผู้นำเสนอทูเปิลจะมีผลบังคับใช้ (และดำเนินการตามที่อธิบายไว้ในขั้นตอนที่ 3) ปัญหาที่อธิบายไว้ในบทความนี้เกิดขึ้นหมายเหตุ
-
เหตุการณ์นี้เกิดขึ้นเนื่องจากสาเหตุใดสาเหตุหนึ่งต่อไปนี้:
-
SQL Server ประสบการณ์การใช้งานหน่วยความจำเกินและเนื้อหาในหน่วยความจำของพจนานุกรม D1 คือเอาจากหน่วยความจำ
-
อินสแตนซ์ของ SQL Server ถูกเริ่มใหม่
-
ฐานข้อมูลที่มีดัชนีคลัสเตอร์ columnstore ไปแบบออฟไลน์แล้วกลับมาออนไลน์
-
-
หลังจากที่เหตุการณ์ใดเหตุการณ์หนึ่งเหล่านี้เกิดขึ้นและ SQL Server reloads โครงสร้างในหน่วยความจำจะไม่มีระเบียนที่มีการใช้งานในพจนานุกรม D1 และ ID ภายใน นี่คือเนื่องจากพจนานุกรม D1 ไม่ถูกเก็บไว้ในตารางระบบเมื่อคำสั่ง Transact SQL สิ้นสุดลงหรือ conceled
-
ถ้างานพื้นหลังของทูเปิลที่ถูกนำเสนอเริ่มต้นที่จุดนี้ไม่มีข้อผิดพลาดเกิดขึ้นเนื่องจากเงื่อนไขที่อธิบายไว้ในขั้นตอนที่3นำไปใช้
-
ถ้ามีการสร้าง rowgroup R3 ใหม่ก่อนที่จะเริ่มต้นงานพื้นหลังผู้นำเสนอทูเปิล (ต่อรายการสัญลักษณ์แสดงหัวข้อก่อนหน้า) SQL Server จะกำหนด ID ภายในเดียวกันให้กับพจนานุกรมใหม่ D1 และอ้างอิงพจนานุกรม D1 สำหรับส่วนที่ S3 ใน rowgroup R3
-
เมื่องานพื้นหลังของทูเปิลผู้นำเสนอจะเริ่มต้นหลังจากการกระทำก่อนหน้านี้จะปล่อยให้มองไม่เห็น rowgroup R1 และส่วนของเซกเมนต์ S1 พร้อมกับพจนานุกรมใหม่ D1 เหตุการณ์นี้เกิดขึ้นเนื่องจากทูเปิลจะพิจารณาว่าพจนานุกรมใหม่ D1 และพจนานุกรมต้นฉบับ D1 ที่การอ้างอิง S1 จะเหมือนกันหมายเหตุ เมื่อเงื่อนไขนี้เกิดขึ้นคุณจะไม่สามารถสอบถามเนื้อหาของ rowgroup R3 ได้
การแก้ไข
ปัญหานี้ได้รับการแก้ไขแล้วในการอัปเดตที่สะสมต่อไปนี้สำหรับ SQL Server ก่อน:
การอัปเดตที่สะสม1สำหรับ Sql server ๒๐๑๔ SP1 การอัปเดตที่สะสม8สำหรับ sql server ๒๐๑๔การแก้ไขสำหรับปัญหานี้จะรวมอยู่ในการอัปเดตการแจกจ่ายทั่วไปของการแจกจ่าย (GDR) ดังต่อไปนี้:
การอัปเดตความปลอดภัยสำหรับ SQL Server ๒๐๑๔ QFE การอัปเดตนี้มีการปรับปรุงที่สะสม8การแก้ไขที่สำคัญนี้และการอัปเดตความปลอดภัยของ MS15-058 ที่จำเป็นการอัปเดตความปลอดภัยสำหรับ SQL Server ๒๐๑๔ GDR การอัปเดตนี้มีการแก้ไขที่สำคัญและการแก้ไขการรักษาความปลอดภัยที่สะสมผ่าน MS15-058การอัปเดต Nonsecurity สำหรับ SQL Server ๒๐๑๔ Service Pack 1 GDR การอัปเดตนี้มีเพียงการแก้ไขที่สำคัญเท่านั้น
การอัปเดตที่สะสมใหม่แต่ละรายการสำหรับ SQL Server ประกอบด้วยโปรแกรมแก้ไขด่วนทั้งหมดและการแก้ไขการรักษาความปลอดภัยทั้งหมดที่รวมอยู่ในการอัปเดตที่สะสมก่อนหน้านี้ ดูการอัปเดตที่สะสมล่าสุดสำหรับ SQL Server:
ข้อมูลเพิ่มเติม
ข้อความแสดงข้อผิดพลาดในฐานข้อมูลที่ได้รับผลกระทบในปัจจุบันถ้าคุณเรียกใช้ DBCC CHECKDB หลังจากที่คุณนำการแก้ไขนี้ไปใช้คุณจะได้รับข้อความแสดงข้อผิดพลาดต่อไปนี้:
ข่าวสารเกี่ยวกับ๕๒๘๙ระดับ16สถานะ1บรรทัด1คลัสเตอร์ columnstore index ' cci ' บนตารางไม่มีค่าข้อมูลอย่างน้อยหนึ่งค่าที่ไม่ตรงกับค่าข้อมูลในพจนานุกรม คืนค่าข้อมูลจากสำเนาสำรอง
ในฐานข้อมูลที่ได้รับผลกระทบในปัจจุบันเมื่อคุณเรียกใช้คิวรีที่สแกนตารางที่ได้รับผลกระทบหลังจากที่คุณนำการแก้ไขนี้ไปใช้คุณจะได้รับข้อความแสดงข้อผิดพลาดต่อไปนี้:
Msg ๕๒๘๘ระดับ16สถานะ 1, บรรทัด 1 Columnstore index มีค่าข้อมูลอย่างน้อยหนึ่งค่าที่ไม่ตรงกับค่าข้อมูลในพจนานุกรม โปรดเรียกใช้ DBCC CHECKDB สำหรับข้อมูลเพิ่มเติม
ถ้าคุณได้รับข้อผิดพลาดเหล่านี้คุณสามารถบันทึกข้อมูลปรณ์ได้โดยการส่งออกข้อมูลของคอลัมน์ที่ไม่ได้รับผลกระทบ/rowgroups จากนั้นจึงโหลดข้อมูลหลังจากที่คุณวางหรือสร้างดัชนีคลัสเตอร์ columnstore คุณควรเปิดใช้งานการตั้งค่าสถานะการติดตาม๑๐๒๐๗เพื่อระงับข้อผิดพลาด๕๒๘๘และย้อนกลับไปยังลักษณะการทำงานเก่าของการข้าม rowgroups ที่เสียหาย บันทึกย่อ ข้อความแสดงข้อผิดพลาด๕๒๘๘และ๕๒๘๙จะถูกสร้างขึ้นสำหรับ rowgroup R3 นี้ที่มีส่วนที่ S3 ติดตามค่าสถานะ๑๐๒๐๗ถูกใช้เพื่อแยกเซกเมนต์ของ rowgroup 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 ชุดผลลัพธ์ที่ว่างเปล่าระบุว่าฐานข้อมูลจะไม่ได้รับผลกระทบ
-
เรียกใช้คิวรีนี้ในระหว่างช่วงเวลาที่ไม่มีกิจกรรมที่จะสร้าง rowgroups ใหม่หรือเปลี่ยนสถานะของ rowgroups ที่มีอยู่ ตัวอย่างเช่นกิจกรรมต่อไปนี้สามารถปรับเปลี่ยนสถานะของ rowgroups: สร้างดัชนี, จัดระเบียบดัชนี, การแทรกจำนวนมาก, ทูเปิลการบีบอัดร้านค้าที่แตกต่างกัน ก่อนที่คุณจะเรียกใช้คิวรีคุณสามารถปิดใช้งานงานทูเปิลของพื้นหลังโดยใช้ค่าสถานะการติดตาม๖๓๔ ใช้คำสั่งนี้เพื่อปิดใช้งานพื้นหลัง: DBCC TRACEON (๖๓๔,-1) หลังจากคิวรีเสร็จสิ้นการดำเนินการโปรดจำไว้ว่าจะเปิดใช้งานพื้นหลังโดยใช้คำสั่ง: DBCC TRACEOFF (๖๓๔,-1) นอกจากนี้ให้ตรวจสอบให้แน่ใจว่าไม่มีคำสั่งแทรกส่วนใหญ่/BCP/เลือกที่จะแทรกข้อมูลลงในตารางที่ใช้ดัชนี columnstore ในขณะที่คิวรีนี้กำลังทำงานอยู่ ขอแนะนำให้ใช้ขั้นตอนเหล่านี้เพื่อป้องกันไม่ให้คิวรีส่งกลับค่า false บวก
สถานะ
Microsoft ยืนยันว่าปัญหานี้เป็นปัญหาที่เกิดขึ้นกับผลิตภัณฑ์ของ Microsoft ซึ่งมีการระบุไว้ในส่วน "นำไปใช้กับ"