PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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-2017, 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;
85  /* no further information */
86  break;
87  case XLOG_GIN_INSERT:
88  {
89  ginxlogInsert *xlrec = (ginxlogInsert *) rec;
90 
91  appendStringInfo(buf, "isdata: %c isleaf: %c",
92  (xlrec->flags & GIN_INSERT_ISDATA) ? 'T' : 'F',
93  (xlrec->flags & GIN_INSERT_ISLEAF) ? 'T' : 'F');
94  if (!(xlrec->flags & GIN_INSERT_ISLEAF))
95  {
96  char *payload = rec + sizeof(ginxlogInsert);
97  BlockNumber leftChildBlkno;
98  BlockNumber rightChildBlkno;
99 
100  leftChildBlkno = BlockIdGetBlockNumber((BlockId) payload);
101  payload += sizeof(BlockIdData);
102  rightChildBlkno = BlockIdGetBlockNumber((BlockId) payload);
103  payload += sizeof(BlockNumber);
104  appendStringInfo(buf, " children: %u/%u",
105  leftChildBlkno, rightChildBlkno);
106  }
107  if (XLogRecHasBlockImage(record, 0))
108  {
109  if (XLogRecBlockImageApply(record, 0))
110  appendStringInfoString(buf, " (full page image)");
111  else
112  appendStringInfoString(buf, " (full page image, for WAL verification)");
113  }
114  else
115  {
116  char *payload = XLogRecGetBlockData(record, 0, NULL);
117 
118  if (!(xlrec->flags & GIN_INSERT_ISDATA))
119  appendStringInfo(buf, " isdelete: %c",
120  (((ginxlogInsertEntry *) payload)->isDelete) ? 'T' : 'F');
121  else if (xlrec->flags & GIN_INSERT_ISLEAF)
123  else
124  {
125  ginxlogInsertDataInternal *insertData =
126  (ginxlogInsertDataInternal *) payload;
127 
128  appendStringInfo(buf, " pitem: %u-%u/%u",
129  PostingItemGetBlockNumber(&insertData->newitem),
130  ItemPointerGetBlockNumber(&insertData->newitem.key),
131  ItemPointerGetOffsetNumber(&insertData->newitem.key));
132  }
133  }
134  }
135  break;
136  case XLOG_GIN_SPLIT:
137  {
138  ginxlogSplit *xlrec = (ginxlogSplit *) rec;
139 
140  appendStringInfo(buf, "isrootsplit: %c",
141  (((ginxlogSplit *) rec)->flags & GIN_SPLIT_ROOT) ? 'T' : 'F');
142  appendStringInfo(buf, " isdata: %c isleaf: %c",
143  (xlrec->flags & GIN_INSERT_ISDATA) ? 'T' : 'F',
144  (xlrec->flags & GIN_INSERT_ISLEAF) ? 'T' : 'F');
145  }
146  break;
148  /* no further information */
149  break;
151  {
152  if (XLogRecHasBlockImage(record, 0))
153  {
154  if (XLogRecBlockImageApply(record, 0))
155  appendStringInfoString(buf, " (full page image)");
156  else
157  appendStringInfoString(buf, " (full page image, for WAL verification)");
158  }
159  else
160  {
163 
164  desc_recompress_leaf(buf, &xlrec->data);
165  }
166  }
167  break;
169  /* no further information */
170  break;
172  /* no further information */
173  break;
175  /* no further information */
176  break;
178  appendStringInfo(buf, "ndeleted: %d",
179  ((ginxlogDeleteListPages *) rec)->ndeleted);
180  break;
181  }
182 }
183 
184 const char *
186 {
187  const char *id = NULL;
188 
189  switch (info & ~XLR_INFO_MASK)
190  {
192  id = "CREATE_INDEX";
193  break;
195  id = "CREATE_PTREE";
196  break;
197  case XLOG_GIN_INSERT:
198  id = "INSERT";
199  break;
200  case XLOG_GIN_SPLIT:
201  id = "SPLIT";
202  break;
204  id = "VACUUM_PAGE";
205  break;
207  id = "VACUUM_DATA_LEAF_PAGE";
208  break;
210  id = "DELETE_PAGE";
211  break;
213  id = "UPDATE_META_PAGE";
214  break;
216  id = "INSERT_LISTPAGE";
217  break;
219  id = "DELETE_LISTPAGE";
220  break;
221  }
222 
223  return id;
224 }
#define BlockIdGetBlockNumber(blockId)
Definition: block.h:115
#define XLogRecHasBlockImage(decoder, block_id)
Definition: xlogreader.h:223
unsigned char uint8
Definition: c.h:266
uint32 BlockNumber
Definition: block.h:31
#define GIN_SPLIT_ROOT
Definition: ginxlog.h:128
#define GIN_INSERT_ISLEAF
Definition: ginxlog.h:127
uint16 flags
Definition: ginxlog.h:41
ginxlogRecompressDataLeaf data
Definition: ginxlog.h:147
#define GIN_SEGMENT_INSERT
Definition: ginxlog.h:95
#define XLOG_GIN_INSERT_LISTPAGE
Definition: ginxlog.h:181
unsigned short uint16
Definition: c.h:267
#define XLogRecGetData(decoder)
Definition: xlogreader.h:218
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
#define GIN_SEGMENT_REPLACE
Definition: ginxlog.h:96
#define XLOG_GIN_CREATE_PTREE
Definition: ginxlog.h:21
#define XLOG_GIN_UPDATE_META_PAGE
Definition: ginxlog.h:163
static void desc_recompress_leaf(StringInfo buf, ginxlogRecompressDataLeaf *insertData)
Definition: gindesc.c:23
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
#define GIN_INSERT_ISDATA
Definition: ginxlog.h:126
const char * gin_identify(uint8 info)
Definition: gindesc.c:185
static char * buf
Definition: pg_test_fsync.c:65
#define GIN_SEGMENT_ADDITEMS
Definition: ginxlog.h:97
#define GIN_SEGMENT_DELETE
Definition: ginxlog.h:94
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:214
#define XLOG_GIN_CREATE_INDEX
Definition: ginxlog.h:19
#define XLOG_GIN_VACUUM_DATA_LEAF_PAGE
Definition: ginxlog.h:143
void gin_desc(StringInfo buf, XLogReaderState *record)
Definition: gindesc.c:74
#define XLOG_GIN_VACUUM_PAGE
Definition: ginxlog.h:137
char * XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len)
Definition: xlogreader.c:1331
ItemPointerData key
Definition: ginblock.h:173
struct BlockIdData BlockIdData
#define PostingItemGetBlockNumber(pointer)
Definition: ginblock.h:176
#define NULL
Definition: c.h:229
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
struct ItemPointerData ItemPointerData
#define ItemPointerGetOffsetNumber(pointer)
Definition: itemptr.h:76
#define XLOG_GIN_INSERT
Definition: ginxlog.h:37
#define SizeOfGinPostingList(plist)
Definition: ginblock.h:326
int i
#define XLogRecBlockImageApply(decoder, block_id)
Definition: xlogreader.h:225
#define ItemPointerGetBlockNumber(pointer)
Definition: itemptr.h:66
#define SHORTALIGN(LEN)
Definition: c.h:584
#define XLOG_GIN_DELETE_PAGE
Definition: ginxlog.h:155
uint16 flags
Definition: ginxlog.h:120
#define XLOG_GIN_SPLIT
Definition: ginxlog.h:111
#define XLOG_GIN_DELETE_LISTPAGE
Definition: ginxlog.h:195