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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
日志服务 SLS,月写入数据量 50GB 1个月
简介: slow log判定是否会加上锁等待时间?

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

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

一、前言

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

二、talk is cheap,show me the code

1.slow log判定逻辑:

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版本

其中

res= cur_utime - thd->utime_after_lock

说明:

T2(sql执行完成时间) - T1(获得锁的实际时间) = T(这个得出来的是SQL执行的实际时间),因此res也就是实际的执行时间

根据实际时间与变量的long_query_time比较:

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

1、手工测试案例

环境说明:

img

测试过程

img

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

2、一个比较另类的测试

另类测试

img

slow log输出如下:

# 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的入口是函数

img

insert会调用函数open_tables_for_query

img

open_tables_for_query又会调用open_tables

img

img

跑到这里打开表报错

img

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

img

这里是记录slow log的入口

img

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

img

lock tables会调用mysql_lock_tables

img

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

img

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

res= cur_utime - thd->utime_after_lock

直接由当前时间-0,超过long_query_time就被认定为slow query,也就记录在了slow log当中。

为了便于理解,化成流程图如下:

img

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

参考: xcode源码调试文档

最后,给八怪小小打个广告,八怪专栏《深入理解MySQL主从原理32讲》上线了,想要深入学习MySQL的同学们千万不要错过了,地址:http://t.cn/AilTRbys

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
3月前
|
SQL 关系型数据库 MySQL
|
2月前
|
存储 大数据 数据库
MySQL设计规约问题之为什么要利用pt-query-digest定期分析slow query log并进行优化
MySQL设计规约问题之为什么要利用pt-query-digest定期分析slow query log并进行优化
|
4月前
|
安全 Linux 调度
【后台开发】TinyWebser学习笔记(4)定时器、日志系统(单例模式)、封装互斥锁信号量
【后台开发】TinyWebser学习笔记(4)定时器、日志系统(单例模式)、封装互斥锁信号量
28 1
|
关系型数据库 MySQL
MySQL的Slow Query日志是干什么的?底层原理是什么?
MySQL的Slow Query日志是干什么的?底层原理是什么?
133 0
|
SQL 数据库
FAQ系列 | slow log中出现commit、binlog dump等奇怪的记录
FAQ系列 | slow log中出现commit、binlog dump等奇怪的记录
102 0
|
存储 运维 NoSQL
Slow Log 慢查询日志
什么是 SLOW LOG 1. Slow log 是 Redis 用来记录查询执行时间的日志系统。 2. 查询执行时间指的是不包括像客户端响应(talking)、发送回复等 IO 操作,而单单是执行一个查询命令所耗费的时间。 3. slow log 保存在内存里面,读写速度非常快,因此你可以放心地使用它,不必担心因为开启 slow log 而损害 Redis 的速度。
Slow Log 慢查询日志
|
SQL 数据库
FAQ系列 | slow log中出现commit、binlog dump等奇怪的记录
FAQ系列 | slow log中出现commit、binlog dump等奇怪的记录
|
SQL 数据库
FAQ系列 | slow log中出现commit、binlog dump等奇怪的记录
FAQ系列 | slow log中出现commit、binlog dump等奇怪的记录
|
SQL 关系型数据库 MySQL
MySQL的Slow_log如何记录SQL的MDL锁耗时
MySQL的Slow_log如何记录SQL的MDL锁耗时
1585 0
MySQL的Slow_log如何记录SQL的MDL锁耗时
|
存储 监控 关系型数据库
InnoDB的后台线程(IO线程,master线程,锁监控线程,错误监控线程)和内存(缓冲池,重做日志缓冲池,额外内存池)
InnoDB有多个内存块,你可以认为这些内存块组成了一个大的内存池,负责如下工作: 维护所有进程/线程需要访问的多个内部数据结构。 缓存磁盘上的数据,方便快速地读取,并且在对磁盘文件的数据进行修改之前在这里缓存。
1073 0