数据库
首页 > 数据库> > <Oracle优化新常态> 第五章 急诊法

<Oracle优化新常态> 第五章 急诊法

作者:互联网

<Oracle优化新常态>第一章

《Oracle优化新常态》第二章强拆(1)

《Oracle优化新常态》第二章强拆(2)

<Oracle优化新常态> 第三章 三大配置

<Oracle优化新常态>第四章 分库分表

<Oracle优化新常态> 第五章 急诊法

前章节要

分库分表是总结了第二章的强拆,也就是ORACLE的分库分表.与MYSQL的分库分表的区别.

从我所了解到的MYSQL分库分表,视野集中在表的身上,把不同的表放在不同的数据库中,这种拆分法跟我的按业务和功能拆分法,基本上类似,不过MYSQL是从下往上看.思维方式有点井底之蛙的感觉。视野集中在性能上,可能无法达到业务和功能上的隔离。

MYSQL拆表法,有两种,一种按字段,常用和不常用分别存在不同表中。另外一种是按某个字段的值,比如user_id=XXX 或者时间字段进行水平拆分。其实这个ORACLE分区技术是一个概念的。当这里有个问题,那就是水平拆分的表,如果放在不同的数据库中,就需要数据库中间件来完成路由工作。光从技术角度来看是无法理解这样的拆分需求的,只有OLQP的大量查询,把查询分别负载到不同的水平数据库中,比如登录的时候根据用户ID分散到不同的数据库中。 比如电商查询不同的商品,电脑和化妆品的查询,就通过水平拆分表的方法,分散到不同的数据库中。每个数据库就保存不同的数据。

把表水平拆分到不同的数据库后,再用MYCAT把请求同时分发到所有的数据库,一起完成工作。然后在MYCAT进行数据合并。这样的操作需求应该是统计类型的,比如说SELECT SUM() FROM USER_ID .需要全表扫描的工作。可表已经拆散了,分布在不同的数据库当中,自然要向全部数据发出命令一起合作完成工作。 这就是典型的OLAP。

说白了大家都差不多,只不过MYSQL是从技术角度由下往上进行拆。 而我提的ORACLE分库分表是从业务角度由上而下地分。

如果你做成到了两级分库,那么日后的性能问题就比较单纯了

<Oracle优化新常态> 第五章 急诊法

有朋友质疑20台ORACLE数据库与100台MYSQL数据库 分库分表性能是否一样? 其实这个嘛,主要是MYSQL是硬解析,不得不用机器来拼人力!ORACLE高效的共享池技术极大了降低了硬解析的CPU消耗。你说20台拼不过100台MYSQL服务器。假设同样的配置,同样的应用!

<Oracle优化新常态> 第五章 急诊法

而电商WEB应用最大的是天量查询请求,也就是OLQP。 QPS量大!

QPS可以用多个备库来完成。把大表水平拆分多个分区,也不需要路由MYCAT的了。因为每个备库都有全量的数据,通过TNSNAME.ORA来负载均衡完成。所以实现起来非常简单明了!

物理实现的方式可以多种多样,考虑公司的经济实力而已。重点是要完成两级分库。日后爱咋折腾都方便了,就不用鸟应用开发啥事了。后台DBA根据性能轻松完成,数据库的部署,架构的调整,数据的迁移等等操作。

你看我啰嗦里八嗦的 好几章了! 不过我还是认为重要的事情说三遍!

当我们被数据库突然慢的时候,这个时候不该做AWR报表!好比你是医院的急诊科的值班医生,当120拉来一名患者,而你要做的是立即判断病情所在。AWR不太适合急诊模式,阅读完它就要花费30分钟!所以我们需要特殊的简单明确的方法,进行快速诊断,快速恢复生产,让用户继续完成业务,让老板有利润。

第一从系统上开始 TOP命令 如下

<Oracle优化新常态> 第五章 急诊法

TOP命令很多LINUX都有,而且比较重要哦!读懂里面的意思是DBA必备良药。

第一 看第一行LOAD AVERAGE 超过1 就比较忙,越大越忙

第二 看第二行 TASKS 任务数 尤其是 RUNNING的数,一般平时的时候都1-2.恐怖的时候达到1000,说明并发量大,排队等候也大。

第三 看第三行 CPU 看目前的CPU消耗在哪个领域。US表示应用,SY表示系统,WA表示等待(IO或者是网络)。通过CPU消耗在什么位置可以确定哪里病了,是心脏还是胃,还脑袋瓜子呢?

第四 看第四和第五行 大致讲的是当前内存使用情况和SWAP内存使用的情况。

第五 下面的进程活动列表,动态变化的,一般都是按CPU使用率变化的。如果排在顶部的大部分是ORACLE进程,说明是数据库发生了问题。

从TOP命令不能精确判断出来, 不过能了解到是什么消耗比较严重 是IO还是CPU 尤其是第三行。大致判断出是系统出了问题还是数据库出了问题。

VMSTAT 命令

<Oracle优化新常态> 第五章 急诊法

由于CENTOS 6带的VMSTA输出格式对齐不咋地,看起来有点不舒服。

重点是看PROCS 的R B两列和SWAP的SI SO两列。

R B 表示运行队列的进程数和阻塞的进程数。 R代表运行进程,B代表阻塞进程。SI SO表示交换内存的进出数量。

VMSTAT 主要用来判断是非发生了交换内存的频繁大量的交换。

下图是ORACLE LINUX 6 的DSTAT命令 大家看下友好性特别的好。

<Oracle优化新常态> 第五章 急诊法

第一组代表的是CPU;

第二组代表的是磁盘IO情况;

第三组代表的是网络情况;

第四组代表交换内存情况;

第五组代表系统情况;Int 中断,CSW上下文切换

到这里我们结束了系统方面的急症了。从上面两个命令可以确定病情集中在CPU,内存还是IO方面。假如CPU 内存 IO 都很正常那就是说系统是没有问题的,问题在数据库上面,起码数据库慢的问题没有体现在系统指标上。说明病情不严重。

ORATOP命令

<Oracle优化新常态> 第五章 急诊法

这个命令是ORACLE公司开发的小工具,变化挺大的。

第一行和第二行,有些我也不懂,主要是变化太大了,每个新版本都不一样,另外还是英文缩写,没有长格式的,都是80列的格式的。

重点看EVENT ,这个就是及时性的TOP五等待事件。这样我们就知道数据库是否发生了严重的等待。比如上图正常情况下是DB CPU占比较多的DBTIME。

如果是下面 LOG FILE SYNC和DB FILE SEQUENTIAL READ 等待事件排在第一或第二位 那就说明IO争用很厉害。

关于小工具看下面链接 ==》ORATOP小工具

接下来就是TOP-SQL了 一眼望过去大部分列都懂,除了E/T STE W/T外。

通过TOP-SQL 你可以心里有普了,知道这些家伙了。你可以KILL了它们。不过要在SQLPLUS里面发不KILL SESSION命令 另外还有手动去查出来。虽然给了SID 和SPID。

也可以在系统上KILL -9 命令,不过也要通过SQLPLUS查出系统ID来。还是有点不方便。

视图 V$SESSION_BLOCKERS

这是个回话阻塞视图里面包含了如下字段

SID

SESS_SERIAL#

WAIT_ID

WAIT_EVENT

WAIT_EVENT_TEXT

BLOCKER_INSTANCE_ID

BLOCKER_SID

BLOCKER_SESS_SERIAL#

分别意思是 回话ID,回话序号,等待ID,等待事件,等待事件文本,阻塞实列ID,阻塞回话ID,阻塞回话序号。

这个视图如果只有一两行还比较给力,如果是几百行的话,就不像话了,一点都不给力。尤其是急症下,上百行阻塞回话,它们之的上下级关系,阻塞连。我写个START WITH类似的树下结构的语句,发现也不行,反而产生更多的行,从原来几百行变成了几千行。也没有机会去调试SQL,毕竟发生阻塞的时候,你必须干掉它,所以就没有机会了。只有截图回来分析下。

另外该表只有这几列字段,显然信息量是不够的,尤其是在急症情况下。必须有等待者的SQL语句,阻塞者的SQL语句,阻塞者的等待事件。

为此我整了个大SQL,不过不太理想

SELECT LEVEL AS LEVEL_NUM,

B.SID AS "会话ID",

B.SESS_SERIAL# AS "会话序列",

B.BLOCKER_INSTANCE_ID AS "阻塞实列ID",

B.BLOCKER_SID AS "阻塞会话ID",

B.BLOCKER_SESS_SERIAL# AS "阻塞会话序列",

SS.EVENT AS "阻塞者等待事件",

S.SCHEMANAME AS "模式名",

S.OSUSER AS "操作系统用户",

S.PROCESS AS "进程ID",

S.MACHINE AS "机器",

S.PORT AS "端口",

S.TERMINAL AS "终端",

S.PROGRAM AS "程序",

S.TYPE AS "类型",

S.SQL_ID AS "当前SQLID",

(SELECT TXT.SQL_TEXT FROM V$SQLAREA TXT WHERE TXT.SQL_ID = S.SQL_ID) AS "当前SQL语句",

S.PREV_SQL_ID AS "上个SQLID",

(SELECT TXT.SQL_TEXT FROM V$SQLAREA TXT WHERE TXT.SQL_ID = S.PREV_SQL_ID) AS "上个SQL语句",

B.WAIT_EVENT_TEXT AS "等待事件",

S.WAIT_CLASS AS "等待类",

S.WAIT_TIME AS "等待时间秒",

'||' AS "阻塞者信息分隔",

SS.STATUS AS "阻塞者会话ID",

SS.STATE AS "阻塞者会话ID",

SS.SCHEMANAME AS "阻塞者模式名",

SS.OSUSER AS "阻塞者操作系统用户",

SS.PROCESS AS "阻塞者进程ID",

SS.MACHINE AS "阻塞者机器",

SS.PORT AS "阻塞者端口",

SS.TERMINAL AS "阻塞者终端",

SS.PROGRAM AS "阻塞者程序",

SS.TYPE AS "阻塞者类型",

SS.SQL_ID AS "阻塞者当前SQLID",

(SELECT TXT.SQL_TEXT FROM V$SQLAREA TXT WHERE TXT.SQL_ID = SS.SQL_ID) AS "当前SQL语句",

SS.PREV_SQL_ID AS "上个SQLID",

(SELECT TXT.SQL_TEXT FROM V$SQLAREA TXT WHERE TXT.SQL_ID = SS.PREV_SQL_ID) AS "上个SQL语句",

SS.WAIT_CLASS AS "等待类",

SS.WAIT_TIME AS "等待时间秒",

SS.EVENT AS "等待事件",

SS.P1TEXT AS "参数一名",

         SS.P1 AS "参数一值",

SS.P2TEXT AS "参数二名",

SS.P2 AS "参数二值",

SS.P3TEXT AS "参数三名",

SS.P3 AS "参数三值",

'alter system kill session ''' || TO_CHAR(SS.SID) || ',' || TO_CHAR(SS.SERIAL#) || ''';' KILLSESSION,

'kill -9 ' || P.SPID AS KILLSYSPROC

FROM V$SESSION_BLOCKERS B

LEFT JOIN V$SESSION S ON S.SID = B.SID AND S.SERIAL# = B.SESS_SERIAL#

LEFT JOIN V$SESSION SS ON SS.SID = B.BLOCKER_SID AND SS.SERIAL# = B.BLOCKER_SESS_SERIAL#

LEFT JOIN V$PROCESS P ON P.ADDR = SS.PADDR

START WITH SS.WAIT_CLASS='Idle'

CONNECT BY PRIOR B.SID=B.BLOCKER_SID ;


ASH报表

急症情况下一般都使用ASH报表,它会帮你抓住你想要的东西,基本上能抓住问题所在。包含TOP 等待事件 等待事件所涉及到的SQL。

在SQLPLUS 里面执行

@?/rdbms/admin/ashrpt ;

连续回车就能生成该报表,默认是15分钟之内的。

<Oracle优化新常态> 第五章 急诊法

<Oracle优化新常态> 第五章 急诊法

<Oracle优化新常态> 第五章 急诊法

这样你就知道哪些SQL在捣蛋了


最后一招就是 重启大法

只要电脑慢,你会告诉别人重启下办公电脑就行,无论是WIN95,WIN98,WIN XP,WIN7,WIN10。这就是你的高招。

你觉得小仙会告诉你这个大招嘛? 重启数据库,不行就重启服务器。

因为重启了,你就是失去了AWR报表,也失去了ASH报表。因为数据库实列重启会造成快照断裂,断档了一切性能报表就失效了。因为性能报表存在内存中,或者说需要内存暂存及时的性能信息,而这个才是关键信息。

这样你两眼一抹黑啊! 你无法交代,也无法解释,心里没底。

那该怎么办啊?

就是杀死病毒啊! 把所有客户端链接统统杀掉,看下面杀人武器

[oracle@MKF-DB-56-10 dbscripts]cat kill_LOCAL_ORA.sh
ps -ef|grep LOCAL=NO|grep -v grep|awk '{print "kill -9",$2}' >> xxx.txt

ps -ef|grep "LOCAL=NO"|grep -v grep|awk '{print $2}'|xargs kill -9

如果系统还能用的话,或者SQLPLUS还能登上去操作的话,并且不慢。尽可能的先杀掉查询的链接。保证修改数据的链接,能继续下去。这样可以保证业务不丢失交易,让客户有个比较好的体验。

脚本是从V$SESSION SID+V$PROCESS 根据操作类型是SELECT的 并获得SPID ,然后在操作系统杀了它们。

标签:10,急诊,SS,数据库,阻塞,第五章,SQL,ID
来源: https://blog.51cto.com/15080028/2647404