/* * redo delete on gist index page to remove tuples marked as DEAD during index * tuple insertion */ static void gistRedoDeleteRecord(XLogReaderState *record) { XLogRecPtr lsn = record->EndRecPtr; gistxlogDelete *xldata = (gistxlogDelete *) XLogRecGetData(record); Buffer buffer; Page page; /* * If we have any conflict processing to do, it must happen before we * update the page. * * GiST delete records can conflict with standby queries. You might think * that vacuum records would conflict as well, but we've handled that * already. XLOG_HEAP2_CLEANUP_INFO records provide the highest xid * cleaned by the vacuum of the heap and so we can resolve any conflicts * just once when that arrives. After that we know that no conflicts * exist from individual gist vacuum records on that index. */ if (InHotStandby) { TransactionId latestRemovedXid = gistRedoDeleteRecordGetLatestRemovedXid(record); RelFileNode rnode; XLogRecGetBlockTag(record, 0, &rnode, NULL, NULL); ResolveRecoveryConflictWithSnapshot(latestRemovedXid, rnode); } if (XLogReadBufferForRedo(record, 0, &buffer) == BLK_NEEDS_REDO) { page = (Page) BufferGetPage(buffer); if (XLogRecGetDataLen(record) > SizeOfGistxlogDelete) { OffsetNumber *todelete; todelete = (OffsetNumber *) ((char *) xldata + SizeOfGistxlogDelete); PageIndexMultiDelete(page, todelete, xldata->ntodelete); } GistClearPageHasGarbage(page); GistMarkTuplesDeleted(page); PageSetLSN(page, lsn); MarkBufferDirty(buffer); } if (BufferIsValid(buffer)) UnlockReleaseBuffer(buffer); }
/* * Mask a Gist page before running consistency checks on it. */ void gist_mask(char *pagedata, BlockNumber blkno) { Page page = (Page) pagedata; mask_page_lsn_and_checksum(page); mask_page_hint_bits(page); mask_unused_space(page); /* * NSN is nothing but a special purpose LSN. Hence, mask it for the same * reason as mask_page_lsn_and_checksum. */ GistPageSetNSN(page, (uint64) MASK_MARKER); /* * We update F_FOLLOW_RIGHT flag on the left child after writing WAL * record. Hence, mask this flag. See gistplacetopage() for details. */ GistMarkFollowRight(page); if (GistPageIsLeaf(page)) { /* * In gist leaf pages, it is possible to modify the LP_FLAGS without * emitting any WAL record. Hence, mask the line pointer flags. See * gistkillitems() for details. */ mask_lp_flags(page); } /* * During gist redo, we never mark a page as garbage. Hence, mask it to * ignore any differences. */ GistClearPageHasGarbage(page); }