為什麼SqlServer有完整備份、差異備份和事務日誌備份三種備份方式,以及為什麼資料庫又有簡單模式、完整模式和大容量日誌模式這三種恢復模式。本文內容適用於2005以上所有版本的SqlServer資料庫。 單就操作過程而言,SqlServer中資料庫備份和恢復過程是相當簡單的,可以通過Managem ...
為什麼SqlServer有完整備份、差異備份和事務日誌備份三種備份方式,以及為什麼資料庫又有簡單模式、完整模式和大容量日誌模式這三種恢復模式。本文內容適用於2005以上所有版本的SqlServer資料庫。
單就操作過程而言,SqlServer中資料庫備份和恢復過程是相當簡單的,可以通過ManagementStudio的圖形界面進行操作,也可以使用幾句T-SQL語句完成。但要明白備份恢復的整個過程,定製符合系統需求資料庫備份方案,卻需要知曉資料庫的實現原理。備份和恢復是資料庫的核心功能。
可能許多同學對SQLServer的備份和還原有一些瞭解,也可能經常使用備份和還原功能,我相信除DBA之外我們大部分開發員隊伍對備份和還原只使用最基礎的功能,對它也只有一個大概的認識。
一、資料庫原理
先簡要討論了SqlServer資料庫的存儲的物理和邏輯結構,這是備份恢復的理論基礎。
1.為什麼使用資料庫
為什麼要使用資料庫,而不是使用一個文件,然後自己寫一些方法來保存數據,那是因為使用資料庫我們就不用自己去實現下麵這些演算法上非常複雜的功能:
a.高效一致的結構化數據存取方法,進行複雜的任意條件組合嵌套的數據查詢(關係資料庫管理系統甚至為實現這一功能專門設計了一種語言:SQL)
b.保障數據操作的原子性和完整性
c.確保在伺服器斷電、網路中斷、伺服器崩潰、客戶端崩潰的情況下,故障恢復後數據仍然是完整的
d.在伺服器被完全物理摧毀的情況下,快速在新的伺服器上使用遠程設備上的備份將數據恢復到災難發生之前的狀態
e.隨時將數據恢復到任意時刻或任意一個操作之前
a主要是功能和性能
bcde四條都可以歸結為完整性。
資料庫系統的核心目標就是:在實現功能需求的基礎上,保證數據完整性和數據存取性能。
2.SqlServer存儲的物理結構和邏輯結構
(1)如何實現完整性
經過很多理論研究和實踐,目前公認的最有效的實現完整性的方法是:將數據的存儲分為數據和事務日誌,在存取過程中使用鎖來控制併發訪問。
數據是實時狀態。
事務日誌記錄了數據發生變化的過程,對於資料庫數據的任何一個改變,都被作為一條記錄寫在了事務日誌文件中。
事務是指一組操作要麼全部成功要麼全部不執行。
任何數據更改操作在寫入到數據文件中之前,必須先將更前後的數據寫入事務日誌文件中,這樣當事務由於用戶取消、數據邏輯錯誤或軟硬體故障中斷時能夠正確的回滾或前滾到正確的狀態。
通過鎖控制多用戶對同一數據的併發訪問。
這是事務系統最基本的原理,大多數關係資料庫系統和麵向對象NoSQL資料庫系統都採用這種方法。
SqlServer也不例外,每個SqlServer資料庫由數據文件(*.mdf)和事務日誌文件(*.ldf)構成。SqlServer包括了從行到表,從頁面到文件的各種粒度的鎖。
(2)如何實現高性能
在電腦數據存取過程中,保障性能的演算法最終都可以歸結為:索引和緩存。從實現層面到應用層面,SqlServer都在建立管理各種索引和各種緩存。
對於需要隨機存取的數據,分頁是最自然的索引方法,同時能夠方便的進行緩存,實現高效率的隨機存取。我們所熟悉的操作系統記憶體管理系統、文件管理系統都採用了分頁的方法。
在SqlServer中,對於數據文件mdf,主要是隨機存取,因此mdf以分頁的形式進行組織管理,每個頁面8KB。還進一步將8個相鄰的頁組成一個擴展,方便管理,類似Windows中的簇。
mdf中保存著多種類型的數據,包括表數據、索引數據和大塊數據等等。每個頁面只保存一種數據。
表中的每一條記錄都保存在一個表數據頁中,記錄不能跨頁,因此任何表中記錄的最大長度是略小於8KB(ntext之類的大塊列只計算引用的大小)的一個數值,略小是因為每個頁面需要一些空間來保存頁面自身的信息(頁頭)和記錄在頁面中的存儲位置。
在SqlServer中,對於事務日誌文件ldf,主要是順序存取。在正常運行時,資料庫管理系統定期將日誌順序寫入到ldf文件;在恢復時,順序讀取ldf文件。因此,日誌文件不需要分頁,只要由一條條順序存儲的事務日誌記錄構成即可。日誌記錄也有緩存,定期寫入到ldf文件。
儘管資料庫系統是一個允許併發訪問的系統,但是對事務日誌的寫入是串列化的,不可以併發,任何一個原子操作對應的事務日誌記錄在事務日誌文件中都有其唯一的位置,也就是唯一的事務日誌記錄編號,這個編號是一直增大的,不會重覆,越新的記錄編號越大,存儲位置也越靠後。
以上內容總結自SqlServer的產品文檔SqlServerBooksOnline,如有興趣可以在裡面瞭解更詳細的內容。這些就是備份和恢復的基礎原理。
2資料庫備份的實現
如前所述,數據文件mdf保存了數據的實時狀態,事務日誌文件ldf記錄了資料庫中數據變化的過程。這個時候,我們要對資料庫進行備份,自然而然就有兩個選擇:
因為mdf文件中保存了資料庫中數據的實時狀態,那麼我們只要把mdf文件拷貝一份就實現了當前時刻的資料庫備份。
既然ldf文件中保存了資料庫中數據變化的整個過程,那麼我們就可以把這個ldf文件備份起來,然後用這些備份的事務日誌記錄從頭重建整個資料庫,而且比至第一種方法,通過事務日誌記錄恢復的方法可以將資料庫恢復到任一時刻。
實際上,SqlServer同時使用了這兩種方法。
恢復模式
右鍵資料庫屬性--選項--可以看到“恢復模式”,SQLServer2008資料庫恢復模式分為三種:完整恢復模式、大容量日誌恢復模式、簡單恢復模式,如下圖。
完整恢復模式
為預設恢復模式。它會完整記錄下操作資料庫的每一個步驟。使用完整恢復模式可以將整個資料庫恢復到一個特定的時間點,這個時間點可以是最近一次可用的備份、一個特定的日期和時間或標記的事務。
大容量日誌恢復模式
簡單地說就是要對大容量操作進行最小日誌記錄,節省日誌文件的空間(如導入數據、批量更新、SELECTINTO等操作時)。比如一次在資料庫中插入數十萬條記錄時,在完整恢復模式下每一個插入記錄的動作都會記錄在日誌中,使日誌文件變得非常大,在大容量日誌恢復模式下,只記錄必要的操作,不記錄所有日誌,這樣一來,可以大大提高資料庫的性能,但是由於日誌不完整,一旦出現問題,數據將可能無法恢復。因此,一般只有在需要進行大量數據操作時才將恢復模式改為大容量日誌恢復模式,數據處理完畢之後,馬上將恢復模式改回完整恢復模式。
簡單恢復模式
在該模式下,資料庫會自動把不活動的日誌***,因此簡化了備份的還原,但因為沒有事務日誌備份,所以不能恢復到失敗的時間點。通常,此模式只用於對資料庫數據安全要求不太高的資料庫,並且在該模式下,資料庫只能做完整和差異備份。
可以看出三種恢復模式的區別在於對“日誌”的處理方式不同,就“日誌”大小來看:完全恢復模式>大容量日誌恢復模式>簡單恢復模式。
備份方式
SQLServer2008提供了四種備份方式:完整備份、差異備份、事務日誌備份、文件和文件組備份。
完整備份
備份整個資料庫的所有內容,包括事務日誌。該備份類型需要比較大的存儲空間來存儲備份文件,備份時間也比較長,在還原數據時,也只要還原一個備份文件。
差異備份
差異備份是完整備份的補充,只備份上次完整備份後更改的數據。相對於完整備份分來說,差異備份的數據量比完整數據備份小,備份的速度也比完整備份要快。因此,差異備份通常作為常用的備份方式。在還原數據時,要先還原前一次做的完整備份,然後還原最後一次所做的差異備份,這樣才能讓資料庫里的數據恢復到與最後一次差異備份時的內容相同。
事務日誌備份
事務日誌備份只備份事務日誌里的內容。事務日誌記錄了上一次完整備份或事務日誌備份後資料庫的所有變動過程。事務日誌記錄的是某一段時間內的資料庫變動情況,因此在進行事務日誌備份之前,必須要進行完整備份。與差異備份類似,事務日誌備份生成的文件較小、占用時間較短,但是在還原數據時,除了先要還原完整備份之外,還要依次還原每個事務日誌備份,而不是只還原最後一個事務日誌備份(這是與差異備份的區別)。
文件和文件組備份
如果在創建資料庫時,為資料庫創建了多個資料庫文件或文件組,可以使用該備份方式。使用文件和文件組備份方式可以只備份資料庫中的某些文件,該備份方式在資料庫文件非常龐大時十分有效,由於每次只備份一個或幾個文件或文件組,可以分多次來備份資料庫,避免大型資料庫備份的時間過長。另外,由於文件和文件組備份只備份其中一個或多個數據文件,當資料庫里的某個或某些文件損壞時,可能只還原損壞的文件或文件組備份。
舉例說明
完整備份
例如,在2012年1月1日早上8點進行了完整備份,那麼將來在還原時,就可以恢復到2012年1月有1日早上8點時的資料庫狀態。
差異備份
差異備份是備份完整備份後的數據變動情況。例如,在2012年1月1日早上8點進行了完整備份後,在1月2日和1月3日又分別進行了差異備份,那麼在1月2日的差異備份里記錄的是從1月1日到1月2日這一段時間里的數據變動情況,而在1月3日的差異備份里記錄的是從1月1日到1月3日這一段時間里的數據變動情況。因此,如果要還原到1月3日的狀態,只要先還原1月1日做的完整備份,再還原1月3日做的差異備份就可以了。
事務日誌備份
事務日誌備份是以事務日誌文件作為備份對象,相當於將資料庫里的每一個操作都記錄下來了。假設在2012年1月1日早上8點進行了完整備份後,到1月2日早上8點為止,資料庫里的數據變動了100次,如果此時做了差異備份,那麼差異備份記錄的是第100次數據變動後的資料庫狀態,而如果此時做了事務日誌備份,備份的將是這100次的數據變動情況。
再舉一個例子,例如在2012年1月1日早上8點進行了完整備份後,在1月2日和1月3日又進行了事務日誌備份,那麼在1月2日的事務日誌備份里記錄的是從1月1日到1月2日這一段時間里的數據變動情況,而在1月3日的事務日誌備份里記錄的是從1月2日到1月3日這一段時間里的數據變動情況。因此,如果要還原到1月3日的數據,需要先還原1月1日做的完整備份,再還原1月2日做的事務日誌備份,最後還要還原1月3日所做的事務日誌備份。
備份方式的選擇
瞭解了以上資料庫備份方式後,便可以針對自己的資料庫利用以上方式來備份資料庫了。合理備份資料庫需要考慮幾方面,首先是數據安全,其次是備份文件大小,最後是做備份和還原能承受的時間範圍。
數據變動量較小
例如,如果資料庫里每天變動的數據量很小,可以每周(周日)做一次完整備份,以後的每天(下班前)做一次事務日誌備份,那麼一旦資料庫發生問題,可以將數據恢復到前一天(下班時)的狀態。
當然,也可以每周(周日)做一次完整備份,以後的每天(下班前)做一次差異備份,這樣一旦資料庫發生問題,同樣可以將數據恢復到前一天下班時的狀態。只是一周的後幾天做差異備份時,備份的時間和備份的文件都會跟著增加。但這也有一個好處,在數據損壞時,只要恢復完整備份的數據和前一天差異備份的數據即可,不需要去恢復每一天的事務日誌備份,恢復的時間會比較短。
數據變動量較大
如果資料庫里的數據變動得比較頻繁,損失一個小時的數據都是十分嚴重的損失時,用上面的辦法備份數據就不可行了,此時可以交替使用三種備份方式來備份資料庫。
例如,每天下班時做一次完整備份,在兩次完整備份之間每隔八小時做一次差異備份,在兩次差異備份之間每隔一小時做一次事務日誌備份。如此一來,一旦數據損壞可以將數據恢復到最近一個小時以內的狀態,同時又能減少資料庫備份數據的時間和備份數據文件的大小。
資料庫文件較大
在前面還提到過當資料庫文件過大不易備份時,可以分別備份資料庫文件或文件組,將一個資料庫分多次備份。在現實操作中,還有一種情況可以使用到資料庫文件的備份。例如在一個資料庫中,某些表裡的數據變動得很少,而某些表裡的數據卻經常改變,那麼可以考慮將這些數據表分別存儲在不同的文件或文件組裡,然後通過不同的備份頻率來備份這些文件和文件組。但使用文件和文件組來進行備份,還原數據時也要分多次才能將整個資料庫還原完畢,所以除非資料庫文件大到備份困難,否則不要使用該備份方式。
尾部日誌備份
針對以上備份方案,能看出數據還是不完整嗎?比如昨天夜間12點做了完整備份,每隔一小時做了一次事務日誌備份,最後一次事務日誌備份是今天中午12點,現在是今天中午12點10分,發現資料庫數據遭到丟失或破壞,可最後一次事務日誌備份是今天中午12點,如果我此時將資料庫恢復到12點,那麼12點後至12點10分前沒遭到破壞的操作數據將丟失(比如資料庫有三個表,一個表的數據遭到破壞,其它兩個表的數據被其它用戶變動)。此時就要用到【尾部日誌備份】,尾部日誌備份原理是從最後一次事務日誌備份的時間點開始,將之後的所有操作進行備份,還原時便可以找到12點後操作的正確數據了。
註:進行尾部日誌備份時,資料庫將強制停止資料庫,此時如果不停止資料庫,還有用戶繼續操作,尾部日誌備份將失去意義。SQLServer2012如果你最後一次備份事務日誌後,對數據進行過改動,即發生過事務日誌(也就是當前日誌文件記錄的LSN(日誌序列號)大於最後一次事務日誌備份里記錄的最大LSN,SQLServer通過LSN來區分日誌的記錄),並尚未對尾部日誌備份,它會提示並要求你必須先做尾部備份。