5.4.4.2 设置二进制日志格式

您可以通过使用--binlog-format=type启动 MySQL 服务器来显式选择二进制日志记录格式。 * type *支持的值为:

  • STATEMENT使日志记录基于语句。

  • ROW使日志记录基于行。

  • MIXED使日志记录使用混合格式。

日志记录格式也可以在运行时进行切换,尽管请注意,在许多情况下您无法执行此操作,如本节后面所述。设置binlog_format系统变量的全局值,以为更改之后连接的 Client 端指定格式:

mysql> SET GLOBAL binlog_format = 'STATEMENT';
mysql> SET GLOBAL binlog_format = 'ROW';
mysql> SET GLOBAL binlog_format = 'MIXED';

单个 Client 端可以通过将会话值设置为binlog_format来控制其自己的语句的日志记录格式:

mysql> SET SESSION binlog_format = 'STATEMENT';
mysql> SET SESSION binlog_format = 'ROW';
mysql> SET SESSION binlog_format = 'MIXED';

更改全局binlog_format值需要足够的特权来设置全局系统变量。更改会话binlog_format的值要求特权足以设置受限制的会话系统变量。参见第 5.1.8.1 节“系统变量特权”

Client 端可能要基于每个会话设置二进制日志记录的原因有几个:

  • 对数据库进行许多小更改的会话可能要使用基于行的日志记录。

  • 执行与WHERE子句中的许多行匹配的更新的会话可能要使用基于语句的日志记录,因为与许多行相比,记录一些语句会更高效。

  • 有些语句在源上需要大量执行时间,但是导致仅修改了几行。因此,使用基于行的日志记录来复制它们可能是有益的。

当您无法在运行时切换复制格式时,会有一些 exceptions:

  • 从存储的函数或触发器中。

  • 如果启用了NDB存储引擎。

  • 如果会话当前处于基于行的复制模式,并且具有打开的临时 table。

在任何这些情况下尝试切换格式都会导致错误。

不存在任何临时 table 时,建议不要在运行时切换复制格式,因为临时 table 仅在使用基于语句的复制时才记录,而在基于行的复制中则不记录。对于混合复制,通常会记录临时 table。用户定义的函数(UDF)和UUID()函数会发生异常。

在复制进行过程中切换复制格式也会导致问题。每个 MySQL Server 可以设置自己的并且只能设置自己的二进制日志记录格式(对于binlog_format是全局范围还是会话范围,则为 true)。这意味着更改复制源服务器上的日志记录格式不会导致副本副本更改其日志记录格式以匹配。使用STATEMENT模式时,不会复制binlog_format系统变量。使用MIXEDROW日志记录模式时,将复制它,但副本将忽略它。

副本无法将以ROW日志记录格式接收的二进制日志条目转换为STATEMENT格式以用于其自己的二进制日志。因此,如果源使用副本,则副本必须使用ROWMIXED格式。在复制过程中将源上的二进制日志记录格式从STATEMENT更改为ROWMIXED,而复制正在进行时是STATEMENT格式的副本,可能会导致复制失败,并显示以下错误,例如错误执行行事件:'无法执行语句:无法写入二进制日志,因为语句为行格式,并且 BINLOG_FORMAT = STATEMENT。当源仍使用MIXEDROW格式时,将副本上的二进制日志记录格式更改为STATEMENT格式也会导致相同类型的复制失败。为了安全地更改格式,必须停止复制并确保对源和副本进行相同的更改。

如果您使用的是InnoDB个 table,并且事务隔离级别为READ COMMITTEDREAD UNCOMMITTED,则只能使用基于行的日志记录。可以将日志记录格式更改为STATEMENT,但是在运行时这样做会非常迅速地导致错误,因为InnoDB无法再执行插入。

将二进制日志格式设置为ROW时,使用基于行的格式将许多更 Rewrite 入二进制日志。但是,某些更改仍然使用基于语句的格式。示例包括所有 DDL(数据定义语言)语句,例如CREATE TABLEALTER TABLEDROP TABLE

--binlog-row-event-max-size选项适用于能够进行基于行的复制的服务器。将行以块的形式存储在二进制日志中,块的大小不超过此选项的值(以字节为单位)。该值必须是 256 的倍数。默认值为 8192.

Warning

当使用“基于语句的日志记录”进行复制时,如果以一种不确定的方式修改数据来设计语句,则源和副本上的数据可能会有所不同。也就是说,它由查询优化器决定。通常,即使在复制之外,这也不是一个好习惯。有关此问题的详细说明,请参见第 B.4.7 节“ MySQL 中的已知问题”