Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * nbtdesc.c
4 : : * rmgr descriptor routines for access/nbtree/nbtxlog.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/nbtdesc.c
12 : : *
13 : : *-------------------------------------------------------------------------
14 : : */
15 : : #include "postgres.h"
16 : :
17 : : #include "access/nbtxlog.h"
18 : : #include "access/rmgrdesc_utils.h"
19 : :
20 : : static void delvacuum_desc(StringInfo buf, char *block_data,
21 : : uint16 ndeleted, uint16 nupdated);
22 : :
23 : : void
3433 heikki.linnakangas@i 24 :CBC 38262 : btree_desc(StringInfo buf, XLogReaderState *record)
25 : : {
3592 26 : 38262 : char *rec = XLogRecGetData(record);
3433 27 : 38262 : uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
28 : :
4155 alvherre@alvh.no-ip. 29 [ + + + + : 38262 : switch (info)
+ + + + -
+ - ]
30 : : {
31 : 37778 : case XLOG_BTREE_INSERT_LEAF:
32 : : case XLOG_BTREE_INSERT_UPPER:
33 : : case XLOG_BTREE_INSERT_META:
34 : : case XLOG_BTREE_INSERT_POST:
35 : : {
36 : 37778 : xl_btree_insert *xlrec = (xl_btree_insert *) rec;
37 : :
373 pg@bowt.ie 38 : 37778 : appendStringInfo(buf, "off: %u", xlrec->offnum);
4155 alvherre@alvh.no-ip. 39 : 37778 : break;
40 : : }
41 : 126 : case XLOG_BTREE_SPLIT_L:
42 : : case XLOG_BTREE_SPLIT_R:
43 : : {
44 : 126 : xl_btree_split *xlrec = (xl_btree_split *) rec;
45 : :
373 pg@bowt.ie 46 : 126 : appendStringInfo(buf, "level: %u, firstrightoff: %d, newitemoff: %d, postingoff: %d",
1462 47 : 126 : xlrec->level, xlrec->firstrightoff,
1509 48 : 126 : xlrec->newitemoff, xlrec->postingoff);
49 : 126 : break;
50 : : }
1509 pg@bowt.ie 51 :GBC 106 : case XLOG_BTREE_DEDUP:
52 : : {
53 : 106 : xl_btree_dedup *xlrec = (xl_btree_dedup *) rec;
54 : :
373 55 : 106 : appendStringInfo(buf, "nintervals: %u", xlrec->nintervals);
4155 alvherre@alvh.no-ip. 56 : 106 : break;
57 : : }
4155 alvherre@alvh.no-ip. 58 :CBC 123 : case XLOG_BTREE_VACUUM:
59 : : {
60 : 123 : xl_btree_vacuum *xlrec = (xl_btree_vacuum *) rec;
61 : :
373 pg@bowt.ie 62 : 123 : appendStringInfo(buf, "ndeleted: %u, nupdated: %u",
1509 63 : 123 : xlrec->ndeleted, xlrec->nupdated);
64 : :
361 65 [ + - ]: 123 : if (XLogRecHasBlockData(record, 0))
370 66 : 123 : delvacuum_desc(buf, XLogRecGetBlockData(record, 0, NULL),
373 67 : 123 : xlrec->ndeleted, xlrec->nupdated);
4155 alvherre@alvh.no-ip. 68 : 123 : break;
69 : : }
4155 alvherre@alvh.no-ip. 70 :GBC 18 : case XLOG_BTREE_DELETE:
71 : : {
72 : 18 : xl_btree_delete *xlrec = (xl_btree_delete *) rec;
73 : :
115 msawada@postgresql.o 74 :UNC 0 : appendStringInfo(buf, "snapshotConflictHorizon: %u, ndeleted: %u, nupdated: %u, isCatalogRel: %c",
75 : : xlrec->snapshotConflictHorizon,
115 msawada@postgresql.o 76 :GNC 18 : xlrec->ndeleted, xlrec->nupdated,
77 [ - + ]: 18 : xlrec->isCatalogRel ? 'T' : 'F');
78 : :
361 pg@bowt.ie 79 [ + - ]:GBC 18 : if (XLogRecHasBlockData(record, 0))
370 80 : 18 : delvacuum_desc(buf, XLogRecGetBlockData(record, 0, NULL),
373 81 : 18 : xlrec->ndeleted, xlrec->nupdated);
4155 alvherre@alvh.no-ip. 82 : 18 : break;
83 : : }
3684 heikki.linnakangas@i 84 :CBC 2 : case XLOG_BTREE_MARK_PAGE_HALFDEAD:
85 : : {
86 : 2 : xl_btree_mark_page_halfdead *xlrec = (xl_btree_mark_page_halfdead *) rec;
87 : :
370 pg@bowt.ie 88 : 2 : appendStringInfo(buf, "topparent: %u, leaf: %u, left: %u, right: %u",
89 : : xlrec->topparent, xlrec->leafblk, xlrec->leftblk, xlrec->rightblk);
3684 heikki.linnakangas@i 90 : 2 : break;
91 : : }
92 : 2 : case XLOG_BTREE_UNLINK_PAGE_META:
93 : : case XLOG_BTREE_UNLINK_PAGE:
94 : : {
95 : 2 : xl_btree_unlink_page *xlrec = (xl_btree_unlink_page *) rec;
96 : :
370 pg@bowt.ie 97 : 2 : appendStringInfo(buf, "left: %u, right: %u, level: %u, safexid: %u:%u, ",
98 : : xlrec->leftsib, xlrec->rightsib, xlrec->level,
1145 99 : 2 : EpochFromFullTransactionId(xlrec->safexid),
100 : 2 : XidFromFullTransactionId(xlrec->safexid));
370 101 : 2 : appendStringInfo(buf, "leafleft: %u, leafright: %u, leaftopparent: %u",
102 : : xlrec->leafleftsib, xlrec->leafrightsib,
103 : : xlrec->leaftopparent);
4155 alvherre@alvh.no-ip. 104 : 2 : break;
105 : : }
4155 alvherre@alvh.no-ip. 106 :GBC 106 : case XLOG_BTREE_NEWROOT:
107 : : {
108 : 106 : xl_btree_newroot *xlrec = (xl_btree_newroot *) rec;
109 : :
361 pg@bowt.ie 110 : 106 : appendStringInfo(buf, "level: %u", xlrec->level);
4155 alvherre@alvh.no-ip. 111 : 106 : break;
112 : : }
4155 alvherre@alvh.no-ip. 113 :UBC 0 : case XLOG_BTREE_REUSE_PAGE:
114 : : {
115 : 0 : xl_btree_reuse_page *xlrec = (xl_btree_reuse_page *) rec;
116 : :
115 msawada@postgresql.o 117 :UNC 0 : appendStringInfo(buf, "rel: %u/%u/%u, snapshotConflictHorizon: %u:%u, isCatalogRel: %c",
118 : : xlrec->locator.spcOid, xlrec->locator.dbOid,
119 : : xlrec->locator.relNumber,
514 pg@bowt.ie 120 :UBC 0 : EpochFromFullTransactionId(xlrec->snapshotConflictHorizon),
115 msawada@postgresql.o 121 :UNC 0 : XidFromFullTransactionId(xlrec->snapshotConflictHorizon),
122 [ # # ]: 0 : xlrec->isCatalogRel ? 'T' : 'F');
4155 alvherre@alvh.no-ip. 123 :UBC 0 : break;
124 : : }
2187 teodor@sigaev.ru 125 :CBC 1 : case XLOG_BTREE_META_CLEANUP:
126 : : {
127 : : xl_btree_metadata *xlrec;
128 : :
1761 michael@paquier.xyz 129 : 1 : xlrec = (xl_btree_metadata *) XLogRecGetBlockData(record, 0,
130 : : NULL);
373 pg@bowt.ie 131 : 1 : appendStringInfo(buf, "last_cleanup_num_delpages: %u",
132 : : xlrec->last_cleanup_num_delpages);
2187 teodor@sigaev.ru 133 : 1 : break;
134 : : }
135 : : }
3495 andres@anarazel.de 136 : 38262 : }
137 : :
138 : : const char *
139 : 38268 : btree_identify(uint8 info)
140 : : {
141 : 38268 : const char *id = NULL;
142 : :
3492 143 [ + + - + : 38268 : switch (info & ~XLR_INFO_MASK)
+ - + + +
+ + + + -
+ - ]
144 : : {
3495 145 : 37675 : case XLOG_BTREE_INSERT_LEAF:
146 : 37675 : id = "INSERT_LEAF";
147 : 37675 : break;
148 : 105 : case XLOG_BTREE_INSERT_UPPER:
149 : 105 : id = "INSERT_UPPER";
150 : 105 : break;
3495 andres@anarazel.de 151 :UBC 0 : case XLOG_BTREE_INSERT_META:
152 : 0 : id = "INSERT_META";
153 : 0 : break;
3495 andres@anarazel.de 154 :GBC 35 : case XLOG_BTREE_SPLIT_L:
155 : 35 : id = "SPLIT_L";
156 : 35 : break;
3495 andres@anarazel.de 157 :CBC 93 : case XLOG_BTREE_SPLIT_R:
158 : 93 : id = "SPLIT_R";
159 : 93 : break;
1509 pg@bowt.ie 160 :UBC 0 : case XLOG_BTREE_INSERT_POST:
161 : 0 : id = "INSERT_POST";
162 : 0 : break;
1509 pg@bowt.ie 163 :GBC 106 : case XLOG_BTREE_DEDUP:
164 : 106 : id = "DEDUP";
165 : 106 : break;
3495 andres@anarazel.de 166 :CBC 124 : case XLOG_BTREE_VACUUM:
167 : 124 : id = "VACUUM";
168 : 124 : break;
3495 andres@anarazel.de 169 :GBC 18 : case XLOG_BTREE_DELETE:
170 : 18 : id = "DELETE";
171 : 18 : break;
3495 andres@anarazel.de 172 :CBC 2 : case XLOG_BTREE_MARK_PAGE_HALFDEAD:
173 : 2 : id = "MARK_PAGE_HALFDEAD";
174 : 2 : break;
175 : 1 : case XLOG_BTREE_UNLINK_PAGE:
176 : 1 : id = "UNLINK_PAGE";
177 : 1 : break;
178 : 1 : case XLOG_BTREE_UNLINK_PAGE_META:
179 : 1 : id = "UNLINK_PAGE_META";
180 : 1 : break;
3495 andres@anarazel.de 181 :GBC 107 : case XLOG_BTREE_NEWROOT:
182 : 107 : id = "NEWROOT";
183 : 107 : break;
3495 andres@anarazel.de 184 :UBC 0 : case XLOG_BTREE_REUSE_PAGE:
185 : 0 : id = "REUSE_PAGE";
4155 alvherre@alvh.no-ip. 186 : 0 : break;
2187 teodor@sigaev.ru 187 :CBC 1 : case XLOG_BTREE_META_CLEANUP:
188 : 1 : id = "META_CLEANUP";
189 : 1 : break;
190 : : }
191 : :
3495 andres@anarazel.de 192 : 38268 : return id;
193 : : }
194 : :
195 : : static void
370 pg@bowt.ie 196 : 141 : delvacuum_desc(StringInfo buf, char *block_data,
197 : : uint16 ndeleted, uint16 nupdated)
198 : : {
199 : : OffsetNumber *deletedoffsets;
200 : : OffsetNumber *updatedoffsets;
201 : : xl_btree_update *updates;
202 : :
203 : : /* Output deleted page offset number array */
204 : 141 : appendStringInfoString(buf, ", deleted:");
205 : 141 : deletedoffsets = (OffsetNumber *) block_data;
206 : 141 : array_desc(buf, deletedoffsets, sizeof(OffsetNumber), ndeleted,
207 : : &offset_elem_desc, NULL);
208 : :
209 : : /*
210 : : * Output updates as an array of "update objects", where each element
211 : : * contains a page offset number from updated array. (This is not the
212 : : * most literal representation of the underlying physical data structure
213 : : * that we could use. Readability seems more important here.)
214 : : */
215 : 141 : appendStringInfoString(buf, ", updated: [");
216 : 141 : updatedoffsets = (OffsetNumber *) (block_data + ndeleted *
217 : : sizeof(OffsetNumber));
218 : 141 : updates = (xl_btree_update *) ((char *) updatedoffsets +
219 : 141 : nupdated *
220 : : sizeof(OffsetNumber));
221 [ + + ]: 595 : for (int i = 0; i < nupdated; i++)
222 : : {
370 pg@bowt.ie 223 :GBC 454 : OffsetNumber off = updatedoffsets[i];
224 : :
225 [ + - + - : 454 : Assert(OffsetNumberIsValid(off));
- + ]
226 [ - + ]: 454 : Assert(updates->ndeletedtids > 0);
227 : :
228 : : /*
229 : : * "ptid" is the symbol name used when building each xl_btree_update's
230 : : * array of offsets into a posting list tuple's ItemPointerData array.
231 : : * xl_btree_update describes a subset of the existing TIDs to delete.
232 : : */
233 : 454 : appendStringInfo(buf, "{ off: %u, nptids: %u, ptids: [",
234 : 454 : off, updates->ndeletedtids);
235 [ + + ]: 1060 : for (int p = 0; p < updates->ndeletedtids; p++)
236 : : {
237 : : uint16 *ptid;
238 : :
239 : 606 : ptid = (uint16 *) ((char *) updates + SizeOfBtreeUpdate) + p;
240 : 606 : appendStringInfo(buf, "%u", *ptid);
241 : :
242 [ + + ]: 606 : if (p < updates->ndeletedtids - 1)
243 : 152 : appendStringInfoString(buf, ", ");
244 : : }
245 : 454 : appendStringInfoString(buf, "] }");
246 [ + + ]: 454 : if (i < nupdated - 1)
247 : 434 : appendStringInfoString(buf, ", ");
248 : :
249 : 454 : updates = (xl_btree_update *)
250 : 454 : ((char *) updates + SizeOfBtreeUpdate +
251 : 454 : updates->ndeletedtids * sizeof(uint16));
252 : : }
194 drowley@postgresql.o 253 :GNC 141 : appendStringInfoChar(buf, ']');
370 pg@bowt.ie 254 :CBC 141 : }
|