1. 为什么我们需要AWR报告?
AWR(Automatic Workload Repository)报告是Oracle数据库性能诊断的"X光片"。作为DBA,我每天都要处理各种性能问题,而AWR报告就是我的第一道诊断工具。它能提供数据库在特定时间段内的完整性能快照,包括:
- 系统负载情况(CPU、内存、I/O)
- SQL语句执行统计
- 等待事件分析
- 各种缓冲区命中率
重要提示:AWR报告默认每小时生成一次快照并保留8天(11g默认配置),超过保留期限的快照会被自动清理。如果需要长期保存,记得定期导出。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. AWR报告生成方法全解析
2.1 命令行生成法(最常用)
这是我个人最推荐的方式,通过SQL*Plus执行:
sql复制-- 生成当前实例最近两个快照之间的AWR报告
@?/rdbms/admin/awrrpt.sql
-- 生成指定快照范围的AWR报告(更灵活)
@?/rdbms/admin/awrrpt.sql
执行后会交互式提示:
- 选择报告类型(HTML或TEXT,建议HTML)
- 输入快照天数(默认1天)
- 选择起始和结束快照ID
- 指定报告文件名
2.2 脚本自动化生成(批量场景)
对于需要定期收集的场景,我常用这个shell脚本:
bash复制#!/bin/bash
ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1
export ORACLE_SID=orcl
export PATH=$ORACLE_HOME/bin:$PATH
# 获取最近两个快照ID
snap_ids=$(sqlplus -S / as sysdba <<EOF
set pagesize 0 feedback off
select min(snap_id), max(snap_id)
from dba_hist_snapshot
where end_interval_time > sysdate-1/24;
EOF
)
# 生成HTML报告
sqlplus -S / as sysdba <<EOF
@?/rdbms/admin/awrrpt.sql
html
${snap_ids// /,}
awr_$(date +%Y%m%d_%H%M%S).html
EOF
2.3 通过OEM生成(图形化方式)
对于习惯图形界面的DBA:
- 登录Oracle Enterprise Manager
- 导航到"Performance" → "AWR" → "AWR Reports"
- 选择时间范围和实例
- 点击"Generate Report"
实测对比:命令行方式生成速度最快,特别是在高负载系统上,比OEM方式快3-5倍。
3. AWR报告关键指标解读指南
3.1 负载概览(Load Profile)
这部分就像数据库的"体检报告单",重点关注:
- DB CPU Usage:超过50%就需要警惕
- Logical Reads:反映SQL效率
- Hard Parses/sec:高于100可能说明绑定变量问题
我常用的判断标准:
code复制DB CPU时间占比 = (DB CPU/(DB CPU+非空闲等待)) * 100%
如果 > 30% → CPU压力
如果 < 10% → 可能存在I/O或锁争用
3.2 Top 5等待事件
这是性能问题的"罪魁祸首"清单,常见的有:
- db file sequential read:索引扫描等待(通常正常)
- db file scattered read:全表扫描等待
- log file sync:提交等待(检查redo日志配置)
上周处理的一个案例:某系统频繁出现"enq: TX - row lock contention"等待,最终发现是应用没有正确处理并发更新。
3.3 SQL统计信息
重点关注:
- Elapsed Time:执行总时间
- CPU Time:消耗的CPU时间
- Executions:执行次数
- Buffer Gets:逻辑读
我的分析公式:
code复制单次执行代价 = (Elapsed Time / Executions)
如果Executions高但Elapsed Time低 → 可能是频繁执行的小SQL
如果Executions低但Elapsed Time高 → 需要优化的重点SQL
4. 实战案例:AWR报告分析全流程
4.1 场景还原
某电商系统在促销期间出现性能下降,通过AWR报告分析:
- 时间范围:选择活动开始前后1小时
- 对比报告:生成活动前(基线)和活动中两份报告
4.2 关键发现
-
负载变化:
- 逻辑读从2000/秒飙升到15000/秒
- 硬解析从5/秒增加到120/秒
-
Top SQL:
sql复制SELECT * FROM orders WHERE status='PENDING' AND create_time>SYSDATE-1该SQL执行计划从索引扫描变成了全表扫描
4.3 解决方案
-
紧急处理:
- 添加缺失的复合索引:
(status, create_time) - 使用SQL Profile固定执行计划
- 添加缺失的复合索引:
-
长期优化:
- 在测试环境使用SQL Tuning Advisor
- 修改应用使用绑定变量
5. 高级技巧与避坑指南
5.1 对比AWR报告
比较不同时段的性能变化:
sql复制@?/rdbms/admin/awrddrpt.sql
这个报告会高亮显示关键指标的变化差异,比人工对比高效得多。
5.2 AWR基线管理
创建性能基线(比如系统正常时的状态):
sql复制-- 创建基线
EXEC DBMS_WORKLOAD_REPOSITORY.CREATE_BASELINE(
start_snap_id => 1234,
end_snap_id => 1235,
baseline_name => 'NORMAL_LOAD');
-- 比较当前与基线
@?/rdbms/admin/awrddrpt.sql
5.3 常见问题排查
问题1:执行awrrpt.sql时报错"ORA-06553: PLS-213: package not standarized"
- 原因:AWR包未正确安装
- 解决:重新运行
?/rdbms/admin/catawr.sql
问题2:报告中没有SQL统计信息
- 检查:
SELECT * FROM dba_hist_sqlstat WHERE snap_id=xxx - 可能原因:STATISTICS_LEVEL未设置为TYPICAL或ALL
问题3:快照间隔过长
- 调整:修改
DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS
sql复制BEGIN
DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(
retention => 11520, -- 改为8天(分钟数)
interval => 30); -- 改为30分钟采集一次
END;
6. AWR扩展应用场景
6.1 容量规划
通过历史AWR数据预测资源需求:
sql复制SELECT snap_time,
ROUND(SUM(cpu_time_delta)/SUM(elapsed_time_delta),2) avg_cpu_cores
FROM dba_hist_sysmetric_summary
WHERE metric_name='CPU Usage Per Sec'
GROUP BY snap_time;
6.2 自动化监控
我常用的监控脚本(检查异常等待事件):
sql复制SELECT e.event_name,
ROUND(e.time_waited_micro/1e6,2) seconds,
ROUND(e.time_waited_micro/NULLIF(e.total_waits,0)/1e3,2) avg_ms
FROM dba_hist_system_event e, dba_hist_snapshot s
WHERE e.snap_id = s.snap_id
AND s.end_interval_time > SYSDATE-1
AND e.wait_class != 'Idle'
ORDER BY e.time_waited_micro DESC;
6.3 与ASH报告配合使用
当问题持续时间很短(<5分钟)时,ASH报告更有效:
sql复制-- 生成ASH报告
@?/rdbms/admin/ashrpt.sql
两者的黄金组合:
- 先用AWR定位问题时间段
- 再用ASH分析该时间点的详细会话活动
7. 性能优化实战心得
经过多年实践,我总结出AWR分析的"三步法":
- 看趋势:先看Load Profile,了解整体负载变化
- 找瓶颈:分析Top 5等待事件,定位资源瓶颈
- 抓元凶:研究Top SQL,找出具体问题语句
最近处理的一个典型案例:某系统CPU使用率高达90%,AWR显示:
- 主要等待事件是"CPU used by this session"
- Top SQL是一个全表扫描的查询
- 该SQL占用了总DB Time的65%
解决方案很简单——添加适当的索引后,CPU使用率降到了40%。
