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)重啓mysqlsudo /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
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”無單引號。
`Mysql>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(即其中之一)進行寫入操作,代理服務器負責對讀操作進行負載均衡。
缺點:需要額外解決讀寫分離的問題
優點:不需要額外的腳本控制主備角色轉換;數據一致性保證