TiDB 慢查询日志分析

导读

TiDB 中的慢查询日志是一项 关键的性能监控工具,其主要作用在于协助数据库管理员追踪执行时间较长的 SQL 查询语句。 通过记录那些超过设定阈值的查询,慢查询日志为性能优化提供了关键的线索,有助于发现潜在的性能瓶颈,优化索引以及重构查询语句,从而提升数据库的整体性能。 本文将主要介绍 TiDB 中慢查询日志的功能,并探讨常用的慢查询日志分析方法 。

本文作者 :王勇,中金公司信息技术部高级架构师,负责中金公司盘古 PaaS 、中间件、数据库规划建设以及公司整体信息技术应用创新、开源治理工作,助力多个投行核心系统国产化落地。

慢查询相关参数

  • tidb_enable_slow_log :用于控制是否开启 slow log 功能。
  • tidb_slow_log_threshold :设置慢日志的阈值,执行时间超过阈值的 SQL 语句将被记录到慢日志中。默认值是 300 ms。
  • tidb_query_log_max_len :设置慢日志记录 SQL 语句的最大长度。默认值是 4096 byte。
  • tidb_redact_log :设置慢日志记录 SQL 时是否将用户数据脱敏用 ? 代替。默认值是 0 ,即关闭该功能。
  • tidb_enable_collect_execution_info :设置是否记录执行计划中各个算子的物理执行信息,默认值是 1 。

慢查询日志原理

TiDB 的慢查询日志原理与 MySQL 一致,在每条 SQL 执行结束时,并且执行时间超过慢日志阈值时,会把 SQL 执行相关信息记录到慢日志中,同样的 SQL 多次执行超过阈值都会记录。

分析慢查询日志

由于 TiDB 是采用存算分离架构的分布式数据库,在这种架构下,每个 TiDB Server 节点都会产生慢日志。为方便查询慢日志,TiDB 提供了内存映射表 INFORMATION_SCHEMA.SLOW_QUERY ,并在 TiDB Dashboard 中提供专门的界面用于搜索和查看慢查询日志。官方文档中也提供了多种常见的慢查询日志查询语句,参考:慢查询日志 ( https://docs.pingcap.com/zh/tidb/v7.1/identify-slow-queries#查询-slow_querycluster_slow_query-示例 )。

然而,在系统高负载或异常情况下,短时间内生成过多慢 SQL 导致慢 SQL 变得难以分析,这也是像 MySQL 等数据库提供慢日志分析工具的原因,例如 mysqldumpslow 、 pt-query-digest 等工具。这些工具通常以某种聚合的方式输出结果,使结果更加清晰易懂。借鉴这些工具的思路,笔者开发了一条常用的慢日志分析 SQL,以更便捷地处理慢查询日志。

1 慢日志聚合查询 SQL

-- 慢查询日志,聚合查询
WITH ss AS
(SELECT s.Digest ,s.Plan_digest,
count(1) exec_count,
sum(s.Succ) succ_count,
round(sum(s.Query_time),4) sum_query_time,
round(avg(s.Query_time),4) avg_query_time,
sum(s.Total_keys) sum_total_keys,
avg(s.Total_keys) avg_total_keys,
sum(s.Process_keys) sum_process_keys,
avg(s.Process_keys) avg_process_keys,
min(s.`Time`) min_time,
max(s.`Time`) max_time,
round(max(s.Mem_max)/1024/1024,4) Mem_max,
round(max(s.Disk_max)/1024/1024,4) Disk_max,
avg(s.Result_rows) avg_Result_rows,
max(s.Result_rows) max_Result_rows,
sum(Plan_from_binding) Plan_from_binding
FROM information_schema.cluster_slow_query s
WHERE s.time>=adddate(now(),INTERVAL -1 DAY)
AND s.time<=now()
AND s.Is_internal =0
-- AND UPPER(s.query) NOT LIKE '%ANALYZE TABLE%'
-- AND UPPER(s.query) NOT LIKE '%DBEAVER%'
-- AND UPPER(s.query) NOT LIKE '%ADD INDEX%'
-- AND UPPER(s.query) NOT LIKE '%CREATE INDEX%'
GROUP BY s.Digest ,s.Plan_digest
ORDER BY sum(s.Query_time) desc
LIMIT 35)
SELECT ss.Digest,         -- SQL Digest
ss.Plan_digest,           -- PLAN Digest
(SELECT s1.Query FROM information_schema.cluster_slow_query s1 WHERE s1.Digest=ss.digest AND s1.time>=ss.min_time AND s1.time<=ss.max_time LIMIT 1) query,  -- SQL文本
(SELECT s2.plan FROM information_schema.cluster_slow_query s2 WHERE s2.Plan_digest=ss.plan_digest AND s2.time>=ss.min_time AND s2.time<=ss.max_time LIMIT 1) plan, -- 执行计划
ss.exec_count,            -- SQL总执行次数
ss.succ_count,            -- SQL执行成功次数
ss.sum_query_time,        -- 总执行时间(秒)
ss.avg_query_time,        -- 平均单次执行时间(秒)
ss.sum_total_keys,        -- 总扫描key数量
ss.avg_total_keys,        -- 平均单次扫描key数量
ss.sum_process_keys,      -- 总处理key数量
ss.avg_process_keys,      -- 平均单次处理key数量
ss.min_time,              -- 查询时间段内第一次SQL执行结束时间
ss.max_time,              -- 查询时间段内最后一次SQL执行结束时间
ss.Mem_max,               -- 单次执行中内存占用最大值(MB)
ss.Disk_max,              -- 单次执行中磁盘占用最大值(MB)
ss.avg_Result_rows,       -- 平均返回行数
ss.max_Result_rows,       -- 单次最大返回行数
ss.Plan_from_binding      -- 走SQL binding的次数
FROM ss;

这条 SQL 是笔者常用的一条慢查询分析语句,大家可以根据个人需要灵活地调整排序字段、查询字段和查询条件,以满足不同场景下的分析需求。

在这个 SQL 中,query 和 plan 字段是使用标量子查询的方式获取。经过测试,这种写法相比直接使用 group by,能够节省大量内存,所以能够分析更长时间段的慢查询。

既然是聚合查询,为什么不直接用 statements_summary_history 表呢?笔者觉得有三点原因,一是 statements_summary_history 由于本身是半小时的聚合数据,在应对短时间段的性能分析时可能不够精细。二是早期版本的 statements_summary_history 是纯内存表,可能由于 TiDB Server OOM 重启而导致数据丢失,而慢查询日志是存储在文件中的,因此 TiDB Server OOM 重启不会导致慢查询日志丢失。三是 statements_summary_history 有容量限制,记录的 SQL 可能被驱逐出去,而慢查询日志默认记录超过 300 毫秒的查询,已满足分析需求了。

2 单条 SQL 执行历史

SELECT 
date_format(adddate(s.Time,interval - s.Query_time second),'%Y-%m-%d %H') sql_exec_start,
count(1) exec_cnt,
sum(s.Succ) succ_cnt,
count(distinct s.Plan_digest) plan_cnt,
case when count(distinct s.Plan_digest)<5 then group_concat(distinct substr( s.Plan_digest,1,4)) else null end plan_digest,
round(sum(s.Query_time),4) sum_q_time,
round(avg(s.Query_time),4) avg_q_time,
sum(s.Total_keys) sum_t_keys,
round(avg(s.Total_keys),4) avg_t_keys,
sum(s.Process_keys) sum_p_keys,
avg(s.Process_keys) avg_p_keys,
round(max(s.Mem_max/1024/1024),2) Mem_max_m,
round(max(s.Disk_max/1024/1024),2) Disk_max_m,
round(avg(s.Result_rows),4) avg_rows,
max(s.Result_rows) max_rows,
sum(Plan_from_binding) PFB
from information_schema.cluster_slow_query s
where s.digest='a0adeeb79b71315ac13a77f3f11162106b5ec7b48212cf17c20c754263ab9228'
and time>=adddate(now(),interval -3 day)
and time<=now()
group by date_format(adddate(s.Time,interval - s.Query_time second),'%Y-%m-%d %H')
order by 1 desc;

这条 SQL 是笔者常用的另一条慢查询分析语句,用于分析单个 SQL 的历史执行情况。通过这个查询,可以清晰地了解特定 SQL 在历次执行中的变化,包括执行计划、扫描数据量、执行时间等方面的情况。

收集慢查询日志脚本

这个脚本用于生成 HTML 格式的慢日志分析结果,结合定时任务和 Nginx 的自动索引功能,可以轻松地收集和查看各个 TiDB 集群的慢日志。

脚本请在这个链接取: https://asktug.com/t/topic/1022684

效果展示:

总结

本文阐述了 TiDB 慢查询日志的相关配置和原理,并分享了笔者在实际工作中使用的慢查询日志分析 SQL。为读者提供了一种实际而有效的慢查询日志分析思路。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/798955.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

libVLC 音频立体声模式切换

在libVLC中&#xff0c;可以使用libvlc_audio_set_channel函数来设置音频的立体声模式。这个函数允许选择不同的音频通道&#xff0c;例如立体声、左声道、右声道、环绕声等。 /*** Set current audio channel.** \param p_mi media player* \param channel the audio channel…

Java | Leetcode Java题解之第16题最接近的三数之和

题目&#xff1a; 题解&#xff1a; class Solution {public int threeSumClosest(int[] nums, int target) {Arrays.sort(nums);int n nums.length;int best 10000000;// 枚举 afor (int i 0; i < n; i) {// 保证和上一次枚举的元素不相等if (i > 0 && nums…

【精品整理】最新数据安全评估标准合集

最新数据安全评估标准合集&#xff0c;以下是资料的目录&#xff0c;共12份。如需下载&#xff0c;请前往星球查阅和获取&#xff1a;https://t.zsxq.com/18JrHhWtQ 1、网络安全标准实践指南 2、数据安全风险评估方法 3、个人信息安全影响评估指南 4、数据出境安全评估指南 5、…

HAL STM32 定时器PWM DMA输出方式

HAL STM32 定时器PWM DMA输出方式 &#x1f9e8;遗留问题&#xff1a;当配置RCR重复计数器&#xff0c;配置为2时&#xff0c;在定义了3组PWM参数情况下&#xff0c;只能输出第二组参数的PWM波形。&#xff08;HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, aCCValue_Buff…

模块化——如何导入模块?(内置模块与自定义模块)

在Node.js中&#xff0c;要导入另一个模块&#xff0c;我们可以使用require函数。这个函数接受一个文件路径参数&#xff0c;并返回导入的模块。 一、require使用注意事项&#xff1a; (1)自己创建的模块&#xff0c;导入时建议写相对路径&#xff0c;不能省略./和../ //我把…

golang web 开发 —— gin 框架 (gorm 链接 mysql)

目录 1. 介绍 2. 环境 3. gin 3.1 gin提供的常见路由 3.2 gin的分组 main.go router.go 代码结构 3.3 gin 提供的Json方法 main.go route.go common.go user.go order.go 3.4 gin框架下如何获取传递来的参数 第一种是GET请求后面直接 /拼上传递的参数 第二种是…

【Lavavel框架】——各目录作用的介绍

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

css anminate 加载中三个点点动态出现

期待效果&#xff1a; 核心代码&#xff1a; css3 anminate方法 //html <div>加载中<span id"dot">...</span></div>//css <style>   #dot {display: inline-block;width: 1.5em;vertical-align: bottom;overflow: hidden;animati…

xilinx 7系列fpga上电配置

一、前言 Xilinx FPGA通过加载比特流到内部存储单元来进行配置。 Xilinx FPGA存在两种数据配置路径&#xff0c;一种是满足最小引脚需求的串行路径&#xff0c;一种是可用8位、16位或32位来连接到行业的高性能通用接口&#xff0c;如处理器&#xff0c;8位或者16位并行的闪存…

在linux服务器上安装anaconda

遇到问题&#xff1a; 在linux服务器中查看当前有哪些虚拟环境&#xff0c;conda环境用不了&#xff0c;anaconda没有安装&#xff0c;所以要在linux服务器中安装虚拟环境 解决步骤如下&#xff1a; 1.首先下载anaconda的Linux版本的安装包 方法1&#xff1a;官网下载&#…

【蓝桥杯嵌入式】Cubemx新建工程引脚配置与点亮LED

【蓝桥杯嵌入式】Cubemx新建工程引脚配置与点亮LED cubemx基础配置LED 引脚配置按键配置按键引脚配置定时器扫描配置 工程管理配置点亮LED程序设计keil配置与程序下载 参考博文1&#xff1a;STM32 | 利用STM32CubeMX初始化一个STM32工程 参考博文1&#xff1a;点亮LED灯&#x…

【C#】版本号

&#x1f4bb; 代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace ConsoleApp16 {internal class Program{static void Main(string[] args){Version version01 new Version("4.0.0…

Web后端搭建

目录 一 搭建服务器端 1.1安装服务器软件 1.2检查环境是否配置 1.3安装Tomcat 二 创建并发Web项目 2.1创建一个java项目 三 创建Servlet 前端程序如何才能访问到后端程序呢&#xff0c;这时候我们就需要web服务器来解决&#xff1a;将后端程序部署到服务器中&#xff0c…

计算机网络实验——学习记录四(TCP协议)

1. 打开TCP服务&#xff1a; nc -e /bin/sh -lv 4499 注释&#xff1a; &#xff08;1&#xff09;nc是Linux下启动通讯服务的命令&#xff1b; &#xff08;2&#xff09;-e表示在nc命令后再执行bin文件夹下的shell命令&#xff0c;启动shell命令会导致所有从TCP连接传递到…

【JavaScript】原型链/作用域/this指针/闭包

1.原型链 参考资料&#xff1a;Annotated ES5 ECMAScript起初并不支持如C、Smalltalk 或 Java 中“类”的形式创建对象&#xff0c;而是通过字面量表示法或者构造函数创建对象。每个构造函数都是一个具有名为“prototype”的属性的函数&#xff0c;该属性用于实现基于原型的继…

【Java+Springboot】------ 通过JDBC+GetMapping方法进行数据select查询、多种方式传参、最简单的基本示例!

一、JDBC如何使用、PostGresql数据库 1、在pom.xml 先引用jdbc组件。 <!--jdbc--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency> 2、在pom.xml 再引用p…

嵌入式Linux驱动开发——汇编点灯

嵌入式Linux驱动开发——汇编点灯 本文章开始记录学习嵌入式Linux的过程&#xff0c;使用的开发板是正点原子的阿尔法&#xff0c;以及左老师的书籍和视频。然后这个系列不会介绍基础知识&#xff08;书上都有&#xff09;&#xff0c;主要是记录思考过程以及需要注意的点。 代…

Ceph学习 -3.存储简介

文章目录 1.存储简介1.1 存储类型1.1.1 储备知识1.1.2 三种存储1.1.3 块存储1.1.4 文件存储1.1.5 对象存储1.1.6 三种存储之间的关系1.1.7 总结 1.2 Ceph简介1.2.1 官方介绍1.2.2 软件特点1.2.3 基本结构1.2.4 应用场景 1.3 小结 1.存储简介 学习目标&#xff1a;这一节&#x…

抖音引流私域转化模式1.0现场视频,从抖音源源不断把人加到私域买单

抖音-引流私域转化模式1.0现场视频&#xff0c;从抖音源源不断把人加到私域&#xff0c;让加到私域的粉丝买单 课程内容&#xff1a;抖音引流私域转化模式1.0现场视频&#xff0c;从抖音源源不断把人加到私域买单 - 百创网-源码交易平台_网站源码_商城源码_小程序源码 01.第一…

Python | Leetcode Python题解之第16题最接近的三数之和

题目&#xff1a; 题解&#xff1a; class Solution:def threeSumClosest(self, nums: List[int], target: int) -> int:nums.sort()n len(nums)best 10**7# 根据差值的绝对值来更新答案def update(cur):nonlocal bestif abs(cur - target) < abs(best - target):best…