Nén sao lưu gây ra tham nhũng trong cơ sở dữ liệu TDE SQL 2017


13

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:

  1. Chạy DBCC CheckDB trên cơ sở dữ liệu "TDE_DB1"; tất cả đều tốt, không có lỗi;
  2. 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;
  3. 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;
  4. 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";
  5. 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"
  6. Lặp lại các bước 1-3; mọi thứ đều tốt;
  7. DROP "TDE_DB1" và "TDE_DB2"; Khôi phục "TDE_DB1" từ bản sao lưu; mọi thứ đều tốt;
  8. 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 = 0x0

TRANG 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 = 1

Tì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

Câu trả lời:


8

Có vẻ như vấn đề này là với các cơ sở dữ liệu đã có các hoạt động SHRINK chạy trên chúng. Trong trường hợp của tôi, tôi đã lấy một bản sao của một trong các cơ sở dữ liệu sản xuất của chúng tôi trên SQL Server 2014 (đã được mã hóa bằng TDE), chạy DBCC SHRINKFILE trên cả tệp dữ liệu và nhật ký, sau đó sao lưu và khôi phục nó trên SQL mới của tôi Máy chủ 2017. (Lý do thu nhỏ là để giảm kích thước để chuyển bản sao lưu nhanh hơn.)

Để thử nghiệm, tôi đã khôi phục một bản sao của cơ sở dữ liệu mà tôi không chạy DBCC SHRINKFILE và nó không gặp vấn đề tham nhũng khi nén các bản sao lưu.

Vì vậy, để tóm tắt, kết quả thử nghiệm của tôi như sau:

  • Các hoạt động sao lưu / khôi phục bình thường trên cơ sở dữ liệu này đã thu nhỏ lại cơ sở dữ liệu TDE hoạt động chính xác trong SQL 2017
  • Nén các bản sao lưu của cơ sở dữ liệu TDE bị thu hẹp dường như gây ra tham nhũng trong bảng sys.sysmultiobjrefs
  • Nén các bản sao lưu của cơ sở dữ liệu TDE thông thường (không chạy DBCC SHRINKFILE) hoạt động chính xác và không báo cáo tham nhũng

Tôi không biết đây có phải là lỗi đã được xác nhận trong SQL Server 2017 không, nhưng tôi đã gửi kết quả của mình cho Microsoft để họ xem xét.

Vì vậy, đạo đức của câu chuyện này là: ĐỪNG CHIA SẺ CÁC CƠ SỞ CỦA BẠN! KHÔNG BAO GIỜ! :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.