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