慢SQL治理分享

简介: 这里的慢SQL指的是MySQL慢查询,是运行时间超过long_query_time值的SQL。真实的慢SQL通常会伴随着大量的行扫描、临时文件排序或者频繁的磁盘flush,直接影响就是磁盘IO升高,让正常的SQL变成了慢SQL,大面积执行超时。本文将和大家分享慢SQL的治理过程。

image.png

作者 | 史伟民
来源 | 阿里技术公众号

一 为什么要做这个事情

1 什么是慢SQL?

这里指的是MySQL慢查询,具体指运行时间超过long_query_time值的SQL。

我们常听常见的MySQL中有二进制日志binlog、中继日志relaylog、重做回滚日志redolog、undolog等。针对慢查询,还有一种慢查询日志slowlog,用来记录在MySQL中响应时间超过阀值的语句。

大家不要被慢查询这个名字误导,以为慢查询日志只会记录select语句,其实也会记录执行时间超过了long_query_time设定的阈值的insert、update等DML语句。

# 查看慢SQL是否开启
show variables like "slow_query_log%";# 查看慢查询设定的阈值 单位:秒
show variables like "long_query_time";

对于我们使用的AliSQL-X-Cluster即XDB来说,默认慢查询是开启的,long_query_time设置为1秒。

2 慢查询为何会导致故障?

真实的慢SQL往往会伴随着大量的行扫描、临时文件排序或者频繁的磁盘flush,直接影响就是磁盘IO升高,正常SQL也变为了慢SQL,大面积执行超时。

去年双11后,针对技术侧暴露的问题,菜鸟CTO线推出多个专项治理,CTO-D各领一项作为sponsor,我所在的大团队负责慢SQL治理这个专项。

二 要做到什么程度

1 怎么来衡量一个应用的慢SQL严重程度?

微平均

sum(aone应用慢SQL执行次数)
-----------------------
sum(aone应用SQL执行次数)

我们认为,该值越大,影响越大;该值越小,影响可能小。

极端情况就是应用里每次执行的SQL全是慢SQL,该值为1;应用里每次执行的SQL全不是慢SQL,该值为0。

但是这个指标带来的问题是区分度不佳,尤其是对SQL QPS很高且大多数情况下SQL都不是慢查询的情况,偶发的慢SQL会被淹没。

另外一个问题,偶发的慢SQL是真的慢SQL吗?我们遇到很多被慢查询日志记录的SQL,实际上可能受到其他慢SQL影响、MySQL磁盘抖动、优化器选择等原因使得常规查询下表现显然不是慢SQL的变成了慢SQL。

宏平均

sum(慢SQL 1执行次数)    sum(慢SQL n执行次数)
-----------------  +  ------------------
sum(SQL 1执行次数)      sum(SQL n执行次数)
---------------------------------------n

这个算法建立在被抓到的慢SQL有一定执行次数的基础上,可以减少假性慢SQL的影响。

当某些应用QPS很低,即一天执行SQL的次数很少,如果碰到假性SQL就会引起统计误差。

执行次数

sum(aone应用慢SQL执行次数)
-----------------------7

统计最近一周平均每天的慢SQL执行次数,可以消除掉宏平均带来的假性SQL问题。

慢SQL模板数量

以上维度均有个时间限定范围,为了追溯慢SQL历史处理情况,我们还引入了全局慢SQL模板数量维度。

count(distinct(aone应用慢SQL模板) )

2 目标

  • 核心应用:解决掉所有的慢SQL
  • 普通应用:微平均指标下降50%

3 CTO报表

以CTO-D为单位根据以上多维度指标统计汇总应用的加权平均,由低到高得出排名,突出头尾top3,每周播报。

三 为什么由我来做

猜测可能与我的背景有关,有C/C++背景,曾在上家公司负责过公司层面异地多活架构的设计和落地,对于MySQL比较了解一些。

另外可能是利益无关,我所在小团队业务刚起步,不存在慢SQL,这样可以插入到各个业务线去。

四 行动支撑

1 集团MySQL规约

索引规约摘录部分:

【强制】超过三个表禁止join。需要join的字段,数据类型保持绝对一致;多表关联查询时,保证被关联的字段需要有索引。

说明:即使双表join也要注意表索引、SQL性能。

【强制】在varchar字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度。

说明:索引的长度与区分度是一对矛盾体,一般对字符串类型数据,长度为20的索引,区分度会高达90%以上,可以使用count(distinct left(列名, 索引长度))/count(*)的区分度来确定。

【强制】页面搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决。

说明:索引文件具有B-Tree的最左前缀匹配特性,如果左边的值未确定,那么无法使用此索引。

【推荐】防止因字段类型不同造成的隐式转换,导致索引失效。

【参考】创建索引时避免有如下极端误解:

1) 索引宁滥勿缺

认为一个查询就需要建一个索引。

2) 吝啬索引的创建

认为索引会消耗空间、严重拖慢更新和新增速度。

3) 抵制唯一索引

认为唯一索引一律需要在应用层通过“先查后插”方式解决。

2 DB变更标准

DDL需要控制变更速度,注意灰度和并发控制,变更发布需要在规定的变更发布窗口内。

五 分享一些我参与优化的例子

1 数据分布不均匀

image.png
image.png

1)分库分表不合理

该业务数据分了8个库,每个库分了16张表,通过查看表空间可以看到数据几乎都分布在各个库的某2张表中。分库分表的策略有问题,另外过高预估了业务增量,这个持保留意见。

2)索引不合理

单表创建了idx_logistics_corp_id_special_id的联合索引,但即便这样区分度依然太低,根据实验及业务反馈(logistics_corp_id,transport_type_id)字段组合区分度非常高,且业务存在transport_type_id的单查场景。

image.png

2 索引问题

SELECTCOUNT(0) AS `tmp_count`
FROM(SELECT`table_holder`.`user_id`,`table_holder`.`sc_item_id`,SUM(CASE`table_holder`.`inventory_type`WHEN 1 THEN `table_holder`.`quantity`ELSE 0END) AS `saleable_quantity`,SUM(CASE`table_holder`.`inventory_type`WHEN 1 THEN `table_holder`.`lock_quantity`ELSE 0END) AS `saleable_lock_quantity`,SUM(CASE`table_holder`.`inventory_type`WHEN 401 THEN `table_holder`.`quantity`ELSE 0END) AS `transfer_on_way_quantity`,`table_holder`.`store_code`,MAX(`table_holder`.`gmt_modified`) AS `gmt_modified`FROM`table_holder`WHERE(`table_holder`.`is_deleted` = 0)AND(`table_holder`.`quantity` > 0)AND `table_holder`.`user_id` IN(3405569954)AND `table_holder`.`store_code` IN('ZJJHBHYTJJ0001', '...1000多个')GROUP BY`table_holder`.`user_id`,`table_holder`.`sc_item_id`ORDER BY`table_holder`.`user_id` ASC,`table_holder`.`sc_item_id` ASC) `a`;

这个case对应的表有store_code索引,因此认为没问题,没办法优化了。实则通过执行计划,我们发现MySQL选择了全表扫描。针对该case实践发现,当范围查询的个数超过200个时,索引优化器将不再使用该字段索引。

最终经过拉取最近一段时间的相关查询SQL,结合业务的数据分布,我们发现采用(is_deleted,quantity)即可解决。

判断执行计划采用的索引长度:key_len的长度计算公式(>=5.6.4)

char(10)允许NULL      =  10 * ( character set:utf8mb4=4,utf8=3,gbk=2,latin1=1) + 1(NULL)
char(10)不允许NULL    =  10 * ( character set:utf8mb4=4,utf8=3,gbk=2,latin1=1)
varchr(10)允许NULL    =  10 * ( character set:utf8mb4=4,utf8=3,gbk=2,latin1=1) + 1(NULL) + 2(变长字段)
varchr(10)不允许NULL  =  10 * ( character set:utf8mb4=4,utf8=3,gbk=2,latin1=1) + 2(变长字段)
int允许NULL           =  4 + 1(NULL)
int不允许NULL         =  4
timestamp允许NULL     =  4 + 1(NULL)
timestamp不允许NULL   =  4
datatime允许NULL      =  5 + 1(NULL)
datatime不允许NULL    =  5

3 被人影响

用到了索引却依然被爆出扫描2千万行:

image.png

索引字段区分度很高:

image.png

同时期常规SQL变为了慢查询:

image.png

DB数据盘访问情况:

image.png

排查共用物理机其他实例的情况,发现有个库在问题时间附近有很多慢sql需要排序,写临时文件刚好写入了2GB:

image.png

多个MySQL实例leader节点混合部署在同一台物理机,虽然通过docker隔离了CPU、MEM等资源,但目前还没有做到buffer io的隔离。

image.png

4 无法解决

通过汇总分析高频的查询并结合业务得出合适的索引往往能够解决日常遇到的慢查询,但这并不是万能的。

比如有可能索引越加越多,乃至成了这样:

image.png

有些场景,比如支持多个字段组合查询,又没有必填项,如果都要通过索引来支持显然是不合理的。

image.png

查询场景下,将区分度较高的字段设定为必填项是个好习惯;查询组合很多的情况下考虑走搜索支持性更好的存储或者搜索引擎。

六 日常化处理

随着各个CTO-D线的深入治理,各项指标较之前均有非常大的改观,比如核心应用完成慢查询清零,影响最大的一些慢SQL被得以解决,而我所在的团队排名也由最初的尾部top3进入到头部top3。

慢SQL治理进入日常化,通过每周固定推送慢SQL工单、owner接手处理、结单,基本形成了定期清零的习惯和氛围,慢SQL治理专项也被多次点名表扬。

七 小结

这是一篇迟到的总结,现在回头看觉得这里面的策略制定、问题分析和解决的过程还是蛮值得拿出来和大家分享下。

原文链接
本文为阿里云原创内容,未经允许不得转载。

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

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

相关文章

英特尔表示:元宇宙的路还很长

编译 | 禾木木出品 | CSDN云计算(ID:CSDNcloud)现在每个人都在谈论元宇宙,各大公司也都在致力于访问它的硬件,而且它似乎最终可能成为万维网规模的下一个主要通信平台。但如果你问的话,「最终」还是有很长的…

java csv 追加_如何在Java中添加一个包含CSV数据的列

基于plirke示例代码和他的帮助,我编写了一个最终的工作代码。在这里分享它,这样它可能对有类似需求的人有用。import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.io.IOExcep…

案例|自建or现成工具?小型创业团队敏捷研发探索

简介: 实践和踩坑建议。 我是刘永良,是一名全栈开发者也是一名创业者,来自济南——一个目前被称为互联网洼地的地方。2020年4月和三位志同道合的朋友,在济南共同创建了山东旷野网络科技有限公司,主要从事自有项目和外包…

代码智能技术如何应用到日常开发?

简介: 原理与演示。 01/ 从开发者的烦恼说起 开发者在编写代码时,需要花费大量时间在低层次的重复编码上,特别是针对一些语法比较冗余的开发语言。 同时,开发者经常被戏称为面向搜索引擎编程,因为我们经常需要通过…

sql server tcp 信号灯超时时间已到_「图文详解」TCP为啥要3次握手和4次挥手?3次挥手不行吗?...

原文链接:https://www.cnblogs.com/qdhxhz/p/8470997.htmlTCP有6种标示:SYN(建立联机) ACK(确认) PSH(传送) FIN(结束) RST(重置) URG(紧急)一、TCP三次握手第一次握手客户端向服务器发出连接请求报文,这时报文首部中的同部位SYN1,同时随机生…

F5:2022年应用交付和安全领域趋势展望

作者 | F5中国区金融事业部技术总监兼安全事业部副总经理 陈亮 出品 | CSDN 云计算 随着人工智能(AI)、物联网 (IoT)等技术的日益普及,企业拥抱互联网技术的程度不断提高,越来越多的企业开始考虑利用数字化来提升劳动生产率和利用电子商务扩…

java的class文件在哪里_传统上,你在哪里存储Java .class文件?

如果你不熟悉它,你应该研究Java classpath的主题.我记得当我第一次开始用Java编程时发现这个令人困惑.Java中有.class文件的定义搜索路径;当你运行设置类路径的java -cp blahblahblah时. java -jar blahblahblah.jar打开一个JAR file,.jar文件的清单可以指示类路径.默认的类路径…

DevOps 能力提升模型

简介: DevOps 能力反映的是技术研发响应业务变化的能力。随着组织规模的增加和业务复杂性增长,DevOps 能力会变得越来越重要。持续提升 DevOps 的能力成为技术研发的共同挑战。 编者按:本文源自阿里云云效团队出品的《阿里巴巴DevOps实践指南…

生态和场景一站式集成?来看看小程序的“共享主义”

简介: mPaaS 小程序市场正式上线,海量小程序一站式集成,用场景拉高终端活跃水位。 01 小程序破壁计划 从 2018 年「支付宝」将支付宝小程序全量开放给用户使用开始,整个小程序生态市场发生了新一波的震荡。 小程序商家通过「支付…

python sanic orm_基于sanic的微服务框架 - 架构分析

感谢songcser分享的《基于sanic的微服务基础架构》https://github.com/songcser/sanic-ms最近正在学习微服务,发现这个repo不错,但不完整,跑不起来。所以学习了一下源码,实际使用Docker部署成功,本文记录实现过程。学习…

拒做背锅侠!如何利用网站性能优化驱动产品体验提升

简介: 对于运维工程师而言,如果要票选五大最抓狂运维支撑场景,花样繁多的各种促销活动一定榜上有名。每个促销季上线都是忐忑不安的不眠夜。大量内容更新、大量客户涌入,大量数据读写,虽有着各种技术方案或工具服务保障…

阿里云飞天论文获国际架构顶会 ATC 2021最佳论文:全球仅三篇

简介: 近日,计算机系统结构国际顶级学术会议 USENIX ATC在线上举行。ATC 始办于1992年,是由USENIX组织的计算机系统领域的顶级会议,至今已成功举办31届,计算机系统领域中Oak语言(JAVA语言的前身&#xff09…

Quorum 和唱票那回事

作者 | 奇伢来源 | 奇伢云存储关于 Quorum 的两个维度前几回说了那么多框架,设计思想的文章。今天分享一个很小的点,etcd 的 quorum 是怎么实现的?Quorum 机制本质就是一个关于多数派的事情,这个多数派应用的有两个方面&#xff1…

java 迷你桌面地图_求教贴,Java桌面小游戏的地图怎么做

展开全部小游戏地e5a48de588b63231313335323631343130323136353331333365656566图一般都是各种图片的拼接,然后保存到2维数组里面比如//数值常量public static final int EMPTY0;//空地什么也没有public static final int BRICK1;//土墙public static final int STONE2;//石头p…

python相对引用_Python 模块相对引用

文件结构如下python_directory/├── __init__.py└── app├── __init__.py├── sub1│ ├── __init__.py│ └── mod1.py└── sub2├── __init__.py├── mod2.py除了 mod1.py,其他文件内容都为空。mod1.pyprint(__name__: {}.format(__name__…

快速界定故障:Socket Tracer网络监控实践

简介: Socket Tracer定位是传输层(Socket&TCP)的指标采集工具,通过补齐网络监控的这部分盲区,来达到快速界定网络问题的目标。 作者 | 四忌 来源 | 阿里技术公众号 一 背景 随着软件应用的集群化、容器化、微服务化,产品的…

剑指企业级云原生,阿里云 CNFS 如何破局容器持久化存储困境

简介: 云原生趋势下,应用容器化比例正在快速增长,Kubernetes 也已成为云原生时代新的基础设施。 据 Forrester 预测,到 2022 年, 全球企业及组织在生产环境运行容器化应用。观察今天的容器和 Kubernetes 的应用现状&am…

Log4j 第三次发布漏洞补丁,漏洞或将长存

整理 | 郑丽媛、禾木木出品 | CSDN这几天,Apache Log4j 2 绝对是众多 Java 程序员提到的高频词之一:由于 Apache Log4j 2 引发的严重安全漏洞,令一大批安全人员深夜修 Bug、打补丁。此次漏洞更是因为其触发简单、攻击难度低、影响人群广泛等特…

mysql 常见密码设置_设置mysql用户密码(5.6/5.7)、远程连接数据库、常用命令

注: 以上命令均需要在mysql下执行;在mysql中每行命令末尾加上分号,表示该行命令执行结束。 tb_name即table name()表名。示例:[rootcentos-01inux mysql]# mysql -uroot -p123456Warning: Using a password on the command line i…

二分法求数组最大最小_js-求数组的最大值和最小值

取出数组中的最大值或者最小值是开发中常见的需求,但你能想出几种方法来实现这个需求呢?Math.maxJavaScript 提供了 Math.max 函数返回一组数中的最大值,用法是:Math.max([value1[,value2, ...]])值得注意的是:如果有任…