備份和恢復是數(shù)據(jù)庫治理員維護數(shù)據(jù)庫安全性和完整性的重要操作。雖然各種數(shù)據(jù)庫系統(tǒng)本身提供了備份和恢復數(shù)據(jù)庫的功能,但是操作步驟比較煩瑣。 本文以SQL Server為例,總結(jié)了常用的幾種備份和恢復數(shù)據(jù)庫的方法,分析了作業(yè)機制的原理,并提出了一種以作業(yè)機制實現(xiàn)恢復和備份數(shù)據(jù)庫的方法。利用此方法,用戶不必打開數(shù)據(jù)庫治理器,在應(yīng)用程序客戶端就可以方便地實現(xiàn)數(shù)據(jù)庫的備份和恢復。
常用方法
備份可以防止由于表和數(shù)據(jù)庫遭受破壞、介質(zhì)失效或用戶錯誤而造成的數(shù)據(jù)災(zāi)難。恢復是在意外發(fā)生后,利用備份來恢復數(shù)據(jù)庫的操作。任何數(shù)據(jù)維護系統(tǒng)都必須具有備份和恢復數(shù)據(jù)庫的功能。
SQL Server 的治理器EnterPRise Manager是一個強大的治理工具,能完成很多功能,備份和恢復數(shù)據(jù)庫是其中的一項基本功能。借助這個治理工具有三種常用的方法實現(xiàn)備份和恢復數(shù)據(jù)庫。
1.完全手工方式
首先選擇要備份和恢復的數(shù)據(jù)庫,然后單擊鼠標右鍵,在快捷菜單中的“ALL TASKS”下選擇備份或者恢復數(shù)據(jù)庫。利用這種方式,用戶要進行多步操作,其中要涉及到一些參數(shù)的設(shè)置,使用起來輕易出錯,而且一旦操作失誤可能帶來很大的損失。
2.半手工方式
這種方式要求治理員事先建立備份或者恢復數(shù)據(jù)庫的作業(yè),待到需要備份或者恢復數(shù)據(jù)庫的時候,治理員打開“SQL Server Enterprise Manager”,在“Manager”里找到相應(yīng)的作業(yè),然后執(zhí)行。這種方式雖然是基于作業(yè)方式實現(xiàn)的,但是治理員必須打開數(shù)據(jù)庫治理器,在繁多的作業(yè)中進行選擇,一旦選擇錯誤并執(zhí)行,就有可能帶來意想不到的損失。
3.全自動方式
這種方式也要求治理員事先建立好恢復或者備份數(shù)據(jù)庫的作業(yè),然后定制一個執(zhí)行計劃,讓計算機在特定的條件下自己執(zhí)行備份和恢復操作。這種方式看起來簡單、省事,但是機器在異常情況下(如掉電),就不能按照計劃執(zhí)行了。
這幾種實現(xiàn)和恢復數(shù)據(jù)庫的方法都需要用戶對Enterprise Manager相當熟悉,而且處理步驟較為煩瑣,操作起來輕易發(fā)生失誤。因此我們需要一種更加簡便可行的實現(xiàn)方法。
作業(yè)機制的工作原理
作業(yè)是Enterprise Manager提供的一種定期處理數(shù)據(jù)的方法,可以在應(yīng)用程序客戶端啟動和關(guān)閉。
作業(yè)機制由控制體和執(zhí)行體兩大部分構(gòu)成(如圖1所示)。
〈p align="center"〉〈img src="/uploadImages/2007-7-2/20077215392633073.jpg"〉〈/p〉
控制體是控制作業(yè)執(zhí)行的實體,靠具體編程實現(xiàn)??刂企w實現(xiàn)時,要調(diào)用MSDB數(shù)據(jù)庫的系統(tǒng)存儲過程Sp_start_job、Sp_end_job等,同時要訪問表sysjobhistory,獲取作業(yè)執(zhí)行狀態(tài)。
執(zhí)行體是作業(yè)執(zhí)行的整體,在應(yīng)用系統(tǒng)投入使用時建立。
控制體由用戶觸發(fā),啟動相應(yīng)的作業(yè),交由執(zhí)行體執(zhí)行,在執(zhí)行過程中,執(zhí)行體執(zhí)行的每一步的狀態(tài)信息都要寫入MSDB數(shù)據(jù)庫的sysjobhistory表里。同時,控制體不斷獲取執(zhí)行狀態(tài)信息,根據(jù)這些信息,控制體決定繼續(xù)執(zhí)行還是停止該作業(yè)。在作業(yè)執(zhí)行完畢或者出錯停止后,控制體向用戶反饋執(zhí)行結(jié)果。
實現(xiàn)備份和恢復
為了便于說明,本文以PB實現(xiàn)的一個具體系統(tǒng)為例,來介紹數(shù)據(jù)庫的備份和恢復。
1.執(zhí)行體的建立
●建立應(yīng)用系統(tǒng)的數(shù)據(jù)庫XCCXXT。
●建立備份數(shù)據(jù)庫所使用的設(shè)備XCCXXTBAK.
DAT。
●建立備份作業(yè)XCCXXT BACKUP,其中命令行為BACKUP DATABASE XCCXXT TO DISK=“C:/MSSQL7/DATA/BACKUP/XCCXXTBAK.DAT”。
2.控制體的實現(xiàn)
在相應(yīng)對象的“備份”按鈕的click事件中寫入以下代碼:
//聲明相應(yīng)的變量
string ls_database,ls_pass,ls_date,ls_time
integer li_gs,li_gs_o
transaction login_trans
login_trans = create transaction
if messagebox(“提示信息”,“是否真的要進行數(shù)據(jù)備份操作?”,Exclamation!,OKCancel!,2)〈〉1 then return
//連接MSDB數(shù)據(jù)庫
login_trans.database = “msdb”
connect using login_trans;
if login_trans.sqlcode 〈〉 0 then
messagebox(“數(shù)據(jù)庫錯誤信息”,login_trans.sqlerrtext)
return
end if
//檢測上次該執(zhí)行體執(zhí)行結(jié)果,用以區(qū)別本次執(zhí)行狀況
select max(instance_id) into :li_gs_o from sysjobhistory using login_trans;
if isnull(li_gs_o) then li_gs_o =0
login_trans.autocommit = true
ls_pass = login_trans.logpass
//運行系統(tǒng)存儲過程Sp_start_job,啟動執(zhí)行體
prepare sqlsa from “Sp_start_job ?” using login_trans;
if login_trans.sqlcode 〈〉 0 then
messagebox(“數(shù)據(jù)庫錯誤信息”,login_trans.sqlerrtext)
login_trans.autocommit = false
disconnect using login_trans;
login_trans.database = ls_database
return
end if
EXECUTE sqlsa USING ‘XCCXXT BACKUP';
//檢測執(zhí)行體啟動是否正常
if login_trans.sqlcode 〈〉 0 then
messagebox(“數(shù)據(jù)庫錯誤信息”,login_trans.sqlerrtext)
login_trans.autocommit = false
disconnect using login_trans;
return
end if
//檢測執(zhí)行體執(zhí)行的整個過程
do
uf_sleep (1)
select max(instance_id) into :li_gs from sysjobhistory
using login_trans;
if isnull(li_gs) then li_gs =0
loop while li_gs〈=li_gs_o+1
//運行系統(tǒng)存儲過程Sp_end_job,關(guān)閉執(zhí)行體
prepare sqlsa from “Sp_end_job ?” using login_trans;
if login_trans.sqlcode 〈〉 0 then
messagebox(“數(shù)據(jù)庫錯誤信息”,login_trans.sqlerrtext)
login_trans.autocommit = false
disconnect using login_trans;
login_trans.database = ls_database
return
end if
EXECUTE sqlsa USING ‘XCCXXT BACKUP';
//返回執(zhí)行結(jié)果
li_gs_o=li_gs - 1
select run_status,run_date,run_time into :li_gs,:ls_date,:ls_time from sysjobhistory where instance_id =:li_gs_o using login_trans;
if li_gs = 1 then
st_3.text = left(ls_date,4)+‘年'+mid(ls_date,5,2)+‘月'+right(ls_date,2)+‘日'+‘ '+ left(ls_time,2)+‘:'+mid(ls_time,3,2)+‘:'+right(ls_time,2)
messagebox(‘提示',“數(shù)據(jù)庫備份操作成功!”)
else
messagebox(‘提示',“數(shù)據(jù)庫備份操作失??!”)
end if
//斷開與數(shù)據(jù)庫MSDB的連接
login_trans.autocommit = false
disconnect using login_trans;
if login_trans.sqlcode 〈〉 0 then
messagebox(“數(shù)據(jù)庫錯誤信息”,login_trans.sqlerrtext)
end if
備份是對源數(shù)據(jù)庫進行讀操作,執(zhí)行體執(zhí)行之前不需要檢查用戶對數(shù)據(jù)庫的使用狀態(tài)。
而恢復則是對整個數(shù)據(jù)庫進行寫操作,在啟動執(zhí)行體之前一定要檢查是否有數(shù)據(jù)庫進行寫操作,否則可能導致失敗。
小結(jié)
作業(yè)機制打破了常規(guī)上在數(shù)據(jù)庫治理器里對大型數(shù)據(jù)庫備份和恢復的局限性,實現(xiàn)了在應(yīng)用程序客戶端對數(shù)據(jù)庫的備份和恢復。