PG shared buffers的优化

PostgreSQL-shared_buffers(双缓存) 4和5标识极高的使用数据块,高使用可能会保留在shared_buffers中(有空间),如果需要更高使用率的空间,则低使用率的块将被移除,一般简单的插入或者更新会将使用次数设置为1。3.shared_buffers是一个8KB的数组,postgres在从磁盘中查询数据前,会先查找shared_buffers的页,如果命中,就直接返回,避免从磁盘查询。1.在访问数据时,数据会先加载到os缓存,然后再加载到shared_buffers,这个加载过程可能是一些查询,也可以使用pg_prewarm预热缓存。 阅读详情

本文很长,有8000字,建议大家先收藏再阅读。本文全面介绍了PG shared buffer pool的结构和一些常见的性能优化点和优化策略。在很多技术特征和概念上,与Oracle数据库做了一定的对比,可以让Oracle DBA通过参照更好的掌握PG的相关概念。

数据库的内存架构对数据库的性能影响十分大,PostgreSQL这些年的发展十分快,其内存架构的核心部分除了共享池外,都和Oracle有一定的类似。下图是PostgreSQL内存架构的一张逻辑示意图。这些结构中,shared memory对PostgreSQL数据库的性能影响很大。在PostgreSQL中最为重要的共享内内存缓冲包含Shared Buffer Pool,WAL Buffer和commit log。因为PostgreSQL数据库的SQL执行计划是会话级共享的,因此PostgreSQL数据库不需要类似Oracle的共享池结构。随着现代硬件技术的发展,CPU资源和内存资源都已经不会成为大型数据库的瓶颈了,因此SQL解析带来的开销已经不是系统中必须重点优化的工作了,反而是执行计划的效率更为重要,因此在现在的数据库产品中,全局共享CURSOR及其执行计划的设计逐渐不是主流了。

图 PostgreSQL逻辑架构图

本文我们重点讨论shared_buffers,这部分缓冲区对应于Oracle数据库就是db cache或者buffer cache。PostgreSQL的backend进程通过Buffer Manager模块来访问PostgreSQL的数据,而Buffer Manager通过Shared Buffer Pool来提高PostgreSQL数据访问的性能。backend访问PostgreSQL数据文件的过程和Oracle数据库十分类似,当backend要访问某个数据块的时候,会把需要访问的数据块的地址发送给Buffer Manager,如果这个数据块已经在Shared Buffer Pool中存在,那么Buffer Manager会返回包含这个数据的buffer id返回给backend,如果当前buffer中没有这个数据块,那么backend 通过调用Buffer Manager去申请一个buffer,然后把数据块的数据读入buffer,返回buffer id给后续处理使用。当然这是最简单的场景,对于分配buffer,还涉及了脏块的处理等过程,这里就不深入分析了,这些过程和Oracle数据库的DB CACHE是十分类似的,对Oracle数据库有所了解的DBA很容易理解这个过程。

为了实现这个过程,PostgreSQL的Buffer Manager分为三层:buffer table层、Buffer Descriptors层和buffer pool 层。buffer pool层是PostgreSQL buffer的物理实现,PostgreSQL的Buffer和Oracle一样,是一个固定长的数组,用于存放PostgreSQL的数据块。Buffer Descriptors层也是一个数组,是存储Buffer的元数据的层面,包含描述buffer及其状态的数据结构,此层的buffer描述和buffer pool中的数组是一一对应的。buffer table层是实现数据块寻址的,里面包含实现寻址的相关数据结构。整个体系如下图,这张图来自于著名的interdb.jp网站。

图1 PostgreSQL Buffer Manager

熟悉Oracle Buffer CACHE的人可能比较容易理解这个过程,在Oracle中也是Buffer HEAD(具体可参考X$BH)指向具体的Buffer,而通过HASH CHAINS来实现数据块的寻址。

PostgreSQL的数据块寻址也是通过HASH CHAINS的,这一点与Oracle类似。了解Oracle的DBA应该很容易回忆起Oracle是通过一个32位的rdba来实现Buffer定位的,其中10位是FILEID,22位是BLOCKID(BIGFILE TABLESPACE是32位的BLOCKID)。PostgreSQL这方面复杂一些,是通过一个叫做buftag的数据结构来唯一定位某个数据块的。

图2 buftag数据结构

buftag包含三个字段,rnode是一个RelFileNode的数据结构,包含了数据对象的inode信息;ForkNumber 为0表示该块是表或者索引文件的数据文件,1表示是freespace map的数据,也就是对应的_fsm文件,2表示是visibility maps的数据,对应的是_vm文件。BlockNumber是数据块的块号。因为PostgreSQL的表空间结构和Oracle不同,所以PostgreSQL的数据与具体文件的对应关系相对复杂一些,因此因为无法像Oracle一样用一个32位的数值+一个表空间ID就能表示某个数据块的物理位置,这样会浪费一些内存空间,不过对于内存价格已经比较低的现在,内存已经完全不是问题了。

和Oracle的RDBA一样,PostgreSQL的buftag能够唯一定位某个数据块的位置。通过Hash算法对buftag计算HASH值就可以获得这个buffer descriptor的hash bucket的桶号。

uint32 bucket_slot = calc_bucket(unsigned hash(BufferTag buffer_tag), uint32 bucket_size)

所有的已经装在到Buffer中的数据块缓冲都被链接在HASH桶中,每个BUCKET上都有一个链表,链接了该桶中的所有Buffer。因为无论HASH BUCKET的数量有多大(比如超过Buffer 的数量),也无法排除在一个BUCKET中可能会链接多个Buffer。这一点也是和Oracle的HASH CHAINS类似的。

图3 Shared Buffers初始化状态图

上图是Shared Buffers pool刚刚初始化的示意图,此时hash table上都是空的,同时所有的buffer descritors都被链接在freelist上,而且没有连接任何buffer。

图4 准备载入一页数据

第一个数据块访问请求提交给Buffer Manager的时候,首先通过buftag算出hash bucket的位置,在hash bucket上看到是空的,于是从freelist分配一个buffer descriptor。然后从数据文件中读取该数据,放入这个buffer descriptor对应的buffer 中。

图5读入数据

此时,Buffer中就缓冲了这个数据块了,下回再访问这个数据块,就可以通过buftag直接定位到hash bucket,从而找到这个buffer了。

上面的示意图都来自于Hironobu SUZUKI的原创,以上的算法描述也基本上基于Hironobu SUZUKI大师的资料。从一个DBA的角度来看PostgreSQL的Buffer Manager,看到了一个和Oracle类似的Buffer Cache的算法。因此在PostgreSQL数据库中,也会存在类似于Oracle db cache带来的一些并发争用问题,比如cache buffer chains闩锁等待,buffer busy wait等待等问题。

类似Oracle cbc闩锁的是一种PostgreSQL的轻量级锁lwlock,这个锁的名字在PostgreSQL的各个版本中可能有所不同,我们统一称之为buffer_mapping(BufMappingLock),这个轻量级锁用于HASH TABLE的串行化访问。因为在每个buffer 访问中都需要使用这个锁,因此和Oracle一样,PostgreSQL采用了分区锁的方式,将整个HASH TABLE分为多个分区(缺省为128个,不同版本缺省值会有不同),每个分区使用一个lwlock来管理。

图6 Buffer访问的串行化控制

当有多个backend来访问buffer cache的时候,首先通过计算HASH值,找到HASH TABLE的位置,然后获得相关的BufMappingLock,才能去访问HASH TABLE,找到HASH CHAIN,最终找到对应的Buffer。当两个BACKEND访问的Buffer属于不同的分区锁控制的时候,不会产生冲突,反之就会产生冲突。前阵子我们在对瀚高数据库做压测的时候,也观察到了这个轻量级锁的冲突:

图7 Buffer_mapping等待统计

在11分钟的压测中,产生了110秒的BufMappingLock等待,占整个等待的0.255%,看上去PostgreSQL的BufferManager的效率还是很高的,在每秒钟超过476万次的buffer 访问中,这个锁的等待只有110秒,平均每次等待为0.023毫秒,这个效率已经相当不错了。从这里可以推断,在实际生产环境中,PostgreSQL因为BufMappingLock导致的热块冲突控制还是相当不错的。

在Buffer Descriptor层,每个buffer_id有两个轻量级锁,content_lock 和 io_in_progress_lock,这里和Oracle是有些区别的,不过从原理上也十分类似。对应于Oracle的等待,等待这两个lwlock的等待类似于buffer busy waits和read by another session这两种等待。实际上在Oracle数据库里,Oracle 10g之前是对buffer busy waits分为几种类别,但是统一使用这个等待事件,Read by other session这个等待是buffer busy waits中的一个特例,就是说某个会话等待访问某个buffer的时候,这个buffer 的buffer descriptor已经产生,buffer pool也已经分配了空间,只是这个bufffer中的数据正由另外一个backend从数据文件中读取到buffer中,这个读取的IO还没有完成。PostgreSQL的io_in_progress_lock是和Oracle的这个等待完全类似的,也许是PostgreSQL借鉴了Oracle的思想。我们再回过头来看上面的那个图中的buffer_content等待和buffer_io等待,对应的就是content_lock 和 io_in_progress_lock这两个lwlock的等待时间,可以看出,buffer_content等待大约是322秒,根据BufMappingLock等待估算一下,大约平均每次等待也只有0.06毫秒左右,效率还是比较高的。在分析PostgreSQL数据库的Buffer层面的冲突导致的性能问题的时候,我们可以根据这三个等待的数量与耗时方面的不同比例关系来判断问题可能会出在什么地方。

图8 分析Buffer相关等待的原因

如果buffer_io的等待比较多,那么很可能问题出在IO层面,或者IO延时过大,或者物理IO的数量过多,如果buffer_content的比例比较多,那么说明并发访问热块冲突比较严重。

PostgreSQL的Shared Buffers和Oracle的DB CACHE十分相似,事实上,一个Oracle DBA往往会用错误的方式来看待PostgreSQL的Shared Buffers。为什么呢?这和Oracle与PostgreSQL的数据库的存储结构方面存在的差异有关。

Oracle数据库的数据库物理结构是基于表空间与数据文件这个基础架构的。PostgreSQL也有表空间,也是和Oracle类似,表空间是一个逻辑概念。不过Oracle的数据文件结构是和PostgreSQL完全不同的。Oracle的数据文件是预分配的,确定的,在操作系统中,数据文件的每个块的地址都是已知的。因此Oracle能够更加自主的控制对物理文件上的数据的读写,利用DB CACHE和预读机制来减少IO。早期的Oracle DBA都会有这个感受,使用了裸设备之后,比使用文件系统,IO总体性能会有一定的提升,这个提升幅度在5%左右。从使用裸设备比使用文件系统总体IO性能有所提升可以看出,Oracle 的DB CACHE+预读机制基本上可以替代文件系统缓冲,因此Oracle数据库不需要使用过多的操作系统缓冲(不是完全不使用,而是不需要过多使用,实际上文件系统缓冲对于Oracle提升文件系统的读IO还是有帮助的,甚至对于裸设备,裸设备的块设备缓冲对IO性能也是有提升的,最为典型的就是AIX系统的PBUF)。

而PostgreSQL则不同了,PostgreSQL的数据物理存储结构是按文件的,每个表对应的是几个数据文件,因此所有的文件IO加速机制都是和表相关的,不能使用像Oracle表空间一样的预读机制。PostgreSQL如果要做预读,不同的业务负载下,预读缓冲的效率会有巨大的不同。因此对于文件系统的IO优化,PostgreSQL更多的是交给操作系统来做的。因此,操作系统的文件缓冲与虚拟内存的配置会对PostgreSQL数据库的性能有着十分重要的影响。

另外由于PostgreSQL独特的MVCC机制,或导致对某一条记录的修改并不是在原来的位置上修改,因此Shared Buffers中数据块的一次读入,多次访问的特性会比Oracle数据库打一些折扣,也就是说PostgreSQL的Shared Buffer Pool在这方面的效率会略微低一点。

基于这个特点,实际上PostgreSQL数据库在配置Shared Buffer Pool的时候,就不能参考Oracle的经验了。PostgreSQL的官方文档建议把Shared Buffer Pool设置为整个屋内内存的15-25%,对于一个32G以上的数据库服务器,建议的Shared Buffer Pool的大小是8GB。目前64G甚至更大内存的服务器都已经十分普及了,因此这个官方文档所建议的8GB的设置建议偏保守了一点,另外针对不同的应用场景,PostgreSQL的Shared Buffers的配置策略并不是这么僵化的。PostgreSQL的官方配置对于一个初级的DBA来说可以确保PostgreSQL数据库不会因为错误的内存配置而出现严重的问题。而对于一个高级PostgreSQL DBA来说,我们需要更为精准的配置方案。要想更好的优化好数据库缓冲区,我们需要首先来了解一下PostgreSQL的double buffering问题。

对于以往习惯于使用Oracle数据库的人来说,不会体会到Double Buffering这个词的含义。很多Oracle DBA也认为Oracle天生就不需要考虑Double Buffering的问题的,只有PostgreSQL/MYSQL这样的开源数据库才需要关心。事实上,Oracle也就是最近这十几年才彻底的解决了Double Buffering问题,采用完全绕过文件缓冲区的方法的,在我早期使用的Oracle版本中,如何利用文件缓冲提升大数据量的访问性能还是Oracle DBA能够用来挣钱的独门绝技,我也曾利用这个技能帮助用户做过一些优化项目。既然今天要讨论Double Buffering,那么我们就先用PostgreSQL的一个IO分层结构图来理解一下PostgreSQL的这个问题吧。

图9 Double Buffering示意图

我们看到最上面的shared buffer是PostgreSQL的主Buffer,PostgreSQL数据库使用Buffered IO和操作系统文件系统进行交互,因此PostgreSQL数据库的读写都需要使用OS CACHE作为缓冲,读取的数据可以通过OS CACHE来进行加速,写入的数据先写入OS CACHE中,然后再通过fsync()来强制刷盘。在PostgreSQL数据库里,我们要访问一个数据块可能会经过两个CACHE,一个是PostgreSQL自己的Shared Buffers,一个是操作系统的CACHE(文件缓冲),这就是Double Buffering的含义。

Double Buffering有什么缺点呢?首先是增加了一个数据块访问的路径,数据块要先读入OS CACHE,然后才能到达Shared Buffers,而这个PAGE在Shared Buffers中被多次使用,期间不再需要再次从文件中读取,因此OS CACHE中的缓冲的效率其实并不高,甚至可能会产生负面的作用。对于PAGE的写入也是如此,你不知道PAGE是写入文件了还是仍然存在于OS CACHE中,有时候我们必须通过fsync()来强制同步OS CACHE与文件系统。这种Double Buffering确实增加了PostgreSQL数据库在cache管理上的复杂性。

实际上,PostgreSQL数据库是能从OS CACHE上大大受益的。首先无论是Oracle的DB CACHE还是PostgreSQL的Shared Buffer Pool,其目的不外乎几个。第一,减少数据库服务器的物理IO,从而提升数据库的整体效率,减少物理IO的工作大部分可以由Shared Buffer Pool buffers来做;第二,缓冲数据,削峰填谷,和系统中所有环节上的CACHE一样,OS CACHE也可以削平OS上的大流量IO,从而让系统处于较为平稳的运行状态。

和数据库的缓冲区不同的是,操作系统的CACHE是一种管理更为简单的,更为灵活的缓冲系统,不过文件缓冲对于数据块IO的减少,并不够专业。操作系统缓冲并不从数据库的角度去缓冲数据,而是通过预读等机制来优化文件系统的IO性能。而Shared Buffer Pool是和数据库的一致性访问紧密相关的缓冲区,里面存储的都是数据库使用的数据块,对Shared Buffer Pool的访问都必须通过lwlock来进行并发控制,其访问成本相对较高。因此,通过Shared Buffer Pool和操作系统缓冲之间的访问量的平衡,可以更好的控制数据库访问数据的性能。通过这种Double Buffering的机制,可以在各种复杂的应用负载下,都能够找到一个平衡的配置,从而让缓冲区的效率达到最佳。

图10 Backend命中方式示意图

当Backend要读取数据的时候,首先要通过lwlock去锁定相关的内存结构,然后对Shared Buffer Pool进行一致性读取,如果找到了,那么就产生了一个逻辑读;如果没有找到,那么就会产生一个“逻辑物理读”操作,去操作系统中读取这个数据。这里我用了一个“逻辑物理读”这个十分别扭的词汇,是因为这个物理读有可能并没有产生真正的物理读,而只是从操作系统缓冲中读取到了这部分数据,实际上并没有产生物理IO;如果在OS CACHE里还是没有找到,那么就要产生实际的物理读了,从数据文件中把数据块读入OS CACHE和Shared Buffer Pool。

第三种方式是成本最高的,其次是方式二,访问成本最低的是方式一。因此无论是什么样的数据块系统,最好都通过第一种方式来获取数据。把Shared  Buffer Pool的命中率提高到最高,就能让绝大多数的访问都是使用方式一的。对于Oracle数据库来说,因为Oracle使用了表空间这种文件存储结构,文件空间的地址相对固定,因此只要DB CACHE的大小足够大,那么一个数据块被读取到DB CACHE中之后,会被更长时间的保存在DB CACHE里,被多次访问。标中新写入的数据或者UPDATE一条数据,也是尽可能先写入已经放在DB CACHE的块中,或者直接在DB CACHE中修改。

PostgreSQL数据库的物理存储架构与Oracle大不相同,表数据是存储在独立文件中的,建立一张新的表,就会创建一个新的文件,修改一条数据,也不会在原来的记录上修改,而是会新产生一条记录,这条记录很可能会写在一个不同的块中。因此一个数据块存储到Shared Buffer Pool中之后,很可能多次被访问的几率没有Oracle高,这样Shared Buffer Pool的效率就有可能在某些应用场景下没有Oracle DB CACHE这么高了。因此,针对某些数据重用率不高的应用,Shared Buffer Pool设置的太大,反而会挤占OS CACHE的容量,从而让数据库的整体性能变得更差。而实际上,如果我们的应用是能够很好的多次访问相同的数据的情况下,比如写入操作比较少,读操作比例比较高的数据库中,设置一个较大的shared buffers,让逻辑读的比例提高,肯定是能够获得较好的性能的。

另外一方面针对写IO,写入OS CACHE的延时要远远低于直接写入文件系统。而对于一些访问十分频繁的热表,OS CACHE也是能够明显的提升IO性能的。而交给DBA的最为主要的问题是,我们如何管理好这个Double Buffering的环境。

这种管理确实比Oracle这样的使用O_DIRECT访问的数据库要复杂的多,在Oracle数据库管理方面,我们只需要设置一个足够大的sga_target甚至Memory_target基本上就万事大吉了。而在PostgreSQL数据库的缓冲区管理中,我们还必须考虑如何平衡Shared Buffers和OS CACHE。在PostgreSQL的官方文档中,建议PostgreSQL数据库的Shared Buffers设置为物理内存的25%左右而不要设置的过高,这个建议主要还是为了平衡OS CACHE和Shared Buffers,让OS CACHE和Shared Buffers同时作为缓冲来使用,虽然Shared Buffers作为数据库主缓冲,其实其对IO的优化作用不见得比OS CACHE高多少。对于一些不是很大的PostgreSQL数据库,特别是服务器的内存不是很大的数据库系统来说,这是一个较为稳妥的设置方案。可以充分利用OS CACHE,并且避免OS 换页带来的更大的性能问题。因此也有很多PostgreSQL DBA认为Shared Buffers不宜设置过大,过大的Shared Buffers对PostgreSQL数据库性能提升没有多大帮助。不过有很多用户用自身的体验驳斥了这种观点。通过加大Shared Buffers,提高Cache Buffer的命中率,获得了较好的数据库性能。有的DBA把超过75%的物理内存使用到Shared Buffers上,也获得了良好的使用效果。这种模式实际上是把Shared Buffers作为主缓冲,OS CACHE作为副缓冲。对于大部分PAGE被读入Shared Buffer Pool后都会被很好的多次访问的情况下,把更多的内存配置到Shared Buffer Pool上,可能会获得更好的效果。

实际上对于PostgreSQL的Double Buffering,网上的很多观点都有些偏颇,可能持这些观点的人面对的都是自己的系统,并没有关注过不同负载的数据库的需求。因此如果从一个较为全面的角度来说,在现阶段,PostgreSQL内核还要依赖于OS CACHE来提升PostgreSQL性能的前提下,Double Buffering依然是目前我们无法绕过去的问题。而对于大多数小系统来说,Double Buffering并不会给我们带来太大的烦恼,只要确保OS不换页,Doube Buffering的副作用是有限的,我们甚至可以完全忽视的。而对于大系统来说,设置多大的Sahred Buffers是我们需要去面对的头疼的问题,因为面对不同的应用负载,不同的个性化的系统,需要采用不同对的设置策略来合理配置Shared Buffer Pool,并且定期对系统的性能进行评估,做出调整。不像我们在管理Oracle数据库那样,只需要确保物理内存足够,OS不换页的情况下,尽可能提高DB CACHE的命中率就可以了。

在PostgreSQL数据库中,90%的db cache命中率不一定比80%的db cache命中率有更好的运行性能,因为有可能有我们看到的90%的物理IO实际上是从OS CACHE中读取数据的。基于Double Buffering的问题,DBA需要根据自己维护的数据库系统,通过个性化的优化策略来评估DB CACHE和OS CACHE对系统带来的性能提升,才能更加正确的设置相关参数,让数据库体验的效果更好。对于大型的PostgreSQL数据库系统,这一点尤为重要。

实际上这对于DBA来说是一个福音,问题出现了,特别是不容易解决的问题出现了,那么体现DBA价值的机会就来了。实际上,解决PostgreSQL数据库的Double Buffering问题也并不是像想象的那么困难。注意好几点,大部分系统的这个问题都可以得以解决。首先,不要相信只能使用25%物理内存作为Shared Buffers这种固化的经验,因为每个系统都是个性化的,提高Shared Buffer Pool的命中率在绝大多数场景下都是有价值的。其次,需要针对操作系统的VM参数做更为精细的调整,包括脏块刷新的策略,这方面在操作系统优化的章节里就有很详细的介绍,这里就不重复讨论了,有兴趣的朋友可以去读读相关的章节。

针对Double Buffering的问题,我们来画一下重点。首先,PostgreSQL的Shared Buffer Pool和OS CACHE共同发挥作用,可以让数据库有效的减少物理IO,提升数据库的总体性能;其次,Shared Buffer Pool的设置并不是越大越好,Shared Buffer Pool的命中率也没有Oracle DB CACHE命中率那么有指向性,没有命中的PAGE也可能不需要物理读,可以直接从OS CACHE中读取到;第三,通过对应用系统的访问特性的分析,根据数据页在Shared Buffer Pool中可能被多次访问的比例,以及这部分数据的大小,可以大致确定Shared Buffer Pool的合理配置,同时根据应用的访问特性,可以大致确定OS CACHE与Shared Buffer Pool的比例;第四,根据服务器的IO能力和数据库的IO访问流量,通过调整OS层面的脏页写入策略参数和PostgreSQL数据库的Checkpoint相关参数,可以获得一个较匹配的配置,增加系统的IO总吞吐量,降低平均IO延时,这对于大系统上做PostgreSQL优化十分重要。

最后,PostgreSQL数据库实际上有很多解决这方面问题的插件,可以帮助我们提升OS CACHE的效率,比如针对性的进行OS CACHE/Shared Buffers的预热等,在某些比较大型的数据库系统,比较复杂的应用场景下,这种预热十分有效。有兴趣的朋友可以去研究一下PostgreSQL fincore这个开源插件,应该会有一些收获的。

除了设置数据库缓冲区的大小之外,另外还有一点需要注意的是,对于大内存的服务器,HUGEPAGE也是必须要注意的,HUGEPAGE同样能够给PostgreSQL数据库带来性能上的提升。Shared Buffer Pool使用HUGEPAGE的方法与Oracle类似,透明大页能给Oracle带来的负面影响,对PostgreSQL也同样成立。

刚才我们讨论过,对于PostgreSQL数据库IO性能影响最大的还有另外一个因素,就是操作系统的文件缓冲。对PostgreSQL数据库来说,最佳的模式是将50%的物理内存用于文件系统缓冲。对于某些小型机操作系统,比如AIX,HP-UX,可以通过操作系统的参数比较精准的控制文件系统缓冲的大小。而对于LINUX操作系统,这是十分复杂的,我们需要通过一系列的VM参数来进行综合调整,大体控制文件系统缓冲的大小。不幸的是,我们目前绝大多数PostgreSQL都是跑在LINUX上。对于如何通过VM参数的调整来让PostgreSQL能够在最优化的文件系统缓冲上跑是个十分复杂的问题,甚至50%的比例也不一定是最佳的,我最近在REDDIT上看过一些老外的研讨,最终结论也是不确定的。不过有一点是明确的,那就是无论如何,尽可能不要产生较大的换页,产生较大的换页,可能会导致PostgreSQL总体性能的不稳定。

最后我们必须来聊聊预制相关的EFFECTIVE_CACHE_SIZE参数,许多PostgreSQL用户可能对这个参数比较迷惑。有些用户把这个参数看成是PostgreSQL使用文件系统缓冲的大小,这其实是一个误解。在LINUX中,如何有效的控制文件系统缓冲的大小是十分困难的。实际上这个参数只是一个用于CBO优化器估算成本使用的参数,而不是实际上PostgreSQL使用文件系统缓冲的大小。这个参数的默认值是OS内存的50%,从这里也可以看出,PostgreSQL希望能够使用50%的物理内存作为文件系统缓冲,从而优化IO。这个参数对于索引扫描的成本估算十分关键,如果这个参数设置的较大,则在CBO优化器中,计算出来的索引扫描的成本也就越低。

PostgreSQL shared_buffers参数优化实战指南 本文详细解析了PostgreSQL中shared_buffers参数的优化策略,帮助数据库管理员提升查询性能。通过实战案例和配置建议,指导如何在不同业务场景下合理设置shared_buffers,避免常见陷阱,并与其他关键参数协同优化,实现数据库性能的最大化。 阅读详情

相关推荐

PostgreSQL 15 shared_buffers参数优化指南

数据库性能优化中,内存管理是关键环节之一。PostgreSQL通过shared_buffers参数控制数据库缓存区大小,直接影响查询性能和I/O效率。其核心原理是将频繁访问的数据块缓存在共享内存中,减少磁盘读取。在OLTP系统中,合理配置shared_buffers可显著提升事务处理能力,而数据分析场景则需平衡内存分配。PostgreSQL 15对缓冲区管理算法进行了优化,包括改进的时钟扫描策略和并行查询支持,使内存使用更高效。配置时需考虑系统总内存、工作负载特性,并配合监控缓存命中率等指标进行调整。典型生

weixin_28338005的博客 57

postgresql-shared_buffers参数详解

postgresql-shared_buffers参数详解

XiaoCai 4772

PostgreSQL查询性能瓶颈诊断与优化实战

本文提供了一套完整的PostgreSQL查询性能瓶颈诊断与优化实战指南。当遇到查询缓慢问题时,首先通过pg_stat_activity定位活跃慢查询,再利用EXPLAIN和EXPLAIN ANALYZE分析执行计划,排查锁冲突,并最终通过调整shared_buffers内存参数和执行VACUUM维护等系统级调优手段,综合解决性能问题。

weixin_29204749的博客 268

PostgreSQL Shared Buffers详解

shared buffers即数据库服务器的共享内存缓冲区,这个参数一般建议设置成操作系统内存的25%,为什么设置这么大呢?设置的越大是不是越好呢?要解决这些问题,我们需要了解在Postgresql中shared buffers究竟是如何工作的。 再介绍shared buffers之前,我们要先介绍以下postgresql中的bgwriter进程。 bgwriter 负责周期性的将shared buffer中的dirty page刷出shared buffer。这里要注意:bgwriter使用的是buffe

Focus on PostgreSQL 4449

想让PostgreSQL快到飞起?先找健康密码还是先换引擎?

title: 想让PostgreSQL快到飞起?先找健康密码还是先换引擎?summary:PostgreSQL性能调优的核心在于性能监控和配置参数调整。性能监控聚焦资源使用、查询性能和系统状态,利用pg_stat_activity、pg_stat_user_tables和pg_stat_statements等工具识别瓶颈。

https://blog.cmdragon.cn/ 1526

PostgreSQL性能优化实战:慢SQL排查、参数调优与索引设计全解析

数据库性能问题常常表现为查询缓慢、CPU飙升或连接耗尽,而真正原因往往不是硬件不足,而是系统配置、执行计划与索引设计未达到最优。PostgreSQL作为功能强大的开源关系型数据库,其优化思路与传统MySQL有显著差异:MVCC机制带来表膨胀风险,基于cost模型的执行计划依赖准确的统计信息,WAL、checkpoint与autovacuum共同影响写入路径的稳定性。从诊断工具如慢查询日志与pg_stat_statements出发,通过EXPLAIN解读执行计划,掌握shared_buffers、work_m

cuixie2370的博客 483

PG 日报|共享内存结构优化,支撑 shared_buffers 在线动态扩容

本次活动汇聚了由 Anupan Roy 带领的印度合作伙伴生态系统成员,重点表彰了表现突出的合作伙伴,并围绕企业级 Postgres 的落地应用展开交流。在 Databricks 内部编程评测中,Opus 5 达到了当前最优水平,在智能体编程、专业知识处理和长链推理方面均有显著提升,且在不同任务强度下都能以更少的 token 实现更强的表现。此版本还新增了 ARM64 Docker 镜像支持,改进了任务管理机制,增强了执行日志功能,并带来了多项稳定性优化。,导致排序变为升序,反转了原本的…

IvorySQL的博客 219

022、PG优化之参数优化

PostgreSQL既使用自身的缓冲区,也使用内核缓冲IO。这意味着数据会在内存中存储两次,首先是存入PostgreSQL缓冲区,然后是内核缓冲区。这被称为双重缓冲区处理。对大多数操作系统来说,这个参数是最有效的用于调优的参数。此参数的作用是设置PostgreSQL中用于缓存的专用内存量。shared_buffers的默认值设置得非常低,因为某些机器和操作系统不支持使用更高的值。但在大多数现代设备中,通常需要增大此参数的值才能获得最佳性能。

Oracle/MySQL 到 国产信创数据库|迁移 · 调优 · 信创替换 1115

PostgreSQL内存优化:shared_buffers与work_mem实战指南

数据库性能优化中,内存管理是核心环节。PostgreSQL采用独特的双缓存架构,通过shared_buffers共享内存池和work_mem私有内存区实现高效数据访问。shared_buffers作为主要工作区,采用改进的CLOCK算法管理数据页,需与Linux的page cache协同工作;而work_mem则控制排序、哈希等操作的临时内存分配。合理配置这些参数可显著提升TPC-C等基准测试性能,在电商、金融等场景中实现查询响应时间的大幅优化。本文通过生产案例验证,提供基于活跃数据集大小和并发连接数的黄金

weixin_32306957的博客 166

【0286】Postgres内核 shared buffer pool 初始化实现

附:shared buffer初始化后,BufferDescriptors中变量bufferdesc的值如下面文件所示: Postgres shared buffer pool初始化过程日志

Postgres 数据库内核开发工程师 586

求一个点到任意两个点所在直线距离 C#代码公式

求点C(X0,Y0) 到点A(x1,y1)和点B(x2,y2)所在直线的距离 1.已知任意两个点,求这两个点所在直线 已知点A(x1,y1),点B(x2,y2) 设直线上另外任意一个点为(x,y) 那么 (x-x1)/(y-y1) = (x2-x1)/(y2-y1); 整理后得方程: (y2-y1)x + (x1-x2)y + (y1-...

qq_29434987的博客 4492

PostgreSQL 生产环境迁移与冷启动优化:利用 pg_prewarm(dump) 与 OS Page Cache 实现双层缓存无感预热

未命中的大范围查询直接穿透到底层磁盘,需要在操作系统层面将核心表及索引文件直接读入 Linux Page Cache。代表成功导出了约 393 万个 8KB 数据块(对应约 30GB 的缓存状态)。该文件默认生成在源库的数据目录。在数据库日常运维与大型变更中,最让 DBA 和基础架构团队头疼的问题之一就是。PostgreSQL 的读写架构并非只依赖自身的数据库内存,而是深度依赖。或网络同步工具将文件复制到目标库对应的。重启数据库后,后台守护进程。在目标库宿主机终端(使用。在 Linux 终端执行。

情深深几许 456

北航机器学习期末考试试题2020年春

北航机器学习期末考试试题2020春 看csdn上试题收费,积分还挺高,本着共享的理念,把2020春季ML考试的试题公开,若侵权,立删 前8道题10分,第9题20分 决策树采用ID3算法 对宇宙星球是否适合生存分类 SVM的原理;软间隔、硬间隔;以及对非线性样本点分类 集成学习的原理,以及及串行boosting以及bagging的简单概括 K-means与混合高斯模型的异同以及EM算法的原理,如何计算 马尔可夫随机场最大团;马尔可夫随机场的联合概率分布(势函数表示),贝叶斯网络联合概率分布 PCA主成分基于

qq_43343919的博客 5417

PostgreSQL内存优化的艺术:从参数调优到查询重构

本文深入探讨PostgreSQL内存优化的系统性方法,涵盖参数调优、查询重构和监控体系。通过分析共享内存和进程私有内存的关键配置,提供针对高内存消耗的排查与优化策略,帮助DBA和开发人员构建高效稳定的数据库环境。重点介绍了pg_top等工具的使用,以及如何通过参数调整和查询优化降低内存使用率。

wine的专栏 821

一条龙开发指南:MCP AI Agent 理论+项目实战开发你的MCP Server

MCP(Model Connection Protocol)是Anthropic于2024年推出的AI模型连接协议,旨在为AI模型提供开放、通用的标准化接口,类似于“USB-C”接口,使AI模型能够无缝连接各种数据源和工具。MCP通过标准化协议解决了AI系统集成中的碎片化问题,提升了开发效率和系统可靠性。开发者可以通过简单的配置,快速接入不同的MCP Server,实现AI模型的多样化应用。MCP支持多种协议,如Stdio、SSE等,并通过JSON-RPC格式进行数据传输。文章还以腾讯云代码助手为例,展示了

杨不易呀 3046

STM32F103C8T6+A4988驱动42步进电机全流程(附接线图+代码解析)

本文详细介绍了使用STM32F103C8T6单片机与A4988驱动模块控制42步进电机的完整流程。内容涵盖硬件接线图解析、电流设置、GPIO驱动代码编写以及细分控制等核心实践,旨在帮助嵌入式开发者和DIY爱好者快速实现精准运动控制,适用于3D打印机、CNC等需要精密定位的项目。

Python的专栏 794

PostgreSQL性能调优实战:shared_buffers参数设置避坑指南(附真实案例)

本文深入探讨PostgreSQL性能调优中shared_buffers参数的关键作用与设置技巧,通过真实案例揭示常见配置误区。文章详细解析了该参数的科学计算方法、不同场景下的配置建议,并提供了AWS RDS环境的特殊处理方案,帮助DBA和运维工程师避免性能陷阱,实现数据库最佳性能。

convnet3designer的博客 151

Natural Language Processing

作者:禅与计算机程序设计艺术 1.简介 自然语言处理(NLP)是研究如何使计算机理解和处理自然语言的理论和方法,目的是让电脑更好的理解、获取、生成、存储和沟通人类语言。20世纪80年代末,IBM的三位博士陈天奇、周博磊和王力雄在贝尔实验室创建了首个自然语言处理系统——“布莱克多·艾森豪威尔”(Bletc

AI天才研究院 724

PostgreSQL 日报|不重启动态修改 shared_buffers(9 月 8 日)

第一个问题是:每次从 WAL 缓冲区满足读取后无条件关闭 WAL 段文件,在反复读取同一段内的页面时会造成不必要的开销。Bharath 的修复方案是:仅…该线程讨论的是一个名为 pg_upgrade_replica 的新工具,旨在通过利用 pg_basebackup --incremental 和 pg_combinebackup,在 pg_upgrade 后避免对 standby 节点进行完整的重新克隆。该平台由数据库审计领域的专业团队负责运营维护,具备良好的扩展能力,能够满足企业在合规方面的核心…

IvorySQL的博客 184

CODESYS无扰切换PID(ST源代码)

/运行信号//手自动切换//设置值、目标值yk : REAL;// 实际值、反馈信号;// 开环给定值;// 比例增益;// 积分时间 单位S;Td : REAL;// 微分时间 单位S;//采样时间 单位S// 滤波时间 单位S;//中断周期 默认10msEND_VARVAR_OUTPUT//uk : REAL;//控制器输出;//上一时刻的实际值;uDk : REAL;

RXXW_Dor的博客 1401

抖音 webmssdk 签名算法解析:X-Dynosaur / X-Gnarly / X-Bogus 生成原理

它只依赖设备指纹/环境编码与随机数,与 query 内容无关,因此可以独立于 Dynosaur/Gnarly 生成。

猫敷雪 198

PostgreSQL 数据库优化

摘要:PostgreSQL数据库优化需从多维度入手,包括核心参数调优(内存分配、WAL日志、连接并发)、查询与索引优化(并行查询、统计信息)、存储I/O优化(表空间分离、分区表)以及定期维护监控。针对32GB内存和SSD的典型配置建议包括:shared_buffers=8GB、work_mem=32MB、random_page_cost=1.1等。优化时应逐步调整参数,结合pg_stat_statements等工具监控效果,并根据业务负载进行针对性调优。(150字)

Will_1130的博客 337

【00】虹软2023届校招专场 ,计算机类笔试攻略(笔试考试时间、考察范围、笔试难度 等说明)

虹软科技2023校招笔试攻略:三大岗位类别(算法、算法优化、开发)分别于7月24日进行。题型包括选择题、编程题和问答题,其中算法类题目降低难度,编程题改为LeetCode模式。重点考察数学基础、机器学习、编程能力(C/C++/Python)、数据结构和算法优化等。建议根据投递岗位选择问答题,算法优化类注重系统知识和SIMD优化,开发类侧重多线程等实际应用能力。笔试结果将作为校招offer的重要参考。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 276

PostgreSQL 性能调优实战:从 Buffer Pool 到执行计划的深度优化路径

PostgreSQL 性能调优的核心逻辑是:用数据定位瓶颈,用原理选择手段,用 Benchmark 验证效果。Buffer Pool 命中率是第一道防线,低于 99% 必须干预;WAL 写入是高并发场景的隐藏瓶颈,是关键观测窗口;执行计划偏移的根因通常是统计信息失真,和分别负责发现和干预。调优不是一次性动作,而是持续观测-调整-验证的闭环。每次参数变更后,必须用 pgbench 或真实业务负载跑至少 30 分钟的压测,采集pg_stat_*系列视图的前后对比数据,确认优化效果可复现。

guoyizhongxing的博客 4010

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

PostgreSQL 16服务器配置与数据库监控实战:从参数优化到慢查询定位

数据库性能调优是保障业务稳定性的基础工程,而服务器参数配置与运行状态监控又是其中最关键的两环。理解 shared_buffers、work_mem、WAL 等核心原理,有助于在内存和磁盘 IO 之间找到平衡;借助 pg_stat_statements 与 pg_stat_activity,则可以量化慢查询、锁等待和连接数压力。无论是 OLTP 高并发场景,还是日常巡检与故障排查,从操作系统内核参数到 SQL 执行计划分析都需要成体系的观测手段。本文围绕 PostgreSQL 16 的配置实战展开,结合 pg

weixin_29274969的博客 150

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

上一篇: 利用非易失性内存打造高性能PG数据库系统
下一篇: 针对PG的等待事件,不妨玩点大的
DBAIOps社区
博客等级 码龄3年 970粉丝 107原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值