多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Oracle AWR报告实战:从快照生成到性能根因分析

Oracle AWR报告实战:从快照生成到性能根因分析 简介这份PDF文档由黄伟波撰写聚焦Oracle数据库自动工作负载仓库AWR报告分析旨在帮助数据库管理员和运维工程师利用AWR报告诊断性能瓶颈、优化数据库配置。文档先从AWR的基本概念、统计信息构成、STATISTICS_LEVEL参数作用及维护进程讲起让读者理解数据收集机制与相关配置随后介绍了使用企业管理器和命令行工具生成AWR报告的方法并详细说明了基线比较、时段对比等不同报告形态的使用场景。分析部分重点解读了缓冲区缓存命中率、硬解析次数、逻辑读取等关键指标同时结合等待事件和活动会话历史记录定位性能瓶颈完整覆盖了从报告导出到问题排查的实战流程。资源为单个PDF文件大小7.13MB内含清晰目录结构方便按章节查阅。目前已有226人浏览学习内容既适合初学者搭建AWR分析框架也能为资深数据库专家提供查漏补缺的参考。1. 数据库突然变慢时为什么先看AWR报告下午三点业务方在工作群丢出一句“系统卡了”监控图上一片绿CPU 30%IO 20%会话数正常但用户就是觉得慢。这时候打开一条SQL去看执行计划大概率找不到问题。我会先拉一份Oracle AWR报告花十分钟把整库的健康状态过一遍。AWR全称Automatic Workload RepositoryOracle每隔一段时间给系统做一次快照记录负载、等待事件、SQL执行统计最终形成一份体检报告。这份报告能回答一个核心问题在这段时间里数据库的时间到底花在了哪里。网上常有人把AWR分析经验整理成PDF标题就叫《Oracle数据库awr报告分析》看标题平平无奇内容全是实战里磨出来的读法。这篇按同样的主线把报告的生成、读法、坑位讲清楚适合刚接触Oracle性能诊断的DBA也适合被SQL慢查反复折磨的开发。2. 从零拿到一份能用的AWR报告快照配置与生成命令生成AWR报告本身只有三步确认快照在收集、确认快照覆盖了你关心的时段、执行报告脚本。但大部分人卡在第一步——不是不会跑脚本而是AWR默认的快照频率和保留时间在排查问题的时候根本不够用。2.1 统计级别与快照参数先在源头把数据配够先检查统计级别这一步决定了AWR到底有没有在采集数据-- 查看当前统计级别 SHOW PARAMETER statistics_level;输出结果里statistics_level的默认值是TYPICAL。如果被误配成BASICAWR直接停止采样报告跑出来基本是空白。ALL比TYPICAL多收集一些细粒度统计比如部分执行计划的详细绑定信息额外开销更大日常诊断用TYPICAL就足够。统计级别没问题后再看快照配置。修改快照间隔和保留时间用的是同一个存储过程-- 间隔30分钟保留14天 BEGIN dbms_workload_repository.modify_snapshot_settings( interval 30, -- 快照间隔单位分钟允许范围10~525600 retention 20160 -- 保留时间单位分钟20160分钟等于14天 ); END; /interval决定两个快照之间的时间距离30分钟意味着一天生成48个快照这是生产环境比较均衡的选择。低于15分钟会显著增大SYSAUX表空间的占用除非正在做专项诊断否则不建议长期开。retention如果只保留7天周一想去回溯上周五的某个异常时段历史快照可能已经被清理掉所以14天是更稳妥的周期。修改快照参数需要SYSDBA权限普通账号执行会报权限错误RAC环境里这个设置是实例级的要对每个节点执行一次。提示修改快照参数需要SYSDBA或至少拥有ADMINISTER DATABASE TRIGGER权限否则会报 ORA-01031 权限不足。2.2 生成报告的三种常用方式交互脚本、Shell自动化和直接函数调用最传统的方式是进入sqlplus后执行AWR报告脚本sqlplus / as sysdba -- 进入sqlplus后执行 ?/rdbms/admin/awrrpt.sql执行后脚本会依次询问报告格式HTML还是文本、要往前追溯几天、起始和结束快照ID。这里的?是ORACLE_HOME的环境变量通配符在11g、12c、19c等主流版本下都通用。文本格式的好处是方便grep但HTML格式可以点击展开SQL的完整文本还能看图表我一般选HTML。第二种方式适合纳入巡检脚本用here-document自动应答交互提示#!/bin/bash # 用here-document自动应答awrrpti.sql的交互问题 sqlplus -S / as sysdba EOF ?/rdbms/admin/awrrpti.sql 1 1 2 101 102 EOF这段脚本里的五次应答分别对应报告类型1为HTML、实例号单实例固定1RAC环境按节点区分、最近2天、起始快照ID、结束快照ID。需要提醒的是不同小版本里awrrpti.sql的交互顺序可能有细微差异第一次跑脚本前先手工执行一遍对照菜单否则自动化流程会在奇怪的位置断掉。第三种方式绕开交互菜单直接调用内建函数适合给研发搭一个自助报告页面-- 直接返回指定快照区间的HTML结果是一个CLOB SELECT dbms_workload_repository.awr_report_html( 3245190735, -- dbid来自v$database 1, -- 实例号单实例固定1 101, -- 起始快照ID 102 -- 结束快照ID ) AS report FROM dual;dbid不同库不一样用SELECT dbid FROM v$database;查。这种方式的好处是研发后台接一个查询就能自己拉取和下载报告不用每次麻烦DBA跑脚本。2.3 生成报告前先确认快照范围别把窗口拉错生成报告之前我习惯先查一遍快照清单确认目标时段有数据覆盖SELECT snap_id, instance_number, begin_interval_time, end_interval_time FROM dba_hist_snapshot WHERE begin_interval_time SYSDATE - 2 ORDER BY snap_id;AWR只统计两个快照之间的数据如果目标时段恰好落在快照间隔的空档里报告覆盖的范围比你预期要小结论自然偏。还有一种特殊情况时段内实例重启过快照会断成两截报告开头会明确标记instance reboot。看到这个标记就放弃从这段数据里找趋势直接看重启前后的单份报告否则会把重启引起的等待全部算进业务问题里。3. 把AWR报告拆开读四个关键区块的读法与判断依据拿到一份HTML报告很多人习惯从中间SQL部分开始看。我建议按头部、负载画像、等待事件、SQL统计的顺序分四个区块读每块只看几个关键数字五到十分钟可以走完第一遍不会漏掉结构性信号。3.1 头部信息与报告边界先确认这份报告在说哪个时段报告第一屏有DB Name、Instance Name、起止时间、Elapsed和DB Time。Elapsed是报告覆盖的墙钟时长DB Time是所有会话花在数据库内部的时间总和。两者相除得到一个核心指标——AASAverage Active Sessions即平均活跃会话数。AAS等于1说明整段时间平均只有一个会话在干活系统基本空闲AAS大于CPU核数意味着大量会话在排队等CPU或其他资源系统已经过载。这个数字决定你接下来怎么读这份报告系统根本不忙问题可能不在数据库内部得去看应用层或外部依赖系统忙到冒烟重点去Top Timed Events找耗时最高的等待事件。注意AAS是平均值五分钟内的瞬时高峰会被一小时平均稀释。定位秒级抖动需要配合ASHAWR负责的是整体趋势。3.2 Load Profile与Top Timed Events先看负载和时间去向Load Profile区域展示每秒级的平均指标逻辑读、物理读、Redo生成量、解析次数。这一块不用逐项盯着看只看两个信号每秒执行次数是否异常放大每秒硬解析是否过高。执行次数放大说明流量型增长SQL本身不一定变慢硬解析每秒超过100大概率是应用没有使用绑定变量大量字面量SQL导致解析开销飙升。Top Timed Events是整份报告的指北针。常见事件的解读差异很大我习惯用一个表格快速对照等待事件出现场景优先排查方向db file sequential read索引扫描、rowid访问SQL访问路径是否走索引、统计信息是否过期db file scattered read全表扫描、索引全扫描是否缺索引、优化器是否误判走全扫log file sync提交时的日志写盘等待提交频率、日志文件所在磁盘延迟enq: TX - row lock contention行锁、唯一索引冲突并发update同一条数据、唯一约束碰撞gc buffer busy acquireRAC节点间块传输等待热点块分布、应用数据访问模式判断口径先算每个事件占用DB Time的百分比超过20%再认真对待。DB CPU排在第一位且占比高说明CPU真的在忙这时候去SQL Statistics里找CPU消耗高的SQL而不是继续在等待事件里纠结。3.3 SQL Statistics按四个维度找到重点SQLSQL Statistics区域有四个排序维度用途完全不同。Elapsed Time维度找累计耗时最长的SQL看是否有单条SQL吃掉大量DB TimeExecutions维度找高频SQL单次执行只要2毫秒、每秒执行上千次累计下来也能吃满一个CPU核Physical Reads维度找物理读大的SQL通常对应全表扫描或巨型索引扫描CPU Time维度找纯CPU烧得最厉害的SQL。判断方法很简单一条SQL的Elapsed Time占DB Time超过20%先停下来看它。占比不高但Executions特别多的要确认是不是被高频循环调用。有个细节容易被忽略——AWR里的Elapsed Time是多次执行的总累计值判断SQL到底慢不慢要看单次平均耗时也就是Elapsed Time除以Executions。如果平均只有几十毫秒问题就不在SQL本身而在调用次数上。3.4 Segment Statistics与等待事件明细落到底层对象SQL定位之后要落到它访问的段对象上。Segment Statistics区域按物理读、逻辑读、行锁等待等维度排序能看到具体是哪个表、哪个索引在承受压力。这里有个联动判断很常用一条SQL物理读高、逻辑读不高说明数据很少命中buffer cache多半是表太大且执行计划走了全量扫描同一SQL逻辑读高、物理读低说明SQL本身访问逻辑复杂比如子查询嵌套过多或过滤条件缺失。等待事件明细区的作用是确认资源瓶颈的具体层级。比如log file sync高去查redo log所在磁盘的平均写耗时db file sequential read高结合Segments by Physical Reads确认是不是同一SQL在同一段对象上反复读。这个区块不是独立看的它是把SQL和资源串起来的桥。4. 一套可复用的分析顺序从负载到根因的完整链路读单个区块不难难的是建立顺序。没有固定顺序的人容易这样先看Top SQL觉得某条最慢改完发现没用再回头看事件又怀疑是IO来回折腾一个下午。我自己的固定顺序是五步每步只回答一个问题不跳步。4.1 五步分析清单每个区块各回答一个问题按固定顺序走报告头部这个时段系统忙不忙看AAS。Load Profile负载画像是什么流量型增长还是单请求劣化。Top Timed Events时间主要花在CPU、IO、锁还是网络。SQL Statistics加Segment Statistics哪条SQL、哪个对象在消耗这块资源。用ASH和ADDM交叉验证聚合结论在个体样本上是否成立。这套顺序的价值在于每一步的产出都是下一步的输入。先判忙闲再判时间去向再到SQL和对象逻辑链不断。很多人跳过了第2步拿到报告直接看Top SQL结果发现Top SQL在报告里占比不到10%真正的问题在等待事件层面方向从一开始就偏了。4.2 一个模拟推演从报告开篇到根因结论构造一份典型的AWR数据来演示完整链路。假设报告覆盖60分钟Elapsed等于60分钟DB Time等于780分钟AAS约等于13。系统在这1小时内平均有13个会话在同时消耗资源属于明显的高负载状态。Top Timed Events里gc buffer busy acquire占42%db file sequential read占22%DB CPU占18%。这个组合说明大部分时间耗在RAC节点间的缓冲区传输等待上CPU反而排在第三位。继续看SQL Statistics发现一条INSERT语句累计Elapsed Time占整个DB Time的35%执行次数5万次平均单次只有几十毫秒——单看不慢但架不住被高频执行。再到Segment Statistics确认该INSERT写入的表上一个以完成时间字段为索引列的对象频繁出现在Buffer Busy Waits排行里。到这里根因已经清楚了多个节点高频插入完成时间字段的索引键值单调递增所有会话都在抢同一个索引右端块块在节点间来回传输就形成了gc buffer busy acquire。对应的修复方向不是改SQLSQL本身的写法和成本都正常。要调整的是索引形态比如把该索引改成哈希分区让插入分散到多个分区右端竞争自然消除。这个例子的关键点在于如果只盯着Top SQL优化永远找不到答案——慢的不是SQL执行本身而是SQL写入时底层索引在竞争。4.3 结论必须验证ASH、ADDM和前后对比AWR是聚合数据它只告诉你这一个小时内发生了大量等待但不说具体是哪些会话在等、等在哪一刻。验证手段有三种。ASH按会话采样能查特定时间点、特定SQL的等待事件分布数据存在dba_hist_active_sess_history里按SQL_ID过滤即可ADDM是Oracle自带的诊断模块快照周期结束后自动生成问题诊断报告给出排名靠前的发现列表最直接的验证是改完之后重拉新时段的AWR对比Top事件占比和DB Time数值是否回落。三种手段都用不上时至少确认一次统计信息和执行计划再动手不要在没验证的情况下上线改动。5. AWR分析避坑与常见问题五个容易翻车的地方AWR分析里最容易出问题的往往不是看不懂报告而是用错了判断口径。下面是五个高频踩坑点每条都按现象、原因和解决方式展开。5.1 平均等待时间不高但等待次数极高现象log file sync的单次等待时间显示2ms觉得完全没有风险但在DB Time里的总占比却排进前三。原因AWR的等待时间统计由单次等待时间和等待次数共同决定。2ms乘以每秒上千次的提交累计起来照样能吞掉大量DB Time。只看了平均值就下结论是最常见的误判。解决同时看Wait Class、总等待次数和每秒等待次数三列不要只看Time per Wait。遇到log file sync高频出现优先想办法降低提交频率比如把循环里的单条commit改成批量提交而不是去调日志盘参数。5.2 快照间隔太小报告里全是短命SQL现象把快照间隔调成10分钟每天生成144个快照结果每份报告的Top SQL都不一样完全没法定位持续性问题。原因采样太密时统计窗口里会混入大量只执行一两次的短命SQLTop列表被这些瞬时SQL占据真正的持续性慢SQL反而被挤下去。解决日常环境用30分钟或60分钟间隔专项诊断时可以临时调成10分钟但诊断结束要马上改回。做趋势对比的两份报告必须使用相同快照间隔否则每秒指标和每小时累计量完全没法比。5.3 把AWR里的Elapsed Time当成SQL实际执行时间现象某条SQL的Elapsed Time显示600秒业务方判断“这条SQL跑一次要10分钟”立刻要求优化。原因AWR记录的是该SQL在统计窗口内所有执行会话的累计时间。如果它在15分钟内被执行了50次单次平均只有12秒。解决用Elapsed Time除以Executions得到单次平均耗时再和业务方感知到的时延对照。若确认是执行次数大导致的累计高先优化调用频率再考虑优化单次执行成本。5.4 拿旧版本的等待事件名直接套到新版本现象在19c环境的AWR报告里找不到buffer busy wait这个事件名以为报告生成异常。原因版本升级过程中等待事件被持续拆分和改名旧事件名在新版本里已经不存在或不再单独采样。解决先用SELECT name FROM v$event_name WHERE name LIKE %buffer%;确认当前版本的事件官方名称再对照报告。事件名的变更本身也是一种性能演化信号新的细粒度事件往往对应更精准的瓶颈定位。5.5 只看Top 5 Events排名忽略负载水平现象Top 5 Timed Events里DB CPU排第一直接判断是CPU瓶颈扩容CPU后问题依旧。原因系统空闲时DB CPU也会排第一。DB CPU不是等待事件只要有任何活动它就会有占比排第一只说明相对占比高不代表系统真的忙。解决先看AAS。AAS小于1.5时系统大部分时间在空闲Top Events排名的参考价值很低此时要往单次事务时延和外部服务依赖方向排查而不是继续在等待事件里打转。6. 进阶技巧用双报告对比找到性能拐点单份AWR报告只描述状态双报告对比才描述变化。一个实用习惯是从业务反馈的变慢时刻往前推取变慢前的一小时和变慢后的一小时各一份报告把关键指标放到同一张表里看。即使不确定确切变慢时刻也可以按快照时间滑动切片把相邻两个小时分别拉报告对比几次就能锁定变化起点。对比时重点看三处。第一处是Load Profile看每秒执行次数和每秒Redo生成量——执行次数翻倍通常意味着流量型增长Redo量暴涨意味着写密集这两个指标能快速区分“请求变多了”和“单个请求变重了”。第二处是Top Timed Events的占比变化某个事件从5%涨到40%就是强烈的拐点信号。第三处是Top SQL按Executions维度排序找出执行次数翻倍的那批SQL而不是平均耗时最长的那些。我习惯用一张固定的对比表记录指标变慢前1小时变慢后1小时变化信号AAS平均活跃会话数314负载放大Executions per second4201350流量型增长Redo size per second180KB1.2MB写放大主要等待事件db file sequential readlog file sync提交链路变化Top SQL执行次数2万9万高频SQL曝光以前排查一个会话连接数暴涨的问题单份AWR怎么看都正常AAS不到2Top Events全是DB CPU。把高峰前后的报告放到这张表里一比发现每秒执行次数半小时内翻了三倍顺着Executions维度找到一条被反复启动的事务批处理SQL最后定位到上游定时任务的重试机制上。那之后就养成了一个习惯条件允许时永远拉两份报告对比不轻易凭单份报告下结论。分析AWR报告本质上就是一层层拆时间先拆到事件再拆到SQL最后拆到对象。希望这份路径对你有帮助。本文还有配套的精品资源点击获取
返回列表