DBCC CHECKDB ความเสียหายที่ไม่สามารถแก้ไขได้: มุมมองที่จัดทำดัชนีมีแถวที่ไม่ได้สร้างขึ้นโดยการกำหนดมุมมอง


14

TL; DR: ฉันมีความเสียหายที่ไม่สามารถแก้ไขได้ในมุมมองที่จัดทำดัชนี นี่คือรายละเอียด:


วิ่ง

DBCC CHECKDB([DbName]) WITH EXTENDED_LOGICAL_CHECKS, DATA_PURITY, NO_INFOMSGS, ALL_ERRORMSGS

บนหนึ่งในฐานข้อมูลของฉันสร้างข้อผิดพลาดต่อไปนี้:

เกี่ยวกับข่าวสาร 8907 ระดับ 16 สถานะ 1 บรรทัด 1 ดัชนีเชิงพื้นที่ดัชนี XML หรือมุมมองที่จัดทำดัชนี 'ViewName' (ID วัตถุ 784109934) ประกอบด้วยแถวที่ไม่ได้สร้างขึ้นโดยการกำหนดมุมมอง สิ่งนี้ไม่จำเป็นต้องแสดงถึงปัญหาด้านความสมบูรณ์ของข้อมูลในฐานข้อมูลนี้ ( ... )

CHECKDB พบข้อผิดพลาดในการจัดสรร 0 ข้อและข้อผิดพลาดความสอดคล้อง 1 ข้อในตาราง 'ViewName'

repair_rebuild เป็นระดับการซ่อมแซมขั้นต่ำ (... )

ฉันเข้าใจว่าข้อความนี้บ่งชี้ว่าข้อมูลที่เป็นรูปธรรมของมุมมองที่จัดทำดัชนี 'ViewName' ไม่เหมือนกับสิ่งที่สร้างข้อความค้นหาต้นแบบ อย่างไรก็ตามการตรวจสอบข้อมูลด้วยตนเองไม่ได้ทำให้เกิดความคลาดเคลื่อน:

SELECT * FROM ViewName WITH (NOEXPAND)
EXCEPT
SELECT ...
from T1 WITH (FORCESCAN)
join T2 on ...

SELECT ...
from T1 WITH (FORCESCAN)
join T2 on ...
EXCEPT
SELECT * FROM ViewName WITH (NOEXPAND)

NOEXPANDถูกใช้ในการบังคับใช้ (เท่านั้น) ViewNameดัชนีใน FORCESCANถูกใช้เพื่อป้องกันการจับคู่มุมมองที่มีการจัดทำดัชนีไว้ แผนการดำเนินการยืนยันว่าทั้งสองมาตรการใช้งานได้

ไม่มีการส่งคืนแถวที่นี่ซึ่งหมายความว่าทั้งสองตารางเหมือนกัน (มีคอลัมน์จำนวนเต็มและ guid เท่านั้นการเปรียบเทียบไม่เข้ามาเล่น)

ข้อผิดพลาดที่ไม่สามารถแก้ไขได้DBCC CHECKDB REPAIR_ALLOW_DATA_LOSSด้วยการสร้างดัชนีในมุมมองหรือโดยการเรียกใช้ การทำซ้ำการแก้ไขก็ไม่ได้ช่วย เหตุใดจึงDBCC CHECKDBรายงานข้อผิดพลาดนี้ จะกำจัดมันได้อย่างไร?

(แม้ว่าการสร้างขึ้นใหม่จะได้รับการแก้ไขคำถามของฉันจะยังคงอยู่ - ทำไมถึงเกิดข้อผิดพลาดถึงแม้ว่าการตรวจสอบข้อมูลของฉันจะทำงานได้สำเร็จ)


อัปเดต: ข้อผิดพลาดได้รับการแก้ไขในบางรุ่น ฉันไม่สามารถทำซ้ำใน SQL Server 2014 SP2 CU 5. 2014 SP2 KB ที่Creating non-clustered index causes DBCC CheckDB With Extended_Logical_Checks to raise corruption errorมีการแก้ไขโดยไม่ต้องบทความกิโลไบต์: ข้อผิดพลาดการเชื่อมต่อสองรายการเกี่ยวกับสิ่งนี้ถูกปิดแล้ว:


1
คุณกำลังบอกว่าคุณทิ้งและสร้างดัชนีใหม่ในมุมมองและ DBCC CHECKDB ยังคงรายงานข้อผิดพลาดเดียวกันอยู่หรือไม่? สิ่งที่เกี่ยวกับการลดมุมมองและสร้างมันตั้งแต่เริ่มต้น?
Aaron Bertrand

จากBOL: การแก้ไขปัญหาข้อผิดพลาด DBCC ในมุมมองที่จัดทำดัชนี If the indexed view does not contain an aggregate over values of type float or real and you receive errors 8907 or 8708, drop the index on the view and re-create it. Do not use ALTER INDEX REBUILD to try to remove the differences between the stored and the computed view, because ALTER INDEX REBUILD does not recalculate the view before rebuilding the index. Then run DBCC CHECKTABLE on the View to verify no differences remain.
Kin Shah

@Kin ฉันแก้ไขความคิดเห็นของคุณ [1]สัญกรณ์ไม่ได้ทำงานในความคิดเห็นเครื่องหมายลง
Aaron Bertrand

ฉันสร้างใหม่ทุกอย่าง ฉันยังปล่อยให้ DBCC CHECKDB REPAIR_ALLOW_DATA_LOSS ทำงาน มันบอกว่ามันสร้างมุมมองใหม่ แต่ก็รายงานข้อผิดพลาดเดียวกัน
usr

คุณสามารถแสดงคำจำกัดความของมุมมอง (ถ้าอยู่ที่นี่นานเกินไปแล้วใน pastebin)?
Aaron Bertrand

คำตอบ:


14

ตัวประมวลผลแบบสอบถามสามารถสร้างแผนการดำเนินการที่ไม่ถูกต้องสำหรับแบบสอบถาม (ที่ถูกต้อง) ที่สร้างโดย DBCC เพื่อตรวจสอบว่าดัชนีมุมมองสร้างแถวเดียวกันกับแบบสอบถามมุมมองต้นแบบ

แผนที่ผลิตโดยตัวประมวลผลแบบสอบถามจัดการอย่างไม่ถูกต้องNULLsสำหรับImageObjectIDคอลัมน์ มันไม่ถูกต้องด้วยเหตุผลที่แบบสอบถามดูปฏิเสธNULLsสำหรับคอลัมน์นี้เมื่อมันไม่ คิดว่าNULLsได้รับการยกเว้นก็สามารถที่จะตรงกับดัชนี nonclustered กรองในตารางที่กรองบนUsersImageObjectID IS NOT NULL

ด้วยการสร้างแผนที่ใช้ดัชนีที่ถูกกรองนี้จะทำให้แน่ใจได้ว่าจะไม่พบแถวที่NULLอยู่ใน ImageObjectIDแถวเหล่านี้ถูกส่งคืน (ถูกต้อง) จากดัชนีมุมมองดังนั้นจึงปรากฏว่ามีความเสียหายเมื่อไม่มี

นิยามมุมมองคือ:

SELECT
    dbo.Universities.ID AS Universities_ID, 
    dbo.Users.ImageObjectID AS Users_ImageObjectID
FROM dbo.Universities
JOIN dbo.Users
    ON dbo.Universities.AdminUserID = dbo.Users.ID

การONเปรียบเทียบความเท่าเทียมกันระหว่างประโยคAdminUserIDและIDปฏิเสธNULLsในคอลัมน์เหล่านั้น แต่ไม่ได้มาจากImageObjectIDคอลัมน์

ส่วนหนึ่งของการสืบค้น DBCC ที่สร้างขึ้นคือ:

SELECT [Universities_ID], [Users_ImageObjectID], 0 as 'SOURCE'
FROM [dbo].[mv_Universities_Users_ID] tOuter WITH (NOEXPAND) 
WHERE NOT EXISTS
( 
    SELECT 1 
    FROM   [dbo].[mv_Universities_Users_ID] tInner
    WHERE 
    (
        (
            (
                [tInner].[Universities_ID] = [tOuter].[Universities_ID]
            ) 
            OR 
            (
                [tInner].[Universities_ID] IS NULL
                AND [tOuter].[Universities_ID] IS NULL
            )
        )
        AND
        (
            (
                [tInner].[Users_ImageObjectID] = [tOuter].[Users_ImageObjectID]
            ) 
            OR 
            (
                [tInner].[Users_ImageObjectID] IS NULL 
                AND [tOuter].[Users_ImageObjectID] IS NULL
            )
        )
    )
)
OPTION (EXPAND VIEWS);

นี่คือรหัสทั่วไปที่เปรียบเทียบค่าในแบบNULL-aware แน่นอนว่าเป็นเรื่องจริง แต่ตรรกะนั้นใช้ได้

ข้อผิดพลาดในการใช้เหตุผลของตัวประมวลผลแบบสอบถามหมายความว่าแผนแบบสอบถามที่ใช้ดัชนีที่กรองไม่ถูกต้องอาจถูกสร้างขึ้นเช่นในตัวอย่างส่วนแผนด้านล่าง:

แผนผิดพลาด

แบบสอบถาม DBCC ใช้เส้นทางรหัสที่แตกต่างกันผ่านตัวประมวลผลแบบสอบถามจากแบบสอบถามของผู้ใช้ เส้นทางรหัสนี้มีข้อบกพร่อง เมื่อแผนที่ใช้ดัชนีที่กรองถูกสร้างขึ้นจะไม่สามารถใช้กับUSE PLANคำใบ้เพื่อบังคับให้รูปร่างแผนนั้นพร้อมกับข้อความแบบสอบถามเดียวกันที่ส่งมาจากการเชื่อมต่อฐานข้อมูลผู้ใช้

พา ธ โค้ดของเครื่องมือเพิ่มประสิทธิภาพหลัก (สำหรับคิวรีผู้ใช้) ไม่มีข้อบกพร่องนี้ดังนั้นจึงเป็นข้อความค้นหาเฉพาะภายในเช่นเดียวกับที่สร้างโดย DBCC


ฉันเห็นแผนการผิดพลาดในเหตุการณ์ SQL Profiler Showplan XML ฉันจะทำเครื่องหมายสิ่งนี้เป็นคำตอบ; เหตุใด DBCC จึงสร้างคิวรีในวิธีที่แตกต่างจากตัวประมวลผลคิวรีทั่วไป? ฉันจะเพิ่มลิงก์ไปยังคำตอบนี้ไปยังรายการเชื่อมต่อ
usr

2
@usr DBCC ทำทุกสิ่งที่ไม่สามารถทำได้จากการเชื่อมต่อของผู้ใช้ ฉันคิดว่ามันใช้งานได้เพราะมันมี แต่คุณต้องถามคนอย่าง Paul Randal เพื่อรับรายละเอียดที่แท้จริง แน่นอนว่าเขาอาจไม่มีเสรีภาพที่จะพูด ฉันรู้ว่ามีหลายสิ่งนอก DBCC ที่ทำสิ่งที่แปลก บางคนถึงกับสร้างแผนการดำเนินการโดยไม่ต้องใช้เครื่องมือเพิ่มประสิทธิภาพเลย!
พอลไวท์ 9

6

การตรวจสอบเพิ่มเติมแสดงให้เห็นว่านี่เป็นข้อผิดพลาดใน DBCC CHECKDB ข้อผิดพลาด Microsoft Connect ถูกเปิดขึ้น:ข้อผิดพลาด unfixable DBCC CHECKDB (ที่ยังเป็นบวกเท็จและแปลกอื่น ๆ ) โชคดีที่ฉันสามารถผลิตซ้ำเพื่อให้พบข้อผิดพลาดและแก้ไข

ข้อผิดพลาดสามารถซ่อนได้ด้วยการเล่นกับคีมาฐานข้อมูล การลบดัชนีตัวกรองที่ไม่เกี่ยวข้องหรือลบตัวกรองซ่อนข้อบกพร่อง สำหรับรายละเอียดโปรดดูรายการเชื่อมต่อ

รายการเชื่อมต่อยังมีแบบสอบถามภายในที่ DBCC CHECKDB ใช้ในการตรวจสอบเนื้อหามุมมอง มันไม่มีผลลัพธ์แสดงให้เห็นว่านี่เป็นข้อผิดพลาด

ข้อผิดพลาดได้รับการแก้ไขในบางรุ่น ฉันไม่สามารถทำซ้ำได้ใน SQL Server 2014 SP2 CU 5


จำเป็นต้องมีข้อมูลจำนวนมาก (การผลิต) เพื่อสร้างข้อผิดพลาด (ซึ่งเป็นหลักฐานเพิ่มเติมว่าการเปลี่ยนแปลงแผนอาจเป็นสาเหตุ) ฉันไม่สบายใจที่จะปล่อยข้อมูลแม้ว่าฉันจะสามารถลบทั้งหมดยกเว้นคอลัมน์สองคอลัมน์จากแต่ละตาราง ปัญหาที่คุณเชื่อมโยงต้องก่อให้เกิดความเสียหายในมุมมอง ฉันสร้างมุมมองใหม่เพื่อไม่ให้เกิดความเสียหายเนื่องจาก DML สามารถเป็นสาเหตุได้; คุณรู้หรือไม่ว่าอะไรก็ตามที่อาจทำให้แผนแตกต่างกันหากมีการเรียกใช้แบบสอบถามภายใต้ DBCC CHECKDB แทนที่จะเป็นในหน้าต่างแบบสอบถามปกติ
usr

ฐานข้อมูลที่ไม่ระบุชื่อเพิ่งถูกอัพโหลด นี่คือสคริปต์ที่สร้างดัชนีใหม่ทั้งหมดและสร้างมุมมองใหม่: pastebin.com/jPEALeEw (มีประโยชน์ในการรีเซ็ตทุกอย่างและตรวจสอบให้แน่ใจว่าโครงสร้างทางกายภาพนั้นใช้ได้) สคริปต์ที่มีประโยชน์อื่น ๆ : pastebin.com/KxNSwm2Jสคริปต์ควรทำงานและปัญหาควรได้รับการแก้ไขทันที
usr

Mirror of the .bak: mega.co.nz/…
usr

ในวันที่ 11.0.3349 กับ -T272,4199,3604 ตัวแก้ไขคิวรีตัวประมวลผลที่เปิดใช้งาน 4199 ฉันเพิ่งลบ TF นั้น บางทีเราจำเป็นต้องกระตุ้นแผนการสืบค้นที่ถูกต้อง ตอนนี้ฉันได้ตั้งค่า RAM 1GB และรีสตาร์ทอินสแตนซ์ (เป็น 8GB) นั่นเปลี่ยนหนึ่งในสองการรวมที่ฉันเห็นเป็น NLJ ยังคงเป็น repros.; หากต้องการลองใช้แผนรูปแบบที่หลากหลายฉันได้เพิ่มและลบแถว: pastebin.com/y972Sx4dข้อผิดพลาดดูเหมือนว่าจะเกิดขึ้นถ้าฉันได้รับการรวมการรวมหรือการแฮชในส่วน "left anti semi join" ของแบบสอบถาม ลองทำดังนี้: เพิ่ม 100k row ให้กับ Users สิ่งนี้ทำให้แฮช (ขนาน) เข้าร่วมได้อย่างน่าเชื่อถือสำหรับฉัน
usr

ฉันเพิ่งอัปโหลด "plans.zip" ไปยังรายการเชื่อมต่อซึ่งมีแผนการดำเนินการที่แตกต่างกันสำหรับแบบสอบถาม DBCC CHECKDB ด้วยจำนวนแถวที่แตกต่างกันในมหาวิทยาลัยฉันสามารถสร้างแผนแตกต่างกันอย่างน้อยสามแผน เฉพาะกับลูปเข้าร่วมแผนปัญหาไม่เกิดขึ้น ด้วยการผสานและแฮชเข้าร่วมข้อผิดพลาดสามารถทำซ้ำได้
usr
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.