您可以通过使用 启动 MySQL 服务器来显式选择二进制日志记录格式
。支持的值为:
--binlog-format=
type
type
STATEMENT
导致日志记录是基于语句的。ROW
导致日志记录基于行。MIXED
导致日志记录使用混合格式。
设置二进制日志记录格式不会激活服务器的二进制日志记录。该设置仅在服务器上启用二进制日志记录时生效,即log_bin
系统变量设置为时的情况ON
。在 MySQL 5.7 中,默认情况下不启用二进制日志记录,您可以使用该
--log-bin
选项启用它。
日志记录格式也可以在运行时切换,但请注意,在许多情况下您不能这样做,如本节后面所述。设置系统变量的全局值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
值需要足够的权限来设置受限会话系统变量。请参阅第 5.1.8.1 节,“系统变量权限”。
客户端可能希望在每个会话的基础上设置二进制日志记录的原因有多种:
对数据库进行许多小更改的会话可能需要使用基于行的日志记录。
执行与子句中的许多行匹配的更新的会话
WHERE
可能希望使用基于语句的日志记录,因为记录少量语句比记录许多行更有效。有些语句在源上需要大量执行时间,但只会修改几行。因此,使用基于行的日志记录来复制它们可能是有益的。
当您无法在运行时切换复制格式时会有例外情况:
从存储函数或触发器中。
如果
NDB
启用了存储引擎。如果会话当前处于基于行的复制模式并且具有打开的临时表。
在任何这些情况下尝试切换格式都会导致错误。
当存在任何临时表时,不建议在运行时切换复制格式,因为只有在使用基于语句的复制时才会记录临时表,而对于基于行的复制,它们不会被记录。对于混合复制,通常会记录临时表;异常发生在可加载函数和
UUID()
函数中。
在复制过程中切换复制格式也会导致问题。每个 MySQL 服务器都可以设置自己的二进制日志记录格式(无论
binlog_format
设置为全局范围还是会话范围,都为真)。这意味着更改复制源服务器上的日志记录格式不会导致副本更改其日志记录格式以匹配。使用
STATEMENT
模式时,
binlog_format
不会复制系统变量。当使用MIXED
或
ROW
记录模式时,它被复制但被副本忽略。
副本无法将以
ROW
日志记录格式
接收的二进制日志条目STATEMENT
转换为在其自己的二进制日志中使用的格式。因此,副本必须使用ROW
或
MIXED
格式化(如果源这样做的话)。将源上的二进制日志记录格式从更改
STATEMENT
为ROW
或
MIXED
在复制正在进行时更改为具有STATEMENT
格式的副本可能会导致复制失败并出现错误,例如错误执行行事件:'无法执行语句:不可能写入二进制日志,因为语句在行中格式和 BINLOG_FORMAT = STATEMENT。将副本上的二进制日志记录格式更改为STATEMENT
当源仍在使用时格式化MIXED
或ROW
格式化也会导致相同类型的复制失败。要安全地更改格式,您必须停止复制并确保对源和副本进行相同的更改。
如果您正在使用InnoDB
表并且事务隔离级别为READ
COMMITTED
或READ
UNCOMMITTED
,则只能使用基于行的日志记录。可以
将日志记录格式更改为
,但在运行时这样做会很快导致错误,因为无法再执行插入。
STATEMENT
InnoDB
将二进制日志格式设置为ROW
,许多更改将使用基于行的格式写入二进制日志。但是,一些更改仍然使用基于语句的格式。示例包括所有 DDL(数据定义语言)语句,例如CREATE TABLE
、
ALTER TABLE
或
DROP TABLE
。
该--binlog-row-event-max-size
选项适用于能够进行基于行的复制的服务器。行以不超过此选项值的字节大小的块存储到二进制日志中。该值必须是 256 的倍数。默认值为 8192。
当使用基于语句的日志记录进行复制时,如果语句的设计方式使得数据修改是 不确定的,则源和副本上的数据可能会变得不同;也就是说,它由查询优化器决定。通常,即使在复制之外,这也不是一个好的做法。有关此问题的详细说明,请参阅 第 B.3.7 节,“MySQL 中的已知问题”。