深入了解复制-三种复制形式

1、基于语句的复制(statement-Based Replication)

MySQL5.0及之前的版本仅支持基于语句的复制(也叫做逻辑复制,logical replication)。master记录下改变数据的查询,然后,slave从中继日志中读取事件,并执行它,这些SQL语句与master执行的语句一样。这种方式的优点就是实现简单。此外,基于语句的复制的二进制日志可以很好的进行压缩,而且日志的数据量也较小,占用带宽少——例如,一个更新GB的数据的查询仅需要几十个字节的二进制日志。而mysqlbinlog对于基于语句的日志处理十分方便。

但是,基于语句的复制并不是像它看起来那么简单,因为一些查询语句依赖于master的特定条件,例如,master与slave可能有不同的时间。所以,MySQL的二进制日志的格式不仅仅是查询语句,还包括一些元数据信息,例如,当前的时间戳。即使如此,还是有一些语句,比如,CURRENT USER函数,不能正确的进行复制。此外,存储过程和触发器也是一个问题。

另外一个问题就是基于语句的复制必须是串行化的。这要求大量特殊的代码,配置,例如InnoDB的next-key锁等。并不是所有的存储引擎都支持基于语句的复制。

如果语句含有任何不确定的函数调用,则可能会导致Master与Slave之间产生不一致的情况。这些函数有:

LOAD_FILE(filename):读取文件,以字符串的形式返回值。

UUID():生成唯一值的函数,128位。

UUID_SHORT():同UUID(),64位。

USER():以utf8字符集返回当前连接MySQL的用户名及主机名。

FOUND_ROWS():返回一个包含limit字句获得的查询总数。

SYSDATE():返回动态执行的时间。

GET_LOCK(str,timeout) :获得一个以字符串命名的锁,且有超时时间。

IS_USED_LOCK(str):检测str命名的锁是否在使用中。

IS_FREE_LOCK(str):检测str命名的锁是否没在使用。

MASTER_POS_WAIT():控制master/slave的同步。

RAND():实现随机数的方法。

RELEASE_LOCK():用来释放因GET_LOCK()获取锁的str。

SLEEP():实现延迟动作的时间的方法。

VERSION():返回MySQL版本信息的函数。

2、基于行的复制(Row-Based Replication)

MySQL增加基于行的复制,在二进制日志中记录下实际数据的改变。这种方式有优点,也有缺点。优点就是可以对任何语句都能正确工作,一些语句的效率更高。主要的缺点就是二进制日志可能会很大,而且不直观,所以,你不能使用mysqlbinlog来查看二进制日志。

对于一些语句,基于记录的复制能够更有效的工作,如:

mysql> INSERT INTO summary_table(col1, col2, sum_col3)

-> SELECTcol1, col2, sum(col3)

-> FROMenormous_table

-> GROUP BYcol1, col2;

假设,只有三种唯一的col1和col2的组合,但是,该查询会扫描原表的许多行,却仅返回三条记录。此时,基于记录的复制效率更高。

另一方面,下面的语句,基于语句的复制更有效:

mysql> UPDATEenormous_table SET col1 = 0;

此时使用基于记录的复制代价会非常高。由于两种方式不能对所有情况都能很好的处理,所以,MySQL 5.1支持在基于语句的复制和基于记录的复制之前动态交换。你可以通过设置session变量binlog_format来进行控制。

3、混合复制

MySQL5.1及其以后的版本推荐使用混合模式的复制,它是根据事件的类型实时的改变binlog的格式。当设置为混合模式时,默认为基于语句的格式,但在特定的情况下它会自动转变为基于行的模式。

当出现如下情况时,混合模式需要切换到基于行的复制:

该语句调用了:

UUID函数;

用户自定义函数(UDFs);

CURRENT_USER或USER函数;

LOAD_FILE函数。

.同一个语句更改了两张或更多包含AUTO_INCREMENT列的表。

.语句中使用了服务器变量。

.存储引擎不允许使用基于语句复制,如:MySQL Cluster引擎。

    原文作者:温东
    原文地址: https://www.jianshu.com/p/047185a672f6
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞