1/*-------------------------------------------------------------------------
2 *
3 * nbtdesc.c
4 * rmgr descriptor routines for access/nbtree/nbtxlog.c
5 *
6 * Portions Copyright (c) 1996-2019, 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
19void
20btree_desc(StringInfo buf, XLogReaderState *record)
21{
22 char *rec = XLogRecGetData(record);
23 uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
24
25 switch (info)
26 {
27 case XLOG_BTREE_INSERT_LEAF:
28 case XLOG_BTREE_INSERT_UPPER:
29 case XLOG_BTREE_INSERT_META:
30 {
31 xl_btree_insert *xlrec = (xl_btree_insert *) rec;
32
33 appendStringInfo(buf, "off %u", xlrec->offnum);
34 break;
35 }
36 case XLOG_BTREE_SPLIT_L:
37 case XLOG_BTREE_SPLIT_R:
38 {
39 xl_btree_split *xlrec = (xl_btree_split *) rec;
40
41 appendStringInfo(buf, "level %u, firstright %d, newitemoff %d",
42 xlrec->level, xlrec->firstright, xlrec->newitemoff);
43 break;
44 }
45 case XLOG_BTREE_VACUUM:
46 {
47 xl_btree_vacuum *xlrec = (xl_btree_vacuum *) rec;
48
49 appendStringInfo(buf, "lastBlockVacuumed %u",
50 xlrec->lastBlockVacuumed);
51 break;
52 }
53 case XLOG_BTREE_DELETE:
54 {
55 xl_btree_delete *xlrec = (xl_btree_delete *) rec;
56
57 appendStringInfo(buf, "%d items, latest removed xid %u",
58 xlrec->nitems, xlrec->latestRemovedXid);
59 break;
60 }
61 case XLOG_BTREE_MARK_PAGE_HALFDEAD:
62 {
63 xl_btree_mark_page_halfdead *xlrec = (xl_btree_mark_page_halfdead *) rec;
64
65 appendStringInfo(buf, "topparent %u; leaf %u; left %u; right %u",
66 xlrec->topparent, xlrec->leafblk, xlrec->leftblk, xlrec->rightblk);
67 break;
68 }
69 case XLOG_BTREE_UNLINK_PAGE_META:
70 case XLOG_BTREE_UNLINK_PAGE:
71 {
72 xl_btree_unlink_page *xlrec = (xl_btree_unlink_page *) rec;
73
74 appendStringInfo(buf, "left %u; right %u; btpo_xact %u; ",
75 xlrec->leftsib, xlrec->rightsib,
76 xlrec->btpo_xact);
77 appendStringInfo(buf, "leafleft %u; leafright %u; topparent %u",
78 xlrec->leafleftsib, xlrec->leafrightsib,
79 xlrec->topparent);
80 break;
81 }
82 case XLOG_BTREE_NEWROOT:
83 {
84 xl_btree_newroot *xlrec = (xl_btree_newroot *) rec;
85
86 appendStringInfo(buf, "lev %u", xlrec->level);
87 break;
88 }
89 case XLOG_BTREE_REUSE_PAGE:
90 {
91 xl_btree_reuse_page *xlrec = (xl_btree_reuse_page *) rec;
92
93 appendStringInfo(buf, "rel %u/%u/%u; latestRemovedXid %u",
94 xlrec->node.spcNode, xlrec->node.dbNode,
95 xlrec->node.relNode, xlrec->latestRemovedXid);
96 break;
97 }
98 case XLOG_BTREE_META_CLEANUP:
99 {
100 xl_btree_metadata *xlrec;
101
102 xlrec = (xl_btree_metadata *) XLogRecGetBlockData(record, 0,
103 NULL);
104 appendStringInfo(buf, "oldest_btpo_xact %u; last_cleanup_num_heap_tuples: %f",
105 xlrec->oldest_btpo_xact,
106 xlrec->last_cleanup_num_heap_tuples);
107 break;
108 }
109 }
110}
111
112const char *
113btree_identify(uint8 info)
114{
115 const char *id = NULL;
116
117 switch (info & ~XLR_INFO_MASK)
118 {
119 case XLOG_BTREE_INSERT_LEAF:
120 id = "INSERT_LEAF";
121 break;
122 case XLOG_BTREE_INSERT_UPPER:
123 id = "INSERT_UPPER";
124 break;
125 case XLOG_BTREE_INSERT_META:
126 id = "INSERT_META";
127 break;
128 case XLOG_BTREE_SPLIT_L:
129 id = "SPLIT_L";
130 break;
131 case XLOG_BTREE_SPLIT_R:
132 id = "SPLIT_R";
133 break;
134 case XLOG_BTREE_VACUUM:
135 id = "VACUUM";
136 break;
137 case XLOG_BTREE_DELETE:
138 id = "DELETE";
139 break;
140 case XLOG_BTREE_MARK_PAGE_HALFDEAD:
141 id = "MARK_PAGE_HALFDEAD";
142 break;
143 case XLOG_BTREE_UNLINK_PAGE:
144 id = "UNLINK_PAGE";
145 break;
146 case XLOG_BTREE_UNLINK_PAGE_META:
147 id = "UNLINK_PAGE_META";
148 break;
149 case XLOG_BTREE_NEWROOT:
150 id = "NEWROOT";
151 break;
152 case XLOG_BTREE_REUSE_PAGE:
153 id = "REUSE_PAGE";
154 break;
155 case XLOG_BTREE_META_CLEANUP:
156 id = "META_CLEANUP";
157 break;
158 }
159
160 return id;
161}
162