前几天有网友在墨天轮平台上问到“如何写一个定时任务监控用户会话连接数”的问题,由于当时比较忙,回答的比较简单也比较匆忙。最近也因为公司新项目老是加班,运维保障,安装 RAC、搭建 DG 、故障处理等等,占据了很大个人时间,休息充电的时间难免减少了很多,今日利用闲暇时间,来继续说一说监控会话相关的这个话题。

通常我们平时都是通过运行 SQL 语句直接查询 V$SESSION 视图得到结果,然后直接输出到屏幕上,具体的 SQL 如下:

--- 查看用户会话
select username,count(username) from gv$session
where username is not null group by username order by 2;--- 查看异常等待事件
select inst_id,sid,serial#,program,sql_id,event,seconds_in_wait "wait(s)" from gv$session
where type<>'BACKGROUND' and wait_class <> 'Idle' order by inst_id;--- 查看活跃会话数
select inst_id,status,count(*) from gv$session
where type<> 'BACKGROUND' group by inst_id,status order by 3;

今天主要是通过 Shell 循环等手段来实现:

[oracle@JiekeXu ~]$ more wait_event.sh
while true
do
DATE=`date +%Y-%m-%d`
sqlplus "/ as sysdba" << EOF | grep -A5 EVENT | grep -v Version | grep -v Copyright | grep -v Enterprise | grep -v '>'
#sqlplus "/ as sysdba" 1>>/home/oracle/wait_history_$DATE.log 2>&1 << EOF |grep -v SQL | grep -v Version | grep -v Copyright | grep -v Enterprise | grep -v '>'set termout off
set linesize 250 pagesize 100
col inst_id for 9
col sid for 9999
col serial# for 99999
column program format a30
column event format a35
col "wait(s)" for 9999
--set timing on
select inst_id ,sid,serial#,program,sql_id,event,seconds_in_wait "wait(s)" from gv\$session
where type<>'BACKGROUND' and wait_class <> 'Idle' order by inst_id;
exit
EOF
sleep 5
done

注:gv$session 中需要用 “\” 转义 “$” 符号,grep -A5 EVENT 这个只是过滤掉 SQLPlus 登陆退出的提示,以便更友好的输出结果。 每隔 5 秒运行此脚本,便可以输出异常的等待事件到屏幕上,通过 While True 循环然后等待 5 s 继续执行达到监控效果,如下是我的测试环境执行结果:

[oracle@JiekeXu ~]$ sh wait_event.sh
INST_ID SID SERIAL# PROGRAM SQL_ID EVENT wait(s)
------- ----- ------- ------------------------------ ------------- ----------------------------------- -------
1 275 21812 sqlplus@JiekeXu (TNS V1-V3) d9n1shwuv7x4q SQL*Net message to client 0INST_ID SID SERIAL# PROGRAM SQL_ID EVENT wait(s)
------- ----- ------- ------------------------------ ------------- ----------------------------------- -------
1 275 23182 sqlplus@JiekeXu (TNS V1-V3) d9n1shwuv7x4q SQL*Net message to client 0INST_ID SID SERIAL# PROGRAM SQL_ID EVENT wait(s)
------- ----- ------- ------------------------------ ------------- ----------------------------------- -------
1 275 17811 sqlplus@JiekeXu (TNS V1-V3) d9n1shwuv7x4q SQL*Net message to client 0INST_ID SID SERIAL# PROGRAM SQL_ID EVENT wait(s)
------- ----- ------- ------------------------------ ------------- ----------------------------------- -------
1 275 4359 sqlplus@JiekeXu (TNS V1-V3) d9n1shwuv7x4q SQL*Net message to client 0INST_ID SID SERIAL# PROGRAM SQL_ID EVENT wait(s)
------- ----- ------- ------------------------------ ------------- ----------------------------------- -------
1 275 31876 sqlplus@JiekeXu (TNS V1-V3) d9n1shwuv7x4q SQL*Net message to client 0INST_ID SID SERIAL# PROGRAM SQL_ID EVENT wait(s)
------- ----- ------- ------------------------------ ------------- ----------------------------------- -------
1 275 12138 sqlplus@JiekeXu (TNS V1-V3) d9n1shwuv7x4q SQL*Net message to client 0INST_ID SID SERIAL# PROGRAM SQL_ID EVENT wait(s)
------- ----- ------- ------------------------------ ------------- ----------------------------------- -------
1 275 44219 sqlplus@JiekeXu (TNS V1-V3) d9n1shwuv7x4q SQL*Net message to client 0^Z
[1]+ Stopped sh wait_event.sh


当然如果异常等待事件较多,或者这里不止一条 SQL 语句,执行结果输出到屏幕上不是一个很好的选择,便可以使用上面注释掉的一行 SQL 将结果输入到wait_history_$DATE.log 文件,然后查查此文件即可。

watch 命令

下面在看一下使用 watch 命令的效果,watch 是一个非常实用的命令,基本所有的 Linux 发行版都带有这个小工具,如同名字一样,watch 可以帮你监测一个命令的运行结果,省得你一遍遍的手动运行。其后跟 -n 或 --interval 参数, watch 缺省每 2 秒运行一下程序,可以用-n或 -interval 来指定间隔的时间。

atch -n 1 /usr/bin/sh cat_user_session.sh


由于这里是测试用例,没有更多的连接,效果不太明显。异常等待事件和活动会话均不明显,下面通过一生产环境 ADG 备库来演示一下。

监控异常等待事件案例分享

监控 ADG 备库活动会话和异常等待事件,每隔 10 秒钟记录一次,将结果保存到日志文件中,并定期清理历史日志文件。

JIEKEDB1:/app/soft$ls
session_history_2020-09-28.log
PatchSearch.xml session_history_2020-09-22.log session_history_2020-09-28.log.bak
agent session_history_2020-09-23.log session_history_2020-09-29.log
catsession.sh session_history_2020-09-24.log
cleartmplog.sh session_history_2020-09-25.log
p19433930_11204180116_AIX64-5L.zip session_history_2020-09-26.log tmp.log
p20380541_112040_AIX64-5L.zip session_history_2020-09-27.log
---- 申明环境变量后存放一些要查的 SQL,并将结果存入 session_history_$DATE.log
JIEKEDB1:/app/soft$cat catsession.sh
umask 022
export ORACLE_BASE=/app/oracle
export ORACLE_HOME=/app/product/11.2.0/db
export ORACLE_SID=JIEKEXUDB1
export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$PATH
export LIBPATH=$ORACLE_HOME/libDATE=`date +%Y-%m-%d`
sqlplus "/ as sysdba" 1>>/app/soft/session_history_$DATE.log 2>&1 <<EOF
set termout off
set heading off feedback off pagesize 0 verify off echo off
set linesize 250 pagesize 300
column program format a30
column event format a45
set time on
host echo '--------------historysession-----------------------'
select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS'),
inst_id,sid,serial#,program,sql_id,event,SECONDS_IN_WAIT
from gv\$session
where status='ACTIVE' and type <> 'BACKGROUND' and wait_class<>'Idle'
and event not in('parallel recovery slave next change')
order by inst_id,sid;
host echo '--数据库异常等待事件-----------------'
select event, SECONDS_IN_WAIT
from v\$session where type <> 'BACKGROUND' and STATE='ACTIVE' and wait_class<>'Idle'
group by event,SECONDS_IN_WAIT
order by SECONDS_IN_WAIT desc;
host echo '-------------------------------'
host echo '--数据库连接数-----------------'
select inst_id,status,count(*) from gv\$session where type <> 'BACKGROUND' group by inst_id,status order by 1;
exit;
EOF

session_history_$DATE.log 日志每天生成一个,时间长久不利于管理,故需要清理,然后使用 cleartmplog.sh 定期清理,脚本如下:

JIEKEDB1:/app/soft$cat cleartmplog.shfind /app/soft -name "session_history*" -mtime +7 -exec rm -rf {} \;

最后,每 10 秒运行一次,这里还有一点小技巧,crontab 里显示的是分时日月周,并没有秒级别的设置,这里便借助 sleep 10 来达到 10 秒运行一次的效果。

min     hour   day  month  week    command
分钟     小时      日      月       周      动作(任务命令)
0-59     0-23    1-31   1-12      0-7    命令或脚本(写绝对路径)
JIEKEDB1:/app/soft$crontab -l
* * * * * sleep 10; /usr/bin/sh /app/soft/catsession.sh
* * * * * sleep 20; /usr/bin/sh /app/soft/catsession.sh
* * * * * sleep 30; /usr/bin/sh /app/soft/catsession.sh
* * * * * sleep 40; /usr/bin/sh /app/soft/catsession.sh
* * * * * sleep 50; /usr/bin/sh /app/soft/catsession.sh
* * * * * sleep 60; /usr/bin/sh /app/soft/catsession.sh
30 2 * * * /usr/bin/sh /app/soft/cleartmplog.sh


最后,搂一眼生成的日志, session_history_2020-09-29.log 日志中每 10 秒则会显示 SQL 查询结果,但是有 SQLPlus 登入登出信息,显示的格式不是很友好,脚本可以继续优化。我这里是 AIX 6.1 ADG 备库上的信息,部分 Shell 命令在操作系统上不好用,但 Linux 系统则没有问题,希望看到的小伙伴们可以在尝试一下。

当备库发生性能问题时,便可以通过此日志记录当时会话信息,异常等待事件,便可以分析性能问题,大大的提供了分析资料,节省了很多查询时间,是值得借鉴的,故此推荐给小伙伴们使用。

参考链接 :

如何通过 Shell 监控异常等待事件和活跃会话 : https://mp.weixin.qq.com/s/O7w10MTgCtf94VJg0qkJKQ

如何通过 Shell 监控异常等待事件和活跃会话相关推荐

  1. shell sqlplus执行sql文_如何通过 Shell 监控异常等待事件和活跃会话

    作者 | JiekeXu 来源 | JiekeXu之路(ID: JiekeXu_IT) 转载请联系授权 | (微信ID:xxq1426321293) 大家好,我是 JiekeXu,分开这么久很高兴又和 ...

  2. oracle缓冲等待块,CSS_Oracle数据库buffer busy wait等待事件, 当会话意图访问缓冲存储 - phpStudy...

    Oracle数据库buffer busy wait等待事件 当会话意图访问缓冲存储器中的数据块,而该数据块正在被其它会话使用时产生buffer busy waits事件.其它会话可能正在从数据文件向缓 ...

  3. 遭遇cursor:pin x等待事件定位阻塞会话诊断过程

    环境描述:DB:10.2.0.4.0 /OS:AIX 5.3 (64bit) 问题描述: 1.会话A执行如下命令被挂起 SQL> exec dbms_shared_pool.purge('070 ...

  4. 监控oracle等待事件

    -- Session总体等待 SELECT a.SID, a.USERNAME, a.MACHINE, a.TERMINAL, b.EVENT, b.TOTAL_WAITS, b.TOTAL_TIME ...

  5. 等待事件系列(1)--User I/O类型

    等待事件系列(1)--User I/O类型 1  BLOG文档结构图 2  前言部分 2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~ ...

  6. ORACLE等待事件:direct path write

    2015年4月27日,晚上6点左右,电渠3g2库ORACLE RAC系统节点1出现大量的direct path write等待事件,导致大量的会话堆积,节点1几乎无法使用,应用受到影响,相关处理流程如 ...

  7. mysql等待事件类型_Oracle中常见的33个等待事件小结

    在Oracle 10g中的等待事件有872个,11g中等待事件1116个. 我们可以通过v$event_name 视图来查看等待事件的相关信息 一. 等待事件的相关知识 1.1 等待事件主要可以分为两 ...

  8. Oracle 常见的33个等待事件

    Oracle 常见的33个等待事件 一. 等待事件的相关知识: 1.1 等待事件主要可以分为两类,即空闲(IDLE)等待事件和非空闲(NON-IDLE)等待事件. 1). 空闲等待事件指ORACLE正 ...

  9. 11g oracle xe启动_详解Oracle等待事件的分类、发现及优化

    一.等待事件由来 大家可能有些奇怪,为什么说等待事件,先谈到了指标体系.其实,正是因为指标体系的发展,才导致等待事件的引入.总结一下,Oracle的指标体系,大致经历了下面三个阶段: 以命中率为主要参 ...

最新文章

  1. JSP JSTL标签库基本使用
  2. linux——sed 流编辑器
  3. python图像锐化_Python图像处理介绍--图像模糊与锐化
  4. LeetCode MySQL 1211. 查询结果的质量和占比
  5. python打开excel窗口_简单介绍python在CMD界面读取excel所有数据
  6. 《学习OpenCV3》第11章 常见的图像变换
  7. 雷电模拟器多开cpu优化_哪个电脑手游模拟器好用 安卓手游模拟器测试对比排行榜...
  8. Mac安装 MySQL 及可视化工具
  9. Google 推出的编程学习应用 Grasshopper
  10. skill快捷键设置
  11. 对程序员而言,学历重要吗?
  12. 详解使用可道云Kodbox快速在云服务器上搭建云盘
  13. 传真服务器维护,DreamFax传真服务器
  14. 安装VMWare Workstation 12的步骤
  15. Android串口编程入门
  16. 全息投影技术及其实现(附素材下载)
  17. 现代通用计算机雏形是,科技知识:什么是现代通用计算机的雏形
  18. 高校青年教师应该怎么提高收入
  19. 告别Ubuntu,与Win 10闹别扭
  20. K-means最优K值计算(利用SSE)

热门文章

  1. 非结构化商业文本中隐私信息识别-第2名方案(含数据)
  2. 校园无盘服务器,校园微机系统优化及无盘改造实例.docx
  3. 双显卡单独分辨率_甜点光追显卡—带你实现GAMING梦!!!
  4. linux 命令大全_【Linux】命令目录大全
  5. b - 数据结构实验之查找二:平衡二叉树_二叉树、平衡二叉树、红黑树、B树、B+树与B*树...
  6. pytorch之学习率变化策略之LambdaLR
  7. java模拟浏览器htmlunit,Java版本的浏览器HtmlUnit入门示例
  8. 本地数据库_干货|本地数据库调用的实现案例
  9. .Net RabbitMQ之消息通信 构建RPC服务器
  10. 全面总结Java泛型