最近在搞PG系国产数据库的AWR报告智能解析,所以又认真研究了一下PG的等待事件。不知道有多少PG DBA在运维PG数据库的时候会使用等待事件,估计用的那些人大多数是以前的ORACLE DBA。
Oracle DBA刚刚转到PG的时候首先会比较高兴,因为PG也有等待事件,不过很快就会很失望,因为PG的等待事件太奇葩了。PG的等待事件机制主要通过pg_stat_activity展示当前会话的wait_event_type和wait_event,用于识别进程正在等待的资源类型和具体事件,它的特点是轻量化,但只提供当前快照信息,不记录累计等待时间或平均延时;相比之下Oracle的等待事件体系更为成熟和细致,提供了全面的等待类目、累计时间、平均延时等统计指标,可以直接用于性能诊断和瓶颈定位,属于内核级的性能分析框架。
PG在等待事件方面偏向简洁和透明,可以通过外部插件或者通过外部工具进行采样和统计,而Oracle则内置了完整的等待事件监控体系,两者的差异体现了设计理念上的不同。PG采用了一种一个是开放式、可扩展的架构,另一个是封闭式、内建的诊断系统。
抛开等待事件反映出的数据库内核运行状态的粒度等因素,当然PG这些年一直在细化等待事件,在PG 16、17版本中还新增了CommitDelay、CheckpointWriteDelay这些千呼万唤始出来的重要等待事件。DBA看PG等待事件的时候觉得比较不爽的是没有等待时间、平均等待延时等重要的属性,无法进行定量分析。当然也有一些PG插件提供了更多的等待事件采集的能力,国产PG系数据库也已经解决了等待事件的等待延时,平均等待时间甚至等待时间直方图等的采集问题。金仓KES的等待事件中还针对SQL ID采集了相关的等待事件,如果遇到某条SQL出现比较奇怪的执行行为(和执行计划无关),则可以通过等待事件去做分析。当然插件都是有代价的,采集这些数据意味着性能的损耗。内核原生采集虽然也会影响效率,不过会小很多。
PG等待事件还有一个十分奇葩的就是命名,不知道是不是PG管这块开发的人都觉得这功能做得有点鸡肋,连个正经名字都不好好起。大家看看上面的这两个等待事件,谁能从名称上猜测出它的意思,BufferFileRead,刚刚看到名字的时候,我还有点小激动,在PG数据库里纯粹从shared buffers中读取的逻辑读,从buffer cache里读取的OS BUFFERED Read和纯粹的物理读三者很难区分,因此无法通过定量分析来做精准的分析。如果BufferFileRead是指从OS BUFFUER读的话,那么就太好了。不过结果是令人啼笑皆非的,这个等待事件居然和WORK_MEM工作缓存溢出有关,也就是说和排序、HASH JOIN,VACUUM、表分析等行为有关。
作为一个开源数据库,其特质是与开源生态有关的,是有开发者基因的,其面向的主要对象不是企业级用户,而是开发者。因此用DBA的眼光来看PG,确实槽点很多。我想PG社区还会这么走下去,继续以开发者的视角来发展这个开源项目。不过对于使用PG搞商用数据库的国产数据库厂商,却应该换换思路。既然国测的要求导致了这些数据库产品必然会与开源产品硬分叉,那么在分叉的时候,就应该在这些PG开源社区设计比较奇葩的地方下点功夫。商用数据库主要是面对企业级用户的,那么像等待事件这些内核级的可观测性,就应该认真去设计了。