1 /*-------------------------------------------------------------------------
2 *
3 * heapdesc.c
4 * rmgr descriptor routines for access/heap/heapam.c
5 *
6 * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/access/rmgrdesc/heapdesc.c
12 *
13 *-------------------------------------------------------------------------
14 */
15 #include "postgres.h"
16
17 #include "access/heapam_xlog.h"
18
19 static void
20 out_infobits(StringInfo buf, uint8 infobits)
21 {
22 if (infobits & XLHL_XMAX_IS_MULTI)
23 appendStringInfoString(buf, "IS_MULTI ");
24 if (infobits & XLHL_XMAX_LOCK_ONLY)
25 appendStringInfoString(buf, "LOCK_ONLY ");
26 if (infobits & XLHL_XMAX_EXCL_LOCK)
27 appendStringInfoString(buf, "EXCL_LOCK ");
28 if (infobits & XLHL_XMAX_KEYSHR_LOCK)
29 appendStringInfoString(buf, "KEYSHR_LOCK ");
30 if (infobits & XLHL_KEYS_UPDATED)
31 appendStringInfoString(buf, "KEYS_UPDATED ");
32 }
33
34 void
35 heap_desc(StringInfo buf, XLogReaderState *record)
36 {
37 char *rec = XLogRecGetData(record);
38 uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
39
40 info &= XLOG_HEAP_OPMASK;
41 if (info == XLOG_HEAP_INSERT)
42 {
43 xl_heap_insert *xlrec = (xl_heap_insert *) rec;
44
45 appendStringInfo(buf, "off %u", xlrec->offnum);
46 }
47 else if (info == XLOG_HEAP_DELETE)
48 {
49 xl_heap_delete *xlrec = (xl_heap_delete *) rec;
50
51 appendStringInfo(buf, "off %u ", xlrec->offnum);
52 out_infobits(buf, xlrec->infobits_set);
53 }
54 else if (info == XLOG_HEAP_UPDATE)
55 {
56 xl_heap_update *xlrec = (xl_heap_update *) rec;
57
58 appendStringInfo(buf, "off %u xmax %u ",
59 xlrec->old_offnum,
gisthandler(PG_FUNCTION_ARGS)60 xlrec->old_xmax);
61 out_infobits(buf, xlrec->old_infobits_set);
62 appendStringInfo(buf, "; new off %u xmax %u",
63 xlrec->new_offnum,
64 xlrec->new_xmax);
65 }
66 else if (info == XLOG_HEAP_HOT_UPDATE)
67 {
68 xl_heap_update *xlrec = (xl_heap_update *) rec;
69
70 appendStringInfo(buf, "off %u xmax %u ",
71 xlrec->old_offnum,
72 xlrec->old_xmax);
73 out_infobits(buf, xlrec->old_infobits_set);
74 appendStringInfo(buf, "; new off %u xmax %u",
75 xlrec->new_offnum,
76 xlrec->new_xmax);
77 }
78 else if (info == XLOG_HEAP_TRUNCATE)
79 {
80 xl_heap_truncate *xlrec = (xl_heap_truncate *) rec;
81 int i;
82
83 if (xlrec->flags & XLH_TRUNCATE_CASCADE)
84 appendStringInfo(buf, "cascade ");
85 if (xlrec->flags & XLH_TRUNCATE_RESTART_SEQS)
86 appendStringInfo(buf, "restart_seqs ");
87 appendStringInfo(buf, "nrelids %u relids", xlrec->nrelids);
88 for (i = 0; i < xlrec->nrelids; i++)
89 appendStringInfo(buf, " %u", xlrec->relids[i]);
90 }
91 else if (info == XLOG_HEAP_CONFIRM)
92 {
93 xl_heap_confirm *xlrec = (xl_heap_confirm *) rec;
94
95 appendStringInfo(buf, "off %u", xlrec->offnum);
96 }
97 else if (info == XLOG_HEAP_LOCK)
98 {
99 xl_heap_lock *xlrec = (xl_heap_lock *) rec;
100
101 appendStringInfo(buf, "off %u: xid %u: flags %u ",
102 xlrec->offnum, xlrec->locking_xid, xlrec->flags);
103 out_infobits(buf, xlrec->infobits_set);
104 }
105 else if (info == XLOG_HEAP_INPLACE)
106 {
107 xl_heap_inplace *xlrec = (xl_heap_inplace *) rec;
108
109 appendStringInfo(buf, "off %u", xlrec->offnum);
110 }
111 }
112 void
113 heap2_desc(StringInfo buf, XLogReaderState *record)
createTempGistContext(void)114 {
115 char *rec = XLogRecGetData(record);
116 uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
117
118 info &= XLOG_HEAP_OPMASK;
119 if (info == XLOG_HEAP2_CLEAN)
120 {
121 xl_heap_clean *xlrec = (xl_heap_clean *) rec;
122
123 appendStringInfo(buf, "remxid %u", xlrec->latestRemovedXid);
124 }
125 else if (info == XLOG_HEAP2_FREEZE_PAGE)
126 {
127 xl_heap_freeze_page *xlrec = (xl_heap_freeze_page *) rec;
128
129 appendStringInfo(buf, "cutoff xid %u ntuples %u",
130 xlrec->cutoff_xid, xlrec->ntuples);
131 }
132 else if (info == XLOG_HEAP2_CLEANUP_INFO)
133 {
134 xl_heap_cleanup_info *xlrec = (xl_heap_cleanup_info *) rec;
135
136 appendStringInfo(buf, "remxid %u", xlrec->latestRemovedXid);
137 }
138 else if (info == XLOG_HEAP2_VISIBLE)
139 {
140 xl_heap_visible *xlrec = (xl_heap_visible *) rec;
141
142 appendStringInfo(buf, "cutoff xid %u flags %d",
143 xlrec->cutoff_xid, xlrec->flags);
144 }
145 else if (info == XLOG_HEAP2_MULTI_INSERT)
146 {
147 xl_heap_multi_insert *xlrec = (xl_heap_multi_insert *) rec;
148
149 appendStringInfo(buf, "%d tuples", xlrec->ntuples);
150 }
151 else if (info == XLOG_HEAP2_LOCK_UPDATED)
152 {
153 xl_heap_lock_updated *xlrec = (xl_heap_lock_updated *) rec;
154
155 appendStringInfo(buf, "off %u: xmax %u: flags %u ",
156 xlrec->offnum, xlrec->xmax, xlrec->flags);
157 out_infobits(buf, xlrec->infobits_set);
158 }
159 else if (info == XLOG_HEAP2_NEW_CID)
160 {
161 xl_heap_new_cid *xlrec = (xl_heap_new_cid *) rec;
162
163 appendStringInfo(buf, "rel %u/%u/%u; tid %u/%u",
164 xlrec->target_node.spcNode,
165 xlrec->target_node.dbNode,
166 xlrec->target_node.relNode,
167 ItemPointerGetBlockNumber(&(xlrec->target_tid)),
168 ItemPointerGetOffsetNumber(&(xlrec->target_tid)));
169 appendStringInfo(buf, "; cmin: %u, cmax: %u, combo: %u",
170 xlrec->cmin, xlrec->cmax, xlrec->combocid);
171 }
172 }
173
174 const char *
175 heap_identify(uint8 info)
176 {
177 const char *id = NULL;
178
179 switch (info & ~XLR_INFO_MASK)
180 {
181 case XLOG_HEAP_INSERT:
182 id = "INSERT";
183 break;
184 case XLOG_HEAP_INSERT | XLOG_HEAP_INIT_PAGE:
185 id = "INSERT+INIT";
186 break;
187 case XLOG_HEAP_DELETE:
188 id = "DELETE";
189 break;
190 case XLOG_HEAP_UPDATE:
191 id = "UPDATE";
192 break;
193 case XLOG_HEAP_UPDATE | XLOG_HEAP_INIT_PAGE:
194 id = "UPDATE+INIT";
195 break;
196 case XLOG_HEAP_HOT_UPDATE:
197 id = "HOT_UPDATE";
198 break;
199 case XLOG_HEAP_HOT_UPDATE | XLOG_HEAP_INIT_PAGE:
200 id = "HOT_UPDATE+INIT";
201 break;
202 case XLOG_HEAP_TRUNCATE:
203 id = "TRUNCATE";
204 break;
205 case XLOG_HEAP_CONFIRM:
206 id = "HEAP_CONFIRM";
207 break;
208 case XLOG_HEAP_LOCK:
209 id = "LOCK";
210 break;
211 case XLOG_HEAP_INPLACE:
212 id = "INPLACE";
213 break;
214 }
215
gistplacetopage(Relation rel,Size freespace,GISTSTATE * giststate,Buffer buffer,IndexTuple * itup,int ntup,OffsetNumber oldoffnum,BlockNumber * newblkno,Buffer leftchildbuf,List ** splitinfo,bool markfollowright,Relation heapRel)216 return id;
217 }
218
219 const char *
220 heap2_identify(uint8 info)
221 {
222 const char *id = NULL;
223
224 switch (info & ~XLR_INFO_MASK)
225 {
226 case XLOG_HEAP2_CLEAN:
227 id = "CLEAN";
228 break;
229 case XLOG_HEAP2_FREEZE_PAGE:
230 id = "FREEZE_PAGE";
231 break;
232 case XLOG_HEAP2_CLEANUP_INFO:
233 id = "CLEANUP_INFO";
234 break;
235 case XLOG_HEAP2_VISIBLE:
236 id = "VISIBLE";
237 break;
238 case XLOG_HEAP2_MULTI_INSERT:
239 id = "MULTI_INSERT";
240 break;
241 case XLOG_HEAP2_MULTI_INSERT | XLOG_HEAP_INIT_PAGE:
242 id = "MULTI_INSERT+INIT";
243 break;
244 case XLOG_HEAP2_LOCK_UPDATED:
245 id = "LOCK_UPDATED";
246 break;
247 case XLOG_HEAP2_NEW_CID:
248 id = "NEW_CID";
249 break;
250 case XLOG_HEAP2_REWRITE:
251 id = "REWRITE";
252 break;
253 }
254
255 return id;
256 }
257