MySQL主从复制原理与实战

MySQL主从复制

适用场景

MySQL主从模式是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,从节点可以复制主数据库 中的所有数据库,或者特定的数据库,或者特定的表。

MySQL主从复制原理与实战_第1张图片

mysql主从复制用途:

  • 实时灾备,用于故障切换(高可用)

  • 读写分离,提供查询服务(读扩展)

  • 数据备份,避免影响业务(高可用)

主从部署必要条件:

  • 从库服务器能连通主库

  • 主库开启binlog日志(设置log-bin参数)

  • 主从server-id不同

原理

主从复制

下图是主从复制的原理图。

MySQL主从复制原理与实战_第2张图片

主从复制整体分为以下三个步骤:

  • 主库将数据库的变更操作记录到Binlog日志文件中

  • 从库读取主库中的Binlog日志文件信息写入到从库的Relay Log中继日志中

  • 从库读取中继日志信息在从库中进行Replay,更新从库数据信息

在上述三个过程中,涉及了Master的BinlogDump Thread和Slave的I/O Thread、SQL Thread,它们的作用如下:

  • Master服务器对数据库更改操作记录在Binlog中,BinlogDump Thread接到写入请求后,读取Binlog信息推送给Slave的I/O Thread。

  • Slave的I/O Thread将读取到的Binlog信息写入到本地Relay Log中。

  • Slave的SQL Thread检测到Relay Log的变更请求,解析relay log中内容在从库上执行。

上述过程都是异步操作,俗称异步复制,存在数据延迟现象

下图是异步复制的时序图。

MySQL主从复制原理与实战_第3张图片

mysql主从复制存在的问题:

  • 主库宕机后,数据可能丢失
  • 从库只有一个SQL Thread,主库写压力大,复制很可能延时

解决方法:

  • 半同步复制 – 解决数据丢失问题
  • 并行复制 – 解决从库复制延迟问题
半同步复制

为了提升数据安全,MySQL让Master在某一个时间点等待Slave节点的 ACK(Acknowledge character)消息,接收到ACK消息后才进行事务提交,这也是半同步复制的基础,MySQL从5.5版本开始引入了半同步复制机制来降低数据丢失的概率。

介绍半同步复制之前先快速过一下 MySQL 事务写入碰到主从复制时的完整过程,主库事务写入分为 4

个步骤:

  • InnoDB Redo File Write (Prepare Write)

  • Binlog File Flush & Sync to Binlog File

  • InnoDB Redo File Commit(Commit Write)

  • Send Binlog to Slave

当Master不需要关注Slave是否接受到Binlog Event时,即为传统的主从复制。

当Master需要在第三步等待Slave返回ACK时,即为 after-commit,半同步复制(MySQL 5.5引入)。当Master需要在第二步等待 Slave 返回 ACK 时,即为 after-sync,增强半同步(MySQL 5.7引入)。

下图是 MySQL 官方对于半同步复制的时序图,主库等待从库写入 relay log 并返回 ACK 后才进行

Engine Commit。

MySQL主从复制原理与实战_第4张图片

实战

环境准备:VM + Ubuntu20.04 + MySQL 5.7.31

MySQL主从复制配置步骤:

  • 主服务器(Master):

    • 开启二进制日志
    • 配置唯一的server-id
    • 获取master二进制日志文件名及位置
    • 创建一个用于slave和master通信的用户账号
  • 从服务器:

    • 配置唯一的server-id
    • 使用master分配的用户账号读取master二进制日志
    • 启用slave服务

主从库:

(Ubuntu 20.04)master : 192.168.157.128
(Ubuntu 20.04)slave : 192.168.157.129

主库(master)相关配置:

  1. 修改mysql配置

    • 找到主数据库的配置文件my.cnf(或my.ini),Ubuntu 20.04 在/etc/mysql/mysql.conf.d下。

      [mysqld]
      # 开启二进制日志
      log-bin=mysql-bin
      # 设置server-id
      server-id=1
      # 设置不需要同步的数据库信息
      binlog-ignore-db=mysql
      binlog-ignore-db=sys
      binlog-ignore-db=information_schema
      binlog-ignore-db=performance_schema
      
    • 重启mysql:/etc/init.d/mysql restart

  2. 创建用于同步的用户账号,并授予相应的权限

    mysql>CREATE USER 'dunk'@'192.168.157.129' IDENTIFIED BY '668566';
    mysql>GRANT REPLICATION SLAVE ON *.* TO 'dunk'@'192.168.157.129';
    mysql>flush privileges;
    
  3. 查看master状态,记录二进制文件名(mysql-bin.000002)

    MySQL主从复制原理与实战_第5张图片

从库(slave)相关配置:

  1. 修改mysql配置

    • mysql配置文件同上,添加server-id

      [mysqld]
      server-id=2
      
    • 重启mysql:/etc/init.d/mysql restart

  2. 建立mysql会话,进入mysql命令行,执行以下命令

    mysql> change master to
        ->   master_host='192.168.157.128',
        ->   master_user='dunk',
        ->   master_password='668566',
        ->   master_log_file='mysql-bin.000002',
        ->   master_log_pos=154;
    
  3. 启动slave同步进程

    mysql> start slave;
    
  4. 查看slave状态

    mysql> show slave status \G;
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.157.128
                      Master_User: dunk
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000002
              Read_Master_Log_Pos: 154
                   Relay_Log_File: dunk-virtual-machine-relay-bin.000002
                    Relay_Log_Pos: 320
            Relay_Master_Log_File: mysql-bin.000002
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
                ......
    

    看到查询的状态结果中的Slave_IO_RunningSlave_SQL_Running的参数值为YES,这就表示主从同步已经设置成功。

测试主从复制效果如下:

MySQL主从复制原理与实战_第6张图片

你可能感兴趣的:(MySQL,mysql)