1 | /*-------------------------------------------------------------------------- |
2 | * ginxlog.h |
3 | * header file for postgres inverted index xlog implementation. |
4 | * |
5 | * Copyright (c) 2006-2019, PostgreSQL Global Development Group |
6 | * |
7 | * src/include/access/ginxlog.h |
8 | *-------------------------------------------------------------------------- |
9 | */ |
10 | #ifndef GINXLOG_H |
11 | #define GINXLOG_H |
12 | |
13 | #include "access/ginblock.h" |
14 | #include "access/itup.h" |
15 | #include "access/xlogreader.h" |
16 | #include "lib/stringinfo.h" |
17 | #include "storage/off.h" |
18 | |
19 | #define XLOG_GIN_CREATE_PTREE 0x10 |
20 | |
21 | typedef struct ginxlogCreatePostingTree |
22 | { |
23 | uint32 size; |
24 | /* A compressed posting list follows */ |
25 | } ginxlogCreatePostingTree; |
26 | |
27 | /* |
28 | * The format of the insertion record varies depending on the page type. |
29 | * ginxlogInsert is the common part between all variants. |
30 | * |
31 | * Backup Blk 0: target page |
32 | * Backup Blk 1: left child, if this insertion finishes an incomplete split |
33 | */ |
34 | |
35 | #define XLOG_GIN_INSERT 0x20 |
36 | |
37 | typedef struct |
38 | { |
39 | uint16 flags; /* GIN_INSERT_ISLEAF and/or GIN_INSERT_ISDATA */ |
40 | |
41 | /* |
42 | * FOLLOWS: |
43 | * |
44 | * 1. if not leaf page, block numbers of the left and right child pages |
45 | * whose split this insertion finishes, as BlockIdData[2] (beware of |
46 | * adding fields in this struct that would make them not 16-bit aligned) |
47 | * |
48 | * 2. a ginxlogInsertEntry or ginxlogRecompressDataLeaf struct, depending |
49 | * on tree type. |
50 | * |
51 | * NB: the below structs are only 16-bit aligned when appended to a |
52 | * ginxlogInsert struct! Beware of adding fields to them that require |
53 | * stricter alignment. |
54 | */ |
55 | } ginxlogInsert; |
56 | |
57 | typedef struct |
58 | { |
59 | OffsetNumber offset; |
60 | bool isDelete; |
61 | IndexTupleData tuple; /* variable length */ |
62 | } ginxlogInsertEntry; |
63 | |
64 | |
65 | typedef struct |
66 | { |
67 | uint16 nactions; |
68 | |
69 | /* Variable number of 'actions' follow */ |
70 | } ginxlogRecompressDataLeaf; |
71 | |
72 | /* |
73 | * Note: this struct is currently not used in code, and only acts as |
74 | * documentation. The WAL record format is as specified here, but the code |
75 | * uses straight access through a Pointer and memcpy to read/write these. |
76 | */ |
77 | typedef struct |
78 | { |
79 | uint8 segno; /* segment this action applies to */ |
80 | char type; /* action type (see below) */ |
81 | |
82 | /* |
83 | * Action-specific data follows. For INSERT and REPLACE actions that is a |
84 | * GinPostingList struct. For ADDITEMS, a uint16 for the number of items |
85 | * added, followed by the items themselves as ItemPointers. DELETE actions |
86 | * have no further data. |
87 | */ |
88 | } ginxlogSegmentAction; |
89 | |
90 | /* Action types */ |
91 | #define GIN_SEGMENT_UNMODIFIED 0 /* no action (not used in WAL records) */ |
92 | #define GIN_SEGMENT_DELETE 1 /* a whole segment is removed */ |
93 | #define GIN_SEGMENT_INSERT 2 /* a whole segment is added */ |
94 | #define GIN_SEGMENT_REPLACE 3 /* a segment is replaced */ |
95 | #define GIN_SEGMENT_ADDITEMS 4 /* items are added to existing segment */ |
96 | |
97 | typedef struct |
98 | { |
99 | OffsetNumber offset; |
100 | PostingItem newitem; |
101 | } ginxlogInsertDataInternal; |
102 | |
103 | /* |
104 | * Backup Blk 0: new left page (= original page, if not root split) |
105 | * Backup Blk 1: new right page |
106 | * Backup Blk 2: original page / new root page, if root split |
107 | * Backup Blk 3: left child, if this insertion completes an earlier split |
108 | */ |
109 | #define XLOG_GIN_SPLIT 0x30 |
110 | |
111 | typedef struct ginxlogSplit |
112 | { |
113 | RelFileNode node; |
114 | BlockNumber rrlink; /* right link, or root's blocknumber if root |
115 | * split */ |
116 | BlockNumber leftChildBlkno; /* valid on a non-leaf split */ |
117 | BlockNumber rightChildBlkno; |
118 | uint16 flags; /* see below */ |
119 | } ginxlogSplit; |
120 | |
121 | /* |
122 | * Flags used in ginxlogInsert and ginxlogSplit records |
123 | */ |
124 | #define GIN_INSERT_ISDATA 0x01 /* for both insert and split records */ |
125 | #define GIN_INSERT_ISLEAF 0x02 /* ditto */ |
126 | #define GIN_SPLIT_ROOT 0x04 /* only for split records */ |
127 | |
128 | /* |
129 | * Vacuum simply WAL-logs the whole page, when anything is modified. This |
130 | * is functionally identical to heap_newpage records, but is kept separate for |
131 | * debugging purposes. (When inspecting the WAL stream, it's easier to see |
132 | * what's going on when GIN vacuum records are marked as such, not as heap |
133 | * records.) This is currently only used for entry tree leaf pages. |
134 | */ |
135 | #define XLOG_GIN_VACUUM_PAGE 0x40 |
136 | |
137 | /* |
138 | * Vacuuming posting tree leaf page is WAL-logged like recompression caused |
139 | * by insertion. |
140 | */ |
141 | #define XLOG_GIN_VACUUM_DATA_LEAF_PAGE 0x90 |
142 | |
143 | typedef struct ginxlogVacuumDataLeafPage |
144 | { |
145 | ginxlogRecompressDataLeaf data; |
146 | } ginxlogVacuumDataLeafPage; |
147 | |
148 | /* |
149 | * Backup Blk 0: deleted page |
150 | * Backup Blk 1: parent |
151 | * Backup Blk 2: left sibling |
152 | */ |
153 | #define XLOG_GIN_DELETE_PAGE 0x50 |
154 | |
155 | typedef struct ginxlogDeletePage |
156 | { |
157 | OffsetNumber parentOffset; |
158 | BlockNumber rightLink; |
159 | TransactionId deleteXid; /* last Xid which could see this page in scan */ |
160 | } ginxlogDeletePage; |
161 | |
162 | #define XLOG_GIN_UPDATE_META_PAGE 0x60 |
163 | |
164 | /* |
165 | * Backup Blk 0: metapage |
166 | * Backup Blk 1: tail page |
167 | */ |
168 | typedef struct ginxlogUpdateMeta |
169 | { |
170 | RelFileNode node; |
171 | GinMetaPageData metadata; |
172 | BlockNumber prevTail; |
173 | BlockNumber newRightlink; |
174 | int32 ntuples; /* if ntuples > 0 then metadata.tail was |
175 | * updated with that many tuples; else new sub |
176 | * list was inserted */ |
177 | /* array of inserted tuples follows */ |
178 | } ginxlogUpdateMeta; |
179 | |
180 | #define XLOG_GIN_INSERT_LISTPAGE 0x70 |
181 | |
182 | typedef struct ginxlogInsertListPage |
183 | { |
184 | BlockNumber rightlink; |
185 | int32 ntuples; |
186 | /* array of inserted tuples follows */ |
187 | } ginxlogInsertListPage; |
188 | |
189 | /* |
190 | * Backup Blk 0: metapage |
191 | * Backup Blk 1 to (ndeleted + 1): deleted pages |
192 | */ |
193 | |
194 | #define XLOG_GIN_DELETE_LISTPAGE 0x80 |
195 | |
196 | /* |
197 | * The WAL record for deleting list pages must contain a block reference to |
198 | * all the deleted pages, so the number of pages that can be deleted in one |
199 | * record is limited by XLR_MAX_BLOCK_ID. (block_id 0 is used for the |
200 | * metapage.) |
201 | */ |
202 | #define GIN_NDELETE_AT_ONCE Min(16, XLR_MAX_BLOCK_ID - 1) |
203 | typedef struct ginxlogDeleteListPages |
204 | { |
205 | GinMetaPageData metadata; |
206 | int32 ndeleted; |
207 | } ginxlogDeleteListPages; |
208 | |
209 | extern void gin_redo(XLogReaderState *record); |
210 | extern void gin_desc(StringInfo buf, XLogReaderState *record); |
211 | extern const char *gin_identify(uint8 info); |
212 | extern void gin_xlog_startup(void); |
213 | extern void gin_xlog_cleanup(void); |
214 | extern void gin_mask(char *pagedata, BlockNumber blkno); |
215 | |
216 | #endif /* GINXLOG_H */ |
217 | |