python 与oracle 发送邮件-阿里云开发者社区

开发者社区> 数据库> 正文

python 与oracle 发送邮件

简介: Oracle AWR 报告 每天自动生成并发送邮箱  Python脚本Oracle AWR 报告 每天自动生成并发送邮箱  Python脚本               Oracle 的AWR 报告能很好的提供有关DB性能的信息。
Oracle AWR 报告 每天自动生成并发送邮箱  Python脚本Oracle AWR 报告 每天自动生成并发送邮箱  Python脚本


            
 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_html和awr_report_text。
(2)dbid,inst_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的信息。


(3)rpt_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 指定的,可以生成其他名称。




三. 自动上传AWR的Python脚本


 在这个脚本里做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.远程连接数据库,并登录执行相应查询语句
修改$ORACLE_HOME/network/admin/tnsnam.ora
119 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST =IP)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = test)
)
)
书写远程连接和执行脚本
#!/bin/sh
su - oracle -c "sqlplus 'user/passwd@119 " <<EOF
@/data/admin/job
@/data/admin/space
quit
EOF
2.书写查询语句/data/admin/job.sql
set pages 50000;
set lines 200;
set trims on;
spool /data/admin/job;
select job,to_char(last_date,'YYYY-MM-DD HH24:MI:SS') last_date,to_char(next_date,'YYYY-MM-DD HH24:MI:SS') next_date,broken broken ,failures from user_jobs ;
col "Tablespace Name" for a20
col "Total Size" for a10
col "Used MB" for a15
col "Free MB" for a15
spool /data/admin/job append (附加到job.lst中查看表空间利用情况)
select b.file_id "File#",b.tablespace_name "Tablespace Name",b.bytes/1048576||'M' "Total Size",(b.bytes-sum(nvl(a.bytes,0)))/1048576||'M' "Used MB",sum(nvl(a.bytes/1048576,0))||'M' "Free MB",sum(nvl(a.bytes,0))/(b.bytes)*100 "Free%" from dba_free_space a,dba_data_files b where a.file_id=b.file_id group by b.tablespace_name,b.file_id,b.bytes order by b.file_id;
spool off;
3.生成可写的SPOOL文件 job.lst 并chmod 755权限,可以让ORACLE写入查询结果。
4.用MAIL命令行EMAIL到指定的多个用户,中间用空格就行。
cat /data/admin/job.lst |mail -s "oracle synlog " user@email.com user2@email.com
5.crontab -e 定时执行查询语句和发邮件到指定帐号
00 7 * * * /data/admin/synjob.sh
30 7 * * * /data/admin/mail.sh
[@more@]


 
 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
数据库
使用钉钉扫一扫加入圈子
+ 订阅

分享数据库前沿,解构实战干货,推动数据库技术变革

其他文章