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