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

注意:從服務器的所有操作日志都會被記錄到數據目錄下的錯誤日志中!

三、MySQL的半同步復制

 

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

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

其配置步驟如下

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

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數據庫復制的半同步方式的架構,並且通過測試查看了復制功能,下面我們進行雙主模型架構吧。

四、MySQL設置主-主復制:master<-->slave 
1、在兩台服務器上各自建立一個具有復制權限的用戶;讓兩個數據庫互為主從的關系

2、修改配置文件:

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM