每种二进制日志记录格式都有优点和缺点。对于大多数用户而言,混合复制格式应提供数据完整性和性能的最佳组合。但是,如果要在执行某些任务时利用特定于基于语句的复制格式或基于行的复制格式的功能,则可以使用本节中的信息,该信息概述了它们的相对优缺点。确定最适合您的需求。
基于语句的复制的优点
基于语句的复制的缺点
基于行的复制的优点
基于行的复制的缺点
基于语句的复制的优点
成熟的技术。
写入日志文件的数据更少。当更新或删除影响许多行时,这将导致 日志文件所需的存储空间大大减少。这也意味着从备份中获取和还原可以更快地完成。
日志文件包含所有进行了任何更改的语句,因此它们可用于审核数据库。
基于语句的复制的缺点
对于SBR不安全的语句。 不修改该数据的所有语句(如 , 和 语句)可以使用基于语句的复制被复制。使用基于语句的复制时,很难复制任何不确定性行为。此类DML(数据修改语言)语句的示例包括: INSERT DELETEUPDATEREPLACE
依赖于不确定性的UDF或存储程序的语句,因为这样的UDF或存储程序返回的值或取决于提供给它的参数以外的因素。(但是,基于行的复制只是复制UDF或存储程序返回的值,因此其对表行和数据的影响在主服务器和从服务器上都是相同的。)请参见 第17.4.1.16节“复制调用的功能” ”,以获取更多信息。
DELETE和 UPDATE使用不带LIMIT子句的 语句ORDER BY是不确定的。请参见 第17.4.1.17节“复制和限制”。
使用以下基于语句的复制无法正确复制使用以下任何功能的语句:
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()等等。
有关更多信息,请参见 第17.4.1.15节“复制和系统功能”。
使用基于语句的复制无法正确复制的语句会记录一条警告,如下所示:
[Warning] Statement is not safe to log in statement format.
在这种情况下,也会向客户发出类似的警告。客户端可以使用显示它 SHOW WARNINGS。
INSERT … SELECT 与基于行的复制相比,需要更多的行级锁。
UPDATEWHERE与基于行的复制相比,要求进行表扫描的语句(因为在子句中未使用索引 )必须锁定更多的行。
对于InnoDB:使用的 INSERT语句将 AUTO_INCREMENT阻止其他不冲突的INSERT 语句。
对于复杂的语句,必须在更新或插入行之前在从属上评估并执行该语句。使用基于行的复制时,从属仅需修改受影响的行,而无需执行完整语句。
如果在从属服务器上的评估出现错误,尤其是在执行复杂的语句时,基于语句的复制可能会随着时间的流逝缓慢地增加受影响行上的错误余量。请参见 第17.4.1.27节“复制期间的从属错误”。
存储的函数以与NOW()调用语句相同的值执行 。但是,对于存储过程,情况并非如此。
确定性UDF必须应用于从站。
主服务器和从服务器上的表定义必须(几乎)相同。有关更多信息,请参见 第17.4.1.9节“在主控和从属上使用不同的表定义进行复制”。
基于行的复制的优点
可以复制所有更改。这是最安全的复制形式。
注意
语句更新的信息 mysql数据库,例如 GRANT, REVOKE和触发器的操作,存储程序(包括存储过程),和看法,都使用基于语句复制复制到slave。
对于诸如之类 CREATE TABLE … SELECT的CREATE 语句,将从表定义中生成一条语句,并使用基于语句的格式进行复制,而行插入则使用基于行的格式进行复制。
该技术与大多数其他数据库管理系统相同。有关其他系统的知识会转移到MySQL。
对于以下类型的语句,在主服务器上需要较少的行锁,从而实现更高的并发性:
INSERT … SELECT
INSERT 陈述与 AUTO_INCREMENT
UPDATE或 DELETE带有WHERE不使用键或不更改大多数已检查行的子句的语句 。
对于任何,或 语句INSERT, 从站上需要的行锁较少 。 UPDATEDELETE
基于行的复制的缺点
RBR可以生成更多必须记录的数据。要复制DML语句(例如 UPDATEor DELETE语句),基于语句的复制仅将语句写入二进制日志。相比之下,基于行的复制会将每个更改的行写入二进制日志。如果该语句更改了许多行,则基于行的复制可能会向二进制日志中写入更多的数据。即使对于回滚的语句也是如此。这也意味着从备份中进行恢复可能需要更多时间。此外,二进制日志被锁定更长的时间以写入数据,这可能会导致并发问题。采用 binlog_row_image=minimal 大大减少了缺点。
生成大BLOB值的确定性UDF 与基于语句的复制相比,使用基于行的复制所花费的时间更长。这是因为BLOB记录了 列值,而不是记录了生成数据的语句。
您无法在从站上看到从主站接收并执行了哪些语句。但是,你可以看到使用被改变什么数据mysqlbinlog可以使用这些选项 --base64-output=DECODE-ROWS 和–verbose。
或者,使用binlog_rows_query_log_events 在MySQL 5.6.2中添加的变量,如果启用该 变量,则在使用该选项时会将Rows_query带有语句的事件添加 到 mysqlbinlog输出中 -vv。
对于使用MyISAM 存储引擎的表,将从属INSERT语句作为基于行的事件应用于二进制日志时,需要比从属语句对锁具有更强的锁定 。这意味着MyISAM在使用基于行的复制时,不支持在表上进行并发插入。