16.2.1.2 基于行的日志记录和复制的用法

MySQL 使用基于语句的日志(SBL),基于行的日志(RBL)或混合格式的日志。所使用的二进制日志的类型会影响日志的大小和效率。因此,在基于行的复制(RBR)或基于语句的复制(SBR)之间进行选择取决于您的应用程序和环境。本节介绍在使用基于行的格式日志时的已知问题,并介绍在复制中使用它的一些最佳实践。

有关更多信息,请参见第 16.2.1 节“复制格式”第 16.2.1.1 节,“基于语句的复制和基于行的复制的优缺点”

有关特定于 NDB 群集复制(取决于基于行的复制)的问题的信息,请参阅第 21.6.3 节“ NDB 群集复制中的已知问题”

使用基于行的格式时,不会复制临时 table,因为没有必要。此外,由于只能从创建临时 table 的线程中读取临时 table,因此即使使用基于语句的格式,复制临时 table 也几乎没有好处。

即使已创建临时 table,也可以在运行时从基于语句的二进制记录格式切换为基于行的二进制记录格式。从 MySQL 5.7.25 开始,MySQL 服务器跟踪创建每个临时 table 时生效的日志记录模式。当给定的 Client 端会话结束时,服务器为每个临时 table 记录一个DROP TEMPORARY TABLE IF EXISTS语句,该临时 table 在使用基于语句的二进制日志记录时创建并创建。如果在创建 table 时使用了基于行或混合格式的二进制日志记录,则不会记录DROP TEMPORARY TABLE IF EXISTS语句。在以前的版本中,无论有效的日志记录模式如何,都记录了DROP TEMPORARY TABLE IF EXISTS语句。

使用binlog_format=ROW时,允许使用涉及临时 table 的非事务 DML 语句,只要受该语句影响的任何非事务 table 都是临时 table 即可(错误#14272672)。

  • RBL 和非事务 table 的同步. 当许多行受到影响时,更改集将拆分为多个事件;当语句提交时,所有这些事件都将写入二进制日志。在副本上执行时,将对所有涉及的 table 进行 table 锁定,然后以批处理模式应用行。根据用于 table 的副本的副本的引擎,这可能有效或无效。

  • 延迟和二进制日志大小. RBL 将每一行的更 Rewrite 入二进制日志,因此其大小可以快速增加。这会显着增加在副本上进行与源上的更改相匹配的更改所需的时间。您应该意识到应用程序中这种延迟的可能性。

  • 读取二进制日志. mysqlbinlog使用BINLOG语句在二进制日志中显示基于行的事件(请参见第 13.7.6.1 节“ BINLOG 语句”)。该语句将事件显示为基本的 64 位编码字符串,其含义不明显。当使用--base64-output=DECODE-ROWS--verbose选项调用时,mysqlbinlog将二进制日志的内容格式化为人类可读的格式。当二进制日志事件以基于行的格式编写并且您要读取复制或数据库故障或从中恢复时,可以使用此命令读取二进制日志的内容。有关更多信息,请参见第 4.6.7.2 节“ mysqlbinlog 行事件显示”

  • 二进制日志执行错误和副本执行模式. 使用slave_exec_mode=IDEMPOTENT通常仅对 MySQL NDB Cluster Replication 有用,其默认值为IDEMPOTENT。 (请参见第 21.6.10 节“ NDB 群集复制:双向复制和循环复制”)。 slave_exec_modeIDEMPOTENT时,由于找不到原始行而无法应用 RBL 更改不会触发错误或导致复制失败。这意味着可能没有对副本应用更新,因此源和副本不再同步。延迟问题以及slave_exec_modeIDEMPOTENT时在 RBR 中使用非事务 table 可能会导致源和副本进一步分散。有关slave_exec_mode的更多信息,请参见第 5.1.7 节“服务器系统变量”

对于其他情况,通常将slave_exec_mode设置为STRICT即可;这是NDB以外的存储引擎的默认值。

  • 不支持基于服务器 ID 的过滤. 您可以通过对更改为主语句使用IGNORE_SERVER_IDS选项来基于服务器 ID 进行过滤。此选项适用于基于语句和基于行的日志记录格式。筛选出某些副本上的更改的另一种方法是使用WHERE子句,该子句包括具有UPDATEDELETE语句的关系@@server_id <> id_value子句。例如WHERE @@server_id <> 1。但是,这不适用于基于行的日志记录。要将server_id系统变量用于语句过滤,请使用基于语句的日志记录。

  • RBL,非事务 table 和已停止的副本. 当使用基于行的日志记录时,如果在复制线程更新非事务 table 时停止了副本服务器,则副本数据库可能会达到不一致的状态。因此,对于使用基于行的格式复制的所有 table,建议您使用事务存储引擎,例如InnoDB。在关闭副本服务器之前使用STOP SLAVE停止从 SQL_THREAD有助于防止出现问题,并且无论使用哪种日志记录格式或存储引擎,都始终建议使用。