本篇文章是系列文章中的第五篇,是對前一個日誌系列的補充篇。如果您對日誌的基本概念還沒有一個比較系統的瞭解,可以參看本系列之前的文章:
淺談SQL Server中的交易記錄(一)----交易記錄的物理和邏輯構架
淺談SQL Server中的交易記錄(二)----交易記錄在修改資料時的角色
淺談SQL Server中的交易記錄(三)----在簡單復原模式下日誌的角色
淺談SQL Server中的交易記錄(四)----在完整復原模式下日誌的角色
簡介
日誌的作用是保證持久性和資料一致性,通過日誌可以實現資料的Undo與Redo,因此通過日誌,SQL Server不僅僅可以實現災難恢複,還可以通過日誌的Redo來實現高可用性。本篇文章主要講述日誌在SQL Server中提供的幾種高可用性中的作用以及在災難恢複中的角色。
日誌損壞
日誌可能會由於IO子系統的故障而損壞,當出現日誌損壞時,如果您對日誌的原來略有瞭解,並能在日誌損壞的情況下盡量挽救資料,那麼感覺一定是非常好的:-),下面我們來瞭解幾種日誌損壞的情況下的恢複情況。
1.資料庫正常關閉,日誌損壞。
當資料庫正常關閉時,日誌損壞就不是那麼重要了,因為此時資料庫中所有提交的事務對應的髒資料都已經CheckPoint到物理磁碟,因此不存在資料不一致的問題。因此,如果MDF和NDF檔案完好,直接指定 FOR ATTACH_REBUILD_LOG參數後附加即可,1所示。
圖1.如果資料庫正常關閉,直接附加即可
但值得注意的是,使用該方式附加資料庫會自動重建記錄檔,記錄檔大小為0.5MB,也就是2個VLF,自動成長為10%,因此您需要手動再來設定一下日誌的大小,避免出現太多VLF的情況。
2.資料庫非正常關閉,日誌損壞
在講述這種情況之前,我們首先來看資料庫所能處在的幾種狀態,一個完整的模型2所示。
圖2.資料庫所能處在的狀態關係
上面的幾種狀態的具體轉換關係超出了本文的討論範圍,但是這裡我會強調兩種和日誌損壞關係很大的狀態:RECOVERY_PENDING和SUSPECT狀態。
假如出現了資料庫沒有正常關閉,也就是還有資料沒有CheckPoint到磁碟,如果資料庫要啟動就必須經曆Recovery過程,如果日誌損壞,則無法進行該Recovery過程,就會造成資料不一致的問題。
此時,資料庫可能處於下面兩種狀態之一:
- RECOVERY_PENDING:需要運行crash recovery,但該過程由於資源等待無法開始,比如說日誌完全損壞
- SUSPECT:crash recovery已經開始,但無法完成
因此處理該類情況要基於您所在的業務環境是否允許資料損失,可以選擇從備份中恢複資料,或是將資料庫狀態改為EMERGENCY。EMERGENCY模式意味著資料庫跳過crash recovery階段,此時雖然可以訪問資料庫,但是會存在資料事務不一致的問題,如果僅僅是某些資料頁不一致還好,但如果是對錶結構修改的事務存在,那就可能存在資料庫結構描述不一致的問題。如果您沒有合適的備份組,那隻能通過該方式來恢複資料。將資料庫設定為EMERGENCY模式非常簡單,如代碼清單1所示。
ALTER DATABASE AdventureWorks2012 SET EMERGENCY
代碼清單1.將資料庫設定為緊急模式
與該模式有關的一個選項是REPAIR_ALLOW_DATA_LOSS,該選項依然會執行crash recovery過程,但會跳過受損的日子,從而儘可能的修複資料一致性問題,該選項會建立一個新的記錄檔,最後使得資料庫處於ONLINE狀態,使用該選項的一個簡單例子如代碼清單2所示。
ALTER DATABASE AdventureWorks2012 SET SINGLE_USER
DBCC CHECKDB(AdventureWorks2012,REPAIR_ALLOW_DATA_LOSS)
代碼清單2.使用REPAIR_ALLOW_DATA_LOSS選項
值得注意的是,作為DBA永遠是要有“備”無患,上面這些操作是在您準備工作不充分的情況下才要去考慮的。
3.資料庫處於線上狀態,日誌損壞
在這種情況下,如果SQL Server在運行時需要使用的日誌損壞(比如說復原時),則SQL Server會將資料庫下線,並轉為SUSPECT模式。
同樣如果沒有備份的話,只能考慮使用EMERGENCY模式。
還有一種方式是,將資料庫的復原模式改為簡單,然後手動發起一個CheckPoint來截斷日誌,最後再將資料庫改回完整復原模式。但這種方式會破壞日誌鏈。但可能會將被損壞的日誌清除掉。
日誌在高可用性中的作用
鏡像與AlwaysOn
這兩種高可用性技術都是基於日誌來維護一個資料庫的副本。通過將日誌即時的傳送到副本,在副本上來不斷的進行REDO操作,就可以保證主體和副本資料庫之間的即時同步。
對於鏡像來說,可以同步或非同步將記錄傳送的1個副本。
而對於AlwaysOn可用性群組來說,就可以將日誌最多同步到2個副本+非同步到2個副本(據說SQL Server 2014已經將該特性翻倍,也就是最多可以4個同步複本和最多4個非同步副本,但目前還沒有發布,所以只是小道訊息)。
所謂的同步概念就是主副本只有將傳送的日誌發送到輔助副本之後,由輔助副本返回ACK資訊後,才能夠在本地提交,因此可能會造成明顯的延遲並影響效能。這裡還值得注意的是,主副本不是等待事務在輔助副本提交之後才能提交,而是只是需要收到輔助副本返回的收到日誌的ACK資訊即可。
無論對於上面兩種高可用特性,無論是哪一種,都需要考慮監控發送隊列和REDO隊列。發送隊列過長意味著當容錯移轉時,可能丟失大量資料,同時還會阻止日誌截斷。REDO隊列過長意味著當容錯移轉時,RECOVERY截斷將會消耗更多的時間,從而使得容錯移轉消耗的宕機時間延長。這兩種隊列的監控都可以使用效能監控器進行,3所示。
圖3.監控隊列的計數器
交易記錄傳送
相比其他高可用性功能來說,交易記錄傳送功能比較簡單。本質上就是一個不斷備份、傳送、還原日誌的過程。使用交易記錄傳送對於測試日誌是否有效來說非常合適。
交易記錄傳送還有一點值得注意的地方就是,當有大量操作的時候,考慮使用大容量交易記錄模式,從而避免大量的日誌通過網路傳輸。
交易記錄對於維護一個資料庫冗餘的副本來說是最簡單的方式,雖然不能保證資料即時,但對於特定業務情境還是非常有意義的。
事務複製
與前幾種高可用性特性不同的是,交易記錄無法直接傳送交易記錄。因為發布端和訂閱端資料庫的結構可以完全不一樣,訂閱端可以僅僅訂閱一個或多個表,表中的一部分列,或是一部分資料子集。由於發布端和訂閱端的表結構和資料不一致,因此無法直接將發布端的記錄傳送到訂閱端。
因此事務複製的原理是Log Reader Agent定期讀取發布端的日誌,匯總日誌對發布內容的更改,從而將這些更改變為邏輯操作,從而使得訂閱端可以Replay這些操作來打到資料同步的目的。
這裡值得注意的是,如果Log Reader Agent還沒有掃描最新的修改,事務複製可能造成發布端的日誌無法截斷。
小結
本篇文章作為對前面四篇文章的補充,講述了日誌在災難恢複和高可用性中的原理和作用。這些原理對於設計一個好的備份計劃、高可用性計劃來說,是必不可少的。