DBCC CHECKDB अयोग्य भ्रष्टाचार: अनुक्रमित दृश्य में वे पंक्तियाँ होती हैं जो दृश्य परिभाषा द्वारा निर्मित नहीं थीं


14

TL; DR: मुझे अनुक्रमित दृश्य में एक अपरिहार्य भ्रष्टाचार मिला है। यहाँ विवरण हैं:


चल रहा है

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

मेरे किसी डेटाबेस में निम्न त्रुटि उत्पन्न होती है:

Msg 8907, स्तर 16, राज्य 1, पंक्ति 1 स्थानिक सूचकांक, XML सूचकांक या अनुक्रमित दृश्य 'ViewName' (ऑब्जेक्ट आईडी 784109934) में वे पंक्तियाँ हैं जो दृश्य परिभाषा द्वारा निर्मित नहीं थीं। यह आवश्यक रूप से इस डेटाबेस में डेटा के साथ एक अखंडता मुद्दे का प्रतिनिधित्व नहीं करता है। (...)

CHECKDB को तालिका 'ViewName' में 0 आवंटन त्रुटियाँ और 1 संगतता त्रुटियाँ मिलीं।

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(केवल) सूचकांक के उपयोग को बल देने के लिए किया गया था ViewNameFORCESCANअनुक्रमित दृश्य को होने से रोकने के लिए उपयोग किया गया था। निष्पादन योजना काम करने के दोनों उपायों की पुष्टि करती है।

यहां कोई पंक्तियाँ नहीं लौटाई जा रही हैं, जिसका अर्थ है कि दोनों तालियाँ समान हैं। (केवल पूर्णांक और गाइड कॉलम हैं, कोलाज खेलने में नहीं आते हैं)।

दृश्य पर अनुक्रमणिका को पुन: बनाकर या चलाकर त्रुटि को ठीक नहीं किया जा सकता हैDBCC CHECKDB REPAIR_ALLOW_DATA_LOSS । फिक्स को दोहराने से भी मदद नहीं मिली। इस त्रुटि की रिपोर्ट क्यों करता है DBCC CHECKDB? मैं इससे छुटकारा कैसे पाऊं?

(यहां तक ​​कि अगर पुनर्निर्माण ने इसे ठीक कर दिया, तो मेरा सवाल अभी भी खड़ा होगा - एक त्रुटि की रिपोर्ट क्यों की गई है, हालांकि मेरे डेटा जांच प्रश्न सफलतापूर्वक चलते हैं?)


अद्यतन: बग को कुछ रिलीज़ में ठीक किया गया है। मैं अब इसे SQL Server 2014 SP2 CU 5 में पुन: पेश नहीं कर सकता। 2014 SP2 KB में KB आलेख के बिना एक फ़िक्सेस है Creating non-clustered index causes DBCC CheckDB With Extended_Logical_Checks to raise corruption error:। इसके बारे में दो कनेक्ट बग्स को बंद कर दिया गया है:


1
क्या आप कह रहे हैं कि आपने दृश्य पर सूचकांक को गिराया और फिर से बनाया है और DBCC CHECKDB अभी भी उसी त्रुटि की रिपोर्ट करता है? दृश्य को छोड़ने और इसे खरोंच से बनाने के बारे में क्या?
हारून बर्ट्रेंड

से बोल: पर इंडेक्स्ड दृश्य समस्या निवारण बी सी सी त्रुटियाँ 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.
परिजनों शाह

@ क्या मैंने आपकी टिप्पणी संपादित की है। [1]अंकन टिप्पणी मार्क-डाउन में काम नहीं करता।
हारून बर्ट्रेंड

मैंने सब कुछ फिर से बनाया। मैंने DBCC CHECKDB REPAIR_ALLOW_DATA_LOSS को भी चलने दिया। इसने कहा कि यह दृश्य को फिर से बनाता है, लेकिन फिर उसने उसी त्रुटि की सूचना दी।
usr

क्या आप दृश्य की परिभाषा दिखा सकते हैं (यदि यहां बहुत समय बीत चुका है तो किसी पास्टबिन में)?
हारून बर्ट्रेंड

जवाबों:


14

क्वेरी प्रोसेसर DBCC द्वारा उत्पन्न (सही) क्वेरी के लिए एक अमान्य निष्पादन योजना बना सकता है ताकि यह जांच सके कि दृश्य सूचकांक अंतर्निहित दृश्य क्वेरी के समान पंक्तियाँ पैदा करता है।

क्वेरी प्रोसेसर द्वारा निर्मित योजना गलत तरीके NULLsसे ImageObjectIDकॉलम के लिए हैंडल करती है। यह गलत कारण है कि दृश्य क्वेरी NULLsइस कॉलम के लिए अस्वीकार कर देती है , जब यह नहीं होता है। यह सोचकर कि NULLsइसे बाहर रखा गया है, यह फ़िल्टर किए गए गैर-अनुक्रमित सूचकांक को उस Usersतालिका पर मिलान करने में सक्षम है जो फ़िल्टर करता है ImageObjectID 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अनजान फैशन में मूल्यों की तुलना करता है । यह निश्चित रूप से क्रिया है, लेकिन तर्क ठीक है।

क्वेरी प्रोसेसर के तर्क में बग का मतलब यह है कि एक क्वेरी प्लान जो गलत तरीके से फ़िल्टर किए गए इंडेक्स का उपयोग करता है, का उत्पादन किया जा सकता है, जैसा कि नीचे दिए गए उदाहरण के टुकड़े में है:

त्रुटिपूर्ण योजना

DBCC क्वेरी उपयोगकर्ता प्रश्नों से क्वेरी प्रोसेसर के माध्यम से एक अलग कोड पथ लेता है। इस कोड पथ में बग है। जब फ़िल्टर किए गए इंडेक्स का उपयोग करने वाली योजना उत्पन्न होती है, तो इसका उपयोग USE PLANउपयोगकर्ता डेटाबेस कनेक्शन से सबमिट किए गए उसी क्वेरी टेक्स्ट के साथ योजना आकार को बाध्य करने के लिए संकेत के साथ नहीं किया जा सकता है ।

मुख्य ऑप्टिमाइज़र कोड पथ (उपयोगकर्ता प्रश्नों के लिए) में यह बग नहीं है, इसलिए यह DBCC द्वारा उत्पन्न आंतरिक प्रश्नों के लिए विशिष्ट है।


मैं SQL Profiler Showplan XML घटना में दोषपूर्ण योजना देख सकते हैं। मैं इसे उत्तर के रूप में चिह्नित करूँगा ।; DBCC सामान्य क्वेरी प्रोसेसर की तुलना में क्वेरी को अलग तरीके से क्यों बनाता है ?; मैं कनेक्ट आइटम से इस उत्तर के लिए एक लिंक जोड़ूंगा।
यूएसआर

2
@usr DBCC उन सभी प्रकार की चीजों को करता है जो एक उपयोगकर्ता कनेक्शन से संभव नहीं होगी। मुझे लगता है कि यह इस तरह से काम करता है क्योंकि इसे करना है, लेकिन आपको पॉल रैंडल जैसे किसी व्यक्ति से उस पर वास्तविक विवरण प्राप्त करने के लिए कहना होगा। वह निश्चित रूप से कहने के लिए स्वतंत्रता पर नहीं हो सकता है। मुझे पता है कि DBCC के बाहर बहुत सारी चीजें हैं जो चीजों को भी अजीब करती हैं; कुछ भी बिल्कुल भी अनुकूलक के माध्यम से जाने के बिना एक निष्पादन योजना का निर्माण!
पॉल व्हाइट 9

6

आगे की जांच से पता चलता है कि यह DBCC CHECKDB में एक बग है। एक Microsoft कनेक्ट बग खोला गया है: Un DBable DBCC CHECKDB त्रुटि (यह भी एक झूठी सकारात्मक है और अन्यथा अजीब है) । सौभाग्य से, मैं एक रिप्रो का उत्पादन करने में सक्षम था ताकि बग को ढूंढा जा सके और तय किया जा सके।

बग को डेटाबेस स्कीमा के साथ खेलकर छिपाया जा सकता है। एक असंबंधित फ़िल्टर किए गए इंडेक्स को हटाना, या फ़िल्टर को हटाना, बग को छुपाता है। जानकारी के लिए कृपया कनेक्ट आइटम देखें।

कनेक्ट आइटम में आंतरिक क्वेरी भी होती है जो DBCC CHECKDB दृश्य सामग्री को मान्य करने के लिए उपयोग करती है। यह कोई परिणाम नहीं देता है, यह दर्शाता है कि यह एक बग है।

कुछ रिलीज में बग को ठीक किया गया है। मैं अब SQL Server 2014 SP2 CU 5 में इसे पुन: पेश नहीं कर सकता।


बग को पुन: उत्पन्न करने के लिए बहुत सारे (उत्पादन) डेटा की आवश्यकता थी (जो आगे इस बात का प्रमाण है कि एक योजना परिवर्तन इसका कारण हो सकता है)। मैं डेटा जारी करने में सहज नहीं हूं, हालांकि मैं प्रत्येक तालिका से सभी लेकिन दो स्तंभों को हटाने में सक्षम था। जिस मुद्दे से आप जुड़े हैं, उसे देखने में भ्रष्टाचार की आवश्यकता है। मैंने दृश्य को फिर से बनाया ताकि डीएमएल के कारण कोई भ्रष्टाचार न हो। क्या आप ऐसी किसी भी चीज़ के बारे में जानते हैं, जो सामान्य क्वेरी विंडो के बजाय DBCC CHECKDB के तहत क्वेरी चलाने पर भिन्न योजना का कारण हो सकती है?
यूएसआर

एक अनाम डेटाबेस अभी अपलोड किया गया है। यहां एक स्क्रिप्ट है जो सभी अनुक्रमितों का पुनर्निर्माण करती है और दृश्य को फिर से बनाती है: pastebin.com/jPEALeEw (भौतिक संरचना ठीक है सब कुछ रीसेट करने और यह सुनिश्चित करने के लिए उपयोगी)। अन्य सहायक स्क्रिप्ट: pastebin.com/KxNSwm2J स्क्रिप्ट को बस चलाना चाहिए और समस्या को तुरंत हटा देना चाहिए।
यूएसआर

दर्पण का .bak: Mega.co.nz/…
usr

11.0.3349 पर -T272,4199,3604 के साथ। 4199 सक्षम क्वेरी प्रोसेसर को ठीक करता है। मैंने अभी उस TF को हटा दिया ;; शायद हमें सही क्वेरी योजना को प्रेरित करने की आवश्यकता है। मैंने अब 1GB रैम सेट किया है और इंस्टेंस को फिर से शुरू किया है (8GB था)। मैंने एनएलजे को देख रहे दो मर्ज जॉइन में से एक को बदल दिया। फिर भी रेप्रो .; मेरे द्वारा जोड़े गए और हटाए गए कुछ प्लान वेरिएशन को ट्राई करने के लिए: pastebin.com/y972Sx4d बग को ट्रिगर करना प्रतीत होता है यदि मुझे क्वेरी के "लेफ्ट एंटी सेमी जॉइन" भाग में मर्ज जॉइन या हैश मिलता है। इसे आज़माएँ: उपयोगकर्ताओं को 100k पंक्तियाँ जोड़ें। यह मज़बूती से मेरे लिए (समानांतर) हैश ज्वाइन करता है।
यूएसआर

मैंने बस कनेक्ट आइटम के लिए "plan.zip" अपलोड किया है जिसमें DBCC CHECKDB क्वेरी के लिए अलग-अलग निष्पादन योजनाएं हैं। विश्वविद्यालयों में अलग-अलग पंक्ति गणनाओं के साथ मैं कम से कम तीन अलग-अलग योजनाओं का उत्पादन कर सकता हूं। केवल लूप जॉइन प्लान के साथ समस्या उत्पन्न नहीं होती है। मर्ज और हैश के साथ बग प्रजनन योग्य है।
यूआर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.