PostgreSQL Source Code git master
gindesc.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * gindesc.c
4 * rmgr descriptor routines for access/transam/gin/ginxlog.c
5 *
6 * Portions Copyright (c) 1996-2025, 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 "lib/stringinfo.h"
19
20static void
22{
23 int i;
24 char *walbuf = ((char *) insertData) + sizeof(ginxlogRecompressDataLeaf);
25
26 appendStringInfo(buf, " %d segments:", (int) insertData->nactions);
27
28 for (i = 0; i < insertData->nactions; i++)
29 {
30 uint8 a_segno = *((uint8 *) (walbuf++));
31 uint8 a_action = *((uint8 *) (walbuf++));
32 uint16 nitems = 0;
33 int newsegsize = 0;
34
35 if (a_action == GIN_SEGMENT_INSERT ||
36 a_action == GIN_SEGMENT_REPLACE)
37 {
38 newsegsize = SizeOfGinPostingList((GinPostingList *) walbuf);
39 walbuf += SHORTALIGN(newsegsize);
40 }
41
42 if (a_action == GIN_SEGMENT_ADDITEMS)
43 {
44 memcpy(&nitems, walbuf, sizeof(uint16));
45 walbuf += sizeof(uint16);
46 walbuf += nitems * sizeof(ItemPointerData);
47 }
48
49 switch (a_action)
50 {
52 appendStringInfo(buf, " %d (add %d items)", a_segno, nitems);
53 break;
55 appendStringInfo(buf, " %d (delete)", a_segno);
56 break;
58 appendStringInfo(buf, " %d (insert)", a_segno);
59 break;
61 appendStringInfo(buf, " %d (replace)", a_segno);
62 break;
63 default:
64 appendStringInfo(buf, " %d unknown action %d ???", a_segno, a_action);
65 /* cannot decode unrecognized actions further */
66 return;
67 }
68 }
69}
70
71void
73{
74 char *rec = XLogRecGetData(record);
75 uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
76
77 switch (info)
78 {
80 /* no further information */
81 break;
82 case XLOG_GIN_INSERT:
83 {
84 ginxlogInsert *xlrec = (ginxlogInsert *) rec;
85
86 appendStringInfo(buf, "isdata: %c isleaf: %c",
87 (xlrec->flags & GIN_INSERT_ISDATA) ? 'T' : 'F',
88 (xlrec->flags & GIN_INSERT_ISLEAF) ? 'T' : 'F');
89 if (!(xlrec->flags & GIN_INSERT_ISLEAF))
90 {
91 char *payload = rec + sizeof(ginxlogInsert);
92 BlockNumber leftChildBlkno;
93 BlockNumber rightChildBlkno;
94
95 leftChildBlkno = BlockIdGetBlockNumber((BlockId) payload);
96 payload += sizeof(BlockIdData);
97 rightChildBlkno = BlockIdGetBlockNumber((BlockId) payload);
98 payload += sizeof(BlockNumber);
99 appendStringInfo(buf, " children: %u/%u",
100 leftChildBlkno, rightChildBlkno);
101 }
102 if (!XLogRecHasBlockImage(record, 0))
103 {
104 char *payload = XLogRecGetBlockData(record, 0, NULL);
105
106 if (!(xlrec->flags & GIN_INSERT_ISDATA))
107 appendStringInfo(buf, " isdelete: %c",
108 (((ginxlogInsertEntry *) payload)->isDelete) ? 'T' : 'F');
109 else if (xlrec->flags & GIN_INSERT_ISLEAF)
111 else
112 {
113 ginxlogInsertDataInternal *insertData =
114 (ginxlogInsertDataInternal *) payload;
115
116 appendStringInfo(buf, " pitem: %u-%u/%u",
120 }
121 }
122 }
123 break;
124 case XLOG_GIN_SPLIT:
125 {
126 ginxlogSplit *xlrec = (ginxlogSplit *) rec;
127
128 appendStringInfo(buf, "isrootsplit: %c",
129 (((ginxlogSplit *) rec)->flags & GIN_SPLIT_ROOT) ? 'T' : 'F');
130 appendStringInfo(buf, " isdata: %c isleaf: %c",
131 (xlrec->flags & GIN_INSERT_ISDATA) ? 'T' : 'F',
132 (xlrec->flags & GIN_INSERT_ISLEAF) ? 'T' : 'F');
134 appendStringInfo(buf, " children: %u/%u",
135 xlrec->leftChildBlkno, xlrec->rightChildBlkno);
136 }
137 break;
139 /* no further information */
140 break;
142 {
143 if (!XLogRecHasBlockImage(record, 0))
144 {
147
148 desc_recompress_leaf(buf, &xlrec->data);
149 }
150 }
151 break;
153 /* no further information */
154 break;
156 {
157 ginxlogUpdateMeta *xlrec = (ginxlogUpdateMeta *) rec;
158
159 appendStringInfo(buf, "ntuples: %d", xlrec->ntuples);
160 if (xlrec->prevTail != InvalidBlockNumber)
161 appendStringInfo(buf, " prevTail: %u",
162 xlrec->prevTail);
163 if (xlrec->newRightlink != InvalidBlockNumber)
164 appendStringInfo(buf, " newRightLink: %u",
165 xlrec->newRightlink);
166 }
167 break;
169 {
171
172 appendStringInfo(buf, "ntuples: %d", xlrec->ntuples);
173 if (xlrec->rightlink != InvalidBlockNumber)
174 appendStringInfo(buf, " rightlink: %u",
175 xlrec->rightlink);
176 }
177 break;
179 appendStringInfo(buf, "ndeleted: %d",
180 ((ginxlogDeleteListPages *) rec)->ndeleted);
181 break;
182 }
183}
184
185const char *
187{
188 const char *id = NULL;
189
190 switch (info & ~XLR_INFO_MASK)
191 {
193 id = "CREATE_PTREE";
194 break;
195 case XLOG_GIN_INSERT:
196 id = "INSERT";
197 break;
198 case XLOG_GIN_SPLIT:
199 id = "SPLIT";
200 break;
202 id = "VACUUM_PAGE";
203 break;
205 id = "VACUUM_DATA_LEAF_PAGE";
206 break;
208 id = "DELETE_PAGE";
209 break;
211 id = "UPDATE_META_PAGE";
212 break;
214 id = "INSERT_LISTPAGE";
215 break;
217 id = "DELETE_LISTPAGE";
218 break;
219 }
220
221 return id;
222}
uint32 BlockNumber
Definition: block.h:31
struct BlockIdData BlockIdData
#define InvalidBlockNumber
Definition: block.h:33
static BlockNumber BlockIdGetBlockNumber(const BlockIdData *blockId)
Definition: block.h:103
uint8_t uint8
Definition: c.h:541
#define SHORTALIGN(LEN)
Definition: c.h:811
uint16_t uint16
Definition: c.h:542
#define SizeOfGinPostingList(plist)
Definition: ginblock.h:342
#define PostingItemGetBlockNumber(pointer)
Definition: ginblock.h:189
static void desc_recompress_leaf(StringInfo buf, ginxlogRecompressDataLeaf *insertData)
Definition: gindesc.c:21
void gin_desc(StringInfo buf, XLogReaderState *record)
Definition: gindesc.c:72
const char * gin_identify(uint8 info)
Definition: gindesc.c:186
#define GIN_INSERT_ISDATA
Definition: ginxlog.h:124
#define GIN_INSERT_ISLEAF
Definition: ginxlog.h:125
#define XLOG_GIN_UPDATE_META_PAGE
Definition: ginxlog.h:162
#define GIN_SEGMENT_ADDITEMS
Definition: ginxlog.h:95
#define GIN_SEGMENT_DELETE
Definition: ginxlog.h:92
#define GIN_SPLIT_ROOT
Definition: ginxlog.h:126
#define XLOG_GIN_INSERT
Definition: ginxlog.h:35
#define XLOG_GIN_CREATE_PTREE
Definition: ginxlog.h:19
#define XLOG_GIN_VACUUM_PAGE
Definition: ginxlog.h:135
#define XLOG_GIN_DELETE_PAGE
Definition: ginxlog.h:153
#define XLOG_GIN_INSERT_LISTPAGE
Definition: ginxlog.h:180
#define XLOG_GIN_VACUUM_DATA_LEAF_PAGE
Definition: ginxlog.h:141
#define XLOG_GIN_SPLIT
Definition: ginxlog.h:109
#define GIN_SEGMENT_INSERT
Definition: ginxlog.h:93
#define XLOG_GIN_DELETE_LISTPAGE
Definition: ginxlog.h:197
#define GIN_SEGMENT_REPLACE
Definition: ginxlog.h:94
#define nitems(x)
Definition: indent.h:31
int i
Definition: isn.c:77
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
Definition: itemptr.h:124
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
Definition: itemptr.h:103
struct ItemPointerData ItemPointerData
static char * buf
Definition: pg_test_fsync.c:72
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
ItemPointerData key
Definition: ginblock.h:186
BlockNumber rightlink
Definition: ginxlog.h:187
uint16 flags
Definition: ginxlog.h:39
uint16 flags
Definition: ginxlog.h:118
BlockNumber leftChildBlkno
Definition: ginxlog.h:116
BlockNumber rightChildBlkno
Definition: ginxlog.h:117
BlockNumber prevTail
Definition: ginxlog.h:172
BlockNumber newRightlink
Definition: ginxlog.h:173
ginxlogRecompressDataLeaf data
Definition: ginxlog.h:145
char * XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len)
Definition: xlogreader.c:2045
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:409
#define XLogRecGetData(decoder)
Definition: xlogreader.h:414
#define XLogRecHasBlockImage(decoder, block_id)
Definition: xlogreader.h:422
#define XLR_INFO_MASK
Definition: xlogrecord.h:62