TL; DR: J'ai une corruption non réparable dans une vue indexée. Voici les détails:
Fonctionnement
DBCC CHECKDB([DbName]) WITH EXTENDED_LOGICAL_CHECKS, DATA_PURITY, NO_INFOMSGS, ALL_ERRORMSGS
sur l'une de mes bases de données produit l'erreur suivante:
Msg 8907, niveau 16, état 1, ligne 1 L'index spatial, l'index XML ou la vue indexée 'ViewName' (ID d'objet 784109934) contient des lignes qui n'ont pas été produites par la définition de la vue. Cela ne représente pas nécessairement un problème d'intégrité avec les données de cette base de données. (...)
CHECKDB a trouvé 0 erreur d'allocation et 1 erreur de cohérence dans la table 'ViewName'.
repair_rebuild est le niveau de réparation minimum (...).
Je comprends que ce message indique que les données matérialisées de la vue indexée 'ViewName' ne sont pas identiques à ce que la requête sous-jacente produit. Cependant, la vérification manuelle des données ne révèle aucune anomalie:
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
a été utilisé pour forcer l'utilisation de l'index (uniquement) sur ViewName
. FORCESCAN
a été utilisé pour empêcher la correspondance des vues indexées. Le plan d'exécution confirme que les deux mesures fonctionnent.
Aucune ligne n'est renvoyée ici, ce qui signifie que les deux tables sont identiques. (Il n'y a que des colonnes entières et guid, les classements n'entrent pas en jeu).
L'erreur ne peut pas être corrigée en recréant l'index sur la vue ou en exécutant DBCC CHECKDB REPAIR_ALLOW_DATA_LOSS
. La répétition des correctifs n'a pas aidé non plus. Pourquoi DBCC CHECKDB
signale cette erreur? Comment s'en débarrasser?
(Même si la reconstruction le corrigeait, ma question resterait posée - pourquoi une erreur est-elle signalée alors que mes requêtes de vérification des données ont réussi?)
Mise à jour: le bogue a été corrigé dans certaines versions. Je ne peux plus se reproduire dans SQL Server 2014 SP2 CU 5. 2014 SP2 KB contient un correctif sans KB article: Creating non-clustered index causes DBCC CheckDB With Extended_Logical_Checks to raise corruption error
. Les deux bogues de connexion à ce sujet ont été fermés:
- 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 ne fonctionne pas dans la marque de commentaire.