19.2.1.1 语句基于和行基于复制的优缺点
每种二进制日志格式都有其优缺点。对于大多数用户,混合复制格式应该提供最佳的数据完整性和性能。如果您想利用语句基于或行基于复制格式的特定功能来执行某些任务,可以使用本节的信息,了解它们的相对优缺点,以确定哪一种最适合您的需求。
-
可靠的技术。
-
写入日志文件的数据量减少。更新或删除多行时,这将导致日志文件所需的存储空间减少。此外,这也意味着可以更快地恢复备份。
-
日志文件包含所有修改了数据的语句,因此可以用来审核数据库。
-
语句不安全的SBR。 不是所有修改数据的语句(例如
INSERT
、DELETE
、UPDATE
和REPLACE
语句)可以使用语句基于复制。任何非确定性行为在使用语句基于复制时很难复制。例如:-
一个依赖于可加载函数或存储程序的语句,该函数或存储程序的返回值依赖于参数以外的因素。 (行基于复制则简单地复制函数或存储程序的返回值,因此在源和副本中对表行和数据的影响相同。)请参阅第19.5.1.16节,“Invoked Features Replication”,了解更多信息。
-
DELETE
和UPDATE
语句使用LIMIT
子句而没有ORDER BY
子句是非确定性的。请参阅第19.5.1.18节,“Replication and LIMIT”。 -
使用NOWAIT或SKIP LOCKED选项的锁定读语句(
SELECT ... FOR UPDATE
和SELECT ... FOR SHARE
)。详见NOWAIT和SKIP LOCKED的锁定读并发。 -
确定的可加载函数必须在复制服务器上应用。
-
以下函数不能正确地使用语句复制:
然而,所有其他函数都可以正确地使用语句复制,包括
NOW()
等。
不能正确地使用语句复制的语句将以警告形式记录,如下所示:
[Warning] Statement is not safe to log in statement format.
类似警告也将在客户端显示,可以使用
SHOW WARNINGS
命令显示。 -
-
INSERT ... SELECT
需要比行级锁定更多的锁定。 -
UPDATE
语句,如果没有索引在WHERE
子句中,那么必须锁定更多的行,以便与基于行的复制相比。 -
对于复杂的语句,语句必须在复制服务器上评估和执行,然后更新或插入行。使用基于行的复制,复制服务器只需要修改受影响的行,而不需要执行完整的语句。
-
如果在复制服务器上出现错误,特别是在执行复杂语句时,基于语句的复制可能会逐渐增加错误的范围。请参阅第19.5.1.29节,“复制服务器错误”。
-
存储函数在执行时使用与调用语句相同的
NOW()
值。然而,这不适用于存储过程。 -
确定的可加载函数必须在复制服务器上应用。
-
表定义必须在源和复制服务器上几乎相同。请参阅第19.5.1.9节,“源和复制服务器上的不同表定义”,了解更多信息。
-
DML 操作从 MySQL 授予权表(通过连接列表或子查询)读取数据,但不修改它们,将以非锁定读取的方式在 MySQL 授予权表上执行,因此不安全用于基于语句的复制。了解更多信息,请参阅授予权表并发。
-
所有更改都可以复制。这是最安全的复制形式。
Note更新
mysql
系统架构中的信息,例如GRANT
、REVOKE
和触发器、存储程序(包括存储过程)、视图的操作都将使用基于语句的复制方式复制到复制服务器上。对于语句,如
CREATE TABLE ... SELECT
,将生成一个CREATE
语句,并使用基于语句的格式复制到复制服务器上,而行插入将使用基于行的格式复制。 -
在源端,需要更少的行锁,以实现更高的并发性,对于以下类型的语句:
-
INSERT
语句中包含AUTO_INCREMENT
-
RBR 可能生成更多需要记录的数据。要复制 DML 语句(例如
UPDATE
或DELETE
语句),语句基于的复制将只将语句写入二进制日志。相比之下,行基于的复制将将每个更改的行写入二进制日志。如果语句更改了许多行,行基于的复制可能将更多的数据写入二进制日志;这也适用于回滚的语句。此外,这也意味着恢复备份可能需要更长的时间。此外,二进制日志将被锁定更长时间,以写入数据,这可能会导致并发问题。使用binlog_row_image=minimal
可以减少不良影响的程度。 -
确定的可加载函数,生成大量
BLOB
值的处理速度在行基于的复制中比语句基于的复制慢。这是因为BLOB
列值被记录,而不是生成数据的语句。 -
您不能在复制服务器上看到来自源服务器的语句和执行的语句。然而,您可以使用 mysqlbinlog 工具,使用选项
--base64-output=DECODE-ROWS
和--verbose
查看数据的变化。或者,您可以使用
binlog_rows_query_log_events
变量,如果启用,将在 mysqlbinlog 输出中添加一个Rows_query
事件,以便使用-vv
选项时。 -
对于使用
MyISAM
存储引擎的表,需要在复制服务器上对INSERT
语句应用时使用更强的锁定,而不是将其应用为语句。这意味着,在使用行基于的复制时,不能支持并发插入MyISAM
表。