在进行问题诊断时,通常需要 SQL 执行的 svr_ip、trace_id 等信息。
- svr_ip 是接收到 SQL 并发起执行的 OBServer 地址,是分布式执行的 Query Coordinator。
- trace_id 标识了一次唯一的 SQL 执行,可以使用 trace_id 在整个集群范围内关联一次远程或者分布式的 SQL 执行。
本文介绍几种获取 SQL 执行的 svr_ip、trace_id 的方法。
适用版本
OceanBase 数据库所有版本。
操作方法
SQL 监控视图 gv$sql_audit 中包含 SQL 执行的 svr_ip、trace_id 以及统计信息,通常我们使用 query_sql 来模糊匹配 SQL text,以便获得某一次 SQL 执行的信息。当系统比较繁忙时,模糊匹配的性能和效率都无法保证。如果在问题诊断时可以在客户端主动执行 SQL,则可以使用以下方法快速获取 SQL 的 svr_ip、trace_id。
SHOW TRACE 命令
当打开 SQL Trace 功能后,可以使用 SHOW TRACE 命令显示上一条 SQL 执行的详细信息,包含 svr_ip、trace_id 等信息和 SQL 各个执行阶段的时间统计,以及物理执行计划信息。
打开 SQL Trace。设置变量
ob_enable_trace_log =1或者使用 SQL Hint。# 使用 session 变量: set ob_enable_trace_log=1; # 使用 hint: select /*+trace_log=on*/* from tb1; 关于 SQL Trace 功能的打开,详见官网文档:SQL Trace使用 SHOW TRACE 查看 trace_id 和 svr_ip。
示例如下所示。
obclient [test]> set ob_enable_trace_log=1; Query OK, 0 rows affected (0.001 sec) obclient [test]> select * from aaa partition(p10); +------+------+ | id | name | +------+------+ | 10 | abc | | 40 | abc | | 70 | abc | | 100 | abc | +------+------+ 4 rows in set (0.001 sec) obclient [test]> show trace; +-------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+------+ | Title | KeyValue | Time | +-------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+------+ | process begin | addr:{ip:"11.xxx.xx.111", port:31211}, in_queue_time:11, receive_ts:1695789249614829, enqueue_ts:1695789249614831, trace_id:YB420BA650A8-000605D9C4843123-0-0 | 0 | | parse begin | stmt:"select * from aaa partition(p10)", stmt_len:32 | 47 | | calc partition location begin | | 63 | | get location cache begin | | 6 | | get location cache end | | 10 | | calc partition location end | | 0 | | execution begin | arg1:false, end_trans_cb:false, plan_id:78 | 35 | | do open plan begin | | 46 | | sql start stmt begin | | 2 | | sql start participant begin | | 28 | | table scan begin | | 25 | | table scan end | | 86 | | start_close_plan begin | | 67 | | start_end_participant begin | | 15 | | start_auto_end_plan begin | | 12 | | aaa | PHY_TABLE_SCAN | | +-------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+------+ 16 rows in set (0.003 sec) obclient [test]> select query_sql,plan_type,trace_id,svr_ip,client_ip,user_client_ip from oceanbase.gv$sql_audit where trace_id='YB420BA650A8-000605D9C4843123-0-0'; +----------------------------------+-----------+-----------------------------------+---------------+---------------+----------------+ | query_sql | plan_type | trace_id | svr_ip | client_ip | user_client_ip | +----------------------------------+-----------+-----------------------------------+---------------+---------------+----------------+ | select * from aaa partition(p10) | 1 | YB420BA650A8-000605D9C4843123-0-0 | 11.xxx.xx.168 | 11.xxx.xx.111 | 11.xxx.xx.111 | +----------------------------------+-----------+-----------------------------------+---------------+---------------+----------------+
LAST_TRACE_ID、HOST_IP 函数
如果不关心 SQL 执行的耗时统计和执行计划等信息,只是想获取 SQL 执行的 svr_ip 和 trace_id 以便日志的搜索,可以使用 HOST_IP、LAST_TRACE_ID 函数来获取上一条 SQL 执行的 svr_ip 和 trace_id。
示例如下所示。
```shell
obclient [test]> select * from aaa partition(p6);
+------+------+
| id | name |
+------+------+
| 6 | abc |
| 36 | abc |
| 66 | abc |
| 96 | abc |
+------+------+
4 rows in set (0.009 sec)
obclient [test]> select host_ip(),last_trace_id();
+---------------+-----------------------------------+
| host_ip() | last_trace_id() |
+---------------+-----------------------------------+
| 11.xxx.xx.115 | YB420BA65073-000605D9B87AE704-0-0 |
+---------------+-----------------------------------+
1 row in set (0.002 sec)
obclient [test]> select query_sql,plan_type,trace_id,svr_ip,client_ip,user_client_ip from oceanbase.gv$sql_audit where trace_id='YB420BA65073-000605D9B87AE704-0-0';
+---------------------------------+-----------+-----------------------------------+---------------+---------------+----------------+
| query_sql | plan_type | trace_id | svr_ip | client_ip | user_client_ip |
+---------------------------------+-----------+-----------------------------------+---------------+---------------+----------------+
| select * from aaa partition(p6) | 1 | YB420BA65073-000605D9B87AE704-0-0 | 11.xxx.xx.115 | 11.xxx.xx.111 | 11.xxx.xx.111 |
+---------------------------------+-----------+-----------------------------------+---------------+---------------+----------------+
```
enable_rich_error_msg
设置集群配置项 enable_rich_error_msg = true 可以在 SQL 执行出错时,OBServer 返回给客户端的消息中添加服务器地址、时间、追踪 ID 等调试信息,便于问题诊断,示例如下。
obclient [oceanbase]> alter system set enable_rich_error_msg='true';
Query OK, 0 rows affected (0.04 sec)
obclient [oceanbase]> select * from gv$memeroy limit 1;
ERROR 1146 (42S02): Table 'oceanbase.gv$memeroy' doesn't exist
[11.xxx.xx.111``:2882] [2023-09-26 14:44:08.478232] [YB420BA6506F-000605D9D7CF0852-0-0]