在 MIXED 日志格式下运行时,服务器会在以下情况下自动从基于语句的日志记录切换到基于行的日志记录:
-
当函数包含
UUID()
时。 -
当一个或多个表具有
AUTO_INCREMENT
列时,并且触发器或存储函数被调用。这类似于所有其他不安全的语句,会生成警告,如果binlog_format = STATEMENT
。有关更多信息,请参阅 第 19.5.1.1 节,“复制和 AUTO_INCREMENT”。
-
当视图的主体需要基于行的复制时,创建视图的语句也将使用它。例如,这发生在创建视图的语句使用
UUID()
函数时。 -
当加载函数调用时。
-
当
FOUND_ROWS()
或ROW_COUNT()
被使用时。(Bug #12092, Bug #30244) -
当
USER()
,CURRENT_USER()
, 或CURRENT_USER
被使用时。(Bug #28086) -
当其中一个表是 mysql 数据库中的日志表时。
-
当
LOAD_FILE()
函数被使用时。(Bug #39701) -
当语句引用一个或多个系统变量时。(Bug #31168)
例外。 以下系统变量,在会话范围内使用时,不会导致日志格式切换:
有关确定系统变量作用域的信息,请参阅 第 7.1.9 节,“使用系统变量”。
有关复制如何处理
sql_mode
的信息,请参阅 第 19.5.1.39 节,“复制和变量”。
在早期版本中,当混合二进制日志格式处于使用状态时,如果一个语句被记录为行,并且执行该语句的会话中有任何临时表,那么所有后续语句都将被视为不安全的并以行格式记录,直到该会话中的所有临时表都被删除。从 MySQL 8.0 开始,对临时表的操作不再记录在混合二进制日志格式中,并且会话中的临时表的存在不会影响每个语句的日志模式。
如果您尝试执行一个语句,使用基于语句的日志记录,而该语句应该使用基于行的日志记录,则会生成警告。该警告将显示在客户端(在 SHOW WARNINGS
的输出中)和通过 mysqld 错误日志。每次执行生成警告的语句时,都将添加到 SHOW WARNINGS
表中。然而,只有每个客户端会话的第一个生成警告的语句将被写入错误日志,以防止日志被淹没。
除了上述决定外,单个引擎还可以确定更新表信息时使用的日志格式。引擎的日志能力可以定义如下:
-
如果引擎支持基于行的日志记录,则该引擎被称为 行日志记录capable。
-
如果引擎支持基于语句的日志记录,则该引擎被称为 语句日志记录capable。
给定的存储引擎可以支持其中一种或两种日志格式。以下表格列出了每个引擎支持的格式。
存储引擎 | 行日志记录支持 | 语句日志记录支持 |
---|---|---|
ARCHIVE |
是 | 是 |
BLACKHOLE |
是 | 是 |
CSV |
是 | 是 |
EXAMPLE |
是 | 否 |
FEDERATED |
是 | 是 |
HEAP |
是 | 是 |
InnoDB |
是 | 是当事务隔离级别为REPEATABLE READ 或SERIALIZABLE 时;否则否。 |
MyISAM |
是 | 是 |
MERGE |
是 | 是 |
NDB |
是 | 否 |
根据语句类型(安全、不安全或二进制注入)、二进制日志格式(STATEMENT
、ROW
或MIXED
)和存储引擎的日志记录能力(语句日志记录、行日志记录、两者或都不支持),确定是否记录语句和日志记录模式。(二进制注入是指使用ROW
格式记录更改。)
语句可能会记录或不记录警告;失败的语句不会记录,但会在日志中生成错误。这在以下决策表中显示。类型、binlog_format、SLC和RLC列概述了条件,而错误 / 警告和记录为列表示相应的操作。SLC是“语句日志记录能力”的缩写,RLC是“行日志记录能力”的缩写。
二进制日志格式
*
错误:无法执行语句-
STATEMENT
STATEMENT
MIXED
STATEMENT
ROW
错误:无法执行语句BINLOG_FORMAT = ROW
-
STATEMENT
警告:不安全语句以语句格式记录日志BINLOG_FORMAT = STATEMENT
STATEMENT
MIXED
错误:无法执行语句BINLOG_FORMAT = MIXED
-
ROW
错误:无法执行语句BINLOG_FORMAT = ROW
STATEMENT
错误:无法执行行注入MIXED
错误:无法执行行注入ROW
错误:无法执行行注入STATEMENT
错误:无法执行语句BINLOG_FORMAT = STATEMENT
-
MIXED
ROW
ROW
ROW
STATEMENT
错误:无法执行语句BINLOG_FORMAT = STATEMENT
MIXED
ROW
ROW
ROW
STATEMENT
错误:无法执行行注入BINLOG_FORMAT = STATEMENT
-
MIXED
ROW
ROW
ROW
STATEMENT
STATEMENT
MIXED
STATEMENT
ROW
ROW
STATEMENT
警告:不安全语句以语句格式二进制日志记录BINLOG_FORMAT = STATEMENT
STATEMENT
MIXED
ROW
ROW
ROW
STATEMENT
错误:无法执行行注入BINLOG_FORMAT = STATEMENT
MIXED
ROW
ROW
ROW
当确定产生警告时,会生成标准的 MySQL 警告(并可以使用SHOW WARNINGS
). 该信息也将被写入mysqld错误日志中。每个客户端连接的每个错误实例只记录一次错误,以防止日志被淹没。日志消息包括尝试执行的 SQL 语句。
如果副本将log_error_verbosity
设置为显示警告,则副本将打印消息到错误日志,以提供其状态信息,例如它开始工作的二进制日志和中继日志坐标、切换到另一个中继日志时、断开连接后重新连接、不适合基于语句的日志记录的语句等等。