淺談SQL Server中的事務日志(五)----日志在高可用和災難恢復中的作用


本篇文章是系列文章中的第五篇,是對前一個日志系列的補充篇。如果您對日志的基本概念還沒有一個比較系統的了解,可以參看本系列之前的文章:

淺談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

圖1.如果數據庫正常關閉,直接附加即可

 

    但值得注意的是,使用該方式附加數據庫會自動重建日志文件,日志文件大小為0.5MB,也就是2個VLF,自動增長為10%,因此您需要手動再來設置一下日志的大小,避免出現太多VLF的情況。

 

2.數據庫非正常關閉,日志損壞

    在講述這種情況之前,我們首先來看數據庫所能處在的幾種狀態,一個完整的模型如圖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

圖3.監控隊列的計數器

 

事務日志傳送

    相比其他高可用性功能來說,事務日志傳送功能比較簡單。本質上就是一個不斷備份、傳送、還原日志的過程。使用事務日志傳送對於測試日志是否有效來說非常合適。

    事務日志傳送還有一點值得注意的地方就是,當有批量操作的時候,考慮使用大容量事務日志模式,從而避免大量的日志通過網絡傳輸。

    事務日志對於維護一個數據庫冗余的副本來說是最簡單的方式,雖然不能保證數據實時,但對於特定業務場景還是非常有意義的。

 

事務復制

    與前幾種高可用性特性不同的是,事務日志無法直接傳送事務日志。因為發布端和訂閱端數據庫的結構可以完全不一樣,訂閱端可以僅僅訂閱一個或多個表,表中的一部分列,或是一部分數據子集。由於發布端和訂閱端的表結構和數據不一致,因此無法直接將發布端的日志傳送到訂閱端。

    因此事務復制的原理是Log Reader Agent定期讀取發布端的日志,匯總日志對發布內容的更改,從而將這些更改變為邏輯操作,從而使得訂閱端可以Replay這些操作來打到數據同步的目的。

    這里值得注意的是,如果Log Reader Agent還沒有掃描最新的修改,事務復制可能造成發布端的日志無法截斷。

 

 

小結

    本篇文章作為對前面四篇文章的補充,講述了日志在災難恢復和高可用性中的原理和作用。這些原理對於設計一個好的備份計划、高可用性計划來說,是必不可少的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM