DBA行业的老司机知道等待事件分析对数据库运维来说有多么重要,等待事件分析是Oracle在7.3版本中推出OWI后才变得可能的,必须在数据库核心层提供接口才能实现。
国产数据库在等待事件接口方面也做了很多的工作,我第一次用达梦数据库的时候就发现居然有等待事件,虽然达梦数据库的等待事件还比较简单,不过对于运维来说还是很有价值的。最近和Oceanbase、Polardb的朋友交流中也发现他们也在等待事件分析方面做很多突破性的功能增强,一些能力可能很快就可以合并到主线版本中了。
PostgreSQL是在9.6版本首先引入等待事件的,虽然openGauss的基础PostgreSQL版本(9.2.4)并不支持等待事件,不过openGauss从1.0开始就支持等待事件了,当然2.0之后openGauss的等待事件有了极大的提升,支持了等待时间。对于等待事件分析来说,支持等待时间分析是一个巨大的提升,这可以让等待事件分析更为有效。
openGauss的等待事件并没有放在pg_stat_activity中,而是另外使用了一个视图接口。这种设计我猜想是为了避免对PG内核做过多的修改,从而影响PG核心的稳定性。因为等待事件采集和会话的活动有直接的关系,涉及到数据库最核心的代码。openGauss通过两张表分别来实现等待事件分析。
一张是thread_wat_status,另外一张是等待事件汇总信息wait_events,记录了数据库启动以来每个等待事件发生的次数、平均等待时间,最大等待时间,最小等待时间等信息。这张视图有点类似Oracle的v$eventmetric。
比较Oracle(上图是11g)的这张视图,openGauss提供了一些类似信息最大值,最小值,平均值的数据,只是有经验的DBA都知道全局的最大值最小值是没有意义的,数据库启动后只要出现过一次极端现象,就会把这些值固化了,反而对于运维来说没有价值了。
看样子这个功能模块的产品经理运维实战的经验还略显不足,实际上如果能够保存最近1分钟,最近5分钟,最近10分钟,最近半小时这些最大最小值,或者仅仅保存最近1分钟的最大/最小值对于运维来说更有价值。不管如何,这种设计体现了openGauss数据库产品的开发者是考虑了运维的需求的。
上面是openGauss 2.1的等待事件数量-321个,比PG 12足足多了一倍,openGauss 3.0的数量差不太多。
总数是353,多了30多个,每个版本等待事件数量都在增加,说明这个接口的活跃度是可以的,如此发展下去,这个功能会越来越完善。
不过比起Oracle 11g的1367还是有差距,Oracle 19c,这个数量赢又快翻了一倍了。国货还是有很大的发展余地。不过看等待事件,不仅仅要看数量,而是要看是不是都是一些有效的等待事件。我们在openGauss3上做了几次小的benchmark压测(我们的环境只是功能测试环境,一台虚拟机上部署了多套数据库,因此只能做一些小压测),大概平均TPMC为2500左右。然后来看看有哪些等待事件是非零的。
相当不错了,有66个等待事件的等待次数是非零的。类似的情况,在Oracle 11g里,大约也只有100多个等待事件是非零的,因为很多等待事件是某些场景下才会发生的。
从这个查询中我们可以看到等待事件排序比较靠前的基本上都是和IO相关的。具体某个等待事件的含义我们后面再慢慢研究,我们也会在PG知识图谱的基础上构建支持openGaus等待事件分析的知识图谱。
接下来我们先来看几个openGauss 等待事件性能视图的考虑的比较好的地方。除了刚才说的并均值之类的,还有就是failed_wait字段和last_updated。正常的系统中一般不会出现failed wait,如果某个时间段里出现了较多的failed wait,说明这个等待存在较大的问题。而last_updated则记录了该等待事件最后一次等待的时间,这在运维中遇到了性能问题,需要分析根因的时候十分重要,有可能这个时间戳就可以帮你过滤掉一些重要的等待事件,从而帮你更精准的定位问题。
说完优点,我们就要说说缺点了,Oracle在v$event_histogram中保留了非零等待事件的直方图数据。
这个数据对于做深度的分析十分有价值。通过定期采集数据,可以了解很多等待事件的详情。
我们再回过头来看看Oracle的v$eventmetric视图,通过begin_time/end_time我们会发现,对于大多数EVENT,oracle记录的都是1分钟的采样周期内的情况。WAIT EVENT是一种瞬间发生的等待,在具体的性能分析工作中,长时间的累计值实际上并不重要,更为重要的是最近的情况,而1分钟的统计值十分有助于帮助DBA进行分析。哪怕存在一些特殊的异常值,通过观察几次一分钟的数值,就可以基本了解某个等待事件在此期间的异常情况。
Oracle的v$sysstat中记录的是一些系统统计数据,这些数据记录一个统计值就够用了,我们可以通过多个SNAP的差异来进行分析。如果我们没有采集历史的SNAP,那么分析历史数据还是有些困难的。不过这些指标在AWR中都有采集。而对于等待事件这种分析,和统计数据的分析需求是不同的。因此简单的记录统计值是不够的,openGauss的研发人员也发现了这方面的问题,因此增加了一些平均值之类的属性。不过个人以多年的运维经验来看,还是更喜欢使用Oracle的这种模式。有可能是我已经在多年的Oracle数据库运维中被洗脑了,不过似乎Oracle的方式在现场分析时效果更好。我们的国产数据库企业还是需要多学习学习Oracle在一些细节上的处理的。这些细节都是多年数据库产品发展中积累下来的,技术含量并不一定很高,但是实战效果确实很好。
最后我们再来看看thread_wait_status,令人略感遗憾的是在会话级的等待事件上并没有包含等待时间,我想以后的版本应该会慢慢的加上,能做系统级的等待事件分析已经为具有细粒度等待事件分析的能力提供了一个基础。