TL; DR: Ich habe eine unfixierbare Beschädigung in einer indizierten Ansicht. Hier sind die Details:
Laufen
DBCC CHECKDB([DbName]) WITH EXTENDED_LOGICAL_CHECKS, DATA_PURITY, NO_INFOMSGS, ALL_ERRORMSGS
In einer meiner Datenbanken tritt der folgende Fehler auf:
Meldung 8907, Ebene 16, Status 1, Zeile 1 Der räumliche Index, der XML-Index oder die indizierte Sicht 'ViewName' (Objekt-ID 784109934) enthält Zeilen, die nicht von der Sichtdefinition erstellt wurden. Dies ist nicht unbedingt ein Integritätsproblem mit den Daten in dieser Datenbank. (...)
CHECKDB hat in der Tabelle 'ViewName' 0 Zuordnungsfehler und 1 Konsistenzfehler gefunden.
repair_rebuild ist die Mindestreparaturstufe (...).
Ich verstehe, dass diese Nachricht darauf hinweist, dass die materialisierten Daten der indizierten Ansicht 'ViewName' nicht mit den Ergebnissen der zugrunde liegenden Abfrage identisch sind. Die manuelle Überprüfung der Daten führt jedoch nicht zu Unstimmigkeiten:
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
wurde verwendet, um die Verwendung des (einzigen) Index zu erzwingen ViewName
. FORCESCAN
wurde verwendet, um den Abgleich der indizierten Ansicht zu verhindern. Der Ausführungsplan bestätigt, dass beide Maßnahmen wirksam sind.
Hier werden keine Zeilen zurückgegeben, was bedeutet, dass die beiden Tabellen identisch sind. (Es gibt nur Ganzzahl- und Guid-Spalten, Kollatierungen kommen nicht ins Spiel).
Der Fehler kann nicht behoben werden, indem der Index für die Ansicht neu erstellt oder ausgeführt wird DBCC CHECKDB REPAIR_ALLOW_DATA_LOSS
. Das Wiederholen der Fixes hat auch nicht geholfen. Warum wird DBCC CHECKDB
dieser Fehler gemeldet? Wie kann man es loswerden?
(Selbst wenn das Problem durch Neuerstellung behoben wird, bleibt meine Frage bestehen. Warum wird ein Fehler gemeldet, obwohl meine Abfragen zur Datenüberprüfung erfolgreich ausgeführt wurden?)
Update: Der Fehler wurde in einigen Releases behoben. Ich kann nicht reproduzieren länger in SQL Server 2014 SP2 CU 5. 2014 SP2 KB ein Update ohne KB - Artikel enthält: Creating non-clustered index causes DBCC CheckDB With Extended_Logical_Checks to raise corruption error
. Die beiden Verbindungsfehler wurden geschlossen:
- https://connect.microsoft.com/SQLServer/feedback/details/847233/creating-non-clustered-index-causes-dbcc-checkdb-with-extended-logical-checks-to-raise-corruption-error
- https://connect.microsoft.com/SQLServer/feedback/details/795478/unfixable-dbcc-checkdb-error-that-is-also-a-false-positive-and-otherwise-strange
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]
Notation funktioniert nicht im Kommentar-Mark-Down.Antworten:
Der Abfrageprozessor kann einen ungültigen Ausführungsplan für die von DBCC generierte (richtige) Abfrage erstellen, um zu überprüfen, ob der Ansichtsindex dieselben Zeilen wie die zugrunde liegende Ansichtsabfrage erzeugt.
Der vom Abfrageprozessor erstellte Plan wird
NULLs
für dieImageObjectID
Spalte falsch verarbeitet .NULLs
Wenn dies nicht der Fall ist , wird die Ansichtsabfrage fälschlicherweise für diese Spalte abgelehnt. Zu denken , dassNULLs
ausgeschlossen werden, ist es in der Lage das gefilterte nicht gruppierten Index auf dem übereinstimmenUsers
Tabelle auf die FilterImageObjectID IS NOT NULL
.Indem ein Plan erstellt wird, der diesen gefilterten Index verwendet, wird sichergestellt, dass keine Zeilen mit
NULL
in gefundenImageObjectID
werden. Diese Zeilen werden (korrekt) aus dem Ansichtsindex zurückgegeben. Es scheint also, dass eine Beschädigung vorliegt, wenn dies nicht der Fall ist.Die Ansichtsdefinition lautet:
Der
ON
Vergleich der Klauselgleichheit zwischenAdminUserID
undID
lehntNULLs
in diesen Spalten ab, jedoch nicht in derImageObjectID
Spalte.Ein Teil der von DBCC generierten Abfrage ist:
Dies ist ein generischer Code, der Werte
NULL
bewusst vergleicht . Es ist sicherlich ausführlich, aber die Logik ist in Ordnung.Der Fehler in der Argumentation des Abfrageprozessors bedeutet, dass möglicherweise ein Abfrageplan erstellt wird, der den gefilterten Index falsch verwendet, wie im folgenden Beispielplanfragment:
Die DBCC-Abfrage verwendet einen anderen Codepfad durch den Abfrageprozessor als Benutzerabfragen. Dieser Codepfad enthält den Fehler. Wenn ein Plan mit dem gefilterten Index generiert wird, kann er nicht mit dem
USE PLAN
Hinweis verwendet werden, um diese Planform mit demselben Abfragetext zu erzwingen, der von einer Benutzerdatenbankverbindung gesendet wurde.Der Haupt-Optimierer-Codepfad (für Benutzerabfragen) enthält diesen Fehler nicht, so dass er für interne Abfragen wie die von DBCC generierten spezifisch ist.
quelle
Weitere Untersuchungen haben ergeben, dass dies ein Fehler in DBCC CHECKDB ist. Ein Microsoft Connect-Fehler wurde geöffnet: Unfixable DBCC CHECKDB error (das ist auch falsch positiv und ansonsten seltsam) . Zum Glück konnte ich einen Repro produzieren, damit der Fehler gefunden und behoben werden kann.
Der Fehler kann durch Spielen mit dem Datenbankschema ausgeblendet werden. Durch Löschen eines nicht verknüpften gefilterten Index oder Entfernen des Filters wird der Fehler ausgeblendet. Einzelheiten entnehmen Sie bitte dem Verbindungselement.
Das Verbindungselement enthält auch die interne Abfrage, mit der DBCC CHECKDB den Inhalt der Ansicht überprüft. Es werden keine Ergebnisse zurückgegeben, was darauf hinweist, dass dies ein Fehler ist.
Der Fehler wurde in einigen Releases behoben. Ich kann es in SQL Server 2014 SP2 CU 5 nicht mehr reproduzieren.
quelle