Trên SQL Server 2017 (CU3), bất cứ khi nào tôi kích hoạt nén sao lưu trên một trong các cơ sở dữ liệu TDE của mình, quy trình sao lưu luôn làm hỏng một trang cụ thể trong cơ sở dữ liệu. Nếu tôi chạy bản sao lưu mà không nén, nó sẽ không bị hỏng. Dưới đây là các bước tôi đã thực hiện để xác minh và tái tạo vấn đề này:
- Chạy DBCC CheckDB trên cơ sở dữ liệu "TDE_DB1"; tất cả đều tốt, không có lỗi;
- Sao lưu thành công cơ sở dữ liệu mà không cần nén; RESTORE XÁC MINH nói tất cả là tốt;
- Khôi phục thành công cơ sở dữ liệu dưới dạng "TDE_DB2"; tất cả đều tốt, DBCC CheckDB cho thấy không có lỗi;
- Sao lưu thành công cơ sở dữ liệu "TDE_DB1" VỚI nén; RESTORE XÁC MINH lỗi, nói rằng "Đã phát hiện thấy hư hỏng cho bộ sao lưu";
- Cố gắng khôi phục cơ sở dữ liệu dưới dạng "TDE_DB2"; lỗi, nói rằng "RESTORE đã phát hiện lỗi trên trang (1: 92454) trong cơ sở dữ liệu"
- Lặp lại các bước 1-3; mọi thứ đều tốt;
- DROP "TDE_DB1" và "TDE_DB2"; Khôi phục "TDE_DB1" từ bản sao lưu; mọi thứ đều tốt;
- Lặp lại các bước 1-5; nhận được kết quả tương tự;
Tóm lại: Cơ sở dữ liệu và các bản sao lưu thông thường có vẻ ổn, chạy CHECKDB trên cơ sở dữ liệu và XÁC MINH trên các bản sao lưu không báo cáo bất kỳ lỗi nào. Sao lưu cơ sở dữ liệu với nén dường như gây ra tham nhũng.
Dưới đây là các mẫu mã có lỗi. (Lưu ý: Cần có MAXTRANSFERSIZE để sử dụng nén với cơ sở dữ liệu TDE )
-- Good, completes with no corruption;
BACKUP DATABASE [TDE_DB1] TO DISK = N'E:\MSSQL\Backup\TDE_DB1a.bak' WITH CHECKSUM;
RESTORE VERIFYONLY FROM DISK = N'E:\MSSQL\Backup\TDE_DB1a.bak' WITH CHECKSUM;
RESTORE DATABASE [TDE_DB2]
FROM DISK = 'E:\MSSQL\Backup\TDE_DB1a.bak'
WITH MOVE 'DataFileName' to 'E:\MSSQL\Data\TDE_DB2.mdf'
,MOVE 'LogFileName' to 'F:\MSSQL\Log\TDE_DB2_log.ldf';
-- Bad, I haz corruption;
BACKUP DATABASE [TDE_DB1] TO DISK = N'E:\MSSQL\Backup\TDE_DB1b.bak' WITH CHECKSUM, COMPRESSION, MAXTRANSFERSIZE = 131072;
RESTORE VERIFYONLY FROM DISK = N'E:\MSSQL\Backup\TDE_DB1b.bak' WITH CHECKSUM;
-- ERROR
--Msg 3189, Level 16, State 1, Line 1
--Damage to the backup set was detected.
--Msg 3013, Level 16, State 1, Line 1
--VERIFY DATABASE is terminating abnormally.
RESTORE DATABASE [TDE_DB2]
FROM DISK = 'E:\MSSQL\Backup\TDE_DB1b.bak'
WITH MOVE 'DataFileName' to 'E:\MSSQL\Data\TDE_DB2.mdf'
,MOVE 'LogFileName' to 'F:\MSSQL\Log\TDE_DB2_log.ldf';
-- ERROR
--Msg 3183, Level 16, State 1, Line 7
--RESTORE detected an error on page (1:92454) in database "TDE_DB2" as read from the backup set.
--Msg 3013, Level 16, State 1, Line 7
--RESTORE DATABASE is terminating abnormally.
Sau đó tôi đã cố kiểm tra trang được báo cáo là có lỗi (Nó luôn luôn là cùng một trang.), Nhưng TRANG DBCC báo cáo rằng ObjectId là 0. Theo bài viết này của Paul Randal có nghĩa là không tìm thấy siêu dữ liệu và một trong những lý do có thể là bản thân trang bị hỏng và các giá trị không chính xác đã được sử dụng để cố gắng tra cứu siêu dữ liệu. Lời khuyên của anh ấy là chạy CHECKDB, điều mà tôi không thể làm được vì bản sao lưu bị hỏng sẽ không khôi phục.
Tôi đã thử các đề xuất từ SO Post này (Thêm INIT và FORMAT vào lệnh BACKUP) để đặt lại siêu dữ liệu, nhưng dường như điều đó không thay đổi gì cả, tôi vẫn bị hỏng trên bản sao lưu nén.
Điều này chỉ xảy ra với một trong các cơ sở dữ liệu TDE của tôi. Tôi có 4 cơ sở dữ liệu TDE khác trên cùng một máy chủ và chúng không gặp phải vấn đề này. Điều đó cho tôi biết rằng có thể có một vấn đề tiềm ẩn với cơ sở dữ liệu cụ thể này. Tôi nhận ra rằng giải pháp dễ dàng là không sử dụng nén, nhưng tôi cảm thấy như đây thực sự có thể là một cảnh báo sớm cho một vấn đề lớn hơn sắp xảy ra.
Có ai từng thấy điều này trước đây, hoặc có bất kỳ ý tưởng tại sao nén sẽ làm hỏng trang đó không? Tại thời điểm này, tôi không biết phải làm gì tiếp theo. Tôi đã xem xét khôi phục trang từ bản sao lưu trước đó, nhưng tôi không nghĩ điều đó có vấn đề vì trang trong cơ sở dữ liệu thông thường có vẻ ổn.
CẬP NHẬT 1: Dưới đây là kết quả từ TRANG DBCC, với tùy chọn 0:
Thực hiện DBCC hoàn thành. Nếu DBCC in thông báo lỗi, liên hệ với quản trị viên hệ thống của bạn.
TRANG: (1: 92454)
ĐỆM:
BUF @ 0x000002187AE55640
bpage = 0x000002184865E000 bhash = 0x0000000000000000
bpageno = (1: 92.454) bdbid = 8 breferences = 0 bcputicks = 563 bsampleCount = 1
bUse1 = 51.429 bstat = 0x809 viết blog = 0x15a
bnext = 0x0000000000000000 bDirtyContext = 0x0000000000000000 bstat2 = 0x0TRANG CHỦ ĐẦU TƯ:
Trang @ 0x000002184865E000
m_pageId = (1: 92.454) m_headerVersion = 111
m_type = 189 m_typeFlagBits = 0x2d m_level = 197
m_flagBits = 0x525e m_objId (AllocUnitId.idObj) = 788.815.194
m_indexId (AllocUnitId.idInd) = 515 Metadata: AllocUnitId = 145011308798541824 Metadata: PartitionID = 0 Metadata: IndexId = -1 Metadata: ObjectId = 0 m_prevPage = (
32842: 1881351155) m_nextPage = 14755
m_xdesId = (12811: 1559482793) m_ghostRecCnt =
12339 m_tornBits = -1381699202 DB Frag ID = 1Tình trạng phân bổ
GAM (1: 2) = GIAO SGAM (1: 3) = không được phân bổ
PFS (1: 88.968) = 0x0 0_PCT_FULL DIFF (1: 6) = không thay đổi
ML (1: 7) = KHÔNG MIN_LOGGED
Nếu tôi cố chạy TRANG DBCC với các tùy chọn khác, tôi sẽ gặp các lỗi sau:
TRANG DBCC với tùy chọn 1: Msg 0, Cấp 11, Trạng thái 0, Dòng 0 Đã xảy ra lỗi nghiêm trọng trên lệnh hiện tại. Các kết quả, nếu có, cần được loại bỏ.
TRANG DBCC với tùy chọn 3: Msg 2514, Cấp 16, Trạng thái 5, Dòng 3 Đã xảy ra lỗi TRANG DBCC: Loại trang không hợp lệ - kiểu kết xuất 3 không thể.
CẬP NHẬT 2: Đây là một số kết quả từ sys.dm_db_database_page_allocations DMO:
object_id = 75 index_id = 1 rowset_id = 281474981625856 allocation_unit_id = 281474981625856
allocation_unit_type = 1 allocation_unit_type_desc = IN_ROW_DATA extent_file_id = 1 extent_page_id = 92.448
allocated_page_iam_file_id = 1 allocated_page_iam_page_id = 104
allocated_page_file_id = 1 allocated_page_page_id = 92.454
is_allocated = 0 is_iam_page = 0 is_mixed_page_allocation = 0