7.4.4.3 混合二进制日志格式
在使用MIXED
日志格式时,服务器自动从语句基于到行基于的日志格式切换,在以下情况下:
-
当函数包含
UUID()
。 -
当一个或多个具有
AUTO_INCREMENT
列的表被更新,并且触发器或存储函数被调用。像所有其他不安全语句一样,这生成一个警告,如果binlog_format = STATEMENT
。 -
当视图的体要求行基于的复制时,创建视图的语句也使用它。例如,这发生在创建视图的语句使用
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之前,使用混合二进制日志格式时,如果会话执行语句具有临时表,所有后续语句都被视为不安全,并以行形式记录,直到该会话中的所有临时表被删除。在MySQL 8.4中,临时表的操作不再以混合二进制日志格式记录,而该会话中的临时表对每个语句的记录模式无影响。
如果您尝试使用语句记录语句,但应该以行形式记录,生成警告。警告在客户端(SHOW WARNINGS
的输出和mysqld错误日志中显示。每次执行该语句时,添加警告到SHOW WARNINGS
表中。但是,每个客户会话的第一个生成警告的语句写入错误日志,以防止日志被淹没。
此外,单独引擎还可以确定更新表中的记录格式。单独引擎的记录能力可以按以下方式定义:
-
如果引擎支持行记录日志,称其为行记录日志能力。
-
如果引擎支持语句记录日志,称其为语句记录日志能力。
一个存储引擎可以支持任意一种或两种记录格式。以下表格列出了每个引擎支持的记录格式。
Storage Engine | Row Logging Supported | Statement Logging Supported |
---|---|---|
ARCHIVE |
Yes | Yes |
BLACKHOLE |
Yes | Yes |
CSV |
Yes | Yes |
EXAMPLE |
Yes | No |
FEDERATED |
Yes | Yes |
HEAP |
Yes | Yes |
InnoDB |
Yes | Yes when the transaction isolation level is REPEATABLE READ or SERIALIZABLE ; No otherwise. |
MyISAM |
Yes | Yes |
MERGE |
Yes | Yes |
NDB |
Yes | No |
是否将语句记录,并且要使用的记录模式,根据语句类型(安全、不安全或二进制注入)、二进制记录格式(STATEMENT
、ROW
或MIXED
)和存储引擎的记录能力(语句记录能力、行记录能力或两者都有)确定。 (二进制注入指的是使用ROW
格式记录必须被记录的变化。)
语句可能被记录或不记录,失败的语句不记录,但在日志中生成错误。这如表所示。 Type、binlog_format、SLC 和 RLC 列描述了条件,Error / Warning 和 Logged as 列表示相应的操作。 SLC 表示“语句记录能力”,RLC 表示“行记录能力”。
Type | binlog_format |
SLC | RLC | Error / Warning | Logged as |
---|---|---|---|---|---|
* | * |
否 | 否 | 错误:无法执行语句:至少有一个引擎参与,且该引擎既不能行记录也不能语句记录。 | - |
Safe | STATEMENT |
是 | 否 | - | STATEMENT |
Safe | MIXED |
是 | 否 | - | STATEMENT |
Safe | ROW |
是 | 否 | 错误:无法执行语句:BINLOG_FORMAT = ROW 且至少有一个表使用不支持行记录的存储引擎。 |
- |
Unsafe | STATEMENT |
是 | 否 | 警告:非安全语句以语句格式日志记录,因为BINLOG_FORMAT = STATEMENT |
STATEMENT |
Unsafe | MIXED |
是 | 否 | 错误:无法执行语句:非安全语句的二进制日志记录在存储引擎限制于语句基于日志记录时,甚至BINLOG_FORMAT = MIXED 。 |
- |
Unsafe | ROW |
是 | 否 | 错误:无法执行语句:二进制日志记录不可行,因为至少一个表使用不支持行基于日志记录的存储引擎。 | - |
Row Injection | STATEMENT |
是 | 否 | 错误:无法执行行注入:二进制日志记录不可行,因为至少一个表使用不支持行基于日志记录的存储引擎。 | - |
Row Injection | MIXED |
是 | 否 | 错误:无法执行行注入:二进制日志记录不可行,因为至少一个表使用不支持行基于日志记录的存储引擎。 | - |
Row Injection | ROW |
是 | 否 | 错误:无法执行行注入:二进制日志记录不可行,因为至少一个表使用不支持行基于日志记录的存储引擎。 | - |
Safe | STATEMENT |
否 | 是 | 错误:无法执行语句:自从BINLOG_FORMAT = STATEMENT 且至少一个表使用不支持语句日志存储引擎。 |
- |
Safe | MIXED |
否 | 是 | - | ROW |
Safe | ROW |
否 | 是 | - | ROW |
Unsafe | STATEMENT |
否 | 是 | 错误:无法执行语句:自从BINLOG_FORMAT = STATEMENT 且至少一个表使用不支持语句日志存储引擎。 |
- |
Unsafe | MIXED |
否 | 是 | - | ROW |
Unsafe | ROW |
否 | 是 | - | ROW |
Row Injection | STATEMENT |
否 | 是 | 错误:无法执行行注入:自从BINLOG_FORMAT = STATEMENT 。 |
- |
Row Injection | MIXED |
否 | 是 | - | ROW |
Row Injection | ROW |
否 | 是 | - | ROW |
Safe | STATEMENT |
是 | 是 | - | STATEMENT |
Safe | MIXED |
是 | 是 | - | STATEMENT |
Safe | ROW |
是 | 是 | - | ROW |
Unsafe | STATEMENT |
是 | 是 | 警告:自Unsafe语句binlogged在语句格式中,自从BINLOG_FORMAT = STATEMENT 。 |
STATEMENT |
Unsafe | MIXED |
是 | 是 | - | ROW |
Unsafe | ROW |
是 | 是 | - | ROW |
Row Injection | STATEMENT |
是 | 是 | 错误:不能执行行注入:因为BINLOG_FORMAT = STATEMENT ,二进制日志不可用。 |
- |
Row Injection | MIXED |
是 | 是 | - | ROW |
Row Injection | ROW |
是 | 是 | - | ROW |
当确定时产生警告,MySQL 会生成标准警告(可使用SHOW WARNINGS
),信息也写入到mysqld错误日志。每个客户端连接只记录一个错误实例,以免日志被淹没。日志消息还包括尝试执行的 SQL 语句。
如果复制服务器设置了log_error_verbosity
,以显示警告,复制服务器将在错误日志中打印状态信息,如开始工作的二进制日志和 relay 日志坐标、切换到另一个 relay 日志时、断开重连时、语句不安全用于语句日志等。