AWR报告生成必须用SYS用户执行,因awr_report_text仅允许SYS或具备SELECT_CATALOG_ROLE+EXECUTE_CATALOG_ROLE的角色调用;JDBC需以SYS AS SYSDBA连接,使用ojdbc8.jar,严格按参数顺序调用并流式读取CLOB防截断。
AWR报告生成必须用SYS用户执行
oracle的dbms_workload_repository包中生成awr报告的存储过程(如awr_report_text)只能由sys或具有select_catalog_role + execute_catalog_role的角色调用,普通dba权限不够。jdbc连接若用非sys账号,会直接报ora-01031: insufficient privileges。
实操建议:
- 确认JDBC URL连接的是
SYS AS SYSDBA:连接串需带?internal_logon=sysdba,且用户名为SYS - 密码不能为空;若用Oracle Wallet,仍需在JDBC中显式指定
user=SYS和password=xxx - 驱动必须用Oracle官方
ojdbc8.jar(或对应DB版本),旧版驱动可能不支持SYSDBA连接模式
调用awr_report_text的参数顺序和类型不能错
这个函数是函数(不是过程),返回CLOB,但JDBC调用时必须用CallableStatement,且参数顺序、方向、SQL类型必须严格匹配Oracle文档定义。常见错误是把第4个参数(report_type)当成字符串传入,实际它是个NUMBER(0=HTML,1=TEXT)。
实操建议:
- 完整签名:
awr_report_text(l_dbid, l_inst_num, l_bid, l_eid, l_options) -
l_dbid和l_inst_num必须查v$database和v$instance获取,不能硬编码 -
l_bid和l_eid是快照ID,必须保证存在、跨实例一致、时间跨度合理(一般≥30分钟) -
l_options设为1得TEXT报告,设0得HTML(但HTML含大量换行和空格,JDBC读CLOB易截断)
JDBC读取CLOB结果要避免字符截断
Oracle返回的CLOB可能超2MB(尤其长周期AWR),而JDBC默认ResultSet.getString()对CLOB有隐式转换限制,容易只读前4KB就截断,现象是报告末尾突然中断、缺“End of Report”字样。
实操建议:
- 不用
getString(),改用getClob()再流式读取 - 设置
setFetchSize(1)防止驱动预取过多内存 - 读取时用
Reader逐块读(例如每次8192字符),拼接StringBuilder,别用getSubString() - 记得在finally里
clob.free()(JDBC 4.2+)释放服务端资源
AWR报告生成失败的典型错误码和应对
不是所有报错都来自权限或语法——很多卡在数据层面。比如快照不存在、DBID不匹配、实例号错位,都会返回模糊的ORA-20200或ORA-06512堆栈,但根因藏在PL/SQL异常信息里。
实操建议:
- 捕获
SQLException后,打印e.getErrorCode()和e.getMessage(),重点看是否含AWR或snapshot关键词 - 手动在SQL*Plus里执行相同参数的
awr_report_text,验证快照范围是否有效(查dba_hist_snapshot) - 若报
ORA-13784: invalid snapshot range,说明l_bid/l_eid不在同一实例的连续快照区间内 - 生成耗时超过30秒属正常,别设过短的
setQueryTimeout(),否则中断后残留临时表空间占用不释放
真正麻烦的是跨PDB场景:awr_report_text默认只查CDB$ROOT的AWR,如果目标库是PDB,得先用ALTER SESSION SET CONTAINER = xxx切过去,且DBID要用PDB自己的(查gv$pdbs),这点极易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










