MySQL數據庫主從同步原理及環境部署


一、MySQL主從復制的作用

1、數據熱備:作為后備數據庫,主數據庫服務器故障后,可切換到從數據庫繼續工作,避免數據丟失。

2、架構擴展:業務量越來越大,I/O訪問頻率過高,單機無法滿足,此時做多庫的存儲,降低磁盤I/O訪問的頻率,提高單個機器的I/O性能。

3、讀寫分離:使數據庫能支撐更大的並發。在報表中尤其重要。由於部分報表sql語句非常的慢,導致鎖表,影響前台服務。如果前台使用master,報表使用slave,那么報表sql將不會造成前台鎖,保證了前台速度。

二、MySQL主從復制的流程

1、主庫db的更新事件(update、insert、delete)被寫到binlog

2、從庫發起連接,連接到主庫

3、此時主庫創建一個binlog dump thread線程,把binlog的內容發送到從庫

4、從庫啟動之后,創建一個I/O線程,讀取主庫傳過來的binlog內容並寫入到relay log.

5、還會創建一個SQL線程,從relay log里面讀取內容,從Exec_Master_Log_Pos位置開始執行讀取到的更新事件,將更新內容寫入到slave的db

 

補充:由上述可知

對於每一個主從復制的連接,都有三個線程

1)inlog輸出線程:每當有從庫連接到主庫的時候,主庫都會創建一個線程然后發送binlog內容到從庫。

      在從庫里,當復制開始的時候,從庫就會創建兩個線程進行處理:

2)從庫I/O線程:當START SLAVE語句在從庫開始執行之后,從庫創建一個I/O線程,該線程連接到主庫並請求主庫發送binlog里面的更新記錄到從庫上。從庫I/O線程讀取主庫的binlog輸出線程發送的更新並拷貝這些更新到本地文件,其中包括relay log文件。

3)從庫的SQL線程:從庫創建一個SQL線程,這個線程讀取從庫I/O線程寫到relay log的更新事件並執行。

三、MySQL主從同步環境部署

3.1、環境規划

安裝MySQL主從同步前,先分別安裝兩台單機版MySQL,參見:https://www.cnblogs.com/wuxinchun/p/15194008.html

主機   系統 IP 賬號 密碼 服務
Master   Centos7.4  10.3.104.52 master 123456 MySQL5.7
Slave Centos7.4  10.3.104.56 slave 123456 MySQL5.7

 

1、master數據庫的my.cnf配置(Master主服務器上操作)

[root@docker01 ~]# vim /etc/my.cnf
#數據庫唯一ID,主從的標識號絕對不能重復。
server-id=1

#開啟bin-log,並指定文件目錄和文件名前綴
log-bin=mysql-bin

#需要同步的數據庫。如果是多個同步庫,就以此格式另寫幾行即可。如果不指明對某個具體庫同步,就去掉此行,表示同步所有庫(除了ignore忽略的庫) 
#binlog-do-db=kevin

#不同步mysql系統數據庫。如果是多個不同步庫,就以此格式另寫幾行;也可以在一行,中間逗號隔開
binlog-ignore-db = mysql,information_schema

#每次寫入時都將binlog與硬盤同步
sync_binlog = 1

#binlog日志格式,mysql默認采用statement,建議使用mixed
binlog_format = MIXED

#binlog日志文件
log-bin =/var/lib/mysql/mysql-bin.log

#binlog過期清理時間
expire_logs_days = 7

#binlog每個日志文件大小
max_binlog_size = 100m

#binlog緩存大小
binlog_cache_size = 4m

#最大binlog緩存大小
max_binlog_cache_size = 512m

 

 

 

2、slave數據庫的my.cnf配置(Slave從服務器上操作)

[root@docker02 ~]# vim /etc/my.cnf
#數據庫唯一ID,主從的標識號絕對不能重復。
server-id=2

#開啟bin-log,並指定文件目錄和文件名前綴
log-bin=mysql-bin

#需要同步的數據庫。如果是多個同步庫,就以此格式另寫幾行即可。如果不指明對某個具體庫同步,就去掉此行,表示同步所有庫(除了ignore忽略的庫)
#binlog-do-db=kevin 

#不同步mysql系統數據庫。如果是多個不同步庫,就以此格式另寫幾行;也可以在一行,中間逗號隔開
binlog-ignore-db = mysql,information_schema

#每次寫入時都將binlog與硬盤同步
sync_binlog = 1

#binlog日志格式,mysql默認采用statement,建議使用mixed
binlog_format = MIXED

#binlog日志文件
log-bin =/var/lib/mysql/mysql-bin.log

#binlog過期清理時間
expire_logs_days = 7

#binlog每個日志文件大小
max_binlog_size = 100m

#binlog緩存大小
binlog_cache_size = 4m

#最大binlog緩存大小
max_binlog_cache_size = 512m

 

 

3、master創建用於slave機器獲取master機器上binlog文件的賬號(Master主服務器上操作)

mysql> grant replication slave,replication client on *.* to slave@'10.3.104.56' identified by "123456";    //IP為slave地址
Query OK, 0 rows affected (0.02 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

 

 

 

4、slave庫同步master庫的命令如下(即不需要跟master_log_file 和 master_log_pos=120,slave服務器上操作):

mysql> stop slave; 
mysql> change master to master_host = '10.3.104.52', master_port = 3306, master_user ='slave', master_password ='123456';
mysql> start slave;
mysql> show slave status \G;
Slave_IO_Running: Yes Slave_SQL_Running: Yes

 注:上述已完成單向主從同步

 

3.2、驗證單向數據同步性

1)在master上創建表並插入數據

mysql> create database test;
Query OK, 1 row affected (0.00 sec)
mysql> use test;
Database changed
mysql> create table testtable(id int,name varchar(20));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into testtable values (1,'zhangsan');
Query OK, 1 row affected (0.01 sec)
mysql> select * from testtable;
+------+----------+
| id   | name     |
+------+----------+
|    1 | zhangsan |
+------+----------+
1 row in set (0.00 sec)

 

 

2)slave庫檢查數據

mysql> select * from test.testtable;
+------+----------+
| id   | name     |
+------+----------+
|    1 | zhangsan |
+------+----------+
1 row in set (0.00 sec)

 注:說明數據已經同步到slave

 

 

3.3、雙向同步配置驗證

1)slave創建用於master機器獲取slave機器上binlog文件的賬號(slave服務器上操作)

mysql> grant replication slave,replication client on *.* to master@'10.3.104.52' identified by "123456";   //IP為master地址
Query OK, 0 rows affected (0.02 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

 

 

2)master庫同步slave庫的命令如下(master服務器上操作)

mysql> stop slave; 
mysql> change master to master_host = '10.3.104.56', master_port = 3306, master_user ='master', master_password ='123456';
mysql> start slave;
mysql> show slave status \G;
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

 注:上述雙向同步已配置完成

1)如果單向同步就關閉另一端stop slave;
2)如果雙向同步在兩個節點分別執行start slave

 

補充:mysql主從同步延時分析

mysql的主從復制都是單線程的操作,主庫對所有DDL和DML產生的日志寫進binlog,由於binlog是順序寫,所以效率很高,slave的sql thread線程將主庫的DDL和DML操作事件在slave中重放。DML和DDL的IO操作是隨機的,不是順序,所以成本要高很多,另一方面,由於sql thread也是單線程的,當主庫的並發較高時,產生的DML數量超過slave的SQL thread所能處理的速度,或者當slave中有大型query語句產生了鎖等待,那么延時就產生了。

解決方案:

1.業務的持久化層的實現采用分庫架構,mysql服務可平行擴展,分散壓力。

2.單個庫讀寫分離,一主多從,主寫從讀,分散壓力。這樣從庫壓力比主庫高,保護主庫。

3.服務的基礎架構在業務和mysql之間加入memcache或者redis的cache層。降低mysql的讀壓力。

4.不同業務的mysql物理上放在不同機器,分散壓力。

5.使用比主庫更好的硬件設備作為slave,mysql壓力小,延遲自然會變小。

6.使用更加強勁的硬件設備

 


免責聲明!

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



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