1515#include "postgres.h"
1616
1717#include "access/heapam_xlog.h"
18+ #include "access/rmgrdesc_utils.h"
1819
1920static void
2021out_infobits (StringInfo buf , uint8 infobits )
2122{
23+ if ((infobits & XLHL_XMAX_IS_MULTI ) == 0 &&
24+ (infobits & XLHL_XMAX_LOCK_ONLY ) == 0 &&
25+ (infobits & XLHL_XMAX_EXCL_LOCK ) == 0 &&
26+ (infobits & XLHL_XMAX_KEYSHR_LOCK ) == 0 &&
27+ (infobits & XLHL_KEYS_UPDATED ) == 0 )
28+ return ;
29+
30+ appendStringInfoString (buf , ", infobits: [" );
31+
2232 if (infobits & XLHL_XMAX_IS_MULTI )
23- appendStringInfoString (buf , "IS_MULTI " );
33+ appendStringInfoString (buf , " IS_MULTI " );
2434 if (infobits & XLHL_XMAX_LOCK_ONLY )
25- appendStringInfoString (buf , "LOCK_ONLY " );
35+ appendStringInfoString (buf , ", LOCK_ONLY " );
2636 if (infobits & XLHL_XMAX_EXCL_LOCK )
27- appendStringInfoString (buf , "EXCL_LOCK " );
37+ appendStringInfoString (buf , ", EXCL_LOCK " );
2838 if (infobits & XLHL_XMAX_KEYSHR_LOCK )
29- appendStringInfoString (buf , "KEYSHR_LOCK " );
39+ appendStringInfoString (buf , ", KEYSHR_LOCK " );
3040 if (infobits & XLHL_KEYS_UPDATED )
31- appendStringInfoString (buf , "KEYS_UPDATED " );
41+ appendStringInfoString (buf , ", KEYS_UPDATED" );
42+
43+ appendStringInfoString (buf , " ]" );
44+ }
45+
46+ static void
47+ plan_elem_desc (StringInfo buf , void * plan , void * data )
48+ {
49+ xl_heap_freeze_plan * new_plan = (xl_heap_freeze_plan * ) plan ;
50+ OffsetNumber * * offsets = data ;
51+
52+ appendStringInfo (buf , "{ xmax: %u, infomask: %u, infomask2: %u, ntuples: %u" ,
53+ new_plan -> xmax ,
54+ new_plan -> t_infomask , new_plan -> t_infomask2 ,
55+ new_plan -> ntuples );
56+
57+ appendStringInfoString (buf , ", offsets:" );
58+ array_desc (buf , * offsets , sizeof (OffsetNumber ), new_plan -> ntuples ,
59+ & offset_elem_desc , NULL );
60+
61+ * offsets += new_plan -> ntuples ;
62+
63+ appendStringInfo (buf , " }" );
3264}
3365
3466void
@@ -42,14 +74,15 @@ heap_desc(StringInfo buf, XLogReaderState *record)
4274 {
4375 xl_heap_insert * xlrec = (xl_heap_insert * ) rec ;
4476
45- appendStringInfo (buf , "off %u flags 0x%02X" , xlrec -> offnum ,
77+ appendStringInfo (buf , "off: %u, flags: 0x%02X" ,
78+ xlrec -> offnum ,
4679 xlrec -> flags );
4780 }
4881 else if (info == XLOG_HEAP_DELETE )
4982 {
5083 xl_heap_delete * xlrec = (xl_heap_delete * ) rec ;
5184
52- appendStringInfo (buf , "off %u flags 0x%02X " ,
85+ appendStringInfo (buf , "off: %u, flags: 0x%02X" ,
5386 xlrec -> offnum ,
5487 xlrec -> flags );
5588 out_infobits (buf , xlrec -> infobits_set );
@@ -58,62 +91,66 @@ heap_desc(StringInfo buf, XLogReaderState *record)
5891 {
5992 xl_heap_update * xlrec = (xl_heap_update * ) rec ;
6093
61- appendStringInfo (buf , "off %u xmax %u flags 0x%02X " ,
94+ appendStringInfo (buf , "off: %u, xmax: %u, flags: 0x%02X" ,
6295 xlrec -> old_offnum ,
6396 xlrec -> old_xmax ,
6497 xlrec -> flags );
6598 out_infobits (buf , xlrec -> old_infobits_set );
66- appendStringInfo (buf , "; new off %u xmax %u" ,
99+ appendStringInfo (buf , ", new off: %u, xmax %u" ,
67100 xlrec -> new_offnum ,
68101 xlrec -> new_xmax );
69102 }
70103 else if (info == XLOG_HEAP_HOT_UPDATE )
71104 {
72105 xl_heap_update * xlrec = (xl_heap_update * ) rec ;
73106
74- appendStringInfo (buf , "off %u xmax %u flags 0x%02X " ,
107+ appendStringInfo (buf , "off: %u, xmax: %u, flags: 0x%02X" ,
75108 xlrec -> old_offnum ,
76109 xlrec -> old_xmax ,
77110 xlrec -> flags );
78111 out_infobits (buf , xlrec -> old_infobits_set );
79- appendStringInfo (buf , "; new off %u xmax %u" ,
112+ appendStringInfo (buf , ", new off: %u, xmax: %u" ,
80113 xlrec -> new_offnum ,
81114 xlrec -> new_xmax );
82115 }
83116 else if (info == XLOG_HEAP_TRUNCATE )
84117 {
85118 xl_heap_truncate * xlrec = (xl_heap_truncate * ) rec ;
86- int i ;
87119
120+ appendStringInfoString (buf , "flags: [" );
88121 if (xlrec -> flags & XLH_TRUNCATE_CASCADE )
89- appendStringInfoString (buf , "cascade " );
122+ appendStringInfoString (buf , " CASCADE " );
90123 if (xlrec -> flags & XLH_TRUNCATE_RESTART_SEQS )
91- appendStringInfoString (buf , "restart_seqs " );
92- appendStringInfo (buf , "nrelids %u relids" , xlrec -> nrelids );
93- for (i = 0 ; i < xlrec -> nrelids ; i ++ )
94- appendStringInfo (buf , " %u" , xlrec -> relids [i ]);
124+ appendStringInfoString (buf , ", RESTART_SEQS" );
125+ appendStringInfoString (buf , " ]" );
126+
127+ appendStringInfo (buf , ", nrelids: %u" , xlrec -> nrelids );
128+ appendStringInfoString (buf , ", relids:" );
129+ array_desc (buf , xlrec -> relids , sizeof (Oid ), xlrec -> nrelids ,
130+ & relid_desc , NULL );
95131 }
96132 else if (info == XLOG_HEAP_CONFIRM )
97133 {
98134 xl_heap_confirm * xlrec = (xl_heap_confirm * ) rec ;
99135
100- appendStringInfo (buf , "off %u" , xlrec -> offnum );
136+ appendStringInfo (buf , "off: %u" , xlrec -> offnum );
101137 }
102138 else if (info == XLOG_HEAP_LOCK )
103139 {
104140 xl_heap_lock * xlrec = (xl_heap_lock * ) rec ;
105141
106- appendStringInfo (buf , "off %u: xid %u: flags 0x%02X " ,
142+ appendStringInfo (buf , "off: %u, xid: %u, flags: 0x%02X" ,
107143 xlrec -> offnum , xlrec -> locking_xid , xlrec -> flags );
108144 out_infobits (buf , xlrec -> infobits_set );
109145 }
110146 else if (info == XLOG_HEAP_INPLACE )
111147 {
112148 xl_heap_inplace * xlrec = (xl_heap_inplace * ) rec ;
113149
114- appendStringInfo (buf , "off %u" , xlrec -> offnum );
150+ appendStringInfo (buf , "off: %u" , xlrec -> offnum );
115151 }
116152}
153+
117154void
118155heap2_desc (StringInfo buf , XLogReaderState * record )
119156{
@@ -125,57 +162,119 @@ heap2_desc(StringInfo buf, XLogReaderState *record)
125162 {
126163 xl_heap_prune * xlrec = (xl_heap_prune * ) rec ;
127164
128- appendStringInfo (buf , "snapshotConflictHorizon %u nredirected %u ndead %u" ,
165+ appendStringInfo (buf , "snapshotConflictHorizon: %u, nredirected: %u, ndead: %u" ,
129166 xlrec -> snapshotConflictHorizon ,
130167 xlrec -> nredirected ,
131168 xlrec -> ndead );
169+
170+ if (!XLogRecHasBlockImage (record , 0 ))
171+ {
172+ OffsetNumber * end ;
173+ OffsetNumber * redirected ;
174+ OffsetNumber * nowdead ;
175+ OffsetNumber * nowunused ;
176+ int nredirected ;
177+ int nunused ;
178+ Size datalen ;
179+
180+ redirected = (OffsetNumber * ) XLogRecGetBlockData (record , 0 ,
181+ & datalen );
182+
183+ nredirected = xlrec -> nredirected ;
184+ end = (OffsetNumber * ) ((char * ) redirected + datalen );
185+ nowdead = redirected + (nredirected * 2 );
186+ nowunused = nowdead + xlrec -> ndead ;
187+ nunused = (end - nowunused );
188+ Assert (nunused >= 0 );
189+
190+ appendStringInfo (buf , ", nunused: %u" , nunused );
191+
192+ appendStringInfoString (buf , ", redirected:" );
193+ array_desc (buf , redirected , sizeof (OffsetNumber ) * 2 ,
194+ nredirected , & redirect_elem_desc , NULL );
195+ appendStringInfoString (buf , ", dead:" );
196+ array_desc (buf , nowdead , sizeof (OffsetNumber ), xlrec -> ndead ,
197+ & offset_elem_desc , NULL );
198+ appendStringInfoString (buf , ", unused:" );
199+ array_desc (buf , nowunused , sizeof (OffsetNumber ), nunused ,
200+ & offset_elem_desc , NULL );
201+ }
132202 }
133203 else if (info == XLOG_HEAP2_VACUUM )
134204 {
135205 xl_heap_vacuum * xlrec = (xl_heap_vacuum * ) rec ;
136206
137- appendStringInfo (buf , "nunused %u" , xlrec -> nunused );
207+ appendStringInfo (buf , "nunused: %u" , xlrec -> nunused );
208+
209+ if (!XLogRecHasBlockImage (record , 0 ))
210+ {
211+ OffsetNumber * nowunused ;
212+
213+ nowunused = (OffsetNumber * ) XLogRecGetBlockData (record , 0 , NULL );
214+
215+ appendStringInfoString (buf , ", unused:" );
216+ array_desc (buf , nowunused , sizeof (OffsetNumber ), xlrec -> nunused ,
217+ & offset_elem_desc , NULL );
218+ }
138219 }
139220 else if (info == XLOG_HEAP2_FREEZE_PAGE )
140221 {
141222 xl_heap_freeze_page * xlrec = (xl_heap_freeze_page * ) rec ;
142223
143- appendStringInfo (buf , "snapshotConflictHorizon %u nplans %u" ,
224+ appendStringInfo (buf , "snapshotConflictHorizon: %u, nplans: %u" ,
144225 xlrec -> snapshotConflictHorizon , xlrec -> nplans );
226+
227+ if (!XLogRecHasBlockImage (record , 0 ))
228+ {
229+ xl_heap_freeze_plan * plans ;
230+ OffsetNumber * offsets ;
231+
232+ plans = (xl_heap_freeze_plan * ) XLogRecGetBlockData (record , 0 , NULL );
233+ offsets = (OffsetNumber * ) & plans [xlrec -> nplans ];
234+ appendStringInfoString (buf , ", plans:" );
235+ array_desc (buf , plans , sizeof (xl_heap_freeze_plan ), xlrec -> nplans ,
236+ & plan_elem_desc , & offsets );
237+ }
145238 }
146239 else if (info == XLOG_HEAP2_VISIBLE )
147240 {
148241 xl_heap_visible * xlrec = (xl_heap_visible * ) rec ;
149242
150- appendStringInfo (buf , "snapshotConflictHorizon %u flags 0x%02X" ,
243+ appendStringInfo (buf , "snapshotConflictHorizon: %u, flags: 0x%02X" ,
151244 xlrec -> snapshotConflictHorizon , xlrec -> flags );
152245 }
153246 else if (info == XLOG_HEAP2_MULTI_INSERT )
154247 {
155248 xl_heap_multi_insert * xlrec = (xl_heap_multi_insert * ) rec ;
249+ bool isinit = (XLogRecGetInfo (record ) & XLOG_HEAP_INIT_PAGE ) != 0 ;
156250
157- appendStringInfo (buf , "%d tuples flags 0x%02X" , xlrec -> ntuples ,
251+ appendStringInfo (buf , "ntuples: %d, flags: 0x%02X" , xlrec -> ntuples ,
158252 xlrec -> flags );
253+
254+ appendStringInfoString (buf , ", offsets:" );
255+ if (!XLogRecHasBlockImage (record , 0 ) && !isinit )
256+ array_desc (buf , xlrec -> offsets , sizeof (OffsetNumber ),
257+ xlrec -> ntuples , & offset_elem_desc , NULL );
159258 }
160259 else if (info == XLOG_HEAP2_LOCK_UPDATED )
161260 {
162261 xl_heap_lock_updated * xlrec = (xl_heap_lock_updated * ) rec ;
163262
164- appendStringInfo (buf , "off %u: xmax %u: flags 0x%02X " ,
263+ appendStringInfo (buf , "off: %u, xmax: %u, flags: 0x%02X" ,
165264 xlrec -> offnum , xlrec -> xmax , xlrec -> flags );
166265 out_infobits (buf , xlrec -> infobits_set );
167266 }
168267 else if (info == XLOG_HEAP2_NEW_CID )
169268 {
170269 xl_heap_new_cid * xlrec = (xl_heap_new_cid * ) rec ;
171270
172- appendStringInfo (buf , "rel %u/%u/%u; tid %u/%u" ,
271+ appendStringInfo (buf , "rel: %u/%u/%u, tid: %u/%u" ,
173272 xlrec -> target_locator .spcOid ,
174273 xlrec -> target_locator .dbOid ,
175274 xlrec -> target_locator .relNumber ,
176275 ItemPointerGetBlockNumber (& (xlrec -> target_tid )),
177276 ItemPointerGetOffsetNumber (& (xlrec -> target_tid )));
178- appendStringInfo (buf , "; cmin: %u, cmax: %u, combo: %u" ,
277+ appendStringInfo (buf , ", cmin: %u, cmax: %u, combo: %u" ,
179278 xlrec -> cmin , xlrec -> cmax , xlrec -> combocid );
180279 }
181280}
0 commit comments