当以MIXED
日志格式运行时,服务器会在以下条件下自动从基于语句的日志记录切换到基于行的日志记录:
当 DML 语句更新
NDBCLUSTER
表时。当函数包含
UUID()
.当
AUTO_INCREMENT
更新一个或多个包含列的表并调用触发器或存储函数时。与所有其他不安全语句一样,这会在 if 时生成警告binlog_format = STATEMENT
。有关详细信息,请参阅 第 16.4.1.1 节,“复制和 AUTO_INCREMENT”。
当视图的主体需要基于行的复制时,创建视图的语句也会使用它。例如,当创建视图的语句使用该
UUID()
函数时,就会发生这种情况。当涉及对可加载函数的调用时。
如果语句按行记录,并且执行该语句的会话有任何临时表,则按行记录用于所有后续语句(访问临时表的语句除外),直到删除该会话使用的所有临时表。
无论是否实际记录任何临时表都是如此。
不能使用基于行的格式记录临时表;因此,一旦使用基于行的日志记录,使用该表的所有后续语句都是不安全的。服务器通过将会话期间执行的所有语句视为不安全的来近似这种情况,直到会话不再包含任何临时表。
何时使用
FOUND_ROWS()
或ROW_COUNT()
。(缺陷 #12092,缺陷 #30244)使用
USER()
、CURRENT_USER()
或 时CURRENT_USER
。(漏洞 #28086)当一条语句引用一个或多个系统变量时。(漏洞 #31168)
例外。 以下系统变量,当与会话范围(仅)一起使用时,不会导致日志记录格式切换:
有关确定系统变量范围的信息,请参阅 第 5.1.8 节,“使用系统变量”。
有关复制如何处理的信息
sql_mode
,请参阅 第 16.4.1.37 节,“复制和变量”。当涉及的表之一是
mysql
数据库中的日志表时。使用该
LOAD_FILE()
功能时。(漏洞 #39701)
如果您尝试使用应该使用基于行的日志记录编写的基于语句的日志记录来执行语句,则会生成警告。该警告同时显示在客户端(在 的输出中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 |
When a warning is produced by the determination, a standard
MySQL warning is produced (and is available using
SHOW WARNINGS
). The information
is also written to the mysqld error log. Only
one error for each error instance per client connection is
logged to prevent flooding the log. The log message includes the
SQL statement that was attempted.
如果log_error_verbosity
在副本上为 2 或更大,则副本将消息打印到错误日志以提供有关其状态的信息,例如二进制日志和中继日志坐标它开始其作业的位置,切换到另一个中继日志的时间,当它断开连接后重新连接,对于基于语句的日志记录不安全的语句,等等。