MySQL在哪些场景下不记录binlog?
摘要:背景 在 MySQL 中,慢日志不仅可以记录在文件中,还可以记录在表中。具体是记录在文件还是表中是由log_output参数决定的。 该参数默认为FILE,即慢日志默认会记录在文件中。如果参数中包含TABLE,则慢日志还会记录在mysql.
背景
在 MySQL 中,慢日志不仅可以记录在文件中,还可以记录在表中。具体是记录在文件还是表中是由log_output参数决定的。
该参数默认为FILE,即慢日志默认会记录在文件中。如果参数中包含TABLE,则慢日志还会记录在mysql.slow_log中,而mysql.slow_log使用的是 CSV 存储引擎。
最初研究这一问题,是为了确认在主从复制以及组复制(MGR)环境下,mysql.slow_log表中的慢日志是否会同步到其他节点。
随着分析的深入,发现 MySQL 实际上提供了多种机制和开关,用于确保操作不会写入 binlog。
由于ROW 格式是目前最常用的 binlog 格式,本文将从ROW 模式下 MySQL 判断操作是否写入 binlog 的实现逻辑入手,逐步引出相关控制开关,并分析它们各自的使用场景。
ROW 格式下判断操作是否写入 binlog 的实现逻辑
在 ROW 格式下,将数据变化记录到 binlog 的核心是在binlog_log_row函数中实现的:
intbinlog_log_row(TABLE *table,constuchar *before_record,
constuchar *after_record, Log_func *log_func){
boolerror =false;
THD *constthd = table->in_use;
// 判断当前操作是否需要写入 binlog
if(check_table_binlog_row_based(thd, table)) {
...
if(likely(!(error = write_locked_table_maps(thd)))) {
boolconsthas_trans = thd->lex->sql_command == SQLCOM_CREATE_TABLE ||
table->file->has_transactions();
// 根据操作类型,将行镜像写入 binlog
error = (*log_func)(thd, table, has_trans, before_record, after_record);
}
}
returnerror ? HA_ERR_RBR_LOGGING_FAILED :0;
}
首先调用check_table_binlog_row_based判断当前操作是否需要写入 binlog,若需要,则会针对不同的操作类型,调用不同的函数来处理。具体来说:
INSERT:Write_rows_log_event::binlog_row_logging_function。
UPDATE:Update_rows_log_event::binlog_row_logging_function。
DELETE:Delete_rows_log_event::binlog_row_logging_function。
接下来,重点看看check_table_binlog_row_based函数的处理逻辑。
