MySQL Replication是MySQL非常出色的一個功能,該功能將一個MySQL例項中的資料複製到另一個MySQL例項中。整個過程是非同步進行的,但由於其高效的效能設計,複製的延時非常小。MySQL複製功能在實際的應用場景中被廣泛的應用於保證資料系統資料的安全性和可擴充套件設計中。
1、MySQL Replication功能的意義
網際網路應用系統中,一個設計恰當的WEB應用伺服器在絕大多數情況下都是無狀態的(Session除外,Session共享可通過WEB容器解決),故WEB應用伺服器的擴充套件和叢集相對簡單。但資料庫的叢集和複製就不那麼容易了。各個資料庫廠商也一直在努力使自己的產品能夠像WEB應用伺服器一樣能夠方便的複製和叢集。
MySQLReplication的出現使我們能夠非常方便將某一資料庫中的資料複製到多臺伺服器中,從而實現資料備份、主從熱備、資料庫叢集等功能。這樣有效的提高了資料庫的處理能力,提高了資料安全性等。
2、MySQLReplication實現原理
MySQL的複製(replication)是一個非同步的複製,從一個MySQLinstace(稱之為Master)複製到另一個MySQLinstance(稱之Slave)。整個複製操作主要由三個程式完成的,其中兩個程式在Slave(Sql程式和IO程式),另外一個程式在Master(IO程式)上。
要實施複製,首先必須開啟Master端的binarylog(bin-log)功能,否則無法實現。因為整個複製過程實際上就是Slave從Master端獲取該日誌然後再在自己身上完全順序的執行日誌中所記錄的各種操作。複製的基本過程如下:
(1)Slave上面的IO程式連線上Master,並請求從指定日誌檔案的指定位置(或者從最開始的日誌)之後的日誌內容;
(2)Master接收到來自Slave的IO程式的請求後,通過負責複製的IO程式根據請求資訊讀取指定日誌指定位置之後的日誌資訊,返回給Slave的IO程式。返回資訊中除了日誌所包含的資訊之外,還包括本次返回的資訊已經到Master端的bin-log檔案的名稱以及bin-log的位置;
(3)Slave的IO程式接收到資訊後,將接收到的日誌內容依次新增到Slave端的relay-log檔案的最末端,並將讀取到的Master端的bin-log的檔名和位置記錄到master-info檔案中,以便在下一次讀取的時候能夠清楚的告訴Master“我需要從某個bin-log的某個位置開始往後的日誌內容,請發給我”;
(4)Slave的Sql程式檢測到relay-log中新增加了內容後,會馬上解析relay-log的內容成為在Master端真實執行時候的那些可執行的內容,並在自身執行。
3、複製實現級別
MySQL的複製有三種模式:Statement Level、Row Level、Mixed Level。複製級別的不同,會導致Master端二進位制日誌檔案的生成形式的不同。
3.1 Statement Level複製
該模式是最早的複製模式,主要的流程是Master端將每一條會修改資料的Query記錄下來,Slave端在複製的時候會根據二進位制檔案重新執行相同的Query。這種模式的優點是Master端不需要記錄每一行資料的變化,二進位制日誌檔案量小,IO成本低,速度快。
相應的,該模式存在的缺點如下:由於記錄的是執行語句,就需要額外的知道每條語句執行的上下文資訊,以保證該相同的操作在Slave端執行時能夠得到和Master同樣的結果。但由於MySQL功能的不斷增多,這種複製模式需要考慮的情況也就越來越多,出現bug的機率也就也大。從MySQL 5.0開始,MySQL複製解決了大量的之前版本中出現的無法複製或複製錯誤的問題,但隨著MySQL的發展,這種挑戰將會日趨嚴峻。
3.2 Row Level複製
MySQL開發人員意識到Statement Level存在的問題,於5.1.5開始提供Row Level模式。該模式的主要流程是,MySQL二級制日誌檔案會將每一行資料修改都記錄下來,然後在Slave端進行同樣的修改。這種模式的優點是:日誌檔案不會將SQL語句執行的上下文記錄下來,只是記錄哪一條資料修改了,修改成什麼樣子了;這樣做可以避免如某些特定情況下儲存過程、trigger的呼叫和觸發沒有被正確執行等複製問題。
同樣,該模式也存在缺點:日質量的成倍增加。例如:執行alter table之類的語句的時候,由於表結構修改,每條記錄都發生改變,那麼該表每一條記錄都會記錄到日誌中。這樣就大增加了複製過程的IO成本,導致速度下降、效能下降。
3.3 Mixed Level複製
MySQL從5.1.8開始,提供Mixed Level。該模式結合了之前兩種模式的優點,規避了二者的缺點。在該模式下,MySQL會根據執行的每一條語句來區分記錄日誌檔案的格式。舉例說明,當涉及到複雜的儲存過程時,採用Row Level,規避Statement Level存在的某些場景無法複製的問題;當涉及到Alter table等操作時,採用Statement Level來規避Row Level帶來的日誌量巨大的問題。
4、MySQL Replication詳細配置
4.1 環境介紹
4.1.1 Master環境介紹
1)作業系統:Ubuntu12.04 32位
2)Mysql版本:5.5.40-0ubuntu0.12.04.1-log (Ubuntu)
3)IP:192.168.245.140
4.1.2 Slave環境介紹:
1)作業系統:Ubuntu12.04 32位
2)Mysql版本:5.5.40-0ubuntu0.12.04.1-log (Ubuntu)
3)IP:192.168.245.139
4.2 配置
4.2.1 Master配置
1)my.cnf配置
#vi /etc/mysql/my.cnf [mysqld] log-bin=mysql-bin //[必須]啟用二進位制日誌 server-id=140 //[必須]伺服器唯一ID,預設是1,一般取IP最後一段
2)重啟mysql
sudo /etc/init.d/mysql restart
3)在主伺服器上建立帳戶並授權slave
#mysql –u root –p 123456 mysql>GRANT REPLICATION SLAVE ON *.* to 'mysync'@'%' identified by '123456'; //一般不用root帳號,“%”表示所有客戶端都可能連,只要帳號,密碼正確,此處可用具體客戶端IP代替,如192.168.245.139,加強安全。
4) 登入mysql,查詢master的狀態
mysql>show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000004 | 308 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec)
注:執行完此步驟後不要再操作主伺服器MYSQL,防止主伺服器狀態值變化。
4.2.2 Slave配置
1)my.cnf配置
#vi /etc/mysql/my.cnf [mysqld] log-bin=mysql-bin //[必須]啟用二進位制日誌 server-id=139 //[必須]伺服器唯一ID,預設是1,一般取IP最後一段
2)重啟mysql
sudo /etc/init.d/mysql restart
3)配置從伺服器Slave:
mysql>change master to master_host='192.168.245.140',master_user='mysync',master_password='123456',master_log_file='mysql-bin.000004',master_log_pos=308; //注意不要斷開,“308”無單引號。M ysql>start slave; //啟動從伺服器複製功能
4) 檢查從伺服器複製功能狀態:
mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.245.140 Master_User: root Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000003 Read_Master_Log_Pos: 5669 Relay_Log_File: mysqld-relay-bin.000002 Relay_Log_Pos: 5482 Relay_Master_Log_File: mysql-bin.000003 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 5669 Relay_Log_Space: 5639 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 140 1 row in set (0.00 sec)
注:Slave_IO及Slave_SQL程式必須正常執行,即YES狀態,否則都是錯誤的狀態。
4.3 主從伺服器測試
主伺服器Mysql,建立資料庫,並在這個庫中建表插入一條資料,觀看從庫是否也增加了相應的資料庫、資料表、資料。
5、MySQL Replication常用架構總結
5.1 主從備份架構設計
簡述:兩臺mysql伺服器如果其中有一臺mysql伺服器掛掉後,另外一臺能立馬接替其進行工作。因此我們就必須保證兩臺mysql資料庫的資料完全一樣,而且當掛掉的那一臺重新啟動的話,不再會被客戶端繼被訪問,而是會充當備機跟現在工作的mysql進行資料同步,一直到提供服務的那臺掛掉後再接替其工作。如此周而復始的實現了mysql的高可用。注意:Slave不對外提供服務;Slave和Master在同一個區域網內,以此保證主從複製的速度和連線的穩定性。
5.2 主主備份架構設計A
簡述:Mysql主主備份架構A——兩臺伺服器互為主備,即A寫的資料可以同步到B中去,B寫的資料可以同步到A中去。代理伺服器負責對讀寫進行負載均衡。
缺點:自增主鍵的衝突問題無法解決;寫操作頻繁時,會導致併發問題。
適用場景:寫操作不多;無自增主鍵;主、備機同時承擔讀寫任務,節省機器,適用於機器緊張的場景。
5.3 主主備份架構設計B
Mysql主主備份架構B——兩臺伺服器互為主備,即A寫的資料可以同步到B中去,B寫的資料可以同步到A中去。但是,應用伺服器通過keepalived只向Master(即其中之一)進行寫入操作,代理伺服器負責對讀操作進行負載均衡。
缺點:需要額外解決讀寫分離的問題
優點:不需要額外的指令碼控制主備角色轉換;資料一致性保證