故障树分析法在数据库诊断分析中的应用

编辑手记:将知识转化为能力,除了需要经验的积累和时间的磨砺,更重要的是正确的方法和思维模式,学会应用知识才是真正的能力。本文试图通过方法的讨论使大家能够形成一个稳定的解决问题的思路和方法,按照这个思路和方法将我们所学的知识整理武装起来,这样在面对问题时就能够快速地找到一条发现和解决问题之路。

故障树分析法

故障树分析法(Fault Tree Analysis,FTA)是在对系统的可靠性进行分析时最常用的方法之一。FTA方法是指在系统设计或改进过程中,通过对可能造成系统故障的各种因素(包括硬件、软件、环境、人为因素等)进行分析,画出逻辑框图(即故障树),从而确定系统故障原因的各种可能组合方式及其发生概率,并以此计算系统的故障概率,采取相应的措施,以提高系统可靠性的一种设计分析方法和评估方法。

故障树分析图经常被用在Six Sigma进程中,特别用在Six Sigma业务改进进程的分析阶段。

  • 故障树分析法对于数据库故障解决的意义

经过在实践和应用中的总结,我发现故障树分析法作为一种分析方法和思路,同样适合数据库故障的分析和解决,如果扩展一步来说,这种方法作为一种思维方式,甚至适合生活中所有事件的分析和处理。

但是需要注意的是,故障分析实际上是一种事后分析的方法,当然我们不希望工作、生活中当事故、问题出现后再来分析,所以,我一直提倡将故障树分析在事前实施,通过参考别人的经验、教训,将故障树引入事前,人类的学习特点应当能够使我们从学习中而不是亲身经历去获得经验。

通过实践我们发现,将应用于传统行业的故障树分析法引入到数据库故障分析及问题解决之中,可以极大地加快问题分析、处理和解决的速度,同时可以帮助我们发现系统的缺陷所在,从而通过实施有效的预防措施显著地提高系统的稳定性和可靠性。

  • 故障树分析模型的建立

如图所示是数据库系统故障分析树的一个示例,这里以数据库故障为起点,来分析可能导致数据库及应用故障的可能因素。

分析的过程是一个穷举故障原因的过程,我们可以按照不同的方法对故障的原因进行分类,在这个分析中,首先我将第一层归结为3类问题:客户端/中间层故障、网络故障、服务器端故障。这其中任何一处出现问题都可能会导致数据库服务出现问题。

再来进一步深入分析,在一个数据库系统中,客户端或中间层如果出现问题,就可能会影响数据库系统的使用,但这在用户看来同样是数据库故障。那么对于这一类问题,进一步细分,客户端/中间层有哪些故障会引起数据库的访问不畅呢?

首先如果客户端的应用程序损坏可能造成数据库的无法连接,曾经有很多案例因为客户端感染病毒而导致应用程序异常;然后常见的还有客户端版本及驱动问题,Oracle的版本众多,如果驱动版本不匹配可能也会出现问题;客户端的防火墙有时候也会成为阻碍数据库成功访问的障碍之一;当然更为常见的是客户端的配置文件(tnsnames.ora文件或中间件的配置文件)存在问题,导致无法正确连接数据库的。可能的原因还有很多,更为完善的故障树分析图如下图所示。

分析完客户端,在数据库和客户端之间还存在网络,网络问题也是常见数据库故障的问题点之一,可以尝试对网络故障再进行细分,如下图所示。

网络故障的可能原因也很多,首先是物理链路的问题,公网和内网都可能存在链路故障、品质降低等,再加上地址路由等因素,这方面的故障实在很多见,其次防火墙、带宽、流量等因素也是需要考虑的。

当客户端、网络一切正常之后,就到了最重要的一环──数据库服务器端,如果这里出现故障或性能问题,那么原因可能是极其复杂和多样化的。下图列举了一些常见的数据库端故障问题,这张故障分析图是应该存储在每个DBA的头脑中的。

首先客户端经过网络向数据库发送请求,数据库服务器端最先接受请求的数据库监听器,如果监听器出现问题,则数据库连接肯定会出现异常,所以监听器是一个重要环节和故障点。

数据库服务器还可能会经常出现资源短缺等问题,比如连接数耗尽、用户无法创建新的连接;因为归档或备份,磁盘空间可能被耗尽,导致数据库问题;或者磁盘I/O因为硬件故障或性能问题,都可能导致数据库故障或响应缓慢;内存资源或交换也是重要内容,如果内存不足,可能导致数据库性能低下,严重影响数据库的正常运行;CPU资源不足是实际生产中经常会遇到的问题,其原因多样化,可以沿这个节点进一步深入分析。

此外,应用问题也是经常会导致故障的原因之一,有的是因为SQL编写问题,有的是因为数据结构设计存在问题,有的甚至是数据库软件本身就存在Bug。最后来看一下这张图的全貌。

事实上,故障树分析法的使用完全可以十分灵活,我们可以以任何一个提出的问题作为分析起点,比如用户经常反映“数据库响应缓慢”的问题,就可以从这里出发进行问题分解和分析。

有了这样的分析基础之后,在遇到故障时就可以快速地在大脑里进行根据故障树进行分析导航,从而迅速地定位问题的原因,并根据经验或知识找到解决故障的方法。从这个意义上说,故障树也是一个索引。

在这篇文章的讨论过程中,曾经有专家问过我这样的问题:你这种方法只是一个理论的设想,还是在实际中能够有所应用?

实际上我在故障处理中一直是按这样一个思路在处理,后来当我思考怎样将思路转化为方法更容易为大家所学习、探讨时,发现了故障树分析法;我发现故障树分析法就正是我一贯的思维方式,两者契合得如此之好,所以我才将这种方法总结出来供大家参考。

故障树分析法在故障解决中的应用

接下来我们通过一个案例来讨论一下故障树分析法在实际问题解决中的应用。这是一个24×7的重要业务系统,故障出现时业务及开发人员报告系统运行缓慢,已经影响业务系统正常使用,请求协助诊断。

  • 性能缓慢到CPU消耗的定位

业务系统缓慢,根据我们的故障树,可能的原因有资源耗尽、应用问题等,在实际环境中,很多问题可能是同时出现和产生影响的。

首先登录数据库主机,检查当前系统状况。使用vmstat检查,发现CPU资源已经耗尽,大量任务位于运行队列:

本案例当时,系统CPU资源已经耗尽,Idle为0,并且运行队列大量进程排队等待。通过故障树分析思路,利用简单的系统工具辅助,很快就可以发现问题的症结所在。进一步地,我们可以检查一下进程问题,CPU资源的过度耗用可能是个别进程异常或者进程过量累积所导致的。

  • CPU到进程的故障树分析

通过Top工具,我们可以查看进程CPU耗用情况,如果存在进程异常,可以通过Top定位,为进一步诊断提供依据。对于本案例,观察进程CPU耗用,发现没有明显过高CPU使用的进程。

从Top的输出中,可以发现有大量进程处于running的运行状态,CPU消耗很平均,单进程消耗大约在1%左右,基本可以排除个别进程异常导致CPU问题的可能。没有个别进程异常,那么过量的CPU消耗可能是进程累积所导致的,我们根据故障树,在同一层面上对可能导致CPU过度消耗的原因进行排查。我们知道对于一个生产数据库系统,稳定运行的进程数量通常是可知的。

提示:对于稳定运行的生产系统,数据库的运行状况通常是稳定的,如果你绘制出性能曲线,你会发现每个星期的曲线几乎是可以重合的,所以说对数据库系统的运行状况及性能指标具有充分认识和了解是必须的。

来看一下当前系统的进程数量,从而进行比较判断:

bash-2.03$ ps -ef|grep ora|wc -l 258 bash-2.03$ ps -ef|grep ora|wc -l 275 bash-2.03$ ps -ef|grep ora|wc -l 274 bash-2.03$ ps -ef|grep ora|wc -l 278 bash-2.03$ ps -ef|grep ora|wc -l 277 bash-2.03$ ps -ef|grep ora|wc -l 366

发现此时系统存在大量Oracle进程,大约在300左右,大量进程消耗了几乎所有CPU资源,而正常情况下Oracle连接数应该在100左右。

由此,可以基本判断,是数据库或应用出现了问题导致进程任务无法完成,又不断累积,从而出现大量队列等待。这些等待在数据库中应该有具体的体现,接下来需要登录数据库进行检查了。

  • 进一步诊断应用问题

判断数据库可能经历了等待,那么Oracle数据库提供了相关视图供我们查询和发现问题,v$session_wait是首先值得关注的。查询v$session_wait获取各进程等待事件:

对于本案例,我们发现存在大量db file scattered read及db file sequential read等待。显然全表扫描等操作成为系统最严重的性能影响因素。确定这些进程因为数据访问产生了等待,我们考虑捕获这些SQL以发现问题。

这里用到了我的以下脚本getsqlbysid.sql,该脚本通过已知session的sid,联合v$session、v$sqltext视图,获得相关session正在执行的完整的SQL语句。

SELECT sql_text FROM v$sqltext a WHERE a.hash_value = (SELECT sql_hash_value FROM v$session b WHERE b.SID = '&sid') ORDER BY piece ASC /

使用该脚本,通过从v$session_wait中获得的等待全表或索引扫描的进程SID,可以捕获可能存在问题的SQL语句:

SQL> @getsqlbysid Enter value for sid: 18 old 5: where b.sid='&sid' new 5: where b.sid='18' SQL_TEXT ---------------------------------------------------------------- select i.vc2title,i.numinfoguid from hs_info i where i.intenab ledflag = 1 and i.intpublishstate = 1 and i.datpublishdate <= sysdate and i.numcatalogguid = 2047 order by i.datpublishdate d esc, i.numorder desc SQL> / Enter value for sid: 54 old 5: where b.sid='&sid' new 5: where b.sid='54' SQL_TEXT ---------------------------------------------------------------- select i.vc2title,i.numinfoguid from hs_info i where i.intenab ledflag = 1 and i.intpublishstate = 1 and i.datpublishdate <= sysdate and i.numcatalogguid = 33 order by i.datpublishdate des c, i.numorder desc ......

对几个进程进行跟踪,分别得到以上SQL语句,这些SQL可能就是问题产生的根源。

  • 从SQL到问题本质的诊断

使用该应用用户连接,通过autotrace功能检查以上SQL的执行计划:

SQL> set autotrace trace explain SQL> select i.vc2title,i.numinfoguid 2 from hs_info i where i.intenabledflag = 1 3 and i.intpublishstate = 1 and i.datpublishdate <=sysdate 4 and i.numcatalogguid = 3475 5 order by i.datpublishdate desc, i.numorder desc ; Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=228 Card=1 Bytes=106) 1 0 SORT (ORDER BY) (Cost=228 Card=1 Bytes=106) 2 1 TABLE ACCESS (FULL) OF 'HS_INFO' (Cost=218 Card=1 Bytes=106) SQL> select count(*) from hs_info; COUNT(*) ---------- 227404

通过执行计划,可以看到以上查询使用了全表扫描,而该表这里有22万记录,全表扫描已经不再适合。检查全表扫描的数据表,发现存在以下索引:

SQL> select index_name,index_type from user_indexes where table_name='HS_INFO'; INDEX_NAME INDEX_TYPE ------------------------------ --------------------------- HSIDX_INFO1 FUNCTION-BASED NORMAL HSIDX_INFO_SEARCHKEY DOMAIN PK_HS_INFO NORMAL

检查索引键值:

SQL> select index_name,column_name 2 from user_ind_columns where table_name ='HS_INFO'; INDEX_NAME COLUMN_NAME ------------------------------ -------------------- HSIDX_INFO1 NUMORDER HSIDX_INFO1 SYS_NC00024$ HSIDX_INFO_SEARCHKEY VC2INDEXWORDS PK_HS_INFO NUMINFOGUID SQL> desc hs_info Name Null? Type --------------------------------- -------- -------------------------------------------- NUMINFOGUID NOT NULL NUMBER(15) NUMCATALOGGUID NOT NULL NUMBER(15) INTTEXTTYPE NOT NULL NUMBER(38) VC2TITLE NOT NULL VARCHAR2(60) VC2AUTHOR VARCHAR2(100) NUMPREVINFOGUID NUMBER(15) NUMNEXTINFOGUID NUMBER(15) NUMORDER NOT NULL NUMBER(15)

……

  • 调整并最终解决问题

检查发现在numcatalogguid字段上并没有索引,该字段具有很好的区分度,考虑在该字段创建索引以消除全表扫描。

观察系统状况,原大量等待消失:

在另外的session里,持续观察的CPU使用情况:

----以上为创建索引之前部分

----以下为创建索引之后部分,CPU使用率恢复正常

至此,此问题得以解决。

  • 性能何以提高

回答这个问题似乎是多余的,我只想重申一点:有效地降低SQL的逻辑读是SQL优化的基本原则之一。下面来比较一下前后两种执行方式的逻辑读取及性能差异。

(1)全表扫描的性能:

(2)使用索引的性能:

consistent gets从3499到89,可以看到性能得到了巨大的提高。

通常,开发人员很少注意SQL代码的效率,他们更着眼于功能的实现。至于性能问题通常被认为是次要的,而且在应用系统开发初期,由于数据库数据量较少,对于查询SQL语句等,不容易体会出各种SQL句法的性能差异。但是一旦这些应用作为生产系统上线运行,随着数据库中数据量的增加,大量并发访问,系统的响应速度可能就会成为系统需要解决的最主要的问题之一。在少量用户下性能可以接受的SQL,可能在大量用户并发的条件下就会成为性能瓶颈。

在我这个案例中,开发人员很难相信仅只一条SQL语句就导致了整个数据库的性能下降。然而事实就是如此,一条低效的SQL语句就可能毁掉你的数据库,所以在系统设计及开发过程中,你必须考虑到诸多细节,严格的测试也是提早发现问题的有效方法。

如果不幸以上环节都被忽略,那么,DBA(也许就是你)就是最后的一环,你必须能够快速地诊断并解决各种复杂问题。

故障树分析法应用的总结

通过以上的故障解决实例我们可以发现,整个故障的解决过程中,故障树的思想是被不自觉地贯穿始终的,那么现在,通过分析归纳和提炼,我将这个分析思路通过故障树的方法展现出来,希望能够对各位读者朋友有所帮助。

原文发布于微信公众号 - 数据和云(OraNews)

原文发表时间:2017-02-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏杨建荣的学习笔记

merge语句导致的ORA错误分析(r9笔记第67天)

最近处理了好几起关于merge导致的问题,其实看到merge语句内心也还是蛮纠结的,这一次还是碰到了问题,简直无语了。 先交代下问题...

3316
来自专栏Java技术

初探性能优化--2个月到4小时的性能提升!

一直不知道性能优化都要做些什么,从哪方面思考,直到最近接手了一个公司的小项目,可谓麻雀虽小五脏俱全。让我这个编程小白学到了很多性能优化的知识,或者说一些思考方式...

591
来自专栏架构说

分布式追踪系统---google的dapper

说明:在info分析看到多次提到全链路跟踪 基本提到google的dapper, 这里不再重复早轮子,转载 看原文链接 最近看了google的分布式追踪系统da...

47312
来自专栏企鹅号快讯

一文教会你数据库性能调优

前言 微软工程师的一个工程师曾经对性能调优有一个非常形象的比喻:剥洋葱 。我也非常认可,让我们来一层一层拨开外面它神秘的面纱。 ? 六大因素 下面祭出的是我们在...

1709
来自专栏北京马哥教育

NoSQL之mongodb我见

NoSQL介绍: NoSQL数据管理系统是目前非常流行的一种非关系性、分布式、不支持ACID设计规范式的数据库;NoSQL简单的数据模型、元数据和数据分离、弱一...

2859
来自专栏JAVA高级架构

多研究些架构,少谈些框架(3)-- 微服务和事件驱动

接上篇,我们采用了领域驱动的开发方式,使用了充血模型,享受了他的好处,但是也不得不面对他带来的弊端。这个弊端在分布式的微服务架构下面又被放大。 事务一致性 事务...

2764
来自专栏谭伟华)的专栏

Amazon Aurora:云时代的数据库 ( 上)

文章是 Amazon 在 SIGMOD\'17 上最新发表的关于 Aurora 论文的翻译版本,详尽的介绍了Aurora 设计背后的驱动和思考,以及如何在云上实...

4990
来自专栏Albert陈凯

2018-08-25 2000万条数据迁移从几天到几个小时

一直不知道性能优化都要做些什么,从哪方面思考,直到最近接手了一个公司的小项目,可谓麻雀虽小五脏俱全。让我这个编程小白学到了很多性能优化的知识,或者说一些思考方式...

872
来自专栏IT技术精选文摘

微信后台基于时间序的海量数据冷热分级架构设计实践

1716
来自专栏数据架构之路

RDBMS变化数据设计,采集和接入大数据平台

在数据爆发式增长的时代,记录数据变化和演变,探究内在规律并运用到生产实践中,驱动业务的增长成为这个时代主旋律。本文就如何记录数据变化,处理数据变化谈谈...

61618

扫码关注云+社区