Salah satu Server SQL kami melaporkan kesalahan berikut baru-baru ini:
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.
Kurang dari 15 menit kemudian saya terhubung ke server dan berlari:
SELECT name
FROM sys.databases
WHERE database_id = 2;
Yang mengembalikan 'tempdb'. Saya kemudian berlari:
DBCC CHECKDB ('tempdb') WITH NO_INFOMSGS, TABLERESULTS;
Yang tidak mengembalikan hasil, menunjukkan tidak ada masalah dengan database yang terpengaruh.
Bagaimana bisa korupsi di database menghasilkan pesan kesalahan di atas namun DBCC CHECKDB
tidak melaporkan masalah? Saya kira jika penghitungan checksum halaman gagal, mengakibatkan halaman tersebut ditandai sebagai tersangka bahwa objek apa pun yang mereferensikan halaman itu tidak akan bisa dijatuhkan, tetapi saya pasti salah.
Setelah halaman ditandai 'tersangka', bagaimana bisa ditandai bukan-tersangka, atau diperbaiki, atau digunakan kembali, atau apa pun yang sedemikian sehingga DBCC CHECKDB
tidak melaporkan masalah dengan halaman yang dimaksud?
Edit: 2013-02-27 13:24
Hanya untuk bersenang-senang, saya mencoba membuat ulang korupsi di TempDB dengan asumsi tabel #temp adalah penyebabnya.
Namun, karena saya tidak bisa mengatur SINGLE_USER
opsi di TempDB, saya tidak bisa menggunakanDBCC WRITEPAGE
untuk merusak halaman, dan karena itu saya tidak bisa memaksa korupsi di TempDB.
Alih-alih menggunakan DBCC WRITEPAGE
satu dapat mengatur database offline dan menggunakan hex editor untuk memodifikasi byte acak dalam file db. Tentu saja, itu tidak berfungsi dengan baik pada TempDB karena mesin database tidak dapat berjalan dengan TempDB offline.
Jika Anda menghentikan instance, TempDB secara otomatis dibuat ulang pada startup berikutnya; karenanya tidak akan melakukan trik juga.
Jika ada yang bisa memikirkan cara untuk menciptakan korupsi ini, saya bersedia melakukan penelitian lebih lanjut.
Untuk menguji hipotesis bahwa halaman yang rusak tidak dapat diperbaiki oleh DROP TABLE
saya membuat database pengujian dan menggunakan skrip berikut untuk merusak halaman, kemudian mencoba untuk menjatuhkan tabel yang terpengaruh. Hasil di sini adalah tabel tidak dapat dihapus; Saya harus RESTORE DATABASE Testdb PAGE = ''...
memulihkan halaman yang terpengaruh. Saya berasumsi jika saya telah membuat perubahan pada bagian lain dari halaman tersebut, mungkin halaman tersebut dapat diperbaiki dengan DROP TABLE
atau mungkin 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.
Pada titik ini Anda terputus dari mesin basis data, jadi sambungkan kembali untuk melanjutkan.
USE Test;
DBCC CHECKDB WITH NO_INFOMSGS, TABLERESULTS;
Korupsi dilaporkan di sini.
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.
Korupsi dilaporkan di sini, DROP TABLE
gagal.
/* 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 # 2, untuk menambahkan info @@ VERSION yang diminta.
SELECT @@VERSION;
Pengembalian:
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: )
Saya tahu ini adalah Edisi Evaluasi, kami memiliki kunci untuk Edisi Perusahaan, dan akan segera melakukan Peningkatan Edisi.
sumber
-T 3609
akan mempertahankan tempdb di awal (tidak berdokumen tetapi sudah diketahui )Jawaban:
Ini adalah masalah yang diketahui dengan perbaikan:
PERBAIKI: "Tidak ada entri katalog yang ditemukan untuk partisi ID dalam database" kesalahan ketika Anda menggunakan SQL Server 2012
Diperbaiki:
Pembaruan kumulatif 4 untuk SQL Server 2012 SP2
Pembaruan Kumulatif 13 untuk SQL Server 2012 SP1
Versi Anda (11.0.3000.0) adalah SQL Server 2012 SP1 RTM
sumber
Menjalankan
CHECKDB
melawantempdb
tidak sama dengan menjalankannya terhadap basis data pengguna.Dari MSDN :
sumber
Ya, tetapi secara khusus, kesalahan katalog tidak dapat diperiksa di TempDB. Anda harus mendaur ulang SQL Server jika memungkinkan untuk memperbaikinya. Per MSDN:
"Menjalankan DBCC CHECKCATALOG terhadap tempdb tidak melakukan pemeriksaan. Ini karena, untuk alasan kinerja, snapshot basis data tidak tersedia di tempdb. Ini berarti bahwa konsistensi transaksional yang diperlukan tidak dapat diperoleh. Daur ulang server untuk menyelesaikan masalah metadata tempdb apa pun."
Artikel MSDB ada di sini: http://msdn.microsoft.com/en-us/library/ms186720.aspx
sumber