zheap是什么?
- zheap是PostgreSQL新一代的存储引擎,遵循PostgreSQL的license.zheap引擎最初是由EnterpriseDB开发。开源版本目前是由
https://github.com/cybertec-postgresql/postgres/tree/REL_13_ZHEAP
项目接管,持续更新。zheap的整体目标是整合到PostgreSQL中
zheap设计的初衷是什么?
- 在特定的场景下PostgreSQL的表会变得很膨胀,PostgreSQL默认是heap表,采用Cow方式,有效行数据和无效行数据会存储在表中,如果不做full vacuum表的空间不会得到回收。zheap的目标就是效仿Oracle的方式,无效数据(被删除或者删除数据)和有效数据分开存储,引入undo的技术。
- 每个主流的DBMS实现MVCC都采用不同的技术,PostgreSQL是元组的所有版本存储在表中;Oracle和MySQL是旧版本数据存储在undo日志中;SQL Server是把旧版本数据存储在tempdb中,每一种实现各有特色。
- zheap的设计是为了达到至少2个目标,第一是更好的控制表的膨胀,执行行数据的原地"更新"来避免表膨胀;第二是保持更小的tuple headers,目前PostgreSQL默认的引擎中表的header存储了大量的事务和为了对齐而采用的padding技术。zheap引擎是要消除这些padding同时在page中不存储事务信息。
zheap 采用什么新技术?
- 在zheap存储引擎中,引入了undo的技术,同时每个page设计了固定数量的
transaction slots
,每个slot
存储了事务信息,事务信息包括transaction id
、epoch
、last undo record pointer
信息。每个zheap的page是可以配置,默认是4个transaction slots
.每个transaction slot
占用16个字节。transaction slots
在zheap存储引擎中是可以复用,当事务提交了,这些transaction slot
可以resued,所以每个page中不需要那么多的slot
.
zheap 是如何工作的?
- zheap引入undo,所有的旧版本数据存储在undo中。当执行一个记录更新的事务,先写wal(redo)日志,随后记录这个操作涉及到所有变更到undo(记录所有的变更)。当事务aborts,undo被用来回滚所有的变更。
- undo日志存储了MVCC需要的所有的记录的版本数据,少量的事务信息记录在表中,减少表中的padding,这样也达到了减少表的表在磁盘上的空间占用。
- 当事务更新记录中发生了crash,可以借助PostgreSQL的wal先进行恢复,后借助undo日志进行回滚那些未被提交或者终止的事务。
- zheap引擎中undo需要记录每条记录的insert/update/delete操作。insert操作采用了heap存储引擎 undo日志,heap表插入数据同时在undo日志中记录删除操作;delete操作采用heap存储引擎 undo日志,undo日志记录所有被删除的数据;update操作首先将旧记录存储在undo日志中,原地更新防止表膨胀,但是这会导致undo日志膨胀,但是一旦失误提交或者回滚undo相关的空间就重用。