前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >slow log判定是否会加上锁等待时间?

slow log判定是否会加上锁等待时间?

作者头像
用户1278550
发布2019-07-30 16:20:25
9080
发布2019-07-30 16:20:25
举报
文章被收录于专栏:idba

作者徐晨亮,MySQL DBA,热衷于数据库优化,自动化运维及数据库周边工具开发,对MySQL源码有一定的兴趣.

一 前言

对MySQL DBA而言,我们经常遇到 slow log,本文通过源码和案例实践来抽丝剥茧,slow log判定是否会加上锁等待时间?

二 talk is cheap,show me the code

1.slow log判定逻辑:
代码语言:javascript
复制
static ulonglong get_query_exec_time(THD *thd, ulonglong cur_utime)
{
  ulonglong res;

#ifndef DBUG_OFF
  if (thd->variables.query_exec_time != 0)
    res= thd->lex->sql_command != SQLCOM_SET_OPTION ?
      thd->variables.query_exec_time : 0;
  else
#endif
    res= cur_utime - thd->utime_after_lock;

  if (res > thd->variables.long_query_time)
    thd->server_status|= SERVER_QUERY_WAS_SLOW;
  else
    thd->server_status&= ~SERVER_QUERY_WAS_SLOW;

  return res;
}

以上代码来自于percona 5.7.23版本 其中

代码语言:javascript
复制
res= cur_utime - thd->utime_after_lock

说明:T2(sql执行完成时间) - T1(获得锁的实际时间) = T(这个得出来的是SQL执行的实际时间),因此res也就是实际的执行时间。根据实际时间与变量的long_query_time比较:

超过long_query_time,那么判定为slow query 否则就不是

三 手工测试案例

环境说明:

参数

value

long_query_time

0.1

min_examined_row_limit

0

log_queries_not_using_indexes

OFF

3.1 测试过程

session1

session2

begin;select * from t1 where id=1 for update;

-

select * from t1 where id=1 for update;

rollback;

-

1 row in set (9.61 sec)

此时,并没有记录到slow log,也符合源码中的定义

3.2 一个比较另类的测试

session1

session2

flush tables with read lock;

Query OK, 0 rows affected (0.00 sec)

-

select * from tx;

-

Table 'xucl.tx' doesn't exist

-

insert into tx values(1);

几秒后

unlock tables;

Query OK, 0 rows affected (0.00 sec)

-

ERROR 1146 (42S02): Table 'xucl.tx' doesn't exist

slow log输出如下:

代码语言:javascript
复制
# Time: 2019-07-05T04:27:42.785888Z
# User@Host: root[root] @ localhost []  Id:  3129
# Query_time: 12.035846  Lock_time: 0.000000 Rows_sent: 0  Rows_examined: 0
SET timestamp=1562300862;
insert into tx values(1);

神奇的是竟然记录到了slow log里面,下面根据debug到的源码进行说明这个问题

insert SQL的入口是函数

insert会调用函数open_tables_for_query

open_tables_for_query又会调用open_tables

跑到这里打开表报错

到这里SQL完成,返回给客户端信息

这里是记录slow log的入口

正常情况下,如果表存在那么会对表进行加锁

lock tables会调用mysql_lock_tables

mysql_lock_tables函数末尾会设置after_lock时间戳,也就是前面提到的utimeafter_lock

由于在打开表的时间就报错了,所以utime_after_lock即为0,这样根据公式

代码语言:javascript
复制
res= cur_utime - thd->utime_after_lock

直接由当前时间-0,超过long_query_time就被认定为slow query,也就记录在了slow log当中。为了便于理解,画成流程图如下:

最后,感谢高鹏老师的指点,尤其是入口函数的指点及思路分析。

参考 xcode源码调试文档

-The End-

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 yangyidba 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 前言
  • 二 talk is cheap,show me the code
    • 1.slow log判定逻辑:
    • 三 手工测试案例
      • 3.1 测试过程
        • 3.2 一个比较另类的测试
        相关产品与服务
        云数据库 SQL Server
        腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档