那天早上刚到公司,运维同事就急匆匆跑过来:"老张,快帮忙看看!监控显示Oracle数据库服务器的CPU使用率飙到70%多,业务部门已经反馈系统变慢了。"作为一名和Oracle打了十年交道的DBA,我立刻意识到这可能是典型的数据库性能问题。不过别慌,咱们手里有Oracle自带的"体检报告"——AWR(Automatic Workload Repository)报告,它能帮我们快速定位问题。
首先登录数据库服务器,切换到oracle用户,用sqlplus连接数据库:
bash复制su - oracle
sqlplus / as sysdba
然后执行AWR报告生成脚本。这里有个小技巧:选择快照时间段时,最好包含问题发生前后的时间点。比如这次CPU高负载发生在上午9点到晚上10点,我就选择了这个时间段的两个snapshot ID:
sql复制@?/rdbms/admin/awrrpt.sql
生成的报告默认保存在/home/oracle目录下,是个HTML文件。我把它下载到本地用浏览器打开,一份详尽的数据库"体检报告"就展现在眼前了。这里提醒新手注意:AWR报告默认保留8天数据,遇到性能问题要第一时间生成报告,否则关键数据可能被自动清理掉。
打开报告后,我首先关注"Load Profile"和"Instance Efficiency"这两个板块。这就好比医生先看病人的体温和血压——数据库的"生命体征"。在本次案例中,几个关键指标亮起了红灯:
翻到"Top 5 Timed Events"部分,这里列出了数据库最耗时的等待事件。不出所料,DB CPU以85%的占比高居榜首,这意味着CPU资源确实被数据库操作大量占用。其他等待事件如"db file sequential read"只占5%,进一步验证了问题出在CPU计算而非磁盘I/O上。
这里有个经验分享:当DB CPU是主要等待事件时,通常意味着:
顺着报告来到"SQL Statistics"部分,这里按资源消耗排序列出了所有SQL语句。我发现两条SQL特别突出:
sql复制select COUNT(*) from EDU_COURSE_CLASS_STUINFO where CLASS_ID=:1
sql复制select * from SYNDATA where synflag=:1 order by createtime
第一条SQL看似简单——只是根据CLASS_ID计数。我手动执行测试发现单次执行只需0.1秒,但架不住每秒执行12次的高频率。这种场景下,数据库层面的优化空间确实有限,于是我建议:
最终开发团队采用了Redis方案,将数据库查询频率从12次/秒降到了1次/分钟。
第二条SQL的分析更有意思。SYNDATA表有300万条数据,当synflag=1时查询需要16秒,=2时只需1秒。检查字段特征:
与开发沟通后了解到,这是数据同步程序在轮询检查新数据。于是我们做了个巧妙调整:
sql复制select * from SYNDATA
where synflag=:1
and createtime >= trunc(sysdate)
order by createtime
优化点在于:
改造后查询时间从1秒降到0.1秒,CPU使用率直接下降了30%。
除了具体SQL优化,AWR报告还揭示了几个系统级问题:
实施这些优化后,数据库CPU使用率从70%降至20%左右,业务响应时间提升60%。这次经历再次证明:AWR报告就像数据库的X光片,能帮我们精准定位性能病灶。关键是要掌握正确的分析方法,把抽象的数据转化为具体的优化动作。