MySQL使用基于语句的日志(SBL),基于行的日志(RBL)或混合格式的日志。使用的二进制日志的类型会影响日志的大小和效率。因此,在基于行的复制(RBR)或基于语句的复制(SBR)之间进行选择取决于您的应用程序和环境。本节描述在使用基于行的格式日志时的已知问题,并讨论在复制中使用它的一些最佳实践。
有关更多信息,请参见 第17.1.2节“复制格式”和 第17.1.2.1节“基于语句的复制和基于行的复制的优点和缺点”。
有关特定于NDB群集复制的问题(取决于基于行的复制)的信息,请参见 第18.6.3节“ NDB群集复制中的已知问题”。
临时表的基于行的日志记录。 如 第17.4.1.29节“复制和临时表”中所述,使用基于行的格式时不会复制临时表。使用混合格式日志记录时, 将使用基于语句的格式记录涉及临时表的“ 安全 ”语句。有关更多信息,请参见第17.1.2.1节“基于语句的复制和基于行的复制的优缺点”。
使用基于行的格式时,不会复制临时表,因为没有必要。另外,由于只能从创建临时表的线程中读取临时表,因此即使使用基于语句的格式,复制临时表也几乎没有好处。
在MySQL 5.6中,即使已经创建了临时表,也可以从基于语句的二进制记录模式切换到基于行的二进制记录模式。但是,在使用基于行的格式时,MySQL服务器无法确定创建给定临时表时生效的日志记录模式。因此,在这种情况下,服务器DROP TEMPORARY TABLE IF EXISTS为每个临时表记录一条语句,该语句在给定客户端会话结束时仍存在。虽然这意味着DROP TEMPORARY TABLE 在某些情况下可能会记录不必要的语句,但是该语句是无害的,即使由于表的存在而导致表不存在也不会引起错误。IF EXISTS 选项。
注意
从MySQL 8.0开始,此行为已更改,因为MySQL服务器跟踪创建每个临时表时生效的日志记录模式。DROP TEMPORARY TABLE IF EXISTS因此,不必为每个临时表记录该 语句。从该发行版开始,当给定的客户端会话结束时,服务器DROP TEMPORARY TABLE IF EXISTS将为每个临时表记录一条语句,该语句在使用基于语句的二进制日志记录时仍存在并已创建。如果在创建表时使用了基于行或混合格式的二进制日志记录,DROP TEMPORARY TABLE IF EXISTS则不会记录该 语句。
使用时binlog_format=ROW,允许使用涉及临时表的非事务DML语句 ,只要受该语句影响的任何非事务表都是临时表即可(错误#14272672)。
RBL和非事务表的同步。 当许多行受到影响时,这组更改将分为几个事件。当语句提交时,所有这些事件都将写入二进制日志。在从属服务器上执行时,将对所有涉及的表进行表锁定,然后以批处理模式应用行。(这可能有效或无效,这取决于用于从属表的副本的引擎。)
延迟和二进制日志大小。 RBL将每一行的更改写入二进制日志,因此其大小可以快速增加。这会大大增加在从属服务器上进行与主服务器上的更改相匹配的更改所需的时间。您应该意识到应用程序中这种延迟的可能性。
读取二进制日志。 mysqlbinlog使用该BINLOG 语句在二进制日志中显示基于行的事件(请参见第13.7.6.1节“ BINLOG语句”)。该语句将事件显示为基本的64位编码字符串,其含义不明显。当使用–base64-output=DECODE-ROWS 和–verbose选项调用时 , mysqlbinlog将二进制日志的内容格式化为易于阅读。如果二进制日志事件是以基于行的格式编写的,并且您想读取复制或数据库故障或从中恢复,则可以使用此命令读取二进制日志的内容。有关更多信息,请参见第4.6.8.2节“ mysqlbinlog行事件显示”。
二进制日志执行错误和slave_exec_mode。 如果slave_exec_mode为 IDEMPOTENT,则由于找不到原始行而导致无法应用RBL所做的更改不会触发错误或导致复制失败。这意味着可能没有将更新应用于从属服务器,从而使主服务器和从属服务器不再同步。延迟问题,使用与RBR非事务性表的时候 slave_exec_mode是 IDEMPOTENT可以进一步导致主从发散。有关的更多信息 slave_exec_mode,请参见 第5.1.7节“服务器系统变量”。
注意
slave_exec_mode=IDEMPOTENT 通常仅适用于NDB群集的循环复制或多主复制,这 IDEMPOTENT是默认值。
对于其他方案,设置 slave_exec_mode于 STRICT通常是足够的; 这是默认值。
注意
以前,使用NDB Cluster时的默认值为 slave_exec_mode=IDEMPOTENT,但MySQL NDB Cluster 7.3及更高版本不再是这种情况。
不支持基于服务器ID的过滤。 在MySQL 5.6中,可以通过使用语句IGNORE_SERVER_IDS 选项基于服务器ID进行过滤CHANGE MASTER TO。此选项适用于基于语句和基于行的日志记录格式。过滤掉某些从属服务器上的更改的另一种方法是使用一个 WHERE子句,该子句包含带有and 语句的关系 子句 。例如,。但是,这不适用于基于行的日志记录。要将 系统变量用于语句过滤,请使用基于语句的日志记录。 @@server_id <> id_valueUPDATEDELETEWHERE @@server_id <> 1server_id
数据库级复制选项。 的影响 --replicate-do-db, --replicate-ignore-db以及 --replicate-rewrite-db 选择差异很大依赖于基于行或基于语句的日志记录是否被使用。因此,建议避免使用数据库级选项,而应使用诸如–replicate-do-table和的 表级选项 --replicate-ignore-table。有关这些选项以及影响复制格式对其操作方式的更多信息,请参见 第17.1.4节“复制和二进制日志记录选项和变量”。
RBL,非事务表和已停止的从属。 使用基于行的日志记录时,如果在从属线程更新非事务表时停止了从属服务器,则从属数据库可能会达到不一致的状态。因此,建议您InnoDB对所有使用基于行格式复制的表使用事务性存储引擎 。在关闭从MySQL服务器之前STOP SLAVE或 STOP SLAVE SQL_THREAD在关闭MySQL服务器之前使用 该功能有助于防止问题的发生,并且无论使用哪种日志记录格式或存储引擎,都始终建议这样做。




