当以MIXED
日志格式运行时,服务器会在以下条件下自动从基于语句的日志记录切换到基于行的日志记录:
当函数包含
UUID()
.当
AUTO_INCREMENT
更新一个或多个包含列的表并调用触发器或存储函数时。与所有其他不安全语句一样,这会在 if 时生成警告binlog_format = STATEMENT
。有关详细信息,请参阅 第 17.5.1.1 节,“复制和 AUTO_INCREMENT”。
当视图的主体需要基于行的复制时,创建视图的语句也会使用它。例如,当创建视图的语句使用该
UUID()
函数时,就会发生这种情况。当涉及对可加载函数的调用时。
何时使用
FOUND_ROWS()
或ROW_COUNT()
。(缺陷 #12092,缺陷 #30244)使用
USER()
、CURRENT_USER()
或 时CURRENT_USER
。(漏洞 #28086)当涉及的表之一是
mysql
数据库中的日志表时。使用该
LOAD_FILE()
功能时。(漏洞 #39701)当一条语句引用一个或多个系统变量时。(漏洞 #31168)
例外。 以下系统变量,当与会话范围(仅)一起使用时,不会导致日志记录格式切换:
有关确定系统变量范围的信息,请参阅 第 5.1.9 节,“使用系统变量”。
有关复制如何处理的信息
sql_mode
,请参阅 第 17.5.1.39 节,“复制和变量”。
在早期版本中,当使用混合二进制日志记录格式时,如果语句按行记录并且执行该语句的会话有任何临时表,则所有后续语句都被视为不安全并以基于行的格式记录,直到所有临时表该会话正在使用的已删除。从 MySQL 8.0 开始,对临时表的操作不会以混合二进制日志记录格式记录,并且会话中临时表的存在对每个语句使用的日志记录模式没有影响。
如果您尝试使用应该使用基于行的日志记录编写的基于语句的日志记录来执行语句,则会生成警告。该警告同时显示在客户端(在 的输出中SHOW WARNINGS
)和mysqld错误日志中。SHOW WARNINGS
每次执行此类语句时都会向表中添加一条警告。但是,只有为每个客户端会话生成警告的第一条语句才会写入错误日志,以防止日志泛滥。
除了上述决定外,各个引擎还可以确定更新表中信息时使用的日志记录格式。单个引擎的日志记录功能可以定义如下:
如果引擎支持基于行的日志记录,则称该引擎是row-logging capable。
如果引擎支持基于语句的日志记录,则称该引擎是statement-logging capable。
给定的存储引擎可以支持其中一种或两种日志记录格式。下表列出了每个引擎支持的格式。
存储引擎 | 支持行记录 | 支持语句记录 |
---|---|---|
ARCHIVE |
是的 | 是的 |
BLACKHOLE |
是的 | 是的 |
CSV |
是的 | 是的 |
EXAMPLE |
是的 | 不 |
FEDERATED |
是的 | 是的 |
HEAP |
是的 | 是的 |
InnoDB |
是的 | 当事务隔离级别为
REPEATABLE READ 或
时是SERIALIZABLE ;没有别的。 |
MyISAM |
是的 | 是的 |
MERGE |
是的 | 是的 |
NDB |
是的 | 不 |
语句是否被记录以及使用的记录模式取决于语句的类型(安全、不安全或二进制注入)、二进制记录格式(STATEMENT
、ROW
或
MIXED
)以及存储引擎的记录能力(语句能力,行能力,两者兼而有之)。(二进制注入是指记录必须使用ROW
格式记录的更改。)
可以在有或没有警告的情况下记录语句;失败的语句不会被记录,但会在日志中产生错误。这显示在以下决策表中。 Type、 binlog_format、 SLC和 RLC列概述了条件,Error / Warning 和Logged as列表示相应的操作。SLC 代表“ statement-logging capable ”, RLC代表 “ row-logging capable ”。
类型 | binlog_format |
单片机 | 无线控制器 | 错误/警告 | 记录为 |
---|---|---|---|---|---|
* | * |
不 | 不 | 错误:无法执行语句:二进制日志记录是不可能的,因为至少涉及一个既不能行又不能语句的引擎。 | - |
安全的 | STATEMENT |
是的 | 不 | - | STATEMENT |
安全的 | MIXED |
是的 | 不 | - | STATEMENT |
安全的 | ROW |
是的 | 不 | 错误:无法执行语句:不可能进行二进制日志记录,因为BINLOG_FORMAT = ROW
至少有一个表使用的存储引擎不支持基于行的日志记录。 |
- |
不安全 | STATEMENT |
是的 | 不 | 警告:不安全的语句 binlogged in statement format,因为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
设置为显示警告,则副本将消息打印到错误日志以提供有关其状态的信息,例如二进制日志和中继日志坐标它开始其作业的位置,切换到另一个中继日志的时间,何时断开连接后重新连接,对于基于语句的日志记录不安全的语句,等等。