在日常定位问题的时候经常遇到通过 TraceID 来定位问题的情况,譬如通过 TraceID 定位某条 SQL 语句的详细执行信息。TraceID 可以很直观的提供某个任务的执行过程给开发人员或者运维人员。OceanBase 数据库是分布式的架构,任务执行的机器可能是未知,这导致即使有了 TraceID,依然需要在各个 OBServer 的机器上进行日志的排查。在简单的 1-1-1 的集群模式下这个任务还能接受,但是当大量 OBServer 组成的复杂集群模式场景下,仅通过定位 TraceID 找到对应的 OBServer 主机需要很多精力去做筛查。
本文讲述如何通过已有的 TraceID 信息直接定位具体任务的执行机器。
适用版本
OceanBase 数据库 所有版本。
原理解析
实际上,TraceID 确实包含具体任务执行的机器 IP 信息。TraceID 的相关定义声明在源码头文件 ob_trace_id.h
,目前有多种版本,如下:
define TRACE_ID_FORMAT "Y%lX-%016lX"
define TRACE_ID_FORMAT_V2 "Y%lX-%016lX-%lx-%lx"
但是核心的 IP 信息这块并没有大的变化。也就是日常的 ID 会以 Y
开始紧接着是 %lX
,意味着无符号的十六进制整数,且无需 0x
的前缀,之后用 -
号进行分段。在 OceanBase 数据库中,IP 信息是写在前一段中的,TraceID 会将 IP 的信息拆离成四块,每一块对应 IP 中的一组数字。常见的 IP 地址分为 IPv4 与 IPv6 两大类。IPv4 的 IP 地址由一串数字组成,IPv4 为 32 位长,通常书写时以四组十进制数字组成,每组 8 位长,并以点分隔,比如:172.xx.xxx.x。
现在我们来分析如下日志里的 TraceID。
现在我们来分析如下日志里的 TraceID。
[2023-07-19 10:23:53.922556] WARN [STORAGE.TRANS] process_cluster_heartbeat_rpc (ob_weak_read_service.cpp:485) [3359][0][YF2A7F000001-000600CD83C2AC7F-0-0] [lt=18] [dc=0] tenant weak read service process cluster heartbeat RPC fail(ret=-4341, ret="OB_NOT_IN_SERVICE", tenant_id=1002, req={req_server:"127.x.x.x:3882", version:1689733433721263, valid_part_count:152, total_part_count:152, generate_timestamp:1689733433921484}, twrs={inited:true, tenant_id:1002, self:"127.x.x.x:2882", svr_version_mgr:{server_version:{version:1689733433721263, total_part_count:152, valid_inner_part_count:149, valid_user_part_count:3, epoch_tstamp:1689733433883943}, server_version_for_stat:{version:1689733433721263, total_part_count:152, valid_inner_part_count:149, valid_user_part_count:3, epoch_tstamp:1689733433883943}}})
现在我们将日志里的 TraceID 信息进行拆解 YF2A7F000001-000600CD83C2AC7F-0-0
。
经过解析 TraceID,这台机器的 IP 地址为 127.x.x.x,端口为 3882。
早下班一把梭
select query_sql,trace_id from oceanbase.GV$OB_SQL_AUDIT where query_sql like 'xxx%' order by REQUEST_TIME desc limit 5;
SELECT last_trace_id();




