Um de nossos servidores SQL relatou o seguinte erro recentemente:
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 depois, conectei-me ao servidor e executei:
SELECT name
FROM sys.databases
WHERE database_id = 2;
O que retornou 'tempdb'. Eu então corri:
DBCC CHECKDB ('tempdb') WITH NO_INFOMSGS, TABLERESULTS;
O que não retornou resultados, indicando que não há problemas com o banco de dados afetado.
Como a corrupção no banco de dados resultou na mensagem de erro acima e ainda DBCC CHECKDB
não relatou o problema? Presumo que um cálculo de soma de verificação de página falhe, resultando na página sendo marcada como suspeita de que qualquer objeto que faça referência a essa página não possa ser descartado, mas devo estar errado.
Depois que uma página é marcada como 'suspeita', como pode ser marcada como não suspeita, ou corrigida ou reutilizada, ou qualquer outra coisa que DBCC CHECKDB
não relate nenhum problema com a página em questão?
Edit: 2013-02-27 13:24
Apenas por diversão, tentei recriar a corrupção no TempDB, assumindo que uma tabela #temp era a culpada.
No entanto, como não consigo definir a SINGLE_USER
opção no TempDB, não posso usar DBCC WRITEPAGE
para corromper uma página e, portanto, não posso forçar a corrupção no TempDB.
Em vez de usar, DBCC WRITEPAGE
pode-se definir o banco de dados offline e usar um editor hexadecimal para modificar bytes aleatórios no arquivo db. Obviamente, isso também não funciona no TempDB, pois o mecanismo do banco de dados não pode ser executado com o TempDB offline.
Se você parar a instância, o TempDB será recriado automaticamente na próxima inicialização; portanto, isso também não funcionará.
Se alguém puder pensar em uma maneira de recriar essa corrupção, eu estaria disposto a fazer pesquisas adicionais.
Para testar a hipótese de que uma página corrompida não pode ser corrigida, DROP TABLE
criei um banco de dados de teste e usei o script a seguir para corromper uma página e, em seguida, tente descartar a tabela afetada. O resultado aqui foi que a tabela não pôde ser excluída; Eu precisei para RESTORE DATABASE Testdb PAGE = ''...
recuperar a página afetada. Presumo que, se eu tivesse feito uma alteração em alguma outra parte da página em questão, talvez a página pudesse ter sido corrigida DROP TABLE
ou talvez 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.
Nesse ponto, você é desconectado do mecanismo de banco de dados, reconecte-se para continuar.
USE Test;
DBCC CHECKDB WITH NO_INFOMSGS, TABLERESULTS;
A corrupção é relatada aqui.
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.
A corrupção é relatada aqui, DROP TABLE
falha.
/* 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';
Edite # 2, para adicionar as informações solicitadas pela @@ VERSION.
SELECT @@VERSION;
Devoluções:
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: )
Sei que esta é a Edição de Avaliação, temos chaves para a Edição Empresarial e faremos uma Atualização da Edição em breve.
fonte
-T 3609
irá preservar tempdb no início (em situação irregular, mas já conhecida )Respostas:
Este é um problema conhecido com uma correção:
CORRECÇÃO: Erro "Nenhuma entrada de catálogo encontrada para a ID da partição no banco de dados" quando você usa o SQL Server 2012
Corrigido em:
Atualização cumulativa 4 para SQL Server 2012 SP2
Atualização cumulativa 13 para SQL Server 2012 SP1
Sua versão (11.0.3000.0) é o SQL Server 2012 SP1 RTM
fonte
Executar
CHECKDB
contratempdb
não é o mesmo que executá-lo em um banco de dados do usuário.Do MSDN :
fonte
Sim, mas especificamente, um erro de catálogo não pode ser verificado no TempDB. Você deve reciclar o SQL Server, se possível, para corrigir isso. Por MSDN:
"A execução do DBCC CHECKCATALOG no tempdb não executa nenhuma verificação. Isso ocorre porque, por motivos de desempenho, as capturas instantâneas do banco de dados não estão disponíveis no tempdb. Isso significa que a consistência transacional necessária não pode ser obtida. Recicle o servidor para resolver quaisquer problemas de metadados do tempdb."
O artigo do MSDB está aqui: http://msdn.microsoft.com/en-us/library/ms186720.aspx
fonte