5.4.4.3 混合二进制日志记录格式

当以MIXED日志记录格式运行时,服务器在以下情况下自动从基于语句的记录切换为基于行的记录:

  • 当一个函数包含UUID()时。

  • 更新具有AUTO_INCREMENT列的一个或多个 table 并调用触发器或存储的函数时。像所有其他不安全的语句一样,如果binlog_format = STATEMENT,则会生成警告。

有关更多信息,请参见第 16.4.1.1 节“复制和 AUTO_INCREMENT”

  • 当视图主体需要基于行的复制时,创建视图的语句也将使用它。例如,当创建视图的语句使用UUID()函数时,就会发生这种情况。

  • 当涉及到 UDF 的调用时。

  • 如果一条语句按行记录,并且执行该语句的会话有任何临时 table,则按行记录将用于所有后续语句(访问临时 table 的语句除外),直到该会话使用的所有临时 table 都被删除为止。

无论是否实际记录任何临时 table,这都是事实。

临时 table 不能使用基于行的格式记录;因此,一旦使用了基于行的日志记录,使用该 table 的所有后续语句都是不安全的。服务器通过将会话期间执行的所有语句视为不安全,直到会话不再拥有任何临时 table,来近似此条件。

exception. 以下系统变量(仅与会话范围一起使用)不会导致日志记录格式切换:

有关确定系统变量范围的信息,请参见第 5.1.8 节“使用系统变量”

有关复制如何处理sql_mode的信息,请参见第 16.4.1.37 节,“复制和变量”

  • 当涉及的 table 之一是mysql数据库中的日志 table 时。

  • 使用LOAD_FILE()功能时。错误 39701)

Note

如果尝试使用基于语句的日志记录执行语句,则应使用基于行的日志记录来生成警告。在 Client 端(在SHOW WARNINGS的输出中)和mysqld错误日志中都将显示警告。每次执行此类语句时,都会向SHOW WARNINGStable 添加警告。但是,只有为每个 Client 端会话生成警告的第一条语句才被写入错误日志,以防止日志泛滥。

除上述决定外,各个引擎还可以确定更新 table 中信息时使用的日志记录格式。单个引擎的日志记录功能可以定义如下:

  • 如果引擎支持基于行的日志记录,则该引擎被称为具有行记录功能。

  • 如果引擎支持基于语句的日志记录,则称该引擎具有语句记录功能。

给定的存储引擎可以支持一种或两种日志格式。下 table 列出了每个引擎支持的格式。

Storage Engine支持行记录支持语句记录
ARCHIVEYesYes
BLACKHOLEYesYes
CSVYesYes
EXAMPLEYesNo
FEDERATEDYesYes
HEAPYesYes
InnoDBYes是,当事务隔离级别为REPEATABLE READSERIALIZABLE时;否则没有。
MyISAMYesYes
MERGEYesYes
NDBYesNo

根据语句的类型(安全,不安全或二进制注入),二进制日志记录格式(STATEMENTROWMIXED)以及日志记录的功能,确定是否要记录一条语句以及要使用的日志记录模式。存储引擎(具有语句功能,具有行功能,或者两者兼而有之)。 (二进制注入是指记录必须使用ROW格式记录的更改.)

可能会在有或没有警告的情况下记录语句;失败的语句不会记录,但会在日志中生成错误。如下决策 table 所示。 Typebinlog_formatSLCRLC 列概述了条件,并且 Error/WarningLogged as 列 table 示相应的操作。 SLC 代 table“具有语句记录功能”,而 RLC 代 table“具有行记录功能”。

Typebinlog_formatSLCRLC错误/警告Logged as
**NoNo错误:无法执行语句:二进制日志记录是不可能的,因为涉及至少一个行不行和语句不行的引擎。-
SafeSTATEMENTYesNo-STATEMENT
SafeMIXEDYesNo-STATEMENT
SafeROWYesNo错误:无法执行语句:二进制记录是不可能的,因为BINLOG_FORMAT = ROW,并且至少一个 table 使用的存储引擎无法进行基于行的日志记录。-
UnsafeSTATEMENTYesNo警告:不安全的语句以BINLOG_FORMAT = STATEMENT的格式记录在日志中STATEMENT
UnsafeMIXEDYesNo错误:无法执行语句:当存储引擎仅限于基于语句的日志记录时,即使BINLOG_FORMAT = MIXED,也不可能对不安全的语句进行二进制日志记录。-
UnsafeROWYesNo错误:无法执行语句:二进制记录是不可能的,因为BINLOG_FORMAT = ROW,并且至少一个 table 使用的存储引擎无法进行基于行的日志记录。-
Row InjectionSTATEMENTYesNo错误:无法执行行注入:由于至少一个 table 使用了不支持基于行的日志记录的存储引擎,因此无法进行二进制日志记录。-
Row InjectionMIXEDYesNo错误:无法执行行注入:由于至少一个 table 使用了不支持基于行的日志记录的存储引擎,因此无法进行二进制日志记录。-
Row InjectionROWYesNo错误:无法执行行注入:由于至少一个 table 使用了不支持基于行的日志记录的存储引擎,因此无法进行二进制日志记录。-
SafeSTATEMENTNoYes错误:无法执行语句:二进制日志记录是不可能的,因为BINLOG_FORMAT = STATEMENT并且至少一个 table 使用了不支持基于语句的日志记录的存储引擎。-
SafeMIXEDNoYes-ROW
SafeROWNoYes-ROW
UnsafeSTATEMENTNoYes错误:无法执行语句:二进制日志记录是不可能的,因为BINLOG_FORMAT = STATEMENT并且至少一个 table 使用了不支持基于语句的日志记录的存储引擎。-
UnsafeMIXEDNoYes-ROW
UnsafeROWNoYes-ROW
Row InjectionSTATEMENTNoYes错误:无法执行行注入:由于BINLOG_FORMAT = STATEMENT,因此无法进行二进制日志记录。-
Row InjectionMIXEDNoYes-ROW
Row InjectionROWNoYes-ROW
SafeSTATEMENTYesYes-STATEMENT
SafeMIXEDYesYes-STATEMENT
SafeROWYesYes-ROW
UnsafeSTATEMENTYesYes警告:自BINLOG_FORMAT = STATEMENT以来,不安全语句以语句格式被二进制记录。STATEMENT
UnsafeMIXEDYesYes-ROW
UnsafeROWYesYes-ROW
Row InjectionSTATEMENTYesYes错误:无法执行行注入:由于BINLOG_FORMAT = STATEMENT,因此无法进行二进制日志记录。-
Row InjectionMIXEDYesYes-ROW
Row InjectionROWYesYes-ROW

当确定产生警告时,将产生标准的 MySQL 警告(并且可以使用SHOW WARNINGS来获得)。该信息也将写入mysqld错误日志。每个 Client 端连接的每个错误实例仅记录一个错误,以防止泛滥日志。日志消息包含尝试的 SQL 语句。

如果副本上的log_error_verbosity为 2 或更大,则副本将向错误日志输出消息,以提供有关其状态的信息,例如二进制日志和中继日志坐标(在其开始工作时,切换到另一个中继日志时,它会在断开连接,对于基于语句的日志记录不安全的语句等之后重新连接。