草庐IT

我不认为PG的Double Buffering是更优秀的解决方案

白鳝 2023-03-28 原文
关于PG在Shared buffers上的DOUBLE BUFFERING设计,一直是争议极多的。有一些搞PG的朋友认为这是PG充分利用OS CACHE的一种特殊设计,是PG数据库设计中比较优秀的地方。还有一些朋友则认为这是一种过时的设计,与当前数据库技术的发展潮流所相违背的。前些天有几个朋友谈到这个问题,希望我写篇位置表达下我的观点。

以我这些年做数据库优化的经验来看,DOUBLE BUFFERING的设计如果算是一种技术上的进步,在这一点上我一直是不太认同的。众所周知,现在几乎所有的现代数据库产品都是用AIO/DIO等方式来访问底层存储系统,只有PG目前还通过BUFFER/CACHE来读取物理文件。随着现代硬件的发展,BUFFERED IO的劣势越来越显现出来了。如果我们采用直接IO,绕过文件缓冲,那么就可以绕过BUFFER CACHE这一层,让数据从文件到内存更为直接,这会大幅提升OS到数据库缓冲的数据交换的吞吐能力,同时,因为DMA等技术的使用,可以让文件IO消耗的CPU资源更少,让系统更为高效。这对于大型数据库系统来说绝对是十分必要的。PG数据库越来越被用于大型OLTP系统,直接IO替代BUFFERED IO肯定可以有效增加大型系统的并发IO能力。

另外一个方面,操作系统是无法充分理解数据库的PAGE访问逻辑的,因此操作系统缓冲的效率比较shared buffers而言,要低的多。两个分别由RDBMS和OS管理的分离的缓冲的效率肯定没有一个独立的数据库缓冲高,这个应该也是广大研发人员的共识。不过这句话成立的前提是数据库缓冲区被设计的十分高效,其LRU算法也被设计的十分合理。通过分析Oracle DB CACHE的算法的改进,我们也了解到为什么Oracle的DB CACHE能够保持那么高的DB CACHE命中率了。

既然使用统一缓冲,消除DOUBLE BUFFERING那么重要,那么为什么PG还在坚持使用DOUBLE BUFFERING呢?这个原因十分复杂,实际上最近这些年里,PG社区也在这方面做着不断的努力。通过利用OS的AIO来替代当前bufmgr.c中的BUFFERD IO操作,不过PG的IO堆栈太长了,在大量的代码中都存在和buffered io相关的内容,再加上PG的文件结构导致的预读、连续块访问的IO合并等问题,要解决这个问题并不容易。在IO路径上,不仅仅需要修改bufmgr.c,在smgr.c,xlog.c,到底层的md.c,fd.c,甚至backend等模块中都有大量IO相关的代码需要修改。这些修改不仅仅是在调用文件IO时的函数调用的修改,还涉及到异步IO模式的修改,以及IO优化、预读等一系列的问题。因此这部分的修改中左虽然已经进行了数年,但是要出现在正是发布的版本中,依然还需要一定的时间。这也成为PG代码中的XID64之外的又一个老大难的问题。

除此之外,在shared buffers的管理上,也需要做相应的优化,否则哪怕底层IO改为了AIO,buffer contention冲突也会让一个大型的统一的数据库缓冲的性能出现问题。比如在Oracle上遇到的buffer busy waits等待,可能会在PG上放大,从而在高并发访问时引发严重的性能问题。

举个最简单的场景,那就是当多个backend需要访问相同的一组PAGE的时候,PG目前的管理算法上海经常会出现lwlock等待方面的超时等问题。而Oracle从9i开始已经优化了这方面的算法,当多个并发的会话访问相同的block的时候,首先为这个BLOCK申请db cache的会话会PIN住这个BUFFER HEADER,然后开始加载这个block(当然也包含IO合并以及预读,多块读方面的算法优化),其他并发访问相同数据的会话就会等待“read by another session”,这个等待事件是Oracle 10g才开始引入的,在9i中等待的依然是buffer busy waits,不过reason code(P3)参数是特殊的,从reason code可以缺别处这种特殊的热块冲突类型。当PG在这方面算法没有做优化之前,就无法区分这种情况,也就无法与AIO配合,达到最低成本的开销。

PG消除DOUBLE BUFFERING,在技术发展上来说,是必须要做的事情,只不过因为历史欠债还是较多,这方面的改造工作量很大,需要一些时间来完成。一旦PG完成这个改造,将可以充分利用AIO的能力,大幅提升PG数据库读写的能力,从而让PG数据库真正向大型关系型数据库迈出一大步。目前我们有很多数据库企业都是基于PG生态在做研发,我也希望我们的数据库厂商能够在这方面多投入一些研发,为PG社区解决这个难题提供一些中国方案。

有关我不认为PG的Double Buffering是更优秀的解决方案的更多相关文章

  1. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  2. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  3. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  4. ruby-on-rails - 错误 : Error installing pg: ERROR: Failed to build gem native extension - 2

    我克隆了一个rails仓库,我现在正尝试捆绑安装背景:OSXElCapitanruby2.2.3p173(2015-08-18修订版51636)[x86_64-darwin15]rails-v在您的Gemfile中列出的或native可用的任何gem源中找不到gem'pg(>=0)ruby​​'。运行bundleinstall以安装缺少的gem。bundleinstallFetchinggemmetadatafromhttps://rubygems.org/............Fetchingversionmetadatafromhttps://rubygems.org/...Fe

  5. 屏幕录制为什么没声音?检查这2项,轻松解决 - 2

    相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声

  6. 【高数】用拉格朗日中值定理解决极限问题 - 2

    首先回顾一下拉格朗日定理的内容:函数f(x)是在闭区间[a,b]上连续、开区间(a,b)上可导的函数,那么至少存在一个,使得:通过这个表达式我们可以知道,f(x)是函数的主体,a和b可以看作是主体函数f(x)中所取的两个值。那么可以有,  也就意味着我们可以用来替换 这种替换可以用在求某些多项式差的极限中。方法: 外层函数f(x)是一致的,并且h(x)和g(x)是等价无穷小。此时,利用拉格朗日定理,将原式替换为 ,再进行求解,往往会省去复合函数求极限的很多麻烦。使用要注意:1.要先找到主体函数f(x),即外层函数必须相同。2.f(x)找到后,复合部分是等价无穷小。3.要满足作差的形式。如果是加

  7. ruby - 使用 postgres.app 在 rvm 下要求 pg 时出错 - 2

    我正在使用Postgres.app在OSX(10.8.3)上。我已经修改了我的PATH,以便应用程序的bin文件夹位于所有其他文件夹之前。Rammy:~phrogz$whichpg_config/Applications/Postgres.app/Contents/MacOS/bin/pg_config我已经安装了rvm并且可以毫无错误地安装pggem,但是当我需要它时我得到一个错误:Rammy:~phrogz$gem-v1.8.25Rammy:~phrogz$geminstallpgFetching:pg-0.15.1.gem(100%)Buildingnativeextension

  8. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  9. ruby - 在好的 Ruby 代码中没有注释是否被认为是可以接受的? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭5年前。Improvethisquestion我审查了一些用Ruby编写的专业代码,没有发现任何评论。代码读起来相当清晰,但没有self记录。我应该期望专业编写的Ruby代码有注释吗?或者,是否有一些Ruby原则认为注释不是必需的?

  10. Ruby 守护进程和 JRuby - 备选方案 - 2

    我有一个应用程序正在从Ruby迁移到JRuby(由于需要通过Java提供更好的Web服务安全支持)。我使用的gem之一是daemons创建后台作业。问题在于它使用fork+exec来创建后台进程,但这对JRuby来说是禁忌。那么-是否有用于创建后台作业的替代gem/wrapper?我目前的想法是只从shell脚本调用rake并让rake任务永远运行......提前致谢,克里斯。更新我们目前正在使用几个与Java线程相关的包装器,即https://github.com/jmettraux/rufus-scheduler和https://github.com/philostler/acts

随机推荐