1 引言
高可用是系統架構設計中必須考慮的因素之一,主要目標是消除基礎架構中的單點故障,通常表示為一個百分比,表示在給定時間段內特定系統或組件的正常運行時間,其中100%表示系統永不失效。而任何的單機系統因受限於軟硬件的限制,如硬件損壞、操作系統崩潰、軟件BUG、業務壓力過大等原因,都不可能保證系統100%可用。一旦出現此類問題,如何能快速恢復用戶業務,將影響程度減至最低,降低故障RTO(Recovery Time Objective,恢復時間目標)成為我們所要考慮的問題。
對於數據庫系統來說,比較通用的解決方案是將單機程序部署在多臺主機上,組成一個集群共同對外提供服務。在MySQL中,最常見的一種部署方式為主從複製,這種部署方式一方面滿足了故障恢復的場景,又能夠在一定程序上分擔主庫的壓力,做到了業務的讀寫分離。相較於Oracle的RAC(real application clusters,實時應用集群)來講,一不需要共享存儲,二不需要內存同步,也無需VIP(Virtual IP Address,虛擬IP地址)。因此MySQL的主從部署更為便捷,實現原理也簡單。本文將對MySQL主從複製的實現原理進行介紹。
2 一主一從複製實現原理
在數據庫實現技術中,最基本的、必須要滿足的一個特性便是ACID,即事務的原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。為了實現ACID,MySQL引入了Binlog(二進制日誌),數據庫中所有的DML、DDL語句都將記錄在Binlog當中。如用戶在主庫上執行了一條update語句,那麼在Binlog中便會記錄這條update語句,這樣就可以使用Binlog來進行實例間的數據同步,Binlog也成為MySQL主從複製的實現基礎,能夠達到增量數據同步的目的,具體實現原理如下圖所示。
圖1:MySQL一主一從複製實現原理圖
- 主庫所有的DML、DDL操作語句記錄到Binlog日誌中。
- 從庫中的IO線程會實時捕獲主庫中Binlog的變化內容,並寫到從庫的中繼日誌Relay log裡。Relay log會持久化到本地文件中。
- 從庫中的SQL線程負責從Relay log日誌裡取出Binlog內容,並把所有的語句按先後順序在從庫中執行一遍,這樣就實現了主從間數據的一致性。
以上便是MySQL主從庫實現增量數據同步的步驟和原理。
3 一主一從部署
在實際部署過程中,需要先做全量數據的同步,保證從庫中存在與主庫相同的基礎數據,然後再進行增量同步。一般使用數據庫全庫的備份恢復來做主從間的全量同步,即先在主庫上做一次全量備份,然後把備份傳到從庫中進行全量恢復。這裡會有一個問題,主庫不會一直是靜止狀態,數據備份和恢復需要一定的時間,這個時間長短完全取決於數據量的大小以及主從間的傳輸帶寬,從庫執行完全量恢復後可能已經落後主庫一段時間,這段時間的增量數據就需要Binlog來追。所以在從庫上需要執行一個change master的命令來告訴從庫需要從哪個位置來同步主庫的Binlog日誌,同時從庫上會啟動IO線程和SQL線程,IO線程從指定位置開始讀取Binlog,SQL線程用來回放日誌。當從庫追平主庫時,便完成了主從部署和搭建。
以上便是MySQL基於Binlog進行主從複製的相關內容,不過這種機制是100%可靠的麼?會不會有例外情況?讀者可思考一下,下期我們將繼續進行介紹。