MIXED二进制日志格式
在运行MIXED日志格式时,服务器会根据以下条件自动从基于语句的日志切换到基于行的日志:
- 当函数中包含UUID()函数时。
- 当更新一个或多个具有AUTO_INCREMENT列的表并调用触发器或存储函数时。与其他不安全语句一样,如果binlog_format = STATEMENT,则会生成警告。
- 当视图的主体要求基于行的复制时,创建视图的语句也会使用它。例如,当创建视图的语句使用UUID()函数时,就会发生这种情况。
- 当涉及调用可加载函数时。
- 当使用FOUND_ROWS()或ROW_COUNT()时。
- 当使用USER(),CURRENT_USER()或CURRENT_USER时。
- 当涉及到mysql数据库中的日志表之一时。
- 当使用LOAD_FILE()函数时。
- 当语句引用一个或多个系统变量时。
例外。以下系统变量仅在会话范围内使用时,不会导致日志格式切换:
- auto_increment_increment
- auto_increment_offset
- character_set_client
- character_set_connection
- character_set_database
- character_set_server
- collation_connection
- collation_database
- collation_server
- foreign_key_checks
- identity
- last_insert_id
- lc_time_names
- pseudo_thread_id
- sql_auto_is_null
- time_zone
- timestamp
- unique_checks
在早期版本中,当使用混合二进制日志格式时,如果一条语句以行的方式记录,并且执行该语句的会话中有任何临时表,那么所有后续的语句都被视为不安全,并以基于行的格式记录,直到该会话中使用的所有临时表被删除。从MySQL 8.0开始,对临时表的操作不会以混合二进制日志格式记录,会话中存在临时表对每个语句使用的日志模式没有影响。
注意: 如果尝试使用基于语句的日志记录执行应该使用基于行的日志记录的语句,将生成警告。警告会在客户端(通过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 |
决定是否记录语句以及所使用的日志模式取决于语句的类型(安全的、不安全的或二进制插入的)、二进制日志格式(语句、行或混合)以及存储引擎的日志记录功能(支持语句、行、两者或都不支持)。 (二进制插入是指必须使用行格式记录的更改进行日志记录。)
语句可以被记录,也可以不被记录并显示警告;失败的语句不会被记录,但会在日志中生成错误。
当决策产生警告时,会生成标准的MySQL警告(可以使用SHOW WARNINGS获取)。该信息也会写入到mysqld错误日志中。为了防止日志被淹没,每个客户端连接的每个错误实例只记录一次错误。日志消息中包含了尝试执行的SQL语句。
如果一个复制服务器将log_error_verbosity设置为显示警告,它会向错误日志输出消息,以提供有关其状态的信息,例如它开始工作的二进制日志和中继日志坐标,当它切换到另一个中继日志时,当它断开连接后重新连接,对于基于语句的日志记录不安全的语句等等。