DBAService SQL执行状态释疑

概要描述

本文主要介绍,DBAService Query页面,每种status的状态解释,以及常见状态异常问题。

DBAService中的和Query相关,Server/Executor状态等监控数据都是来自Quark Server,Quark Server通过leviathan-message(封装了akka的消息框架)发送监控埋点数据给DBAService。

详细说明

1. 一个Query常见的状态流转图

场景1. 普通的查询:

场景2. PLSQL

场景3. 一些配置语句或者DDL语句:

以上非SUCCESS状态都可能会流转到异常状态:

2. ArgoDB中一个Query执行的完整生命周期

SUBMITTED状态: 查询已经提交到了server,但还没有生成作业RDD,这个中间会包括:编译,生成执行计划,获取锁(可能会有)等阶段),对应与上面时序图中的步骤(1)Submit SQL Query ~(2)Parsing。

**RUNNING状态:**生成RDD,执行任务:Job/Stage/Task,对应于上面时序图中的步骤(3)~(9)。

**FILECOMMIT状态:**将作业执行结果写到HDFS,对应上面时序图的步骤(10)。

**FETCHRESULT状态:**客户端读取Query的计算结果,对应上面时序图的步骤(11)~(12)。

**SUCCESS状态:**Query执行结束,对应上面时序图的步骤(13)。

DBAService 9.4.6版本开始,支持存储和展示PerfLog各阶段耗时(SQL END时显示),Query页面-> Perflog Time Cost,可以辅助定位步骤执行信息。

常见问题

1. 标记(Tags)列 在哪里?

查询页面,往右拉能够找到

2. 标记(Tags)列 枚举值说明

字段内容 说明
LvtMsgLost 标记该SQL由于SqlEnd消息丢失,dba侧主动查询检测到该SQL实际结束,将其状态结束,946及后续通常该SQL状态为UNKNOWN
FINISHED 表示该SQL执行结束后,客户端statement连接还未关闭,即此时查询system.processes_v获取的该SQL的状态是FINISHED,DBA侧标记后,会记录当前的tagFinishTime,持续时长为tagFinishTime-提交时间(即任务实际执行时长),收到sqlEnd消息的完成时间是客户端连接关闭的时间,故会出现持续时长<完成时间-提交时间
ServerRestart 标记该SQL在Running过程中,Server发生了重启,dba无法收到sqlEnd消息,检测到server重启后,会将该SQL状态结束并标记,946及后续通常该SQL状态为UNKNOWN
Killed by user xx 标记该SQL在DBA侧是通过提交kill sql (opId)命令,执行的kill操作,该SQL状态为FAILED,实际kill方式参考 展示inceptor 正在执行的进程,以及kill 命令

3. 什么情况下会流转到COMPLETE状态?

一般情况下 **标记(Tags)**列会有更详细的信息,最常见的是 LvtMsgLost/ServerRestart,有如下几种可能:

a) DBAService监控埋点数据有丢失(QuarkServer或DBAService压力比较大会导致该现象),一般看是不是一个dbaservice监控太多quark,如果是,则建议用多个dbaservice,建议一个dbaservice最多监控不超过4个。

b) 如果是dba-9.4.2或以下版本,则可能是已知BUG,可以通过升级最新DBAService,或更新 Patch-DBAService-9.4.2-20230621-01 及以上版本patch。

4. SQL卡在postrun状态

在9.4.2及以下版本,DBA Service上的 PostRun 阶段被简单定义为LvtSQLComputeFinish消息和LvtSqlEnd消息之间的状态。
实际上在这个阶段发生很多事:Commit File (移动文件阶段)、 Fetch Result (对应JDBC的读结果阶段)

建议:升级到DBAService 9.4.3 + 最新patch,不再有postrun状态,将该阶段拆分为最关键的两个阶段:FILECOMMIT 和 FETCHRESULT,对于FETCHRESULT阶段,通过 select * from system.processes_v 检查SQL执行状态,如果存在该SQL且该SQL的状态为FINISHED,则给当前SQL增加一个标记 FINISHED

5. SQL卡在fetchresult状态

执行 select * from system.processes_v 

如果SQL的执行结果状态为 FETCHRESULT,客户端正在取计算结果。

如果SQL的执行结果状态为 FETCHRESULT,且标记列中包含 FINISHED,客户端连接未释放,可能是执行完查询未close。

6. 持续时长 <(完成时间-提交时间),且标记列(Tags)为 FINISHED

原因在于,不规范的JDBC使用方式,执行完查询后,没有 close statement。以下面的样例代码为例,注释掉 st.close();

import java.sql.*;
public class testMetaData {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        Class.forName("org.apache.hive.jdbc.HiveDriver");
        String jdbcUrl = "jdbc:hive2://172.22.23.1:10000/default?hive.session.id=my.s1";
        try (Connection connection = DriverManager.getConnection(jdbcUrl, "hive", "123456")) {
            runCmd(connection);
            runCmd(connection);
            runCmd(connection);
            Thread.sleep(120000);
        } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        e.printStackTrace();
    }
    }
    public static void runCmd(Connection connection) throws SQLException {
        Statement st = null;
        try {
            st = connection.createStatement();
            String cmd = "show databases";
            System.out.println("runSql: " + cmd);
            boolean hasResultSet = st.execute(cmd);
            if (hasResultSet) {
                ResultSet rs = st.getResultSet();
                while (rs.next()) {
                    System.out.println(rs.getString(1));
                }
            }
        } finally {
            if (st != null && !st.isClosed()) {
			//这里注释掉 close statement。
//                    st.close();
            }
        }
    }
}

最终,持续时长为1m20s,小于 完成时间 减去 提交时间 的 2m 。且后面的标记列为 FINISHED

7. executor负载 100% 爆红了怎么办?

executor 负载100% 是非常正常的现象,说明这个这个quark/inceptor的task并发全都用来跑任务了;
executor负载的计算方式是:(running task数)/(并发可执行total cores),其中
【并发可执行total cores】 = 【每个executor节点配置的CPU核数(inceptor.executor.cores) 累加之和】 乘以 【executor.number.eachnode

以下图为例,【并发可执行total cores】 =(3+3+9)*2=30

 

阅读剩余
THE END