日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

【SQL Server备份恢复】数据库恢复:对page header的恢复

發布時間:2025/3/15 数据库 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【SQL Server备份恢复】数据库恢复:对page header的恢复 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前兩天在論壇,看到有個網友提問,說是:

格式化磁盤前把.mdf和.ldf拷貝出來了,然后格式化完成后在拷貝回去(拷貝前后都沒有錯誤提示,文件大小也一樣),在企業管理器中附加數據庫出錯,提示“錯誤823”,附加數據庫失敗。從網上搜了搜方案:重建同名數據庫之類的做法都試過了,都不能解決問題。請問版主或各位高手,有什么解決方案嗎?
注:拷貝之前數據庫使用正常,并且以前都是此種方法附加的,這次不知如何出現這樣的問題了。


幫他嘗試恢復:

1、他已經按照網上的方法,新建了一個同名的數據庫。


2、停止服務,然后把原始的文件拷貝到目錄中。


3、啟動服務,發現數據庫處于質疑狀態。


4、運行如下命令,都報錯:打不開數據庫

dbcc checkdb(xxx); dbcc checkdb(xxx,repair_allow_data_loss);


5、運行如下命令成功,?設置數據庫為緊急模式 ?

Use Master GO sp_configure 'allow updates', 1 reconfigure with override GO UPDATE sysdatabases SET status = 32768 where name = 'xxx' GO
6、再次運行命令,報錯:數據庫必須處于單用戶模式

dbcc checkdb(xxx,repair_allow_data_loss);
7、如果如下命令,設置數據庫為單用戶模式:

alter database test set single_user
8、再次運行命令,還是報錯:數據庫必須處于單用戶模式

dbcc checkdb(xxx,repair_allow_data_loss);
在這里就覺得很奇怪,明明已經設置為單用戶模式了,怎么還報這個錯誤呢?

在網上找了一下,發現有很多人都有這個問題,但是沒有解決辦法。


9、嘗試運行如下命令,但類似這樣的報錯:

服務器: 消息 8909,級別 16,狀態 1,行 1 表錯誤: 對象 ID 0,索引 ID 0,頁 ID 0。 服務器: 消息 8966,級別 16,狀態 1,行 1 未能讀取并閂鎖頁 (1:123456)(用閂鎖類型 SH)。sysobjects 失敗。
在網上找到一篇文章:

sql server 系統表損壞修復方法?http://wenku.baidu.com/view/901cd511f18583d04964592e

這個文章中提到的解決方法就是,新建一個數據庫,通過dts,把原來數據庫的數據,導出到新的數據庫中,但前提是其中的表都能訪問,也就是能夠select * from 表,否則就沒用了。


那么有沒有什么好的辦法,能修復呢?

在網上找了一下,發現有專業的數據恢復公司,能恢復這種錯誤,從文章中提到的信息來看,應該通過直接構造損壞的頁面來修復的。


由于這種情況比較難重現,所以這里模擬當某個數據頁的page header損壞時,如何手動修復這個數據頁,其實就是一個復制粘帖的過程。


1、先創建一個數據庫,創建表,插入數據:

create database w go use w go if OBJECT_ID('test') is not null drop table test select * into test from sys.objects go insert into test select * from test
2、分離數據庫w,把數據文件和日志文件,直接復制到一個備份目錄。


3、本來通過dbcc writelog來修改數據,但是應該是沒有修改好。

dbcc writepage的語法為: dbcc writepage ({ dbid,'dbname' }, fileid, pageid, offset, length, data) --生成96個字節的數據 select '0x'+replicate('00',96) dbcc writepage('w',1,310,0,96, 0x000000000000000000000000000000000000000 00000000000000000000000000000000000000000 00000000000000000000000000000000000000000 00000000000000000000000000000000000000000 000000000000000000000000000000) /* 消息 8939,級別 16,狀態 5,第 1 行 表錯誤: 對象 ID 0,索引 ID -1,分區 ID 0,分配單元 ID 0 (類型為 Unknown),頁 (0:0)。測試(m_headerVersion == HEADER_7_0)失敗。值為 0 和 1。 消息 8939,級別 16,狀態 6,第 1 行 表錯誤: 對象 ID 0,索引 ID -1,分區 ID 0,分配單元 ID 0 (類型為 Unknown),頁 (0:0)。測試((m_type >= DATA_PAGE && m_type <= UNDOFILE_HEADER_PAGE) || (m_type == UNKNOWN_PAGE && level == BASIC_HEADER))失敗。值為 0 和 0。 消息 8939,級別 16,狀態 7,第 1 行 表錯誤: 對象 ID 0,索引 ID -1,分區 ID 0,分配單元 ID 0 (類型為 Unknown),頁 (0:0)。測試(m_freeData >= PageHeaderOverhead () && m_freeData <= (UINT)PAGESIZE - m_slotCnt * sizeof (Slot))失敗。值為 0 和 8192。 DBCC 執行完畢。如果 DBCC 輸出了錯誤信息,請與系統管理員聯系。 */
所以,改用二進制編輯工具,輸入:0x0026C000,定位到這個物理偏移,然后修改了數據庫w中的fileID為1,pageID為310的,前96個字節全為00,這個正好是page header部分:

select 8*1024*310 as '310頁在文件中的物理偏移', CAST(8*1024*310 as varbinary) '轉化為16進制' /* 310頁在文件中的物理偏移 轉化為16進制 2539520 0x0026C000 */






4、重新附加這個數據庫

dbcc checkdb(w) /* 消息 8909,級別 16,狀態 1,第 1 行 表錯誤: 對象 ID 0,索引 ID -1,分區 ID 0,分配單元 ID 0 (類型為 Unknown),頁 ID (1:310) 在其頁頭中包含錯誤的頁 ID。頁頭中的 PageId = (0:0)。 CHECKDB 發現有 0 個分配錯誤和 1 個一致性錯誤與任何單個的對象都沒有關聯。 消息 8928,級別 16,狀態 1,第 1 行 對象 ID 981578535,索引 ID 0,分區 ID 72057594038910976,分配單元 ID 72057594042580992 (類型為 In-row data): 無法處理頁 (1:310)。有關詳細信息,請參閱其他錯誤消息。 CHECKDB 在數據庫 'w' 中發現 0 個分配錯誤和 2 個一致性錯誤。 對于由 DBCC CHECKDB (w)發現的錯誤,repair_allow_data_loss 是最低的修復級別。 DBCC 執行完畢。如果 DBCC 輸出了錯誤信息,請與系統管理員聯系。 */
5、把數據庫分離,從備份的文件中,復制page header到這個文件



6、再次附加數據庫,就可以查詢了。

不過,使用repair_allow_data_loss也可以恢復。


轉載于:https://blog.51cto.com/yupeigu/1367935

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的【SQL Server备份恢复】数据库恢复:对page header的恢复的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。