如何关联Oracle ORDS各REST模块负载与数据库SQL活动
ORDS 19.4 原生没有提供REST模块信息到数据库会话的透传字段,以下是经过验证的可落地方案,不需要升级版本即可实现REST模块维度的数据库负载统计:
方案1:Handler SQL 加固定标识注释(改造成本最低)
直接在ords_handlers表中各模块对应handler的source字段内,给待执行的SQL/PLSQL最头部添加统一格式的注释,例如/* ORDS_MODULE:用户中心模块 HANDLER:查询用户信息 */。ORDS执行语句时会把头部注释原样传入数据库,Oracle解析SQL时会保留头部注释不会被归一化剔除,后续直接匹配v$sql.sql_fulltext字段即可完成关联。
注意注释必须放在语句最开头:如果是纯SQL就放在SELECT/UPDATE/DELETE/INSERT关键字前,如果是PL/SQL块就放在BEGIN关键字前。
关联统计参考SQL:SELECT om.name AS rest_module_name, oh.uri_pattern AS handler_path, SUM(vs.executions) AS total_exec_count, ROUND(SUM(vs.cpu_time)/1000000,2) AS total_cpu_time_sec, ROUND(SUM(vs.elapsed_time)/1000000,2) AS total_elapsed_time_sec FROM v$sql vs JOIN user_ords_handlers oh ON vs.sql_fulltext LIKE '%/* ORDS_MODULE:'||oh.module_id||'%' JOIN user_ords_modules om ON om.id = oh.module_id GROUP BY om.name, oh.uri_pattern;方案2:配置请求Hook设置数据库会话标识(准确率最高,无业务侵入)
利用ORDS 19.4支持的请求前后置Hook能力,给每个REST模块配置前置处理PL/SQL,调用Oracle原生的dbms_application_info包把当前模块、handler信息写入会话元数据,请求处理完成后清空标识即可。
前置Hook核心代码:BEGIN dbms_application_info.set_module( module_name => 'ORDS_REST', action_name => 'MOD:'||:module_name||';PATH:'||:request_path ); END;配置完成后,直接关联
v$sql视图的module、action字段做统计即可,不需要做SQL文本匹配,统计准确率100%,也不会改动业务逻辑SQL。方案3:日志+ASH关联(零改造兜底方案)
如果不方便修改现有handler配置,可以开启ORDS访问日志,记录每个请求的REST模块名、请求时间、对应的数据库会话SID、SERIAL#,再通过v$active_session_history按时间窗口+会话ID关联对应时段执行的SQL做统计。该方案不需要改动任何线上配置,缺点是依赖ASH的采样频率,适合做负载趋势统计,无法做到100%精确的执行次数计数。
避坑提示:不要尝试通过SQL文本哈希关联,ORDS生成的动态SQL、绑定变量拼接逻辑会导致相同handler的SQL存在多版本哈希,直接匹配
sql_id漏统计率极高。
内容的提问来源于stack exchange,提问作者joluinfante

