通過Oracle的email實現資料庫自動告警
一、郵件配置部分
1、建立訪問控制列表
BEGIN
dbms_network_acl_admin.create_acl(acl =>email_server_ftoa.xml'
,description =>'FTOA'
,principal =>'SYSTEM'
,is_grant =>TRUE
,privilege =>'connect'
,start_date =>NULL
,end_date => NULL);
END;
/
PL/SQL procedure successfully completed
注意:
(1)這裡privilege要用小寫,否則出現ORA-24245
(2)ACL格式中xml字尾要小寫,否則出現ORA-46059錯誤
2、伺服器授權
BEGIN
dbms_network_acl_admin.assign_acl(acl =>'ftoa_email_server.xml'
,host =>'10.41.128.1'
,lower_port =>85
,upper_port =>85);
END;
/
PL/SQL procedure successfully completed
注意:
(1)acl名稱與上面create的要一樣,否則出現ORA-31001 : 資源控制代碼或路徑名 "/sys/acls/******.xml"
(2)訪問埠需要正確,否則應用發郵件時會出現ORA-24247:網路訪問被訪問控制列表 (ACL)拒絕 錯誤
3、傳送郵件的通用儲存過程
照搬了網上一個現成的儲存過程,蠻好用的
CREATEORREPLACEPROCEDURE P_SENDMAIL(P_TXT VARCHAR2,
P_SUB VARCHAR2,
P_SENDOR VARCHAR2,
P_RECEIVER VARCHAR2,
P_USER VARCHAR2DEFAULTNULL,
P_PASS VARCHAR2DEFAULTNULL,
P_FILENAME VARCHAR2
P_ENCODE VARCHAR2DEFAULT'bit 7')
AUTHIDCURRENT_USERIS
/*
作用:用oracle傳送郵件
主要功能:1、支援多收件人。
2、支援中文
3、支援抄送人
4、支援大於32K的附件
5、支援多行正文
6、支援多附件
7、支援文字附件和二進位制附件
8、支援HTML格式
9、支援
作者:suk
引數說明:
p_txt :郵件正文
p_sub: 郵件標題
p_SendorAddress : 傳送人郵件地址
p_ReceiverAddress : 接收地址,可以同時傳送到多個地址上,地址之間用","或者";"隔開
p_EmailServer : 郵件伺服器地址,可以是域名或者IP
p_Port :郵件伺服器埠
p_need_smtp:是否需要smtp認證,0表示不需要,1表示需要
p_user:smtp驗證需要的使用者名稱
p_pass:smtp驗證需要的密碼
p_filename:附件名稱,必須包含完整的路徑,如"d:\temp\a.txt"。
可以有多個附件,附件名稱只見用逗號或者分號分隔
p_encode:附件編碼轉換格式,其中 p_encode='bit 7' 表示文字型別附件
p_encode='base64'表示二進位制型別附件
注意:
1、對於文字型別的附件,不能用base64的方式傳送,否則出錯
2、對於多個附件只能用同一種格式傳送
*/
二、應用部分
1、建立郵件待發送表、傳送歷史表
droptable MAIL_TOSEND;
createtable MAIL_TOSEND
(
idVARCHAR2(32)notnull,
fsr VARCHAR2(100),
jsr VARCHAR2(4000),
csr VARCHAR2(4000),
yjnr VARCHAR2(2000),
czrq DATE,
pch VARCHAR2(100)notnull
);
altertable MAIL_TOSENDaddconstraintPK_MAIL_TOSENDprimarykey (ID, PCH) usingindex;
commentoncolumnMAIL_TOSEND.id is'序列SEQ_TXID產生';
commentoncolumnMAIL_TOSEND.fsr is'傳送人,預設是admin_sx';
commentoncolumnMAIL_TOSEND.jsr is'接收人,可多個用逗號分隔';
commentoncolumnMAIL_TOSEND.csr is'抄送人,可多個用逗號分隔';
commentoncolumnMAIL_TOSEND.yjnr is'郵件內容,html原始碼';
commentoncolumnMAIL_TOSEND.czrq is'操作日期';
commentoncolumnMAIL_TOSEND.pch is'批次號';
droptable MAIL_SENT;
createtable MAIL_SENT
(
idVARCHAR2(32)notnull,
fsr VARCHAR2(100),
jsr VARCHAR2(4000),
csr VARCHAR2(4000),
yjnr VARCHAR2(2000),
czrq DATE,
fsrq DATE,
fszt NUMBER(1)notnull,
bcxx VARCHAR2(4000),
pch VARCHAR2(100)notnull
);
altertable MAIL_SENTaddconstraint PK_MAIL_SENTprimarykey (PCH,ID, FSZT)usingindex;
commentoncolumnMAIL_SENT.id is'序列號';
commentoncolumnMAIL_SENT.fsr is'傳送人';
commentoncolumnMAIL_SENT.jsr is'接收人';
commentoncolumnMAIL_SENT.csr is'抄送人';
commentoncolumnMAIL_SENT.yjnr is'郵件內容';
commentoncolumnMAIL_SENT.czrq is'操作日期';
commentoncolumnMAIL_SENT.fsrq is'傳送日期';
commentoncolumnMAIL_SENT.fszt is'傳送狀態1:成功 0';
commentoncolumnMAIL_SENT.bcxx is'報錯資訊';
commentoncolumnMAIL_SENT.pch is'批次號';
2、收集告警資訊併發送郵件的儲存過程
根據個人需求不同,選擇不同的收集物件,我這裡主要跟蹤3個內容:
(1)GoldenGate的錯誤
--建立GoldenGate日誌外部表
createorreplacedirectory gg_dir as'/gg';
droptable ggserr_log_ext;
createtable ggserr_log_ext
(
txt varchar2(2000)
)
organizationexternal
(
type oracle_loader
defaultdirectory gg_dir
accessparameters
(
records delimitedby newline
fields terminatedby "\r\n"
)
location('ggserr.log'));
--收集GoldenGate故障
select WM_CONCAT(MSG)from(
select'<br> <br/> GoldenGate同步故障:<br> <br /> 開始時間:'||to_char(min(dt),'yyyy-mm-ddhh24:mi:ss')
||'<br> <br />故障資訊:'||ERRMSG MSG
from (Select TO_DATE(SUBSTR(TXT,1,19),'YYYY-MM-DD HH24:MI:SS')DT,SUBSTR(TXT,INSTR(TXT,',')+2) ERRMSG
from ggserr_log_extwhere txtlike'%ERROR%'AND TXTNOTLIKE'%ABEND%')
groupby ERRMSGhavingmax(dt)>sysdate-1/24 );
(2)alert告警
--建立alert外部表
createorreplacedirectory alert_dir as'/orahome/app/oracle/diag/rdbms/sxcz/sxcz/trace';
droptable alert_log_ext;
createtable alert_log_ext
(
text varchar2(2000)
)
organizationexternal
(
type oracle_loader
defaultdirectory alert_dir
accessparameters
(
records delimitedby newline
fields terminatedby "\r\n"
)
location('alert_sxcz.log'));
--收集ALERT日誌告警
with t_alertas
(select ROWNUM r,casewhen text like'%__:__:__ 20__%'then'DT'ELSE'EXCEPTION'ENDASTYPE,TEXT
from alert_log_ext
where UPPER(text)like'%ORA-%'
OR textlike'%__:__:__ 20__%')
select WM_CONCAT(MSG)from(
select V_MSG2||'<br><br /> Alert告警:<br> <br /> 開始時間:'||to_char(min(start_time),'yyyy-mm-dd hh24:mi:ss')
||'-'||to_char(max(start_time),'yyyy-mm-dd hh24:mi:ss')
||'<br> <br />告警資訊:'||text MSG
from
(
select r,casewhen start_time isnullthenlag(to_date(start_time,'Dy Mon DDHH24:MI:SS YYYY','NLS_DATE_LANGUAGE=AMERICAN') ignorenulls) over(orderby r) else to_date(start_time,'Dy Mon DD HH24:MI:SS YYYY','NLS_DATE_LANGUAGE=AMERICAN')end start_time,textfrom
(
select r,type,text,lagtype,casewhen lagtype='DT'then Lag(text,1) OVER(ORDERBY R)elsenullend start_timefrom
(
select r,TYPE,text,lag(type,1) OVER(ORDERBY R) lagtype
from t_alert
)
) wheretype='EXCEPTION'
)
groupby text);
(2)broken狀態的job
select WM_CONCAT('<br> <br /> JOB停止執行:<br> <br /> JOB_ID:'||JOB||'<br> <br />USER:'||log_user
||'<br> <br /> STOP_TIME:'||TO_CHAR(LAST_DATE,'YYYY-MM-DDHH24:MI:SS')
||'<br> <br /> CONTENTS:'||CHR(13)||CHR(9)||WHAT)
from dba_jobs
where BROKEN='Y'AND LOG_USER NOT IN('SYS','SYSTEM');
這個程式還涉及到不同的告警傳送給不同的使用者,內容重複的告警如何處理等具體處理,不在一一表述,還是這句話,根據自己的需求做處理。
3、把寫好的儲存過程放在job或者伺服器crontab裡定時執行,這是我收到的郵件