oracle 19c 无原生自动awr报告功能,所谓“自动”实为脚本+调度封装;awrrpt.sql 仅支持手工交互式执行,存在必须sql*plus运行、不支持传参、输出路径固定三大硬限制;pdb环境下易因dbid/inst_num/容器上下文错配导致报告数据错误。

awrrpt.sql 生成的是手工报告,而“自动AWR报告”并不存在——Oracle 19c 没有内置的、开箱即用的“自动发送HTML报告邮件”或“定时落盘”功能。所谓“自动”,通常指人为封装脚本+调度(如cron或DBMS_SCHEDULER)调用 awrrpt.sql 或 DBMS_WORKLOAD_REPOSITORY 包,本质仍是手工触发逻辑。
为什么你看到的“自动AWR报告”其实是包装出来的?
Oracle原生只提供生成能力,不提供分发或调度。所有标榜“自动”的方案,底层都依赖以下组合:
- 调用
DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_TEXT或AWR_REPORT_HTML函数导出内容 - 用
UTL_MAIL.SEND或外部 shell +mailx发送 - 用
DBMS_SCHEDULER.CREATE_JOB或系统 cron 定时执行 - 把输出重定向到文件路径(如
/u01/app/oracle/rpt/awr_20260728.html),再配合清理逻辑
如果你没自己写过这套链路,那所谓的“自动报告”大概率来自 OEM(Enterprise Manager)——它只是把上述流程图形化、配置化了,背后仍是调用相同 API。
awrrpt.sql 手工报告的三个硬限制
这个脚本是 SQL*Plus 环境下的交互式工具,不是 PL/SQL 接口,因此有明确边界:
- 必须在 SQL*Plus 中运行,无法直接嵌入存储过程或触发器
- 不支持传参自动化:不能用变量指定快照ID范围,每次都要手动输
begin_snap和end_snap - 输出路径固定为当前 SQL*Plus 工作目录,且文件名由交互输入决定,无法用脚本预设
想绕过这些限制?得换用 DBMS_WORKLOAD_REPOSITORY 包。例如:
SELECT * FROM TABLE(DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_HTML( l_dbid => 123456789, l_inst_num => 1, l_bid => 1000, l_eid => 1010 ));
但注意:该函数返回的是 CLOB,需额外处理(如写入文件或转 Base64 发邮件),且对 PDB 场景需显式指定 l_dbid(非根容器 DBID)。
PDB 环境下手工 vs “自动”报告最容易错的点
在多租户架构中,awrrpt.sql 默认只面向 CDB$ROOT,不会自动识别当前连接的 PDB。常见误操作:
- 用
conn pdb_user@my_pdb登录后直接跑@?/rdbms/admin/awrrpt.sql→ 报告仍是 CDB 全局视图,PDB 数据被淹没 - 以为设置
ALTER SESSION SET CONTAINER = my_pdb就够了 → 不生效,awrrpt.sql不感知 container 切换 - 用
awrrpti.sql脚本时漏填 PDB 的inst_num→ 实际取的是 CDB 的实例号,导致快照范围错乱
正确做法:要么在 CDB$ROOT 下用 awrrpti.sql 并手动填入目标 PDB 的 inst_id(查 v$instance 在该 PDB 中的值),要么用 DBMS_WORKLOAD_REPOSITORY 并传入该 PDB 对应的 dbid(查 cdb_pdbs)。
真正麻烦的不是生成,而是上下文一致性:快照 ID、DBID、INST_NUM、容器身份,四个值缺一不可。少校验一个,报告就变成“看起来正常,但数据不属于你要查的那个 PDB”。











