批量生成AWR报告

最近在做优化,涉及的系统较多,发现弄AWR是个体力活,我的上一篇博文解决了如何从客户的生成环境下将AWR数据导入到自己的机子,博文地址:http://blog.itpub.net/29821678/viewspace-1377260/。但是,导入之后问题来了,我需要分析近一个月的AWR报告,每隔一个小时生成一个AWR报告,那么一天我就得生成24个报告,一个月就得生成720个,我这有10多个系统,就需要生成7000多个AWR,每个AWR都得去执行@?/rdbms/admin/awrrpti.sql,还得输入几个参数。想想这个工作量,这画面太美。。。不敢直视啊!对于一个懒人,这怎么能忍,这个必须自动化。

我们首先来看下awrrpti.sql脚本的内容,其中的各种花招我们都略去,直接看到下面的代码行:

  1. -- call the table function to generate the report
  2. select output from table(dbms_workload_repository.&fn_name( :dbid,
  3.                                                             :inst_num,
  4.                                                             :bid, :eid,
  5.                                                             :rpt_options ));

这个注释是本身就带着的,oracle在这里也很直接。就是说,我们在生成AWR报告的时候,调用的就是这段代码。括号中的参数都很好理解了,就不解释了。&fn_name,这个参数根据代码走读发现,就是生成AWR报告的格式,text格式那是不能忍受的,这里我就直接选择html格式了,那么&fn_name就可以变成awr_report_html。其余代码,有兴趣的童鞋可以执行研究下,下面就是我改写的批量生成AWR报告的脚本:

  1. set serveroutput on;
  2. set feedback off;
  3. set linesize 300;
  4. prompt ***************************************************************;
  5. prompt usage:
  6. prompt 1.noninteractive : SQL>@awrrpt_batch.sql dbid instance_num start_snap end_snap;
  7. prompt 2.interactive : SQL>@awrrpt_batch.sql;
  8. prompt author : Darren_Guo
  9. prompt ***************************************************************;
  10. pause press enter to continue or ctrl-c to exit.;
  11. col snap_id for 999999999;
  12. col snap dbid 9999999999;
  13. col startup_time for a30;
  14. col begin_interval_time for a30;
  15. col end_interval_time for a30;
  16. select dbid,snap_id,instance_number,startup_time,begin_interval_time,end_interval_time from dba_hist_snapshot order by dbid,instance_number,snap_id,;
  17. exec dbms_output.put_line(chr(13)||chr(10)||'please enter dbid,inst_number,start and end snap_id:');
  18. declare
  19. v_dbid number;
  20. v_instance number;
  21. v_b_id number;
  22. v_e_id number;
  23. v_code number;
  24. v_errm varchar2(300);
  25. v_sql varchar2(300);
  26. v_html varchar2(20000);
  27. cur_awrrpt_html SYS_REFCURSOR;
  28. cur_snapshot SYS_REFCURSOR;
  29. fileID utl_file.file_type;
  30. v_filename varchar2(30);
  31. v_snap_id number;
  32. v_startup_time timestamp(3);
  33. v_begin_snap_time timestamp(3);
  34. v_end_snap_time timestamp(3);
  35. v_dpath varchar2(60);
  36. begin
  37. v_dbid:=&1;
  38. v_instance:=&2;
  39. v_b_id:=&3;
  40. v_e_id:=&4;
  41. dbms_output.put_line(chr(13)||chr(10)||'awrrpt report files:');
  42. for k in v_b_id..v_e_id-1 loop
  43. v_filename:='gyl_'||k||'_'||(k+1)||'.html';
  44. fileID:=utl_file.fopen('DATA_PUMP_DIR',v_filename,'a',32767);
  45. v_sql:='select output from table(dbms_workload_repository.awr_report_html('||v_dbid||','||v_instance||','||k||','||(k+1)||',8))';
  46. open cur_awrrpt_html for v_sql;
  47. loop
  48. exit when cur_awrrpt_html%notfound;
  49. fetch cur_awrrpt_html into v_html;
  50. utl_file.put_line(fileID,v_html);
  51. end loop;
  52. utl_file.fclose(fileID);
  53. execute immediate 'select directory_path from dba_directories where directory_name=:dname' into v_dpath using 'DATA_PUMP_DIR';
  54. dbms_output.put_line(v_dpath||v_filename);
  55. end loop;
  56. exception
  57. when others then
  58. v_code:=SQLCODE;
  59. v_errm:=SQLERRM;
  60. dbms_output.put_line('ERROR CODE'||v_code||':'||v_errm);
  61. end;
  62. /

运行脚本后,根据提示,依次输入dbid、instance_number、开始 snap_id和结束snap_id,脚本会按snap_id,每隔一个小时生成一个AWR报告。写到这里,突然想到一个问题,可能有的童鞋会认为,为什么不用一个月的AWR数据生成一个报告,那样不是更省事吗?这样理论上是可以的,但是这样的AWR报告对分析系统的性能瓶颈是无意义的,因为其中的大部分问题都可能由于时间跨度太长而被稀释,很难反映出系统的真实情况;另外,几乎所有的系统都存在业务高峰期,如果AWR的时间跨度太大,就没办法分析到业务高峰期间的情况,而这部分数据对于解决系统性能瓶颈是至关重要的。所以,AWR报告的时间跨度最好不要超过一个小时。

作者:Darren_Guo

来源:http://m.blog.itpub.net/29821678/viewspace-1377588/


如果给你带来帮助,欢迎微信或支付宝扫一扫,赞一下。