闲话不说直接上脚本。
用于再rac环境下监控本机所有非standby db的blocking 情况。11g应该也适用。

blocking2.sql

set serveroutput on
set lines 300
declare
v_msg varchar2(20000);
v_title varchar2(20000);
v_find_obj_sql varchar2(20000);
v_full_sql_txt varchar2(20000);
v_objname varchar2(30) ;
function send_mail(vc_subject in varchar2,vc_message in varchar2)return pls_integer
asmail_sendr constant varchar(32) := 'db@dex.com';mail_recpt constant varchar(32) := 'db@dex.com';
BEGINUTL_MAIL.send(sender => mail_sendr,recipients => mail_recpt,subject => vc_subject,message => vc_message,mime_type => 'text; charset=us-ascii');return 1;
exception when others thenreturn 0;
END;
function get_full_sqltext(vc_sqlid in varchar2) return varchar2
asv_find_sql_txt varchar2(20000) ;v_sql_txt varchar2(20000) ;
beginv_find_sql_txt := 'select max(dbms_lob.substr(sql_fulltext)) FULL_TEXT from v$sql where sql_id=:sqlid ';execute immediate v_find_sql_txt into v_sql_txt using vc_sqlid;return v_sql_txt ;
end;begin
v_find_obj_sql := 'select max(o.owner) || ''.'' ||max(o.object_name) || nvl2 (max(subobject_name), ''.'' || max(subobject_name), null) obj_name from containers(dba_objects) o where o.object_id=:objid and o.con_id=:conid' ;
for rec in (select'Container '||p.name||' Session '||a.sid||' is blokcing session '||b.sid||' duration: '|| lpad (to_char (trunc (w.ctime / 3600)), 3, '0') || ':' ||lpad (to_char (mod (trunc (w.ctime / 60), 60)), 2, '0') || ':' ||lpad (to_char (mod (w.ctime, 60)), 2, '0')||' Lock type ' ||h.type summary,
'Blocker SID                :' || a.sid ||chr(10)||
'Blocker Username           :' || a.username ||chr(10)||
'Blocker App Machine        :' || a.machine ||chr(10)||
'Blocker Serial number      :' || a.serial# ||chr(10)||
'Blocker Current Status     :' || a.status ||chr(10)||
'Blocker SQL ID current     :' || a.sql_id ||chr(10)||
'Blocker Previous SQL ID    :' || a.prev_sql_id ||chr(10)||
'Blocker KCML Partition No  :' || a.module ||chr(10)||
'Blocker Program name       :' || a.program ||chr(10)||
'Blocker Client Information :' || a.client_info ||chr(10)||
'Blocker Application UUID   :' || a.ecid ||chr(10)||
'Waiter  SID                :' || b.sid||chr(10)||
'Waiter  Username           :' || b.username ||chr(10)||
'Waiter  App Machine        :' || b.machine ||chr(10)||
'Waiter  Serial number      :' || b.serial# ||chr(10)||
'Waiter  Current Status     :' || b.status ||chr(10)||
'Waiter  SQL ID current     :' || b.sql_id ||chr(10)||
'Waiter  Previous SQL ID    :' || b.prev_sql_id ||chr(10)||
'Waiter  KCML Partition No  :' || b.module ||chr(10)||
'Waiter  Program name       :' || b.program ||chr(10)||
'Waiter  Client Information :' || b.client_info ||chr(10)||
'Waiter  Application UUID   :' || b.ecid details,a.sql_id b_sql_id,a.prev_sql_id b_prev_sql_id,b.sql_id w_sql_id,b.prev_sql_id w_prev_sql_id,p.name pdbname,p.con_id,decode (w.type, 'TX', b.row_wait_obj#,'TM', w.id1) obj_idfrom v$lock h, v$lock w, v$session b, v$session a , v$pdbs pwhere h.block   != 0and h.lmode   != 0and h.lmode   != 1and w.request != 0and w.id1     = h.id1and w.id2     = h.id2and h.sid     = a.sidand w.sid     = b.sidand w.con_id=p.con_id and h.ctime > 901)  loop
execute immediate v_find_obj_sql into v_objname using rec.obj_id,rec.con_id;
v_msg := rec.summary || chr(10) || 'Locked object :' || v_objname || chr(10) ||rec.details;
v_title := sys_context('USERENV','INSTANCE_NAME')||'_'||rec.pdbname||'_12c_oracle_15';
v_msg := v_msg || chr(10) || 'Additional sql text:'|| chr(10) ;
if rec.b_sql_id is not null then
v_msg := v_msg || chr(10) || rec.b_sql_id ||':'||chr(10) ||get_full_sqltext(rec.b_sql_id);
end if ;
if rec.w_sql_id is not null then
v_msg := v_msg || chr(10) || rec.w_sql_id ||':'||chr(10) ||get_full_sqltext(rec.w_sql_id);
end if ;
if rec.b_prev_sql_id is not null then
v_msg := v_msg || chr(10) || rec.b_prev_sql_id ||':'||chr(10) ||get_full_sqltext(rec.b_prev_sql_id);
end if ;
if rec.w_prev_sql_id is not null then
v_msg := v_msg || chr(10) || rec.w_prev_sql_id ||':'||chr(10) ||get_full_sqltext(rec.w_prev_sql_id);
end if ;
#dbms_output.put_line(v_msg) ;
#dbms_output.put_line(v_title) ;
#dbms_output.put_line(send_mail(v_title,v_msg)) ;
end loop ;
end;
/
exit;

这里单独取object name是因为再cdb里面不存储single pdb的 object 信息。
所以只能使用containers()函数获取。还需要注意的是,如果在plsql 块的sql里面使用containers函数会出现无法编译的情况,所以这里只能使用动态sql。

local_db_blocking_check_15.sh

#!/bin/bash
OLDPATH=$PATH
export PATH=$PATH:/usr/local/bin
SCRIPTDIR=/oracle/src/scripts/monitoring
SCANADDR=$(hostname | awk -F- '{print $1"-"$2"-"$3"-scan"}')
QWERTY=QAZ2wsx3edc
PORT=1521#echo date >> /tmp/blocking_monitoring.logfunction Role_Check {CONNECTTO=$1DB_ROLE=NONE# Database role check
DB_ROLE=$(sqlplus -s system/"${QWERTY}"@${SCANADDR}:${PORT}/${CONNECTTO} <<EOFset pagesize 0set heading offset feedback offSELECT database_role FROM v\$database;exit;
EOF
)}
ORACLE_SID=$(ps -eaf | grep -i smon | cut -d_ -f3 | grep +)# Use ORAENV_ASK set to NO to prevent prompting, but instead use the SID value set aboveORAENV_ASK=NO. oraenv for db_uniq in $(srvctl config database)
doRole_Check ${db_uniq}if [ "${DB_ROLE}" == "PRIMARY" ]; thensqlplus -s sys/"${QWERTY}"@${SCANADDR}:${PORT}/${db_uniq} as sysdba  @${SCRIPTDIR}/BASE/blocking2.sql fi
done

这个就没什么好说的了。

最后只要把
local_db_blocking_check_15.sh
放到corntab 里面就可以了,一般是15分钟检查一次。如果要修改频率,记得再sql 里面修改h.ctime > 901 的 时间间隔。

最后注意两点:

  1. UTL_MAIL 记得开启权限
  2. 我们的scan addr是有规律的,所以如果要使用你们自己的环境记得修改这部分shell代码。
    SCANADDR=$(hostname | awk -F- ‘{print $1"-"$2"-"$3"-scan"}’)

附录:

检查blocking脚本是类似于这样的:

select /*+ rule */'Container '||p.name||' Session '||a.sid||' is blokcing session '||b.sid||' by object '||o.owner || '.' || o.object_name ||nvl2 (subobject_name, '.' || subobject_name, null)||' duration: '|| lpad (to_char (trunc (w.ctime / 3600)), 3, '0') || ':' ||lpad (to_char (mod (trunc (w.ctime / 60), 60)), 2, '0') || ':' ||lpad (to_char (mod (w.ctime, 60)), 2, '0')||' Lock type ' ||h.type summary,
'Blocker SID                :' || a.sid ||chr(10)||
'Blocker Username           :' || a.username ||chr(10)||
'Blocker App Machine        :' || a.machine ||chr(10)||
'Blocker Serial number      :' || a.serial# ||chr(10)||
'Blocker Current Status     :' || a.status ||chr(10)||
'Blocker SQL ID current     :' || a.sql_id ||chr(10)||
'Blocker Previous SQL ID    :' || a.prev_sql_id ||chr(10)||
'Blocker KCML Partition No  :' || a.module ||chr(10)||
'Blocker Program name       :' || a.program ||chr(10)||
'Blocker Client Information :' || a.client_info ||chr(10)||
'Blocker Application UUID   :' || a.ecid ||chr(10)||
'Waiter  SID                :' || b.sid||chr(10)||
'Waiter  Username           :' || b.username ||chr(10)||
'Waiter  App Machine        :' || b.machine ||chr(10)||
'Waiter  Serial number      :' || b.serial# ||chr(10)||
'Waiter  Current Status     :' || b.status ||chr(10)||
'Waiter  SQL ID current     :' || b.sql_id ||chr(10)||
'Waiter  Previous SQL ID    :' || b.prev_sql_id ||chr(10)||
'Waiter  KCML Partition No  :' || b.module ||chr(10)||
'Waiter  Program name       :' || b.program ||chr(10)||
'Waiter  Client Information :' || b.client_info ||chr(10)||
'Waiter  Application UUID   :' || b.ecid details,a.sql_id b_sql_id,a.prev_sql_id b_pre_sql_id,b.sql_id w_sql_id,b.prev_sql_id w_prev_sql_idfrom v$lock h, v$lock w, v$session b, v$session a, dba_objects o , v$pdbs pwhere h.block   != 0and h.lmode   != 0and h.lmode   != 1and w.request != 0and w.id1     = h.id1and w.id2     = h.id2and h.sid     = a.sidand w.sid     = b.sidand decode (w.type, 'TX', b.row_wait_obj#,'TM', w.id1)= o.object_idand w.con_id=o.con_idand w.con_id=p.con_id
order by w.ctime desc;

以上sql适用于11g,如果是12c记得把获取object_name的部分去掉。

最后的效果类似于这样:

email title:

xxx-xxx-xxx-0101_1_xxxDB39_12c_oracle_15

body:

Container DB125439 Session 32787 is blokcing session 35500 duration: 000:47:33 Lock type TX Locked object :DEXTER.TESTTABLE
Blocker SID                :32787
Blocker Username           :DEXTER
Blocker App Machine        :xxx-xxx-xxx-01
Blocker Serial number      :44996
Blocker Current Status     :INACTIVE
Blocker SQL ID current     :
Blocker Previous SQL ID    :cdvppfnyngumd
Blocker KCML Partition No  :SQL*Plus
Blocker Program name       :sqlplus@xxx-xxx-xxx-01 (TNS V1-V3)
Blocker Client Information :
Blocker Application UUID   :
Waiter  SID                :35500
Waiter  Username           :DEXTER
Waiter  App Machine        :xxx-xxx-xxx-01
Waiter  Serial number      :18786
Waiter  Current Status     :ACTIVE
Waiter  SQL ID current     :5z3w5m3z9yv6y
Waiter  Previous SQL ID    :cdvppfnyngumd
Waiter  KCML Partition No  :SQL*Plus
Waiter  Program name       :sqlplus@xxx-xxx-xxx-01 (TNS V1-V3)
Waiter  Client Information :
Waiter  Application UUID   :
Additional sql text:xxxxxx:
update testtable set id=333 where id=3
xxxxxx:
update testtable set  id=5
xxxxxx:
update testtable set  id=5 

敏感信息我就用xxx代替了

分享一个前两天写的自动监控blocking 的脚本(基于12C)相关推荐

  1. 分享一个前后端分离的轻量级内容管理框架

    开发框架要考虑的面太多了:安全.稳定.性能.效率.扩展.整洁,还要经得起实践的考验,从零开发一个可用的框架,是很耗时费神的工作.网上很多开源的框架,为何还要自己开发?我是基于以下两点: 没找到合适的: ...

  2. 分享一个四两拨千斤的真实故事

    分享一个四两拨千斤的真实故事. 看懂的人都是当老板的料. 有一家小食品公司,辣椒酱上市前想做宣传,无奈没有太雄厚的经济实力,租不起市区广告牌. 于是,他们突发奇想,租下城门口的一个不值钱的广告牌. 租 ...

  3. 【开源】分享一个前后端分离方案-前端angularjs+requirejs+dhtmlx 后端asp.net webapi

    一.前言 半年前左右折腾了一个前后端分离的架子,这几天才想起来翻出来分享给大家.关于前后端分离这个话题大家也谈了很久了,希望我这个实践能对大家有点点帮助,演示和源码都贴在后面. 二.技术架构 这两年a ...

  4. 用python写一个自动注册脚本_python写的自动登录人人网的脚本

    我今天给大家分享一个我自己用 #!/usr/bin/env python #encoding=utf-8 import sys import re import urllib2 import urll ...

  5. 分享一个电影网站源码。自动抓取

    分享一个电影网站源码.下面是演示地址,可能UI方面有些不同. www.qwdianying.top 下载地址:https://pan.baidu.com/s/1VU16AkklpCZ-tiPCAZ51 ...

  6. 分享一个自己利用Python写的淘宝秒杀工具源码

    看论坛里有好多大神上传了秒杀神器,我是一个初学者,写了一段代码,但是根本实现不了毫秒级的秒杀,只能做到"秒点",但是无论如何,我也突破不了这个瓶颈,今天分享给大家,希望大家能给出一 ...

  7. 分享一个前后端分离的web项目(vue+spring boot)

    Github地址:https://github.com/smallsnail-wh 前端项目名为wh-web 后端项目名为wh-server 项目展示地址为我的github pages(https:/ ...

  8. 分享一个强大的在线写API接口文档的工具showdoc

    网站地址:https://www.showdoc.cc 第一步:注册 第二步:填写注册信息,这里填写用户名和密码即可,用户名不可重复,注册登录后可以绑定邮箱. 也可以不注册查看示例决定要不要使用这个网 ...

  9. python网址太长_【原创】分享一个自己用python写的长网址转短网址工具,给需要的你...

    [Python] 纯文本查看 复制代码import requests import json from tkinter import * class Get_url_short(): def __in ...

最新文章

  1. linux(gentoo)安装配置conky
  2. rust(13)-闭包作为参数 trait泛型
  3. 1.VMwareTools的安装,vmware启动的时候,虚拟机黑屏,解决办法
  4. MyBatis 实践
  5. iPhone 14系列升级巨大:两款Pro版或将配置4800万像素镜头
  6. 阿里巴巴Java开发手册
  7. spring transactional 事务传播机制
  8. 计算机组成原理/计算机硬件基础第五章:存储器
  9. Set Scrolling Pictrues in the WebPage
  10. mysql data seek_mysql_data_seek函数详解
  11. MacBook Air 2013全新安装Win7
  12. phython入门开始
  13. 【Java实战小项目】考试系统
  14. 统计信号处理基础 习题解答5-8
  15. 《武则天正传》读后感
  16. Unittest-跳过
  17. 烤仔星选·NFT实验室 | 非同质化代币在游戏领域的应用
  18. 如何知道页面浏览时长系列之 Web 篇
  19. 1024分辨率《加勒比海盗4》BD中英双字无水印
  20. python static方法_浅谈python 类方法/静态方法

热门文章

  1. 席裕庚《预测控制》学习记录 (一)-基于阶跃响应的动态矩阵控制(DMC)包含仿真
  2. 对百草味企业网站的诊断评价
  3. 树状图JQuery.ztree插件的使用
  4. 每次进入命令需要重新source的解决方法
  5. OpenSSL之十三:证书和CA指令
  6. Uni-app使用原生aar本地包云打包报错
  7. 用户控制 阻止运行程序_阻止或允许您的孩子通过家长控制使用的程序
  8. vue-微信小程序-自定义计时器-答题倒计时
  9. 整个部门就一个研发?
  10. java 设计模式