¿Cómo podría una partición corrupta en TempDB hacer que DBCC CHECKDB no informe ningún problema?


9

Uno de nuestros servidores SQL informó el siguiente error recientemente:

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.

Menos de 15 minutos después me conecté al servidor y ejecuté:

SELECT name
FROM sys.databases
WHERE database_id = 2;

Que devolvió 'tempdb'. Entonces corrí:

DBCC CHECKDB ('tempdb') WITH NO_INFOMSGS, TABLERESULTS;

Lo cual no arrojó resultados, lo que indica que no hay problemas con la base de datos afectada.

¿Cómo podría la corrupción en la base de datos dar como resultado el mensaje de error anterior sin DBCC CHECKDBinformar el problema? Supongo que si falla el cálculo de una suma de comprobación de la página, lo que hace que la página se marque como sospechosa de que no se podrá descartar ningún objeto que haga referencia a esa página, pero debo estar equivocado.

Una vez que una página se marca como 'sospechosa', ¿cómo se puede marcar como no sospechosa, o reparada, o reutilizada, o lo que sea que DBCC CHECKDBno informe ningún problema con la página en cuestión?


Editar: 2013-02-27 13:24

Solo por diversión, intenté recrear la corrupción en TempDB asumiendo que una tabla #temp era la culpable.

Sin embargo, como no puedo configurar la SINGLE_USERopción en TempDB, no puedo usar DBCC WRITEPAGEpara dañar una página y, por lo tanto, no puedo forzar la corrupción en TempDB.

En lugar de usar DBCC WRITEPAGEuno, podría establecer la base de datos fuera de línea y usar un editor hexadecimal para modificar bytes aleatorios en el archivo db. Por supuesto, eso tampoco funciona en TempDB ya que el motor de base de datos no puede ejecutarse con TempDB sin conexión.

Si detiene la instancia, TempDB se recrea automáticamente en el próximo inicio; por lo tanto, eso tampoco funcionará.

Si alguien puede pensar en una manera de recrear esta corrupción, estaría dispuesto a investigar más.

Para probar la hipótesis de que una página dañada no puede repararse DROP TABLE, creé una base de datos de prueba y utilicé el siguiente script para dañar una página, luego intenté descartar la tabla afectada. El resultado aquí fue que la tabla no se pudo eliminar; Tuve que hacerlo RESTORE DATABASE Testdb PAGE = ''...para recuperar la página afectada. Supongo que si hubiera hecho un cambio en alguna otra parte de la página en cuestión, tal vez la página podría haber sido corregida DROP TABLEo tal vez 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.

En este punto, te desconectas del motor de la base de datos, así que vuelve a conectarte para continuar.

USE Test;
DBCC CHECKDB WITH NO_INFOMSGS, TABLERESULTS;

La corrupción se informa aquí.

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.

La corrupción se informa aquí, DROP TABLEfalla.

/* 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';

Editar # 2, para agregar la información @@ VERSION solicitada.

SELECT @@VERSION;

Devoluciones:

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: )

Sé que esta es la Edición de Evaluación, tenemos claves para la Edición Enterprise, y pronto haremos una Actualización de Edición.


2
FYI -T 3609preservará tempdb al inicio (indocumentado pero ya conocido )
Remus Rusanu

Respuestas:


3

Este es un problema conocido con una solución:

REVISIÓN: error "No se encontró entrada de catálogo para ID de partición en la base de datos" cuando utiliza SQL Server 2012

Suponga que consulta la tabla tempdb.sys.allocation_units en Microsoft SQL Server 2012. Cuando utiliza la sugerencia NOLOCK en la consulta o la consulta está bajo el nivel de aislamiento de transacción LEER NO COMPROMETIDO, recibe el siguiente mensaje de error 608 intermitente:

Error: 608 Gravedad: 16 Estado: 1
No se encontró ninguna entrada de catálogo para la partición en la base de datos. Los metadatos son inconsistentes. Ejecute DBCC CHECKDB para verificar si hay daños en los metadatos

Nota El comando DBCC CHECKDB no muestra ningún signo de corrupción de la base de datos.

Arreglado en:

Su versión (11.0.3000.0) es SQL Server 2012 SP1 RTM


7

Ejecutar CHECKDBcontra tempdbno es lo mismo que ejecutarlo contra una base de datos de usuario.

De MSDN :

La ejecución de DBCC CHECKDB contra tempdb no realiza ninguna asignación o verificación de catálogo y debe adquirir bloqueos de tabla compartidos para realizar comprobaciones de tabla. Esto se debe a que, por razones de rendimiento, las instantáneas de la base de datos no están disponibles en tempdb. Esto significa que no se puede obtener la consistencia transaccional requerida.


6

Sí, pero específicamente, un error de catálogo no se puede verificar en TempDB. Debería reciclar SQL Server si es posible para solucionar esto. Por MSDN:

"Ejecutar DBCC CHECKCATALOG contra tempdb no realiza ninguna verificación. Esto se debe a que, por razones de rendimiento, las instantáneas de la base de datos no están disponibles en tempdb. Esto significa que no se puede obtener la consistencia transaccional requerida. Recicle el servidor para resolver cualquier problema de metadatos tempdb".

El artículo de MSDB está aquí: http://msdn.microsoft.com/en-us/library/ms186720.aspx

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.