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-2019, 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/relfilenode.h"
21 
22 static void
24 {
25  int i;
26  char *walbuf = ((char *) insertData) + sizeof(ginxlogRecompressDataLeaf);
27 
28  appendStringInfo(buf, " %d segments:", (int) insertData->nactions);
29 
30  for (i = 0; i < insertData->nactions; i++)
31  {
32  uint8 a_segno = *((uint8 *) (walbuf++));
33  uint8 a_action = *((uint8 *) (walbuf++));
34  uint16 nitems = 0;
35  int newsegsize = 0;
36 
37  if (a_action == GIN_SEGMENT_INSERT ||
38  a_action == GIN_SEGMENT_REPLACE)
39  {
40  newsegsize = SizeOfGinPostingList((GinPostingList *) walbuf);
41  walbuf += SHORTALIGN(newsegsize);
42  }
43 
44  if (a_action == GIN_SEGMENT_ADDITEMS)
45  {
46  memcpy(&nitems, walbuf, sizeof(uint16));
47  walbuf += sizeof(uint16);
48  walbuf += nitems * sizeof(ItemPointerData);
49  }
50 
51  switch (a_action)
52  {
54  appendStringInfo(buf, " %d (add %d items)", a_segno, nitems);
55  break;
56  case GIN_SEGMENT_DELETE:
57  appendStringInfo(buf, " %d (delete)", a_segno);
58  break;
59  case GIN_SEGMENT_INSERT:
60  appendStringInfo(buf, " %d (insert)", a_segno);
61  break;
63  appendStringInfo(buf, " %d (replace)", a_segno);
64  break;
65  default:
66  appendStringInfo(buf, " %d unknown action %d ???", a_segno, a_action);
67  /* cannot decode unrecognized actions further */
68  return;
69  }
70  }
71 }
72 
73 void
75 {
76  char *rec = XLogRecGetData(record);
77  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
78 
79  switch (info)
80  {
82  /* no further information */
83  break;
84  case XLOG_GIN_INSERT:
85  {
86  ginxlogInsert *xlrec = (ginxlogInsert *) rec;
87 
88  appendStringInfo(buf, "isdata: %c isleaf: %c",
89  (xlrec->flags & GIN_INSERT_ISDATA) ? 'T' : 'F',
90  (xlrec->flags & GIN_INSERT_ISLEAF) ? 'T' : 'F');
91  if (!(xlrec->flags & GIN_INSERT_ISLEAF))
92  {
93  char *payload = rec + sizeof(ginxlogInsert);
94  BlockNumber leftChildBlkno;
95  BlockNumber rightChildBlkno;
96 
97  leftChildBlkno = BlockIdGetBlockNumber((BlockId) payload);
98  payload += sizeof(BlockIdData);
99  rightChildBlkno = BlockIdGetBlockNumber((BlockId) payload);
100  payload += sizeof(BlockNumber);
101  appendStringInfo(buf, " children: %u/%u",
102  leftChildBlkno, rightChildBlkno);
103  }
104  if (XLogRecHasBlockImage(record, 0))
105  {
106  if (XLogRecBlockImageApply(record, 0))
107  appendStringInfoString(buf, " (full page image)");
108  else
109  appendStringInfoString(buf, " (full page image, for WAL verification)");
110  }
111  else
112  {
113  char *payload = XLogRecGetBlockData(record, 0, NULL);
114 
115  if (!(xlrec->flags & GIN_INSERT_ISDATA))
116  appendStringInfo(buf, " isdelete: %c",
117  (((ginxlogInsertEntry *) payload)->isDelete) ? 'T' : 'F');
118  else if (xlrec->flags & GIN_INSERT_ISLEAF)
120  else
121  {
122  ginxlogInsertDataInternal *insertData =
123  (ginxlogInsertDataInternal *) payload;
124 
125  appendStringInfo(buf, " pitem: %u-%u/%u",
126  PostingItemGetBlockNumber(&insertData->newitem),
127  ItemPointerGetBlockNumber(&insertData->newitem.key),
128  ItemPointerGetOffsetNumber(&insertData->newitem.key));
129  }
130  }
131  }
132  break;
133  case XLOG_GIN_SPLIT:
134  {
135  ginxlogSplit *xlrec = (ginxlogSplit *) rec;
136 
137  appendStringInfo(buf, "isrootsplit: %c",
138  (((ginxlogSplit *) rec)->flags & GIN_SPLIT_ROOT) ? 'T' : 'F');
139  appendStringInfo(buf, " isdata: %c isleaf: %c",
140  (xlrec->flags & GIN_INSERT_ISDATA) ? 'T' : 'F',
141  (xlrec->flags & GIN_INSERT_ISLEAF) ? 'T' : 'F');
142  }
143  break;
145  /* no further information */
146  break;
148  {
149  if (XLogRecHasBlockImage(record, 0))
150  {
151  if (XLogRecBlockImageApply(record, 0))
152  appendStringInfoString(buf, " (full page image)");
153  else
154  appendStringInfoString(buf, " (full page image, for WAL verification)");
155  }
156  else
157  {
159  (ginxlogVacuumDataLeafPage *) XLogRecGetBlockData(record, 0, NULL);
160 
161  desc_recompress_leaf(buf, &xlrec->data);
162  }
163  }
164  break;
166  /* no further information */
167  break;
169  /* no further information */
170  break;
172  /* no further information */
173  break;
175  appendStringInfo(buf, "ndeleted: %d",
176  ((ginxlogDeleteListPages *) rec)->ndeleted);
177  break;
178  }
179 }
180 
181 const char *
183 {
184  const char *id = NULL;
185 
186  switch (info & ~XLR_INFO_MASK)
187  {
189  id = "CREATE_PTREE";
190  break;
191  case XLOG_GIN_INSERT:
192  id = "INSERT";
193  break;
194  case XLOG_GIN_SPLIT:
195  id = "SPLIT";
196  break;
198  id = "VACUUM_PAGE";
199  break;
201  id = "VACUUM_DATA_LEAF_PAGE";
202  break;
204  id = "DELETE_PAGE";
205  break;
207  id = "UPDATE_META_PAGE";
208  break;
210  id = "INSERT_LISTPAGE";
211  break;
213  id = "DELETE_LISTPAGE";
214  break;
215  }
216 
217  return id;
218 }
#define BlockIdGetBlockNumber(blockId)
Definition: block.h:115
#define XLogRecHasBlockImage(decoder, block_id)
Definition: xlogreader.h:251
unsigned char uint8
Definition: c.h:356
uint32 BlockNumber
Definition: block.h:31
#define GIN_SPLIT_ROOT
Definition: ginxlog.h:126
#define GIN_INSERT_ISLEAF
Definition: ginxlog.h:125
uint16 flags
Definition: ginxlog.h:39
ginxlogRecompressDataLeaf data
Definition: ginxlog.h:145
#define GIN_SEGMENT_INSERT
Definition: ginxlog.h:93
#define XLOG_GIN_INSERT_LISTPAGE
Definition: ginxlog.h:180
unsigned short uint16
Definition: c.h:357
#define XLogRecGetData(decoder)
Definition: xlogreader.h:246
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define GIN_SEGMENT_REPLACE
Definition: ginxlog.h:94
#define XLOG_GIN_CREATE_PTREE
Definition: ginxlog.h:19
#define XLOG_GIN_UPDATE_META_PAGE
Definition: ginxlog.h:162
static void desc_recompress_leaf(StringInfo buf, ginxlogRecompressDataLeaf *insertData)
Definition: gindesc.c:23
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
#define GIN_INSERT_ISDATA
Definition: ginxlog.h:124
const char * gin_identify(uint8 info)
Definition: gindesc.c:182
static char * buf
Definition: pg_test_fsync.c:68
#define GIN_SEGMENT_ADDITEMS
Definition: ginxlog.h:95
#define GIN_SEGMENT_DELETE
Definition: ginxlog.h:92
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:242
#define XLOG_GIN_VACUUM_DATA_LEAF_PAGE
Definition: ginxlog.h:141
void gin_desc(StringInfo buf, XLogReaderState *record)
Definition: gindesc.c:74
#define XLOG_GIN_VACUUM_PAGE
Definition: ginxlog.h:135
char * XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len)
Definition: xlogreader.c:1391
ItemPointerData key
Definition: ginblock.h:187
struct BlockIdData BlockIdData
#define PostingItemGetBlockNumber(pointer)
Definition: ginblock.h:190
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
struct ItemPointerData ItemPointerData
#define ItemPointerGetOffsetNumber(pointer)
Definition: itemptr.h:117
#define XLOG_GIN_INSERT
Definition: ginxlog.h:35
#define SizeOfGinPostingList(plist)
Definition: ginblock.h:343
int i
#define XLogRecBlockImageApply(decoder, block_id)
Definition: xlogreader.h:253
#define ItemPointerGetBlockNumber(pointer)
Definition: itemptr.h:98
#define SHORTALIGN(LEN)
Definition: c.h:681
#define XLOG_GIN_DELETE_PAGE
Definition: ginxlog.h:153
uint16 flags
Definition: ginxlog.h:118
#define XLOG_GIN_SPLIT
Definition: ginxlog.h:109
#define XLOG_GIN_DELETE_LISTPAGE
Definition: ginxlog.h:194