Hi, The zheap patchset, even after being based on pluggable storage, currently has the following condition in RelationAddExtraBlocks(): if (RelationStorageIsZHeap(relation)) { Assert(BufferGetBlockNumber(buffer) != ZHEAP_METAPAGE); ZheapInitPage(page, BufferGetPageSize(buffer)); freespace = PageGetZHeapFreeSpace(page); } else { PageInit(page, BufferGetPageSize(buffer), 0); freespace = PageGetHeapFreeSpace(page); }
I.e. it initializes the page differently when zheap is used versus heap. Thinking about whether it's worth to allow to extend that function in an extensible manner made me wonder: Is it actually a good idea to initialize the page at that point, including marking it dirty? As far as I can tell that that has several downsides: - Dirtying the buffer for initialization will cause potentially superfluous IO, with no interesting data in the write except for a newly initialized page. - As there's no sort of interlock, it's entirely possible that, after a crash, the blocks will come up empty, but with the FSM returning it as as empty, so that path would be good to support anyway. - It adds heap specific code to a routine that otherwise could be generic for different table access methods It seems to me, this could be optimized by *not* initializing the page, and having a PageIsNew(), check at the places that check whether the page is new, and initialize it in that case. Right now we'll just ignore such pages when we encounter them (e.g. after a crash) until vacuum initializes them. But given that we've accepted that we'll potentially create empty pages anyway, I don't see what advantages that provides? The warnings emitted by vacuum are pretty scary, and can happen in a lot of legitimate cases, so removing them seems like a good idea anyway. I'm pretty tired, so I might be missing something large and obvious here. Greetings, Andres Freund