当openGauss推出USTORE存储引擎的时候,就不止一个朋友说高斯的USTORE是基于开源项目ZHEAP开发的。以前没怎么研究,所以也不方便发表意见。正好这几天在研究高斯USTORE,顺便也找了些ZHEAP的资料看了看。ZHEAP这个项目目前似乎已处于停滞状态,这个原本计划PG 15时合并到PG主版本的项目很可能会夭折。项目的最后更新时间时2021年6月,支持的PG版本为PG 13。ZHEAP是一个开源项目,因此大家如果有兴趣去测试一下,可以去https://www.cybertec-postgresql.com/en/postgresql-zheap-current-status/下载,目前这个项目由CYBERTEC公司维护。
说实在的数据库十分复杂,如果从表象上去判断两个数据库是否同源实际上是很难判断的。我一般会从一些基础数据结构和存储引擎来分析二者是否同源。数据库的存储结构是最为底层的,每个字段都可以找到存在的理由,因此通过存储结构,特别是页结构来判断数据库底层代码的亲缘关系是十分有效的办法。前阵子很多人和我讨论达梦数据库是不是购买了Oracle 9i的代码,我可以十分肯定的回答,答案是否定的。因为从达梦的BLOCK结构来看,和Oracle是完全不同的,如果说相似,达梦的BLOCK结构和INNODB的PAGE结构有点类似,比较凑巧的是,达梦和INNODB都采用了BTREE表,而不是Oracle的HEAP表。如果说达梦的早期版本参考过MYSQL的INNODB,可能还有点可能性,买Oracle 9i的代码那就是无稽之谈了。提出这个问题的人可能感叹于达梦和Oracle在使用方法上的相似性,不过这种相似性,是达梦公司二十多年来不断的模仿,积累的结果,绝不是简单的偷了人家的代码。实际上我敢十分肯定的说这句话还源于这些年我和达梦研发团队的几次直接交流,我们两个团队交流的时候,达梦的研发人员总是在和我们探讨某项功能Oracle是如何实现的,他们有什么可借鉴之处。如果他们拿到了Oracle 9i的代码,这些问题就没必要和我们一起来研究了。
回到正题,高斯的USTORE是抄袭了EDB的ZHEAP项目吗?我们也还是从底层的存储结构上来看。其实昨天我写了一篇关于USTORE的文章,指出USTORE的块结构完全模仿了ORACLE,甚至在一些代码的注释里,把事务槽TD称为ORACLE的术语ITL。从这一点上,我更详细研发人员充分借鉴了Oracle的设计思想。而ZHEAP项目的PAGE结构是完全不同的。
ZHEAP的事务槽并没有模仿Oracle,放在PAGEHEADER后面,数据前面,而是放在块尾,ZHEAP默认有4个事务槽,这一点和USTORE类似。放在尾部就有一个问题,无法扩展。和USTORE的设计相同的是,ZHEAP的事务槽也要等某个UNDO RECORD失效后才能释放,因此扩展事务槽是必须的。而放在尾部无法扩展的问题如何解决呢?ZHEAP想到了TPD扩展,TPD页是一种没有数据只有事务槽的页,如果不够用了,最后一个SLOT里就指向了一个TPD页。
这种设计避免了因为SLOT不足而产生长时间的等待,不过查找TPD信息依然是有成本的。USTORE的设计是TD最大可以扩展到100个,超过100个就会产生等待,甚至SLEEP,而ZHEAP的设计是永远不需要SLEEP,不过超过4个SLOT,性能就会有问题。Oracle的设计似乎更好一些,把ITL的历史信息放入UNDO 中,这样事务一旦提交,不用管UNDO RETENTION就可以重新占用ITL了。当然ITL写入UNDO依然会产生开销,和ZHEAP的TPD页访问类似。一种折中的方案是结合USTORE和ZHEAP的算法,最后一条TD记录里指向yige TPD页,这样既保持了常态化状态下的性能,又确保了一旦出现极端的情况,出现事务槽争用也有解决方法。
从TUPLE头结构上,也可以看出USTORE和ZHEAP的不同,ZHEAP的设计还是尽可能要和PG原生代码保持兼容,而从USTORE的设计上处处透着高斯今后要完全用USTORE替代ASTORE的想法。其实到这里我也不需要再过多的分析这个问题了。ZHEAP和USTORE是两种完全不同的设计和实现,也许USTORE设计时参考了一些ZHEAP的思想,不过最终USTORE采用了抄袭Oracle的方案。
原本我想测试下USTORE和ASTORE的性能。不过当前的USTORE版本还是BETA版,性能并没有某些网文吹嘘的那么好,甚至再我的测试环境中,USTORE和ASTORE比,性能是惨不忍睹的。实际上,EDP前几年公布ZHEAP的测试结果时,只是用了存储容量的比较,并没有发布性能比较的结果。而再CYBERTECH网站上更是指出,一个新的存储引擎,没有多年的优化以及大量用户的测试,再加以优化改进,是不可能在性能上超过PG现有的存储引擎的。
不过我们还是针对USTORE做了一些测试,当INIT_TD使用默认的4时,我们测出来的TPMC指标为95954 neworder。总的TPMC为21.3万。
而INIT_TD=32时,为newoerder为10.8万,总tpmc为24万。设置合理的事务槽数量,对高并发的TPMC测试场景还是有效的。
不过和使用ASTORE相比,TPMC差距还是很大。差不多少了50%。
最后我们来看看存储容量。使用ASTORE,数据装在后,BMSQL_ORDER_LINE表大小为1447MB。
压测结束时,这张表的大小为4643MB。增加了3倍多。
如果我们使用USTORE,采用INIT_TD=64,压测开始前,BMSQL_ORDER_LINE是1361MB。
压测结束时,表的大小是3950MB,大约是2倍多,空间节约了一些,不过似乎没有那么明显。这和场景有关,对于UPDATE为主的场景,情况会有不同。
今天我简单的分析了一下目前PG的两个USTORE实现,这也是广大PGER期望的功能,如果PG能够解决ASTORE带来的问题,将会完美的多。不过一个数据库产品,底层存储引擎对稳定性与性能影响极大。要想做好USTORE也并非易事,这是伤筋动骨的改造。我们也希望高斯的USTORE能够成功。