Oracle技术支持是如何分析数据库性能问题的

Oracle技术支持是如何分析数据库性能问题的

Dongwei Wang | September 15, 2013
 
 
    调优是一个永恒的话题,贯穿于一个数据库系统的完整生命周期。在这里我们主要关注的是作为技术支持我们是如何看待调优问题的,面向的对象主要是负责维护数据库系统的DBA。这个话题国内外有很多的大牛们写了很多很牛的书了,真的很好,我们中国的Oracle爱好者在这方面也有很多很好的经验。但是,我们还是会遇到有人问如何分析数据库的性能问题?万变不离其中。下边就简单阐述一下作为Oracle技术支持是如何分析一个性能问题的。首先声明,这个不是个人创造的,而是Oracle全球技术支持通用的一个方法论(听起来是不是挺吓人?)

    有几个概念先要说清楚。对于用户而言,性能就是响应时间,也就是我发起一个操作,到这个操作完成的时间间隔。比如在12306买火车票,用户只关心从我开始发起买票这个操作,到什么时候我买到了。但是从整个系统的角度看就不一样了。一个三层架构的系统至少包含了客户端,应用服务器,数据库服务器。对于最终用户而言,我只知道我点了确认键后等了10分钟才跳转到成功页面,但是如果想要做优化,系统的维护者必须知道这10分钟究竟是分别花在哪一个阶段。一个典型的流程图:
      客户端发起请求→应用服务器收到请求→应用用服务器发送请求→数据库服务器收到请求→数据库服务器处理请求→数据库服务器返回请求→应用用服务器收到返回→客户端收到返回

      所以,这中间任何一个环节的缓慢都会造成这个请求响应的缓慢。实际上,我们还可以进一步深入分析,究竟是在某一个环节中间慢,还是两个环节在交互的时候有延迟?举个例子,如果大量的时间消耗在数据库服务器收到请求到数据库服务器返回请求,那么这个就是数据库这个环节的问题;但如果时间是消耗在数据库服务器返回请求到应用用服务器收到返回,那么就是两个环节之间的问题了。好在现在每一层都有自己的日志,通过客户端的日志我们能知道总共的响应时间,应用程序和数据库服务器的日志能知道这两层消耗的时间,加加减减就知道问题出在哪了。

      好了,如果不幸问题确认是发生在数据库层(为什么总是我?!),我们该怎么办呢?从数据库的角度,响应时间是这样计算的:
    响应时间=服务时间+等待时间

    服务时间其实就是我们通常说的CPU时间,等待时间就比如等待I/O,等待锁等等。绝大部分时候我们都是期望响应时间要尽可能接近服务时间,因为那样CPU才是真正在干活的;等待时间是我们通常需要去减小的,因为这意味着请求在等待某些资源,而没有干活。降低响应时间实际就是降低服务和等待时间,或者说降低CPU时间,I/O或锁等待。我们今天讲的是一个大的方法论,以后有机会会继续讲一些特定场景的优化。

    还有一个我想强调的是,对于操作系统而言,Oracle也是一个应用程序。我们依然需要从操作系统上获得CPU,内存这样的资源。如果操作系统有性能问题了的话,所有运行在上边的应用程序都将出问题,Oracle也不例外。当然,你可能会说我这个服务器就是数据库服务器,上边只运行了Oracle,但你能保证没有人用这个服务器下载复制电影导致带宽和I/O耗尽吗?这个真的是可能的。

    下边要说说我们是怎么分析数据库性能问题的了。
    + 问题描述。我一直以为性能问题比有错误或告警报出的问题更难解决,其中一个原因就是有错误的问题描述很简单,比如我运行了一条SQL,返回了942错误。性能问题的一个难点就是到底什么是问题,好多人都只会说”我的数据库慢“或者”我的应用没有响应“,从我上边画的流程图你就能知道这样的描述真的是没有意义的,那么什么样的描述是好的呢?

      - 用户看到的现象是什么样的?所有的应用都慢,还是某一条特定的SQL慢?
      - 问题发生的起止时间点?现象是自己消失的还是DBA手工干预了?DBA做了什么操作?
      - 问题发生的频率?很多性能问题都是有规律可循的。
      - 发生问题的时候有什么特殊的操作?对一张表添加了一个列?
      - 应用程序的负载是否有变化?比如正好是早晨刚开门时的业务高峰期?
      - 是否最近做过什么变更?比如上了一套新的应用?数据库刚打了一个补丁?操作系统加CPU了?

    回答了这些问题,说不定你自己也找到问题的原因了。如果你不说,技术支持,尤其是远程技术支持,是不会知道这个系统的背景的。多说一句,不光是使用Oracle技术支持要这样,大家在论坛或社区问问题的时候也要遵循这个原则,含糊的问题只能得到含糊的回答。

    + 问题描述清楚了,下边该我们技术支持来验证问题到底是不是这样的了。你可能又会说你就是不相信我们呗,真的不是这样的。要知道如果一个问题的描述都是错误的话,之后的分析再怎么正确也是徒劳的。我们要避免这种情况,就算它只有万分之一的可能,因为它会极大的浪费我们的精力。那么怎么验证呢?
      - 对于整个系统的性能问题,大家都知道AWR/ASH report,但其实你还要提供一份基线作对比。嗯,你可能会说如果我是新上的系统呢?好吧,我只能说我们尽力而为,因为调优无极限,你要是就是想拿能并发100个用户的系统并发10000个用户我也没办法。
      - 对于某条SQL语句的问题,大家都知道SQL_TRACE,同样,我们要基线。一条从来都没有快过的SQL可能真的需要应用程序开发者看看是不是真的要这么写了。

    + 分析问题。基于自上而下的原则:
      - 操作系统的性能有没有问题?给我看看OSWatcher的输出呗(MOS文档1526578.1,中文的哦)
      - 整个数据库的性能有没有问题?AWR/ASH。对于整个数据库的性能问题,我的原则是看有问题时消耗最多DB Time的是什么类型,当然,这个是基于基线的,有的系统可能物理I/O永远是占用DB Time最多的部分,但不见得有问题。
      - 数据库hang住了?hanganalyze和systemstate dump。我们有个工具叫HANGFG(MOS文档362094.1),你就不用手工输入那些复杂的命令了。
      - 只是某条语句有问题?看看SQL_TRACE吧

    + 解决问题。一旦问题的原因定位到,找一个最合适的解决方法实施就好了。对于性能问题,调优有时是渐进的,你可能需要调调这,改改那,最后彻底解决问题。我理解大家做一次变更走流程很麻烦,我们也会尽可能尽量一次性将需要做的变更都找到,但真的不能百分百保证。

    综上,分析一个数据库性能问题,我们需要
      - 一个清晰准确的问题描述。
      - 足够的诊断信息,推荐MOS文档1549179.1 - 最佳实践:针对性能问题的主动型数据收集,也是中文的。

    当然,最好所有问题都消灭在萌芽中(技术支持不会失业吧。。),推荐MOS文档1549184.1 - 最佳实践:主动避免数据库和查询相关的性能问题。

    后续的讨论可以到这里继续

posted @ 2021-11-23 20:37  耀阳居士  阅读(99)  评论(0编辑  收藏  举报