Mysql内建的复制功能是构建基于MySQL的大规模高性能应用的基础,使用所谓水平拓展的架构,可以通过为服务器配置一个或者多个备库的方式来进行数据同步,

复制概述

复制解决的基本问题是让一台服务器的数据与其他服务器保持同步,一台主库的数据可以同步到多台备库中,备库本身也可以被配置为另外一台服务器的主库,主库与备库之间可以有多种不同的组合方式

MySQL支持两种复制方式,基于行的复制和基于语句的复制,两种方式都是通过在主库上记录二进制日志,在备库重放日志的方式来实现异步的数据复制,也就意味者,同一时间点,备库的数据可能与主库存在不一致,并且无法保证主备之间的延迟,一些打的语句可能导致备库产生几秒,甚至几个小时的延迟.

复制通常不会增加主库的开销,主要是启用二进制日志带来的开销.通过复制可以将读操作指向备库来获得更好的读拓展,但对于写操作,除非设计得当,否则不适合通过复制来拓展写操作.当使用一主库多备库的架构时,可能会造成一些浪费,因为本质上会复制大量不必要的数据.

通过复制可以将读操作指向备库来获得更好的读拓展,但是对于写操作,除非设计得当,否则并不适合通过复制来拓展写操作,在一主多从多备库的架构中,写操作会被执行多次,这时候整个系统的性能取决于写入最慢的那部分。

复制的用途

主要有,

  • 数据分布(在不同的地理位置分布数据备份)
  • 负载均衡(通过复制将多个读操作分布到多个服务器上,实现对读密集型应用的优化)
  • 备份
  • 高可用性和故障切换,(复制能够帮助应用程序避免MYSQL单点失败。一个包含复制的设计良好的故障切换系统能够显著地缩短宕机时间,)
  • MySQL升级测试
复制如何工作

三步,第一步,在主库上把数据更改记录到二进制日志中,第二步备库将主库上的日志复制到自己的中继日志中,第三步,备库读取中继日志中的事件,将其重放到备库数据中.

第一步是在主库上记录二进制日志,在每次准备提交事务完成数据更新前,主库将数据更新的事件记录到二进制日志中。MYSQL 会按事务提交的顺序而非每条语句的执行顺序来记录二进制日志,在记录二进制日志后,主库会告诉存储引擎可以提交事务了。

下一步,备库将主库的二进制日志复制到其本地的中继日志中,首先,备库会启动一个工作线程,称为IO线程,IO线程会跟主库建立一个普通的客户端连接,然后在主库上启动一个特殊的二进制转储线程,这个二进制转储线程会读取主库上二进制日志中的事件,它不会对事件进行轮询。如果该线程追赶上了主库,它将进入睡眠状态,直到主库发送信号量通知其有新的事件产生时才会被唤醒,备库IO线程会将接收到的事件记录到中继日志中。

备库的SQL 线程执行最后一步,该线程从中继日志中读取事件并在备库执行,从而实现备库数据的更新。当SQL线程追赶上IO线程时,中继日志通常已经在系统缓存中,所以中继日志的开销很低。

配置复制

三步,在每台服务器上创建复制账号,配置主库和备库,通知备库连接到主库并从主库辅助数据.

复制的原理

MySQL5.0之前的版本只支持基于语句的复制,在基于语句的复制模式下,主库会记录那些造成数据更改的查询,当备库读取并重放这些事件时,实际上只是把主库上执行过的SQL重新执行了一遍,好处是实现相当简单,另一个好处是二进制日志里的事件更加紧凑。

MySQL5.1开始支持基于行的复制,这种方式会将实际数据记录在二进制日志中,最大的好处就是可以正确的复制每一行.

MySQL可以在两种模式下动态切换,默认情况下,使用的是基于语句的复制方式,但是如果发现有语句无法被正确的复制,就会切换到基于行的复制模式.

发送复制事件到其他备库

log_slave_updates 选项可以让备库变成其他服务器的主库,在设置该选项后,MYSQL 会将其执行过的事件记录到它自己的二进制日志中。这样,它的备库就可以从其日志中检索并执行事件。

复制拓扑

可以在任意个主库和备库之间建立复制,只有一个限制,每一个备库只能有一个主库.

下面是一些基本原则:

一个MYSQL 备库实例只能有一个主库。

每个备库必须有一个唯一的服务器ID

一个主库可以由多个备库

一主库多个备库

备库之间没有交互,它们仅仅是连接到同一个主库上,在有少量写和大量读时,这种配置非常有用,可以把读分摊到多个备库上,直到备库给主库造成了太大的负担.

用途:

  • 为不同的角色使用不同的备库,(例如添加不同的索引或使用不同的存储引擎)
  • 把一台备库当待用的主库,除了复制没有其他数据传输
  • 将一台备库放到远程数据中心,用作灾难恢复
  • 延迟一个或者多个备库,以备灾难恢复
  • 实用其中一个备库,作为备份,培训,开发或者测试使用服务器
主动-主动模式下的主-主复制

两台服务器,每一个都被配置成对方的主库和备库,换句话说,他们是一对主库. 通常用于特殊的目的,,一种可能的应用场景是两个出于不同地理位置的办公室,并且都需要一份可写的数据拷贝.这种情况下导致的问题会非常多,两个服务器都可以写

主动-被动模式下的主-主复制

构建容错性和高可用性系统的强大方式,和上面的主要区别在于其中的一台服务器是只读的被动服务器.

这种方式使得反复切换主动和被动服务器非常方便,因为服务器的配置是对称的,这使得故障恢复和故障转移很容易,可以在不关闭服务器的情况下执行维护,优化表,升级操作系统或其他任务.

拥有备库的主-主结构

为每一个主库增加一个备库

优点是增加了冗余,对于不同地理位置的复制拓扑,能够消除站点单点失效的问题,

环形复制(尽量避免)
主库,分发主库和备库

备库足够多时,会给主库造成很大的负载,每个备库会在主库上创建一个线程,并执行binlog dump命令, 该命令会读取二进制日志文件中的数据并将其发送给备库,每个备库都会重复这样的工作,他们不会共享binlog dump的资源

因此,如果需要多个备库,一个好的方法是从主库移除负载并使用分发主库,分发主库事实上也是一个备库,它的唯一目的是提取和提供主库的二进制文件,多个备库连接到分发主库,使原来的主库拜托了负担,为了避免在分发主库上做实际的查询,可以将它的表修改为blackhole引擎

树型或金字塔型

如果正在将主库复制到大量的备库中,不管是把数据分发到不同的地方,还是提供更高的读性能,使用金字塔结构都能够更好的管理.这种设计减轻了主库的负担.

复制与容量规划

写操作通常是复制的瓶颈,并且很难使用复制来拓展写操作,当计划为系统增加复制容量时,需要确保进行了正确的计算,否则很容易犯一些复制相关的错误。

糟糕的服务容量比例的根本原因是不能像分发读操作那样把写操作等同地分发到更多服务器上,也就是说,复制只能拓展读操作,无法拓展写操作。对数据进行分区是唯一可以拓展写入的方法。

高性能MySQL