设为首页 收藏本站
查看: 975|回复: 0

[经验分享] Oracle AWR 报告 每天自动生成并发送邮箱 Python脚本

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-12-15 09:08:19 | 显示全部楼层 |阅读模式
http://blog.csdn.net/tianlesoftware/article/details/6319198
      Oracle AWR 报告能很好的提供有关DB性能的信息。 所以DBA 需要定期的查看AWR的报告。 有关AWR报告的说明参考:         Oracle AWR 介绍
         http://blog.csdn.net/tianlesoftware/archive/2009/10/17/4682300.aspx
  
         如果说每天都去手工的出创建AWR报告,是个费时的活。 所以,最好就是弄成脚本来执行。 这篇文章就是说明这个问题的。
  
         注意的一个问题,AWR 报告的两个snap 之间不能有重启DB的操作。
  
  Python 执行 系统命令
  http://blog.csdn.net/tianlesoftware/archive/2011/02/17/6192202.aspx
  
  Python 发送带 附件 邮件 脚本
  http://blog.csdn.net/tianlesoftware/archive/2011/04/12/6318199.aspx
  
  
  . 准备工作
  
         一般我们都是条用awrrpt.sql 来创建我们的AWR报告。 我们先看下这个脚本的具体内容:
  [oracle@rac1 admin]$ cat awrrpt.sql | grep -v 'Rem'|grep -v '^--'
  set echo off heading on underline on;
  column inst_num  heading "Inst Num"  new_value inst_num  format 99999;
  column inst_name heading "Instance"  new_value inst_name format a12;
  column db_name   heading "DB Name"   new_value db_name   format a12;
  column dbid      heading "DB Id"     new_value dbid      format 9999999999 just c;
  
  prompt
  prompt Current Instance
  prompt ~~~~~~~~~~~~~~~~
  
  select d.dbid            dbid
       , d.name            db_name
       , i.instance_number inst_num
       , i.instance_name   inst_name
    from v$database d,
         v$instance i;
  
  @@awrrpti
  
  undefine num_days;
  undefine report_type;
  undefine report_name;
  undefine begin_snap;
  undefine end_snap;
  
         在以上的脚本里,我们发现它只是生成了一些变量,然后把这些变量传给了另一个脚本:awrrpti.sql 我们看下awrrpti.sql 脚本的具体内容:
  
  [oracle@rac1 admin]$ cat awrrpti.sql | grep -v 'Rem'|grep -v '^--'  
  
  set echo off;
  set veri off;
  set feedback off;
  
  variable rpt_options number;
  
  define NO_OPTIONS   = 0;
  define ENABLE_ADDM  = 8;
  
  
  begin
    :rpt_options := &NO_OPTIONS;
  end;
  /
  
  prompt
  prompt Specify the Report Type
  prompt ~~~~~~~~~~~~~~~~~~~~~~~
  prompt Would you like an HTML report, or a plain text report?
  prompt Enter 'html' for an HTML report, or 'text' for plain text
  prompt  Defaults to 'html'
  
  column report_type new_value report_type;
  set heading off;
  select 'Type Specified: ',lower(nvl('&&report_type','html')) report_type from dual;
  set heading on;
  
  set termout off;
  column ext new_value ext;
  select '.html' ext from dual where lower('&&report_type') <> 'text';
  select '.txt' ext from dual where lower('&&report_type') = 'text';
  set termout on;
  
  @@awrinput.sql
  -- 这个脚本主要是确定SNAP的。
  @@awrinpnm.sql 'awrrpt_' &&ext
  -- 这个脚本主要是确定AWR 文件名称的
  
  set termout off;
  column fn_name new_value fn_name noprint;
  select 'awr_report_text' fn_name from dual where lower('&report_type') = 'text';
  select 'awr_report_html' fn_name from dual where lower('&report_type') <> 'text';
  
  column lnsz new_value lnsz noprint;
  select '80' lnsz from dual where lower('&report_type') = 'text';
  select '1500' lnsz from dual where lower('&report_type') <> 'text';
  
  set linesize &lnsz;
  set termout on;
  spool &report_name;
  
  select output from table(dbms_workload_repository.&fn_name( :dbid,
                                                      :inst_num,
                                                      :bid, :eid,
                                                      :rpt_options ));
  
  
  spool off;
  
  prompt Report written to &report_name.
  
  set termout off;
  clear columns sql;
  ttitle off;
  btitle off;
  repfooter off;
  set linesize 78 termout on feedback 6 heading on;
  undefine report_name
  
  undefine report_type
  undefine ext
  undefine fn_name
  undefine lnsz
  
  undefine NO_OPTIONS
  undefine ENABLE_ADDM
  
  undefine top_n_events
  undefine num_days
  undefine top_n_sql
  undefine top_pct_sql
  undefine sh_mem_threshold
  undefine top_n_segstat
  
  whenever sqlerror continue;
  [oracle@rac1 admin]$
  
  
         这个脚本才是我们真正生成AWR的脚本。 在这个脚本里面,提示我们选择AWR报告的类型。
  
  
  通过上面的2个脚本,我们将AWR报告简化一下:
         select output from
  table(dbms_workload_repository.&fn_name(:dbid, :inst_num,:bid, :eid,:rpt_options ));
  
  这条语句就是整个AWR报告的核心:
  1&fn_name 决定AWR报告的类型,有2个值:awr_report_htmlawr_report_text
  2dbidinst_num,bid,eid 可以通过dba_hist_snapshot查询. bid 指的是begin snap_id, eid 指的是end snap_id.
  
  
  SQL> select * from (select snap_id,dbid,instance_number from dba_hist_snapshot  order by snap_id) where rownum<10;
  
     SNAP_ID       DBID INSTANCE_NUMBER
  ---------- ---------- ---------------
         184  809910293               2
         184  809910293               1
         185  809910293               2
         185  809910293               1
         186  809910293               2
         186  809910293               1
         187  809910293               2
         187  809910293               1
         188  809910293               2
  
  9 rows selected.
  
         我这里是个RAC 环境, 通过这个可以看出在每个节点上都保存着AWR的信息。
  
  3rpt_options:该参数控制是否显示ADDM的。
  --  NO_OPTIONS -
  --    No options. Setting this will not show the ADDM
  --    specific portions of the report.
  --    This is the default setting.
  --
  --  ENABLE_ADDM -
  --    Show the ADDM specific portions of the report.
  --    These sections include the Buffer Pool Advice,
  --    Shared Pool Advice, PGA Target Advice, and
  --    Wait Class sections.
  define NO_OPTIONS   = 0;
  define ENABLE_ADDM  = 8;
  
  
  有了上面的数据之后,我们就可以使用如下SQL直接生成AWR报告了。
  SQL>select output from table(dbms_workload_repository.awr_report_html(809910293, 2,220,230,0));
  
  SQL>select output from table(dbms_workload_repository.awr_report_text(809910293, 2,220,230,0));
  
  
  . 生成AWR报告 SQL脚本
         以上写了这么多,就是为了一个脚本:myawrrpt.sql. 这个脚本就是自动的去收集信息。 因为如果我们是调用awrrpt.sql的话,需要输入一些参数。 我们修改一下脚本,让它根据我们的需求来收集信息,这样就不用输入参数了。
  
  [oracle@rac1 admin]$ cat myawrrpt.sql
  conn / as sysdba;
  set echo off;
  set veri off;
  set feedback off;
  set termout on;
  set heading off;
  
  variable rpt_options number;
  
  define NO_OPTIONS = 0;
  define ENABLE_ADDM = 8;
  
  -- according to your needs, the value can be 'text' or 'html'
  define report_type='html';
  begin
  :rpt_options := &NO_OPTIONS;
  end;
  /
  
  variable dbid number;
  variable inst_num number;
  variable bid number;
  variable eid number;
  begin
  select max(snap_id)-48 into :bid from dba_hist_snapshot;
  select max(snap_id) into :eid from dba_hist_snapshot;
  select dbid into :dbid from v$database;
  select instance_number into :inst_num from v$instance;
  end;
  /
  
  column ext new_value ext noprint
  column fn_name new_value fn_name noprint;
  column lnsz new_value lnsz noprint;
  
  --select 'txt' ext from dual where lower('&report_type') = 'text';
  select 'html' ext from dual where lower('&report_type') = 'html';
  --select 'awr_report_text' fn_name from dual where lower('&report_type') = 'text';
  select 'awr_report_html' fn_name from dual where lower('&report_type') = 'html';
  --select '80' lnsz from dual where lower('&report_type') = 'text';
  select '1500' lnsz from dual where lower('&report_type') = 'html';
  
  set linesize &lnsz;
  
  -- print the AWR results into the report_name file using the spool command:
  
  column report_name new_value report_name noprint;
  select 'awr'||'.'||'&ext' report_name from dual;
  set termout off;
  spool &report_name;
  select output from table(dbms_workload_repository.&fn_name(:dbid, :inst_num,:bid, :eid,:rpt_options ));
  spool off;
  
  
  set termout on;
  clear columns sql;
  ttitle off;
  btitle off;
  repfooter off;
  undefine report_name
  undefine report_type
  undefine fn_name
  undefine lnsz
  undefine NO_OPTIONS
  exit
  [oracle@rac1 admin]$
  
         这个脚本是收集过去48个小时的snap 来生成AWR 生成的文件名称是awr .html,这个也是spool 指定的,可以生成其他名称。
  
  
  . 自动上传AWRPython脚本
  
         在这个脚本里做2件事,第一是调用第二步里的SQL脚本,生成awr报告,然后将AWR 发送到指定邮箱。
  
  
  createSendAWR.py
  
  #!/usr/bin/python
  #coding=gbk
  #created by tianlesoftware
  #2011-4-12
  
  import os
  import sys
  import smtplib
  import pickle
  import mimetypes
  from email.MIMEText import MIMEText
  from email.MIMEImage import MIMEImage
  from email.MIMEMultipart import MIMEMultipart
  
  
  SMTP_SERVER='192.168.1.120'
  EMAIL_USER='user'
  EMAIL_PASSWD='pwd'
  EMAIL_SUBJECT='192.168.88.209 AWR Report'
  FROM_USER='daimingming@1876.cn'
  TO_USERS=['daimingming@1876.cn','dvd.dba@gmail.com']
  
  
  def createawr():
    pipe = os.popen(' /u01/app/oracle/product/10.2.0/db_1/bin/sqlplus /nolog @awrrpt.sql')
  
  def mysendmail(fromaddr,toaddrs,subject):
  
          COMMASPACE=','
          msg = MIMEMultipart()
          msg['From'] = fromaddr
          msg['To'] = COMMASPACE.join(toaddrs)
          msg['Subject'] = subject
  
        
          txt = MIMEText("192.168.88.209 AWR Report, The report be send at 9 AM every day ")
          msg.attach(txt)   
    
     
          fileName = r'/home/oracle/awr.html'
          ctype, encoding = mimetypes.guess_type(fileName)
          if ctype is None or encoding is not None:
              ctype = 'application/octet-stream'
          maintype, subtype = ctype.split('/', 1)
          att = MIMEImage((lambda f: (f.read(), f.close()))(open(fileName, 'rb'))[0], _subtype = subtype)
          att.add_header('Content-Disposition', 'attachment', filename = fileName)
          msg.attach(att)   
  
          server=smtplib.SMTP(SMTP_SERVER)
          server.login(EMAIL_USER,EMAIL_PASSWD)
          server.sendmail(fromaddr,toaddrs,msg.as_string())
          server.quit()
  
  if __name__=='__main__':
                 createawr()
          mysendmail(FROM_USER, TO_USERS, EMAIL_SUBJECT)
          #print 'send successful'
  
  
  . Python 添加到crontab
  
  
  [oracle@qs-wg-db1 scripts]$ crontab -l
  
  40 17 * * * export ORACLE_HOME='/home/oracle_app' && ORACLE_SID=XX  &&cd /u01/backup/scripts && /u01/backup/scripts/createSendAWR.py >/u01/backup/scripts/createSendAWR.log 2>&1
  
  我这里因为报了
  SP2-0750: You may need to set ORACLE_HOME to your Oracle software directory
  的错误,所以把变量加了上去。
  
  
    Linux Crontab 定时任务 命令详解
    http://blog.csdn.net/tianlesoftware/archive/2010/02/21/5315039.aspx

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-151357-1-1.html 上篇帖子: LinkStack linkQueue 的实现,摘自Data Structures and Algorithms in python 下篇帖子: python 杂记 (一)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表