摘要:該文通過ASP程序?qū)嵗榻B了遠(yuǎn)程備份和恢復(fù)SQL數(shù)據(jù)庫的方法。
關(guān)鍵詞:ASP;SQL;遠(yuǎn)程;備份;恢復(fù)
中圖分類號:TP311文獻(xiàn)標(biāo)識(shí)碼:A文章編號:1009-3044(2009)32-8868-02
ASP Remote SQL Database Backup and Restore the Method
WENG Wen-hui
(Huangyan District, Toyama Power Authority, Taizhou 318023, China)
Abstract: Based on ASP program, for example,introduces remote SQL database backup and restore the method.
Key words: ASP; SQL; remote; backup and restore
近年來,SQL數(shù)據(jù)庫遭到注入攻擊是很常見,通常在程序中加上防注入代碼就可以抵御這類攻擊。但有的時(shí)候,因?yàn)槌绦蛭募容^多或者其他某原因,暫時(shí)無法防住注入攻擊,這時(shí)網(wǎng)站維護(hù)人員就比較頭疼了。本人便遇到過這樣的事,這個(gè)網(wǎng)站數(shù)據(jù)量不大,更新也不算頻繁,所以被注入后就需要恢復(fù)之前備份的數(shù)據(jù)庫。最初是通過遠(yuǎn)程桌面連到服務(wù)器上,手動(dòng)恢復(fù)SQL數(shù)據(jù)庫,也不算費(fèi)勁。但后來有段時(shí)間,注入攻擊非常頻繁,一天可能發(fā)生好幾次,這樣就比較麻煩了。總是維護(hù)人員發(fā)現(xiàn)注入,打電話通知我,我再恢復(fù)數(shù)據(jù)庫,這樣經(jīng)常會(huì)使用問題的處理時(shí)間比較長。而且有時(shí)網(wǎng)站剛更新了一部分?jǐn)?shù)據(jù),不久遭到注入攻擊,這時(shí)直接恢復(fù)數(shù)據(jù)庫就會(huì)丟失剛更新的數(shù)據(jù),沒辦法,只有手工清除注入的代碼或者恢復(fù)后重新更新。這樣的事情發(fā)生幾次之后,我就產(chǎn)生了做一個(gè)程序讓網(wǎng)站維護(hù)人員自己在更新數(shù)據(jù)之后備份數(shù)據(jù)庫,在發(fā)現(xiàn)注入攻擊后自己完成數(shù)據(jù)庫的恢復(fù)。
1 技術(shù)準(zhǔn)備
1.1 備份
備份的問題比較好處理,與數(shù)據(jù)庫建立連接后,執(zhí)行BACKUP語句就可以實(shí)現(xiàn)。
BACKUP語句語法為:
BACKUP DATABASE { database_name | @database_name_var }
TO
[
[ WITH { DIFFERENTIAL |
[;]
第一行:BACKUP DATABASE 數(shù)據(jù)庫名;
第二行:文件名,一般只在數(shù)據(jù)庫的大小和性能要求使得進(jìn)行數(shù)據(jù)庫備份無法實(shí)現(xiàn)時(shí)用到;
第三行:指定用于備份操作的邏輯備份設(shè)備或物理備份設(shè)備,這個(gè)是我們要用到的;
第四行:指定一組輔助備份設(shè)備(最多三個(gè)),其中每個(gè)設(shè)備都將鏡像 TO 子句中指定的備份設(shè)備,因?yàn)闆]這種需求,可以忽略;
第五行:這行比較重要,指定了備份的各種參數(shù),這里只介紹幾種可能用到的,其他的請查閱MSDN。
DIFFERENTIAL:指定數(shù)據(jù)庫備份或文件備份應(yīng)該只包含上次完整備份后更改的數(shù)據(jù)庫或文件部分,即差異備份。
NOINIT | INIT:控制備份操作是追加到還是覆蓋備份媒體中的現(xiàn)有備份集。默認(rèn)為追加到媒體中最新的備份集 (NOINIT)。
權(quán)限要求:默認(rèn)授予 sysadmin 固定服務(wù)器角色和 db_owner 及 db_backupoperator 固定數(shù)據(jù)庫角色的成員。
1.2 恢復(fù)
恢復(fù)的問題就比較麻煩,首先要以SA用戶登陸,其次是要中止其他用戶與數(shù)據(jù)庫的連接,然后才能用RESTORE語句恢復(fù)數(shù)據(jù)庫。
中止其他用戶與數(shù)據(jù)庫的連接,如不進(jìn)行這個(gè)操作,在恢復(fù)過程中多半會(huì)出現(xiàn)“因?yàn)閿?shù)據(jù)庫正在使用,所以未能獲得對數(shù)據(jù)庫的排它訪問權(quán)。”的提示:
exec p_killspid 數(shù)據(jù)庫名
這里使用了一個(gè)自定義的存儲(chǔ)過程,代碼如下:
CREATEproc p_killspid
@dbname varchar(200)--要關(guān)閉進(jìn)程的數(shù)據(jù)庫名
as
declare @sqlnvarchar(500)
declare @spid nvarchar(20)
declare #tb cursor for
select spid=cast(spid as varchar(20)) from master..sysprocesses where dbid=db_id(@dbname)
open #tb
fetch next from #tb into @spid
while @@fetch_status=0
begin
exec('kill '+@spid)
fetch next from #tb into @spid
end
close #tb
deallocate #tb
GO
RESTORE語句語法為:
RESTORE DATABASE { database_name | @database_name_var }
[ FROM
WITH
{
[ RECOVERY | NORECOVERY ]
[ ,
} [ ,...n ]
[;]
第一行:RESTORE DATABASE 數(shù)據(jù)庫名;
第二行:文件名,一般只在數(shù)據(jù)庫的大小和性能要求使得進(jìn)行數(shù)據(jù)庫備份無法實(shí)現(xiàn)時(shí)用到;
第三行:指定用于備份操作的邏輯備份設(shè)備或物理備份設(shè)備,這個(gè)是我們要用到的;
第六行:NORECOVERY 指定不發(fā)生回滾。從而使前滾按順序在下一條語句中繼續(xù)進(jìn)行。
在這種情況下,還原順序可還原其他備份,并執(zhí)行前滾。
RECOVERY(默認(rèn)值)表示,應(yīng)在完成當(dāng)前備份前滾之后執(zhí)行回滾。
其他參數(shù)略。
權(quán)限要求:如果不存在要還原的數(shù)據(jù)庫,則用戶必須有 CREATE DATABASE 權(quán)限才能執(zhí)行 RESTORE。如果該數(shù)據(jù)庫存在,則 RESTORE 權(quán)限默認(rèn)授予 sysadmin 和 dbcreator 固定服務(wù)器角色成員以及該數(shù)據(jù)庫的所有者 (dbo)(對于 FROM DATABASE_SNAPSHOT 選項(xiàng),該數(shù)據(jù)庫始終存在)。
RESTORE 權(quán)限被授予那些成員身份信息始終可由服務(wù)器使用的角色。因?yàn)橹挥性诠潭〝?shù)據(jù)庫可以訪問且沒有損壞時(shí)(在執(zhí)行 RESTORE 時(shí)并不會(huì)總是這樣)才能檢查固定數(shù)據(jù)庫角色成員身份,所以 db_owner 固定數(shù)據(jù)庫角色成員沒有 RESTORE 權(quán)限。
下面順便說一下有可能出現(xiàn)的一些問題:
1)恢復(fù)數(shù)據(jù)庫后,增加登錄名出現(xiàn)“數(shù)據(jù)庫中的用戶名存在“,但是登錄名卻顯示<無>而且新加用戶會(huì)提示用戶已存在 !”,這時(shí)需要執(zhí)行以下代碼:
sp_change_users_login 'update_one','數(shù)據(jù)庫用戶名稱','登錄名稱'
2)無法更改數(shù)據(jù)庫中對象的所有者,這時(shí)需要使用如下代碼:
exec sp_changeobjectowner '原所有者名',[dbo]
執(zhí)行存儲(chǔ)過程changename
exec changename '原所有者名','新所有者名'
2 程序代碼
<%act=request(\"act\")
if act=\"B\" then’備份數(shù)據(jù)庫
SQL=\"backup database WebSiteData to disk='\"Server.MapPath(\"bk\")\"\\\"\"bk.bak\"\"' with INIT\"
set cnn=Server.createobject(\"adodb.connection\")
cnn.open \"driver={SQL Server};server=(local);uid=abc;pwd=123;database= WebSiteData \" ‘建立與數(shù)據(jù)庫的連接
cnn.execute SQL
on error resume next
if err<>0 then
response.write \"錯(cuò)誤:\"err.Descripting
else
response.write \"數(shù)據(jù)備份成功!\"
end if
cnn.close
set cnn=nothing
end if
if act=\"R\" then’恢復(fù)數(shù)據(jù)庫
SQL=\"Restore database WebSiteData from disk='\"Server.MapPath(\"bk\")\"\\\"\"bk.bak\"\"'\"
set cnn=Server.createobject(\"adodb.connection\")
cnn.open \"driver={SQL Server};server=(local);uid=sa;pwd=123;database=master\" ‘以SA用戶身份登錄
cnn.execute(\"exec p_killspid'WebSiteData'\")’結(jié)束其他用戶與數(shù)據(jù)庫連接
cnn.execute SQL ‘恢復(fù)數(shù)據(jù)庫
on error resume next
if err<>0 then
response.write \"錯(cuò)誤:\"err.Descripting
else
response.write \"數(shù)據(jù)恢復(fù)成功!\"
end if
cnn.close
set cnn=nothing
end if
%>
3 結(jié)束語
接收程序改為多線程異步接收方式后,經(jīng)測試無丟包現(xiàn)象。通過此次實(shí)踐筆者認(rèn)為多線程異步SOCKET接收并不像想象中那么復(fù)雜,只要弄清楚各線程的啟動(dòng)順序、互相之間的關(guān)系就可以很容易地實(shí)現(xiàn)各種應(yīng)用。當(dāng)然,其中還是有些細(xì)節(jié)問題需要讀者在實(shí)際應(yīng)用中注意的,如:數(shù)據(jù)接收線程中無法直接在啟動(dòng)界面中顯示數(shù)據(jù)(因?yàn)橥痪€程)、如何把DataGridView中數(shù)據(jù)直接寫入數(shù)據(jù)庫等,篇幅有限無法在此討論。
本程序在WINDOWS XP、VS 2005中調(diào)試通過。
參考文獻(xiàn):
[1] Silberschatz A.數(shù)據(jù)庫系統(tǒng)概念[M].楊冬青,馬秀莉,譯.5版.北京:機(jī)械工業(yè)出版社,2008.
[2] 唐學(xué)忠.SQL Server 2000數(shù)據(jù)庫教程[M].北京:電子工業(yè)出版社,2005.
[3] 張躍廷.ASP.NET數(shù)據(jù)庫系統(tǒng)開發(fā)完全手冊[M].北京:人民郵電出版社,2007.