MySQL复制/.../ 使用基于行的日志记录和复制

5.1.2基于行日志和复制的使用

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

有关其他信息,请参见第5.1节“复制格式”,第5.1.1节,“基于语句和基于行复制的优缺点”

有关NDB集群复制(依赖于基于行的复制)特定问题的信息,请参见NDB集群复制的已知问题

  • 临时表的基于行的日志记录。如在4.1.31节“复制和临时表”当使用基于行的格式或(从MySQL 8.0.4开始)混合格式时,临时表不会被复制。有关更多信息,请参见第5.1.1节,“基于语句和基于行复制的优缺点”

    使用基于行的格式或混合格式时不复制临时表,因为不需要。此外,由于只能从创建临时表的线程读取临时表,因此即使使用基于语句的格式,复制临时表也几乎没有任何好处。

    即使已经创建了临时表,也可以在运行时从基于语句的二进制日志记录格式切换到基于行的二进制日志记录格式。但是,在MySQL 8.0中,您不能在运行时从二进制日志的基于行或混合格式切换到基于语句的格式,这是由于任何原因创建临时表在上一种模式中,二进制日志中省略了语句。

    MySQL服务器跟踪每个临时表创建时生效的日志记录模式。当给定的客户端会话结束时,服务器记录a如果存在,删除临时表在使用基于语句的二进制日志记录时创建的每个临时表。如果在创建表时使用了基于行或混合格式的二进制日志记录,则如果存在,删除临时表语句未被记录。在MySQL 8.0.4和5.7.25之前的版本中如果存在,删除临时表语句将被记录,而不管生效的日志记录模式是什么。

    使用时允许使用涉及临时表的非事务性DML语句binlog_format =行,只要受语句影响的任何非事务性表都是临时表(Bug #14272672)。

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

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

  • 读取二进制日志。mysqlbinlog属性显示二进制日志中基于行的事件BINLOG声明(见BINLOG声明).此语句将事件显示为基本64编码的字符串,其含义不明显。当使用——base64-output = DECODE-ROWS而且——详细选项,mysqlbinlog将二进制日志的内容格式化为人类可读。当二进制日志事件以基于行的格式写入,并且希望从复制或数据库故障中读取或恢复时,可以使用此命令读取二进制日志的内容。有关更多信息,请参见mysqlbinlog行事件显示

  • 二进制日志执行错误和副本执行模式。使用slave_exec_mode =幂等通常只对MySQL NDB集群复制有用,用于哪个幂等为默认值。(见NDB集群复制:双向复制和循环复制).当系统变量replica_exec_modeslave_exec_mode幂等,由于无法找到原始行而从RBL应用更改的失败不会触发错误或导致复制失败。这意味着有可能没有对副本应用更新,因此源和副本不再同步。延迟问题和使用RBR的非事务性表时replica_exec_modeslave_exec_mode幂等会导致源和副本进一步背离。欲了解更多有关replica_exec_mode而且slave_exec_mode,请参阅服务器系统变量

    其他场景,设置replica_exec_modeslave_exec_mode严格的通常是足够的;这是存储引擎以外的默认值NDB

  • 不支持基于服务器ID的过滤。属性可以基于服务器ID进行筛选IGNORE_SERVER_IDS选项。将复制源更改为语句(从MySQL 8.0.23)或将master更改为语句(MySQL 8.0.23之前)。此选项适用于基于语句和基于行的日志记录格式,但不建议在以下情况下使用GTID_MODE =对是集。筛选某些副本上的更改的另一种方法是使用在哪里包含关系的子句@@server_id < >id_value条款与更新而且删除语句。例如,WHERE @@server_id <> 1.但是,这在基于行的日志记录中不能正常工作。使用server_id用于语句过滤的系统变量,使用基于语句的日志记录。

  • RBL、非事务性表和停止的副本。在使用基于行的日志记录时,如果在副本线程更新非事务性表时停止了副本服务器,则副本数据库可能会达到不一致状态。出于这个原因,建议您使用事务性存储引擎,例如InnoDB对于使用基于行的格式复制的所有表。使用停止复制停止复制sql_thread(或者在MySQL 8.0.22之前,使用SLAVE而不是REPLICA),在关闭副本MySQL服务器之前,这有助于防止问题的发生,无论您使用的日志格式或存储引擎是什么,总是建议使用。