MySQL數據的主從複製、半同步複製和主主複製詳解

一、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:

       安裝環境準備:

  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的安裝配置完成,下面增加一個用於同步數據的賬戶並設置相關的權限吧!

  1. 建立用戶賬戶  
  2. mysql> grant replication slave on *.* to 'chris'@'172.16.%.%' identified by 'work';  
  3. 刷新數據使其生效  
  4. mysql> flush privileges;  

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

   Slave:

   安裝環境配置:

  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複製吧,開啓之前先查看下從服務上的二進制文件吧

  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:

  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內:

  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  

  確認半同步功能已經啓用,通過下面的操作進行查看

  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、修改配置文件:

把上面的連個數據庫的配置文件重新配置,其配置如下 

  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開始。  


  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  

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

  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;

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

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

  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;  

  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

發佈了29 篇原創文章 · 獲贊 16 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章