TL; DR: Eu tenho uma corrupção não corrigível em uma exibição indexada. Aqui estão os detalhes:
Corrida
DBCC CHECKDB([DbName]) WITH EXTENDED_LOGICAL_CHECKS, DATA_PURITY, NO_INFOMSGS, ALL_ERRORMSGS
em um dos meus bancos de dados produz o seguinte erro:
Msg 8907, Nível 16, Estado 1, Linha 1 O índice espacial, o índice XML ou a exibição indexada 'ViewName' (ID do objeto 784109934) contém linhas que não foram produzidas pela definição da exibição. Isso não representa necessariamente um problema de integridade com os dados desse banco de dados. (...)
O CHECKDB encontrou 0 erros de alocação e 1 erros de consistência na tabela 'ViewName'.
repair_rebuild é o nível mínimo de reparo (...).
Entendo que esta mensagem indica que os dados materializados da exibição indexada 'ViewName' não são idênticos ao que a consulta subjacente produz. No entanto, verificar manualmente os dados não gera discrepâncias:
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
foi usado para forçar o uso do (somente) índice ViewName
.FORCESCAN
foi usado para impedir que a correspondência de exibição indexada aconteça. O plano de execução confirma que ambas as medidas estão funcionando.
Nenhuma linha está sendo retornada aqui, o que significa que as duas tabelas são idênticas. (Existem apenas colunas de número inteiro e guia, os agrupamentos não entram em jogo).
O erro não pode ser corrigido recriando o índice na exibição ou executando DBCC CHECKDB REPAIR_ALLOW_DATA_LOSS
. Repetir as correções também não ajudou. Por que DBCC CHECKDB
relatar esse erro? Como se livrar dele?
(Mesmo que a reconstrução o corrigisse, minha pergunta ainda permaneceria - por que um erro é relatado, embora minhas consultas de verificação de dados sejam executadas com êxito?)
Atualização: O bug foi corrigido em algumas versões. Já não posso reproduzi-lo no SQL Server 2014 SP2 CU 5. A KB 2014 SP2 contém uma correção sem artigo KB: Creating non-clustered index causes DBCC CheckDB With Extended_Logical_Checks to raise corruption error
. Os dois erros de conexão sobre isso foram fechados:
- 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]
notação não funciona na marcação de comentário.