MySQL复制格式大解析

前言

以下内容基于MySQL5.7官方文档

复制格式

复制之所以有效,是因为从源读取了写入二进制日志的事件,然后在副本上对其进行了处理。根据事件的类型,事件以不同的格式记录在二进制日志中。使用的复制格式对应于将事件记录在源的二进制日志中时使用的二进制日志记录格式。二进制日志记录格式有以下三种:

  1. 使用基于语句的二进制日志记录时,源会将SQL语句写入二进制日志。将源复制到副本可以通过在副本上执行SQL语句来进行。这称为
    基于语句的复制(可以缩写为 SBR),它对应基于MySQL语句的二进制日志记录格式。
  2. 使用基于行的日志记录时,源会将事件写入
    二进制日志,以指示如何更改各个表行。通过将表示对表行所做的更改的事件复制到副本,可以将源复制到副本。这称为基于行的复制(可以缩写为RBR)。
  3. 您还可以配置MySQL以同时使用基于语句的记录和基于行的记录,这取决于哪种记录最适合记录更改。这称为混合格式日志记录。使用混合格式日志记录时,默认情况下使用基于语句的日志。根据某些语句以及所使用的存储引擎,在特定情况下,日志会自动切换为基于行的日志。使用混合格式的复制称为基于混合的复制 或混合格式的复制。

在MySQL 5.7.7之前,基于语句的格式是默认格式。在MySQL 5.7.7和更高版本中,基于行的格式是默认格式。

正在运行的MySQL服务器中的日志记录格式是通过设置 binlog_format系统变量来实现的。可以使用会话或全局范围设置此变量。。设置当前会话的变量仅持续到该会话结束,并且其他会话看不到该更改。全局设置变量对更改后连接的客户端生效,但不适用于任何当前客户端会话,包括更改了变量设置的会话。要使全局系统变量设置永久生效,以便将其应用于服务器重新启动之后,那就必须​​在配置文件中进行设置。

基于语句的复制和基于行的复制的优缺点

每种二进制日志记录格式都有优点和缺点。对于大多数用户,混合复制格式应提供数据完整性和性能的最佳组合。但是,如果您希望在执行某些任务时利用特定于基于语句或基于行的复制格式的功能,则可以使用本节中的信息(该摘要概述了它们的相对优缺点)来实现以下目的:确定最适合您需求的复制格式。

基于语句的复制的优点

1、成熟的技术。

2、写入日志文件的数据更少。当更新或删除影响许多行时,这将导致 日志文件所需的存储空间大大减少。这也意味着可以更快地完成备份的备份和还原。

3、日志文件包含所有进行了任何更改的语句,因此它们可用于审核数据库。

基于语句的复制的缺点

1、使用基于语句的复制时,很难复制任何不确定性的行为。例如:DELETEUPDATE使用不带LIMIT子句的 语句ORDER BY是不确定的。

2、确定性UDF必须应用于副本。

3、使用基于语句的复制无法正确复制使用以下任何功能的语句:

LOAD_FILE()

UUID(), UUID_SHORT()

USER()

FOUND_ROWS()

SYSDATE()(除非源和副本都使用该--sysdate-is-now 选项启动 )

GET_LOCK()

IS_FREE_LOCK()

IS_USED_LOCK()

MASTER_POS_WAIT()

RAND()

RELEASE_LOCK()

SLEEP()

VERSION()

但是,所有其他功能都可以使用基于语句的复制正确地复制,包括 NOW()等等。


使用基于语句的复制无法正确复制的语句会记录一条警告,如下所示:

[Warning] Statement is not safe to log in statement format.

4INSERT ... SELECT的语句复制与基于行的复制相比,需要更多的行级锁。

5UPDATE WHERE的语句复制与基于行的复制相比,要求进行表扫描的语句(因为在子句中未使用索引 )必须锁定更多的行。

6、对于InnoDB:使用AUTO_INCREMENTINSERT语句会 阻塞其他非冲突的INSERT 语句。

7、对于复杂的语句,在更新或插入行之前,必须在副本上评估并执行该语句。对于基于行的复制,副本仅需修改受影响的行,而无需执行完整语句。

8、如果对副本的评估存在错误,尤其是在执行复杂的语句时,基于语句的复制可能会随着时间的流逝缓慢地增加受影响行上的错误余量。请参见 第16.4.1.27节“复制过程中的复制错误”。

9、存储的函数以与NOW()调用语句相同的值执行 。但是,存储过程不是这样。

10、确定性UDF必须应用于副本。

11、表定义在源和副本上必须(几乎)相同。

基于行的复制的优点

1、所有更改都可以复制。这是最安全的复制形式。

2、对于以下类型的语句,源上需要的行锁更少,从而实现更高的并发性:
使用AUTO_INCREMENT的插入语句

UPDATEDELETE语句,其中的WHERE子句不使用键或不更改大多数已检查的行。

UPDATEDELETE带有WHERE不使用键或不更改大部分已检查行的子句的语句 。

3、对于任何INSERTUPDATEDELETE语句,副本上所需的行锁更少。

基于行复制的缺点

1、RBRhh会生成更多记录的数据。为了复制DML语句(例如更新或删除语句),基于语句的复制只将该语句写入二进制日志。相反,基于行的复制将每个更改的行写入二进制日志。如果该语句更改了很多行,基于行的复制可能会向二进制日志写入更多的数据;即使对于回滚的语句也是如此。这也意味着,创建和恢复备份可能需要更多的时间。此外,二进制日志被锁定较长时间以写入数据,这可能会导致并发性问题。使用binlog_row_image=minimal可以大大减少这个缺点。

2、生成大型BLOB值使用基于行的复制比使用基于语句的复制花费更长的时间。这是因为记录的是BLOB列值,而不是生成数据的语句。

3、您无法在副本上看到从源接收和执行了哪些语句。但是,您可以看到使用mysqlbinlog更改了哪些数据。

4、对于使用MyISAM 存储引擎的表,将副本INSERT作为基于行的事件应用于二进制日志时,与将副本作为语句应用于语句相比,在副本上需要对语句进行更强的锁定。这是因为在MyISAM使用基于行的复制时,不支持在表上进行并发插入。

猜你喜欢

转载自blog.csdn.net/qq_36551991/article/details/111566985