Age Owner TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * gindesc.c
4 : * rmgr descriptor routines for access/transam/gin/ginxlog.c
5 : *
6 : * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : *
10 : * IDENTIFICATION
11 : * src/backend/access/rmgrdesc/gindesc.c
12 : *
13 : *-------------------------------------------------------------------------
14 : */
15 : #include "postgres.h"
16 :
17 : #include "access/ginxlog.h"
18 : #include "access/xlogutils.h"
19 : #include "lib/stringinfo.h"
20 : #include "storage/relfilelocator.h"
21 :
22 : static void
3296 heikki.linnakangas 23 UBC 0 : desc_recompress_leaf(StringInfo buf, ginxlogRecompressDataLeaf *insertData)
24 : {
25 : int i;
26 0 : char *walbuf = ((char *) insertData) + sizeof(ginxlogRecompressDataLeaf);
27 :
28 0 : appendStringInfo(buf, " %d segments:", (int) insertData->nactions);
29 :
30 0 : for (i = 0; i < insertData->nactions; i++)
31 : {
32 0 : uint8 a_segno = *((uint8 *) (walbuf++));
33 0 : uint8 a_action = *((uint8 *) (walbuf++));
34 0 : uint16 nitems = 0;
35 0 : int newsegsize = 0;
36 :
37 0 : if (a_action == GIN_SEGMENT_INSERT ||
38 : a_action == GIN_SEGMENT_REPLACE)
39 : {
40 0 : newsegsize = SizeOfGinPostingList((GinPostingList *) walbuf);
41 0 : walbuf += SHORTALIGN(newsegsize);
42 : }
43 :
44 0 : if (a_action == GIN_SEGMENT_ADDITEMS)
45 : {
46 0 : memcpy(&nitems, walbuf, sizeof(uint16));
47 0 : walbuf += sizeof(uint16);
48 0 : walbuf += nitems * sizeof(ItemPointerData);
49 : }
50 :
3260 bruce 51 0 : switch (a_action)
52 : {
3296 heikki.linnakangas 53 0 : case GIN_SEGMENT_ADDITEMS:
54 0 : appendStringInfo(buf, " %d (add %d items)", a_segno, nitems);
55 0 : break;
56 0 : case GIN_SEGMENT_DELETE:
57 0 : appendStringInfo(buf, " %d (delete)", a_segno);
58 0 : break;
59 0 : case GIN_SEGMENT_INSERT:
60 0 : appendStringInfo(buf, " %d (insert)", a_segno);
61 0 : break;
62 0 : case GIN_SEGMENT_REPLACE:
63 0 : appendStringInfo(buf, " %d (replace)", a_segno);
64 0 : break;
65 0 : default:
66 0 : appendStringInfo(buf, " %d unknown action %d ???", a_segno, a_action);
67 : /* cannot decode unrecognized actions further */
68 0 : return;
69 : }
70 : }
71 : }
72 :
73 : void
3062 74 0 : gin_desc(StringInfo buf, XLogReaderState *record)
75 : {
3221 76 0 : char *rec = XLogRecGetData(record);
3062 77 0 : uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
78 :
3784 alvherre 79 0 : switch (info)
80 : {
81 0 : case XLOG_GIN_CREATE_PTREE:
82 : /* no further information */
83 0 : break;
84 0 : case XLOG_GIN_INSERT:
85 : {
3420 heikki.linnakangas 86 0 : ginxlogInsert *xlrec = (ginxlogInsert *) rec;
87 :
3062 88 0 : appendStringInfo(buf, "isdata: %c isleaf: %c",
2118 tgl 89 0 : (xlrec->flags & GIN_INSERT_ISDATA) ? 'T' : 'F',
90 0 : (xlrec->flags & GIN_INSERT_ISLEAF) ? 'T' : 'F');
3420 heikki.linnakangas 91 0 : if (!(xlrec->flags & GIN_INSERT_ISLEAF))
92 : {
2316 fujii 93 0 : char *payload = rec + sizeof(ginxlogInsert);
94 : BlockNumber leftChildBlkno;
95 : BlockNumber rightChildBlkno;
96 :
3419 heikki.linnakangas 97 0 : leftChildBlkno = BlockIdGetBlockNumber((BlockId) payload);
98 0 : payload += sizeof(BlockIdData);
99 0 : rightChildBlkno = BlockIdGetBlockNumber((BlockId) payload);
3420 100 0 : payload += sizeof(BlockNumber);
101 0 : appendStringInfo(buf, " children: %u/%u",
102 : leftChildBlkno, rightChildBlkno);
103 : }
2316 fujii 104 0 : if (XLogRecHasBlockImage(record, 0))
105 : {
2251 rhaas 106 0 : if (XLogRecBlockImageApply(record, 0))
107 0 : appendStringInfoString(buf, " (full page image)");
108 : else
109 0 : appendStringInfoString(buf, " (full page image, for WAL verification)");
110 : }
111 : else
112 : {
2316 fujii 113 0 : char *payload = XLogRecGetBlockData(record, 0, NULL);
114 :
115 0 : if (!(xlrec->flags & GIN_INSERT_ISDATA))
116 0 : appendStringInfo(buf, " isdelete: %c",
2153 bruce 117 0 : (((ginxlogInsertEntry *) payload)->isDelete) ? 'T' : 'F');
2316 fujii 118 0 : else if (xlrec->flags & GIN_INSERT_ISLEAF)
119 0 : desc_recompress_leaf(buf, (ginxlogRecompressDataLeaf *) payload);
120 : else
121 : {
122 0 : ginxlogInsertDataInternal *insertData =
123 : (ginxlogInsertDataInternal *) payload;
124 :
125 0 : appendStringInfo(buf, " pitem: %u-%u/%u",
2118 tgl 126 0 : PostingItemGetBlockNumber(&insertData->newitem),
127 0 : ItemPointerGetBlockNumber(&insertData->newitem.key),
128 0 : ItemPointerGetOffsetNumber(&insertData->newitem.key));
129 : }
130 : }
131 : }
3784 alvherre 132 0 : break;
133 0 : case XLOG_GIN_SPLIT:
134 : {
3364 heikki.linnakangas 135 0 : ginxlogSplit *xlrec = (ginxlogSplit *) rec;
136 :
3062 137 0 : appendStringInfo(buf, "isrootsplit: %c",
2118 tgl 138 0 : (((ginxlogSplit *) rec)->flags & GIN_SPLIT_ROOT) ? 'T' : 'F');
3364 heikki.linnakangas 139 0 : appendStringInfo(buf, " isdata: %c isleaf: %c",
2118 tgl 140 0 : (xlrec->flags & GIN_INSERT_ISDATA) ? 'T' : 'F',
141 0 : (xlrec->flags & GIN_INSERT_ISLEAF) ? 'T' : 'F');
142 : }
3784 alvherre 143 0 : break;
144 0 : case XLOG_GIN_VACUUM_PAGE:
145 : /* no further information */
146 0 : break;
3364 heikki.linnakangas 147 0 : case XLOG_GIN_VACUUM_DATA_LEAF_PAGE:
148 : {
3062 149 0 : if (XLogRecHasBlockImage(record, 0))
150 : {
2251 rhaas 151 0 : if (XLogRecBlockImageApply(record, 0))
152 0 : appendStringInfoString(buf, " (full page image)");
153 : else
154 0 : appendStringInfoString(buf, " (full page image, for WAL verification)");
155 : }
156 : else
157 : {
158 : ginxlogVacuumDataLeafPage *xlrec =
2153 bruce 159 0 : (ginxlogVacuumDataLeafPage *) XLogRecGetBlockData(record, 0, NULL);
160 :
3296 heikki.linnakangas 161 0 : desc_recompress_leaf(buf, &xlrec->data);
162 : }
163 : }
3364 164 0 : break;
3784 alvherre 165 0 : case XLOG_GIN_DELETE_PAGE:
166 : /* no further information */
167 0 : break;
168 0 : case XLOG_GIN_UPDATE_META_PAGE:
169 : /* no further information */
170 0 : break;
171 0 : case XLOG_GIN_INSERT_LISTPAGE:
172 : /* no further information */
173 0 : break;
174 0 : case XLOG_GIN_DELETE_LISTPAGE:
3062 heikki.linnakangas 175 0 : appendStringInfo(buf, "ndeleted: %d",
176 : ((ginxlogDeleteListPages *) rec)->ndeleted);
3784 alvherre 177 0 : break;
178 : }
3124 andres 179 0 : }
180 :
181 : const char *
182 0 : gin_identify(uint8 info)
183 : {
184 0 : const char *id = NULL;
185 :
3121 186 0 : switch (info & ~XLR_INFO_MASK)
187 : {
3124 188 0 : case XLOG_GIN_CREATE_PTREE:
189 0 : id = "CREATE_PTREE";
190 0 : break;
191 0 : case XLOG_GIN_INSERT:
192 0 : id = "INSERT";
193 0 : break;
194 0 : case XLOG_GIN_SPLIT:
195 0 : id = "SPLIT";
196 0 : break;
197 0 : case XLOG_GIN_VACUUM_PAGE:
198 0 : id = "VACUUM_PAGE";
199 0 : break;
200 0 : case XLOG_GIN_VACUUM_DATA_LEAF_PAGE:
201 0 : id = "VACUUM_DATA_LEAF_PAGE";
202 0 : break;
203 0 : case XLOG_GIN_DELETE_PAGE:
204 0 : id = "DELETE_PAGE";
205 0 : break;
206 0 : case XLOG_GIN_UPDATE_META_PAGE:
207 0 : id = "UPDATE_META_PAGE";
208 0 : break;
209 0 : case XLOG_GIN_INSERT_LISTPAGE:
210 0 : id = "INSERT_LISTPAGE";
211 0 : break;
212 0 : case XLOG_GIN_DELETE_LISTPAGE:
213 0 : id = "DELETE_LISTPAGE";
3784 alvherre 214 0 : break;
215 : }
216 :
3124 andres 217 0 : return id;
218 : }
|