当前位置: 首页 > 科技观察

数据库的等待事件分析接口其实比我们想象的要丰富

时间:2023-03-20 13:22:50 科技观察

等待事件是数据库一个非常重要的可观察接口。通过等待事件,我们可以快速定位数据库存在的问题,及时掌握数据库的运行状态。二十年前,我在一家银行任职时,他们需要对核心系统进行监控,要求监控人员每五分钟检查一次是否有异常等待事件,以保证核心业务的正常运行。Oracle是第一个提供等待事件接口的数据库产品,现在很多数据库也提供了等待事件接口,只是提供的能力有些不同。国庆长假的这7天,每天看一点SQLSERVER的资料。首先,我发现微软的文档功底确实不错。阅读SQLSERVER资料甚至比阅读Oracle资料还要舒服。其次,我还发现SQLSERVER在等待事件接口方面做得很好。今天我将以Oracle、SQLSERVER、openGauss、Polardb为例,分析一下这些数据库的等待事件接口的特点,以及如何利用这些接口进行系统诊断。在说他的数据库之前,我们先来看看等待事件分析的鼻祖Oracle提供了哪些等待事件。我还是以经典版的Oracle11g为例。这个版本虽然是十几年前推出的,但是在等待事件方面已经非常完善了。其实不管是现在的Oracle数据库,还是其他一些支持等待事件分析的数据库,都和Oracle刚刚推出OWI时有所不同,等待事件的接口也丰富了很多。然而这些年我发现大家还在使用20多年前OWI刚出现时的等待事件接口来分析数据库系统,并没有使用一些在某些分析场景下更有效的新接口数据。这是一种惯性,就像十几年前,我习惯用v$session_wait视图来分析session的等待事件,而不是像一些年轻的DBA那样使用v$session。V$session_wait是Oracle在7.3.2版本推出的一个等待事件接口的视图,也是最经典的一个。不过这个视图并不是我们今天要讨论的主角,因为目前数据库系统等待事件分析的数据接口已经大大丰富了。我习惯把等待事件接口数据分为明细数据、汇总数据、抽样数据和这些数据的历史数据。这些数据在不同的场景下可以发挥不同的作用,利用得好可以满足DBA分析工作的方方面面。详细数据是当前等待事件的实时状态,对于当前的实时分析非常有价值。如果故障问题依然存在,分析当前的数据可以给我们一个直观的反映。不过大家在使用v$session的时候要注意一个问题,就是Oracle的等待事件接口和其他数据库不一样。让我们看看有什么不同。以前我们可能只关注会话的活跃状态,而很少关注状态。oracle的v$session中显示的waitingevents不仅显示了waitingevents,还显示了刚刚等待的状态。所以有时候我们看到的一个等待事件可能在那个时候已经结束了,而不是正在发生,有的正在发生。注意到这个区别非常重要,可以帮助我们详细分析数据库的等待事件。其他数据库一旦结束某个等待事件,就会立即进入IDLE状态,这样在系统中,我们看到的IDLE就更多了。等待事件相关视图的多次查询可能会有较大差异。作为DBA,我更喜欢Oracle这种输出接口的方式。因为在大多数情况下,我们不需要知道准确的实时状态,而是了解这段时间的大趋势。保持刚好在结束之前和其他等待事件开始之前的状态是非常重要的。事实上,详细的数据更有利于分析当前的实时状态,找出当时某个会话存在的问题,或者某些会话引起的某个问题。要了解系统当前等待事件的整体情况,发现系统中隐藏的一些深层次问题,往往需要统计数据。这也是DBA倾向于从AWR报告中比通过v$session更容易看到系统问题的主要原因。在PG数据库中,pg_stat_activity提供了一些session等待事件的信息,但是缺少等待时间。这个视图在一些基于PG的开源或者国内的数据库中也有提供,也做了一些扩展。依靠PolarDB的两个插件polar_monitor/polar_monitor_reload,我们可以获得很多原生态PG数据库没有的监控功能。其中最重要的是我们可以获得等待事件等待时间的数据。等待时间可以为运维分析提供更准确的信息。这个在我前段时间发的几篇关于openGauss的文章中也有说明。Polar_monitor插件为我们带来了几个以polar开头的监控视图。其中就有我们期待的polar_stat_activity。这个类似pg_stat_activity的监控界面有我们需要的新数据。SQLSERVER从2016(13.x)版本开始提供dm_exec_session_wait_stats视图,可以提供类似于v$session的数据接口。Oracle实际上提供了丰富的等待事件统计信息。通过v$eventmetric可以看到最近1分钟等待事件的统计信息。在这个系统界面中,我们可以看到等待次数,等待时间,最后一分钟等待每个等待事件的会话数,以及前台进程的等待次数和总时长数据。这些数据对于我们分析最后一分钟某个等待事件的发生有很大的帮助。但是,如果我们想要了解系统中等待事件的整体情况,v$eventmetric提供的信息是不够的,我们还需要v$system_event的信息。v$system_event根据系统中等待事件的类别提供统计信息,是自数据库启动以来的统计值。如果我们定期对该视图的数据进行采样,就可以掌握系统中等待事件的整体情况。此采样数据可用于对任何时间段的等待事件进行整体分析。openGauss和PolarDB也提供了类似的统计数据接口。openGauss的dbe_perf.wait_events提供了类似于Oracle的统计信息,但是更详细。因为openGauss没有提供类似于Oracle的柱状图的信息,它提供的是最大值和最小值的统计。虽然不如提供柱状图那么直观,但对于等待事件分析还是非常有价值的。SQLSERVER也提供了类似的统计数据接口dm_os_wait_stats。可以看到这里也出现了max_wait_time_ms这个字段。观察最大值对于分析等待事件非常关键。以上两个统计数据对于等待事件的分析是不够的,因为我们只有平均值。如果几十万甚至几百万的等待事件中有几千,那我们就无法从中学习。在这数千个数据中发现异常的平均等待时间。而v$event_histogram弥补了这个缺陷。通过直方图,我们可以了解各种等待时间的等待事件的统计情况,从而发现某个时间段内出现了某个问题。这个接口也是系统启动时的一个统计值。但是我们可以通过LAST_UPDATE_TIME来分析某个柱状图的数据在我们分析的时间段内是否有更新。因此,如果我们不定期收集这些数据,还是可以看出一些端倪的。当然,如果能够实现定期收集这些数据,那肯定是有好处的。AWR会定期收集这些数据并保存,但是它的收集粒度太粗了。对于一些数据,很难完整地保存历史详细数据,因此常采用抽样的方式。Oracle会对v$session非常重要的数据,以1秒为单位进行动态采样。保存活跃会话的全量采样,openGauss、OceanBase等也做过类似的采样。PolarDB在新版本中也会提供类似的采样。在Oracle中,可以通过v$active_session_history访问此采样。但是大家要注意,因为是抽样数据,所以会漏掉一些。虽然1秒是一个比较短的采样周期,但是还是会遗漏一些等待事件。但是,如果某个问题一直在发生,那么很有可能在采样过程中会捕获到这个等待事件。除了Oracle数据库,openGauss率先提供了类ASH数据接口,其次是Oceanbase和PolarDB。我想以后国内会有越来越多的数据库提供类似的接口。因为这个接口对于分析数据库问题,尤其是性能问题是非常关键的。另外,历史数据也是我们分析问题最常用的,因为我们经常要分析数据库中之前某个时间段的问题,而不仅仅是分析当前。没有历史事件的积累,我们就无法进行分析。借助AWR等成熟的数据采样机制,Oracle提供了多种历史数据存储机制。如果我们能够充分利用它,它可以帮助我们解决很多问题。与Oracle相比,国内和开放数据库的数据接口还是比较少的。我觉得这是国内数据库以后要改进的地方。