Skip to content

Commit 5d6728e

Browse files
Fix nbtree posting list update desc output.
We cannot use the generic array_desc approach with per-tuple nbtree posting list update metadata because array_desc can only deal with fixed width elements (e.g., page offset numbers). Using array_desc led to incorrect rmgr descriptions for updates from nbtree DELETE/VACUUM WAL records. To fix, add specialized code to describe the update metadata as array elements in desc output. We now iterate over the update metadata using an approach that matches related REDO routines. Also stop showing the updates offset number array separately in nbtree DELETE/VACUUM desc output. It's redundant information, since the same page offset numbers appear in the description of each individual update element. Also make some small tweaks to the way that we format arrays in all desc routines (not just nbtree desc routines) to make arrays a little less verbose. Oversight in commit 1c453cf, which enhanced the nbtree rmgr desc routines. Author: Peter Geoghegan <pg@bowt.ie> Discussion: https://postgr.es/m/CAH2-WzkbYuvwYKm-Y-72QEh6SPMQcAo9uONv+mR3bMGcu9E_Cg@mail.gmail.com
1 parent fbbd7ed commit 5d6728e

File tree

5 files changed

+87
-98
lines changed

5 files changed

+87
-98
lines changed

doc/src/sgml/pgwalinspect.sgml

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -71,19 +71,19 @@
7171
after the <replaceable>in_lsn</replaceable> argument. For
7272
example:
7373
<screen>
74-
postgres=# SELECT * FROM pg_get_wal_record_info('0/E84F5E8');
75-
-[ RECORD 1 ]----+--------------------------------------------------
76-
start_lsn | 0/E84F5E8
77-
end_lsn | 0/E84F620
78-
prev_lsn | 0/E84F5A8
74+
postgres=# SELECT * FROM pg_get_wal_record_info('0/E419E28');
75+
-[ RECORD 1 ]----+-------------------------------------------------
76+
start_lsn | 0/E419E28
77+
end_lsn | 0/E419E68
78+
prev_lsn | 0/E419D78
7979
xid | 0
8080
resource_manager | Heap2
8181
record_type | VACUUM
82-
record_length | 50
82+
record_length | 58
8383
main_data_length | 2
8484
fpi_length | 0
85-
description | nunused: 1, unused: [ 22 ]
86-
block_ref | blkref #0: rel 1663/16389/20884 fork main blk 126
85+
description | nunused: 5, unused: [1, 2, 3, 4, 5]
86+
block_ref | blkref #0: rel 1663/16385/1249 fork main blk 364
8787
</screen>
8888
</para>
8989
<para>
@@ -144,27 +144,27 @@ block_ref |
144144
references. Returns one row per block reference per WAL record.
145145
For example:
146146
<screen>
147-
postgres=# SELECT * FROM pg_get_wal_block_info('0/10E9D80', '0/10E9DC0');
147+
postgres=# SELECT * FROM pg_get_wal_block_info('0/1230278', '0/12302B8');
148148
-[ RECORD 1 ]-----+-----------------------------------
149-
start_lsn | 0/10E9D80
150-
end_lsn | 0/10E9DC0
151-
prev_lsn | 0/10E9860
149+
start_lsn | 0/1230278
150+
end_lsn | 0/12302B8
151+
prev_lsn | 0/122FD40
152152
block_id | 0
153153
reltablespace | 1663
154154
reldatabase | 1
155-
relfilenode | 2690
155+
relfilenode | 2658
156156
relforknumber | 0
157-
relblocknumber | 5
158-
xid | 117
157+
relblocknumber | 11
158+
xid | 341
159159
resource_manager | Btree
160160
record_type | INSERT_LEAF
161161
record_length | 64
162162
main_data_length | 2
163163
block_data_length | 16
164164
block_fpi_length | 0
165165
block_fpi_info |
166-
description | off 14
167-
block_data | \x00005400020010001407000000000000
166+
description | off: 46
167+
block_data | \x00002a00070010402630000070696400
168168
block_fpi_data |
169169
</screen>
170170
</para>

src/backend/access/rmgrdesc/heapdesc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ heap_desc(StringInfo buf, XLogReaderState *record)
127127
appendStringInfo(buf, ", nrelids: %u", xlrec->nrelids);
128128
appendStringInfoString(buf, ", relids:");
129129
array_desc(buf, xlrec->relids, sizeof(Oid), xlrec->nrelids,
130-
&relid_desc, NULL);
130+
&oid_elem_desc, NULL);
131131
}
132132
else if (info == XLOG_HEAP_CONFIRM)
133133
{

src/backend/access/rmgrdesc/nbtdesc.c

Lines changed: 63 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -17,59 +17,8 @@
1717
#include "access/nbtxlog.h"
1818
#include "access/rmgrdesc_utils.h"
1919

20-
static void btree_del_desc(StringInfo buf, char *block_data, uint16 ndeleted,
21-
uint16 nupdated);
22-
static void btree_update_elem_desc(StringInfo buf, void *update, void *data);
23-
24-
static void
25-
btree_del_desc(StringInfo buf, char *block_data, uint16 ndeleted,
26-
uint16 nupdated)
27-
{
28-
OffsetNumber *updatedoffsets;
29-
xl_btree_update *updates;
30-
OffsetNumber *data = (OffsetNumber *) block_data;
31-
32-
appendStringInfoString(buf, ", deleted:");
33-
array_desc(buf, data, sizeof(OffsetNumber), ndeleted,
34-
&offset_elem_desc, NULL);
35-
36-
appendStringInfoString(buf, ", updated:");
37-
array_desc(buf, data, sizeof(OffsetNumber), nupdated,
38-
&offset_elem_desc, NULL);
39-
40-
if (nupdated <= 0)
41-
return;
42-
43-
updatedoffsets = (OffsetNumber *)
44-
((char *) data + ndeleted * sizeof(OffsetNumber));
45-
updates = (xl_btree_update *) ((char *) updatedoffsets +
46-
nupdated *
47-
sizeof(OffsetNumber));
48-
49-
appendStringInfoString(buf, ", updates:");
50-
array_desc(buf, updates, sizeof(xl_btree_update),
51-
nupdated, &btree_update_elem_desc,
52-
&updatedoffsets);
53-
}
54-
55-
static void
56-
btree_update_elem_desc(StringInfo buf, void *update, void *data)
57-
{
58-
xl_btree_update *new_update = (xl_btree_update *) update;
59-
OffsetNumber *updated_offset = *((OffsetNumber **) data);
60-
61-
appendStringInfo(buf, "{ updated offset: %u, ndeleted tids: %u",
62-
*updated_offset, new_update->ndeletedtids);
63-
64-
appendStringInfoString(buf, ", deleted tids:");
65-
66-
array_desc(buf, (char *) new_update + SizeOfBtreeUpdate, sizeof(uint16),
67-
new_update->ndeletedtids, &uint16_elem_desc, NULL);
68-
69-
updated_offset++;
70-
71-
appendStringInfo(buf, " }");
72-
}
20+
static void delvacuum_desc(StringInfo buf, char *block_data,
21+
uint16 ndeleted, uint16 nupdated);
7322

7423
void
7524
btree_desc(StringInfo buf, XLogReaderState *record)
@@ -114,9 +63,8 @@ btree_desc(StringInfo buf, XLogReaderState *record)
11463
xlrec->ndeleted, xlrec->nupdated);
11564

11665
if (!XLogRecHasBlockImage(record, 0))
117-
btree_del_desc(buf, XLogRecGetBlockData(record, 0, NULL),
66+
delvacuum_desc(buf, XLogRecGetBlockData(record, 0, NULL),
11867
xlrec->ndeleted, xlrec->nupdated);
119-
12068
break;
12169
}
12270
case XLOG_BTREE_DELETE:
@@ -128,16 +76,15 @@ btree_desc(StringInfo buf, XLogReaderState *record)
12876
xlrec->ndeleted, xlrec->nupdated);
12977

13078
if (!XLogRecHasBlockImage(record, 0))
131-
btree_del_desc(buf, XLogRecGetBlockData(record, 0, NULL),
79+
delvacuum_desc(buf, XLogRecGetBlockData(record, 0, NULL),
13280
xlrec->ndeleted, xlrec->nupdated);
133-
13481
break;
13582
}
13683
case XLOG_BTREE_MARK_PAGE_HALFDEAD:
13784
{
13885
xl_btree_mark_page_halfdead *xlrec = (xl_btree_mark_page_halfdead *) rec;
13986

140-
appendStringInfo(buf, "topparent: %u; leaf: %u; left: %u; right: %u",
87+
appendStringInfo(buf, "topparent: %u, leaf: %u, left: %u, right: %u",
14188
xlrec->topparent, xlrec->leafblk, xlrec->leftblk, xlrec->rightblk);
14289
break;
14390
}
@@ -146,11 +93,11 @@ btree_desc(StringInfo buf, XLogReaderState *record)
14693
{
14794
xl_btree_unlink_page *xlrec = (xl_btree_unlink_page *) rec;
14895

149-
appendStringInfo(buf, "left: %u; right: %u; level: %u; safexid: %u:%u; ",
96+
appendStringInfo(buf, "left: %u, right: %u, level: %u, safexid: %u:%u, ",
15097
xlrec->leftsib, xlrec->rightsib, xlrec->level,
15198
EpochFromFullTransactionId(xlrec->safexid),
15299
XidFromFullTransactionId(xlrec->safexid));
153-
appendStringInfo(buf, "leafleft: %u; leafright: %u; leaftopparent: %u",
100+
appendStringInfo(buf, "leafleft: %u, leafright: %u, leaftopparent: %u",
154101
xlrec->leafleftsib, xlrec->leafrightsib,
155102
xlrec->leaftopparent);
156103
break;
@@ -242,3 +189,59 @@ btree_identify(uint8 info)
242189

243190
return id;
244191
}
192+
193+
static void
194+
delvacuum_desc(StringInfo buf, char *block_data,
195+
uint16 ndeleted, uint16 nupdated)
196+
{
197+
OffsetNumber *deletedoffsets;
198+
OffsetNumber *updatedoffsets;
199+
xl_btree_update *updates;
200+
201+
/* Output deleted page offset number array */
202+
appendStringInfoString(buf, ", deleted:");
203+
deletedoffsets = (OffsetNumber *) block_data;
204+
array_desc(buf, deletedoffsets, sizeof(OffsetNumber), ndeleted,
205+
&offset_elem_desc, NULL);
206+
207+
/*
208+
* Output updates as an array of "update objects", where each element
209+
* contains a page offset number from updated array. (This is not the
210+
* most literal representation of the underlying physical data structure
211+
* that we could use. Readability seems more important here.)
212+
*/
213+
appendStringInfoString(buf, ", updated: [");
214+
updatedoffsets = (OffsetNumber *) (block_data + ndeleted *
215+
sizeof(OffsetNumber));
216+
updates = (xl_btree_update *) ((char *) updatedoffsets +
217+
nupdated *
218+
sizeof(OffsetNumber));
219+
for (int i = 0; i < nupdated; i++)
220+
{
221+
OffsetNumber off = updatedoffsets[i];
222+
223+
Assert(OffsetNumberIsValid(off));
224+
Assert(updates->ndeletedtids > 0);
225+
226+
appendStringInfo(buf, "{ off: %u, nptids: %u, ptids: [",
227+
off, updates->ndeletedtids);
228+
for (int p = 0; p < updates->ndeletedtids; p++)
229+
{
230+
uint16 *ptid;
231+
232+
ptid = (uint16 *) ((char *) updates + SizeOfBtreeUpdate) + p;
233+
appendStringInfo(buf, "%u", *ptid);
234+
235+
if (p < updates->ndeletedtids - 1)
236+
appendStringInfoString(buf, ", ");
237+
}
238+
appendStringInfoString(buf, "] }");
239+
if (i < nupdated - 1)
240+
appendStringInfoString(buf, ", ");
241+
242+
updates = (xl_btree_update *)
243+
((char *) updates + SizeOfBtreeUpdate +
244+
updates->ndeletedtids * sizeof(uint16));
245+
}
246+
appendStringInfoString(buf, "]");
247+
}

src/backend/access/rmgrdesc/rmgrdesc_utils.c

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,11 @@
2929
* or comma, however all subsequent appends to the string are responsible for
3030
* prepending themselves with a comma followed by a space.
3131
*
32-
* Arrays should have a space between the opening square bracket and first
33-
* element and between the last element and closing brace.
34-
*
3532
* Flags should be in ALL CAPS.
3633
*
3734
* For lists/arrays of items, the number of those items should be listed at
3835
* the beginning with all of the other numbers.
3936
*
40-
* List punctuation should still be included even if there are 0 items.
41-
*
4237
* Composite objects in a list should be surrounded with { }.
4338
*/
4439
void
@@ -51,16 +46,14 @@ array_desc(StringInfo buf, void *array, size_t elem_size, int count,
5146
appendStringInfoString(buf, " []");
5247
return;
5348
}
54-
appendStringInfo(buf, " [");
49+
appendStringInfoString(buf, " [");
5550
for (int i = 0; i < count; i++)
5651
{
57-
if (i > 0)
58-
appendStringInfoString(buf, ",");
59-
appendStringInfoString(buf, " ");
60-
6152
elem_desc(buf, (char *) array + elem_size * i, data);
53+
if (i < count - 1)
54+
appendStringInfoString(buf, ", ");
6255
}
63-
appendStringInfoString(buf, " ]");
56+
appendStringInfoString(buf, "]");
6457
}
6558

6659
void
@@ -78,13 +71,7 @@ redirect_elem_desc(StringInfo buf, void *offset, void *data)
7871
}
7972

8073
void
81-
relid_desc(StringInfo buf, void *relid, void *data)
74+
oid_elem_desc(StringInfo buf, void *relid, void *data)
8275
{
8376
appendStringInfo(buf, "%u", *(Oid *) relid);
8477
}
85-
86-
void
87-
uint16_elem_desc(StringInfo buf, void *value, void *data)
88-
{
89-
appendStringInfo(buf, "%u", *(uint16 *) value);
90-
}

src/include/access/rmgrdesc_utils.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ extern void array_desc(StringInfo buf, void *array, size_t elem_size, int count,
1717
void *data);
1818
extern void offset_elem_desc(StringInfo buf, void *offset, void *data);
1919
extern void redirect_elem_desc(StringInfo buf, void *offset, void *data);
20-
extern void relid_desc(StringInfo buf, void *relid, void *data);
21-
extern void uint16_elem_desc(StringInfo buf, void *value, void *data);
20+
extern void oid_elem_desc(StringInfo buf, void *relid, void *data);
2221

2322
#endif /* RMGRDESC_UTILS_H */

0 commit comments

Comments
 (0)