MYSQL主从复制(2)

MYSQL主从复制(2)

三、使用GTID复制时的建议(失效切换和横向扩展)

(see Section 16.1.3.3, “Using GTIDs for Failover and Scaleout”)

使用MYSQL的GTID技术进行复制时有很多技术可以增加一个新的从服务器用于横向扩展,增加了主服务器容错几率。本节讨论以下几种技术:

  • 简单复制
  • 复制数据和事务到备用服务器
  • 注入空事务
  • 使用gtid_purged排除事务
  • 恢复GTID模式的备用服务器

GTID用于MYSQL复制的主要目的是数据流的复制和容错切换。每一个ID都唯一的标识出一组binary log 事件,这组事件可以产生事务。GTID在应用改变数据库时使用的关键规则是:服务器可以自动的跳过已经在某台服务器上应用(recognize)过的ID。这个行为对于自动复制位置和正确的失效切换至关重要

标示符和事件(events)组的映射由binary log中的事务组成。当执行复制时这会引起一些挑战(challenge)。在新服务器上重现在旧服务器上产生的标识符集,必须从旧的服务器上复制标识符拷贝到新的服务器上并保存标识符和实际事件之前的关联。对于一个用于灾备服务器,让恢复的数据立即可用是非常有必要的。

简单复制。在新服务器上重现标示符和事务最简单的办法是开启使用GTID的主从复制。

一旦复制开始,新服务器从主服务器复制全部的binary log,并获得所有的GTID信息。

这个方法简单有效,但是需要备用服务器从主服务器读取binary log。它可能需要很长的时间才能从主服务器把信息读完,所以这个方法不适用于快速的容灾恢复或恢复备份。这节解释如何避免从主服务器获得所有的执行历史(execution history)。

复制数据和事务到备用服务器。当主服务器执行了大量的事务后,备用服务器执行全部的事务历史会耗时很久。当添加一个新的备用服务器时,这将会是一个主要的瓶颈。为了消除这个问题,源服务器的数据集快照、binary log和全局事件信息要能导入到新服务器中。源服务器可以是主服务器也可以是备服务器,在COPY数据之前必须确定源服务器已经处理完所有请求的事务。

这个方法有几处不同,主要是传输到备用服务器的数据和事务,大纲如下:

 

数据集 历史事务
  • 使用mysql client导入mysqldump创建的文件。在源服务器上使用–master-data选项,用于包含binary logging信息;并且使用–set-gtid-purged设置为auto(默认)或ON,在dump中包含被执行事务的信息。
  • 停止源服务器,复制源的数据目录相关内容到新备机的数据目录,然后重新启动备用服务器。备用服务器必须开启基于GTID的复制,也就是说gtid_mode=ON。
  • 使用mysqlbinlog从源服务器向新的备用服务器导入binary log 时,使用–read-from-remote-server和–read-from-remote-master选项。
  • 复制源的binary log文件到备机。可以在备机上使用mysqlbinlog –read-from-remote-server –raw。这能以两种方式读到备机中:
    (1)更新备机的binlog.index文件至已经复制的日志文件位置。然后在mysql client中执行change master to 语句到被复制日志的第一条,然后执行start slave读取它们。
    (2)使用mysqlbinlog > file(没有–raw选项)导出binary log文件为能被mysql client处理的SQL文件。

See also Section 4.6.7.3, “Using mysqlbinlog to Back Up Binary Log Files”.

这个方法的优点是新的服务器几乎立即就能使用。只有那些在制作快照时已经提交的事务被备份了,在新备机上重放时还要获取那些在主服务器上刚刚被提交的事务。这意味着新备机不是立刻可以使用——但是只要很短的时候就能把没复制过来的事务都同步完。

复制binary log到目标主机要比直接从主服务器读取全部日志要块很多。由于一些特殊要求和原因这种方法并不是一直都很快。

注入空事务。主服务器的全局 gtid_executed 变量包含了主服务器上所有执行过的事务的集合。当使用快照建立一个新的服务器时相比拷贝binary log,你更应该注意主服务器gtid_executed的内容。在添加新的服务器到(主从)复制链以前,为了主服务器的gtid_executed中包含的事务标示符,在新的服务器上提交一个空的事务,如:

SET GTID_NEXT='aaa-bbb-ccc-ddd:N';

BEGIN;
COMMIT;

SET GTID_NEXT='AUTOMATIC';

一但所有事务标示符已经恢复原状态,你必须flush和purge备机的binary logs,如下所示(N是非零的binary log后缀名):

FLUSH LOGS;
PURGE BINARY LOGS TO 'master-bin.00000N';

这么做是为了防止服务器被大量无效事务涌入。( FLUSH
LOGS
语句用于创建新的binary log文件;PURGE BINARY LOGS 用于消除空事务,但是保留它们的标示符。)

这个方法建立的服务器本质上是个快照,但是在之后可以变成一个主服务器,因为它的binary log历史囊括了复制流。

使用gtid_purged排除事务。主服务器的全局gtid_purged变量包含所有已经从(主服务器的)binary log中消除的事务。就像上面讨论过的(see Injecting empty transactions),你能从它的快照获得服务器上的 gtid_executed值(在新服务器的binary log位置)。与之前的方法不同,这里不需要提交空事务(或执行 PURGE BINARY LOGS);取而代之的是基于源服务器上的gtid_executed 值,直接在备用服务器上设置 gtid_purged

因为这个方法使用了空事务,所以这个方法建立的服务器基本上是一个快照,但是在以后能变成一个主服务器,因为它的binary log历史囊括了主服务器或组。(As with the method using empty transactions, this method creates a server that is functionally a snapshot, but in time is able to become a master as its binary log history converges with that of the replication master or group. )

恢复GTID模式的备用服务器。当恢复一个基于GTID复制的备用服务器时会遇到一个错误,因为事件不包含GTID,所以注入一个空事务也不能解决这个问题。

Use mysqlbinlog to find the next transaction, which is probably the first transaction in the next log file after the event. Copy everything up to the COMMIT for that transaction, being sure to include the SET @@SESSION.GTID_NEXT. Even if you are not using row-based replication, you can still run binary log row events in the command line client.

Stop the slave and run the transaction you copied. The mysqlbinlog output sets the delimiter to /*!*/;, so set it back:

mysql> DELIMITER ;

Restart replication from the correct position automatically:


mysql> SET GTID_NEXT=automatic;
mysql> RESET SLAVE;
mysql> START SLAVE;

四、使用基于GTID的复制时的限制

(see Section 16.1.3.4, “Restrictions on Replication with GTIDs”)

因为基于GTID的复制是依赖事务的,当使用该技术时MYSQL的一些其它功能不被支持。

更新包含了非事务的存储引擎。当使用GTID时更新了非事务的表——如MyISAM,就不能像使用InnoDB一样更新表。

这个限制是由于混合使用了事务表和非事务表导致了多条GTID被分配到同一个事务上。

CREATE TABLE … SELECT 语句CREATE
TABLE ... SELECT
基于语句的复制并不安全。当使用row-based的复制时,这条语句实际上被记录成分开的两个事件——一个是创建表,另一个是从源表中取得数据插入到新表中。当这个语句在事务中被执行时,在某些情况下这两个事件会收到同相的事务标示符,这意味着事务包含的插入会被备机忽略。因此,create table … select不被基于GTID的复制支持。

临时表。当使用GTID (that is, when the server was started with the --enforce-gtid-consistency option)时CREATE TEMPORARY TABLE 和 DROP TEMPORARY TABLE语句在事务内部是不支持的。但是,在事务外部并且autocommit=1时,当GTID开启时也可以被使用。

防止不支持的语句执行。为了防止不被GTID复制支持的语句执行,所有的服务器必须使用 --enforce-gtid-consistency 选项启动服务器。这将导致那些不被GTID支持的语句执行失败,提示一个错误信息。

For information about other required startup options when enabling GTIDs, see Section 16.1.3.2, “Setting Up Replication Using GTIDs”.

当使用GTID时sql_slave_skip_counter 不被支持。如果你需要跳过事务,gtid_executed变量代替; see Injecting empty transactions, for more information.

GTID mode and mysqldump。由mysqldump导出的文件可能不包含GTID信息。

GTID模式和mysql_upgrade。不推荐在使用 --gtid-mode=ON 的MYSQL服务器上使用代--write-binlog 选项的mysql_upgrade 命令,因为mysql_upgrade 会让系统表使用MyISAM引擎,它是非事务的。

更多信息

For information about MySQL Server options and variables relating to GTID-based replication, see Section 16.1.6.5, “Global Transaction ID Options and Variables”. See also Section 12.17, “Functions Used with Global Transaction IDs”, which describes SQL functions supported by MySQL 5.7 for use with GTIDs.

五、部分数据复制

以下参数可以在命令行或配置文件中设置:

(1)主库添加参数的方法:

–binlog-do-db=db-name#复制哪个库

–binlog-ignore-db=db-name#不复制哪个库

(2)从库添加参数的方法:

--replicate-do-db=db-name#复制具体哪个数据库
PS:类似CHANGE REPLICATION FILTER语句,但是CHANGE REPLICATION FILTER不需要重启数据库实例。
--replicate-ignore-db=db-name#不复制具体哪个数据库

--replicate-do-table=db.table#复制具体哪个库中的哪个表

--replicate-ignore-table=db.table#不复制具体
哪个库中的哪个表
replicate_wild_do_table=db%.%#百分号是通配符,复制以db开头的所有库的所有表

replicate_wild_ignore_table=db%.%#同上,不过这个是忽略

六、

发表评论