16.2.1.1 基于语句的复制和基于行的复制的优缺点
每种二进制日志记录格式都有优点和缺点。对于大多数用户,混合复制格式应提供数据完整性和性能的最佳组合。但是,如果要在执行某些任务时利用特定于基于语句的复制格式或基于行的复制格式的功能,则可以使用本节中的信息,该信息概述了它们的相对优缺点,确定最适合您的需求。
基于语句的复制的优点
-
Proven technology.
-
写入日志文件的数据更少。当更新或删除影响许多行时,这将导致日志文件所需的存储空间减少*少得多。这也意味着从备份中获取和还原可以更快地完成。
-
日志文件包含所有进行了任何更改的语句,因此它们可用于审核数据库。
基于语句的复制的缺点
-
对于 SBR 不安全的语句. 并非所有修改数据的语句(例如INSERT DELETE,UPDATE和REPLACE语句)都可以使用基于语句的复制来复制。使用基于语句的复制时,很难复制任何不确定性行为。此类数据修改语言(DML)语句的示例包括以下内容:
-
依赖于不确定性的 UDF 或存储程序的语句,因为这样的 UDF 或存储程序返回的值或取决于提供给它的参数以外的因素。 (但是,基于行的复制只是复制 UDF 或存储的程序返回的值,因此其对 table 行和数据的影响在源和副本上都是相同的.)有关详细信息,请参见第 16.4.1.16 节,“调用功能的复制”。
-
使用
LIMIT
子句而不使用ORDER BY
的DELETE和UPDATE语句是不确定的。参见第 16.4.1.17 节,“复制和限制”。 -
确定性 UDF 必须应用于副本。
-
使用以下基于语句的复制无法正确复制使用以下任何功能的语句:
-
但是,所有其他功能都可以使用基于语句的复制正确地复制,包括NOW()等。
有关更多信息,请参见第 16.4.1.15 节,“复制和系统功能”。
使用基于语句的复制无法正确复制的语句会记录一条警告,如下所示:
[Warning] Statement is not safe to log in statement format.
在这种情况下,也会向 Client 发出类似的警告。Client 端可以使用SHOW WARNINGS显示它。
-
插入...选择比基于行的复制需要更多的行级锁。
-
与基于行的复制相比,需要进行 table 扫描的UPDATE语句(因为
WHERE
子句中未使用索引)必须锁定更多的行。 -
对于复杂的语句,在更新或插入行之前,必须在副本上评估并执行该语句。对于基于行的复制,副本仅需修改受影响的行,而无需执行完整语句。
-
如果对副本的评估存在错误,尤其是在执行复杂的语句时,基于语句的复制可能会随着时间的流逝缓慢地增加受影响行上的错误余量。参见第 16.4.1.27 节“复制过程中的复制错误”。
-
存储的函数以与调用语句相同的NOW()值执行。但是,存储过程不是这样。
-
确定性 UDF 必须应用于副本。
-
table 定义在源和副本上必须(几乎)相同。有关更多信息,请参见第 16.4.1.10 节,“在源和副本上使用不同的 table 定义进行复制”。
基于行的复制的优点
- 可以复制所有更改。这是最安全的复制形式。
Note
更新mysql
系统数据库中信息的语句(例如GRANT,REVOKE以及触发器,存储例程(包括存储过程)和视图的操纵)都使用基于语句的复制复制到副本。
对于诸如创建 table...选择的语句,将从 table 定义中生成CREATE
语句,并使用基于语句的格式复制,而使用基于行的格式复制行插入。
-
对于以下类型的语句,源上需要较少的行锁,从而实现更高的并发性:
基于行的复制的缺点
-
RBR 可以生成更多必须记录的数据。要复制 DML 语句(例如UPDATE或DELETE语句),基于语句的复制仅将语句写入二进制日志。相比之下,基于行的复制会将每个更改的行写入二进制日志。如果该语句更改许多行,则基于行的复制可能会向二进制日志中写入大量数据;即使对于回滚的语句也是如此。这也意味着制作和还原备份可能需要更多时间。此外,二进制日志被锁定更长的时间以写入数据,这可能会导致并发问题。使用binlog_row_image=minimal可以大大减少不利之处。
-
生成大BLOB值的确定性 UDF 与基于语句的复制相比,使用基于行的复制所花费的时间更长。这是因为记录了BLOB列的值,而不是记录生成数据的语句。
-
您无法在副本上看到从源接收并执行了哪些语句。但是,您可以看到使用mysqlbinlog和--base64-output=DECODE-ROWS和--verbose选项更改了哪些数据。
或者,使用binlog_rows_query_log_events变量,如果启用了-vv
选项,则启用该变量会向_输出添加带有该语句的Rows_query
事件。