排查医疗系统卡慢的一次经历

某家医院的系统会时不时的卡死,导致整个医院的系统无法使用。严重影响业务的正常运行,现场运维人员观察发现系统卡死时 ping不通服务器。仅此信息,其它信息无。
赶赴现场后,首先排查是网络问题还是系统问题。

第一步的 排查方法也很简单, 打开任务管理器,(他的服务器是Window server2008 r2 ),打开资源监视器,等待系统卡顿时,观察网络流量,和磁盘使用量,内存,CPU。等信息,如果是网络问题,那么最常见的有两种情况。 一种是断网,一种是病毒攻击。 针对这两种情况他的表现是不一样的。
如果是断网,那么表现为网络流量为0, 系统使用流畅。操作流畅。
如果是病毒攻击,那么表现为网络流量很大。
如果是系统本身大批量的产生流量, 那么表现为,系统很卡,网络流量很大,系统相应进程的读写和CPU也会相应提高。

经过第一波的观察,发现网络流量比较正常3MB/S上下。CPU使用量飙升到90%上下。磁盘读写很高达到130MB/s,有的人说这个速度不算高。 但是在我看来已经很高了因为这个是5万左右的服务器,装了一个虚拟机,虚拟出了3台服务器,2台应用服务器,1台数据库服务器。

卡的时候ping另外两台服务器是正常的,ping数据库这台就卡。
初步断定,是数据库这台服务器内部有问题,不在网络上。观察的时候发现数据库服务器上Oracle.exe这个进程比较耗资源,读取量比较高。写入量比较少。 现场情况图拍摄。
在这里插入图片描述在这里插入图片描述
到了这一步估计很多人就到此为止了。 只知道好像是服务器的数据库很卡。有的人认为,这个是数据库,读写如此是正常的。。。我只能汗颜了。。说也说不清。

事情到这里我也心理在想,我到底要不要回去交差? 回去吧–感觉好像事情没搞定。没彻底解决问题,只是查出来问题的大概方向了。还没有彻底的查清楚,到底是什么情况下会导致这卡。是哪个SQL语句导致数据库卡?还是系统性能不够了?
不回去吧—继续查下去事情会很棘手,Oracle不熟悉,咱不是专业的DBA,简单的CURD咱会写, 涉及到数据库的专业知识咱以前没学过。
最怕的是这个事情继续查下去沾到身上脱不了手。不管你有没有优化,哪怕你只是查一下问题点在哪里,事后只要是系统卡了都会是你的事情,跟你脱不了关系。这就是现状,无知的人太多,无知不可怕, 最怕一知半解的乱点鸳鸯谱。 (额!!,容我吐槽一下)。
考虑再三,咱不能辜负了领导的期望是吧! 领导要的是把事情彻底解决,不是回去汇报一下谁谁没做好,谁谁谁的问题。 再说咱也不喜欢干事情弄个半吊子。事情干了一半,没下文了。这不是我的做事风格。 另外这个事情对我来讲也有着莫大的诱惑,因为我很想知道到底是什么原因引起的系统卡顿。
那接下来继续查,简单的跟领导汇报一下。看看领导的意思。领导的意思也是继续查。
那怎么查呢?
那怎么查呢?
那怎么查呢?
万事不知问百度。。
俗话说工欲行其实必先利其器。于是咱们网上百度了,
oracle 查询当前最慢的sql语句
oracle 当前正在执行的sql语句
oracle 历史最慢的sql
oracle 性能排查工具
各种搜索过后。发现Oracle没有像SqlServer那样简单直观的企业管理器。
需要各种SQL语句查询出来,各种命令生成AWR报告和ASH报告。

晚上自学了一下,Oracle的数据库性能分析相关课程。https://www.bilibili.com/video/av60373207/?p=27
简单了解了一下AWR报告和ASH报告。

个人感觉最重要的是这个图。如何定位性能问题。
在这里插入图片描述
这个图确实有道理,这是事后看到的讲解,事前没认真看导致我绕了很多弯路。
由于时间紧迫,我并没有从第一节课开始看,直接从27节课开始看的。 看了两节课, 大概对Oracle有了些了解。
主要用了很多的视图。

如果在系统卡顿的时候恰巧你不在,没有看到相关数据信息,其实也不用怕。强大的oracle有历史记录的,只不过历史记录的相对少一些。但是足够排查出性能问题了。
下面是查询已经过去数据库相关的sql记录的主要表dba_hist_active_sess_history。
关于这些视图如何看, 前期建议先每个视图都select * from 视图 打开看一下, 了解一下每个字段的意思和作用。这样后面的查询才会有依据。本文下面部分有很多都摘抄自
https://www.cnblogs.com/lanzi/archive/2011/12/15/2289474.html

咱再开一篇讲如何排查卡顿中的系统性能SQL
此篇只是开篇,大家自己先了解下,后面再详细讲如何在事中排查性能问题,和事后排查性能问题。

如果是在系统卡顿的时候那么下面这些视图查询到的数据是正在发生的数据。
v$sqlarea; //我个人感觉最重要的视图。 里面包含了SQL语句的性能统计, 基本上这一个视图就能查出来90%有问题的SQL。
v$session; //我个人感觉第二个最重要的视图。
v$sql
v$sqltext
v$sysstat
v$system_event
v$process
v$lock
v$latch_children
v$bh
v$session_wait_history
如果是在系统卡顿过后,那么就要用这个了。
dba_hist_active_sess_history:
/*每60分钟,MMON后台进程都要刷新过滤了得ASH数据到磁盘,使其成为按小时的AWR快照的一部分。若ASH缓冲区已满,
则MMML后台进程进行数据的刷新。ASH数据被刷新到磁盘后,就不能在v$active_session_history视图中看到它了。此时要查看历史数据,就必须通过
dba_hist_active_sess_history视图。*/

v$sql与v$sqlarea
v$sql与v$sqlarea基本相同,记录共享sql区(share pool)中sql统计信息,如内存消耗、IO(物流磁盘读和逻辑内存读)、排序操作、哈希ID等数据。不同之处在于v$sql为每一条sql保留一个条目,而v$sqlarea中根据sql_text进行group by,统计列进行sum(),通过version_count计算子指针的个数。 Sql_text相同的sql语句在数据库中意义可能完全不同,此时,v$sql会有这两条完全一样的sql各自的统计信息,而在v$sqlarea中sql_text相同的2个指针会合并,执行次数,DISK_READS,BUFFER_GETS等统计信息会累加,这就是v$sqlarea的聚合作用。

v$sqltext
中没有统计信息,却存储着完整的sql语言及其哈希ID等。

v$session
主要用来确定会话相关信息,如通过SID和SERIAL来确定一个Session、会话拥有者用户名username、会话状态、会话由哪个客户端发起、正在执行什么sql(通过sql_address、sql_hash_value、sql_id、sql_child_number确定,再借助v$sqltext就可以知道)、锁等待相关信息(如所在表、文件、块、被锁行)等。

v$session_wait_history
该视图保存每个活动会话的最后10个等待事件的有关信息。v $session和v$session_wait视图只显示最近一次等待的信息

-- 查询140会话最近在等啥
SELECT seq#, event, wait_time, p1, p2, p3
  FROM v$session_wait_history WHERE sid = 140
 ORDER BY seq#;

v$active_session_history:当前的活动会话历史
–查询导致最多等待的对象及这些对象在最后15分钟内等待的事件类型

SELECT o.object_name,
       o.object_type,
       a.event,
       SUM(a.wait_time + a.time_waited) total_wait_time
  FROM v$active_session_history a, dba_objects o
 WHERE a.sample_time BETWEEN SYSDATE - 30 / 2880 AND SYSDATE
   AND a.current_obj# = o.object_id
 GROUP BY o.object_name, o.object_type, a.event
 ORDER BY total_wait_time;

–列出数据库中最后15分钟内最重要的等待事件

SELECT a.event,
       SUM(a.wait_time + a.time_waited) total_wait_time
  FROM v$active_session_history a
 WHERE a.sample_time BETWEEN SYSDATE - 30 / 2880 AND SYSDATE
 GROUP BY a.event
 ORDER BY total_wait_time DESC;

–等待最多的用户

SELECT s.sid,
       s.username,
       SUM(a.wait_time + a.time_waited) total_wait_time
  FROM v$active_session_history a,v$session s
 WHERE a.sample_time BETWEEN SYSDATE - 30 / 2880 AND SYSDATE
   AND a.session_id = s.sid
 GROUP BY s.sid,s.username
 ORDER BY total_wait_time DESC;

–确定等待最多的sql

SELECT a.user_id,
       s.sql_text,
       d.username,
       SUM(a.wait_time + a.time_waited) total_wait_time
  FROM v\$active_session_history a, v\$sqlarea s, dba_users d
 WHERE a.sample_time BETWEEN SYSDATE - 30 / 2880 AND SYSDATE
   AND a.sql_id = s.sql_id
   AND a.user_id = d.user_id
 GROUP BY a.user_id, s.sql_text, d.username;
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值