7.4 如何分析 SQL 审计视图
SQL 审计视图可以查看在 OceanBase 里执行过的所有 SQL,不管是成功的还是失败的。这对开发同学了解自己的业务 SQL 和定位问题细节非常有帮助。
SQL 审计视图概述
SQL 审计视图 gv$sql_audit 是虚拟表,是内存中一个 FIFO 队列。
功能的开启和数据大小是通过下面的 OceanBase 集群参数控制的。
| 参数名 | 参数值 | 参数含义 |
|---|---|---|
| enable_sql_audit | TRUE | 指定是否开启 SQL 审计。默认 TRUE 是开启。FALSE 是关闭。 |
| sql_audit_queue_size | 10000000 | SQL 审计视图里最大记录数。 |
| sql_audit_memory_limit | 3G | SQL 审计视图内存最大大小。 |
SQL 审计能保留的数据大小跟租户内存资源的大小也有关系,通常不会特别大。建议自行实时将 SQL 审计视图的数据抽取走,然后做二次分析。
您可以在租户里开启或关闭 SQL 审计功能。
set global ob_enable_sql_audit = on;
视图列定义如下:
| 列名 | 含义 |
|---|---|
| SVR_IP | SQL 执行的 OBServer 节点 IP |
| SVR_PORT | SQL 执行的 OBServer 节点端口 |
| REQUEST_ID | 唯一标识 |
| TRACE_ID | 该 SQL 的 TRACE_ID 信息,在 OBServer 节点日志里可以关联查询相关日志 |
| SID | SQL 执行的 OBServer 节点上的会话 ID |
| CLIENT_IP | 该 SQL 执行的客户端 IP,通常是 ODP IP |
| TENANT_ID | 该 SQL 执行的租户 ID |
| TENANT_NAME | 该 SQL 执行的租户名称 |
| USER_NAME | 该 SQL 执行的租户内部用户名 |
| USER_CLIENT_IP | 该 SQL 执行的实际客户端 IP |
| DB_ID | 该 SQL 执行的数据库 ID |
| DB_NAME | 该 SQL 执行的数据库名称 |
| SQL_ID | 该 SQL 的 SQL_ID |
| QUERY_SQL | 该 SQL 的文本,如果太长会截断 |
| PLAN_ID | 该 SQL 的执行计划 ID |
| AFFECTED_ROWS | 该 SQL 的写影响行数 |
| RETURN_ROWS | 该 SQL 的返回行数 |
| PARTITION_CNT | 该 SQL 访问的分区数量 |
| RET_CODE | 该 SQL 的返回代码 |
| EVENT | 该 SQL 的主要等待事件 |
| PLAN_TYPE | 该 SQL 的执行计划类型 1:本地 SQL;2:远程 SQL;3:分布式 SQL |
| IS_HIT_PLAN | 是否命中执行计划 |
| REQUEST_TIME | 该 SQL 执行时间点(时间戳类型,可通过 usec_to_time 转换为可读时间格式) |
| ELAPSED_TIME | 该 SQL 执行总耗时 |
| NET_TIME | 该 SQL 执行网络消耗时间 |
| QUEUE_TIME | 该 SQL 执行内部排队时间 |
| DECODE_TIME | 出队列后 decode 时间 |
| GET_PLAN_TIME | 该 SQL 执行计划生成时间 |
| EXECUTE_TIME | 该 SQL 实际内部执行时间(不包括 CPU 排队时间) |
如何查看 SQL 审计视图
以下 SQL 可以在 sys 租户和业务租户里执行。业务租户只能查看属于自己租户的 SQL 数据。
查看近期所有 SQL
SELECT /*+ read_consistency(weak) ob_querytimeout(100000000) */ substr(usec_to_time(request_time),1,19) request_time_, s.svr_ip, s.client_Ip, s.sid,s.tenant_id, s.tenant_name, s.user_name, s.db_name, s.query_sql, s.affected_rows, s.return_rows, s.ret_code, s.event, s.elapsed_time, s.queue_time, s.execute_time, round(s.request_memory_used/1024/1024/1024,2) req_mem_mb, plan_type, is_executor_rpc, is_inner_sql, TRANSACTION_HASH, trace_id FROM gv$sql_audit s WHERE 1=1 and s.tenant_id = 1002 and user_name='u_tpcc' and request_time >= time_to_usec(DATE_SUB(current_timestamp, INTERVAL 30 MINUTE) ) ORDER BY request_time DESC LIMIT 100;
request_time是时间戳,可通过函数usec_to_time和time_to_usec与微秒数转换。分析统计近期所有 SQL
根据
sql_id统计平均总耗时、平均执行时间等。SELECT sql_id, count(*), round(avg(elapsed_time)) avg_elapsed_time, round(avg(execute_time)) avg_exec_time FROM gv$sql_audit s WHERE 1=1 and s.tenant_id = 1002 and user_name='u_tpcc' and request_time >= time_to_usec(DATE_SUB(current_timestamp, INTERVAL 30 MINUTE) ) GROUP BY sql_id order by avg_elapsed_time desc ;
查看报错的 SQL
ret_code是 SQL 执行报错时的错误码。正常是0,错误码为负数。SELECT /*+ read_consistency(weak) ob_querytimeout(100000000) */ substr(usec_to_time(request_time),1,19) request_time_, s.svr_ip, s.client_Ip, s.sid,s.tenant_id, s.tenant_name, s.user_name, s.db_name, s.sql_id, s.query_sql, s.affected_rows, s.return_rows, s.ret_code, s.event, s.elapsed_time, s.queue_time, s.execute_time, round(s.request_memory_used/1024/1024/1024,2) req_mem_mb, plan_type, is_executor_rpc, is_inner_sql, TRANSACTION_HASH, trace_id FROM gv$sql_audit s WHERE 1=1 and s.tenant_id = 1002 and user_name='u_tpcc' and ret_code < 0 and request_time >= time_to_usec(DATE_SUB(current_timestamp, INTERVAL 30 MINUTE) ) ORDER BY request_time DESC LIMIT 500;
查看远程 SQL 和分布式 SQL
plan_type的值有三个:1表示本地 SQL;2表示远程 SQL;3表示分布式 SQL。SELECT /*+ read_consistency(weak) ob_querytimeout(100000000) */ substr(usec_to_time(request_time),1,19) request_time_, s.svr_ip, s.client_Ip, s.sid,s.tenant_id, s.tenant_name, s.user_name, s.db_name, s.sql_id, s.query_sql, s.affected_rows, s.return_rows, s.ret_code, s.event, s.elapsed_time, s.queue_time, s.execute_time, round(s.request_memory_used/1024/1024/1024,2) req_mem_mb, plan_type, is_executor_rpc, is_inner_sql, TRANSACTION_HASH, trace_id FROM gv$sql_audit s WHERE 1=1 and s.tenant_id = 1002 and user_name='u_tpcc' and plan_type > 1 and request_time >= time_to_usec(DATE_SUB(current_timestamp, INTERVAL 30 MINUTE) ) ORDER BY request_time DESC LIMIT 500;
远程 SQL 的出现需要结合事务的业务逻辑分析。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




