1、mysql slow query log参数设置
首先简单的介绍一下如何开启mysql的slowlog,主要设置一下几个参数:
1)–slow_query_log = 1,开启slowlog。
2)–slow_query_log_file=file_name.,设置slowlog文件存放的地方
3)–long_query_time = 10,定义slow query执行时间的阈值。
4)–min_examined_row_limit ,sql语句执行时间大于long_query_time至少被检查到的次数。
5)–log-output = {file|table}不能为NULL,否则也不能记录慢查询。
还有其他一些slowlog相关的参数,The Slow Query Log
2、如何记录mysql所有执行的sql?
在mysql运维过程中,经常需要分析mysql的全量日志,一般的有两种方法。
1)开启general log。
2)开启slowlog,并设置long_query_time=0,且min_examined_row_limit为0或者1。这两个参数都可以动态设置。
第一种方法很好理解。第二种方案为什么需要这样设置,下面从mysql源码中寻找一下蛛丝马迹。
3、slow query log执行逻辑
其实很多人知道要设置long_query_time参数,但是对 min_examined_row_limit没有多少理解。
先看下下面两个函数
sql/sql_parse.cc中的log_slow_applicable()函数
/*
The following should never be true with our current code base,
but better to keep this here so we don't accidently try to log a
statement in a trigger or stored function
*/
if (unlikely(thd->in_sub_stmt))
DBUG_RETURN(false); // Don't set time for sub stmt
/*
Do not log administrative statements unless the appropriate option is
set.
*/
if (thd->enable_slow_log)
{
bool warn_no_index= ((thd->server_status &
(SERVER_QUERY_NO_INDEX_USED |
SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
opt_log_queries_not_using_indexes &&
!(sql_command_flags[thd->lex->sql_command] &
CF_STATUS_COMMAND));
bool log_this_query= ((thd->server_status & SERVER_QUERY_WAS_SLOW) ||
warn_no_index) &&
(thd->get_examined_row_count() >=
thd->variables.min_examined_row_limit);
bool suppress_logging= log_throttle_qni.log(thd, warn_no_index);
if (!suppress_logging && log_this_query)
DBUG_RETURN(true);
}
DBUG_RETURN(false);
}
sql/sql_class.h中的update_server_status()函数判断sql是否是慢查询。
/**
Update server status after execution of a top level statement.
Currently only checks if a query was slow, and assigns
the status accordingly.
Evaluate the current time, and if it exceeds the long-query-time
setting, mark the query as slow.
*/
void update_server_status()
{
ulonglong end_utime_of_query= current_utime();
if (end_utime_of_query > utime_after_lock + variables.long_query_time)
server_status|= SERVER_QUERY_WAS_SLOW;
}
简单的分析一下mysql的检测和记录mysql slow query log的逻辑。
1)判断是否开启了slowlog
2)not using index检测
3)bool log_this_query用于判断slow log是否记录这种慢查询。
bool表达式转换一下可以发现这种关系。
SERVER_QUERY_WAS_SLOW) && (thd->get_examined_row_count() >= thd->variables.min_examined_row_limit)
需要同时满足两个条件:
1)sql执行时间是否超过long_query_time
2)sql检查到的次数是否大于min_examined_row_limit的次数