慢SQL治理经验总结




在过去两年的工作中,我们团队曾负责大淘宝技术的慢SQL治理工作,作为横向的数据安全治理平台,如何快速准确地发现部门内所有应用的慢SQL,并进行高效的推动治理,同时覆盖多个开发、生产环境,是一个很大的挑战。以下是一些经验分享,我们通过持续的慢SQL推动治理,有效降低了DB相关的线上问题,极大提高了系统稳定性。


关于慢SQL

集团对于慢SQL的定义,执行超过1s的SQL为慢SQL。

慢SQL由于执行时间长,会导致:
  1. 系统的响应时间延迟,影响用户体验
  2. 资源占用增加,增高了系统的负载,其他请求响应时间也可能会收到影响。
  3. 慢SQL占用数据库连接的时间长,如果有大量慢SQL查询同时执行,可能会导致数据库连接池的连接被全部占用,导致数据连接池打满、缓冲区溢出等问题,使数据库无法响应其他请求。
  4. 还有可能造成锁竞争增加、数据不一致等问题

由此可见,需要及时发现和优化慢SQL,对保障系统稳定性是非常重要的。


慢SQL是如何引入的

产生慢SQL的原因可能有很多,以下是一些常见的原因:
  1. 缺乏索引/索引未生效,导致数据库全表扫描,会产生大量的IO消耗,产生慢SQL。
  2. 单表数据量太大,会导致加索引的效果不够明显。
  3. SQL语句书写不当,例如join或者子查询过多、in元素过多、limit深分页问题、order by导致文件排序、group by使用临时表等。
  4. 数据库在刷“脏页”,redo log写满了,导致所有系统更新被堵住,无法写入了。
  5. 执行SQL的时候,遇到表锁或者行锁,只能等待锁被释放,导致了慢SQL。


如何发现慢SQL及高危SQL


  发现慢SQL


执行时常超过1s的为真实存在的慢SQL,阿里集团内部提供了很多可以方便获取应用慢SQL的方法,例如通过TDDL连接数据库,TDDL会将慢SQL日志统一记录到机器的tddl-slow.log文件中。集团内部的数据库服务中心也会提供相关的慢SQL数据查询记录以及接口。

对于外部用户,可以在数据库配置中启用慢查询日志功能,数据库会将执行时间超过一定阈值的慢SQL语句记录到日志中,也可以方便地获取慢查询日志。或者使用其他的数据库性能监控工具、SQL性能分析工具等。


  发现全量SQL


除了执行时长超过1s的慢SQL之外,我们还额外关注了未来可能劣化的慢SQL,这样就需要获取全量SQL,再对其进行分析,筛选出其中风险较大的SQL。我们采取了如下方法:


  • 基于JVM Sandbox进行SQL流水记录的采集


关于JVM Sandbox:「JVM-Sandbox提供动态增强你所指定的类,获取你想要的参数和行信息;提供动态可插拔容器,管理基于JVM-Sandbox的模块。」


简单来说,JVM Sandbox可以动态地将你要实现的代码模板打包编织到目标代码中,实现事件的监听、切入与代码增强。将目标代码的Java方法的调用分解为BEFORE、RETURN和THROWS三个环节,由此在三个环节上引申出对应环节的事件探测和流程控制机制。不仅如此,还有Line事件,可以完成代码行的记录。


// BEFORE-EVENTtry {    /*    * do something...    */
//LINE-EVENT
a();
// RETURN-EVENT return;
} catch (Throwable cause) { // THROWS-EVENT}


jvm-sandbox-repeater是JVM-sandbox生态体系下的重要模块,具备了JVM-Sandbox所有特点, 封装请求录制/回放基础协议,也提供了通用可拓展的丰富API。


repeator模块可以无侵入式地录制HTTP/Java/Dubbo入参/返回值,业务系统无感知。基于这个能力,我们可以方便的采集和SQL执行相关的Java方法参数以及返回值。通过配置采集点,来采集执行sql的java代码的相关方法、参数和返回值,辅助实现sql采集功能。


jvm-sandbox-repeater 地址:https://github.com/alibaba/jvm-sandbox-repeater?spm=ata.21736010.0.0.3e5975362i3rJi

  • 确认采集点


根据对MyBatis源码分析,我们确认了如下采集点:


JVMSandbox完成数据采集后,通过发送metaq消息的方式,与系统进行对话。对于不同种类的采集消息,我们通过不同的字段加以匹配,最终可以获得每一条SQL流水对应的SQL文本、执行时长、sql参数、db名称、ip端口、sql_mapper资源文件等全部信息,具体如图所示:


以上可以采集到应用的全部SQL,量级是很大的。我们采用了Blink创建时间窗口,进行数据聚合,实时数据处理,减少回流的在线数据量,在此就不展开说明了。


  如何识别高危SQL


根据历史慢SQL治理经验,我们把高危SQL分为以下几类:

  1. 不符合集团SQL规约的SQL,可能会埋坑,造成线上问题,影响执行效率等。

  2. 通过对SQL语句分析,发现SQL索引使用不当、造成全表扫描,或者SQL扫描行数过多、出现文件排序等。这种SQL即使当前不是慢SQL,随着表数据量的膨胀,未来也可能发展为慢SQL。

  3. SQL执行时间过长,比较容易理解。对慢SQL来说,执行时间越长,风险越高。


  • SQL规约


集团重点强制SQL规约如下:

  1. 【强制】不要使用count(列名)或count(常量)来替代count(*),count(*)就是SQL92定义的标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关。

  2. 【强制】count(distinct col) 计算该列除NULL之外的不重复数量。注意 count(distinct col1, col2) 如果其中一列全为NULL,那么即使另一列有不同的值,也返回为0。

  3. 【强制】当某一列的值全是NULL时,count(col)的返回结果为0,但sum(col)的返回结果为NULL,因此使用sum()时需注意NPE问题。

  4. 【强制】使用ISNULL()来判断是否为NULL值。

  5. 【强制】对于数据库中表记录的查询和变更,只要涉及多个表,都需要在列名前加表的别名(或表名)进行限定。

  6. 【强制】在代码中写分页查询逻辑时,若count为0应直接返回,避免执行后面的分页语句。

  7. 【强制】不得使用外键与级联,一切外键概念必须在应用层解决。

  8. 【强制】禁止使用存储过程,存储过程难以调试和扩展,更没有移植性。

  9. 【强制】IDB数据订正(特别是删除或修改记录操作)时,要先select,避免出现误删除,确认无误才能提交执行。


我们使用了Druid SQL Parser进行SQL解析,Druid SQL Parser是阿里巴巴的开源项目,可以将SQL语句解析为语法树,可以解析SQL的各个部分,如SELECT语句、FROM语、WHERE语句等,并且可以方便获取SQL语句的结构信息,如表名、列名、操作符等。通过分析SQL,可以轻松判断SQL是否符合规约。


  • SQL索引


SQL explain语句可以提供关于SQL查询执行的详细信息和执行计划,并且可以了解sql的索引使用情 况以及数据访问方式。通过使用Explain语句,可以了解SQL是如何执行的,并且可以看出其可能存在的性能问题。

一个常见的返回结果示例如下:

返回结果解析:


我们重点关注的点如下:

  1. 使用全表扫描,性能最差,即type="ALL"

  2. 扫描行数过多,即rows>阈值

  3. 查询时使用了排序操作,也比较耗时,即Extra包含"Using filesort"

  4. 索引类型为index,代表全盘扫描了索引的数据,Extra信息为Using where,代表要搜索的列没有被索引覆盖,需要回表,性能较差。


以上几点都可能造成SQL性能的劣化,是我们需要额外关注的高风险sql。


如何推动治理慢SQL


作为横向的数据安全治理团队,为了对大淘宝技术部门进行慢SQL治理,我们建立了统一的问题发现-追踪-治理机制。慢SQL治理中涵盖了生产环境、开发环境的慢SQL,区别在于:生产环境中为已经上线的存量慢SQL,开发环境中为新引入的慢SQL,对开发环境引入的慢SQL,修复代价要小于生产环境。接下来分别介绍。


  存量慢SQL治理


存量慢SQL治理的难点在于,历史遗留下的慢SQL可能量级很大,所以要区分慢SQL治理的优先级。我们制定了健康分机制,对SQL分批分级治理。


对慢SQL来说,健康分主要受SQL的执行次数、扫描行数、执行时长影响。另外根据应用中包含慢SQL的数量、平均SQL执行数据等,给应用打出健康分。再根据部门维度汇总,根据应用等级、应用健康分情况等,计算出部门维度的健康分。

整体流程大致如下:


在慢SQL推动治理方面,高危慢SQL,会建立Issue持续追踪,Issue存在超期时间,超期后会影响团队健康分。另外,提供应用维度、部门维度的整体慢SQL风险大盘以及排名,针对重点业务、慢SQL高发团队等,进行集中的推进治理。


  增量慢SQL治理


我们希望增量慢SQL能在上线前得到解决,即分支内不要引入慢SQL或者风险SQL,所以结合3.2和3.3,我们建立了开发环境下增量慢SQL发现机制,并建立发布前卡点能力。整体流程如下:


增量慢SQL的修复代价是小于存量慢SQL的,因此这里我们添加了分支定位的能力。同一应用存在多个同学共同开发的情况,有效的分支定位,可以准确指派慢SQL引入人,实现快速推动治理。这里以git上代码改动为切入点,完成了引入慢SQL的sql_map与修改人之间的关系映射,大致逻辑如下:

a. 监听应用部署消息

b. 获取应用信息,拿到git地址

c. 将本次部署分支与master分支做分支diff

d. 解析sql_map文件,获取本次修改的sql内容

e. 记录被修改sql_id与分支的对应关系

f. 根据sql_id查询对应分支

……


这样就可以精准匹配到增量SQL的引入分支,从而指派到开发者,实现了定向问题指派和追踪,并且可以方便完成分支发布前的管控能力。如果存在增量慢SQL,分支发布,合并到master之前,会触发卡点,需要问题解决才能发布。


  安全生产环境慢SQL治理


安全生产环境(SPE环境),是集团层面为保障线上稳定性的灰度流量生产环境,安全生产环境执行过的慢SQL,在线上流量放大后,可能会对DB造成过大的压力。我们额外新增了安全生产环境慢SQL的管控,作为开发环境下SQL被引入到线上的最后一道防线。


整体方案与上面慢SQL治理方案类似,在此就不赘述了。


总结

慢SQL可能引起很严重的系统性能问题,影响系统可用性和稳定性,因此,及时发现和治理慢SQL是十分重要的。我们建了一套完整的慢SQL发现-分析-推动治理的机制,极大减少了由慢SQL引发的系统问题。同时,在db稳定性上,我们还额外关注数据库CPU使用情况、活跃会话数情况等,建立及时的风险预警和快恢机制,第一时间解决数据库风险。


团队介绍


营销与平台策略技术团队是淘天集团的核心部门之一,负责淘天集团核心用户产品——搜索、拍立淘,并支撑双11、618、年货节等大型活动,百亿补贴、淘宝好价、聚划算等营销产品。通过优惠券、跨店满减、直降、会员卡等多种营销工具的创新和沉淀,基于商品的搜索引擎建设对搜索产品的探索,招商、选品、搭建、投放的活动支撑链路的建设,以平台化、数据化、智能算法等方式支撑了以大淘宝为主的集团核心平台营销场景,全力为淘宝天猫打造有乐趣的购物体验。在这里可以接触到最前沿的人工智能产品和大数据开发体系,在数据和创新驱动下,为数亿用户提供优质服务。
若你对我们的工作内容感兴趣,欢迎加入挑战,简历(研发、前端、测开)投递邮箱:[email protected]




本文分享自微信公众号 - 大淘宝技术(AlibabaMTT)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

JetBrains 发布 Rust IDE:RustRover Java 21 / JDK 21 (LTS) GA 中国这么多 Java 开发者,应该诞生出生态级应用开发框架 .NET 8 性能大幅提升,比 .NET 7 遥遥领先 PostgreSQL 16 发布 Rust 团队前成员深感后悔,要求取消挂名,昨日完成移除 前端新轮子 Nue JS,作者称要打造全新的 Web 生态 网易伏羲回应员工“因 BUG 被 HR 威胁”离世 任正非:我们即将进入第四次工业革命、苹果是华为的老师 Vercel 新产品 "v0":根据文本生成 UI 界面代码
{{o.name}}
{{m.name}}

猜你喜欢

转载自my.oschina.net/u/4662964/blog/10112099