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-2024, 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 
20 static 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;
54  case GIN_SEGMENT_DELETE:
55  appendStringInfo(buf, " %d (delete)", a_segno);
56  break;
57  case GIN_SEGMENT_INSERT:
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 
71 void
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  if (XLogRecBlockImageApply(record, 0))
105  appendStringInfoString(buf, " (full page image)");
106  else
107  appendStringInfoString(buf, " (full page image, for WAL verification)");
108  }
109  else
110  {
111  char *payload = XLogRecGetBlockData(record, 0, NULL);
112 
113  if (!(xlrec->flags & GIN_INSERT_ISDATA))
114  appendStringInfo(buf, " isdelete: %c",
115  (((ginxlogInsertEntry *) payload)->isDelete) ? 'T' : 'F');
116  else if (xlrec->flags & GIN_INSERT_ISLEAF)
118  else
119  {
120  ginxlogInsertDataInternal *insertData =
121  (ginxlogInsertDataInternal *) payload;
122 
123  appendStringInfo(buf, " pitem: %u-%u/%u",
124  PostingItemGetBlockNumber(&insertData->newitem),
125  ItemPointerGetBlockNumber(&insertData->newitem.key),
126  ItemPointerGetOffsetNumber(&insertData->newitem.key));
127  }
128  }
129  }
130  break;
131  case XLOG_GIN_SPLIT:
132  {
133  ginxlogSplit *xlrec = (ginxlogSplit *) rec;
134 
135  appendStringInfo(buf, "isrootsplit: %c",
136  (((ginxlogSplit *) rec)->flags & GIN_SPLIT_ROOT) ? 'T' : 'F');
137  appendStringInfo(buf, " isdata: %c isleaf: %c",
138  (xlrec->flags & GIN_INSERT_ISDATA) ? 'T' : 'F',
139  (xlrec->flags & GIN_INSERT_ISLEAF) ? 'T' : 'F');
140  }
141  break;
143  /* no further information */
144  break;
146  {
147  if (XLogRecHasBlockImage(record, 0))
148  {
149  if (XLogRecBlockImageApply(record, 0))
150  appendStringInfoString(buf, " (full page image)");
151  else
152  appendStringInfoString(buf, " (full page image, for WAL verification)");
153  }
154  else
155  {
157  (ginxlogVacuumDataLeafPage *) XLogRecGetBlockData(record, 0, NULL);
158 
159  desc_recompress_leaf(buf, &xlrec->data);
160  }
161  }
162  break;
164  /* no further information */
165  break;
167  /* no further information */
168  break;
170  /* no further information */
171  break;
173  appendStringInfo(buf, "ndeleted: %d",
174  ((ginxlogDeleteListPages *) rec)->ndeleted);
175  break;
176  }
177 }
178 
179 const char *
181 {
182  const char *id = NULL;
183 
184  switch (info & ~XLR_INFO_MASK)
185  {
187  id = "CREATE_PTREE";
188  break;
189  case XLOG_GIN_INSERT:
190  id = "INSERT";
191  break;
192  case XLOG_GIN_SPLIT:
193  id = "SPLIT";
194  break;
196  id = "VACUUM_PAGE";
197  break;
199  id = "VACUUM_DATA_LEAF_PAGE";
200  break;
202  id = "DELETE_PAGE";
203  break;
205  id = "UPDATE_META_PAGE";
206  break;
208  id = "INSERT_LISTPAGE";
209  break;
211  id = "DELETE_LISTPAGE";
212  break;
213  }
214 
215  return id;
216 }
uint32 BlockNumber
Definition: block.h:31
struct BlockIdData BlockIdData
static BlockNumber BlockIdGetBlockNumber(const BlockIdData *blockId)
Definition: block.h:103
unsigned short uint16
Definition: c.h:505
#define SHORTALIGN(LEN)
Definition: c.h:807
unsigned char uint8
Definition: c.h:504
#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:180
#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:194
#define GIN_SEGMENT_REPLACE
Definition: ginxlog.h:94
#define nitems(x)
Definition: indent.h:31
int i
Definition: isn.c:73
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:73
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:182
ItemPointerData key
Definition: ginblock.h:186
uint16 flags
Definition: ginxlog.h:39
uint16 flags
Definition: ginxlog.h:118
ginxlogRecompressDataLeaf data
Definition: ginxlog.h:145
char * XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len)
Definition: xlogreader.c:2025
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:410
#define XLogRecBlockImageApply(decoder, block_id)
Definition: xlogreader.h:425
#define XLogRecGetData(decoder)
Definition: xlogreader.h:415
#define XLogRecHasBlockImage(decoder, block_id)
Definition: xlogreader.h:423
#define XLR_INFO_MASK
Definition: xlogrecord.h:62