Skip to content

面试速答(先看这里)

**一句话结论:**以上日志我做了简单的脱敏,其中最重要的就是这句:

60秒标准回答:

我们有一个定时任务,是做扫表的,但是最近经常出现定时任务扫表处理失败的报警,登录到机器上之后,发现有数据库层面的报错

以上日志我做了简单的脱敏,其中最重要的就是这句

这是一个数据库查询执行过程中的错误信息,通常在数据库系统中会出现。 这个错误消息表示数据库查询中的排序操作被中断或终止了

**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点

回答主线:

  • **要点1:**我们有一个定时任务,是做扫表的,但是最近经常出现定时任务扫表处理失败的报警,登录到机器上之后,发现有数据库层面的报错:
  • **要点2:**这个问题的发生,一般来说有几个原因:
  • **要点3:**1、慢SQL导致查询超时,这时候就会为了避免数据库链接被长时间占用而中断此次查询
  • **要点4:**主要就是以上这三个原因,接下来我们分析了一下导致失败的SQL 语句,这个语句在上面的ERROR日志打印的同时就已经给打印出来了,我隐藏了一些无关紧要的内容,大致SQL如下:
  • **要点5:**想要使用到索引进行排序,就需要建立一个subject_id_enum, subject_id两个字段的联合索引,但是又要兼顾where条件的查询性能。

**记忆锚点:**risk_case_status_enum → subject_id → SQL → subject_id_enum → product_type_enum → where

关键取舍:

  • 这个问题的发生,一般来说有几个原因: 1、慢SQL导致查询超时,这时候就会为了避免数据库链接被长时间占用而中断此次查询 2、查询被手动终止,数据库管理员手动中止正在执行的查询操作也会出现这个异常 3、资源不足,查询排序操作可能需要大量的计算和内存资源,如果数据库服务器的资源不足以执行排序操作,那么查询可能会被中断。
  • 那么,首先想到的优化方式就是提升这个sort的性能。
  • 想要使用到索引进行排序,就需要建立一个subject_id_enum, subject_id两个字段的联合索引,但是又要兼顾where条件的查询性能。

易错提醒:

  • 我们有一个定时任务,是做扫表的,但是最近经常出现定时任务扫表处理失败的报警,登录到机器上之后,发现有数据库层面的报错: 以上日志我做了简单的脱敏,其中最重要的就是这句: 这是一个数据库查询执行过程中的错误信息,通常在数据库系统中会出现。
  • 这个问题的发生,一般来说有几个原因: 1、慢SQL导致查询超时,这时候就会为了避免数据库链接被长时间占用而中断此次查询 2、查询被手动终止,数据库管理员手动中止正在执行的查询操作也会出现这个异常 3、资源不足,查询排序操作可能需要大量的计算和内存资源,如果数据库服务器的资源不足以执行排序操作,那么查询可能会被中断。

追问准备:

  • 围绕「risk_case_status_enum」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「subject_id」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「SQL」:底层原理是什么?使用时有哪些边界和常见坑?
  • 如果线上出现异常,你会如何定位、验证并规避?

问题发现 ​

我们有一个定时任务,是做扫表的,但是最近经常出现定时任务扫表处理失败的报警,登录到机器上之后,发现有数据库层面的报错:

plain
Caused by: com.taobao.tddl.common.exception.TddlRuntimeException: ERR-CODE: [TDDL-4614][ERR_EXECUTE_ON_MYSQL] Error occurs when execute on GROUP 'FIN_RISK_XXX_GROUP' ATOM 'cn-zhangjiakou_i-xxxxx_fin_risk_xxx_3028': Sort aborted: Query execution was interrupted More: [http://xxx.alibaba-inc.com/faq/faqByFaqCode.ht
ml?faqCode=XXX-4614]

以上日志我做了简单的脱敏,其中最重要的就是这句:

plain
Sort aborted: Query execution was interrupted

这是一个数据库查询执行过程中的错误信息,通常在数据库系统中会出现。这个错误消息表示数据库查询中的排序操作被中断或终止了。

问题排查 ​

这个问题的发生,一般来说有几个原因:

1、慢SQL导致查询超时,这时候就会为了避免数据库链接被长时间占用而中断此次查询

2、查询被手动终止,数据库管理员手动中止正在执行的查询操作也会出现这个异常

3、资源不足,查询排序操作可能需要大量的计算和内存资源,如果数据库服务器的资源不足以执行排序操作,那么查询可能会被中断。这可能发生在高负载或资源不足的环境中。

主要就是以上这三个原因,接下来我们分析了一下导致失败的SQL 语句,这个语句在上面的ERROR日志打印的同时就已经给打印出来了,我隐藏了一些无关紧要的内容,大致SQL如下:

sql
### The error occurred while setting parameters### SQL: 
select
  business_type_enum,
  product_type_enum,
  subject_id,
  subject_id_enum,
  GROUP_CONCAT(distinct (number) SEPARATOR ',') as risk_case_numbers,
  GROUP_CONCAT(distinct (risk_level_enum) SEPARATOR ',') as risk_level_enums,
from
  fraud_risk_case
WHERE
  product_type_enum = ?
  and risk_case_status_enum = 'DRAFT'
  and subject_id like "23%"
group by
  subject_id_enum,
  subject_id
limit
  ?, ?

大致就是基于product_type_enum,risk_case_status_enum,subject_id做了条件查询,并且基于 subject_id_enum、subject_id两个字段做了一下分组。

看了一下这条SQL的执行计划:

sql
+----+-------+------------------------------+---------------------+----------------------------------------------------+                                           
| id | type  | possible_keys                | key                 | Extra                                              |                                           
+----+-------+------------------------------+---------------------+----------------------------------------------------+                                           
|  1 | range | idx_subject_product          | idx_subject_product | Using index condition; Using where; Using filesort |                                           
+----+-------+------------------------------+---------------------+----------------------------------------------------+

通过这个SQL我们可以分析出来,其实它是走了索引的,命中了idx_subject_product这个索引,其中包含了subject_id和product_type_enum字段。

并且这条SQL因为用到了group by所以需要进行排序,但是并没有用到索引排序,而是基于filesort进行的。

📄 ✅order by 是怎么实现的?

打开文档:✅order by 是怎么实现的?

那么,首先想到的优化方式就是提升这个sort的性能。

问题解决 ​

想要使用到索引进行排序,就需要建立一个subject_id_enum, subject_id两个字段的联合索引,但是又要兼顾where条件的查询性能。所以也需要考虑product_type_enum,risk_case_status_enum等字段。

但是因为这里面risk_case_status_enum是一个常量值进行where判断的,并且根据业务分析,risk_case_status_enum = 'DRAFT'的数据量在这张表中占比非常小,所以那么就很容易想到索引该怎么创建了:

即建立一个risk_case_status_enum,subject_id_enum, subject_id三个字段的联合索引,并且顺序按照risk_case_status_enum,subject_id_enum, subject_id这样排列。

如此机能让where判断走索引,也能让排序走到索引。索引建立之后,执行计划如下:

sql
+----+-------+-------------------------------------------------+---------------------+----------------------------------------------------+                                           
| id | type  | possible_keys                                   | key                 | Extra                                              |                                           
+----+-------+-------------------------------------------------+---------------------+----------------------------------------------------+                                           
|  1 | range | idx_subject_product ,idx_status_subject         | idx_status_subject  | Using index condition;                             |                                           
+----+-------+-------------------------------------------------+---------------------+----------------------------------------------------+

这样Extra中就只有Using index condition了,即基于索引实现了排序。

并且在发布之后,不再有报警发生,问题解决。