搭建MySQL主從復制及原理詳解


搭建MySQL主從復制及原理詳解

​ MySQL的復制有3中常見架構,分別是一主多從復制架構、多級復制架構和雙主復制架構。本片文章主要講解的是一主多從架構及其搭建過程,其它兩種有興趣的讀者可以留言。

1.復制簡述

​ MySQL從3.23版本開始提供復制的功能。復制是指將主數據庫的DDL和DML操作通過二進制日志傳到復制服務器(也叫從庫)上,然后在從庫上對這些日志重新執行(也叫重做),從而使得從庫和主庫的數據保持同步。
​ MySQL支持一台主庫同時向多台從庫進行復制,從庫同時也可以作為其他服務器的主庫,實現鏈狀的復制。
​ MySQL復制的優點主要包括以下3個方面:

  1. 如果主庫出現問題,可以快速切換到從庫提供服務;
  2. 可以在從庫上執行查詢操作,降低主庫的訪問壓力;
  3. 可以在從庫上執行備份,以避免備份期間影響主庫的服務。

2.復制原理

​ (1)首先,MySQL主庫在事務提交時會把數據變更作為事件Events記錄在二進制日志文件Binlog中;MySQL主庫上的sync_binlog參數控制Binlog日志刷新到磁盤。
​ (2)主庫推送二進制日志文件Binlog中的事件到從庫的中繼日志Relay Log,之后從庫根據中繼日志Relay Log重做數據變更操作,通過邏輯復制以此來達到主庫和從庫的數據一致。
​ MySQL通過 3個線程來完成主從庫間的數據復制:其中Binlog Dump線程跑在主庫上, I/O線程和SQL線程跑在從庫上。當在從庫上啟動復制(START SLAVE)時,首先創建 I/O線程連接主庫,主庫隨后創建Binlog Dump線程讀取數據庫事件並發送給 I/O線程,I/O線程獲取到事件數據后更新到從庫的中繼日志Relay Log中去,之后從庫上的SQL線程讀取中繼日志Relay Log中更新的數據庫事件並應用,如下圖所示:

<img src="C:\Users\50312\AppData\Roaming\Typora\typora-user-images\image-20201207083143526.png" alt="image-202

01207083143526" style="zoom:80%;" />

3.復制涉及的各類文件

二進制日志(Binlog)

​ 二進制日志文件(Binlog)會把 MySQL 中的所有數據修改操作以二進制的形式記錄到日志文件中,包括Create、Drop、Insert、Update、Delete操作等,但二進制日志文件(Binlog)不會記錄Select操作,因為Select操作並不修改數據。
​ 二進制日志文件Binlog格式有以下3種:

  • Statement:基於SQL語句級別的Binlog,每條修改數據的SQL都會保存到Binlog里
  • Row:基於行級別,記錄每一行數據的變化,也就是將每行數據的變化都記錄到Binlog里面,記錄得非常詳細,但是並不記錄原始SQL;在復制的時候,並不會因為存儲過程或觸發器造成主從庫數據不一致的問題,但是記錄的日志量較Statement格式要大得多。
  • Mixed:混合Statement和Row模式,默認情況下采用Statement模式記錄,某些情況下會切換到Row模式,例如SQL中包含與時間、用戶相關的函數等。

中繼日志(Relay Log)

​ 中繼日志文件Relay Log的文件格式、內容和二進制日志文件Binlog一樣,唯一的區別在於從庫上的SQL線程在執行完當前中繼日志文件Relay Log中的事件之后,SQL線程會自動刪除當前中繼日志文件Relay Log,避免從庫上的中繼日志文件Relay Log占用過多的磁盤空間。

4.搭建步驟

關閉主從機器的防火牆

# systemctl stop iptables(需要安裝iptables服務)
# systemctl stop firewalld(默認)
# systemctl disable firewalld.service(設置開啟不啟動)

主服務器配置

第一步:修改my.cnf文件

​ 修改主數據庫服務器的配置文件my.cnf,開啟BINLOG,並設置server-id的值。這兩個參數的修改需要重新啟動數據庫服務才可以生效。

[mysqld]
#啟用二進制日志
log-bin=mysql-bin
#服務器唯一ID,一般取IP最后一段
server-id=136

第二步:重啟MySQL

# systemctl restart mysqld

第三步:授予Slave從機權限

mysql> GRANT REPLICATION SLAVE ON *.* TO 'root'@'192.168.211.138'IDENTIFIED BY '123456';

第四步:刷新權限

FLUSH PRIVILEGES;

第五步:查看master的狀態

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000006 |      120 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

上圖表示,主機將從 mysql-bin.000006這個二進制文件的120行這個位置開始同步。

從服務器配置

第一步:修改my.cnf文件

[mysqld]
server-id=138

確保集群中的各個服務器的server-id唯一。

第二步:重啟並登錄到從庫

先使用如下命令查看從機是否在運行,是的話先停止運行

mysql> show slave status \G;
mysql> stop slave;

第三步:配置從數據庫服務器

​ 指定復制用戶,主數據庫服務器IP、端口以及開始執行復制的日志文件和位置等,具體如下:

mysql> change master to
-> master_host='master_host_name',
-> master_port='master_host_port',
-> master_user='replication_user_name',
-> master_password='replication_password',
-> master_log_file='recorded_log_file_name',
-> master_log_pos=recorded_log_position;

舉例說明如下:

mysql> change master to
    -> master_host='192.168.211.136',
    -> master_port=3306,
    -> master_user='root',
    -> master_password='123456',
    -> master_log_file='mysql-bin.000006',
    -> master_log_pos=120;

第四步:啟動slave線程

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

第五步:檢查從服務器復制功能狀態

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.211.136
                  Master_User: root
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000006
          Read_Master_Log_Pos: 120
               Relay_Log_File: mysqld-relay-bin.000002
                Relay_Log_Pos: 283
        Relay_Master_Log_File: mysql-bin.000006
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
。。。。。。。省略

Slave_IO_Running: Yes 說明從庫IO線程已就緒。
Slave_SQL_Running: Yes 說明從庫SQL線程已就緒。

測試

​ 搭建成功之后,往主機中插入數據,看看從機中是否有數據

注: 如果出現復制不成功,可以使用
mysql> set global sql_slave_skip_counter =1; # 忽略一個錯誤
mysql> start slave

5.存在問題:主從延時

查看主機處理狀態

​ 可以通過SHOW PROCESSLIST命令在主庫上查看Binlog Dump線程,從BinlogDump線程的狀態可以看到,MySQL 的復制是主庫主動推送日志到從庫去的,是屬於“推”日志的方式來做同步

mysql> mysql> show processlist \g;
+----+------+-----------------------+------+-------------+-------+-----------------------------------------------------------------------+------------------+
| Id | User | Host                  | db   | Command     | Time  | State                                                                 | Info             |
+----+------+-----------------------+------+-------------+-------+-----------------------------------------------------------------------+------------------+
|  3 | root | 192.168.211.1:50147   | NULL | Sleep       | 11225 |                                                                       | NULL             |
|  6 | root | 192.168.211.138:52846 | NULL | Binlog Dump |  6174 | Master has sent all binlog to slave; waiting for binlog to be updated | NULL             |
|  7 | root | localhost             | NULL | Query       |     0 | init                                                                  | show processlist |
+----+------+-----------------------+------+-------------+-------+-----------------------------------------------------------------------+------------------+
3 rows in set (0.00 sec)

查看從機處理狀態

​ 在從庫上通過SHOW PROCESSLIST可以看到 I/O線程和SQL線程,I/O線程等待主庫上的Binlog Dump線程發送事件並更新到中繼日志Relay Log,SQL線程讀取中繼日志Relay Log並應用變更到數據庫:

mysql> show processlist \g;
+----+-------------+---------------------+------+---------+------+-----------------------------------------------------------------------------+------------------+
| Id | User        | Host                | db   | Command | Time | State                                                                       | Info             |
+----+-------------+---------------------+------+---------+------+-----------------------------------------------------------------------------+------------------+
|  4 | root        | 192.168.211.1:50207 | NULL | Sleep   |  572 |                                                                             | NULL             |
|  6 | system user |                     | NULL | Connect | 6343 | Waiting for master to send event                                            | NULL             |
|  7 | system user |                     | NULL | Connect | 5859 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL             |
|  9 | root        | localhost           | NULL | Query   |    0 | init                                                                        | show processlist |
+----+-------------+---------------------+------+---------+------+-----------------------------------------------------------------------------+------------------+
4 rows in set (0.00 sec)


免責聲明!

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



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