web-dev-qa-db-fra.com

Comment une partition corrompue de TEMPDB pourrait-elle entraîner une notification de DBCC CheckDB.

L'un de nos serveurs SQL a récemment signalé l'erreur suivante:

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.

Moins de 15 minutes plus tard, j'ai connecté au serveur et a couru:

SELECT name
FROM sys.databases
WHERE database_id = 2;

Qui a retourné 'TEMPDB'. J'ai ensuite couru:

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

Ce qui n'a renvoyé aucun résultat, indiquant aucun problème avec la base de données affectée.

Comment la corruption dans la base de données pourrait-elle aboutir au message d'erreur ci-dessus pourtant DBCC CHECKDB ne signalez pas le problème? Je présume si un calcul de la page de contrôle de page échoue, ce qui a entraîné la marquage de la page comme suspect que tout objet référencant cette page ne pourrait pas être abandonné, mais je dois avoir tort.

Une fois qu'une page est marquée "suspect", comment peut-elle être marquée non-suspect, ni fixe, ni réutilisée, ou quelque telle telle que DBCC CHECKDB ne signale aucun problème avec la page en question?


EDIT: 2013-02-27 13:24

Juste pour le plaisir, j'ai essayé de recréer la corruption dans TEMPDB en supposant qu'une table #TEpp était le coupable.

Cependant, puisque je ne peux pas régler le SINGLE_USER Option dans TEMPDB, je ne peux pas utiliser DBCC WRITEPAGE Pour corrompre une page, et donc je ne peux donc pas forcer la corruption dans TEMPDB.

À la place d'utiliser DBCC WRITEPAGE On pourrait définir la base de données hors ligne et utiliser un éditeur Hex pour modifier des octets aléatoires dans le fichier DB. Bien sûr, cela ne fonctionne pas non plus sur TEMPDB, car le moteur de base de données ne peut pas fonctionner avec TEMPDB hors ligne.

Si vous arrêtez l'instance, TEMPDB est automatiquement recréé au démarrage suivant; Par conséquent, cela ne fera pas l'affaire non plus.

Si quelqu'un peut penser à un moyen de recréer cette corruption, je serais prêt à faire de nouvelles recherches.

Afin de tester l'hypothèse qu'une page corrompue ne peut pas être corrigée par DROP TABLE J'ai créé une base de données de test et utilisé le script suivant pour corrompre une page, puis essayez de déposer la table concernée. Résultat ici était la table ne pouvait pas être supprimée; J'ai dû RESTORE DATABASE Testdb PAGE = ''... Afin de récupérer la page concernée. Je suppose que si j'avais apporté une autre partie de la page en question, peut-être que la page aurait peut-être été corrigée avec DROP TABLE ou peut-être 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.

À ce stade, vous vous êtes déconnecté du moteur de base de données, alors reconnectez-vous à continuer.

USE Test;
DBCC CHECKDB WITH NO_INFOMSGS, TABLERESULTS;

La corruption est rapportée ici.

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 corruption est rapportée ici, DROP TABLE échoue.

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

Edit n ° 2, pour ajouter les informations @@ version demandées.

SELECT @@VERSION;

Retour:

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

Je sais que c'est l'édition d'évaluation, nous avons des clés pour l'édition Enterprise et effectuera une mise à niveau d'édition bientôt.

9
Max Vernon

Ceci est un problème connu avec un correctif:

Correction: "Aucune entrée de catalogue trouvé pour la partition ID dans la base de données" Erreur lorsque vous utilisez SQL Server 2012

Supposons que vous interrogez la table TEMPDB.SYS.ALLOCATION_UNITS dans Microsoft SQL Server 2012. Lorsque vous utilisez Nolock Indicateur dans la requête ou la requête est sous le niveau de l'isolation de transaction disponible en lecture, vous recevez le message d'erreur intermittent 608 suivant:

ERREUR: 608 Gravité: 16 State: 1
[.____] Aucune entrée de catalogue n'a été trouvée pour la partition dans la base de données. Les métadonnées sont incompatibles. Exécuter DBCC CheckDB pour vérifier une corruption de métadonnées

Remarque La commande DBCC Checkdb ne montre aucun signe de corruption de base de données.

Corrigé dans:

Votre version (11.0.3000.0) est SQL Server 2012 SP1 RTM

3
Mitch Wheat

Exécution CHECKDB contre tempdb n'est pas la même chose que l'exécution de la base de données utilisateur.

De - MSDN :

Exécuter DBCC CheckdB sur TEMPDB n'effectue aucune vérification d'allocation ou de catalogue et doit acquérir des verrouillages de table partagés pour effectuer des contrôles de table. En effet, pour des raisons de performances, des instantanés de base de données ne sont pas disponibles sur TEMPDB. Cela signifie que la consistance transactionnelle requise ne peut être obtenue.

7
Jon Seigel

Oui, mais spécifiquement, une erreur de catalogue ne peut pas être vérifiée dans TEMPDB. Vous devez recycler SQL Server si possible pour résoudre ce problème. Par msdn:

"Exécution de DBCC CheckCatalog contre TEMPDB n'effectue aucune vérification. En effet, pour des raisons de performances, les instantanés de base de données ne sont pas disponibles sur TEMPDB. Cela signifie que la cohérence transactionnelle requise ne peut pas être obtenue. Recycler le serveur pour résoudre les problèmes de métadonnées TEMPDB."

L'article MSDB est ici: http://msdn.microsoft.com/en-us/library/ms186720.aspx

6
Cate Donoghue