MySQL基于二进制日志的主从复制

一、什么是MySQL的主从复制?

      MySQL可以将一个数据库设置为主库,另一个数据库设置为该主库的从库,当主库发生了变更,会同步到从库中。MySQL的主从架构,可以是星型的,也可以是线型的。

     星型架构:

     

        线型架构:

    

         

         由于主从复制的延迟问题,星型架构比线型架构更常用。下文中的应用主要是以星型架构为例。

二、MySQL主从复制的方式

       MySQL的复制可以分为基于二进制日志的复制和基于事务(GTID)的复制,基于二进制日志的复制方式,又可以分为基于行(ROW)的二进制日志复制方式,和基于语句(STATEMENT)的二进制日志复制方式。那么这些复制方式有什么区别呢?

      基于语句的二进制日志复制,主库将变更SQL语句以及上下文记录到二进制日志中,这样的话,如果SQL语句中有不确定值的函数,例如uuid(),在从库中执行执行相同的SQL语句可能会导致不同的变更结果。现在来看一下基于语句的二进制日志,临时设置二进制日志格式为statement:set session binlog_format=statement,在库中插入一条数据:insert into novel values(4, '杯雪')。查看产生的二进制日志:mysqlbinlog --no-defaults mysql-bin.000002,日志如下所示:

     

     基于行的二进制日志复制,主库是将每行的变更数据记录到二进制日志中,在从库中直接是对每行数据进行修改,而不用在从库中执行SQL语句,这样会更高效,并且不会导致主从数据不一致的问题。不过,这样会导致二进制日志比较大。下面是基于ROW的二进制日志:

      

    上面的两种二进制日志复制方式,需要指定是哪个二进制日志以及相应的偏移量,来进行增量同步,如果指定错误会造成遗漏或者重复。

    GTID方式,本文暂不讨论,后续会补上。

三、MySQL复制的原理

     

  • 主库发生变更,将变更事件记录到二进制日志中
  • 从库启动一个I/O线程,该线程和主库建立一个连接,并在主库上启动一个二进制转储线程,用于读取主库中的二进制日志事件,从库的I/O线程将接收到的二进制日志事件写到中继日志中。
  • 从库的SQL线程从中继日志中读取事件,并更新从库。

 四、基于行的二进制日志的主从复制方式实例

  • 准备MySQL环境:
  1. 在win10,以管理员的身份启动docker,启动一个centos6.7容器:

            docker run --name cnt-centos-mysql-w -itd  87de1d39ef43 /bin/bash

         2. 在容器中安装并配置mysql,参考https://www.cnblogs.com/lzj0218/p/5724446.html

         3. docker commit cfb8dfa6ddd8  centos-mysql,将安装mysql后的容器保存为一个镜像。

         4. 用上述centos-mysql镜像,启动三个容器实例,作为一主二从:

            Master:docker run --name cnt-centos-mysql-master -itd -p 7000:22 centos-mysql /bin/bash

            Slave1:ocker run --name cnt-centos-mysql-slave1 -itd  -p 7001:22 centos-mysql /bin/bash

            Slave2:docker run --name cnt-centos-mysql-slave2 –itd –p 7002:22 centos-mysql /bin/bash

         5. 在主库创建一个数据库,创建表,插入数据

            在启动mysql服务的时候,如果报“”,可以尝试使用rm -fr /var/lib/mysql/*这个命令来解决,重新初始化数据库。

           

  • 配置主库,vi /etc/my.cnf

          

  • 配置从库

          

  •  将主库的初始数据,初始化到从库中

          备份主数据库:

          

          将备份脚本拷贝到从库中:

          

         初始化从库:

         

  • 在主库上建立复制用户并授权:

          建立对应网段的复制用户:

          

         给repl用户授予复制权限:

         

  • 在从库上配置复制链路:

          

         其中,master_log_file的取值,来自备份的脚本,如下:

         

        启动复制链路,并查看复制链路转态信息:

        

  • 测试

          在主库中插入数据:

          

          查询从库,可以看到刚插入的数据已经从主库同步到从库中了:

          

 

posted @ 2018-07-26 16:26  孤剑者  阅读(1036)  评论(0编辑  收藏  举报