抱怨最多的PostgreSQL问题在国产数据库解决了哪些?
两年前,Rick Branson撰写了一篇备受关注的文章,题为《10 Things I Hate About PostgreSQL》,其中总结了他对PostgreSQL的十大批评点。作为一位拥有近20年PostgreSQL使用经验的专家,他提出的问题是客观的。尽管他本人深表认可PostgreSQL,并且是其坚定的拥护者,但他不赞同一些人对其无条件的赞美。当时,他的文章是针对Hacker News上一篇报道标题为《PostgreSQL 是世界上最好的数据库》的文章而撰写的。
近期,国内的PostgreSQL推动者冯若航在公众号上发表了一篇题为《PostgreSQL:世界上最成功的数据库》的文章,引发了外网Twitter上的讨论。一位国外评论者表示:“有些聪明人总认为一双鞋子可以适用所有人。”Rick Branson在他的文章中也提到了:“没有一个软件是完美的。”
尽管PostgreSQL非常成熟,设计精良,但由于它是开源软件,仅提供了内核功能。在社区和客户之间缺乏紧密的关系,因此无法满足所有需求。另外,由于其设计是基于几十年前的环境,PostgreSQL在当前的大规模数据和高并发环境下存在一些不足之处,随着硬件技术和数据规模的不断发展,可能更加显现,虽然改进这些问题并不容易,但PostgreSQL社区一直在努力改进。那么,简单地看看国产数据库在解决这些问题上的进展,或许可以提供一些参考。
以Rick Branson文章中提到的10个问题:
1, PostgreSQL 使用 32 位事务 ID,数据库在耗尽时会冻结.
2, 主服务器突然发生故障,故障转移普通的流式复制设置几乎肯定会丢失已提交的数据。“这就是异步复制的代价”,PostgreSQL 支持使用仲裁提交进行同步复制,以实现容错持久性,但它具有更严格的性能限制,Galera Cluster的群复制可能比这个更理想。
3, 低效的复制,在PostgreSQL, 流式复制是迄今为止生产部署中使用率最高的复制机制。页面级别的 WAL 物理复制,整个页面(FPW)的副本写入预写日志 (WAL),创建大量 WAL 条目,这很容易使复制流成为瓶颈。虽然 PostgreSQL 支持逻辑复制已经有一段时间了,但大多数部署都使用物理流复制. 非整页的 WAL 记录损坏可能会传递到备库。
4, MVCC带来的垃圾,PostgreSQL 是追加更新,即使更新单个列的一个字节也会复制整行,产生表膨胀。占用磁盘空间,旧版本保留在磁盘上,直到可以清理它们,需要频繁Vacumm. 没有mysql和oracle的REDO UNDO.
5, 进程模式,每个连接都需要内存,而服务器上的内存是有限的,添加更多连接会降低性能(大约 ~2 倍内核),特别是使用双缓冲时,更少的可用内存意味着更多的 I/O.
6,Heap table, 主键是二级索引,存双份数据(表和索引列),浪费了空间, 即使是index read only也需要读取表(因为Pg索引结构限制)。
7,大版本升级需要停机时间。某些主要版本升级需要数小时的停机时间才能转换大型数据库的数据。使用典型的流式复制机制,无法通过升级副本并执行故障转移来正常执行此操作,存在不兼容问题。
8:有点繁琐的复制设置
9, PostgreSQL开发团队多年来一直拒绝支持HINT,认为优化器足够的聪明,不需要人为干涉执行计划
10, PostgreSQL 不提供压缩,它依靠操作系统来处理任何与文件相关的内容。
PostgreSQL功能丰富,通常没有锋利的边缘,并且对于绝大多数用例来说都能满足性能需求。它也不受占主导地位的企业赞助商的阻碍,包括出色的文档,并拥有专业、包容的社区。再看看国内的数据库目前解决了哪些?
#1 问题
在opengauss系已经改为64位xid, 达梦和Oceanbase 是类似于Oracle的SCN,OB使用的是全局时间戳服务,OceanBase 数据库内部每个租户启动一个全局时间戳服务,事务提交时通过本租户的时间戳服务获取事务版本号,保证全局的事务顺序,而像其它分布式数据库CockRoachDB、YugabyteDB 使用了混合逻辑时钟 HLC,TiDB 的 TSO 使用集中式混合逻辑时钟来提供时间服务。它使用 64 位来表示时间间隔。低 18 位代表逻辑时钟,其余 46 位代表物理时钟。由于其逻辑时钟为 18 位结构,每秒总共可以生成和分配 2^18 * 1,000 或 262,144,000 个时间戳。
#2 问题
这点opengauss似乎还是PG的这种模式,不过开始做基于共享存储架构、像GaussDB Naf网络 依赖存储能力同步,保障RPO=0 . 而像分布式数据库OB,TIDB,YugabyteDB等专为高效同步复制构建的多副本,Raft或Paxos 分布式一致性协议组,始终只有1个leader读写,没有脑裂,如果故障,flowwer在3-5秒左右可以选举成为新主。
#3 问题
Postgresql全页写确实会因为整个数据块写入到WAL日志文件中导致WAL日志膨胀,提高了数据安全性,MySQL是double writer, oracle是有写丢失保护和db block checking/checksum,在opengauss系使用的也是double write不再使用full page write防止半页写问题。 至于OB,TIDB的同一个集群内是基于paxos/raft的分布式一致性协议多节点记录,同样使用多级SSTABLE 合并只读存储顺序写入,每个节点独立压缩同时校验。至于逻辑复制日志内容我不是很确认,YugabyteDB是基于键值的逻辑复制,但是有一点如OB如果SQL没有明确分区/分片,多分区表可能会放大事务导致日志膨胀。
#4问题
PostgreSQL的MVCC 追加更新,在openGauss对于ustore支持in-place更新,astore和PG一样,达梦数据库和ORACLE/MYSQL一样利用UNDO; OB,TIDB,YugabyteDB LSM -tree存储引擎,按列存储更新,存储存储管理后台自动压缩SSTABLE,并且不会和写入冲突,因为sstable是不可变的,OB的数据压缩有的客户观察可以达6-10倍。
#5问题
Postgresql是进程模式,在opengauss系、达梦和中兴goldendb、万里greatedb、OB,TIDB为线程模式, 但集中数据库的线程模式有时也可能因为某个连接的bug导致实例crash、产生业务中断或switchover,而不只是用户进程级crash。国外的CockroachDB前台用户连接也是通过线程来处理的 ,YugabyteDB是进程模式,但是分布式数据库连接可以扩展到多个节点。
#6问题
postgresql是和oracle一样的heap table, opengauss系DB也是堆表,达梦和MySQL一样是索引组织表,MySQL系的分布式如中兴、万里也是继承了MySQL. 而TIDB,Oceanbase和国外的CRDB、YugabyteDB是使用表存储在其主索引结构的LSM存储,第一级在内存中确保了主键的快速访问。
#7问题
opengauss升级策略需要考虑版本间是否发生元数据变更。当元数据的版本不发生变化时可以使用滚动升级,发生元数据变化需要停机。分布式数据库有一些特性可以实现无感知升级,它允许在不中断服务的情况下逐步升级集群中的各个节点。然而,即使使用了这样的功能,升级过程中仍然可能会引入潜在的风险,比如由于不同版本之间的兼容性问题导致的数据不一致或者服务不可用等情况。
#8问题
配置复制opengauss系应该是和PG一样的,分布式数据库同一集群内增加副本数可能比较简单,完全自动化。
#9问题
在Pg中当然也可以使用pg_hint_plan完成,在opengauss系,达梦、OB、TIDB等基本和oracle一样都是支持hint的,可能没有oracle的全。
#10问题
opengauss系一些商业发行版支持行级压缩,而像OB,TIDB 支持存储上的压缩,而且还很明显。
总结
说了那么多PG的问题,你可能仍然应该使用PG,像Rick Branson作者说的“一般来说,我建议从 PostgreSQL 开始,然后尝试弄清楚为什么它不适用于您的用例。” PG有丰富的组件和一些云托管服务或分支在逐渐解决它的问题,如openGauss.,国产当前分布式数据库也非常的火, 当然分布式数据库也非魔法,并不是可以解决所有问题,像 Franck Pachot说的”分布式数据库需要更多的前期设计,例如主键分片,并且由于没有共享缓冲区缓存,因此在单节点操作中可能显示较低的性能。”, PostgreSQL 是我所知道的最好的开源数据库,适用于广泛的工作负载。而openGauss继承并优化了它的一些问题,希望后期国内社区可以持续的支持更新。
— 以上仅代表个人观点,错误请指正。
Reference
https://rbranson.medium.com/10-things-i-hate-about-postgresql-20dbab8c2791
https://franckpachot.medium.com/which-postgresql-problems-are-solved-with-yugabytedb-7e479df472ba
对不起,这篇文章暂时关闭评论。