当前位置: 首页 > 技术与资源 > 技术分享 > 正文

简述MySQL Replication(复制)基本原理

2016-03-10 18:43:05

作者:朱明豪新炬网络高级技术专家。


一、复制概述

 

MySQL复制就是同步一个mysql数据库(master)上的所有改变到另一台mysql数据库(slave),所有数据库的改变记录到binary log。复制经常用来创建主节点的一个可靠副本,用于备份、故障恢复等。

 

MySQL支持三种复制方式:基于SQL语句的复制(statement-based replication,SBR),基于行的复制(row-based replication,RBR),混合模式复制(mixed-based replication,MBR)。以上方式都是通过在主库上记录binary log、在备库重放日志的方式实现异步数据复制。异步复制必然导致在同一时间点备库上的数据可能与主库的不一致,并且无法保证主备之间的延迟。

 

复制会主库带来主要的开销:二进制日志的开销;备库请求从主库读取旧的二进制日志文件的I/O开销;从一个高吞吐量的主库上复制到多个备库,唤醒多个复制线程发送事件的累加开销。

 

二、原理介绍

 

复制是通过slave重放master上的binary log,重新执行,实现的数据同步。

 

主要有三个步骤:

1.master记录数据变更到二进制日志(Binary Log)

2.slave复制主库上的Binary Log到自己的中继日志(relay log)

3.slave重放中继日志的事件,在slave上重新执行。

 

具体实现如下图:

 

MySQL主从复制原理:

 

1.数据变更时,Master将数据变更的事件记录到binary log

2.Master发送信号,唤醒Dump thread,通知其有新的事件产生。

3.Dumpthread将新事务发送给Slave的I/O线程。

4.Slave的I/OThread会将接受到的事件记录到relay log

5.Slave的SQLThread从relay log中读取事件

6.SQLThread在Slave重放读取的事件,从而实现备库数据的更新

 

Mysql复制配置完成后,各线程显示情况:

 

  • Master的binlog dump线程

 

  • Slave的IO thread和SQLthread

 

三、简单搭建

 

根据mysql复制的原理,建立基本的复制需要三个简单步骤:

1.配置一个mysql数据库为Master

2.配置一个mysql数据库为slave

3.将slave连接到Master

 

(一)配置Master

 

1、参数配置

将mysql数据库配置为Master,需要启动binary log和设置唯一的server_id。Binary log保存Master上的所有改变,server_id用于区分mysql数据库。相关参数为log_bin、log_bin_index、server_id,设置这几个参数需要停止mysql数据库。

 

将配置参数添加到my.cnf的[mysqld]

 

2、创建复制账号

Slave启动一个标准的客户端连接到Master,并请求Master将所有的改变的转储给它,Slave连接时要求Master上需要一个有特定复制权限的用户。需要在Master、Slave上都创建。

 

创建复制账号并赋予适当的权限

 

(二)配置Slave

 

1、参数配置

与Master一样需要配置server id和relay log。

将配置参数添加到my.cnf的[mysqld]

 

2、初始化slave

为了保持与master的一致,slave必须是master同步数据某个时间点的一致性快照。因此需要三部分数据:

  • 在某个时间点Master同步数据的一致性快照。

  • 快照时间点master的当前binary log文件和改时间点在binary log中的偏移量。

  • 从快照时间到当前的binary log。

 

获得master同步时间某个时间点的一致性快照的有如下方法:

 

  • 冷备份

关闭master,把数据文件复制到备库。重启主库后,会使用新的binary log文件,通过show master status获得当前binary log文件和起始点。

 

  • Mysqldump

针对innodb表,通过选项--single-transaction,可以获得事务开始前的一致性数据。如果非事务性表,可以使用选项--lock-all-tables获得所有表的一致性快照。

 

  • 存储快照或备份

只要知道快照或备份对应的binary log的坐标,就可以把快照或备份恢复到备库,然后使用CHANGEMASTER TO指定binary log的坐标。

 

  • Percona xtrabackup

Xtrabackup是percona公司开发的一款开源的热备份工具,能够在备份时不堵塞mysql数据库的操作。

 

(三)连接master和slave

 

现在需要指定slave从master的binarylog那个点开始复制。因此需要知道master的4部分信息:

  • 主机名

  • 端口号

  • Master上的replicationslave权限的用户账号

  • 用户密码

  • 起始Binlog日志文件

  • 起始复制点

     

 

下面是开始复制的基本命令:


 

这样就完成了复制的简单配置。

我们可以通过线程列表查看到具体的复制线程。在Master上可以看到由slave IO线程向master发起的连接。

 

 

在备库上也可以看到两个线程,一个是IO线程,一个是SQL线程。并且IO线程和SQL线程总是运行在“system user”账号下。

 

 

上述的输出来自一台已经运行了一段时间的mysql数据库,所以IO线程在master和slave上的Time列的值较大。SQL线程在slave上已经空闲了1126658秒,这意味着1126658秒内没有重放任务事件。

 

 

四、复制扩展

 

(一)级联复制

Log_slave_updates参数可以让备库变成其他mysql数据库的主库。启用该参数后,MySQL会将其执行过的事件记录到自己的binary log中;这样它的备库就可以从其日志中获取变更事件并执行。下图演示了执行过程。

 

 

(二)过滤复制

复制过滤有两种方式:主库上过滤记录到binary log中的时间,备库上重放执行时过滤中继日志的事件。下图展示这两种类型:

 

 

 

binlog-do-db和binlog-ignore-db参数,在主库上生效,直接控制binary log的记录内容。可从如下实验得到证明。

 

 

Master操作

Binlog日志记录内容,未发现sakila库的相关事件。

 

--replicate-*选项,在从master获取变更事件记录到relay log时不进行过滤,relay log仍然保存master 所有的变更事件;而是在SQL thread重放时进行过滤。可从如下实验得到证明。

 

  • Master操作

在sakila库下进行操作。

 

 

  • Slave 操作

     

查看relay log记录内容


查看执行情况,发现未执行过滤项”sakila.t%”的内容。

 

(三)半同步复制

 

1、半同步复制原理

半同步复制是google提供的一组mysql和innodb的扩展补丁,目前集成到mysql5.5以后的版本中。它能够保证主库和至少一台从库之间的数据一致性。

 

它的原理是:

在主库事务提交存储引擎后返回客户端前,至少有一台从库,确认更新已经写入其Relay Log  (不是应用到slave)。

出现超时,主库会暂时还原为常规的异步复制模式继续复制,直到一台设置为半同步复制模式的从库及时收到信息后,再切回半同步模式。

 

下图为半同步复制的事物提交过程:

 

 

2、配置半同步复制

半同步复制要求master和slave都支持。启动半同步复制的步骤如下:

 


 

 

五、管理维护

 

(一)常用参数

 


 

(二)常用命令

 

  • 主库:

1、SHOWBINLOG EVENTS;   所有的变更事件

显示binary log的的变更事件,缺省为第一个binlog文件

语法:

SHOWBINLOG EVENTS [IN 'log_name'][FROM pos][LIMIT [offset,] row_count]

 

2、showmaster status;  

当前binlog文件名称,及下个event的Position  。

 

3、showslave hosts;

显示当前注册到master的slave列表

 

4、resetmaster;

删除binary log index 中所有binary log

清空binary log index file

创建一个新的binary log file( .000001)

所有注册到master的slave将失效

 

5、showmaster logs;

等同于SHOW BINARY LOGS,查看主库上binary log的文件列表,经常在PURGE BINARY LOGS之前使用。

 

6、PURGEBINARY LOGS

删除binlog index中,指定文件或时间之前binlog文件

 

PURGEBINARY LOGS TO 'mysql-bin.010';

PURGEBINARY LOGS BEFORE '2008-04-02 22:46:26';

 

  • 从库:

1、changemaster to

设置slave的同步选项

 

常用写法:

 

2、resetslave

删除所有relay log,并生成一个新relay log

重置master.info,relay.info

MASTER_DELAY重置为0

需要stop slave

 

3、resetslave all

情况change master to信息,删除slave在master的注册信息。show slave status \G;为空,主库show slave hosts 删除该slave 信息

 

4、STOPSLAVE

  • 停止slave的复制线程。 

  • STOP SLAVE IO_THREAD/SQL_THREAD

单独停止IO_THREAD/SQL_THREAD线程

 

5、startslave

启动slave的复制线程。 

  • Start SLAVEIO_THREAD/SQL_THREAD

单独启动IO_THREAD/SQL_THREAD线程     

  • start slaveuntil …; 

执行到某个点时停止.

 

6、showslave status

显示当前slave的复制运行状况

 


 

六、参考文档

 

《MySQl 5.7 Reference Manual-Chapter 17 Replication》

《MySQl 5.7 Reference Manual-Chapter 13 SQL Statement Syntax》

《高性能MySQL_第3版》

《高可用MySQL_第2版》

上一篇:DB2 V10.5之BLU:IBM数据库新时代的到来?
下一篇:XTTS,减少数据库迁移时业务停机时间的利器