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

跑进去的时候`混合`日志记录格式，服务器会在以下情况下自动从基于语句的日志切换到基于行的日志记录：

-   当一个函数包含[`UUID()`](miscellaneous-functions.html#function_uuid).

-   当一张或多张桌子`自动递增`更新列并调用触发器或存储函数。像所有其他不安全的语句一样，这会在以下情况下生成警告[`binlog_format = 声明`](replication-options-binary-log.html#sysvar_binlog_format).

    有关详细信息，请参阅[第 17.5.1.1 节，“复制和自动\_增量”](replication-features-auto-increment.html).

-   当视图的主体需要基于行的复制时，创建视图的语句也会使用它。例如，当创建视图的语句使用[`UUID()`](miscellaneous-functions.html#function_uuid)功能。

-   当涉及对可加载函数的调用时。

-   什么时候[`FOUND_ROWS()`](information-functions.html#function_found-rows)要么[`ROW_COUNT()`](information-functions.html#function_row-count)用来。（错误 #12092、错误 #30244）

-   什么时候[`用户（）`](information-functions.html#function_user),[`当前用户（）`](information-functions.html#function_current-user)， 要么[`当前用户`](information-functions.html#function_current-user)用来。（错误 #28086）

-   当涉及的表之一是日志表时`mysql`数据库。

-   当。。。的时候[`加载文件（）`](string-functions.html#function_load-file)使用功能。（错误 #39701）

-   当一个语句引用一个或多个系统变量时。（错误 #31168）

     **例外。**以下系统变量在与会话范围（仅）一起使用时不会导致日志记录格式切换：

    -   [`auto_increment_increment`](replication-options-source.html#sysvar_auto_increment_increment)

    -   [`auto_increment_offset`](replication-options-source.html#sysvar_auto_increment_offset)

    -   [`character_set_client`](server-system-variables.html#sysvar_character_set_client)

    -   [`字符集连接`](server-system-variables.html#sysvar_character_set_connection)

    -   [`字符集数据库`](server-system-variables.html#sysvar_character_set_database)

    -   [`character_set_server`](server-system-variables.html#sysvar_character_set_server)

    -   [`collat​​ion_connection`](server-system-variables.html#sysvar_collation_connection)

    -   [`collat​​ion_database`](server-system-variables.html#sysvar_collation_database)

    -   [`collat​​ion_server`](server-system-variables.html#sysvar_collation_server)

    -   [`foreign_key_checks`](server-system-variables.html#sysvar_foreign_key_checks)

    -   [`身份`](server-system-variables.html#sysvar_identity)

    -   [`last_insert_id`](server-system-variables.html#sysvar_last_insert_id)

    -   [`lc_time_names`](server-system-variables.html#sysvar_lc_time_names)

    -   [`伪线程 ID`](server-system-variables.html#sysvar_pseudo_thread_id)

    -   [`sql_auto_is_null`](server-system-variables.html#sysvar_sql_auto_is_null)

    -   [`时区`](server-system-variables.html#sysvar_time_zone)

    -   [`时间戳`](server-system-variables.html#sysvar_timestamp)

    -   [`独特的支票`](server-system-variables.html#sysvar_unique_checks)

        有关确定系统变量范围的信息，请参阅[第5.1.9节，“使用系统变量”](using-system-variables.html).

        有关复制如何处理的信息[`sql_模式`](server-system-variables.html#sysvar_sql_mode)看见[第17.5.1.39节，“复制和变量”](replication-features-variables.html).

    在早期版本中，当使用混合二进制记录格式时，如果一条语句按行记录，并且执行该语句的会话有任何临时表，则所有后续语句都被视为不安全的，并以基于行的格式记录，直到该会话使用的所有临时表都被删除。从MySQL 8.0开始，临时表上的操作不会以混合二进制日志记录格式记录，会话中临时表的存在对每条语句使用的日志记录模式没有影响。

笔记

如果试图使用基于语句的日志记录执行语句，则会生成一条警告，该语句应该使用基于行的日志记录来编写。该警告显示在客户端（在[`显示警告`](show-warnings.html))通过[**mysqld**](mysqld.html)错误日志。警告被添加到[`显示警告`](show-warnings.html)每次执行这样的语句时。但是，只有为每个客户端会话生成警告的第一条语句才会写入错误日志，以防止日志被淹没。

除了上面的决定，单个引擎还可以确定更新表中信息时使用的日志记录格式。单个引擎的日志记录功能可定义如下：

-   如果引擎支持基于行的日志记录，则称该引擎支持行日志记录。

-   如果引擎支持基于语句的日志记录，则称该引擎支持语句日志记录。

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

[](<>)

| 存储引擎 | 支持行日志记录 | 支持语句日志记录 |
| ---- | ------- | -------- |
| `档案文件` | 对 | 对 |
| `黑洞` | 对 | 对 |
| `CSV` | 对 | 对 |
| `实例` | 对 | 不 |
| `联邦的` | 对 | 对 |
| `堆` | 对 | 对 |
| `InnoDB` | 对 | 当事务隔离级别为[`可重复读取`](innodb-transaction-isolation-levels.html#isolevel_repeatable-read)或[`可序列化`](innodb-transaction-isolation-levels.html#isolevel_serializable); 没有别的。 |
| `米萨姆` | 对 | 对 |
| `合并` | 对 | 对 |
| [`NDB`](mysql-cluster.html) | 对 | 不 |

根据语句类型（安全、不安全或二进制注入）、二进制日志记录格式，确定是否记录语句以及使用的日志记录模式(`陈述`, `一行`或`混合的`)，以及存储引擎的日志功能（支持语句、支持行、两者都有或两者都没有）。（二进制注入指的是记录必须使用`一行`格式。）

记录语句时，可以有警告，也可以没有警告；失败的语句不会被记录，但会在日志中生成错误。这在下面的决策表中显示。**类型**, **二进制日志\_总体安排**, **SLC**和**RLC**列列出了条件，以及**错误/警告**和**登录为**列表示相应的操作。**SLC**代表“能够记录语句”，以及**RLC**代表“行记录能力”。

| 类型 | [`binlog_format`](replication-options-binary-log.html#sysvar_binlog_format) | SLC | RLC | 错误/警告 | 记录为 |
| --- | --------------------------------------------------------------------------- | --- | --- | ----- | --- |
| \* | `*` | 不 | 不 | 错误：无法执行语句：二进制日志记录是不可能的，因为至少涉及一个引擎，该引擎既不支持行又不支持语句。 | `-` |
| 安全的 | `陈述` | 是的 | 不 | - | `陈述` |
| 安全的 | `混合` | 是的 | 不 | - | `陈述` |
| 安全的 | `排` | 是的 | 不 | 错误：无法执行语句：二进制日志记录是不可能的，因为`BINLOG_FORMAT = 行`并且至少有一个表使用了无法进行基于行的日志记录的存储引擎。 | `-` |
| 不安全 | `陈述` | 是的 | 不 | 警告：以语句格式记录不安全的语句，因为`BINLOG_FORMAT = 声明` | `陈述` |
| 不安全 | `混合` | 是的 | 不 | 错误：无法执行语句：当存储引擎仅限于基于语句的日志记录时，不安全语句的二进制日志记录是不可能的，即使`BINLOG_FORMAT = 混合`. | `-` |
| 不安全 | `排` | 是的 | 不 | 错误：无法执行语句：二进制日志记录是不可能的，因为`BINLOG_FORMAT = 行`并且至少有一个表使用了无法进行基于行的日志记录的存储引擎。 | - |
| 行注入 | `陈述` | 是的 | 不 | 错误：无法执行行注入：无法进行二进制日志记录，因为至少有一个表使用了无法进行基于行的日志记录的存储引擎。 | - |
| 行注入 | `混合` | 是的 | 不 | 错误：无法执行行注入：无法进行二进制日志记录，因为至少有一个表使用了无法进行基于行的日志记录的存储引擎。 | - |
| 行注入 | `排` | 是的 | 不 | 错误：无法执行行注入：无法进行二进制日志记录，因为至少有一个表使用了无法进行基于行的日志记录的存储引擎。 | - |
| 安全的 | `陈述` | 不 | 是的 | 错误：无法执行语句：二进制日志记录是不可能的，因为`BINLOG_FORMAT = 声明`并且至少有一个表使用了不支持基于语句的日志记录的存储引擎。 | `-` |
| 安全的 | `混合` | 不 | 是的 | - | `排` |
| 安全的 | `排` | 不 | 是的 | - | `排` |
| 不安全 | `陈述` | 不 | 是的 | 错误：无法执行语句：二进制日志记录是不可能的，因为`BINLOG_FORMAT = 声明`并且至少有一个表使用了不支持基于语句的日志记录的存储引擎。 | - |
| 不安全 | `混合` | 不 | 是的 | - | `排` |
| 不安全 | `排` | 不 | 是的 | - | `排` |
| 行注入 | `陈述` | 不 | 是的 | 错误：无法执行行注入：无法进行二进制日志记录，因为`BINLOG_FORMAT = 声明`. | `-` |
| 行注入 | `混合` | 不 | 是的 | - | `排` |
| 行注入 | `排` | 不 | 是的 | - | `排` |
| 安全的 | `陈述` | 是的 | 是的 | - | `陈述` |
| 安全的 | `混合` | 是的 | 是的 | - | `陈述` |
| 安全的 | `排` | 是的 | 是的 | - | `排` |
| 不安全 | `陈述` | 是的 | 是的 | 警告：不安全的语句以语句格式记录，因为`BINLOG_FORMAT = 声明`. | `陈述` |
| 不安全 | `混合` | 是的 | 是的 | - | `排` |
| 不安全 | `排` | 是的 | 是的 | - | `排` |
| 行注入 | `陈述` | 对 | 对 | 错误：无法执行行注入：无法进行二进制日志记录，因为`BINLOG_FORMAT=语句`. | - |
| 行注入 | `混合的` | 对 | 对 | - | `一行` |
| 行注入 | `一行` | 对 | 对 | - | `一行` |

当通过确定生成警告时，将生成标准的MySQL警告（并且可以使用[`显示警告`](show-warnings.html))。该信息也会写入[**mysqld**](mysqld.html)错误日志。每个客户端连接的每个错误实例只记录一个错误，以防止日志被淹没。日志消息包含尝试的SQL语句。

如果复制品[`日志错误详细`](server-system-variables.html#sysvar_log_error_verbosity)设置为显示警告，复制副本会将消息打印到错误日志，以提供有关其状态的信息，例如二进制日志和中继日志坐标，它开始工作的位置，切换到另一个中继日志的时间，断开连接后重新连接的时间，对于基于语句的日志记录不安全的语句，等等。
