主從複製的原理:
分爲同步複製和異步複製,實際複製架構中大部分爲異步複製。
複製的基本過程如下:
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端真實執行時候的那些可執行的內容,並在自身執行。
Mysql爲了解決這個風險並提高複製的性能,將Slave端的複製改爲兩個進程來完成。提出這個改進方案的人是Yahoo!的一位工程師“Jeremy Zawodny”。這樣既解決了性能問題,又縮短了異步的延時時間,同時也減少了可能存在的數據丟失量。當然,即使是換成了現在這樣兩個線程處理以後,同樣也還是存在slave數據延時以及數據丟失的可能性的,畢竟這個複製是異步的。只要數據的更改不是在一個事物中,這些問題都是會存在的。如果要完全避免這些問題,就只能用mysql的cluster來解決了。不過mysql的cluster是內存數據庫的解決方案,需要將所有數據都load到內存中,這樣就對內存的要求就非常大了,對於一般的應用來說可實施性不是太大。
複製常用架構
Mysql複製環境90%以上都是一個Master帶一個或者多個Slave的架構模式,主要用於讀壓力比較大的應用的數據庫端廉價擴展解決方案。因爲只要master和slave的壓力不是太大(尤其是slave端壓力)的話,異步複製的延時一般都很少很少。尤其是自slave端的複製方式改成兩個進程處理之後,更是減小了slave端的延時。而帶來的效益是,對於數據實時性要求不是特別的敏感度的應用,只需要通過廉價的pc server來擴展slave的數量,將讀壓力分散到多臺slave的機器上面,即可解決數據庫端的讀壓力瓶頸。這在很大程度上解決了目前很多中小型網站的數據庫壓力瓶頸問題,甚至有些大型網站也在使用類似方案解決數據庫瓶頸。
Mysql主從複製配置過程:
環境:master: 192.168.0.3
Slave: 192.168.0.4
Mysql版本爲5.0.67(編譯安裝)
database: eric
1. Master服務器啓動mysql,
a) #mysql –uroot –proot
b) 創建一個有複製權限的用戶,只限slave遠程連接訪問.
i. mysql>grant replication slave on *.* to [email protected] identified by ‘password’;
ii. mysql>flush privileges;
c) mysql>flush tables with read lock; #鎖定master服務器所有表的寫入。
d) 重新打開一終端,備份要複製的數據庫。
i. Var]#tar zcvf eric.tar.gz eric/ //eric所在路徑/opt/mysql/var/eric/即一個庫。
ii. ]#scp eric.tar.gz 192.168.0.4:/opt/mysql/var/ //將主服務器的庫傳到slave相應路徑下。
e) 返回上一終端。
i. Mysql>show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000014 | 98 | eric | |
+------------------+----------+--------------+------------------+
1 row in set (0.01 sec)
其中mysql-bin.000014和98二個值將是slave與master的同步點。
f) 給數據庫解鎖(當備份完成後) mysql>unlock tables;
g) 編輯mysql的配置文件。Vim /etc/my.cnf 設置這三個參數,沒有的添加,有的直接更改即可。
log-bin=mysql-bin
server-id = 1
binlog-do-db=eric
保存退出。
2. Slave服務器配置
a) 將從master中備份的庫解壓到相應路徑下(退庫的導入)
i. Var]#tar zxvf eric.tar.gz ./
b) 修改my.cnf
server-id=2
master-host=192.168.0.3
master-user= replication
master-password= password
log-bin=
3. 重啓master, slave的mysql服務
a) 注意順序,先重啓master-à 然後是slave.
b) Slave服務器重啓後,登錄mysql
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> change master to
-> master_host='192.168.0.3',
-> master_user='replication',
-> master_password='password',
-> master_log_file='mysql-bin.000014',
-> master_log_pos=98;
Query OK, 0 rows affected (0.02 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.0.3
Master_User: replication
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000014
Read_Master_Log_Pos: 98
Relay_Log_File: alan-relay-bin.000002
Relay_Log_Pos: 235
Relay_Master_Log_File: mysql-bin.000014
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: 98
Relay_Log_Space: 235
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
1 row in set (0.01 sec)
ERROR: No query specified
當這個參數都爲yes時,證明主從複製成功
Slave_IO_Running: Yes Slave_SQL_Running: Yes