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

为什么平均等待时间对数据库运维很重要

时间:2023-03-12 16:55:12 科技观察

昨天讲到人大金仓数据库的二次使用,能够从可观察接口获取到等待事件的等待时间信息,我感受到了数据库在易用性上的进步。有的朋友很疑惑,不就是等待数据采集的时间长短吗?有那么重要吗!说实话,运维人员获取数据库的等待事件的等待时间比重要的还要重要。我们很容易从数据库中获取等待事件的数量。等待事件数的统计对于数据库内核来说并不麻烦,只要维护一个内存数据结构,并用轻量级锁保护内存结构即可。数据库会话可以通过将它们累积到数组中来获取这些统计信息。甚至很多数据库根本不需要统计等待次数,只需要在session信息中加入一些等待事件的相关数据项即可。每个session维护自己的sessionstateblock,每次产生一定的等待,只需要累加,其维护成本很低。但是统计某个等待事件的等待时间就不一样了。十多年前和国内的数据库厂商交流时,他们指出他们在新版本中引入了等待事件,但目前只能提供等待次数,无法提供等待时间。他们测试过在session信息中加入等待时间的统计,但是加入之后,数据库整体性能下降了10%以上。他们想知道Oracle数据库是如何实现OWI接口中等待时??间统计的。当时,我并没有深入研究这个问题。为了回答这个问题,我也研究了一下OracleOWI接口的发展历史。事实上,甲骨文在这些数据的统计上经历了一些波折。起初,它甚至使用CPU周期、资源管理器等来粗略估计持续时间。之后使用统一的时间戳进行近似估计。其目的是逼近成本最低、对数据库操作影响最小的统计等待时间。既然获取等待事件的时长要付出这样的代价,为什么DBA还需要获取这个数据呢?难道不能从数据库等待事件的次数就知道数据库在做什么,在等待什么吗?其实等待事件的分析是非常复杂的。和一些DBA想的不一样,看到等待事件,百度一下就可以定位到数据库的问题。某个等待事件是否会导致某个数据库出现问题,不仅取决于等待事件是否发生,还取决于等待事件占总等待的比例。这个比例可以是等待次数,也可以是等待时间,等待时间的准确度更高。如果某个等待事件发生的次数很高,只能说这个区域的负载很高。如果每次等待时间都很低,或者在日常数据库没有问题的情况下非常接近平均等待时间,那么可能说明数据库在这方面的并发性能没有问题,而数据库问题可能不是由这个等待事件引起的。比如上图中,我们发现IO延迟突然增加了,那么我们可以通过IO延迟突然增加和十几分钟后服务器重启来综合分析,从而缩小原因对比较狭窄的分析面的失败以上,利用这个问题进行下一步的问题定位。而如果只知道IO等待数,那么只能知道当前的SQL读写IO负载很高,可能有一些产生大IO的SQL,或者有大量的并发访问。但是我们无从得知当前的IO负载是否会导致数据库出现问题,或者数据库是否存在宕机风险。我们很高兴看到国内大部分数据库都开始提供等待事件等待时间的数据,这对于DBA运维国内数据库来说非常重要。收集等待事件的等待时间对数据库核心也是一个挑战。收集成本最低、对数据库性能影响最小的等待时间非常重要。记得去年测试Polardb-O的可观察性能力时,惊喜地发现Polardb可以采集一些关键等待事件的等待时间。这些关键等待事件主要与lwlock和数据库IO有关。对于其他等待事件,Polardb不提供等待时间。这种设计也体现了运维和数据库性能之间的平衡。通常,对于现代硬件,如果启用这些捕获,增加的数据库开销不到5%,在某些系统上甚至可以接受不到10%。但如果太高,是不可接受的。当时我发现在Polardb-O商业版中IO等待时间的采集数据是空的,而在开源版Polardb-PG中可以看到这些数据。我们当时没有深究这个问题。今年我们加入了Polardb社区,同时我们也开始在D-SMART中对Polardb做深度对接,将Polardb-PG数据库从社区版PG数据库中分离出来,利用增强的可观察性POLARDB的能力加强POLARDB的监控诊断和分析能力,所以我们重新分析了这些可观察性接口。通过与阿里技术人员的沟通,我们发现如果要在Polardb商业版上采集Polar_stat_io_latency等IO相关的等待时间数据,即使使用单机版的本地文件系统,也必须存储数据库在Polar自带的PFS文件系统上,并设置polar_enable_shared_storage_mode=on,即可采集到相关数据。完成这些设置后,我们可以从polar_stat_io_info/polar_stat_io_latency视图中看到数据。在开源版本中,IO延迟时间的获取是基于大多数数据库使用的native模式,可以直接在数据库内核中实现。而在商业版中,这些优化是利用云原生数据库的特性,通过PFS的底层实现来完成的,可以大大降低数据库内核等待IO收集的时间成本。