ODC 如何精确呈现SQL耗时 | OceanBase 开发者工具解析

前言

在程序员或DBA的日常工作中,编写并执行SQL语句如同日常饮食中的一餐一饭,再寻常不过。然而,在使用命令行或黑屏客户端处理SQL时,常会遇到编写难、错误排查缓慢以及查询结果可读性不佳等难题,因此,图形化工具成为了我们调试与执行SQL的首选。那么,你是否曾好奇,当我们借助直观易用的开发者工具执行一条SQL语句时,从按下执行按钮的那一刻起,直至结果呈现、查询执行计划展现的过程,这条SQL语句究竟经历了怎样的旅程?倘若执行响应迟缓,又是哪个环节遭遇了瓶颈呢?

ODC 作为OceanBase的数据库开发者工具,致力于为用户提供更高效、更易用的 SQL 执行与诊断方案,在 4.1.0 版本,对 SQL 执行阶段的耗时也做了进一步的细化展示,以方便用户更清晰的了解 SQL 耗时详情。本文以 OceanBase Oracle 模式下一条 SQL 在 ODC 以及 OBServer 上的生命周期为例,介绍 ODC SQL 执行过程及耗时计算方案。

1 SQL 的执行过程

前置处理

在 SQL 被实际执行前,首先会被解析,获取其操作对象类型、是否加写锁(for update)、是否为多表查询等基础信息。之后根据解析结果,若其满足一定的条件,可能会对 SQL 进行改写操作。

Apply SQL

改写包括两点,一是为了提升查询性能,当语句为 SELECT 类型,查询字段中包含 * 且非 .* 的语句时,会尝试替换为 table.* ;二是会在 SELECT 后增加 ROWID AS __ODC_INTERNAL_ROWID__ 的字段,这是因为结果集编辑时,若查询中未指定 ROWID 字段,那么可能会出现数据误更新的情况。

SELECT * FROM DEMO;为例,在发出执行请求后,会被改写为:

SELECT ROWID AS "__ODC_INTERNAL_ROWID__", DEMO.* FROM DEMO;

Validate SQL semantics

尽管对是否改写 SQL 已经经过了一定的判定,但仍然可能出现改写后无法执行的情况,例如查询 GV$SYSSTAT 等不支持 ROWID 的系统视图,那么即便语法不存在错误,也会导致执行失败。

为了避免改写导致的执行失败,在真实执行 SQL 之前,会执行 EXPLAIN + SQL ,若执行成功则说明改写成功,执行改写后的 SQL 并返回结果,否则仍然会采用原 SQL。

SQL 执行

SQL 执行阶段是 SQL 生命周期中最主要的阶段,其经过内部处理和准备后,通过网络协议一次或多次发送至 OceanBase Server 端,由 OBServer 进行具体执行操作,之后将结果以同样的方式返回客户端。

一条 SQL 在调用 JDBC 驱动执行语句后,驱动首先会进行一系列准备,例如设置查询行数限制、判断是否通过代理连接 Server 、设置执行超时计时器 等,这个阶段记作 Jdbc prepare 。

SQL 在从客户端发送至 OceanBase Server 端后,会进入等待队列,若租户 CPU 不足或服务器负载过高,则此过程可能会耗费大量时间。结束排队后,将会对其进行解析、改写和获取 SELECT 语句的执行计划,该过程若未命中缓存,也可能占用较长时间。拿到物理执行计划后,执行器才会调用线程执行该条 SQL ,并将计划保存至缓存中。为简化理解成本,上述一系列操作合并记作 OBServer wait 阶段。

OBServer 执行完成后,将数据返回客户端,通过 Get result-set 阶段,从返回结果中解析出要展示的数据,至此,便是一条 SQL 的实际执行过程。

后置处理

在获取到执行结果后,为了客户端的展示、编辑及错误提示,还会对该条 SQL 和执行结果进行几项后置处理。

Init SQL type

针对不同类型的 SQL,Navicat、SQL Developer 等数据库开发工具一般会给出不同的结果展示方式,例如 Navicat 对于 DML(INSERT、DELETE、UPDATE)类型语句会展示 Affected rows 影响行数,而对于 DDL、DQL 等仅提示 OK 执行成功,且展示 DQL 类型的查询结果。

ODC 对 SQL 类型的结果展示逻辑与 Navicat 基本相同,而解析类型的过程即被记作 Init SQL type 阶段,具体解析工作通过 OceanBase sql-parser 工具完成。

Init column comment 与 Init editable Info

在解析完 SQL 类型后,如果执行结果包含一个或多个表的列数据,则 ODC 会从字典视图 ALL_TAB_COLUMNS 中尝试获取相关列和表信息,并将其暂存在缓存中,以供接下来获取列注释和判断结果集是否可编辑。

若当前 SQL 涉及到对表或视图对象的查询,那么在展示时会显示列注释。而且,若当前 SQL 为单表查询,那么 ODC 能够允许用户对结果集进行编辑;若为多表查询,有且只有其中一张表的 ROWID 被指定,则指定 ROWID 的表的列可编辑,其余列不可。

Init warning message

OceanBase 数据库提供了字典视图 ALL_ERRORS,用于查看当前用户可访问的存储对象的错误。由于 SQL 窗口同样可以执行 PL,因此在执行结束后,ODC 将尝试查询 ALL_ERRORS 视图,通过对象名名称、Schema 名称和对象类型进行标识。若存在错误信息,则将其结构化处理后返回给用户。

至此,SQL 和结果集的后置处理也结束了,我们通过在 执行记录 界面中的 DB 耗时,查看上述各阶段的具体耗时。

2 OBServer 上的执行时间

SQL_AUDIT 视图

OceanBase 数据库将每一次 SQL 执行的来源、执行状态、详细耗时等信息存储在 GV$SQL_AUDIT 系统视图中,您可以通过该视图来查询 SQL 在 OBServer 端的耗时详情。

SQL_AUDIT 视图相关字段如下所示:

字段名称类型描述
TRACE_IDVARCHAR2(128)该语句的 trace_id
TENANT_IDNUMBER(38)发送请求的租户 ID
REQUEST_TIMENUMBER(38)开始执行时间点,单位:微秒
ELAPSED_TIMENUMBER(38)接收到请求到执行结束所消耗的总时间
EXECUTE_TIMENUMBER(38)实际计划执行所消耗的时间

注:在 OceanBase 4.0 版本之后,GV$SQL_AUDIT 命名更改为 GV$OB_SQL_AUDIT 。该视图按照租户拆分,除了系统租户,其他租户不能跨租户查询。

SQL TRACE

此外, OceanBase 支持 Trace 功能,通过变量 OB_ENABLE_TRACE_LOG 控制。

开启该功能后,可以使用SHOW TRACE命令来快速获取最近一次 SQL 请求的完整日志。该命令获取的数据格式如下所示:

示例结果说明如下:

  • Title 列包含整个 SQL 执行经历的各个阶段的信息以及该 SQL 真实的执行路径。若结果中有经过 Resolve、Transform、Optimizer 和 Code Generate 四个流程,则说明该 SQL 重新生成了计划,没有命中 Plan Cache。
  • KeyValue 列包含一些执行信息,可以用于排查问题:
    • TRACE_ID 可以作为 SQL_AUDIT 视图中的过滤条件,快速找到该 SQL 执行信息,同时也可以通过该 TRACE_ID 快速查找相关的 OBServer 日志。
    • plan_id 可以用于在 v$plan_cache_plan_explain 中查看 Plan Cache 中缓存的具体执行计划。
    • phy_plan_type 指出该次执行计划的类型(1 表示本地计划/2 表示远程计划/3 表示分布式计划),可以辅助 SQL 诊断。
  • Time 列显示上一个阶段点到这次阶段点执行耗时。如果某个 SQL 执行很慢,则通过查看 TIME 列,能够快速定位出具体是哪个阶段执行较慢,然后再进行具体分析。假设执行耗时主要在生成计划过程中,则只需要分析没有命中 Plan Cache 的原因,可能是计划淘汰后第一次执行该 SQL,或是 Plan Cache 不支持的 SQL。

3 ODC 如何计算耗时

Jdbc 准备耗时

JDBC驱动记录了执行请求发送和接收结果的时间节点,通过api来获取 JDBC 网络开销的时间,ODC 通过调用接口获取两个关键时间戳,将其作为计算耗时的数据来源。

Jdbc prepare 阶段耗时通过计算真实发送网络请求调用执行方法之间的时间差得到。当 Server 端的查询结果较多时,会分多次网络通信返回数据,我们使用 Jdbc 记录第一个数据包接收的时间戳,用于后续计算 Network consumption 阶段的耗时。

实际执行耗时

在 SQL 执行完成后,ODC 会通过 SHOW TRACE 命令获取查询该条 SQL 在 OBServer 端的实际执行日志。通过分析计算该日志,可得到该次请求的 ELAPSED_TIME (接收到请求到执行结束消耗的总时间)和 EXECUTE_TIME (实际执行物理计划所消耗的时间)。

其中 EXECUTE_TIME 即为 OBServer Execute SQL 阶段耗时,且被展示为执行记录中做外层的 DB 耗时。解析、改写、获取执行计划等预处理操作的耗时为除 EXECUTE_TIME 之外时间之和,合并记作 OBServer wait 阶段。

网络耗时

虽然 GV$SQL_AUDIT 视图中记录了每条 SQL 执行请求的 REQUEST_TIME ,理论上可通过该时间戳与请求发送之间的时间差获取到网络延时。但实际上由于该字段取自 OBServer 本地服务器时钟,而不同服务器间的·,时钟存在时间差异,因此难以单独计算请求发送或接收的耗时。

ODC 将接收到第一个回包的时间节点与请求发送的时间节点之间的差值作为请求往返时间,并减去上一步获取到的 ELAPSED_TIME 即 OBServer 端总耗时,从而获取到请求发送与接收的总网络耗时,记作 Network consumption 阶段。

4 ODC 执行耗时展示

在 ODC 中,我们可以通过“执行记录”界面的 “DB 耗时”功能查看 SQL 执行各个阶段的耗时,进而定位问题所在。ODC 在 4.1.0 版本,将每个阶段的执行耗时时间单位进行了自适应处理,保留小数点后两位,且对 SQL 执行阶段的耗时也做了进一步的细化展示,以方便用户更清晰的了解 SQL 耗时详情。

文中的例子是在 OB-Oracle 模式下运行,OB-MySQL 模式与之相比,不会对 SQL 进行解析与改写,而是直接交由驱动和 OBServer 执行,其余阶段基本相同,因此不再赘述。

总结

SQL 的一生很长,本文仅仅是简要描述了其被 ODC 执行时,各个生命周期中的主要工作以及耗时是如何得到的,对 SQL 在 OceanBase Server 端内部的执行过程也仅是粗略介绍。

后续的文章中将会带大家了解 ODC 的权限管理模型,敬请期待

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大数据学习15之Scala集合与泛型

1. 概述 大部分编程语言都提供了数据结构对应的编程库,并称之为集合库(Collection Library),Scala 也不例外,且它还拥有以下优点: 易用:灵活组合运用集合库提供的方法,可以解决大部分集合问题 简洁&#xf…

Linux网络——网络初识

目录 1. 认识协议 2. 协议的分层 3. OSI 七层模型 && TCP/IP 五层(四层)模型 4. 网络传输的基本流程 5. 以太网的通信原理 6. 数据的跨网络传播 7. 认识 IP 地址 ① IP 是什么 ② IP 与 MAC 的关系 ③ 为什么需要 IP 在谈及网络之前,我们要先对学…

数字IC后端低功耗设计实现案例分享(3个power domain,2个voltage domain)

下图所示为咱们社区T12nm A55低功耗实现项目。其实这个项目还可以根据产品的需求做一些改进。改进后项目实现的难度会大大增加。也希望通过今天的这个项目案例分享,帮助到今年IC秋招的同学。 芯片低功耗设计实现upf编写指南(附低功耗项目案例&#xff0…

Ubuntu从入门到精通(一)系统安装

Ubuntu从入门到精通(一) 1 Ubuntu镜像选择 下载Ubuntu 20.04系统ISO镜像 安装 Ubuntu 20.04系统,就必须有 Ubuntu 20.04系统软件安装程序可以通过浏览器访问Ubuntu20.04的官方站点, 然后在导舰栏找划 Dowwnloads->Mirrors链接&#xff…

说说软件工程中的“协程”

在软件工程中,协程(coroutine)是一种程序运行的方式,可以理解成“协作的线程”或“协作的函数”。以下是对协程的详细解释: 一、协程的基本概念 定义:协程是一组序列化的子过程,用户能像指挥家…

【linux】进程等待与进程替换

🔥个人主页:Quitecoder 🔥专栏:linux笔记仓 目录 01.进程等待系统调用获取子进程status常用宏使用示例 02.进程替换替换函数关键点解释:代码详细分析execvpe 函数的使用 01.进程等待 任何子进程,在退出的…

认证鉴权框架SpringSecurity-5--权限管理篇

上面两篇我们重点介绍了如何在代码上集成springSecurity,同时完成登录认证和token认证的过程。我们直到springSecurity处理能帮我们完成认证外,还可以帮助我们完成权限校验的工作,这篇我们来重点介绍下springSecurity是如何实现鉴权的。 一、…

RK3588开发板Android12-SDK更新通知

迅为RK3588开发板Android12 SDK升级至RK的android-12.1-mid-rkr14版本 内核版本:升级至 5.10.160 版本,提供更好兼容性和性能。 rkbin 版本:支持最新的 1.17 版本 bin 和 1.46 版本的 bl31。

stm32教程:OLED屏显示字母、汉字、图片工程讲解

早上好啊,大佬们,今天带来的是我们 stm32系列的第一个外设——OLED,相信大家对于OLED都不陌生了吧,这个可以说每一个项目里的必需品了,单片机离不开OLED就像西方离不开耶路撒冷。 在生活中,我们见到的OLED的…

力扣 LeetCode 28. 找出字符串中第一个匹配项的下标(Day4:字符串)

解题思路: KMP算法 需要先求得最长相等前后缀,并记录在next数组中,也就是前缀表,前缀表是用来回退的,它记录了模式串与主串(文本串)不匹配的时候,模式串应该从哪里开始重新匹配。 next[ j - 1 ] 记录了 …

我与Linux的爱恋:进程间通信 匿名管道

​ ​ 🔥个人主页:guoguoqiang. 🔥专栏:Linux的学习 文章目录 匿名管道pipe 匿名管道 匿名管道(Anonymous Pipes)是Unix和类Unix操作系统中的一种通信机制,用于在两个进程之间传递数据。匿名…

Java之JDBC,Maven,MYBatis

前言 就是用来操作数据库的 1.JDBC快速入门 注意在使用前一定要导入jar包 在模块那里新建目录,新建lib,粘贴复制jar包,我这个jar设置的是模块有效 package test1017;import java.sql.Connection; import java.sql.DriverManager; import…

基于Matlab的碎纸片的自动拼接复原技术

碎纸片的自动拼接复原技术 摘要:破碎文件的拼接在司法物证复原、历史文献修复以及军事情报获取等领域都有着重要的应用。目前发现对碎纸片的拼接大部分由人工完成,准确率较高,但耗费大量人力财力及时间,效率很低。随着计算机技术的…

STM32 设计的较为复杂的物联网项目,包括智能家居控制系统,涵盖了硬件和软件的详细设计。

使用 STM32 设计的较为复杂的物联网项目,包括智能家居控制系统,涵盖了硬件和软件的详细设计。 一、硬件设计 微控制器:选择 STM32F4 系列微控制器,如 STM32F407ZGT6,具有高性能和丰富的外设资源。 传感器模块&#x…

1.7 JS性能优化

从输入url到页面加载完成都做了些什么 输入 URL - 资源定位符 http://www.zhaowa.com - http 协议 域名解析 https://www.zhaowa.com > ip 1. 切HOST? > 浏览器缓存映射、系统、路由、运营商、根服务器 2. 实际的静态文件存放? 大流量 > 多个…

LPDDR4芯片学习(四)——DDR Training

一、ZQ Calibration DDR 学习时间 (Part B - 6):DRAM ZQ 校正 - 知乎 (zhihu.com) 从原理上解释什么是DDR的ZQ校准? - 知乎 (zhihu.com) LPDDR4的训练(training)和校准(calibration)--ZQ校准(Calibration)_wonder_coole-腾讯云开发者社区 01 ZQ校准的…

pycharm分支提交操作

一、Pycharm拉取Git远程仓库代码 1、点击VCS > Get from Version Control 2、输入git的url,选择自己的项目路径 3、点击Clone,就拉取成功了 默认签出分支为main 选择develop签出即可进行开发工作 二、创建分支(非必要可以不使用&#xf…

鸿蒙实战:页面跳转

文章目录 1. 实战概述2. 实现步骤2.1 创建项目2.2 准备图片素材2.3 编写首页代码2.4 创建第二个页面 3. 测试效果4. 实战总结 1. 实战概述 实战概述:本实战通过ArkUI框架,在鸿蒙系统上开发了一个简单的两页面应用。首页显示问候语和“下一页”按钮&…

IDEA部署AI代写插件

前言 Hello大家好,当下是AI盛行的时代,好多好多东西在AI大模型的趋势下都变得非常的简单。 比如之前想画一幅风景画得先去采风,然后写实什么的,现在你只需描述出你想要的效果AI就能够根据你的描述在几分钟之内画出一幅你想要的风景…

深入理解 Spark 中的 Shuffle

Spark 的介绍与搭建:从理论到实践_spark环境搭建-CSDN博客 Spark 的Standalone集群环境安装与测试-CSDN博客 PySpark 本地开发环境搭建与实践-CSDN博客 Spark 程序开发与提交:本地与集群模式全解析-CSDN博客 Spark on YARN:Spark集群模式…