1515#include "postgres.h"
1616
1717#include "access/nbtxlog.h"
18+ #include "access/rmgrdesc_utils.h"
19+
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+ }
1873
1974void
2075btree_desc (StringInfo buf ,XLogReaderState * record )
@@ -31,15 +86,15 @@ btree_desc(StringInfo buf, XLogReaderState *record)
3186{
3287xl_btree_insert * xlrec = (xl_btree_insert * )rec ;
3388
34- appendStringInfo (buf ,"off %u" ,xlrec -> offnum );
89+ appendStringInfo (buf ,"off: %u" ,xlrec -> offnum );
3590break ;
3691}
3792case XLOG_BTREE_SPLIT_L :
3893case XLOG_BTREE_SPLIT_R :
3994{
4095xl_btree_split * xlrec = (xl_btree_split * )rec ;
4196
42- appendStringInfo (buf ,"level %u, firstrightoff %d, newitemoff %d, postingoff %d" ,
97+ appendStringInfo (buf ,"level: %u, firstrightoff: %d, newitemoff: %d, postingoff: %d" ,
4398xlrec -> level ,xlrec -> firstrightoff ,
4499xlrec -> newitemoff ,xlrec -> postingoff );
45100break ;
@@ -48,31 +103,41 @@ btree_desc(StringInfo buf, XLogReaderState *record)
48103{
49104xl_btree_dedup * xlrec = (xl_btree_dedup * )rec ;
50105
51- appendStringInfo (buf ,"nintervals %u" ,xlrec -> nintervals );
106+ appendStringInfo (buf ,"nintervals: %u" ,xlrec -> nintervals );
52107break ;
53108}
54109case XLOG_BTREE_VACUUM :
55110{
56111xl_btree_vacuum * xlrec = (xl_btree_vacuum * )rec ;
57112
58- appendStringInfo (buf ,"ndeleted %u; nupdated %u" ,
113+ appendStringInfo (buf ,"ndeleted: %u, nupdated: %u" ,
59114xlrec -> ndeleted ,xlrec -> nupdated );
115+
116+ if (!XLogRecHasBlockImage (record ,0 ))
117+ btree_del_desc (buf ,XLogRecGetBlockData (record ,0 ,NULL ),
118+ xlrec -> ndeleted ,xlrec -> nupdated );
119+
60120break ;
61121}
62122case XLOG_BTREE_DELETE :
63123{
64124xl_btree_delete * xlrec = (xl_btree_delete * )rec ;
65125
66- appendStringInfo (buf ,"snapshotConflictHorizon %u; ndeleted %u; nupdated %u" ,
126+ appendStringInfo (buf ,"snapshotConflictHorizon: %u, ndeleted: %u, nupdated: %u" ,
67127xlrec -> snapshotConflictHorizon ,
68128xlrec -> ndeleted ,xlrec -> nupdated );
129+
130+ if (!XLogRecHasBlockImage (record ,0 ))
131+ btree_del_desc (buf ,XLogRecGetBlockData (record ,0 ,NULL ),
132+ xlrec -> ndeleted ,xlrec -> nupdated );
133+
69134break ;
70135}
71136case XLOG_BTREE_MARK_PAGE_HALFDEAD :
72137{
73138xl_btree_mark_page_halfdead * xlrec = (xl_btree_mark_page_halfdead * )rec ;
74139
75- appendStringInfo (buf ,"topparent %u; leaf %u; left %u; right %u" ,
140+ appendStringInfo (buf ,"topparent: %u; leaf: %u; left: %u; right: %u" ,
76141xlrec -> topparent ,xlrec -> leafblk ,xlrec -> leftblk ,xlrec -> rightblk );
77142break ;
78143}
@@ -81,11 +146,11 @@ btree_desc(StringInfo buf, XLogReaderState *record)
81146{
82147xl_btree_unlink_page * xlrec = (xl_btree_unlink_page * )rec ;
83148
84- appendStringInfo (buf ,"left %u; right %u; level %u; safexid %u:%u; " ,
149+ appendStringInfo (buf ,"left: %u; right: %u; level: %u; safexid: %u:%u; " ,
85150xlrec -> leftsib ,xlrec -> rightsib ,xlrec -> level ,
86151EpochFromFullTransactionId (xlrec -> safexid ),
87152XidFromFullTransactionId (xlrec -> safexid ));
88- appendStringInfo (buf ,"leafleft %u; leafright %u; leaftopparent %u" ,
153+ appendStringInfo (buf ,"leafleft: %u; leafright: %u; leaftopparent: %u" ,
89154xlrec -> leafleftsib ,xlrec -> leafrightsib ,
90155xlrec -> leaftopparent );
91156break ;
@@ -94,14 +159,14 @@ btree_desc(StringInfo buf, XLogReaderState *record)
94159{
95160xl_btree_newroot * xlrec = (xl_btree_newroot * )rec ;
96161
97- appendStringInfo (buf ,"lev %u" ,xlrec -> level );
162+ appendStringInfo (buf ,"lev: %u" ,xlrec -> level );
98163break ;
99164}
100165case XLOG_BTREE_REUSE_PAGE :
101166{
102167xl_btree_reuse_page * xlrec = (xl_btree_reuse_page * )rec ;
103168
104- appendStringInfo (buf ,"rel %u/%u/%u; snapshotConflictHorizon %u:%u" ,
169+ appendStringInfo (buf ,"rel: %u/%u/%u, snapshotConflictHorizon: %u:%u" ,
105170xlrec -> locator .spcOid ,xlrec -> locator .dbOid ,
106171xlrec -> locator .relNumber ,
107172EpochFromFullTransactionId (xlrec -> snapshotConflictHorizon ),
@@ -114,7 +179,7 @@ btree_desc(StringInfo buf, XLogReaderState *record)
114179
115180xlrec = (xl_btree_metadata * )XLogRecGetBlockData (record ,0 ,
116181NULL );
117- appendStringInfo (buf ,"last_cleanup_num_delpages %u" ,
182+ appendStringInfo (buf ,"last_cleanup_num_delpages: %u" ,
118183xlrec -> last_cleanup_num_delpages );
119184break ;
120185}