Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  Setting The Binary Log Format

7.4.4.2 设置二进制日志格式

您可以通过使用--binlog-format=type明确地选择二进制日志格式。支持的type值是:

  • STATEMENT使logging基于语句。

  • ROW使logging基于行。这是默认的。

  • MIXED使logging使用混合格式。

设置二进制日志格式不激活服务器的二进制日志功能。该设置只在服务器启用了二进制日志时生效,而不是默认情况下启用,除非您以--skip-log-bin--disable-log-bin启动服务器。在 MySQL 8.4 中,二进制日志默认启用,只有在您以这两个选项启动服务器时才会禁用。

logging格式也可以在运行时切换,但是注意有一些情况下不能这样做,后面这个部分将讨论。将全局值binlog_format系统变量设置为指定连接后续的客户端格式:

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

单个客户端可以通过设置binlog_format会话值来控制其语句的日志格式:

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

更改全局binlog_format值需要具有足够权限以设置全局系统变量。更改会话binlog_format值需要具有足够权限以设置受限制的会话系统变量。见第7.1.9.1节,“系统变量权限”

有几个原因使客户端想要在会话基础上设置二进制日志:

  • 一个对数据库进行许多小改动的会话可能想使用行基于日志。

  • 一个对更新语句中的多行进行更新的会话可能想使用语句基于日志,因为它更高效地记录少数语句,而不是多行。

  • 一些语句在源服务器上需要很长时间执行,但最终只修改少数行。因此,使用行基于日志来复制它们可能是有益的。

有一些情况下不能在运行时更改复制格式:

  • 不能从存储函数或触发器中更改复制格式。

  • NDB存储引擎启用时不能更改。

  • 如果会话打开临时表,不能更改会话的复制格式(SET @@SESSION.binlog_format)。

  • 如果有任何复制通道打开临时表,不能全局更改复制格式(SET @@GLOBAL.binlog_formatSET @@PERSIST.binlog_format)。

  • 如果有任何复制通道应用线程当前正在运行,不能全局更改复制格式(SET @@GLOBAL.binlog_formatSET @@PERSIST.binlog_format)。

在这些情况下或尝试设置当前复制格式都会导致错误。然而,您可以使用 PERSIST_ONLYSET @@PERSIST_ONLY.binlog_format)随时更改复制格式,因为这不会修改运行时全局系统变量的值,直到服务器重启才生效。

在有临时表的情况下不建议在运行时切换复制格式,因为临时表只有在使用语句级别复制时才被记录,而使用行级别复制和混合复制时不会被记录。

在复制过程中更改存储引擎格式也可能会出现问题。每个 MySQL 服务器都可以设置自己的二进制日志格式(无论是全局或会话范围),这意味着在源服务器更改日志格式时,副本不一定会相应地更改其日志格式。使用 STATEMENT 模式时,binlog_format 系统变量不会被复制。使用 MIXEDROW 日志模式时,它将被复制,但副本会忽略它。

从属服务器不能将接收到的二进制日志记录转换为STATEMENT格式用于其自己的二进制日志。因此,必须在源服务器上使用ROWMIXED格式。如果在从属服务器正在进行 replication 到一个使用STATEMENT格式的服务器,而源服务器正在更改为ROWMIXED格式,可能会导致 replication 失败,出现错误,如Error executing row event: 'Cannot execute statement: impossible to write to binary log since statement is in row format and BINLOG_FORMAT = STATEMENT.'。要安全地更改格式,必须停止 replication,并确保在源服务器和从属服务器上都进行相同的更改。

如果您使用InnoDB表,并且事务隔离级别是READ COMMITTEDREAD UNCOMMITTED,只能使用行基于日志记录。虽然可以将日志格式更改为STATEMENT,但是在运行时这样做会很快出现错误,因为InnoDB不能再执行插入操作。

在将二进制日志格式设置为 ROW 时,许多变化使用行基于的格式写入二进制日志。然而,一些变化仍然使用语句基于的格式。例如包括所有DDL语句,如CREATE TABLEALTER TABLEDROP TABLE

当使用行基于的二进制日志时,binlog_row_event_max_size 系统变量和相应的启动选项--binlog-row-event-max-size 设置了行事件的软限制。默认值为 8192 字节,可以在服务器启动时更改。可能的地方,二进制日志中存储的行被分组成不超过该设置值的事件。如果事件不能被分割,最大大小可以超出。

--binlog-row-event-max-size 选项适用于支持行基于复制的服务器。二进制日志中存储的行以字节为单位,且不超过该选项值的大小。该值必须是256的倍数。默认值为 8192。

Warning

在使用语句日志进行复制时,如果一个语句的数据修改是非确定性的,那么源服务器和副本服务器上的数据可能不同;即使是由查询优化器来决定。一般来说,这种做法在复制外也不是好的实践。关于这个问题的详细解释,请参见第B.3.7节,“MySQL中的已知问题”