CheckDB mit auswertbarem Ergebnis
Zu den regelmäßigen und wichtigsten Wartungsarbeiten eines DBA (Database Administrator) gehört das Ausführen aller Datenbanken mittels DBCC CHECKDB(0);, um sie auf Konsistenz und Fehlerfreiheit zu überprüfen.
Das Problem ist nur, das je komplexer die Datenbank ist, so umfangreicher das Protokoll als Ergebnis ist. Diese Ergebnisliste durchzusehen ist aufwendig und es kommt leicht vor, dass man wichtige Meldungen übersieht. Da wäre es doch besser, wenn man das Protokoll auf bestimmte Ergebnisse hin selektieren kann.
Das kann man mit dem folgenden Script, es schreibt das ResultSet in eine temporäre Tabelle und selektiert daraus die wichtigsten Eckdaten und kumulierte Werte.
Das wäre in abgewandelter Form eine gute Basis für einen „benutzerdefinierten Report“ in SSMS; muss ich aber noch dran arbeiten.
Ebenso wäre interessant, eine History-Tabelle zu verwenden, um den Datenbank-Status zeitlich zu protokollieren; schaden kann es jedenfalls nicht.
-- Für MS SQL Server 2005 -- CheckDB für die aktuelle Datenbank ausführen und -- auswerten (Status-Übersicht und Details). -- Die Mindest-Stati Werte können konfiguriert werden. DECLARE @MinState int, @MinStatus int, @MinLevel int SET @MinState = 1; SET @MinStatus = 0 SET @MinLevel = 10; -- Temporäre Tabelle für das CheckDB Ergebnis CREATE TABLE #CheckDB ([Error] int, [Level] int, [State] int, [MessageText] varchar(7000), [RepairLevel] int, [Status] int, [DbId] int, [ObjectID] int, [IndexId] int, [PartitionId] int, [AllocUnitId] int, [File] int, [Page] int, [Slot] int, [RefFile] int, [RefPage] int, [RefSlot] int, [Allocation] int); -- CheckDB ausführen und Ergebnis in die TempTabelle INSERT INTO #CheckDB ([Error], [Level], [State], [MessageText], [RepairLevel], [Status], [DbId], [ObjectID], [IndexId], [PartitionId], [AllocUnitId], [File], [Page], [Slot], [RefFile], [RefPage], [RefSlot], [Allocation]) EXEC ('DBCC CHECKDB(0) WITH TABLERESULTS'); -- Die schließende Meldung mit der Zusammenfassung SELECT [MessageText] FROM #CheckDB WHERE [Error] = 8989; -- Übersicht mit Anzahl je Stati SELECT CDB.Error, CDB.Level, CDB.State, CDB.Status, CDB.RepairLevel, COUNT(*) AS CountOccurence FROM #CheckDB AS CDB WHERE CDB.State >= @MinState AND CDB.Status >= @MinStatus AND CDB.Level >= @MinLevel GROUP BY CDB.Error, CDB.Level, CDB.State, CDB.Status, CDB.RepairLevel; --Ergebnis-Details selektieren SELECT OBJ.name AS ObjName, OBJ.type_desc AS ObjType, IDX.Name AS IndexName, ALU.type_desc AS AllocationType, CDB.Error, CDB.Level, CDB.State, CDB.Status, CDB.RepairLevel, MessageText FROM #CheckDB AS CDB LEFT JOIN sys.objects AS OBJ ON CDB.ObjectId = OBJ.object_id LEFT JOIN sys.indexes AS IDX ON CDB.ObjectId = IDX.object_id AND CDB.IndexID = IDX.index_id LEFT JOIN sys.allocation_units AS ALU ON CDB.AllocUnitId = ALU.allocation_unit_id WHERE CDB.State >= @MinState AND CDB.Status >= @MinStatus AND CDB.Level >= @MinLevel ORDER BY ObjType, ObjName, IndexName; GO -- Aufräumen DROP TABLE #CheckDB; GO