mysql主從同步原理

1、MySQL複製概述mysql

   ⑴、MySQL數據的複製的基本介紹linux

   目前MySQL數據庫已經佔去數據庫市場上很大的份額,其一是因爲MySQL數據的開源性和高性能,固然還有重要的一條就是免費~不過不知道還能免費多久,不容樂觀的將來,可是咱們仍是要能熟練掌握MySQL數據的架構和安全備份等功能,畢竟如今它還算是開源界的老大吧!sql

   MySQL數據庫支持同步複製、單向、異步複製,在複製的過程當中一個服務器充當主服務,而一個或多個服務器充當從服務器。主服務器將更新寫入二進制日誌文件,並維護文件的一個索引以跟蹤日誌循環。這些日誌能夠記錄發送到從服務器的更新。當一個從服務器鏈接主服務器時,它通知主服務器從服務器在日誌中讀取的最後一次成功更新的位置。從服務器接收從那時起發生的任何更新,而後封鎖並等待主服務器通知新的更新。數據庫

請注意當你進行復制時,全部對複製中的表的更新必須在主服務器上進行。不然,你必需要當心,以免用戶對主服務器上的表進行的更新與對從服務器上的表所進行的更新之間的衝突。
   單向複製有利於健壯性、速度和系統管理:vim

   健壯性:主服務器/從服務器設置增長了健壯性。主服務器出現問題時,你能夠切換到從服務器做爲備份。緩存

   速度快:經過在主服務器和從服務器之間切分處理客戶查詢的負荷,能夠獲得更好的客戶響應時間。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 線程至少已經索取了全部內容,以便語句的安全拷貝保存到本地從服務器的中繼日誌中,供從服務器下次啓動時執行。這樣容許清空主服務器上的二進制日誌,由於再也不須要等候從服務器來索取其內容。

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

     主從架構數據庫的複製圖以下:

其配置詳細過程以下:

   一、環境架構:

       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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
爲mysql的安裝提供前提環境和初始化安裝mysql
建立數據庫目錄
# mkdir /mydata/data –pv
建立mysq用戶
# useradd -r mysql
修改權限
# chown -R mysql.mysql /mydata/data/
使用mysql- 5.5 通用二進制包安裝
解壓mysql軟件包
# tar xf mysql- 5.5 . 28 -linux2. 6 -i686.tar.gz-C /usr/local/
建立鏈接,爲了方便查看mysql的版本等信息
# cd /usr/local/
#ln –sv mysql- 5.5 . 28 -linux2. 6 -i686.tar.gzmysql
修改屬主屬組
# cd mysql
# chown -R root.mysql ./*
初始化數據庫
# scripts/mysql_install_db –user=mysql --datadir=/mydata/data/
提供配置文件
# cp support-files/my-large.cnf /etc/my.cnf
提供服務腳本
# cp support-files/mysql.server/etc/rc.d/init.d/mysqld
添加至服務列表
# chkconfig --add mysqld
# chkconfig --list mysqld
# chkconfig mysqld on
編輯配置文件,提供數據目錄
# vim /etc/my.cnf
# The MySQL server  修改mysqld服務器端的內容
log-bin=master-bin 主服務器二進制日誌文件前綴名
log-bin-index=master-bin.index  索引文件
innodb_file_per_table=  1      開啓innodb的一表一個文件的設置
server-id       =  1           必須是惟一的
datadir =/mydata/data        數據目錄路徑
啓動mysql服務
# servicemysqld start
爲了便於下面的測試,設置環境變量
# vim/etc/profile.d/mysql.sh
export PATH=$PATH:/usr/local/mysql/bin
執行環境變量腳本,使其當即生效
# . /etc/profile.d/mysql.sh

 

 

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

 mysql的安裝配置完成,下面增長一個用於同步數據的帳戶並設置相關的權限吧!

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

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

   Slave:

   安裝環境配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
建立mysql數據庫目錄
# mkdir /mydata/data –pv
建立mysql用戶
# useradd -r mysql
修改數據目錄權限
# chown -R mysql.mysql /mydata/data/
使用mysql- 5.5 通用二進制包安裝mysql
解壓mysql軟件包
# tar xf mysql- 5.5 . 28 -linux2. 6 -i686.tar.gz-C /usr/local/
建立鏈接,便於查看mysql的版本等信息
# cd /usr/local/
# ln –sv mysql- 5.5 . 28 -linux2. 6 -i686.tar.gzmysql
修改mysql屬主屬組
# cd mysql
# chown -R root.mysql ./*
初始化mysql數據庫
# scripts/mysql_install_db –user=mysql--datadir=/mydata/data/
提供mysql配置文件
# cp support-files/my-large.cnf /etc/my.cnf
提供服務腳本
# cp support-files/mysql.server /etc/init.d/mysqld
添加至服務列表
# chkconfig --add mysqld
編輯配置文件
# vim /etc/my.cnf
# The MySQL server
#log-bin=mysql-bin      禁用二進制日誌,從服務器不須要二進制日誌文件
datadir = /mydata/data  mysql的數據目錄
relay-log = relay-log   設置中繼日誌
relay-log-index = relay-log.index  中繼日誌索引
innodb_file_per_table =  1
server-id       =  2     id不要和主服務器的同樣
設置環境變量
# vim/etc/profile.d/mysql.sh
export PATH=$PATH:/usr/local/mysql/bin
執行此腳本(導出環境變量)
# . /etc/profile.d/mysql.sh
啓動服務
# service mysqld start

 

  到這slave服務的mysql安裝和配置完成,下面啓動slave複製吧,開啓以前先查看下從服務上的二進制文件吧

1
2
3
4
5
mysql> show master status; #在Master上執行查看二進制文件
在從服務器上開啓複製功能
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 ;
開啓複製功能
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

注意:從服務器的全部操做日誌都會被記錄到數據目錄下的錯誤日誌中!

3、MySQL的半同步複製

 

   實現半同步複製的功能很簡單,只需在mysql的主服務器和從服務器上安裝個google提供的插件便可實現,

   主服務上使用semisync_master.,從服務器上使用sosemisync_slave.so插件便可實現,插件在mysql通用二進制的mysql/lib/plugin目錄內。

其配置步驟以下

一、分別在主從節點上安裝相關的插件

master:

1
2
3
安裝插件:mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME  'semisync_master.so' ;
啓動模塊:mysql> SET GLOBAL rpl_semi_sync_master_enabled =  1 ;
設置超時時間: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
2
3
4
5
6
7
8
在Master和Slave的my.cnf中編輯:
# On Master
[mysqld]
rpl_semi_sync_master_enabled= 1
rpl_semi_sync_master_timeout= 1000    #此單位是毫秒
# On Slave
[mysqld]
rpl_semi_sync_slave_enabled= 1

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

1
2
3
4
5
master:
mysql> CREATE DATABASE asyncdb;
master> SHOW STATUS LIKE  'Rpl_semi_sync_master_yes_tx' ;
slave> SHOW DATABASES;
其測試過程以下

而後把從服務器上的複製進程開啓,

  咱們至此已經實現了mysql數據庫複製的半同步方式的架構,而且經過測試查看了複製功能,下面咱們進行雙主模型架構吧。

4、MySQL設置主-主複製:master<-->slave 
一、在兩臺服務器上各自創建一個具備複製權限的用戶;讓兩個數據庫互爲主從的關係

二、修改配置文件:

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

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

1
2
3
4
5
6
7
[mysqld]
server-id =  2
log-bin = mysql-bin
relay-log = relay-mysql
relay-log-index = relay-mysql.index
auto-increment-increment =  2
auto-increment-offset =  2

  若是此時兩臺服務器均爲新創建,且無其它寫入操做,各服務器只需記錄當前本身二進制日誌文件及事件位置,以之做爲另外的服務器複製起始位置便可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
master:查看日誌文件信息
mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin. 000001  |       107  |              |                  |
+------------------+----------+--------------+------------------+
Slave:查看服務器日誌文件信息
mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin. 000001  |       107  |              |                  |
+------------------+----------+--------------+------------------+
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
2
3
slave:
mysql> GRANT REPLICATION SLAVE ON *.* TO  'chrisli' @ '172.16.%.%'  IDENTIFIED BY  'work' ;
mysql> flush privileges

在各服務器上指定對另外一臺服務器爲本身的主服務器便可:

 

1
2
server1
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
2
server2:
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 ;

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

 

   至此咱們經過上面的測試,能夠看出已經實現了主主複製的功能~到此咱們關於mysql數據庫的主從複製、半同步複製和主主複製的架構都已經實現,東西較多~整理的很差,還望包涵~其中的錯誤還望各位大神指出~

 

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

相關文章
相關標籤/搜索