MySQL主從複製、半同步複製和主主複製概述

zping發表於2016-03-14

一、MySQL複製概述

   ⑴、MySQL資料的複製的基本介紹

   目前MySQL資料庫已經佔去資料庫市場上很大的份額,其一是由於MySQL資料的開源性和高效能,當然還有重要的一條就是免費~不過不知道還能免費多久,不容樂觀的未來,但是我們還是要能熟練掌握MySQL資料的架構和安全備份等功能,畢竟現在它還算是開源界的老大吧!

   MySQL資料庫支援同步複製、單向、非同步複製,在複製的過程中一個伺服器充當主服務,而一個或多個伺服器充當從伺服器。主伺服器將更新寫入二進位制日誌檔案,並維護檔案的一個索引以跟蹤日誌迴圈。這些日誌可以記錄傳送到從伺服器的更新。當一個從伺服器連線主伺服器時,它通知主伺服器從伺服器在日誌中讀取的最後一次成功更新的位置。從伺服器接收從那時起發生的任何更新,然後封鎖並等待主伺服器通知新的更新。

請注意當你進行復制時,所有對複製中的表的更新必須在主伺服器上進行。否則,你必須要小心,以避免使用者對主伺服器上的表進行的更新與對從伺服器上的表所進行的更新之間的衝突。
   單向複製有利於健壯性、速度和系統管理:

   健壯性:主伺服器/從伺服器設定增加了健壯性。主伺服器出現問題時,你可以切換到從伺服器作為備份。

   速度快:通過在主伺服器和從伺服器之間切分處理客戶查詢的負荷,可以得到更好的客戶響應時間。SELECT查詢可以傳送到從伺服器以降低主伺服器的查詢處理負荷。但修改資料的語句仍然應傳送到主伺服器,以便主伺服器和從伺服器保持同步。如果非更新查詢為主,該負載均衡策略很有效,但一般是更新查詢。

   系統管理:使用複製的另一個好處是可以使用一個從伺服器執行備份,而不會干擾主伺服器。在備份過程中主伺服器可以繼續處理更新。

   ⑵、MySQL資料複製的原理

   MySQL複製基於主伺服器在二進位制日誌中跟蹤所有對資料庫的更改(更新、刪除等等)。因此,要進行復制,必須在主伺服器上啟用二進位制日誌。

   每個從伺服器從主伺服器接收主伺服器已經記錄到其二進位制日誌的儲存的更新,以便從伺服器可以對其資料拷貝執行相同的更新。

   認識到二進位制日誌只是一個從啟用二進位制日誌的固定時間點開始的記錄非常重要。任何設定的從伺服器需要主伺服器上的在主伺服器上啟用二進位制日誌時的資料庫拷貝。如果啟動從伺服器時,其資料庫與主伺服器上的啟動二進位制日誌時的狀態不相同,從伺服器很可能失敗。

   將主伺服器的資料拷貝到從伺服器的一個途徑是使用LOAD DATA FROM MASTER語句。請注意LOAD DATA FROM MASTER目前只在所有表使用MyISAM儲存引擎的主伺服器上工作。並且,該語句將獲得全域性讀鎖定,因此當表正複製到從伺服器上時,不可能在主伺服器上進行更新。當我們執行表的無鎖熱備份時,則不再需要全域性讀鎖定。

   MySQL資料複製的原理圖大致如下:

從上圖我們可以看出MySQL資料庫的複製需要啟動三個執行緒來實現:

   其中1個在主伺服器上,另兩個在從伺服器上。當發出START SLAVE時,從伺服器建立一個I/O執行緒,以連線主伺服器並讓它傳送記錄在其二進位制日誌中的語句。主伺服器建立一個執行緒將二進位制日誌中的內容傳送到從伺服器。該執行緒可以識別為主伺服器上SHOW PROCESSLIST的輸出中的Binlog Dump執行緒。從伺服器I/O執行緒讀取主伺服器Binlog Dump執行緒傳送的內容並將該資料拷貝到從伺服器資料目錄中的本地檔案中,即中繼日誌。第3個執行緒是SQL執行緒,是從伺服器建立用於讀取中繼日誌並執行日誌中包含的更新。

   在前面的描述中,每個從伺服器有3個執行緒。有多個從伺服器的主伺服器建立為每個當前連線的從伺服器建立一個執行緒;每個從伺服器有自己的I/O和SQL執行緒。

   這樣讀取和執行語句被分成兩個獨立的任務。如果語句執行較慢則語句讀取任務沒有慢下來。例如,如果從伺服器有一段時間沒有執行了,當從伺服器啟動時,其I/O執行緒可以很快地從主伺服器索取所有二進位制日誌內容,即使SQL執行緒遠遠滯後。如果從伺服器在SQL執行緒執行完所有索取的語句前停止,I/O 執行緒至少已經索取了所有內容,以便語句的安全拷貝儲存到本地從伺服器的中繼日誌中,供從伺服器下次啟動時執行。這樣允許清空主伺服器上的二進位制日誌,因為不再需要等候從伺服器來索取其內容。

二、實列說明MySQL的主從複製架構和實現詳細過程

     主從架構資料庫的複製圖如下:

其配置詳細過程如下:

   1、環境架構:

       RedHat Linux Enterprise 5.8         mysql-5.5.28-linux2.6-i686.tar

       Master:172.16.7.1/16                 Slave:172.16.7.2/16

   2 、安裝mysql-5.5.28,需要在主節點和備節點上安裝mysql

       Master:

       安裝環境準備:

 

[sql] view plain copy
 
 print?
  1. 為mysql的安裝提供前提環境和初始化安裝mysql  
  2. 建立資料庫目錄  
  3. # mkdir /mydata/data –pv  
  4. 建立mysq使用者  
  5. # useradd -r mysql  
  6. 修改許可權  
  7. # chown -R mysql.mysql /mydata/data/  
  8. 使用mysql-5.5通用二進位制包安裝  
  9. 解壓mysql軟體包  
  10. # tar xf mysql-5.5.28-linux2.6-i686.tar.gz-C /usr/local/  
  11. 建立連線,為了方便檢視mysql的版本等資訊  
  12. # cd /usr/local/  
  13. #ln –sv mysql-5.5.28-linux2.6-i686.tar.gzmysql  
  14. 修改屬主屬組  
  15. # cd mysql  
  16. # chown -R root.mysql ./*  
  17. 初始化資料庫  
  18. # scripts/mysql_install_db –user=mysql --datadir=/mydata/data/  
  19. 提供配置檔案  
  20. # cp support-files/my-large.cnf /etc/my.cnf  
  21. 提供服務指令碼  
  22. # cp support-files/mysql.server/etc/rc.d/init.d/mysqld  
  23. 新增至服務列表  
  24. # chkconfig --add mysqld  
  25. # chkconfig --list mysqld  
  26. # chkconfig mysqld on  
  27. 編輯配置檔案,提供資料目錄  
  28. # vim /etc/my.cnf  
  29. # The MySQL server  修改mysqld伺服器端的內容  
  30. log-bin=master-bin 主伺服器二進位制日誌檔案字首名  
  31. log-bin-index=master-bin.index  索引檔案  
  32. innodb_file_per_table= 1     開啟innodb的一表一個檔案的設定  
  33. server-id       = 1          必須是唯一的  
  34. datadir =/mydata/data        資料目錄路徑  
  35. 啟動mysql服務  
  36. # servicemysqld start  
  37. 為了便於下面的測試,設定環境變數  
  38. # vim/etc/profile.d/mysql.sh  
  39. export PATH=$PATH:/usr/local/mysql/bin  
  40. 執行環境變數指令碼,使其立即生效  
  41. # . /etc/profile.d/mysql.sh  



 

 

 啟動服務並進行相關的測試:

 mysql的安裝配置完成,下面增加一個用於同步資料的賬戶並設定相關的許可權吧!

 

 

[sql] view plain copy
 
 print?
  1. 建立使用者賬戶  
  2. mysql> grant replication slave on *.* to 'chris'@'172.16.%.%' identified by 'work';  
  3. 重新整理資料使其生效  
  4. mysql> flush privileges;  

 

   至此我們mysql的Master設定完成,下面進行slave端的設定吧!

   Slave:

   安裝環境配置:

 

 

[sql] view plain copy
 
 print?
  1. 建立mysql資料庫目錄  
  2. # mkdir /mydata/data –pv  
  3. 建立mysql使用者  
  4. # useradd -r mysql  
  5. 修改資料目錄許可權  
  6. # chown -R mysql.mysql /mydata/data/  
  7. 使用mysql-5.5通用二進位制包安裝mysql  
  8. 解壓mysql軟體包  
  9. # tar xf mysql-5.5.28-linux2.6-i686.tar.gz-C /usr/local/  
  10. 建立連線,便於檢視mysql的版本等資訊  
  11. # cd /usr/local/  
  12. # ln –sv mysql-5.5.28-linux2.6-i686.tar.gzmysql  
  13. 修改mysql屬主屬組  
  14. # cd mysql  
  15. # chown -R root.mysql ./*  
  16. 初始化mysql資料庫  
  17. # scripts/mysql_install_db –user=mysql--datadir=/mydata/data/  
  18. 提供mysql配置檔案  
  19. # cp support-files/my-large.cnf /etc/my.cnf  
  20. 提供服務指令碼  
  21. # cp support-files/mysql.server /etc/init.d/mysqld  
  22. 新增至服務列表  
  23. # chkconfig --add mysqld  
  24. 編輯配置檔案  
  25. # vim /etc/my.cnf  
  26. # The MySQL server  
  27. #log-bin=mysql-bin      禁用二進位制日誌,從伺服器不需要二進位制日誌檔案  
  28. datadir = /mydata/data  mysql的資料目錄  
  29. relay-log = relay-log   設定中繼日誌  
  30. relay-log-index = relay-log.index  中繼日誌索引  
  31. innodb_file_per_table = 1  
  32. server-id       = 2    id不要和主伺服器的一樣  
  33. 設定環境變數  
  34. # vim/etc/profile.d/mysql.sh  
  35. export PATH=$PATH:/usr/local/mysql/bin  
  36. 執行此指令碼(匯出環境變數)  
  37. # . /etc/profile.d/mysql.sh  
  38. 啟動服務  
  39. # service mysqld start  

 

 

  到這slave服務的mysql安裝和配置完成,下面啟動slave複製吧,開啟之前先檢視下從服務上的二進位制檔案吧

[sql] view plain copy
 
 print?
  1. mysql> show master status; #在Master上執行檢視二進位制檔案  
  2. 在從伺服器上開啟複製功能  
  3. change master to master_host='172.16.7.1',master_user='chris',master_password='work',master_log_file='master-bin.000001',master_log_pos=407;  
  4. 開啟複製功能  
  5. mysql>start slave;  

至此我們的mysql伺服器的主從複製架構已經基本完成,下面開啟服務並測試測試吧~

在從伺服器開啟複製程式:mysql>start slave;

   至此我們mysql伺服器的主從複製架構已經完成,但是我們現在的主從架構並不完善,因為我們的從服務上還可以進行資料庫的寫入操作,一旦使用者把資料寫入到從伺服器的資料庫內,然後從伺服器從主伺服器上同步資料庫的時候,會造成資料的錯亂,從而會造成資料的損壞,所以我們需要把從伺服器設定成只讀~方法如下:

注意:read-only = ON ,這項功能只對非管理員組以為的使用者有效!

OK,此致我們的mysql基於主從架構的複製功能已經搭建全部完成~下面介紹下關於mysql資料目錄下面各個檔案的功能和作用!

   由於二進位制檔案的緩衝區內,當我們的伺服器當機的時候,快取區內的資料並沒有同步到二進位制日誌檔案內的時候,那就悲劇了,緩衝區內的資料就無法找回了,為了防止這種情況的傳送,我們通過設定mysql直接把二進位制檔案記錄到二進位制檔案而不再緩衝區內停留。

sync-binlog = ON 在主伺服器上進行設定,用於事務安全

  從上面我們可以看到從伺服器啟動的時候其Slave_IO_Running: Yes和Slave_SQL_Running: Yes是自動啟動的,但是有時候我們在主服務上進行的誤操作等,也會直接同步到從伺服器上的,要想恢復那就難了,所以我們需要關閉其自動執行功能,讓其能夠停止,skip-slave-start = 1 ,讓其不開啟自動同步,但是遺憾的是mysql5.28上已經沒有了,我們可以通過停止相關執行緒來實現:

mysql>STOP SLAVE 或STOP SLAVE  IO_THREAF或STOP SLAVE SQL_THREAD

注意:從伺服器的所有操作日誌都會被記錄到資料目錄下的錯誤日誌中!

三、MySQL的半同步複製

 

   實現半同步複製的功能很簡單,只需在mysql的主伺服器和從伺服器上安裝個google提供的外掛即可實現,

   主服務上使用semisync_master.,從伺服器上使用sosemisync_slave.so外掛即可實現,外掛在mysql通用二進位制的mysql/lib/plugin目錄內。

其配置步驟如下

1、分別在主從節點上安裝相關的外掛

master:

 

 

[sql] view plain copy
 
 print?
  1. 安裝外掛:mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';  
  2. 啟動模組:mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;  
  3. 設定超時時間:mysql> SET GLOBAL rpl_semi_sync_master_timeout = 1000;  

 

1
2
3
4
slave:
安裝外掛:msyql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
啟動模組:mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
重啟程式使其模組生效:mysql> STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;


  上面的設定時在mysql程式內動態設定了,會立即生效但是重啟服務以後就會失效,為了保證永久有效,需要把相關配置寫到主、從伺服器的配置檔案my.cnf內:

 

 

[sql] view plain copy
 
 print?
  1. 在Master和Slave的my.cnf中編輯:  
  2. On Master  
  3. [mysqld]  
  4. rpl_semi_sync_master_enabled=1  
  5. rpl_semi_sync_master_timeout=1000   #此單位是毫秒  
  6. On Slave  
  7. [mysqld]  
  8. rpl_semi_sync_slave_enabled=1  

 

  確認半同步功能已經啟用,通過下面的操作進行檢視

[sql] view plain copy
 
 print?
  1. master:  
  2. mysql> CREATE DATABASE asyncdb;  
  3. master> SHOW STATUS LIKE 'Rpl_semi_sync_master_yes_tx';  
  4. slave> SHOW DATABASES;  
  5. 其測試過程如下  

然後把從伺服器上的複製程式開啟,

  我們至此已經實現了mysql資料庫複製的半同步方式的架構,並且通過測試檢視了複製功能,下面我們進行雙主模型架構吧。

四、MySQL設定主-主複製:master<-->slave 
1、在兩臺伺服器上各自建立一個具有複製許可權的使用者;讓兩個資料庫互為主從的關係

2、修改配置檔案:

把上面的連個資料庫的配置檔案重新配置,其配置如下 

 

 

[sql] view plain copy
 
 print?
  1. # 主伺服器上  
  2. [mysqld]  
  3. server-id = 1  
  4. log-bin = mysql-bin  
  5. relay-log = relay-mysql  
  6. relay-log-index = relay-mysql.index  
  7. auto-increment-increment = 2           #每次跳兩個數。  
  8. auto-increment-offset = 1              #從1開始。  

 

 

 

[sql] view plain copy
 
 print?
  1. [mysqld]  
  2. server-id = 2  
  3. log-bin = mysql-bin  
  4. relay-log = relay-mysql  
  5. relay-log-index = relay-mysql.index  
  6. auto-increment-increment = 2  
  7. auto-increment-offset = 2  

 

  如果此時兩臺伺服器均為新建立,且無其它寫入操作,各伺服器只需記錄當前自己二進位制日誌檔案及事件位置,以之作為另外的伺服器複製起始位置即可

 

 

[sql] view plain copy
 
 print?
  1. master:檢視日誌檔案資訊  
  2. mysql> show master status;  
  3. +------------------+----------+--------------+------------------+  
  4. | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |  
  5. +------------------+----------+--------------+------------------+  
  6. | mysql-bin.000001 |      107 |              |                  |  
  7. +------------------+----------+--------------+------------------+  
  8. Slave:檢視伺服器日誌檔案資訊  
  9. mysql> show master status;  
  10. +------------------+----------+--------------+------------------+  
  11. | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |  
  12. +------------------+----------+--------------+------------------+  
  13. | mysql-bin.000001 |      107 |              |                  |  
  14. +------------------+----------+--------------+------------------+  
  15. 1 row in set (0.00 sec)  

 

 在各個伺服器上建立賬號和許可權,來進行同步設定

1
2
3
master:
mysql> GRANT REPLICATION SLAVE ON *.* TO 'chrislee'@'172.16.%.%' IDENTIFIED BY 'work';
mysql> flush privileges;

 

 

[sql] view plain copy
 
 print?
  1. slave:  
  2. mysql> GRANT REPLICATION SLAVE ON *.* TO 'chrisli'@'172.16.%.%' IDENTIFIED BY 'work';  
  3. mysql> flush privileges  

 

在各伺服器上指定對另一臺伺服器為自己的主伺服器即可:

 

[sql] view plain copy
 
 print?
  1. server1  
  2. mysql> CHANGE MASTER TO MASTER_HOST='172.16.7.2',MASTER_USER='chrisli',MASTER_PASSWORD='work',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=344;  

 

 

 

[sql] view plain copy
 
 print?
  1. server2:  
  2. mysql> CHANGE MASTER TO MASTER_HOST='172.16.7.1',MASTER_USER='chrislee',MASTER_PASSWORD='work',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=345;  

 

雙主架構配置基本完成,下面在各自上面啟動複製程式吧~並進行測試:

 

轉載自:http://chrinux.blog.51cto.com/6466723/1204586

相關文章