OceanBase数据库全链路追踪

OceanBase数据库全链路追踪

在OceanBase中,当用户发起一个请求后,首先会被发送给OBProxy代理,由OBProxy路由转发到OceanBase集群,进入集群中的某一个OBServer节点,随后会经过SQL引擎、存储引擎、事务引擎等(不同的请求会涉及不同引擎中的诸多处理模块),该请求也有可能通过rpc任务访问多个OBServer节点的数据,最终将结果返回给客户端。

当用户请求出现报错或者执行慢的问题时,可能是请求执行过程中的某个组件问题,也可能是不同组件节点间的网络等问题。为进一步提高分布式场景下用户请求问题诊断效率,OceanBase实现了全链路追踪机制,能够追踪用户SQL请求在数据库全链路过程中,在不同阶段、不同组件执行的相关信息,并以可视化方式展现给用户,从而帮助用户快速定位问题所在位置。

用户通过OceanBase运维平台(OCP),可以通过不同维度快速检索到有问题的请求,比如按耗时检索,按指定Trace ID或者SQL ID检索等,并且直观地看到请求从客户端到数据库内部全链路各组件的执行信息,方便快速定位出问题的阶段。

OceanBase基于各个链路的trace log,一键生成SQL的全链路耗时信息,以便用户可以快速定位链路问题。如果是通过ODP访问数据库,跟踪信息会同时记录在OBProxy(obproxy_trace.log)和OBServer的日志文件(trace.log)中;若是直接访问OBServer,则只在OBServer的日志文件中记录。

全链路追踪流程

在全链路中,不同的请求有对应的请求链路。一条完整的请求链路(Trace)则是若干个请求流程(Span)构成,在OceanBase数据库将内部处理的每一个流程定义为一个Span。请求链路可以理解为树状图,包含父节点Span以及相应的子节点Span,此部分信息会被打印到跟踪日志(trace logs)中,并通过parent_idid来关联父子节点。

同时,在trace logs中对于每个请求流程会包含实际执行SQL信息,这部分被命名为Tag,以不同的Tag来记录当前操作的详细信息。Span和Tag被记录在trace logs中,来帮助运维人员理解数据库内部的处理逻辑以及定位问题所在。

⭐️重要概念:

  • Trace:在全链路追踪流程中,Trace可以理解为OceanBase的一个事务。
  • Span:属于具体某个Trace,一个Trace可以有多个Span,Span可以是语句、函数、匿名块等。
  • Tag:KV,属于具体某个Span,一个Span可以有多个tag。
  • Log:KV with timestamp,属于具体某个Span,一个Span可以有多个log。

常见的Span解读

  1. 与客户端相关的Span:
  • obclient:通过OBClient客户端进行访问。
  • JDBC:通过JDBC驱动进行连接。
  1. 与OBProxy相关的Span:
  • ob_proxy:为OBProxy对一条SQL处理的全部耗时,即OceanBase数据库除前端驱动层以外的从数据库请求开始到数据处理完成,结果反馈的整条链路耗时。
  • ob_proxy_partition_location_lookup:为OBProxy在请求转发阶段,获取partition location准备进行路由的耗时。
  • ob_proxy_server_process_req:为OBProxy对一条SQL请求的处理耗时和访问来回的网络开销。
  1. 与OBServer相关的Span:OBServer内部将分发过来的请求根据请求类型分为文本SQLpreprocess statement存储过程三类。
  • 文本SQL:
    • com_query_entry(同com_query_process):查询过程
    • mpquery_single_stmt:单个语句的访问路径
    • sql_compile:编译 SQL
    • pc_get_plan:获取执行计划
    • hard_parse:硬解析
    • parse:软解析
    • resolve:解析语法树的语义并生成语句
    • rewrite:重写 SQL
    • optimize:进行基于成本的优化并生成执行计划日志
    • code_generate:根据执行计划日志生成物理执行计划
    • pc_add_plan:将生成的执行计划加入plan cache
    • sql_execute:执行物理执行计划
    • open:打开执行计划
    • response_result:执行计划过程和结果
    • px_schedule:按照px划分任务
    • px_task:执行px子任务
    • close:关闭执行计划
    • cmd_execute:执行命令
    • cmd_open:开启cmd计划
  • preprocess statement
    • ps_prepare:preprocess statement的预处理
    • ps_execute:preprocess statement的执行
    • ps_close:关闭preprocess statement
  • procedure
    • pl_entry:存储过程处理
    • pl_compile:编译存储过程对象
    • pc_get_pl_object:从plan cache获取存储过程对象
    • pc_add_pl_object:把存储过程对象存储在plan cache
    • pl_execute:执行存储过程
    • pl_spi_query:执行存储过程中的spi语句
    • pl_spi_prepare:存储过程预处理阶段
    • pl_spi_execute:执行存储过程中的spi语句

常见的Tag解读

  • com_query_entry
    • log_trace_id:当前请求在log中的trace ID
    • err_code:当前请求的错误代码
  • sql_compile
    • sess_id:session ID
    • sql_text:SQL文本
    • sql_id:SQL ID
    • hit_plan:执行计划命中执行计划缓存
  • px_task
    • task_id:并行任务的逻辑ID
    • dfo_id:数据流操作ID
    • sqc_id:子查询协调器ID
    • qc_id:查询协调器ID
    • group_id:资源组ID
  • px_schedule
    • dfo_id:数据流操作ID
    • used_worker_cnt:正在使用的px工作线程的个数
    • qc_id:查询协调器ID
  • ps_close
    • ps_id:preprocess statement ID

如何开启全链路追踪

前提条件

SHOW TRACE命令行查看追踪信息和通过OceanBase运维平台(OCP)查看追踪信息,使用全链路追踪对OceanBase及相关生态工具版本有一定要求。

🐯版本要求

  • OceanBase:V4.2.0及以上版本
  • ODP:V4.2.0及以上版本
  • JDBC:V2.4.3及以上版本
  • OBClient:V2.2.3及以上版本
  • OCP:V4.0.3及以上版本

使用show trace时,需使用上述正确版本并开启OceanBase 2.0协议,开启全链路诊断。

  1. ODP配置 :使用root@sys用户通过ODP代理登录 OceanBase数据库、或使用root用户登录数据库的`proxysys租户后,通过执行SQL语句配置。
sql 复制代码
obclient> alter proxyconfig set enable_ob_protocol_v2_with_client=true;
obclient> alter proxyconfig set enable_ob_protocol_v2=true;
  1. JDBC配置

JDBC可通过URL控制开启,在JDBC URL中添加

复制代码
enableFullLinkTrace=true

或者

复制代码
useOceanBaseProtocolV20=true&enableFullLinkTrace=true

均可开启全链路诊断功能。

开启会话级别全链路追踪

通过客户端连接OceanBase数据库后执行如下命令开启session级别SHOW TRACE功能。

sql 复制代码
obclient> set ob_enable_show_trace='on';

开启租户级别全链路追踪

OceanBase默认开启租户的全链路Trace功能。可以使用DBMS_MONITOR系统包来配置租户的全链路收集策略。

  1. 查询全链路Trace的收集策略。

使用root用户登录到业务租户进行查询;也可以登录到业务集群sys租户,查询的是所有租户的全链路Trace收集策略。

sql 复制代码
obclient(root@sys)[oceanbase]> SELECT * FROM oceanbase.GV$OB_FLT_TRACE_CONFIG;
+-----------+--------+-------------+-------------+-------------+-------------------+-------+-------------------+-----------------------+
| TENANT_ID | TYPE   | TENANT_NAME | MODULE_NAME | ACTION_NAME | CLIENT_IDENTIFIER | LEVEL | SAMPLE_PERCENTAGE | RECORD_POLICY         |
+-----------+--------+-------------+-------------+-------------+-------------------+-------+-------------------+-----------------------+
|         1 | TENANT | sys         |             |             |                   |     1 |                10 | SAMPLE_AND_SLOW_QUERY |
|      1003 | TENANT | META$1004   |             |             |                   |     1 |                10 | SAMPLE_AND_SLOW_QUERY |
|      1004 | TENANT | obmtest     |             |             |                   |     1 |                10 | SAMPLE_AND_SLOW_QUERY |
|      1005 | TENANT | META$1006   |             |             |                   |     1 |                10 | SAMPLE_AND_SLOW_QUERY |
|      1006 | TENANT | obotest     |             |             |                   |     1 |                10 | SAMPLE_AND_SLOW_QUERY |
+-----------+--------+-------------+-------------+-------------+-------------------+-------+-------------------+-----------------------+
5 rows in set (0.048 sec)

其中:

  • RECORD_POLICY字段表示trace信息输出到日志文件中策略, 支持以下三种策略:
    • ALL:所有span和tag信息均打印到日志文件中,并且是在每个span结束时, 就打印到日志文件中。
    • ONLY_SLOW_QUERY:当前请求为slow query,则该部分信息的span和tag会打印到日志文件中。
    • SAMPLE_AND_SLOW_QUERY:当前请求为slow query,则该部分信息的span和tag会打印到日志文件中;其他请求信息的span和tag有一定的概率会打印到日志文件中。
  • SAMPLE_PERCENTAGE字段表示采样的频率。输出为10,代表采样频率为10%。
  • LEVEL字段代表打印日志的粒度。目前支持三个粒度等级,其中Level1为模块级别的粗粒度,Level3的粒度最精细。
  1. 关闭当前租户的trace:
sql 复制代码
obclient(root@obmtest)[oceanbase]> SELECT * FROM oceanbase.GV$OB_FLT_TRACE_CONFIG;
+-----------+--------+-------------+-------------+-------------+-------------------+-------+-------------------+-----------------------+
| TENANT_ID | TYPE   | TENANT_NAME | MODULE_NAME | ACTION_NAME | CLIENT_IDENTIFIER | LEVEL | SAMPLE_PERCENTAGE | RECORD_POLICY         |
+-----------+--------+-------------+-------------+-------------+-------------------+-------+-------------------+-----------------------+
|      1004 | TENANT | obmtest     |             |             |                   |     1 |                10 | SAMPLE_AND_SLOW_QUERY |
+-----------+--------+-------------+-------------+-------------+-------------------+-------+-------------------+-----------------------+
1 row in set (0.158 sec)

obclient(root@obmtest)[oceanbase]> call dbms_monitor.ob_tenant_trace_disable();
Query OK, 0 rows affected (0.556 sec)

obclient(root@obmtest)[oceanbase]> SELECT * FROM oceanbase.GV$OB_FLT_TRACE_CONFIG;
+-----------+--------+-------------+-------------+-------------+-------------------+-------+-------------------+---------------+
| TENANT_ID | TYPE   | TENANT_NAME | MODULE_NAME | ACTION_NAME | CLIENT_IDENTIFIER | LEVEL | SAMPLE_PERCENTAGE | RECORD_POLICY |
+-----------+--------+-------------+-------------+-------------+-------------------+-------+-------------------+---------------+
|      1004 | TENANT | obmtest     |             |             |                   |    -1 |                -1 | NULL          |
+-----------+--------+-------------+-------------+-------------+-------------------+-------+-------------------+---------------+
1 row in set (0.004 sec)
  1. 重新开启当前租户的trace:
sql 复制代码
obclient(root@obmtest)[oceanbase]> call dbms_monitor.ob_tenant_trace_enable(1, 0.1, 'SAMPLE_AND_SLOW_QUERY');
Query OK, 0 rows affected (0.021 sec)

obclient(root@obmtest)[oceanbase]> SELECT * FROM oceanbase.GV$OB_FLT_TRACE_CONFIG;
+-----------+--------+-------------+-------------+-------------+-------------------+-------+-------------------+-----------------------+
| TENANT_ID | TYPE   | TENANT_NAME | MODULE_NAME | ACTION_NAME | CLIENT_IDENTIFIER | LEVEL | SAMPLE_PERCENTAGE | RECORD_POLICY         |
+-----------+--------+-------------+-------------+-------------+-------------------+-------+-------------------+-----------------------+
|      1004 | TENANT | obmtest     |             |             |                   |     1 |                10 | SAMPLE_AND_SLOW_QUERY |
+-----------+--------+-------------+-------------+-------------+-------------------+-------+-------------------+-----------------------+
1 row in set (0.005 sec)

⚠️生产环境谨慎开启ALL收集策略,可能会导致OpenSearch占用存储空间过大。如果当前租户已经开启全链路收集策略,需要先关闭后,再设置新的收集策略。

全链路追踪结果展示

全链路追踪信息可以通过OCP平台或者命令行查看。

OCP平台上的查看路径为:日志服务 => 链路查询。通过在链路查询界面中设置查询条件,辅助定位目标Trace。

我们也可以在OceanBase数据库的命令行界面使用Show Trace功能,在执行SQL语句后快速获取执行过程的详细调用链路和耗时信息。

sql 复制代码
obclient> show variables like 'ob_enable_show_trace';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| ob_enable_show_trace | OFF   |
+----------------------+-------+
1 row in set (0.003 sec)

obclient> SET ob_enable_show_trace = 1;
Query OK, 0 rows affected (0.000 sec)

obclient> select /*+parallel(2)*/ * from t_fundinfo;
...

obclient> show trace;
+---------------------------------------------------------+----------------------------+------------+
| Operation                                               | StartTime                  | ElapseTime |
+---------------------------------------------------------+----------------------------+------------+
| obclient                                                | 2025-12-19 14:14:05.481779 | 302.144 ms |
| └── com_query_process                                   | 2025-12-19 14:14:05.493015 | 295.960 ms |
|     └── mpquery_single_stmt                             | 2025-12-19 14:14:05.493020 | 295.942 ms |
|         ├── sql_compile                                 | 2025-12-19 14:14:05.493030 | 44.722 ms  |
|         │   ├── pc_get_plan                             | 2025-12-19 14:14:05.493035 | 0.004 ms   |
|         │   └── hard_parse                              | 2025-12-19 14:14:05.493082 | 44.661 ms  |
|         │       ├── parse                               | 2025-12-19 14:14:05.493083 | 0.041 ms   |
|         │       ├── resolve                             | 2025-12-19 14:14:05.493153 | 0.919 ms   |
|         │       ├── rewrite                             | 2025-12-19 14:14:05.494188 | 0.258 ms   |
|         │       ├── optimize                            | 2025-12-19 14:14:05.494466 | 23.152 ms  |
|         │       ├── code_generate                       | 2025-12-19 14:14:05.517641 | 19.171 ms  |
|         │       └── pc_add_plan                         | 2025-12-19 14:14:05.537075 | 0.646 ms   |
|         └── sql_execute                                 | 2025-12-19 14:14:05.537769 | 251.106 ms |
|             ├── open                                    | 2025-12-19 14:14:05.537770 | 35.198 ms  |
|             ├── response_result                         | 2025-12-19 14:14:05.572998 | 215.750 ms |
|             │   ├── px_schedule                         | 2025-12-19 14:14:05.573010 | 188.075 ms |
|             │   │   ├── inner_execute_read              | 2025-12-19 14:14:05.750774 | 2.112 ms   |
|             │   │   ├── do_local_das_task               | 2025-12-19 14:14:05.753254 | 0.080 ms   |
|             │   │   └── px_task                         | 2025-12-19 14:14:05.774513 | 14.028 ms  |
|             │   │       ├── do_local_das_task           | 2025-12-19 14:14:05.776247 | 0.072 ms   |
|             │   │       └── close_das_task              | 2025-12-19 14:14:05.787779 | 0.006 ms   |
|             │   └── px_schedule                         | 2025-12-19 14:14:05.788723 | 0.002 ms   |
|             └── close                                   | 2025-12-19 14:14:05.788761 | 0.105 ms   |
|                 └── end_transaction                     | 2025-12-19 14:14:05.788846 | 0.002 ms   |
+---------------------------------------------------------+----------------------------+------------+
24 rows in set (0.027 sec)

obdiag全链路功能诊断

使用obdiag analyze flt_trace命令可对OceanBase的全链路日志进行分析,给出全链路诊断报告。

使用示例

  1. gv$ob_sql_audit视图中查找SQL的flt_trace_id
sql 复制代码
SQL> select query_sql, flt_trace_id from oceanbase.gv$ob_sql_audit where query_sql like 'select @@version_comment limit 1';
+----------------------------------+--------------------------------------+
| query_sql                        | flt_trace_id                         |
+----------------------------------+--------------------------------------+
| select @@version_comment limit 1 | 00060aa3-d607-f5f2-328b-388e17f687cb |
+----------------------------------+--------------------------------------+

⚠️ 关于gv$ob_sql_audit返回的flt_trace_id字段值可能为空的问题:

  • gv$ob_sql_audit里的每一个在observer运行过的SQL记录,都会有对应的trace_id,但是flt_trace_id不一定会有,通常这是OB抽样决定的。
  • 如果客户端会话链路上所有组件都开通了全链路诊断对应的能力,那么这个会话发出的所有sql的flt_trace_id都有值。这个有性能损失代价,所以不是默认行为。
  • 这个规则将来还可能改变。

或者也可从OBProxy、OceanBase数据库的trace.log日志中找到flt_trace_id

bash 复制代码
less trace.log

[2023-12-07 22:20:07.242229] [489640][T1_L0_G0][T1][YF2A0BA2DA7E-00060BEC28627BEF-0-0] {"trace_id":"00060bec-275e-9832-e730-7c129f2182ac","name":"close_das_task","id":"00060bec-2a20-bf9e-56c9-724cb467f859","start_ts":1701958807240606,"end_ts":1701958807240607,"parent_id":"00060bec-2a20-bb5f-e03a-5da01aa3308b","is_follow":false}

其中,00060bec-275e-9832-e730-7c129f2182ac就是其flt_trace_id

  1. 执行全链路诊断命令。
bash 复制代码
obdiag analyze flt_trace --flt_trace_id 00060aa3-d607-f5f2-328b-388e17f687cb

References

【1】https://www.oceanbase.com/docs/common-oceanbase-database-standalone-1000000003577635

【2】https://open.oceanbase.com/blog/18850863969

【3】https://open.oceanbase.com/blog/1775421184

【4】https://open.oceanbase.com/blog/8144195424

【5】https://open.oceanbase.com/blog/16859818034

相关推荐
徐同保15 分钟前
使用node清空pinecones向量数据库
数据库
陈逸轩*^_^*15 分钟前
软件工程考试速通
数据库·软件工程
Lhan.zzZ19 分钟前
Qt绘制残留问题排查与修复日志
开发语言·数据库·qt
岙利岙22 分钟前
MySQL使用jemalloc作为内存分配器
数据库·mysql·jemalloc
老年DBA27 分钟前
PostgreSQL BRIN索引揭秘
数据库·postgresql
小光学长32 分钟前
基于微信小程序的评奖评优系统51r12nd0(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·微信小程序·小程序
煎蛋学姐35 分钟前
SSM校园扶助综合服务平台的设计与实现r941j(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·ssm 框架·校园扶助平台
ℳ₯㎕ddzོꦿ࿐37 分钟前
企业级 MySQL 8.0 物理备份实践:使用 XtraBackup 实现全量与增量自动备份
数据库·mysql
羊小猪~~41 分钟前
数据库学习笔记(十八)--事务
数据库·笔记·后端·sql·学习·mysql
optimistic_chen1 小时前
【Redis 系列】常用数据结构---ZSET类型
数据结构·数据库·redis·xshell·zset·redis命令