Mysql主從架構的複製原理及配置詳解

一、什麼叫mysql複製?

   關於mysql複製,我是這樣理解的:將某一臺主機上的Mysql數據複製到其它主機(slaves)上,並重新執行一遍從而實現當前主機上的mysql數據與(master)主機上數據保持一致的過程我們可以稱爲複製。

   複製過程中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。主服務器將更新寫入二進制日誌文件,並維護文件的一個索引以跟蹤日誌循環。這些日誌可以記錄發送到從服務器的更新。當一個從服務器連接主服務器時,它通知主服務器從服務器在日誌中讀取的最後一次成功更新的位置。從服務器接收從那時起發生的任何更新,然後封鎖並等待主服務器通知新的更新。


二、mysql複製是如何工作的?

142325926.gif

   從上圖看mysql的主從複製整體來說分爲3個部分:

   1、master將狀態信息的改變記錄到二進制日誌(binary log)中(這些記錄叫做二進制日誌事件,binary log events);

   2、slave將master的binary log events拷貝到它的中繼日誌(relay log);

   3、slave重做中繼日誌中的事件,將狀態信息的改變存儲到本地磁盤行成數據;


   詳細描述如下:

   首先該過程的第一部分就是master記錄二進制日誌。在每個事務更新數據完成之前,master在二日誌記錄這些改變。MySQL將事務串行的寫入二進制日誌,即使事務中的語句都是交叉執行的。在事件寫入二進制日誌完成後,master通知存儲引擎提交事務。

   接下來就是slave將master的binary log拷貝到它自己的中繼日誌。先是slave開始一個工作線程——I/O線程,I/O線程在master上打開一個普通的連接,然後開始binlog dump process從master的二進制日誌中讀取事件,如果已經跟上master,它會睡眠並等待master產生新的事件(Seconds_Behind_Masterk可以觀察落後的狀態),I/O線程將這些事件寫入中繼日誌。

   最後SQL thread(SQL從線程)從中繼日誌讀取事件,並執行事件語句更新slave的數據,使其與master中的數據一致。


   此外,在master中也有一個工作線程:和其它MySQL的連接一樣,slave在master中打開一個連接也會使得master開始一個線程。複製過程有一個很重要的限制——複製在slave上是串行化的,也就是說master上的並行更新操作不能在slave上並行操作(slave會有數據上的延時)。


三、複製能解決的問題及mysql支持的複製類型:

   1、MySQL複製技術有以下一些好處:

       1.1、數據分佈 (Data distribution )

       1.2、可以實現負載均衡(load balancing),通常所說的讀寫分離

       1.3、可以實現數據的備份(Backups),但是不能當真正意義上數據備份來用

       1.4、高可用性和容錯行(比如雙主模型中的互爲主從能實現高可用)

   2、複製類型:

       2.1、基於語句的複製(statement):在主服務器上執行的SQL語句,在從服務器上執行同樣的語句。

            優點:基於語句的複製,效率比較高;需要注意地方:可能無法精確複製,比如sql中更新時間的時候如果不是精準值而是time();什麼的,由於主從複製有延時導致數據的不一致。

       2.2、基於行的複製(row):把改變的內容複製過去,而不是把命令在從服務器上執行一遍。數據複製相對安全,但是產生的日誌文件會過大,比如update某一範圍來數據的狀態,這個範圍有1W條數據,就會產生1W條update語句;

       2.3、混合類型的複製(mixed): mysql5.5默認採用混合類型的複製,也就是上面的兩種根據情況變換着複製。此方法可能會打亂日誌的結構,一會基於語句一會兒基於行,日誌排查日誌的可能看起來不太好使;

   3、mysql複製中需要注意的問題:

       3.1、主從服務器mysql的版本,主庫的版本可以低於從庫,但是從庫的版本一定不能低於主庫(從版本 >= 主版本)

       3.2、爲了複製的安全額外設置:

               從服務器:

                   read_only=ON              關閉寫

                   skip-slave-start=ON       關閉從服務自動啓動

               主服務器:

                   sync_binlog=ON            同步事務的二進制日誌


四、主從複製的配置:

 1、主從服務器各自需要的準備操作  

       1.1、主服務器:

           a、創建具有複製權限的用戶帳號;

mysql> grant replication slave, replication client on *.* to copyuser@'172.16.5.%' identified by '123456';

               mysql> flush privileges;

           b、設置server-id;

# server-id = 10

           c、啓用二進制日誌;

# log-bin = /mydata/log/mysql-bin        日誌存放位置

# binlog_format = row                    基於行復制


       1.2、從服務器:

           a、啓用中繼日誌;(可選:關閉二進制日誌)

               # relay-log = /mydata/log/relay-bin     日誌存放位置

               # read-only = 1                         設置爲只讀(對root權限賬號無效)

           b、設置server-id;

               # server-id = 20

           c、啓動複製線程;

               # change master to master_host='172.16.5.100' master_user='copyuser' master_password='123456'

               # slave start;

               查看狀態:

               # show slave status\G;

               # show processlist;

               在這裏主要是看:

Slave_IO_Running = Yes

               Slave_SQL_Running = Yes

               如果需要只複製某些庫可以指定過濾條件;

               replicate-do-db        = db1,db2      只複製某庫

               replicate-do-table     = db1.mytbl    只複製某庫某表

               replicate_ignore_db    = db3          不復制某庫

               replicate_ignore_table = db1.nytb3    不復制某庫中的某表


五、深入瞭解複製

   1、一主多從

       由一個master和一個slave組成複製系統是最簡單的情況。Slave之間並不相互通信,只能與master進行通信。在實際應用場景中,MySQL複製90%以上都是一個Master複製到一個或者多個Slave的架構模式,主要用於讀壓力比較大的應用的數據庫端廉價擴展解決方案。

155139101.jpg

       在上圖中,如果一主拖了多個從的話,這時主庫既要負責寫又要負責爲幾個從庫提供二進制日誌,此時可以稍做調整,將二進制日誌只給某一從,這一從再開啓二進制日誌並將自己的二進制日誌再發給其它從,或者是乾脆這個從不記錄只負責將二進制日誌轉發給其它從,這樣架構起來性能可能要好得多,而且數據之間的延時應該也稍微要好一些。


   2、主主複製

160305141.jpg

       上圖中,Master-Master複製的兩臺服務器,既是master,又是另一臺服務器的slave。這樣,任何一方所做的變更,都會通過複製應用到另外一方的數據庫中。在這種複製架構中,各自上運行的不是同一db,比如左邊的是db1,右邊的是db2,db1的從在右邊反之db2的從在左邊,兩者互爲主從,再輔助一些監控的服務還可以實現一定程度上的高可以用。


   3、主動-被動模式(HA)

160336681.jpg

       上圖中,這是由master-master結構變化而來的,它避免了M-M的缺點,實際上,這是一種具有容錯和高可用性的系統。它的不同點在於其中只有一個節點在提供讀寫服務,另外一個節點時刻準備着,當主節點一旦故障馬上接替服務。比如通過corosync+pacemaker+drbd+mysql就可以提供這樣一組高可用服務,主備模式下再跟着slave服務器,也可以實現讀寫分離。


   4、mysql-5.5支持半同步複製

       mysql複製我們都知道是基於異步來實現的,但是從mysql-5.5開始,支持半自動複製。在以前版本中異步(asynchronous)複製中,主庫在執行完一些事務後,是不會管備庫的進度的。如果備庫處於落後,而更不幸的是主庫此時又出現Crash(例如宕機),這時備庫中的數據就是不完整的。簡而言之,在主庫發生故障的時候,我們無法使用備庫來繼續提供數據一致的服務了。Semisynchronous Replication(半同步複製)則一定程度上保證提交的事務已經傳給了至少一個備庫。Semi synchronous中,僅僅保證事務的已經傳遞到備庫上,但是並不確保已經在備庫上執行完成了。

       此外,還有一種情況會導致主備數據不一致。在某個session中,主庫上提交一個事務後,會等待事務傳遞給至少一個備庫,如果在這個等待過程中主庫Crash,那麼也可能備庫和主庫不一致,這是很致命的。如果主備網絡故障或者備庫掛了,主庫在事務提交後等待10秒(rpl_semi_sync_master_timeout的默認值)後,就會繼續。這時,主庫就會變回原來的異步狀態。

MySQL在加載並開啓Semi-sync插件後,每一個事務需等待備庫接收日誌後才返回給客戶端。如果做的是小事務,兩臺主機的延遲又較小,則Semi-sync可以實現在性能很小損失的情況下的零數據丟失。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章