我讨厌PostgreSQL的10件事(2020)

2021-04-06 16:45:15

在过去的几年里,软件开发社区与流行开源关系数据库的爱情发生了一点发烧间距。这种黑客新闻线覆盖着名为“PostgreSQL的世界最佳数据库”,在宣传Sycophants奢侈品无条件赞美的接缝处破坏,是这种现象的一个完美典范。

虽然大部分赞美肯定应该得到很好的,但缺乏有意义的异议让我感到有点困扰。没有软件是完美的,所以究竟是什么PostgreSQL的瑕疵?

自2003年以来,我一直在生产PostgreSQL,从小(千兆字节)到谦虚到非常大的部署(〜Petabyte)。我的观点主要来自建设和运行系统,这些系统至少打算不断使用。毋庸置疑,我多年来通过一些痛苦的产量问题获得了PostgreSQL的特殊特质的一手经验。

阅读更多。足以说,这个人可以咬人吧。这个问题导致的多日中断有很多故事。继续,谷歌它,你会发现众多贫困的灵魂写作他们踩到这个地雷的时间。几乎没有任何与顶级专家的非琐碎的PostgreSQL安装最终会遇到它。

它可能会在将来的某些时候,xids将转换为使用64位整数,但直到那时,我们陷入困境。我猜至少我们可以感谢有一个过程,这是防止它发生的过程,而不是一些飞机软件。

如果活动主站突然失败,则磨坊流媒体Replication Setup几乎肯定会丢失承诺数据。 “这就是异步复制的价格,”有些人可能会说,但它不一定是这样的。 PostgreSQL支持具有容错耐用性的Quorum提交的同步复制,但它具有更紧密的性能包络,使其应用​​程序复杂化。

等待不利用系统资源,但在确认传输之前继续保持事务锁。因此,由于增加的响应时间和更高的争用,不断使用同步复制的使用将降低数据库应用程序的性能。

这种螺栓频率复制在捏捏中是有用的,但我犹豫推荐用于通用用例。它与Kafka的ISR复制类似于ACKS =全部和仲裁Min_ISR,但具有运行任意查询的事务关系数据库的所有细微复杂性。我目前不知道在非琐碎尺度上成功地应用了Quorum提交的高耐用性复制。如果你有,伸出去吧!

就关系数据库而言,Galera Cluster的组复制也是不完美的,但更接近理想。他们甚至鼓励地理分布式复制,这对于使用仲裁提交的PostgreSQL复制设置很可能是灾难性的。

流媒体复制是迄今为止生产部署中最利用的复制机制。它是物理复制的一种形式,这意味着它复制了磁盘二进制数据本身的变化。

每次通过写入操作都需要修改磁盘数据库页面(8KB),甚至只是单个字节,均使用所请求的更改编辑的整个页面的副本,写入预先写入日志(WAL) 。物理流复制将该现有WAL基础架构利用它作为将其流到副本的更改的日志。

更新:有些人指出PostgreSQL每个WAL检查点只需要执行此全页。这是真的,但在大多数现实世界的系统中,大多数写作最终会在电力法分布之后的检查点之间的独特页面上。更重要的是:当预期系统行为时,正确的方法是假设更昂贵的情况,特别是如果它取决于应用程序的难以预测和高度动态的行为。

具有物理复制,例如,大索引构建,创建了大量的WAL条目,可以轻松瓶颈瓶颈。页面粒度的读取修改 - 复制过程可以导致主机上的硬件引起的数据损坏,更容易传播到副本,我在生产中亲自见证了多次。

与逻辑复制相比,这与逻辑复制相反,只能复制逻辑数据更改。至少从理性地,大索引构建只会导致在网络上复制的单个命令。当PostgreSQL支持相当一段时间的逻辑复制时,大多数部署都使用物理流复制,因为它更加强大,更广泛地支持,更容易使用。

与大多数主流数据库一样,PostgreSQL使用多版本并发控制(MVCC)来实现并发事务。然而,其特殊实施经常在垃圾行版本周围引入操作疼痛及其清理(真空)。一般来说,更新操作创建任何修改行的新副本(或“行版本”),将旧版本留在磁盘上,直到可以清理它们。

虽然多年来这种情况稳步提高,但它是一个复杂的系统,这是一个黑匣子,因为任何一个都是第一次接近这个问题的黑匣子。例如,了解只有堆的元组(热),并且当它踢出时可以是用于维护一致的计数器列的重新更新的工作负载的制作或中断。默认的Autovacuum Setup在大多数情况下工作,但是当它没有时,良好的主。

相比之下,MySQL和Oracle使用重做和撤消日志。它们不需要类似的背景垃圾收集过程。权衡他们使他们的交易提交和回滚操作的额外延迟。

它可能是在遥远的未来的某些时候,Zheap拯救了我们所有人。

PostgreSQL为每个连接的流程伪造,在大多数其他数据库中使用更有效的连接并发模型。这使得在困难的调谐问题中,因为存在相对低的阈值,在此添加更多连接降低性能(左右〜2x核心)并且最终是另一个更高的阈值(难以估计,高度工作依赖性),其性能将骤降。

使用连接吸收器的标准配方肯定会踢掉路径,但引入了显着的额外架构复杂性。在一个特别大的部署中,我最终不得不在第二个pgbouncer层中划分。在应用程序服务器上以及数据库服务器上的另一个层上ran。完全占用的连接约100万客户进程。调整为40%的黑暗艺术,40%的蛮力,10%纯粹​​运气。

过程可伸缩性一直在逐步逐步逐步升级,但是与像线程相比的内容相比,这种体系结构的性能有所艰难的限制,它在MySQL中使用。

postgreSQL中的表具有主键和名为堆的单独行存储的索引。其他数据库将这些数据库集成在一起或支持“索引组织表”。在这种安排中,主键查找过程直接导致行数据而不进行次要获取以获取完整的行和必要的附加CPU和I / O利用率。

PostgreSQL中的群集命令根据索引重新组织了一张表以提高性能,但对大多数现实世界的OLTP案例并不是真正的工作。它在独占锁下重写整个表,阻止任何读取或写入。 PostgreSQL不会为新数据维护群集布局,因此必须定期运行此操作。因此,如果您可以定期将数据库脱机脱机,则真的很有用。

但更为严重的是,索引组织的表节省空间,因为索引不需要行数据的单独副本。对于具有大多数由主键覆盖的小行的表,例如加入表,这可以轻松地将表的存储空间分成两半。

创建表所喜好(Object_type Integer not null,object_id bigint不会生成始终为身份,user_id bigint not null,created_at timestamp与时区不是null,主键(object_type,object_id,user_id);

PostgreSQL将为主键维护与基本表存储分开的主键的索引。此索引将包含每行的Object_type,Object_ID和User_ID列的完整副本。每行中28个字节中的20个(〜70%)中的20个将被重复。如果PostgreSQL支持索引组织的表,则不会消耗所有额外空间。

一些主要版本升级需要几个小时的停机时间来转换大型数据库的数据。使用典型的流复制机制,通过升级副本并进行故障转移,无法优雅地执行此操作。磁盘上的二进制格式在主要版本中不兼容,因此主设备和副本之间的线路协议有效地也不兼容。

希望逻辑复制最终将完全替换流式复制,这将使在线,滚动升级策略。当我在大规模的水平缩放部署工作时,我们在自定义基础架构中进行了重大的工程投资,以便使用还使用用于碎片迁移的额外触发器的复制系统进行这些升级。

要公平,MySQL的开箱即用的复制更加繁琐,但与MongoDB和Redis等一些NoSQL商店相比,从易用性地,MySQL Group Replication和Galera Cluster等一些面向群集的复制系统和锐利的边缘避免透视,在PostgreSQL中设置复制留下了很多。虽然逻辑复制理论上为在这些差距上对纸张的第三方解决方案提供了更大的灵活性,但到目前为止,它是一些非常大的警告,用于使用它代替流媒体复制。

策划者提示允许查询指示查询计划者使用策略,否则无法使用它。在似乎是一种足够聪明的编译器参数的形式中,PostgreSQL开发团队在拒绝支持查询计划者提示时举行了这条线。

我确实理解他们的推理,这主要是关于阻止用户使用应该通过编写适当查询来修复的查询提示来攻击问题。然而,在突然和意外的查询计划班次下观看生产数据库螺旋到全崩溃时,这种哲学似乎是野蛮的。

在许多这些情况下,到计划者的提示可以在几分钟内减轻这个问题,购买工程团队他们需要对查询进行适当的修复时的时间或天。虽然有一些间接解决方法涉及禁用某些查询计划策略,但它们是风险的,并且绝对不应该在任何时间压力下都受雇。

InnodB在MySQL的页面压缩通常会在半场剪裁存储脚印,并且从表现形式的角度来看是“免费”。 PostgreSQL将自动压缩大值,但这对于数据存储在关系数据库中的最常用方式并不有用。对于大多数RDBMS使用情况,行通常是几百个或更小,这意味着压缩在跨多行或块中应用时只能真正有效。

块压缩确实很难为PostgreSQL核心的数据结构实际实施,但MySQL的InnoDB存储引擎采用的“孔打孔”策略似乎在实践中工作得很好,尽管有一些缺点。

2020-04-07更新:Mark Callaghan,“MySQL在Facebook”的名声,在此质疑我的陈述,孔冲压压缩工作“在实践中很好”。事实证明,世界上最大的MySQL安装从未使用过孔冲压,因为我以前认为。他们确实成功地使用略微修改的innodb压缩,并且在几年前迁移到MyRocks之前,它已经成功了。

虽然孔冲压压缩似乎为某些人工作,但有一些警告使其成为一个家庭运行。如果您正在运行Percona的MySQL版本,MyRocks是一个更好的赌注。如果没有,似乎经典的InnoDB表压缩是对闪存存储上非常读取的重型工作负载的更安全下注。标记没有指向主要生产问题的任何特定实例,但确实指出他“疑虑文件系统已经为每页孔打孔而设计,我会害怕失败。”

PostgreSQL世界广泛使用的唯一通用块压缩设置利用ZFS,这对人们来说似乎很好。这些天是Linux的生产级现实,但绝对带来了一些管理开销,它不存在于XFS或Ext4等“开箱即用的”文件系统中。

您可能仍然应该使用PostgreSQL而不是别的东西来存储您理想地喜欢的数据,您知道,保持一段时间。通常,我建议从PostgreSQL开始,然后尝试弄清楚为什么它不适用于您的用例。

PostgreSQL非常成熟,精心设计,丰富的特色,一般是没有锋利的边缘,并且对于绝大多数用例具有相当的性能。它也是由占优势公司赞助商的不受控制,包括梦幻般的文件,拥有专业,包容性的社区。

好消息是,通过使用Heroku PostgreSQL这样的托管数据库服务,可以减少或消除由Heroku PostgreSQL,PostgreSQL的PostgreSQL,或PostgreSQL的谷歌云SQL,或者可以消除这篇文章中提出的许多问题引起的疼痛。如果您可以使用其中一个服务,因为对所有圣洁的爱,请做!

我很自豪地说我在PostgreSQL之上建立了近二十年的软件,尽管它缺陷,但仍然是一个强大的倡导者。鉴于我令人难以置信的发展团队多年来一直在目睹的进展,我可以说,大多数情况下,如果不是所有这些问题都将在适当的时候解决。