Trước hết, cảm ơn vì đã xem xét điều này - Chúng tôi đã có một cơ sở dữ liệu lớn trong môi trường sản xuất của chúng tôi (1,26 TB), nó có vài trăm trang bị hỏng trong đó và đã thực hiện trong nhiều tháng, vì vậy tất cả tham nhũng tương tự của các bản sao lưu có sẵn.
Tôi đã bị kéo vào cuối tuần trước vì dường như các công việc được lên lịch để sắp xếp lại các chỉ mục đã bị thất bại trong một thời gian do tham nhũng và chúng tôi hiện đang ở giai đoạn mà các chỉ mục trên các bảng lớn nhất và được sử dụng phổ biến nhất nằm trong khoảng từ 50% và Phân mảnh 80% đang làm giảm nghiêm trọng hiệu suất ứng dụng.
Tôi đã giải trí một số ý tưởng về cách tôi có thể khắc phục tình trạng này (tin tôi đi, tôi không chỉ cởi mở với các lựa chọn thay thế) và từ những gì tôi đã đọc tôi nghĩ những âm thanh sau đây giống như một ý tưởng hay:
- Hãy sao lưu cơ sở dữ liệu bị hỏng từ sản xuất (SQL Server 2008R2), sao chép xuống máy chủ phát triển (cục bộ) của chúng tôi (SQL Server 2016) và chạy sửa chữa (không đủ không gian trên hệ thống sản xuất để có hai bản sao của db tham nhũng được đính kèm đồng thời).
- Khôi phục hai bản sao lưu bị hỏng này lên máy chủ phát triển nơi chúng tôi có đủ dung lượng.
- Chạy sửa chữa trên máy chủ phát triển với tùy chọn allow_data_loss cho một trong những dbs này, đổi tên thành "DbNameHereRepaired" (hầu hết các trang bị hỏng mà tôi đã xem với DBCC PAGE dù sao cũng đã đặt dữ liệu của chúng thành 0x00).
Đổi tên bản sao khác thành DbNameHereCorrupt, cố gắng chạy khôi phục cấp độ trang bằng mã sau đây:
alter database DbNameHereCorrupt set single_user with rollback immediate --set db to FULL recovery mode alter database DbNameHereCorrupt set recovery full --Declare paths for backups declare @fullBackupPath nvarchar(max) = N'D:\Restore\DbNameHereCorrupt-FullBackup.bck' declare @tranLogBackupPath nvarchar(max) = N'D:\Restore\DbNameHereCorrupt-LogBackup.bck' --Take full backup to begin new TLogChain backup database DbNameHereCorrupt to disk = @fullBackupPath with init, differential; --Immediately after whilst in single user mode, begin the t-log chain, this will also put the db in a restoring state backup log DbNameHereCorrupt to disk=@tranLogBackupPath with init, norecovery; --get corrupted pages declare @corruptedPages nvarchar(max) = ( select stuff ( ( select ',' + cast(s.file_id as nvarchar(20)) + ':' + cast(s.page_id as nvarchar(20)) from msdb.dbo.suspect_pages s where s.database_id = 20 for xml path('') ), 1 ,1, '' ) ) --push page-level restore restore database DbNameHereCorrupt page=@corruptedPages from disk=N'D:\Restore\DbNameHereRepaired.bak' with norecovery; -- restore log over db restore log DbNameHereCorrupt from disk=@tranLogBackupPath with norecovery; -- put db back into usable state restore database DbNameHereCorrupt with recovery --set db to SIMPLE recovery mode alter database DbNameHereCorrupt set recovery simple alter database DbNameHereCorrupt set multi_user
Điều này dường như hoạt động theo cách tôi nghĩ rằng nó được cho là cho đến khi tuyên bố khôi phục cấp độ trang, trong đó nó báo lỗi:
Msg 4346, Cấp 16, Trạng thái 1, Dòng 35 TRANG RESTORE không được phép với cơ sở dữ liệu sử dụng mô hình khôi phục đơn giản hoặc đã phá vỡ chuỗi sao lưu nhật ký.
Đây là lần đầu tiên tôi sử dụng mô hình khôi phục hoàn toàn, vì vậy tôi có thể đã làm gì đó sai ... Tôi có thể thấy những gì trông giống như một khoảng cách nhỏ giữa lsn cuối cùng của chênh lệch và sao lưu giao dịch, mà tôi đoán rằng ở đó không nên
Bất cứ ai cũng có thể thấy những gì tôi đã làm sai ở đây? Tôi đã cố gắng làm theo các ví dụ trên web rằng tất cả dường như theo một mô hình tương tự, nhưng tôi đoán tôi đang thiếu một cái gì đó?