標籤:sqlserver
最近幾天,公司的技術維護人員頻繁讓我恢複資料庫,因為他們總是少了where條件,導致update、delete出現了無法恢複的後果,加上那些庫都是幾十G。恢複起來少說也要十幾分鐘。為此,找了一些資料和工作總結,給出一下幾個方法,用於快速恢複表,而不是庫,但是切記,防範總比亡羊補牢好。上章分享了如何使用SQLCMD在SQLServer執行多個指令碼詳解需要的朋友可以看下。
在生產環境或者開發環境,往往都有某些非常重要的表。這些表存放了核心資料。當這些表出現資料損毀時,需要儘快還原。但是,正式環境的資料庫往往都是非常大的,統計資料表明,1T的資料庫還原時間接近24小時,所以因為一個表而還原一個庫,不單空間,甚至時間上都是一個很大的挑戰。本文介紹如何恢複單表,而不需要恢複整個庫。
現在假設一個表:TEST_TABLE。我們需要儘快恢複這個表,並且把恢複過程中對其他表和使用者的影響降到最低。
SQLServer(特別是2008以後),具有很多備份及恢複功能:完整、部分、檔案、差異和事務備份。而復原模式的選擇嚴重影響備份策略和備份類型。
下面是幾個可供參考的方案,但是記住,各有好壞,應該按照實際需要選擇:
方案1:恢複到一個不同的資料庫:
這對於小資料庫來說不失為一種好的辦法,用備份還原一個新的庫,並把新庫中的表資料同步回去。你可以做完整恢複,或者時間點恢複。但是對於大資料庫,是非常耗時和耗費磁碟空間的。這個方法僅僅用於還原資料,在還原資料(就是同步資料)的時候,你要考慮觸發器、外鍵等因素。
方案2:使用STOPAT來還原日誌:
你可能想恢複最近的Database Backup,並復原到某個時間點,即發生意外前的某個時刻。此時可以使用STOPAT子句,但是前提是必須為完整或大量記錄復原模式。下面是例子:
123456789 |
RESTOREDATABASE 需要恢複的資料庫FROMDatabase BackupWITHFILE=3,NORECOVERY ; RESTORELOG需要恢複的資料庫FROMDatabase BackupWITHFILE=4,NORECOVERY,STOPAT =‘Oct 22, 2012 02:00 AM‘; RESTOREDATABASE 需要恢複的資料庫WITH RECOVERY; |
注意:這種方法的主要缺點是會覆蓋掉從stopat指定時間點之後所修改的所有資料。所以要衡量好得失。
方案3:資料庫快照集:
建立資料庫快照集。當發生意外時,可以從快照中直接擷取原來的資料。但是必須是在發生意外之前建立的快照。這在核心表不經常更新,特別是有規律更新時很有用。但是當表經常、不定期被更新,或者很多使用者在訪問時,這種方法就不可取了。當需要使用這種方法時,記得在每次更新前先建立快照。
方案4:使用視圖:
你可以建立一個新的資料庫,並把TEST_TABLE移動到這個庫裡面。當你需要恢複的時候,你只需要恢複這個非常小的資料庫即可。訪問來源資料庫的資料時,最簡單的方法就是建立一個視圖,選擇TEST_TABLE表中所有列的所有資料。但是注意這個方法需要在建立視圖前,重新命名或者刪除來源資料庫的表:
1234567 |
USE需要恢複的資料庫 ;GOCREATEVIEW TEST_TABLEAS SELECT * FROM 備份資料庫.架構名.TEST_TABLE;GO |
使用這種方法,可以對視圖使用SELECT /INSERT/UPDATE/DELETE語句,就像直接操作實體表似得。當TEST_TABLE更改時,要使用SP_REFRESHVIEW預存程序來更新中繼資料。
方案5:建立同義字(Synonym):
和方案4類似,把表移到另外一個資料庫,然後對來源資料庫的這個表建立一個同義字:
12345 |
USE需要恢複的資料庫 ;GOCREATESYNONYM TEST_TABLEFOR 新資料庫.架構名.TEST_TABLE;GO |
這個方法的有點就是你不需要擔心中繼資料更新所帶來的結構變更不及時。但是這個方法的問題就是不能在DDL語句中引用同義字,或者不能在連結的伺服器中找到。
方案6:使用BCP儲存資料:
你可以建立一個作業,使用BCP定期匯出資料。但是這種方法的缺點和方案1類似,需要找到哪天的檔案並導進去,同時要考慮觸發器和外鍵問題。
各種方法的對比:
方法 |
優點 |
缺點 |
還原資料庫 |
快且容易 |
適用於小庫,且要注意觸發器和外鍵等 |
還原日誌 |
能指定時間點 |
所有時間點後的新資料會被覆蓋 |
資料庫快照集 |
當表不是經常更新時很有用 |
當表並行更新時,快照容易出現問題 |
視圖 |
把表的資料於庫分開,沒有資料丟失 |
中繼資料需要周期性更新,並要定期維護新資料庫 |
同義字 |
把表的資料於庫分開,沒有資料丟失 |
在連結的伺服器上不能用,並要定期維護新資料庫 |
BCP |
擁有表的專用備份 |
需要額外的空間、還會出現觸發器、外鍵等問題 |
總結:
良好的編程習慣和良好的備份機制才是解決問題的根本,以上的措施都僅僅是一個亡羊補牢的辦法。可能有人說SQLServer 新版本不是有部分還原嗎?我們來看看聯機叢書的說明:
可以看到,其他這種方法很難還原一個表,但是當庫小的時候,倒可以試試。