Einer unserer SQL Server hat kürzlich den folgenden Fehler gemeldet:
DATE/TIME: 2/25/2013 9:15:14 PM
DESCRIPTION: No catalog entry found for partition ID 9079262474267394048
in database 2. The metadata is inconsistent. Run DBCC CHECKDB to check for
a metadata corruption.
Weniger als 15 Minuten später stellte ich eine Verbindung zum Server her und lief:
SELECT name
FROM sys.databases
WHERE database_id = 2;
Welches gab 'tempdb' zurück. Ich rannte dann:
DBCC CHECKDB ('tempdb') WITH NO_INFOMSGS, TABLERESULTS;
Was keine Ergebnisse ergab, was darauf hinweist, dass keine Probleme mit der betroffenen Datenbank vorliegen.
Wie kann eine Beschädigung der Datenbank zu der obigen Fehlermeldung führen, DBCC CHECKDB
ohne das Problem zu melden? Ich gehe davon aus, dass wenn eine Seitenprüfsummenberechnung fehlschlägt, die Seite als verdächtig markiert wird, dass ein Objekt, das auf diese Seite verweist, nicht gelöscht werden kann, aber ich muss mich irren.
Wenn eine Seite als "verdächtig" markiert ist, wie kann sie als nicht verdächtig markiert, repariert oder wiederverwendet werden oder was auch immer, DBCC CHECKDB
das kein Problem mit der betreffenden Seite meldet?
Bearbeiten: 2013-02-27 13:24
Nur zum Spaß habe ich versucht, die Beschädigung in TempDB wiederherzustellen, vorausgesetzt, eine # temp-Tabelle war der Schuldige.
Da ich die SINGLE_USER
Option in TempDB nicht festlegen kann, kann ich DBCC WRITEPAGE
eine Seite nicht beschädigen und daher keine Beschädigung in TempDB erzwingen.
Anstatt zu verwenden DBCC WRITEPAGE
, könnte man die Datenbank offline setzen und einen Hex-Editor verwenden, um zufällige Bytes in der Datenbankdatei zu ändern. Dies funktioniert natürlich auch in TempDB nicht, da das Datenbankmodul nicht offline mit TempDB ausgeführt werden kann.
Wenn Sie die Instanz stoppen, wird TempDB beim nächsten Start automatisch neu erstellt. daher reicht das auch nicht aus.
Wenn sich jemand einen Weg ausdenken kann, um diese Korruption wiederherzustellen, wäre ich bereit, weitere Nachforschungen anzustellen.
Um die Hypothese zu testen, dass eine beschädigte Seite nicht behoben werden kann, habe DROP TABLE
ich eine Testdatenbank erstellt und das folgende Skript verwendet, um eine Seite zu beschädigen , und dann versucht, die betroffene Tabelle zu löschen. Ergebnis hier war, dass die Tabelle nicht gelöscht werden konnte; Ich musste, RESTORE DATABASE Testdb PAGE = ''...
um die betroffene Seite wiederherzustellen. Ich gehe davon aus, dass die Seite, wenn ich eine Änderung an einem anderen Teil der fraglichen Seite vorgenommen hätte, möglicherweise mit DROP TABLE
oder möglicherweise korrigiert worden wäre TRUNCATE table
.
/* ********************************************* */
/* ********************************************* */
/* DO NOT USE THIS CODE ON A PRODUCTION SYSTEM!! */
/* ********************************************* */
/* ********************************************* */
USE Master;
GO
ALTER DATABASE test SET RECOVERY FULL;
BACKUP DATABASE Test
TO DISK = 'Test_db.bak'
WITH FORMAT
, INIT
, NAME = 'Test Database backup'
, SKIP
, NOREWIND
, NOUNLOAD
, COMPRESSION
, STATS = 1;
BACKUP LOG Test
TO DISK = 'Test_log.bak'
WITH FORMAT
, INIT
, NAME = 'Test Log backup'
, SKIP
, NOREWIND
, NOUNLOAD
, COMPRESSION
, STATS = 1;
GO
ALTER DATABASE test SET SINGLE_USER;
GO
USE Test;
GO
IF EXISTS (SELECT name FROM sys.key_constraints WHERE name = 'PK_temp')
ALTER TABLE temp DROP CONSTRAINT PK_temp;
IF EXISTS (SELECT name FROM sys.default_constraints
WHERE name = 'DF_temp_testdata')
ALTER TABLE temp DROP CONSTRAINT DF_temp_testdata;
IF EXISTS (SELECT name FROM sys.tables WHERE name = 'temp')
DROP TABLE temp;
GO
CREATE TABLE temp
(
tempID INT NOT NULL CONSTRAINT PK_temp PRIMARY KEY CLUSTERED IDENTITY(1,1)
, testdata uniqueidentifier CONSTRAINT DF_temp_testdata DEFAULT (NEWID())
);
GO
/* insert 10 rows into #temp */
INSERT INTO temp default values;
GO 10
/* get some necessary parameters */
DECLARE @partitionID bigint;
DECLARE @dbid smallint;
DECLARE @tblid int;
DECLARE @indexid int;
DECLARE @pageid bigint;
DECLARE @offset INT;
DECLARE @fileid INT;
SELECT @dbid = db_id('Test')
, @tblid = t.object_id
, @partitionID = p.partition_id
, @indexid = i.index_id
FROM sys.tables t
INNER JOIN sys.partitions p ON t.object_id = p.object_id
INNER JOIN sys.indexes i on t.object_id = i.object_id
WHERE t.name = 'temp';
SELECT TOP(1) @fileid = file_id
FROM sys.database_files;
SELECT TOP(1) @pageid = allocated_page_page_id
FROM sys.dm_db_database_page_allocations(@dbid, @tblid, null, @partitionID, 'LIMITED')
WHERE allocation_unit_type = 1;
/* get a random offset into the 8KB page */
SET @offset = FLOOR(rand() * 8192);
SELECT @offset;
/* 0x75 below is the letter 't' */
DBCC WRITEPAGE (@dbid, @fileid, @pageid, @offset, 1, 0x74, 1);
SELECT * FROM temp;
Msg 824, Level 24, State 2, Line 36
SQL Server detected a logical consistency-based I/O error: incorrect checksum
(expected: 0x298b2ce9; actual: 0x2ecb2ce9). It occurred during a read of page
(1:1054) in database ID 7 at offset 0x0000000083c000 in file 'C:\SQLServer
\MSSQL11.MSSQLSERVER\MSSQL\DATA\Test.mdf'. Additional messages in the SQL
Server error log or system event log may provide more detail. This is a
severe error condition that threatens database integrity and must be
corrected immediately. Complete a full database consistency check
(DBCC CHECKDB). This error can be caused by many factors; for more
information, see SQL Server Books Online.
Zu diesem Zeitpunkt werden Sie vom Datenbankmodul getrennt. Stellen Sie daher die Verbindung wieder her, um fortzufahren.
USE Test;
DBCC CHECKDB WITH NO_INFOMSGS, TABLERESULTS;
Korruption wird hier gemeldet.
DROP TABLE temp;
Msg 824, Level 24, State 2, Line 36
SQL Server detected a logical consistency-based I/O error: incorrect checksum
(expected: 0x298b2ce9; actual: 0x2ecb2ce9). It occurred during a read of page
(1:1054) in database ID 7 at offset 0x0000000083c000 in file 'C:\SQLServer
\MSSQL11.MSSQLSERVER\MSSQL\DATA\Test.mdf'. Additional messages in the SQL
Server error log or system event log may provide more detail. This is a
severe error condition that threatens database integrity and must be
corrected immediately. Complete a full database consistency check
(DBCC CHECKDB). This error can be caused by many factors; for more
information, see SQL Server Books Online.
Korruption wird hier gemeldet, DROP TABLE
schlägt fehl.
/* assuming ENTERPRISE or DEVELOPER edition of SQL Server,
I can use PAGE='' to restore a single page from backup */
USE Master;
RESTORE DATABASE Test PAGE = '1:1054' FROM DISK = 'Test_db.bak';
BACKUP LOG Test TO DISK = 'Test_log_1.bak';
RESTORE LOG Test FROM DISK = 'Test_log.bak';
RESTORE LOG Test FROM DISK = 'Test_log_1.bak';
Bearbeiten Sie # 2, um die angeforderten @@ VERSION-Informationen hinzuzufügen.
SELECT @@VERSION;
Kehrt zurück:
Microsoft SQL Server 2012 (SP1) - 11.0.3000.0 (X64)
Oct 19 2012 13:38:57
Copyright (c) Microsoft Corporation
Enterprise Evaluation Edition (64-bit) on Windows NT 6.2 <X64>
(Build 9200: )
Ich weiß, dass dies die Evaluation Edition ist. Wir haben Schlüssel für die Enterprise Edition und werden in Kürze ein Edition-Upgrade durchführen.
-T 3609
Ihrer Information, Tempdb wird zu Beginn beibehalten (undokumentiert, aber bereits bekannt )