复制
复制的原理
复制文件
- 3.master.info
这个文件用于保存备库连接到主库所需要的信息,格式为纯文本(每行一个值),不同的MySQL版本,其记录的信息也可能不同。此文件不能删除,否则备库在重启后无法连接到主库。这个文件以文本的方式记录了复制用户的密码,所以要注意此文件的权限控制 - 4.relay-log.info
这个文件包含了当前备库复制的二进制日志和中继日志坐标(例如,备库复制在主库上的位置),同样也不要删除这个文件,否则在备库重启后将无法获知从哪个位置开始复制,可能会导致重放已经执行过的语句
使用这些文件来记录MySQL复制和日志状态是一种非常粗糙的方式。更不幸得是,它们不是同步写的。如果服务器断电并且文件数据没有被刷新到磁盘,在重启服务器后,文件中记录的数据可能是错误的。正如之前提到的,这些问题在MySQL5.5里做了改进。以.index作为后缀的文件也与设置expire_logs_days存在交互,该参数定义了MySQL清理过期日志的方式,如果文件mysql-bin.index在磁盘上不存在,在某些MySQL版本自动清理就会不起作用,甚至执行PURGE MASTER LOGS语句也没有用。这个问题的解决方法通常是使用MySQL服务器管理二进制日志,这样就不会产生误解(这意味着不应该使用rm来自己清理日志)。最好能显式地执行一些日志清理策略,比如设置expire_logs_days参数或者其他方式,否则MySQL的二进制日志i可能会将磁盘撑满。当做这些事情时,还需要考虑到备份策略。
发送复制事件到其他备库
log_slave_updates选项可以让备库变成其他服务器的主库。在设置该选项后,MySQL会将其执行过的事件记录到它自己的二进制日志中。这样它的备库就可以从其日志中检索并执行事件。如图所示。在这种场景下,主库将数据更新事件写入二进制日志,第一个备库提取并执行这个事件。这时候一个事件的生命周期应该结束了,但由于设置了log_slave_updates,备库会将这个时间写到它自己的二进制日志中。这样第二个备库就可以将事件提取到它的中继日志中并执行。这意味着作为源服务器的主库可以将其数据变化传递给没有与其直接相连的备库上。默认情况下这个选项是被打开的,这样在连接到备库时就不需要重启服务器。
当第一个备库从主库获得鞥多事件写入到其二进制日志中时,这个事件在备库二进制日志中的位置与其在主库二进制日志中的位置几乎肯定是不相同的,可能在不同的日志文件或文件内不同鞥多位置。这意味着你不能嘉定所有拥有统一逻辑复制点的服务器拥有相同的日志坐标。这种情况会使某些任务更加复杂,例如,修改一个备库的主库或将备库提升为主库。
除非你已经注意到要给每个服务器分配一个唯一的唯一的服务器ID,否则按照这种方式配置备库会导致一些奇怪的错误,甚至还会导致复制停止。一个更常见的问题是:为什么要指定服务器ID,难道MySQL在不知道复制命令来源的情况下不能执行吗?为什么MySQL要在意服务器ID是全局唯一的。问题的答案在于MySQL在复制过程中如何防止无限循环。当复制SQL线程读中继日志时,会丢弃事件中记录的服务器ID和该服务器本身ID相同的事件,从而打破了复制过程中的无限循环。在某些复制拓扑结构下打破无限循环非常重要,例如主-主复制结构(语句在无限循环中来回传递也是多服务器环形复制拓扑结构中比较有意思的话题之一)。
如果在设置复制的时候碰到问题,服务器ID应该是需要检查的因素之一。当然只检查@@server_id是不够的,它有一个默认值,除非在my.cnf文件或通过SET命令明确指定它的值,复制才会工作。如果使用SET命令,确保同时也更新了配置文件,否则SET命令的设定可能在服务器重启后丢失。
复制拓扑
可以在任意个主库和备库之间建立复制,只有一个限制:每一个备库只能有一个主库。有很多复杂的拓扑结构,但即使是最简单的也可能会非常灵活。一种头普可以有多种用途。关于使用复制的不同方式可以很轻易地写一本书。前面已经讨论了如何为主库设置一个备库,接下来讨论其他比较普遍地拓扑结构以及它们的优缺点.记住下面的基本原则:
- 1.一个MySQL备库实例只能有一个主库
- 2.每个备库必须有一个唯一的服务器ID
- 3.一个主库可以有多个备库(或者相应的,一个备库可以有多个兄弟备库)
- 4.如果打开了log_slave_updates选项,一个备库可以把其主库上的数据变化传播到其他备库
一主库多备库
除了前面已经提过的两台服务器的主备结构外,这是最简单的拓扑结构。事实上一主多备的结构和基本配置差不多简单,因为备库之间根本没有交互(从技术上讲这并非正确的。但如果有重复的服务器ID,它们将现如竞争,并反复将对方从主库上踢出),它们仅仅是连接到同一个主库上,如图显示了这种结构。
尽管这是非常简单的拓扑结构,但它非常灵活,能满足多种需求。下面是它的一些用途:
- 1.为不同的角色使用不同的备库(例如添加不同的索引或使用不同的存储引擎)
- 2.把一台备库当作待用的主库,除了复制没有其他数据传输
- 3.延迟一个或多个备库,以备灾难恢复
- 4.使用其中一个备库,作为备份、培训、开发或者测试使用服务器
这种结构流行的原因是它避免了很多其他拓扑结构的复杂性。例如:可以方便地比较不同备库重放的事件在主库二进制日志中的位置。换句话说,如果在同一个逻辑点停止所有备库的复制,它们正在读取的是主库上同一个日志文件的相同物理位置。这是个很好的特性,可以减轻管理员许多工作,例如把备库提升为主库。这种特性只存在于兄弟备库之间。在没有直接的主备或兄弟关系的服务器上去比较日志文件的位置要复杂很多。
主动-主动模式下的主-主复制
主-主复制(也叫双主复制或双向复制)包含两台服务器,每一个都被配置成对方的主库和备库,换句话说,它们是一对主库,如图显示了该结构。主动-主动模式下主-主复制有一些应用场景,但通常用于特殊的目的。一个可能的应用场景是两个处于不同地理位置的办公室,并且都需要一份可写的数据拷贝。
这种配置最大的问题是如何解决冲突,两个可写的互主服务器导致的问题非常多。这通常发生在两台服务器同时修改一行记录,或同时在两台服务器上向一个包含AUTO_INCREMENT列的表里插入数据(事实上这些问题经常一周发生三次,并且发现需要好几个月才能解决这些问题)
MySQL5.0增加了一些特性,使得这种配置稍微安全了点,就是设置auto_increment_increment和auto_increment_offset。通过这两个选项可以让MySQL自动为INSERT语句选择不互相冲突的值。然而允许向两台主库上写入仍然很危险。在两台机器上根据不同的顺序更新,可能会导致数据不同步。例如,一个只有一列的表,只有一行值为1的记录假设同时i执行下面两条语句:
- 1.在第一台主库上:
mysql>UPDATE tbl SET col=col +1
- 2.在第二台主库上:
mysql>UPDATE tbl SET col=col *2;
那么结果呢?一台服务器上值为4,另一台值为3,并且没有报告任何复制错误。数据不通过不还仅仅是开始。当正常的复制发生错误停止了,但应用在同时向两台服务器写入数据,这时候会发生什么呢?你不能简单地把数据从一台服务器复制到另外一台,因为这两台机器上需要复制的数据都可能发生了变化。解决这个问题将会非常困难。
如果足够仔细地配置这种架构,例如很好地划分数据和权限,并且你很清楚自己在做什么,可以避免一些问题(一些,但不是全部),然而这通常很难做好,并且有更好的办法来实现你所需要的。
总地来说,允许向两个服务器上写入带来的麻烦远远大于其带来的好处
MySQL不支持多主库复制
多主库复制(multisource replication)特指一个备库有多个主库。不管之前你知道什么,但MySQL(和其他数据库产品不一样)现在不支持如图所示的结构
主动-被动模式下的主-主复制
这是前面描述的主-主结构的变体,它能够避免上面讨论的问题。这也是构建容错性和高可用性系统的非常强大的方式,主要区别在于其中的一台服务器是只读的被动服务器,如图所示。这种方式使得反复切换主动和被动服务器非常方便,因为服务器的配置是对称的。这使得故障转移和故障恢复很容易。它也可以让你在不关闭服务器的情况下执行维护、优化表、升级操作系统(或者应用程序、硬件等)或其他任务。
例如,执行ALTER TABLE操作可能会锁住整个表,阻塞对表的读和写,这可能会花费很长事件并导致服务中断。然而在主-主配置下,可以先停止主动服务器上的备库复制线程(这样就不会在被动服务器上执行任何更新),然后在被动服务器上执行ALTER操作,交换角色,最后在先前的主动服务器上启动复制线程。这个服务器将会读取中继日志并执行相同的ALTER语句。这可能花费很长时间,但不要紧,因为该服务器没有为任何活跃查询提供服务。
主动-被动模式的主-主结构能够帮助会比许多MySQL的问题和限制,此外还有一些工具可以完成这种类型的操作。
让我们看看如何配置主-主服务器对,在两台服务器上执行如下设置后,会使其拥有对称的设置:
- 1.确保两台服务器上有相同的数据
- 2.启用二进制日志,选择唯一的服务器ID,并创建复制账号。
- 3.启用备库更新的日志记录,后面将会看到,这是故障转移和故障恢复的关键
- 4.把被动服务器配置成只读,防止可能与主动服务器上的更新产生冲突,这一点是可选的。
- 5.启动每个服务器的MySQL实例
- 6.将每个主库设置为对方的备库,使用新创建的二进制日志开始工作
让我们看看主动服务器上更新时会发生什么事情。更新被记录到二进制日志中,通过复制传递给被动服务器的中继日志中。被动服务器执行查询并将其记录到自己的二进制日志中(因为开启了log_slave_updates选项)。由于时间的服务器ID与主动服务器的相同,因此主动服务器将忽略这些时间。
设置主动-被动的主-主拓扑结构在某种意义上类似于创建了一个热备份,但是可以使用这个"备份"来提高性能,例如,用它来执行读操作、备份、"离线"维护以及升级等。真正的热备份做不了这些事情,然而,你不会获得比单台服务器更好的写性能。它是一种非常常见的并且重要的拓扑结构