Một trong những Máy chủ SQL của chúng tôi đã báo cáo lỗi sau đây:
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.
Chưa đầy 15 phút sau tôi đã kết nối với máy chủ và chạy:
SELECT name
FROM sys.databases
WHERE database_id = 2;
Mà trả về 'tempdb'. Sau đó tôi chạy:
DBCC CHECKDB ('tempdb') WITH NO_INFOMSGS, TABLERESULTS;
Mà trả về không có kết quả, cho thấy không có vấn đề với cơ sở dữ liệu bị ảnh hưởng.
Làm thế nào tham nhũng trong cơ sở dữ liệu dẫn đến thông báo lỗi ở trên mà DBCC CHECKDB
không báo cáo vấn đề? Tôi cho rằng nếu tính toán tổng kiểm tra trang không thành công, dẫn đến việc trang bị đánh dấu là nghi ngờ rằng bất kỳ đối tượng nào tham chiếu trang đó sẽ không thể bị hủy, nhưng tôi phải sai.
Khi một trang được đánh dấu là 'nghi ngờ', làm thế nào nó có thể được đánh dấu là không nghi ngờ, hoặc cố định hoặc tái sử dụng hoặc bất cứ điều gì DBCC CHECKDB
không báo cáo bất kỳ vấn đề nào với trang được đề cập?
Chỉnh sửa: 2013 / 02-27 13:24
Để giải trí, tôi đã cố gắng tạo lại tham nhũng trong TempDB khi cho rằng bảng #temp là thủ phạm.
Tuy nhiên, vì tôi không thể đặt SINGLE_USER
tùy chọn trong TempDB, tôi không thể sử dụng DBCC WRITEPAGE
để làm hỏng trang và do đó tôi không thể buộc tham nhũng trong TempDB.
Thay vì sử dụng, DBCC WRITEPAGE
người ta có thể đặt cơ sở dữ liệu ngoại tuyến và sử dụng trình soạn thảo hex để sửa đổi các byte ngẫu nhiên trong tệp db. Tất nhiên, điều đó không hoạt động trên TempDB vì công cụ cơ sở dữ liệu không thể chạy với TempDB ngoại tuyến.
Nếu bạn dừng cá thể, TempDB sẽ tự động được tạo lại ở lần khởi động tiếp theo; do đó sẽ không làm điều đó.
Nếu bất cứ ai có thể nghĩ ra cách tái tạo tham nhũng này, tôi sẽ sẵn sàng nghiên cứu thêm.
Để kiểm tra giả thuyết rằng một trang bị hỏng có thể được sửa bằng cách DROP TABLE
tôi tạo một cơ sở dữ liệu kiểm tra và sử dụng tập lệnh sau để làm hỏng một trang, sau đó thử bỏ bảng bị ảnh hưởng. Kết quả ở đây là bảng không thể bị xóa; Tôi đã phải RESTORE DATABASE Testdb PAGE = ''...
phục hồi các trang bị ảnh hưởng. Tôi giả sử nếu tôi đã thực hiện một thay đổi đối với một số phần khác của trang được đề cập, có lẽ trang có thể đã được sửa chữa bằng DROP TABLE
hoặc có lẽ 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.
Tại thời điểm này, bạn bị ngắt kết nối với công cụ cơ sở dữ liệu, vì vậy hãy kết nối lại để tiếp tục.
USE Test;
DBCC CHECKDB WITH NO_INFOMSGS, TABLERESULTS;
Tham nhũng được báo cáo ở đây.
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.
Tham nhũng được báo cáo ở đây, DROP TABLE
thất bại.
/* 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';
Chỉnh sửa # 2, để thêm thông tin @@ VERSION được yêu cầu.
SELECT @@VERSION;
Trả về:
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: )
Tôi biết đây là Phiên bản Đánh giá, chúng tôi có các khóa cho Phiên bản Doanh nghiệp và sẽ sớm thực hiện Nâng cấp Phiên bản.
-T 3609
sẽ bảo tồn tempdb khi bắt đầu (không có giấy tờ nhưng đã được biết đến )