1. 介绍

当前用的比较多的mysql高可用架构一般是HA或MMM,Master-Slaver之间通过binlog实现主从数据一致性,有必要理解一下主从复制的基本原理。首先从理解数据的日志类型入手,数据库提供了以下几种日志: 错误日志、binlog日志(二进制日志)、查询日志、慢查询日志。

  • 错误日志
    记录mysql启动和停止,以及服务器运行过程中发生任何严重性错误的相关信息。
  • 二进制日志(binlog)
    早前版本mysql采用文本形式保存记录DDL和DML类日志(不包括查询语句),后来为了确保效率直接采用二进制的形式保存,binlog默认关闭,开启损失约1%性能。
    语句以事件的形式保存,用于数据恢复和数据复制,可以通过mysqlbinlog工具查看日志。

    1. 数据恢复
      场景:比如,我们每天午夜12:00进行数据的备份。如果某天,下午13:00,数据库出现故障,导致数据库内容丢失。我们可以通过二进制日志解决这个问题。
      解决思路:先将前一天午夜12:00的数据备份文件恢复到数据库,然后再使用二进制日志回复从前一天午夜12:00到当天13:00对数据库的操作。
    2. 数据复制(主从复制)
      主从之间通过二进制日志实现数据的传递,从库通过执行二进制日志保证主从服务器间的数据一致性。
  • 查询日志
    用于记录所有sql语句,默认关闭,对系统性能影响较大。

  • 慢查询日志
    记录执行时间超过参数long_query_time(单位:秒),的SQL语句日志。
  • 中继日志:
    也是二进制文件,但是用来给slave库同步数据的。

2. 复制过程

步骤:

步骤一:master记录二进制日志,在每个事务更新数据完成之前,master在二进制日志中记录这些改变,MySQL将事务串行写入二进制日志,在事件写入二进制日志完成后,会通知存储引擎提交事务。
步骤二:slave将master的二进制日志拷贝过来放到自己的中继日志中,首先,slave开始一个工作线程—I/O线程。I/O线程在master上打开一个普通的连接,开始接受二进制日志。I/O线程会将这些事件写入到中继日志中,如果已经跟上了master 的更新速度则睡眠等待产生新的事件。
步骤三:SQL从线程会处理最后一步,SQL线程会从中继日志中读取事件,并更新自己的数据。中继日志一般来说会保存到OS的缓存中,所以中继日志很小。
此外,在master中会有一个工作线程,复制过程中有一个限制—复制在slave上串行化,也就是master上并行更新操作不在slave上并行操作。所以导致slave上的同步数据很慢,慢于master服务器。

复制类型

  1. 基于语句的复制:在服务器上执行SQL语句,在从服务器上执行同样的语句,MySQL默认采用的基于语句的复制,效率高
  2. 基于行的复制:把改变的内容复制过去,而不是命令在从服务器上执行一遍,从MySQl5开始支持
  3. 混合类型的复制:默认采用的基于语句的复制,一旦发现基于语句无法精准的复制时,就会采用基于行的复制。

    复制方法

  4. 同步复制:主服务器要等所有的从服务器都保存完(同步完)再运行,也就是主服务器要等从服务器。
  5. 异步复制:主只执行自己的,从服务器的同步不理会
  6. 半同步复制:主服务器只等一个从服务器复制完(或者等大部分slaver复制完),就认为同步结束,而不等其他的服务器。