SQL Server 高可用鏡像實現原理

數據副本
鏡像技術實現了位于不同物理服務器上的兩個 SQL Server 實例數據同步,在鏡像集群中, SQL Server 實例具有三種角色:
○ Principal:具有完整的數據副本,對外提供數據庫讀寫服務;
○ Mirror:具有完整的數據副本,本身不提供讀寫服務,通過接收來自 Principal 的更新日志實現數據同步,允許創建快照實現報表;
○ Witness:本身不存儲數據,只負責在高安全運行模式下提供自動故障切換的能力,確保兩個 SQL Server 實例只有一個對外提供服務,避免腦裂情況出現;
在鏡像集群中,principal 和 mirror 的數據同步是依靠事務日志來實現的,與 Oracle 和 MySQL 不同,SQL Server 的事務日志是 Database 級別的,不是實例級別的,每個 Database 都單獨的事務日志,這也就使得 SQL Server 的鏡像是可以基于 Database 層面實現。
一個 SQL Server 實例中的兩個 Database,一個可以作為 principal,一個可以作為 mirror,分別與其他 SQL Server 實例組建鏡像關系;另外,SQL Server 一個 Database 只能有一個 mirror 節點,一個 mirror 的 database 不可以再有 mirror 節點,這點與 MySQL 級聯復制不同;
SQL Server 的事務日志是物理記錄級別的,記錄了對數據庫某個頁的某行記錄(slot)的操作,principal 創建鏡像后,會啟動一個單獨的事務日志發送線程,維護一個虛擬的發送隊列,然后讀取事務日志,將其進行壓縮,根據官方公布的測試數據,壓縮比不低于12.5%,然后發送給 mirror 節點,mirror 節點接收到以后,會將其寫入本地在磁盤上的一個重做隊列文件中,然后再通過另外的一個線程異步的方式,從重做隊列中獲取事務日志,然后分發給應用線程(process unit)進行回放。

不同于 MySQL Binlog,由于 SQL Server 的事務日志在 principal 上事務執行過程中就已經源源不斷的寫入(MySQL Binlog 僅在事務提交階段生成),在 principal 事務執行的同時事務日志就已經傳遞給了 mirror,所以基于事務日志的 SQL Server 的復制性能會更理想。同時,在 mirror 回放的過程中,可以基于頁(page)級別進行并發更新(redo parallel),在 SQL Server 的標準版中,僅提供一個線程進行事務日志回放(roll forward),在企業版中,如果當前服務器 CPU 大于5核,則每4個核,增加一個并行線程,如果低于5個核,則仍然使用單線程回放。同時,基于頁的事務日志的并發執行,還有一個好處就是對于同一個頁面的更新可以合并刷新,減少臟頁刷新數量。