MySQL數據庫主從架構

在這裏插入圖片描述

爲什麼會用到MySQL主從架構?

1.做數據的熱備,將從庫作爲後備數據庫,主數據庫服務器故障後,可切換到從數據庫繼續工作,避免數據丟失。
2.滿足業務需求,當業務量越來越大,O/I頻率越來越高,單個主機已經無法滿足需求,增添架構,可以分擔業務量,提升O/I性能,也就是所謂的負載均衡。
3.爲MySQL其他架構做基礎,例如:讀寫分離,高可用。

什麼是MySQL主從複製(REPLICATION)?

通過字面上來看,最起碼要有兩臺數據庫,並且他們的關係是主與從。MySQL主從複製就是將數據庫羣中一臺或多臺服務器作爲主(master)數據庫,其他數據庫作爲從(slave)數據庫,然後指向主庫,實時同步主庫中的數據;當主庫數據發生變化時,會將變化的數據實時同步到一個或多個從庫。

MySQL主從複製過程

其中涉及到了三個線程和兩個日誌:
Binary log(二進制日誌)和Binary log Jump Thread(二進制日誌線程)屬於主數據庫。
I/OThread(輸入/輸出線程),Relay Log(中繼日誌)和SQL Thread(SQL線程)屬於從數據庫。

對於日誌就不用多說了,不管是二進制日誌還是中繼日誌,其中存放的都是SQL語句。

線程解釋:
Binary log dump 線程
當從節點連接主節點後,主節點會創建一個log dump線程,用於發送binlog日誌中的內容。

I/O線程
當從節點執行"start slave"命令後,從節點會創建一個I/O線程用來連接主節點,請求主庫更新的binlog日誌。I/O線程接收到主節點log dump線程發來的更新數據之後,保存到本地的relay log日誌。

SQL線程
SQL線程讀取relay log日誌中的內容,然後解析成具體的SQL語句並執行,最終完成數據同步。

在這裏插入圖片描述
主從複製過程:
1)主節點數據更新,隨後將具體的更新語句寫到binlog日誌中。

2)從節點開啓主從複製功能,創建一個I/O線程,連接主節點。

3)主節點接收到從節點的連接後,創建一個binary log dump線程,把binlog日誌中更新的內容發送到從節點。

4)從節點的I/O線程讀取主節點發送的binlog日誌,並寫入到relay log中。

5)從庫創建SQL線程,讀取relay log日誌中的內容,並解析執行,完成數據同步。

以上描述是一主一從架構,若是其他架構,其原理也是一樣的,只不過細節上稍微有一點不一樣。例如:一主多從架構,在主從複製時,主節點會分別爲每個從節點創建一個binary log dump線程傳遞更新數據,而從節點使用各自的I/O線程和SQL線程。

二進制日誌格式

MySQL的三種複製方式:
基於SQL語句複製(statement-based replication,簡稱SBR)
基於行的複製(row-based replication,簡稱RBR)
混合模式複製(mixed-based replication,簡稱MBR)

根據不同的方式,binlog日誌的格式也有三種,分別是:STATEMENT(基於SQL語句複製),ROW(基於行的複製),MIXED (混合模式複製)。

STATEMENT模式(SBR)

會將數據修改的SQL語句寫到binlog日誌中,無需記錄每行數據變化,減少了日誌量,但有些數據無法保存,不能保證數據的一致性。

ROW模式(RBR)

此模式爲默認。

僅記錄數據被修改,修改成什麼樣子,不記錄SQL語句信息,很大程度上保證了數據的一致性,但會產生大量的日誌。

MIXED模式(MBR)

結合STATEMENT模式和ROW模式使用,優先使用STATEMENT模式保存binlog,對於STATEMENT模式無法保存的數據,則使用ROW模式進行保存。對於STATEMENT模式是否能夠保存數據,由MySQL自行判斷。

MySQL主從複製模式

全同步模式
主庫執行完一個事務後,所有從庫也執行該事務,當所有從庫都執行完該事務後才返回給客戶端。

優點:確保數據的一致性
缺點:性能影響嚴重

異步複製

此模式爲默認。

主庫執行完一個事務後,立即將更新數據發送給從庫,並不關心從庫是否接收。

優點:減少部分資源消耗
缺點:無法確認從庫是否複製成功

半同步模式
相當於異步複製的改良版,主庫執行完事務後,至少一個從庫接收並寫入到relay log中才返回給客戶端。

優點:確保從庫複製成功
缺點:這個過程需要花費一部分時間

MySQL架構方案

一主一從
在這裏插入圖片描述
提升負載均衡

一主多從
在這裏插入圖片描述
提升負載均衡,可用於高可用和讀寫分離,但主節點I/O壓力較大。

多主一從
在這裏插入圖片描述
適用於寫操作較爲頻繁的環境。

互爲主從
在這裏插入圖片描述
也叫做雙主互備,用於讀寫操作都較爲頻繁的環境。

注:有人說這個架構可以提供負載均衡,我個人認爲對的,但是每當有一個庫數據更新,另一個庫都需要消耗一部分資源來進行同步數據,架構還不如使用一主一從。

聯機複製
在這裏插入圖片描述
將一臺從庫作爲中繼,減輕主庫的I/O壓力。

更改二進制日誌格式

對於二進制日誌的保存操作,默認的ROW格式並不是一個很好的選擇,其會產生大量的日誌數據,對後續的主從複製效率不高。

查看binlog格式

mysql> show variables like "binlog_format";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+

其實不管是主從架構,還是單純的保存binlog日誌,ROW格式都不是最好的選擇,建議使用MIXED格式,其結合STATEMENT模式和ROW模式保存數據,即能減少日誌的大小,又能確保數據的完整。

直接編輯/etc/my.cnf配置文件,在其中指定binlog日誌格式即可。

binlog-format=MIXED

隨後重啓數據庫,刷新配置。

/etc/init.d/mysql.server restart 

再次進入到數據庫中查看binlog日誌格式

mysql> show variables like "binlog_format";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | MIXED |
+---------------+-------+

已成功更改爲MIXED模式。

MySQL主從複製部署

以一主一從爲例,列舉了MySQL架構的搭建過程。

環境準備

系統版本/MySQL版本 主機名 IP地址 角色 準備
CentOS7.7/MySQL8.0.13 linux.node1 192.168.1.123 master 關閉防火牆,selinux
CentOS7.7/MySQL8.0.13 linux.node2 192.168.1.123 slave 關閉防火牆,selinux

一主一從架構部署

1)搭建時間同步服務

對於數據的實時同步,若兩臺服務器的時間都對不上,又談何而來的實時同步呢?

主節點安裝NTP服務

yum install -y ntp

修改ntp服務的配置文件,路徑位於 /etc/ntp.conf ,並添加以下兩項

server 127.127.1.0  #權威NTP不可用時,本機時間作爲時間服務
fudge 127.127.1.0 stratum 8 #NTP服務的階級層數,同步上層服務器的stratum 大小不能超過或等於16

開啓服務

systemctl start ntpd

查看端口

netstat -anpu | grep ntpd
udp        0      0 192.168.122.1:123       0.0.0.0:*                           2726/ntpd           
udp        0      0 192.168.1.123:123       0.0.0.0:*                           2726/ntpd           
udp        0      0 127.0.0.1:123           0.0.0.0:*                           2726/ntpd           
udp        0      0 0.0.0.0:123             0.0.0.0:*                           2726/ntpd           
udp6       0      0 fe80::8c62:89:ad82::123 :::*                                2726/ntpd           
udp6       0      0 ::1:123                 :::*                                2726/ntpd           
udp6       0      0 :::123                  :::*                                2726/ntpd           

從節點安裝ntp客戶端

yum install -y ntpdate

與主節點同步時間

ntpdate 192.168.1.123
19 Jun 16:31:27 ntpdate[61266]: adjust time server 192.168.1.123 offset 0.459178 sec

顯示將時間偏移了0.459178秒,時間同步成功。

注:以下爲主節點配置

2)創建測試數據

mysql> create database replication;
mysql> use replication;
mysql> create table test(id int,name varchar(233));
mysql> insert into test values(1,'一主一從');

3)創建主從複製授權用戶

mysql> create user 'slave'@'192.168.1.%' identified by '123456'; 
mysql> grant replication slave on *.* to 'slave'@'192.168.1.%';
mysql> flush privileges;

4)修改my.cnf文件

以下爲添加配置項

server-id=1
binlog-format=MIXED
log-bin=/data/mysql/log/mysql-bin-master
binlog-do-db=replication
#binlog-ignore-db=mysql

server-id: mysql的同步的數據中是包含server-id的,用於標識該語句最初是從哪個server寫入,不同節點的server-id不能相同。
binlog-format:binlog日誌格式
log-bin:binlog日誌存放路徑
binlog-do-db:指定binlog日誌保存哪個庫的數據記錄,不添加爲全庫。
binlog-ignore-db:指定binlog日誌不保存哪個庫的數據記錄,不添加爲全部不保存。(若有binlog-do-db配置項,則只保存其指定的庫)

重啓數據庫,刷新配置

/etc/init.d/mysql.server restart 

5)查看生成的二進制日誌

ls /data/mysql/log/
mysql-bin-master.000001  mysql-bin-master.index  mysqld.log

數據庫中查看

mysql> show master status\G
*************************** 1. row ***************************
             File: mysql-bin-master.000001
         Position: 155
     Binlog_Do_DB: replication
 Binlog_Ignore_DB: mysql
Executed_Gtid_Set: 

6)將主庫的數據傳入從庫

mysqldump -uroot replication > db.sql
scp db.sql root@192.168.1.124:~
The authenticity of host '192.168.1.124 (192.168.1.124)' can't be established.
ECDSA key fingerprint is SHA256:dt6xhgOGH0g33XrYjk1qPbtD4C2hg62DlqfRMoUSK88.
ECDSA key fingerprint is MD5:9b:ef:79:5b:01:9e:63:0d:75:a7:c7:3e:62:a7:6a:04.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.124' (ECDSA) to the list of known hosts.
root@192.168.1.124's password: 
db.sql                                     100% 1817     2.3MB/s   00:00    

注:以下爲從節點配置

7)從庫將SQL腳本導入庫中

mysql -uroot -e "create database replication;"
mysql replication < db.sql 

查看數據是否導入成功

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| replication        |
| sys                |
+--------------------+

8)修改my.cnf文件
在原有基礎上添加以下配置項

server-id=2
relay-log=/data/mysql/log/relay-log-bin
relay-log-index=/data/mysql/log/slave-relay-bin.index
#replicate_do_db=replication

server-id:服務器ID號
relay-log:relay-log日誌存放路徑
relay-log-index:relay-log日誌的索引文件存放路徑
replicate_do_db:指定從庫複製的數據庫

重啓服務,刷新配置

/etc/init.d/mysql.server restart 

9)測試授權用戶是否可以登錄主庫

mysql -uslave -h192.168.1.123 -p123456

登錄進去後,查看其中的數據庫

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
+--------------------+

因爲只有主從複製權限,其他權限沒有開放,所以是看不到其他庫的,但不影響查看數據庫的命令執行。

10)從庫使用授權用戶連接主庫

這裏的授權用戶是由主庫創建的,本案例中的爲slave。

數據庫默認是開啓主從複製的,先關閉

mysql> stop slave;

連接主庫,具體參數根據實際情況指定

mysql> change master to master_host='192.168.1.123',master_user='slave',master_password='123456',master_log_file='mysql-bin-master.000001',master_log_pos=155;

以下爲此案例中主庫的binlog日誌文件,用於理解命令

mysql> show master status\G
*************************** 1. row ***************************
             File: mysql-bin-master.000001
         Position: 155
     Binlog_Do_DB: replication
 Binlog_Ignore_DB: mysql
Executed_Gtid_Set: 

解讀:
master_host:主庫IP地址
master_user:主庫授權用戶
master_password:主庫授權用戶密碼
master_log_file:主庫binlog日誌文件名稱
master_log_pos:主庫binlog日誌文件位置

開啓主從複製功能

mysql> start slave;

11)分別在主庫和從庫中查看主從複製狀態

從庫中查看

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.123
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin-master.000001
          Read_Master_Log_Pos: 155
               Relay_Log_File: relay-log-bin.000002
                Relay_Log_Pos: 329
        Relay_Master_Log_File: mysql-bin-master.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: replication
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 155
              Relay_Log_Space: 535
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 1b3423c4-b047-11ea-bfaa-000c29bbe2d8
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0

其中 Slave_IO_Running和Slave_SQL_Running線程爲YES,表示主庫連接成功,也就是說主從複製搭建成功了。有一個爲Connecting,都表示主從複製沒有搭建成功。

主庫中查看

mysql> show processlist\G
...
*************************** 3. row ***************************
     Id: 18
   User: slave
   Host: 192.168.1.124:43856
     db: NULL
Command: Binlog Dump
   Time: 716
  State: Master has sent all binlog to slave; waiting for more updates
   Info: NULL

可以看到binlog dump線程已經建立,連接的主機爲192.168.1.124。

12)驗證主從複製功能
主庫現有數據

mysql> select * from replication.test;
+------+--------------+
| id   | name         |
+------+--------------+
|    1 | 一主一從     |
+------+--------------+

從庫現有數據

mysql> select * from replication.test;
+------+--------------+
| id   | name         |
+------+--------------+
|    1 | 一主一從     |
+------+--------------+

在主庫中插入數據

mysql> insert into replication.test values(2,'測試');

在從庫中查看數據是否同步成功

mysql> select * from replication.test;
+------+--------------+
| id   | name         |
+------+--------------+
|    1 | 一主一從     |
|    2 | 測試         |
+------+--------------+

若是主從狀態正常,但數據沒有同步成功,那一定概率就是主庫的binlog日誌位置變了,重新查看主庫的binlog日誌位置,再次連接主庫即可。

或者說刪除binlog日誌(reset master),重新創建並連接。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章