一、 MySQL復制的實現原理
MySQL支持單向、雙向復制、異步復制,復制過程中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。主服務器將更新寫入一個二進制日志文件中,並創建一個索引文件以跟蹤日志循環。這些日志可以記錄發送到從服務器的更新。當一個從服務器連接主服務器時,日志文件會通知主服務器,從服務器在日志中讀取的最後一次成功更新的位置。接著,從服務器在上次成功更新的位置處開始進入更新操作。更新完成後從服務器開始進入等待狀態,等待主服務器後續的更新。
需要注意的是:在進行復制時,所有對復制中的表的更新必須在主服務器上進行。否則,可能發生對主服務器上的表進行的更新與對從服務器上的表所進行的更新之間的沖突。
單向復制有利於健壯性、速度和系統管理.
主服務器/從服務器設置增加了健壯性。主服務器出現問題時,可以切換到從服務器。
通過在主服務器和從服務器之間切分處理客戶查詢的負荷,可以得到更好的客戶響應時間。SELECT查詢可以發送到從服務器以降低主服務器的查詢處理負荷。但修改數據的語句仍然應發送到主服務器,以便主服務器和從服務器保持同步。
MySQL提供了數據庫的同步功能,這對實現數據庫的冗災、備份、恢復、負載均衡等都是有極大幫助的。
一般情況下,在Mysql復制中,主服務器也稱為master,二從服務器稱為slave,因此,想要啟用同步機制,在master上就必須啟用二進制日志。每個slave接受來自master上在二進制日志中記錄的更新操作,而在slave上相當於執行了這個操作的一個拷貝。
二、 MySQL同步細節
MySQL同步功能由3個線程(master上1個binlog dump,slave上2個,分別是Sql進程和IO進程)來實現。執行“START SLAVE”語句後,slave就創建一個I/O線程。I/O線程連接到master上,並請求master發送二進制日志中的語句。master創建一個線程來把日志的內容發送到slave上。
slave上的I/O線程讀取master的Binlog Dump線程發送的語句,並且把它們拷貝到其數據目錄下的中繼日志(relay logs)中。第三個是SQL線程,salve用它來讀取中繼日志,然後執行它們來更新數據。
slave上使用2個線程的優點是,把讀日志和執行分開成2個獨立的任務。執行任務如果慢的話,讀日志任務不會跟著慢下來。例如,如果slave停止了一段時間,那麼I/O線程可以在slave啟動後很快地從master上讀取全部日志,盡管SQL線程可能落後I/O線程好幾的小時。如果slave在SQL線程沒全部執行完就停止了,但I/O線程卻已經把所有的更新日志都讀取並且保存在本地的中繼日志中了,因此在slave再次啟動後就會繼續執行它們了。這就允許在master上清除二進制日志,因為slave已經無需去master讀取更新日志了。
本文講解的環境為:一個mysql的master主節點node1,三個Mysql的Slave節點,三個Slave節點都從primary節點進行實時的同步數據,Mysql高可用集群主機信息如圖1所示:
圖1
三、在node1、slave1、slave2、slave3上安裝MYSQL
安裝MySQL有多種方法,這裡僅以rpm安裝為列說明。
[root@node1~]#yum -y install mysql-server mysql-devel mysql mysql-bench mysql-test
安裝完成後,使用如下命令啟動mysql服務:
[root@node1 ~]# /etc/init.d/mysqld start
為了保障數據安全,建議把數據放到專業的存儲設備或者磁盤陣列分區,這裡假定磁盤陣列的分區為/data目錄,接著把數據文件放到/data目錄下:
[root@node1 ~]# cp -R /var/lib/mysql /data/mysql
[root@node1 ~]# chown –R mysql:mysql /data/mysql
修改/etc/my.cnf文件,在[mysqld]組增加如下配置:
datadir = /data/mysql
最後,重啟MySQL服務即可。
四、在Mysql主節點node1上編輯配置文件my.cnf
編輯主服務器的配置文件/etc/my.cnf,在[mysqld]中添加如下內容即可:
server-id = 1 #服務器ID。服務器之間不能有重復ID,一般master是1
log-bin=mysql-bin #打開mysql的binlog功能,後面的名字可以自己指定,如果不改名字的話,默認是以主機名字命名
binlog-do-db=ixdba #ixdba是需要備份的數據庫名,如果備份多個數據庫,重復設置這個選項即可
binlog-ignore-db=mysql #不需要備份的數據庫名稱,如果需要忽略備份多個數據庫,重復設置這個選項即可。
五、在master節點node1上建立復制用戶
mysql>GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%' IDENTIFIED BY 'repl_password';
這裡一定將repl_user用戶設置為遠程任意節點可以登錄。
六、備份Master數據
備份Master上的數據,首先執行如下SQL語句:
mysql>FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.00 sec)
mysql> reset master;
Query OK, 0 rows affected (0.00 sec)
不要退出這個終端,否則這個鎖就失效了;在不退出終端的情況,再開一個終端直接打包壓縮數據文件或使用mysqldump工具來導出數據。
[root@node1 ~]# cd /var/lib/ #進入mysql的數據目錄,根據自己情況而定。
[root@node1 lib]# tar zcvf mysql.tar.gz mysql
[root@node1 lib]# scp mysql.tar.gz 192.168.12.231/232/233:/var/lib/
用scp命令把打包的數據傳到其他幾台Slave機器上。
數據傳輸完成之後,在上面的命令終端上執行:
mysql>UNLOCK TABLES;
七、設置Slave主機
編輯/etc/my.cnf文件,在[mysqld]中添加如下內容即可:
server-id = 2
log-bin=mysql-bin
binlog-do-db=ixdba
binlog-ignore-db=mysql
其他的Slave以此類推,保證server-id全局唯一即可。
八、 在slave上執行如下命令
mysql> CHANGE MASTER TO MASTER_HOST='192.168.12.135',
-> MASTER_USER='repl_user',
-> MASTER_PASSWORD='repl_password',
-> MASTER_LOG_FILE='mysql-bin.000001',
-> MASTER_LOG_POS=98;
執行完之後執行:
mysql> slave start;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G
從輸出可以看到:Slave_IO_Running和Slave_SQL_Running如果都為Yes時,表示配置成功。
九、需要注意的幾個問題
(1)如果在my.cnf裡面定義了log-bin、relay-log參數,那麼要保證定義與hostname無關,因為如果這兩類log的文件名與主機名有關,切換過程會導致slave主機不能繼續同步的問題。例如可以做下設置:
log-bin = mysql-bin
relay-log = mysql-relay-bin
保證在兩台主機上兩種文件的名字一樣。
(2)最好把my.cnf文件也放入磁盤陣列所在分區的數據目錄。