MySQL主从复制原理

MySQL主从复制原理

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:

涉及线程

主库

bin log dump thread:负责接收 slave 的请求并传送主库的 bin log 给 slave。

该进程可以在主库中通过 show processlist 查看,如下:

mysql> show processlist;
+----+----------+------------------+------+-------------+------+---------------------------------------------------------------+------------------+
| Id | User     | Host             | db   | Command     | Time | State                                                         | Info             |
+----+----------+------------------+------+-------------+------+---------------------------------------------------------------+------------------+
|  3 | repluser | 10.0.1.201:40328 | NULL | Binlog Dump | 3256 | Master has sent all binlog to slave; waiting for more updates | NULL             |
|  8 | root     | localhost        | NULL | Query       |    0 | starting                                                      | show processlist |
+----+----------+------------------+------+-------------+------+---------------------------------------------------------------+------------------+
2 rows in set (0.00 sec)

还可通过 show slave hosts 查看当前有多少个从库连接:

mysql> show slave hosts;
+-----------+------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID                           |
+-----------+------+------+-----------+--------------------------------------+
|         2 |      | 3306 |         1 | ca83bdb3-941e-11ea-9974-000c29496b80 |
+-----------+------+------+-----------+--------------------------------------+
1 row in set (0.01 sec)

从库

IO 线程:负责与主库的 dump thread 通信请求并接收、存储 bin log 日志到 relay log 中。

SQL 线程:负责从 relay log 中读取并在本地回放 relay log。

这两个线程可以通过在从库通过 show slave status 查看,如下:

mysql> show slave status\G;
*************************** 1. row ***************************
		      -- 主库连接信息与 bin log 日志信息
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.0.1.200
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000004
          -- 当前读取到的主库日志位置点,存放在 master.info 中
          Read_Master_Log_Pos: 154
          -- relay log 回放状态信息
               Relay_Log_File: relay-log.000019
          -- 从库回放到的日志位置点,存放在 relay.info 中
                Relay_Log_Pos: 369
        Relay_Master_Log_File: master-bin.000004
          -- 线程监控信息
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
          -- 复制过滤器相关信息
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: t.%
  Replicate_Wild_Ignore_Table: 
          -- 错误信息
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          -- SQL 线程回放到的 relay log 位置点对应到主库 bin log 的位置点
          -- 主库 bin log 最后的位置点 - Exec_Master_Log_Pos = 延时日志量
          -- 位置点是按字节大小计算的,所以延时日志量实际就是和主库的差异字节大小
          Exec_Master_Log_Pos: 154
              Relay_Log_Space: 737
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
          -- SSL 加密信息
           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
          -- IO 线程与 SQL 线程的错误信息
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: cc1a793f-941e-11ea-991d-000c29ec139d
             Master_Info_File: /data/3306/data/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: 
          -- gtid 复制信息
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
          -- 主库使用的 TLS 版本
           Master_TLS_Version: 
1 row in set (0.00 sec)

上述我们常关注的信息已经通过注释标识了~~

涉及文件

主库

bin log 日志文件,可在 my.cnf 中通过 log-bin 设置 bin log 日志文件的位置。

以如下配置为例:

[mysqld]
...
log-bin=master-bin

未指定绝对路径,那么此时将会在数据目录生成 binlog 文件,如下:

$ ls master-bin.*
master-bin.000001  master-bin.000002  master-bin.000003  master-bin.000004  master-bin.index

从库

relay log 日志文件,可在 my.cnf 中通过 relay-log 设置 relay log 日志文件的位置。

以如下配置为例:

[mysqld]
...
relay-log=relay-log

未指定绝对路径,那么此时将会在数据目录生成 relay log 文件,如下:

$ ls relay-log.*
relay-log.000018  relay-log.000019  relay-log.index  relay-log.info

主库信息文件,在主从复制架构中的从节点会将主库的连接信息保存到数据目录的 master.info,其内容结构大致如下:

$ cat master.info 
25
master-bin.000004
154
10.0.1.200
repluser
123
3306
60
0





0
30.000

0
cc1a793f-941e-11ea-991d-000c29ec139d
86400


0

其中保存的有主库 ip、port、user、password、bin log 位置等信息。

中继日志状态信息文件,从节点会将当前与主节点通信的状态信息保存在数据目录的 relay-log.info,其内容结构大致如下:

$ cat relay-log.info 
7
./relay-log.000019
369
master-bin.000004
154
0
0
1

其中可以看到 relay log 的当前位置点对应着主库的哪个点、当前使用的 relay log 文件等信息。

流程概述

  1. 在从库执行 change master to ...;,此时会将 change master to ...; 中指定的主库信息记录到 master.info 文件中,然后通过 start slave 启动 IO 线程和 SQL 线程;
  2. IO 线程读取 master.info 文件的连接信息发起连接请求到达主库所在主机的连接层与 dump 线程建立连接;
  3. IO 线程通过已建立的连接请求主库生成的 bin log 数据;
  4. 主库 dump 线程响应从库的 IO 线程的请求返回对应的 bin log 数据;
  5. IO 线程接收到数据将其保存到 relay log 中,并更新此时的接收状态信息更新到 master.info 中;
  6. SQL 线程读取 relay.info 中当前的回放状态信息,然后从 relay log 中读取并回放最新的日志;
  7. 回放完毕后将最新的回放状态更新到 reley.info 中;

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.zze.xyz/archives/mysql-master-slave-principle.html

Buy me a cup of coffee ☕.