J'ai une grande table avec 15 000 000 d'enregistrements et soudainement Select Top a cessé de fonctionner. J'utilise MS SQL Management Studio.
Cela ne fonctionne pas, la requête renvoie 0 enregistrements:
SELECT TOP (10)
[Id]
,[Result]
,[DateStamp]
,[ConversionTime]
,[Converter]
,[SourceFileFormat]
,[DestinationFileFormat]
,[Ip]
,[Source]
,[Error]
,[UserId]
,[TokenId]
,[ConversionCost]
FROM [ca-v2].[dbo].[Log]
À ma grande surprise, si j'essaie de sélectionner un champ ID, cela fonctionne en pourcentage.
Fonctionne bien:
SELECT TOP (10)
[Id]
FROM [ca-v2].[dbo].[Log]
De plus, si j'ajoute une commande à la fin, la requête commence également à fonctionner:
SELECT TOP (10)
[Id]
,[Result]
,[DateStamp]
,[ConversionTime]
,[Converter]
,[SourceFileFormat]
,[DestinationFileFormat]
,[Ip]
,[Source]
,[Error]
,[UserId]
,[TokenId]
,[ConversionCost]
FROM [ca-v2].[dbo].[Log]
Order By [DateStamp]
L'Iran DBCC CHECKTABLE
sur la table et a reçu l'erreur suivante:
Erreur: Msg 8978, niveau 16, état 1, ligne 1
Erreur de table: ID d'objet 1029578706, ID d'index 1, ID de partition 72057594043367424, ID d'unité d'allocation 72057594045071360 (type Données en ligne). La page (1: 5044) manque une référence de la page précédente (1: 5042). Problème de liaison de chaîne possible.
Que puis-je faire à ce sujet?
Avec l'aide de @RDFozz, j'ai pu réparer l'index endommagé à l'aide de sql
ALTER DATABASE "db" SET SINGLE_USER WITH ROLLBACK IMMEDIATE
go
DBCC CheckTable ("log", REPAIR_REBUILD)
go
ALTER DATABASE "db" SET MULTI_USER WITH ROLLBACK IMMEDIATE
Deux choses importantes ici: 1) une base de données doit être mise en mode mono-utilisateur. 2) si la base de données est en production et a d'autres connexions, la commande utilisateur SET doit être obtenue avec ROLLBACK IMMEDIATE pour supprimer les connexions actuelles.
Lorsque vous êtes confronté à une corruption de base de données, vous devrez déterminer l'étendue du problème. Avez-vous une table/un index corrompu, ou plusieurs? Vous voudrez probablement exécuter DBCC CHECKDB
sur la base de données.
Selon ce que vous trouvez, vous disposez des options suivantes (par ordre décroissant de sécurité):
Restaurer à partir d'une sauvegarde
Il s'agit généralement de la solution la plus simple et la plus sûre. Cependant, si vous n'êtes pas certain de la date à laquelle la corruption est apparue, cela peut ne pas être pratique - il est possible que vous n'ayez aucune sauvegarde récente sans la corruption. Et, selon l'utilisation de la base de données, jeter une journée de données pour corriger la corruption pourrait être très coûteux, en termes de continuer à être en mesure de gérer votre entreprise.
Cependant, si la corruption est grave, cela peut être la seule solution dont vous disposez. Même si vous essayez certaines des options suivantes, vous devrez peut-être revenir à celle-ci.
Si vous avez des sauvegardes, gardez-les à portée de main et n'en faites pas de cycle (si possible) avant d'avoir résolu le problème.
Utilisation DBCC CHECKTABLE
ou DBCC CHECKDB
avec une option de réparation
Votre série de DBCC CHECKTABLE
et/ou DBCC CHECKDB
peut avoir indiqué une option de réparation que vous pourriez utiliser pour essayer de restaurer les choses à la normale.
Les commandes ont les mêmes options de réparation:
REPAIR_FAST
- comme il est dit, il a essayé des choses simples et prendra moins de temps que les autres options de réparation. Comme vous pouvez le deviner, cela signifie également qu'il est le moins susceptible de réussir.
REPAIR_REBUILD
- Cela fait ce que REPAIR_FAST
le fait, mais est également prêt à essayer de reconstruire des index à partir de zéro - du problème est dans un index non clusterisé, cela devrait le résoudre.
REPAIR_ALLOW_DATA_LOSS
- Comme indiqué, il essaiera de restaurer la convivialité des objets affectés, mais devra peut-être éliminer les lignes partielles et ainsi de suite; vous risquez de perdre certaines de vos données. C'est l'une des raisons pour lesquelles la restauration d'une sauvegarde est souvent la meilleure solution.
Frankensteining votre mauvaise table (pour ainsi dire)
Si seul ce tableau est affecté, vous pouvez essayer de:
DBCC CHECKDB
encore; et
Ou, pour essayer de conserver autant de données les plus récentes que possible:
REPAIR_ALLOW_DATA_LOSS
sur la table.Comme indiqué par CaM dans les commentaires, vous devez l'utiliser comme motivation pour vous assurer que vous effectuez des tâches de maintenance régulières sur votre base de données.
Tout d'abord, si vous n'êtes pas aujourd'hui, commencez à le sauvegarder régulièrement. La plupart des bases de données que j'administre ont une sauvegarde complète hebdomadaire et des sauvegardes différentielles quotidiennes, nous ne devons donc jamais perdre plus d'une journée de données.
En outre, vous devez exécuter DBCC CHECKDB
régulièrement pour détecter la corruption avant qu'elle ne devienne trop grave pour être corrigée. C'est aussi quelque chose que j'essaie d'exécuter chaque semaine.