2017年5月1日星期一

MySQL 系列连载之主从复制原理


Linuxeden 开源社区 --
导读 MySQL 数据库支持同步复制、单向、异步复制,在复制的过程中一个服务器充当主服务,而一个或多个服务器充当从服务器。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。

Mysql 复制 (Replication)

1、Mysql 复制作用
  • 负载平衡 (load balancing)
  • 备份
  • 高可用性 (high availability) 和容错
2、Mysql 复制原理

主要有三步(如下图):

master 将改变记录到二进制日志 (binary log) 中(这些记录叫做二进制日志事件,binary log events);

slave 将 master 的 binary log events 拷贝到它的中继日志 (relay log);

slave 重做中继日志中的事件,将改变它自己的数据。

具体说明:

该过程的第一部分就是 master 记录二进制日志。在每个事务更新数据完成之前,master 在二进制日志记录这些改变。MySQL 将事务串行的写入二进制日志,即使事务中的语句都是交叉执行的。在事件写入二进制日志完成后,master 通知存储引擎提交事务。

下一步就是 slave 将 master 的 binary log 拷贝到它自己的中继日志。 首先,slave 开始一个工作线程——I/O 线程。I/O 线程在 master 上打开一个普通的连接,然后开始 binlog dump process。 Binlog dump process 从 master 的二进制日志中读取事件,如果已经跟上 master,它会休眠并等待 master 产生新的事件。I/O 线程将这些事件写入中继日志。

SQL slave thread 处理该过程的最后一步。SQL 线程从中继日志读取事件,更新 slave 的数据,使其与 master 中的数据一致。只要该线程与 I/O 线程保持一致,中继日志通常会位于 OS 的缓存中,所以中继日志的开销很小。

此外,在 master 中也有一个工作线程:和其它 MySQL 的连接一样,slave 在 master 中打开一个连接也会使得 master 开始一个线程。复制过程有一个很重要的限制——复制在 slave 上是串行化的,也就是说 master 上的并行更新操作不能在 slave 上并行操作。所以 slave 上数据一般要慢于 master 上数据。即 master 与 slave 之间的数据在一定时间内会不同步。

Mysql 复制 (Replication) 类型

1、一主多从模式

注,由一个 master 和一个 slave 组成复制系统是最简单的情况。Slave 之间并不相互通信,只能与 master 进行通信。

具体说明:

如果写操作较少,而读操作很多时,可以采取这种架构。你可以将读操作分布到其它的 slave,从而减小 master 的压力。

但是,当 slave 增加到一定数量时,slave 对 master 的负载以及网络带宽都会成为一个严重的问题。

这种架构虽然简单,但是,它却非常灵活,足够满足大多数应用需求。

一些建议:

不同的 slave 扮演不同的作用 (例如使用不同的索引,或者不同的存储引擎)

用一个 slave 作为备用 master,只进行复制

用一个远程的 slave,用于灾难恢复

发送复制事件到其它 slave,当设置 log_slave_updates 时,你可以让 slave 扮演其它 slave 的 master。

此时,slave 把 SQL 线程执行的事件写进自己的二进制日志 (binary log),然后,它的 slave 可以获取这些事件并执行它
MySQL 级联复制 (A->B->C)log_slave_updates

MySQL 主从结构实际中是用到最多的一种架构。

新上的两台服务器 B 和 C,要替换掉之前旧的服务器 A,同时,B 和 C 是新的主从关系。因此,配置成级联复制,来迁移数据,也方便切换。

架构图如下:

master A ——> slave B ——> slave C

有这么情况发生了,服务器 B 可以正常复制服务器 A 的数据,服务器 B 和 C 主从状态 Slave_IO_Running 和 Slave_SQL_Running 都是 yes 的,但是服务器 C 却无法复制新的数据。

原因分析:

1. 检查服务器B有没有开启二进制日志 log_bin

2. log_slave_updates 是否启用

log_slave_updates 是将从服务器从主服务器收到的更新记入到从服务器自己的二进制日志文件中。

上面的问题是由于没有启用 log_slave_updates = 1导致的。

总结:

因此,对于 mysql 级联复制,上游的从服务器不仅仅要开启 log_bin 还要开启 log_slave_updates,否则将导致下游的从服务器无法更新复制。

2、双主模式

注,Master-Master 复制的两台服务器,既是 master,又是另一台服务器的 slave。

具体说明:

主的 Master-Master 复制有一些特殊的用处。例如,地理上分布的两个部分都需要自己的可写的数据副本。

这种结构最大的问题就是更新冲突。假设一个表只有一行 (一列) 的数据,其值为 1,如果两个服务器分别同时执行如下语句:

在第一个服务器上执行:

mysql> UPDATE tbl SET col=col + 1;

在第二个服务器上执行:

mysql> UPDATE tbl SET col=col * 2;

那么结果是多少呢?一台服务器是 4,另一个服务器是 3,但是,这并不会产生错误。

实际上,MySQL 并不支持其它一些 DBMS 支持的多主服务器复制 (Multimaster Replication),

这是 MySQL 的复制功能很大的一个限制 (多主服务器的难点在于解决更新冲突),但是,如果你实在有这种需求,

你可以采用 MySQL Cluster,以及将 Cluster 和 Replication 结合起来,可以建立强大的高性能的数据库平台。

但是,可以通过其它一些方式来模拟这种多主服务器的复制。

3、主从模式

注,这是 master-master 结构变化而来的,它避免了 M-M 的缺点,实际上,这是一种具有容错和高可用性的系统。

4、带从服务器的 Master-Master 结构 (Master-Master with Slaves)

注,这种结构的优点就是提供了冗余。在地理上分布的复制结构,它不存在单一节点故障问题,而且还可以将读密集型的请求放到 slave 上。

总结:一般常用的两种复制类型一种是主从模式,另一种是一主多从模式。在这我们主要讲解主从模式复制。

原文地址: http://ift.tt/2py761e 编辑员:杨鹏飞,审核员:逄增宝

The post MySQL 系列连载之主从复制原理 appeared first on Linuxeden开源社区.

http://ift.tt/2ql7Ol5

没有评论:

发表评论