萬盛學電腦網

 萬盛學電腦網 >> 數據庫 >> 數據庫綜合 >> MySQL 的復制的工作原理

MySQL 的復制的工作原理

當然,MySQL的復制有許多方面,但本文主要講述其邏輯——復制事件怎樣寫入主機,怎樣傳送至復制語句以及他們隨後怎樣應用。注意,本文並不講述怎樣執行復制,而是介紹復制的工作原理。

復制事件

我在這篇文章中說“復制事件”是因為我不想避免討論與不同的復制格式有關的東西。 這些都已經非常好地在 in the MySQL manual here談到了。簡單地說,這些事件可以是以下的兩種:

基於語句 – 在這種情況下編寫查詢語句

基於行 – 如果你真要為其歸類的話,類似於行變化的差異信息

除些之外,我不會回顧用不同的復制格式來復制, 主要是因為它們在傳輸數據時差異性很小。

關於master

讓我們先來看看master是如何工作的. 對於復制的工作, 首先所有的master需要向一個特別的稱之為二進制日志的文件中寫入復制事件. 這是個非常輕量的動作(假設事件不會同步到磁盤), 因為寫操作是順序的並且是緩沖的形式. 二進制日志文件存儲了之後slave將要讀取的數據信息.(master/slave個人覺得還是英文更能體現其深刻意義,故未翻譯,譯者注)

當slave請求連接到一個master的時候, master會創建一個新的線程 (這個過程和其他的服務器客戶端的方式基本一樣) 來處理客戶端 – slave 的請求. 大部分的操作給slave提供二進制日志中的事件並且通知slave有新的寫入事件到二進制日志中.

Slaves最開始的時候很可能會去讀取仍存儲在master操作系統緩存中的事件, 因此這時在master上還沒有任何物理磁盤的讀操作. 但是, 當你幾小時後甚至幾天後連接到一台slave機器上, slave會首先開始讀取幾小時或幾天之前寫入的二進制日志 – 此時master很可能不會再有這些數據的緩存, 那麼讀磁盤操作就不可避免的發生了. 如果master沒有任何的空閒的IO資源, 這時你可能會感受到服務震蕩.

關於復制

讓我們看看slave都干了些什麼東東. 當你啟動應用的時候, slave會開啟二個線程:

1. IO 線程

這個過程會調用IO 線程連接到一台master上, 讀取master到來的二進制日志事件然後僅僅是將它們復制到本地的一個叫 中繼日志的文件中. 僅僅是這些.

盡管只有一個線程從master上讀binlog,同時只有一個線程在slave上去寫relay log,但是這種 replication event 被復制的方式,幾乎不會被當做導致 replication變得更慢的因素

如果你想了解當前IO線程所處何處, 使用“show slave status\G”來查看具體信息:

Master_Log_File – 從master上復制過來的最近的文件 (多數情況下它和master最近寫入的二進制日志文件一樣)

Read_Master_Log_Pos – master上二進制日志復制到slave上中繼日志的位置.

2. SQL 線程

第二個過程 – SQL 線程 – 從slave本地的中繼日志中讀取事件 (就是被IO線程寫入的文件) 並且盡快的使用它們.

這個線程由於是單線程化的所以飽受人們的批判. 回到 “show slave status\G”, 你可以從下面的變量中獲取當前SQL線程的狀態信息:

Relay_Master_Log_File – 來自master的二進制日志, 供SQL線程處理 (實際上SQL線程是工作在中繼日志上的, 這僅僅是為了展示信息的方便性)

Exec_Master_Log_Pos – SQL線程執行的二進制日志的位置.

復制延遲

在這裡,現在我大體上介紹一下復制延遲這個問題。當你遇到復制延遲時,首先你要知道兩個復制線程中,是哪一個出問題。大多數情況下是由於SQL線程出現了問題,不過你仍然需要二次檢查一下。你可以使用上面提到的(本機)復制狀態(show slave status\G)和主機二進制日志狀態(使用show master status\G獲得)進行比較。

我上面已經提過很多次了,由於IO線程引起的復制延遲是很少見的,如果是IO線程引起的,有一個你可以嘗試解決的方法是,使用enabling slave compressed protocol(備機數據壓縮協議)。

另外,如果你確認是SQL線程的問題,想搞明白問題的原因,你可以使用vmstat命令了解具體原因。使用這個命令對服務器狀態監控一段時間後,觀察輸出列表中是“r”列還是“b”列占用了大部分時間。如果是“r”列數值較高,那麼復制過程主要是CPU密集型操作,否則是IO密集型操作。如果還不是非常確定,可以使用CPU監控命令mpstat,得到更直觀的了解。

注意,上面監控的結果是假設你沒有其他程序運行在服務器上。如果有一些其他的程序運行在服務器上,你可以了解一下diskstats,使用這個工具查詢SQL線程可以生成一個更好的監控圖。

如果你確定復制是CPU密集型操作, 這個可能也會對你有用。

如果是IO密集型操作,解決這個問題可能並不容易(也許可能很簡單)。讓我解釋一下吧。如果是IO密集型,這意味著大多數時間,因為讀操作是單線程進行的,所以SQL線程不能夠快速讀到數據。是的,這就是問題所在,讀操作限制了復制的性能,而不是寫操作。讓我更詳細地解釋一下。

假設你有一個RAID10,帶寫緩存的硬盤。現在開始寫操作,即使寫操作是串行操作,因為寫數據可以緩沖在緩存控制器,並且RAID卡內部可以並行寫數據到多個硬盤。因此具備相似硬件的備機,寫速度幾乎可以和主機同步。

然後現在開始 讀操作。當你的任務集合(workset)不適合在內存中時,已經變化的數據將必須首先從硬盤讀出,這時候單線程讀操作限制了復制的速度,因為單線程讀操作時,某一時刻一個線程僅僅只能從一個硬盤讀取數據。

正如剛才所說的,解決IO密集型復制操作性能的問題,可以增加內存容量,使更多的任務集合(workset)可以適合在內存中。另一種方法是更換IO設備,以使單線程每秒鐘可以讀取更多的數據 - 現在傳統最快的硬盤可以達到250個IO操作/每秒,SSDs(固態硬盤)可以達到1000個IO操作/每秒。

以上就是精品為大家整理的MySQL 的復制的工作原理,希望對大家有所幫助。

copyright © 萬盛學電腦網 all rights reserved