/* * Given a BRIN index page, initialize it if necessary, and record it into the * FSM if necessary. Return value is true if the FSM itself needs "vacuuming". * The main use for this is when, during vacuuming, an uninitialized page is * found, which could be the result of relation extension followed by a crash * before the page can be used. */ bool brin_page_cleanup(Relation idxrel, Buffer buf) { Page page = BufferGetPage(buf); Size freespace; /* * If a page was left uninitialized, initialize it now; also record it in * FSM. * * Somebody else might be extending the relation concurrently. To avoid * re-initializing the page before they can grab the buffer lock, we * acquire the extension lock momentarily. Since they hold the extension * lock from before getting the page and after its been initialized, we're * sure to see their initialization. */ if (PageIsNew(page)) { LockRelationForExtension(idxrel, ShareLock); UnlockRelationForExtension(idxrel, ShareLock); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); if (PageIsNew(page)) { brin_initialize_empty_new_buffer(idxrel, buf); LockBuffer(buf, BUFFER_LOCK_UNLOCK); return true; } LockBuffer(buf, BUFFER_LOCK_UNLOCK); } /* Nothing to be done for non-regular index pages */ if (BRIN_IS_META_PAGE(BufferGetPage(buf)) || BRIN_IS_REVMAP_PAGE(BufferGetPage(buf))) return false; /* Measure free space and record it */ freespace = br_page_get_freespace(page); if (freespace > GetRecordedFreeSpace(idxrel, BufferGetBlockNumber(buf))) { RecordPageWithFreeSpace(idxrel, BufferGetBlockNumber(buf), freespace); return true; } return false; }
/* * Mask a BRIN page before doing consistency checks. */ void brin_mask(char *pagedata, BlockNumber blkno) { Page page = (Page) pagedata; PageHeader pagehdr = (PageHeader) page; mask_page_lsn_and_checksum(page); mask_page_hint_bits(page); /* * Regular brin pages contain unused space which needs to be masked. * Similarly for meta pages, but mask it only if pd_lower appears to have * been set correctly. */ if (BRIN_IS_REGULAR_PAGE(page) || (BRIN_IS_META_PAGE(page) && pagehdr->pd_lower > SizeOfPageHeaderData)) { mask_unused_space(page); } }