| /*-------------------------------------------------------------------------- |
| * ginxlog.h |
| * header file for postgres inverted index xlog implementation. |
| * |
| * Copyright (c) 2006-2021, PostgreSQL Global Development Group |
| * |
| * src/include/access/ginxlog.h |
| *-------------------------------------------------------------------------- |
| */ |
| #ifndef GINXLOG_H |
| #define GINXLOG_H |
| |
| #include "access/ginblock.h" |
| #include "access/itup.h" |
| #include "access/xlogreader.h" |
| #include "lib/stringinfo.h" |
| #include "storage/off.h" |
| |
| #define XLOG_GIN_CREATE_PTREE 0x10 |
| |
| typedef struct ginxlogCreatePostingTree |
| { |
| uint32 size; |
| /* A compressed posting list follows */ |
| } ginxlogCreatePostingTree; |
| |
| /* |
| * The format of the insertion record varies depending on the page type. |
| * ginxlogInsert is the common part between all variants. |
| * |
| * Backup Blk 0: target page |
| * Backup Blk 1: left child, if this insertion finishes an incomplete split |
| */ |
| |
| #define XLOG_GIN_INSERT 0x20 |
| |
| typedef struct |
| { |
| uint16 flags; /* GIN_INSERT_ISLEAF and/or GIN_INSERT_ISDATA */ |
| |
| /* |
| * FOLLOWS: |
| * |
| * 1. if not leaf page, block numbers of the left and right child pages |
| * whose split this insertion finishes, as BlockIdData[2] (beware of |
| * adding fields in this struct that would make them not 16-bit aligned) |
| * |
| * 2. a ginxlogInsertEntry or ginxlogRecompressDataLeaf struct, depending |
| * on tree type. |
| * |
| * NB: the below structs are only 16-bit aligned when appended to a |
| * ginxlogInsert struct! Beware of adding fields to them that require |
| * stricter alignment. |
| */ |
| } ginxlogInsert; |
| |
| typedef struct |
| { |
| OffsetNumber offset; |
| bool isDelete; |
| IndexTupleData tuple; /* variable length */ |
| } ginxlogInsertEntry; |
| |
| |
| typedef struct |
| { |
| uint16 nactions; |
| |
| /* Variable number of 'actions' follow */ |
| } ginxlogRecompressDataLeaf; |
| |
| /* |
| * Note: this struct is currently not used in code, and only acts as |
| * documentation. The WAL record format is as specified here, but the code |
| * uses straight access through a Pointer and memcpy to read/write these. |
| */ |
| typedef struct |
| { |
| uint8 segno; /* segment this action applies to */ |
| char type; /* action type (see below) */ |
| |
| /* |
| * Action-specific data follows. For INSERT and REPLACE actions that is a |
| * GinPostingList struct. For ADDITEMS, a uint16 for the number of items |
| * added, followed by the items themselves as ItemPointers. DELETE actions |
| * have no further data. |
| */ |
| } ginxlogSegmentAction; |
| |
| /* Action types */ |
| #define GIN_SEGMENT_UNMODIFIED 0 /* no action (not used in WAL records) */ |
| #define GIN_SEGMENT_DELETE 1 /* a whole segment is removed */ |
| #define GIN_SEGMENT_INSERT 2 /* a whole segment is added */ |
| #define GIN_SEGMENT_REPLACE 3 /* a segment is replaced */ |
| #define GIN_SEGMENT_ADDITEMS 4 /* items are added to existing segment */ |
| |
| typedef struct |
| { |
| OffsetNumber offset; |
| PostingItem newitem; |
| } ginxlogInsertDataInternal; |
| |
| /* |
| * Backup Blk 0: new left page (= original page, if not root split) |
| * Backup Blk 1: new right page |
| * Backup Blk 2: original page / new root page, if root split |
| * Backup Blk 3: left child, if this insertion completes an earlier split |
| */ |
| #define XLOG_GIN_SPLIT 0x30 |
| |
| typedef struct ginxlogSplit |
| { |
| RelFileNode node; |
| BlockNumber rrlink; /* right link, or root's blocknumber if root |
| * split */ |
| BlockNumber leftChildBlkno; /* valid on a non-leaf split */ |
| BlockNumber rightChildBlkno; |
| uint16 flags; /* see below */ |
| } ginxlogSplit; |
| |
| /* |
| * Flags used in ginxlogInsert and ginxlogSplit records |
| */ |
| #define GIN_INSERT_ISDATA 0x01 /* for both insert and split records */ |
| #define GIN_INSERT_ISLEAF 0x02 /* ditto */ |
| #define GIN_SPLIT_ROOT 0x04 /* only for split records */ |
| |
| /* |
| * Vacuum simply WAL-logs the whole page, when anything is modified. This |
| * is functionally identical to XLOG_FPI records, but is kept separate for |
| * debugging purposes. (When inspecting the WAL stream, it's easier to see |
| * what's going on when GIN vacuum records are marked as such, not as heap |
| * records.) This is currently only used for entry tree leaf pages. |
| */ |
| #define XLOG_GIN_VACUUM_PAGE 0x40 |
| |
| /* |
| * Vacuuming posting tree leaf page is WAL-logged like recompression caused |
| * by insertion. |
| */ |
| #define XLOG_GIN_VACUUM_DATA_LEAF_PAGE 0x90 |
| |
| typedef struct ginxlogVacuumDataLeafPage |
| { |
| ginxlogRecompressDataLeaf data; |
| } ginxlogVacuumDataLeafPage; |
| |
| /* |
| * Backup Blk 0: deleted page |
| * Backup Blk 1: parent |
| * Backup Blk 2: left sibling |
| */ |
| #define XLOG_GIN_DELETE_PAGE 0x50 |
| |
| typedef struct ginxlogDeletePage |
| { |
| OffsetNumber parentOffset; |
| BlockNumber rightLink; |
| TransactionId deleteXid; /* last Xid which could see this page in scan */ |
| } ginxlogDeletePage; |
| |
| #define XLOG_GIN_UPDATE_META_PAGE 0x60 |
| |
| /* |
| * Backup Blk 0: metapage |
| * Backup Blk 1: tail page |
| */ |
| typedef struct ginxlogUpdateMeta |
| { |
| RelFileNode node; |
| GinMetaPageData metadata; |
| BlockNumber prevTail; |
| BlockNumber newRightlink; |
| int32 ntuples; /* if ntuples > 0 then metadata.tail was |
| * updated with that many tuples; else new sub |
| * list was inserted */ |
| /* array of inserted tuples follows */ |
| } ginxlogUpdateMeta; |
| |
| #define XLOG_GIN_INSERT_LISTPAGE 0x70 |
| |
| typedef struct ginxlogInsertListPage |
| { |
| BlockNumber rightlink; |
| int32 ntuples; |
| /* array of inserted tuples follows */ |
| } ginxlogInsertListPage; |
| |
| /* |
| * Backup Blk 0: metapage |
| * Backup Blk 1 to (ndeleted + 1): deleted pages |
| */ |
| |
| #define XLOG_GIN_DELETE_LISTPAGE 0x80 |
| |
| /* |
| * The WAL record for deleting list pages must contain a block reference to |
| * all the deleted pages, so the number of pages that can be deleted in one |
| * record is limited by XLR_MAX_BLOCK_ID. (block_id 0 is used for the |
| * metapage.) |
| */ |
| #define GIN_NDELETE_AT_ONCE Min(16, XLR_MAX_BLOCK_ID - 1) |
| typedef struct ginxlogDeleteListPages |
| { |
| GinMetaPageData metadata; |
| int32 ndeleted; |
| } ginxlogDeleteListPages; |
| |
| extern void gin_redo(XLogReaderState *record); |
| extern void gin_desc(StringInfo buf, XLogReaderState *record); |
| extern const char *gin_identify(uint8 info); |
| extern void gin_xlog_startup(void); |
| extern void gin_xlog_cleanup(void); |
| extern void gin_mask(char *pagedata, BlockNumber blkno); |
| |
| #endif /* GINXLOG_H */ |