丢失日志文件的风险与对策
實驗背景:
在備份與恢復(fù)數(shù)據(jù)庫時,偶爾使用分離/附加的方法。如果在附加時丟失了或者刪除了日志文件(LDF),可能會有哪些風(fēng)險呢?下面通過實驗來驗證。
一、搭建環(huán)境
1. 創(chuàng)建數(shù)據(jù)庫
CREATE DATABASE [db01] ON ?PRIMARY ( NAME = N'db01', FILENAME = N'C:\SQLDATA\db01.mdf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) LOG ON ( NAME = N'db01_log', FILENAME = N'C:\SQLDATA\db01_log.ldf' , SIZE = 1024KB , FILEGROWTH = 10%) |
2. 創(chuàng)建表
USE db01 CREATE TABLE [dbo].[Table01]( [IntID] [int] NULL, [CharFill] [varchar](50) NULL ?) |
二、使用nowait選項停止SQL Server實例(服務(wù))造成數(shù)據(jù)丟失?
1. 添加2條記錄
USE db01 insert Table01 values(1,'abcd') CHECKPOINT insert Table01 values(2,'hijk') select * from Table01 |
查詢添加的結(jié)果,確認(rèn)上述2條記錄已經(jīng)添加到數(shù)據(jù)庫。區(qū)別是:第1條記錄后面有一個檢查點,此時這條記錄已經(jīng)被回寫到MDF文件,而第2條記錄還在data cache pool,等待下一個檢查點才會寫入MDF文件。
2. 使用nowait選項停止SQL Server實例(服務(wù))
| SHUTDOWN WITH NOWAIT |
3. 轉(zhuǎn)移文件后啟動SQL Server服務(wù)
刪除LDF文件,再將MDF文件(這個文件我們稱之為“A文件”)移動到另一個文件夾
再啟動SQL Server服務(wù),然后刪除db01數(shù)據(jù)庫。
4. 附加時刪除LDF的鏈接信息
附加時,由于找不到LDF文件,會顯示“找不到”的信息。刪除它,讓系統(tǒng)重新創(chuàng)建一個LDF文件。
5. 附加數(shù)據(jù)庫時報錯
繼續(xù)附加數(shù)據(jù)庫,出現(xiàn)報錯信息。
6. 修復(fù)數(shù)據(jù)庫
(1) 新建db01數(shù)據(jù)庫
CREATE DATABASE [db01] ON ?PRIMARY ( NAME = N'db01', FILENAME = N'C:\SQLDATA\db01.mdf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) LOG ON ( NAME = N'db01_log', FILENAME = N'C:\SQLDATA\db01_log.ldf' , SIZE = 1024KB , FILEGROWTH = 10%) |
(2) 替換MDF文件
停止SQL Server服務(wù),把上一步新建的MDF文件刪除。再把最初的MDF文件(即前面所稱的“A文件”)轉(zhuǎn)移回來。(即用“A文件”替換上一步新建的MDF文件)。
(3)重啟SQL Server服務(wù)
重啟之后,db01數(shù)據(jù)庫為“可疑”狀態(tài),如果直接訪問這個數(shù)據(jù)庫則會報錯“無法訪問數(shù)據(jù)庫db01。”
執(zhí)行以下命令,修復(fù)數(shù)據(jù)庫。
alter database db01 set emergency alter database db01 set single_user dbcc checkdb('db01',REPAIR_ALLOW_DATA_LOSS) dbcc checkdb('db01',REPAIR_REBUILD) alter database db01 set multi_user |
(4)檢查數(shù)據(jù)
use db01 select * from Table01 |
執(zhí)行上述檢查,發(fā)現(xiàn)只有第1條記錄,丟失了第2條記錄。假設(shè)這是一家銀行的取款操作數(shù)據(jù)庫,由于數(shù)據(jù)庫shutdown with nowait并且LDF文件損壞,你的提款記錄就不見了。多爽啊!
結(jié)論:
SQL Server為了加快關(guān)機的速度,允許使用NOWAIT選項。此選項將跳過檢查點操作,導(dǎo)致部分?jǐn)?shù)據(jù)未回寫到MDF文件(僅記錄在LDF中)。在這種情況下,如果丟失了LDF文件,盡管可以修復(fù)數(shù)據(jù)庫,卻會有數(shù)據(jù)丟失。
三、未提交的事務(wù)導(dǎo)致不能回滾?
1. 創(chuàng)建事務(wù)
使用上一步的數(shù)據(jù)庫,添加一個事務(wù)。
BEGIN TRAN T1 insert Table01 values(3,'lmn') |
2. 停止SQL Server
使用“SQL Server配置管理器”停止SQL Server。
3. 轉(zhuǎn)移MDF文件
參考前面的實驗,把MDF文件轉(zhuǎn)轉(zhuǎn)移到另一個文件夾,并刪除LDF文件。
4. 修復(fù)數(shù)據(jù)庫
參考前面的實驗,修復(fù)數(shù)據(jù)庫
5. 檢查數(shù)據(jù)
參考前面的實驗,查看修復(fù)后的數(shù)據(jù)。你將發(fā)現(xiàn)第3條記錄已經(jīng)提交(盡管它屬于一個未提交的事務(wù))!假如這是一家銀行的存款操作數(shù)據(jù)庫,重啟數(shù)據(jù)庫以后發(fā)現(xiàn)LDF壞了,即使你的存款操作最后撤銷了,可是數(shù)據(jù)庫里顯示你的存款操作已經(jīng)提交(存款成功)。多爽啊!
結(jié)論:
本實驗是正常shutdown,所以第3條記錄遇到檢查點操作而被回寫到磁盤的MDF文件,然后事務(wù)日志中記錄了這條insert操作需要回滾(因為這個事務(wù)未提交)。由于LDF文件已丟失,導(dǎo)致數(shù)據(jù)庫啟動時不能回滾所有未提交的事務(wù)。
四、結(jié)論
丟失了數(shù)據(jù)庫的事務(wù)日志文件,最多只能恢復(fù)到最后一個檢查點。但是:
1. 在最后一個檢查點之后,data cache pool中修改過的數(shù)據(jù),將全部丟失。
2. 事務(wù)日志中未提交的事務(wù),將無法撤銷。
總結(jié)
以上是生活随笔為你收集整理的丢失日志文件的风险与对策的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数学知识在游戏中的运用
- 下一篇: Javascript函数调用的四种模式