超碰人人人人人,亚洲AV午夜福利精品一区二区,亚洲欧美综合区丁香五月1区,日韩欧美亚洲系列

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

拯救SQL Server數(shù)據(jù)庫(kù)事務(wù)日志文件損壞的終極大招

freeflydom
2025年2月18日 8:47 本文熱度 1174

在數(shù)據(jù)庫(kù)的日常管理中,我們不可避免的會(huì)遇到服務(wù)器突然斷電(沒(méi)有進(jìn)行電源冗余),服務(wù)器故障或者 SQL Server 服務(wù)突然停掉,

頭大的是ldf事務(wù)日志文件也損毀了,SQL Server服務(wù)器起來(lái)之后,發(fā)現(xiàn)數(shù)據(jù)庫(kù)處于"Recovery Pending" 狀態(tài)。

更麻煩的是該數(shù)據(jù)庫(kù)沒(méi)有任何備份或者備份已經(jīng)比較久遠(yuǎn);

當(dāng)然這些都不是最難的,最難的是連資深DBA使出ATTACH_REBUILD_LOG和 DBCC CEHECKDB 的 REPAIR_ALLOW_DATA_LOSS 選項(xiàng)等招數(shù)時(shí)候,

即使已經(jīng)做好了最壞打算,做了丟失部分?jǐn)?shù)據(jù)的準(zhǔn)備,數(shù)據(jù)庫(kù)還是無(wú)法上線。

本文將分享終極處理方法,幫助您成功恢復(fù)數(shù)據(jù)庫(kù)。 


測(cè)試環(huán)境: SQL Server 2022,Windows 2016

注意:奇技淫巧有風(fēng)險(xiǎn),做任何操作之前注意先做備份! 

 

模擬環(huán)境

首先,在數(shù)據(jù)庫(kù) testdb 中創(chuàng)建 testObject 表,并不停插入所有對(duì)象數(shù)據(jù)。

在窗口一我們運(yùn)行插入數(shù)據(jù)腳本,使用多次 CROSS JOIN,以獲得足夠多的數(shù)據(jù),插入數(shù)據(jù)腳本實(shí)際是一個(gè)模擬的大事務(wù)。

--窗口1
CREATE DATABASE testdb
GO
USE testdb
GO        
SELECT * INTO testObject FROM sys.all_objects --前面腳本執(zhí)行完成再執(zhí)行下面的插入語(yǔ)句 INSERT INTO dbo.testObject SELECT o.* FROM sys.all_objects o CROSS JOIN sys.all_objects o1 CROSS JOIN sys.all_objects o2 CROSS JOIN sys.all_objects o3 CROSS JOIN sys.all_objects o4

返回信息如下

-- Msg 109, Level 20, State 0, Line 0
--A transport-level error has occurred when receiving results from the server. (provider: Shared Memory Provider, error: 0 - 管道已結(jié)束。)

 

在窗口二我們?cè)陉P(guān)閉測(cè)試實(shí)例時(shí),窗口一的插入事務(wù)仍然在運(yùn)行。

這將使得數(shù)據(jù)庫(kù)處于不一致?tīng)顟B(tài),在數(shù)據(jù)庫(kù)啟動(dòng)時(shí),執(zhí)行數(shù)據(jù)庫(kù)恢復(fù)。

--窗口2
--執(zhí)行完下面語(yǔ)句之后,移走ldf文件,模擬ldf文件損壞
SHUTDOWN WITH NOWAIT

數(shù)據(jù)庫(kù)停服后,將testdb數(shù)據(jù)庫(kù) 的ldf事務(wù)日志文件改名或者移到其他路徑,重新啟動(dòng)SQL Server 服務(wù),可以看到,testdb 數(shù)據(jù)庫(kù)處于“恢復(fù)掛起”狀態(tài)。

 

因?yàn)樵谕7r(shí)候,還有未提交的插入事務(wù)保存在ldf事務(wù)日志文件,需要在數(shù)據(jù)庫(kù)啟動(dòng)時(shí)候把事務(wù)日志撈出來(lái)做crash recovery。

 

數(shù)據(jù)庫(kù)啟動(dòng)之前,已經(jīng)把ldf事務(wù)日志文件移動(dòng)到別的地方

此時(shí),我們已經(jīng)有一個(gè)孤立的,不一致的數(shù)據(jù)庫(kù)文件。

現(xiàn)在我們必須先離線數(shù)據(jù)庫(kù),把mdf文件復(fù)制到別的地方作為備份,然后刪除數(shù)據(jù)庫(kù),為后續(xù)的附加ldf事務(wù)日志文件做準(zhǔn)備

--窗口3
USE master
GO     
ALTER DATABASE [testdb] SET OFFLINE;

把mdf文件復(fù)制到別的地方作為備份,因?yàn)閿?shù)據(jù)庫(kù)離線了,并不會(huì)刪除物理數(shù)據(jù)文件

--窗口4
USE master
GO     
DROP  DATABASE [testdb] ;

 

傳統(tǒng)方法

使用 ATTACH_REBUILD_LOG 來(lái)重建ldf事務(wù)日志文件

--窗口5
USE master
GO    
CREATE DATABASE [testdb] ON
(FILENAME='E:\DataBase\testdb.mdf')
FOR ATTACH_REBUILD_LOG
GO  

報(bào)錯(cuò)信息如下

--文件激活失敗。物理文件名稱(chēng)'E:\DataBase\testdb_log.ldf'可能不正確。
--無(wú)法重新生成日志,原因是數(shù)據(jù)庫(kù)關(guān)閉時(shí)存在打開(kāi)的事務(wù)/用戶,該數(shù)據(jù)庫(kù)沒(méi)有檢查點(diǎn)或者該數(shù)據(jù)庫(kù)是只讀的。如果事務(wù)日志文件被手動(dòng)刪除或者由于硬件或環(huán)境問(wèn)題而丟失,則可能出現(xiàn)此錯(cuò)誤。
--Msg 1813, Level 16, State 2, Line 8
--無(wú)法打開(kāi)新數(shù)據(jù)庫(kù) 'testdb'。CREATE DATABASE 中止。


到此為止,我們很可能只有去找備份文件還原了(如果有的話),否則可能就是一場(chǎng)災(zāi)難了。

就算資深DBA老司機(jī)也會(huì)在這里翻車(chē)


 

新方法
接下來(lái)將介紹終極恢復(fù)數(shù)據(jù)庫(kù)的方法,以幫助您度過(guò)劫難。

使用 CREATE DATABASE 語(yǔ)句中非官方文檔記載(undocument)的命令,這個(gè)命令就是ATTACH_FORCE_REBUILD_LOG

這個(gè)命令會(huì)強(qiáng)制重建ldf事務(wù)日志文件,即使數(shù)據(jù)庫(kù)檢測(cè)到ldf事務(wù)日志文件和mdf數(shù)據(jù)文件之間有不一致的情況。

--窗口6
USE master
GO    
CREATE DATABASE [testdb] ON
(FILENAME='E:\DataBase\testdb.mdf')
FOR ATTACH_FORCE_REBUILD_LOG
GO  

返回信息如下

--文件激活失敗。物理文件名稱(chēng)'E:\DataBase\testdb_log.ldf'可能不正確。
--新的日志文件 'E:\DataBase\testdb_log.ldf' 已創(chuàng)建。

數(shù)據(jù)庫(kù)雖然恢復(fù)正常,但數(shù)據(jù)表依然無(wú)法訪問(wèn)

--窗口7
USE [testdb]
GO
SELECT TOP 10 *  FROM [dbo].[testObject]
SELECT COUNT(*)  FROM [dbo].[testObject]

報(bào)錯(cuò)信息如下

--Msg 824, Level 24, State 2, Line 18
--SQL Server 檢測(cè)到基于邏輯一致性的 I/O 錯(cuò)誤: pageid 不正確(應(yīng)為 1:69856,但實(shí)際為 0:0)。在文件“E:\DataBase\testdb.mdf”中的偏移 0x000000221c0000 處,在數(shù)據(jù)庫(kù) ID 9 中的頁(yè)面 (1:69856) 的 讀取 期間發(fā)生。SQL Server 錯(cuò)誤日志或操作系統(tǒng)錯(cuò)誤日志中的其他消息可能會(huì)提供更多詳細(xì)信息。這是一個(gè)威脅數(shù)據(jù)庫(kù)完整性的嚴(yán)重錯(cuò)誤條件,必須立即更正。請(qǐng)執(zhí)行完整的數(shù)據(jù)庫(kù)一致性檢查(DBCC CHECKDB)。此錯(cuò)誤可以由許多因素導(dǎo)致;有關(guān)詳細(xì)信息,請(qǐng)參閱 https://go.microsoft.com/fwlink/?linkid=2252374。

 

使用最小數(shù)據(jù)丟失的方式,修復(fù)數(shù)據(jù)庫(kù)

頭兩個(gè)命令將數(shù)據(jù)庫(kù)分別置于緊急模式和單用戶模式,這是我們執(zhí)行 DBCC CHECKDB 的 REPAIR_ALLOW_DATA_LOSS 選項(xiàng)的前提。

最后一句命令是將數(shù)據(jù)庫(kù)恢復(fù)多用戶模式。

--窗口8
--使用最小數(shù)據(jù)丟失的方式,修復(fù)數(shù)據(jù)庫(kù)
USE [master]
GO 
ALTER DATABASE [testdb] SET EMERGENCY
GO  
ALTER DATABASE [testdb] SET SINGLE_USER WITH NO_WAIT
GO  
DBCC CHECKDB([testdb],REPAIR_ALLOW_DATA_LOSS) WITH ALL_ERRORMSGS
--dbcc checkdb執(zhí)行完畢之后執(zhí)行下面語(yǔ)句,讓數(shù)據(jù)庫(kù)可以重新訪問(wèn)
ALTER DATABASE [testdb] SET MULTI_USER WITH NO_WAIT

DBCC CHECKDB返回信息如下,很多信息這里做了省略

可以看到有5924 個(gè)一致性錯(cuò)誤,修復(fù)了 5924 個(gè)一致性錯(cuò)誤,也就是全部修復(fù)了

--testdb的 DBCC 結(jié)果。
--Msg 8909, Level 16, State 1, Line 19
--表錯(cuò)誤: 對(duì)象 ID 0,索引 ID -1,分區(qū) ID 0,分配單元 ID 0 (類(lèi)型為 Unknown),頁(yè) ID (1:69830) 在其頁(yè)頭中包含錯(cuò)誤的頁(yè) ID。頁(yè)頭中的 PageId 為 (0:0)。
--        該錯(cuò)誤已修復(fù)。
--Msg 8909, Level 16, State 1, Line 19
--表錯(cuò)誤: 對(duì)象 ID 0,索引 ID -1,分區(qū) ID 0,分配單元 ID 0 (類(lèi)型為 Unknown),頁(yè) ID (1:69831) 在其頁(yè)頭中包含錯(cuò)誤的頁(yè) ID。頁(yè)頭中的 PageId 為 (0:0)。
--        該錯(cuò)誤已修復(fù)。
--Msg 8909, Level 16, State 1, Line 19
--data)釋放。
--修復(fù): 頁(yè) (1:70420) 已從對(duì)象 ID 1541580530,索引 ID 0,分區(qū) ID 72057594045857792,分配單元 ID 72057594052673536 (類(lèi)型為 In-row data)釋放。
--修復(fù): 頁(yè) (1:70421) 已從對(duì)象 ID 1541580530,索引 ID 0,分區(qū) ID 72057594045857792,分配單元 ID 72057594052673536 (類(lèi)型為 In-row data)釋放
。。。
--對(duì)象 ID 1541580530,索引 ID 0,分區(qū) ID 72057594045857792,分配單元 ID 72057594052673536 (類(lèi)型為 In-row data): 無(wú)法處理頁(yè) (1:69866)。有關(guān)詳細(xì)信息,請(qǐng)參閱其他錯(cuò)誤消息。
--        該錯(cuò)誤已修復(fù)。
--Msg 8928, Level 16, State 1, Line 19
--對(duì)象 ID 1541580530,索引 ID 0,分區(qū) ID 72057594045857792,分配單元 ID 72057594052673536 (類(lèi)型為 In-row data): 無(wú)法處理頁(yè) (1:69867)。有關(guān)詳細(xì)信息,請(qǐng)參閱其他錯(cuò)誤消息。
--        該錯(cuò)誤已修復(fù)。
。。。
--sys.filetable_updates_2105058535的 DBCC 結(jié)果。
--對(duì)象“sys.filetable_updates_2105058535”在 0 頁(yè)中找到 0 行。
--CHECKDB 在數(shù)據(jù)庫(kù) 'testdb' 中發(fā)現(xiàn) 0 個(gè)分配錯(cuò)誤和 5924 個(gè)一致性錯(cuò)誤。
--CHECKDB 在數(shù)據(jù)庫(kù) 'testdb' 中修復(fù)了 0 個(gè)分配錯(cuò)誤和 5924 個(gè)一致性錯(cuò)誤。
--DBCC 執(zhí)行完畢。如果 DBCC 輸出了錯(cuò)誤信息,請(qǐng)與系統(tǒng)管理員聯(lián)系。

數(shù)據(jù)庫(kù)處于單用戶模式

 

設(shè)置回多用戶模式之后,嘗試查詢數(shù)據(jù)

--從數(shù)據(jù)行數(shù)來(lái)看,具體你是不知道丟失多少數(shù)據(jù)的,只能說(shuō)能挽救多少是多少吧
USE [testdb]
GO
SELECT TOP 10 *  FROM [dbo].[testObject]
SELECT COUNT(*) AS'rowcount' FROM [dbo].[testObject]

數(shù)據(jù)是查詢出來(lái)了,但是具體丟失多少數(shù)據(jù),我們無(wú)法掌握

至少數(shù)據(jù)庫(kù)最后一次checkpoint點(diǎn)之后的所有數(shù)據(jù)將會(huì)丟失。

?


總結(jié)

在傳統(tǒng)的方法里面,還有一個(gè)方法就是 新建一個(gè)同名的空數(shù)據(jù)庫(kù)作為傀儡數(shù)據(jù)庫(kù),然后替換傀儡數(shù)據(jù)庫(kù)的數(shù)據(jù)文件

再對(duì)傀儡數(shù)據(jù)庫(kù)執(zhí)行DBCC CEHECKDB 的 REPAIR_ALLOW_DATA_LOSS 選項(xiàng),但是實(shí)際上也不能保證100%有效

這個(gè)方法網(wǎng)上已經(jīng)有相關(guān)文章,這里就不展開(kāi)敘述了。


前幾天幫一個(gè)網(wǎng)友恢復(fù)數(shù)據(jù)庫(kù),由于這個(gè)網(wǎng)友的數(shù)據(jù)庫(kù)沒(méi)有任何備份,并且遇到ldf事務(wù)日志損壞的問(wèn)題,

起初使用ATTACH_REBUILD_LOG來(lái)重建ldf事務(wù)日志文件不成功,還有打算借助第三方工具ApexSQL Log,不過(guò)因?yàn)榫W(wǎng)友的數(shù)據(jù)庫(kù)版本太高

ApexSQL Log工具不支持,幸好在外網(wǎng)剛好搜索到ATTACH_FORCE_REBUILD_LOG這個(gè)命令,

最后總算幫這個(gè)網(wǎng)友盡最大努力挽回了數(shù)據(jù)。


最后提醒一下,附加沒(méi)有l(wèi)df事務(wù)日志文件的數(shù)據(jù)庫(kù),并重建日志文件,有以下方法,其中有些方法已經(jīng)廢棄

DBCC REBUILD_LOG:已經(jīng)廢棄
sp_attach_single_file_db:已經(jīng)廢棄
ATTACH_REBUILD_LOG:推薦使用
ATTACH_FORCE_REBUILD_LOG:慎用

轉(zhuǎn)自https://www.cnblogs.com/lyhabc/p/18306393/ultimate-solution-to-rescue-sql-server-transaction-log-file-corruption


該文章在 2025/2/18 8:49:41 編輯過(guò)
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專(zhuān)業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車(chē)隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類(lèi)企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷(xiāo)售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved