2010年我开始创作《DBA的思想天空》,当时是以论道的心态来写这本书的。我觉得一个DBA在没有弄懂数据库的原理的时候,只能重复一些前人总结出来的操作和案例。一旦遇到一些以前没有遇到过的问题,就会手足无措。而高手之所以能够面对各种复杂的问题场景都能游刃有余,最关键的是他们对数据库这个“道”的理解达到了很深的地步。因此面对从来没有遇到过的场景,也能通过推理找到可能的解决方案。
整个21世纪的最初十年,我都在追求这个数据库之道,不过那时候在我的世界里,数据库就是Oracle。2012年我把这本书写出来交付给出版社后,我觉得通过写这本书,我可能给一些DBA朋友指出了一种系统学习Oracle数据库的方法,同时对我自己而言,通过写作,我也打通了全身的经脉,对Oracle数据库的理解也提升了一个层次。
在我的世界里的很长一段时间我都是把Oracle的“道”当成数据库的“道”了,看到别的数据库也都以Oracle的原理去理解和看待。在有些时候,数据库的“道”是相通的,Oracle的原理也可以应用到国产数据库上。不过在某些情况下,各种数据库的实现原理是不同的,核心的能力与功能也有很大的差异,一味地用Oracle的原理来理解其他数据库就很容易出偏差了。
第一次遇到特别严重的理解误区是在一个PG数据库的优化工作中,用户的一套基于PG的数据库的某条SQL忽快忽慢,快的时候20毫秒,慢的时候可能要几百毫秒。我帮着分析了一下,执行计划、逻辑读、物理读这些数据都差别不大,SQL的执行计划也没发生变化,表里的数据也没有太大变化,索引等也一切正常。在测试环境中,这个问题也很容易复现,为什么还会出现这种情况呢?
当时我对PG原理的理解不深,只能用Oracle的原理来套用PG数据库。所以刚开始的时候走了很多弯路。当我弄明白PG数据库的数据库IO的原理,理解了PG的DOUBLE BUFFER机制的时候,这个问题就很容易理解了。因为这条SQL在不同时间执行的时候,虽然说shared buffers中的缓冲数量差不多,命中率也差不多。不过当数据没有在shared buffers中命中的时候,就会出现差异了。如果当时所需要做物理读的数据都存在于操作系统的文件缓冲里的时候,这时候的物理IO不是真实的物理IO,而是直接从内存中获得的,这样SQL的性能受到的影响不大。而如果这些数据都已经不在操作系统的文件缓冲中,必须从磁盘重新读取的时候,真正的物理读才会出现,这时候SQL的性能就下降了。
弄明白这些道理之后,今后遇到此类问题就容易分析了。首先我们会去关注操作系统的IOPS和IO吞吐量的差异。这个才是能够反映出真实的物理IO的指标,PG的SQL物理读指标是不够准确的。如果SQL涉及的数据相对较热,那么我们可以通过适当加到shared buffers的大小,尽可能让这些数据能在数据库缓冲区中多停留一段时间。对于一些冷数据的访问,比如每天晚上的统计或者月底的统计报表。我们可以在这些统计开始之前首先预热一下相关的冷数据,让SQL开始执行之前,这些数据尽可能多地加载到数据库缓冲或者文件缓冲中。这样就可以避免DOUBLE BUFFERS带来的性能不稳定的问题了。
现在很多DBA是从Oracle DBA转向开源、国产数据库DBA的,对这些DBA,我建议也要放弃一些执念,了解新数据库与Oracle不同的一些关键点,知道Oracle的道并不是数据库的道,尽快更新知识,才能更好地运维好新的数据库。如果非要用Oracle的原理去硬套其他数据库,那就是刻舟求剑了。