LCOV - code coverage report
Current view: top level - src/bin/pg_waldump - nbtdesc.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 93 136 68.4 %
Date: 2024-12-12 17:14:55 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          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
      24       72040 : btree_desc(StringInfo buf, XLogReaderState *record)
      25             : {
      26       72040 :     char       *rec = XLogRecGetData(record);
      27       72040 :     uint8       info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
      28             : 
      29       72040 :     switch (info)
      30             :     {
      31       71088 :         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       71088 :                 xl_btree_insert *xlrec = (xl_btree_insert *) rec;
      37             : 
      38       71088 :                 appendStringInfo(buf, "off: %u", xlrec->offnum);
      39       71088 :                 break;
      40             :             }
      41         240 :         case XLOG_BTREE_SPLIT_L:
      42             :         case XLOG_BTREE_SPLIT_R:
      43             :             {
      44         240 :                 xl_btree_split *xlrec = (xl_btree_split *) rec;
      45             : 
      46         240 :                 appendStringInfo(buf, "level: %u, firstrightoff: %d, newitemoff: %d, postingoff: %d",
      47         240 :                                  xlrec->level, xlrec->firstrightoff,
      48         240 :                                  xlrec->newitemoff, xlrec->postingoff);
      49         240 :                 break;
      50             :             }
      51         212 :         case XLOG_BTREE_DEDUP:
      52             :             {
      53         212 :                 xl_btree_dedup *xlrec = (xl_btree_dedup *) rec;
      54             : 
      55         212 :                 appendStringInfo(buf, "nintervals: %u", xlrec->nintervals);
      56         212 :                 break;
      57             :             }
      58         256 :         case XLOG_BTREE_VACUUM:
      59             :             {
      60         256 :                 xl_btree_vacuum *xlrec = (xl_btree_vacuum *) rec;
      61             : 
      62         256 :                 appendStringInfo(buf, "ndeleted: %u, nupdated: %u",
      63         256 :                                  xlrec->ndeleted, xlrec->nupdated);
      64             : 
      65         256 :                 if (XLogRecHasBlockData(record, 0))
      66         256 :                     delvacuum_desc(buf, XLogRecGetBlockData(record, 0, NULL),
      67         256 :                                    xlrec->ndeleted, xlrec->nupdated);
      68         256 :                 break;
      69             :             }
      70          24 :         case XLOG_BTREE_DELETE:
      71             :             {
      72          24 :                 xl_btree_delete *xlrec = (xl_btree_delete *) rec;
      73             : 
      74          24 :                 appendStringInfo(buf, "snapshotConflictHorizon: %u, ndeleted: %u, nupdated: %u, isCatalogRel: %c",
      75             :                                  xlrec->snapshotConflictHorizon,
      76          24 :                                  xlrec->ndeleted, xlrec->nupdated,
      77          24 :                                  xlrec->isCatalogRel ? 'T' : 'F');
      78             : 
      79          24 :                 if (XLogRecHasBlockData(record, 0))
      80          24 :                     delvacuum_desc(buf, XLogRecGetBlockData(record, 0, NULL),
      81          24 :                                    xlrec->ndeleted, xlrec->nupdated);
      82          24 :                 break;
      83             :             }
      84           0 :         case XLOG_BTREE_MARK_PAGE_HALFDEAD:
      85             :             {
      86           0 :                 xl_btree_mark_page_halfdead *xlrec = (xl_btree_mark_page_halfdead *) rec;
      87             : 
      88           0 :                 appendStringInfo(buf, "topparent: %u, leaf: %u, left: %u, right: %u",
      89             :                                  xlrec->topparent, xlrec->leafblk, xlrec->leftblk, xlrec->rightblk);
      90           0 :                 break;
      91             :             }
      92           0 :         case XLOG_BTREE_UNLINK_PAGE_META:
      93             :         case XLOG_BTREE_UNLINK_PAGE:
      94             :             {
      95           0 :                 xl_btree_unlink_page *xlrec = (xl_btree_unlink_page *) rec;
      96             : 
      97           0 :                 appendStringInfo(buf, "left: %u, right: %u, level: %u, safexid: %u:%u, ",
      98             :                                  xlrec->leftsib, xlrec->rightsib, xlrec->level,
      99           0 :                                  EpochFromFullTransactionId(xlrec->safexid),
     100           0 :                                  XidFromFullTransactionId(xlrec->safexid));
     101           0 :                 appendStringInfo(buf, "leafleft: %u, leafright: %u, leaftopparent: %u",
     102             :                                  xlrec->leafleftsib, xlrec->leafrightsib,
     103             :                                  xlrec->leaftopparent);
     104           0 :                 break;
     105             :             }
     106         220 :         case XLOG_BTREE_NEWROOT:
     107             :             {
     108         220 :                 xl_btree_newroot *xlrec = (xl_btree_newroot *) rec;
     109             : 
     110         220 :                 appendStringInfo(buf, "level: %u", xlrec->level);
     111         220 :                 break;
     112             :             }
     113           0 :         case XLOG_BTREE_REUSE_PAGE:
     114             :             {
     115           0 :                 xl_btree_reuse_page *xlrec = (xl_btree_reuse_page *) rec;
     116             : 
     117           0 :                 appendStringInfo(buf, "rel: %u/%u/%u, snapshotConflictHorizon: %u:%u, isCatalogRel: %c",
     118             :                                  xlrec->locator.spcOid, xlrec->locator.dbOid,
     119             :                                  xlrec->locator.relNumber,
     120           0 :                                  EpochFromFullTransactionId(xlrec->snapshotConflictHorizon),
     121           0 :                                  XidFromFullTransactionId(xlrec->snapshotConflictHorizon),
     122           0 :                                  xlrec->isCatalogRel ? 'T' : 'F');
     123           0 :                 break;
     124             :             }
     125           0 :         case XLOG_BTREE_META_CLEANUP:
     126             :             {
     127             :                 xl_btree_metadata *xlrec;
     128             : 
     129           0 :                 xlrec = (xl_btree_metadata *) XLogRecGetBlockData(record, 0,
     130             :                                                                   NULL);
     131           0 :                 appendStringInfo(buf, "last_cleanup_num_delpages: %u",
     132             :                                  xlrec->last_cleanup_num_delpages);
     133           0 :                 break;
     134             :             }
     135             :     }
     136       72040 : }
     137             : 
     138             : const char *
     139       72052 : btree_identify(uint8 info)
     140             : {
     141       72052 :     const char *id = NULL;
     142             : 
     143       72052 :     switch (info & ~XLR_INFO_MASK)
     144             :     {
     145       70902 :         case XLOG_BTREE_INSERT_LEAF:
     146       70902 :             id = "INSERT_LEAF";
     147       70902 :             break;
     148         190 :         case XLOG_BTREE_INSERT_UPPER:
     149         190 :             id = "INSERT_UPPER";
     150         190 :             break;
     151           0 :         case XLOG_BTREE_INSERT_META:
     152           0 :             id = "INSERT_META";
     153           0 :             break;
     154          70 :         case XLOG_BTREE_SPLIT_L:
     155          70 :             id = "SPLIT_L";
     156          70 :             break;
     157         174 :         case XLOG_BTREE_SPLIT_R:
     158         174 :             id = "SPLIT_R";
     159         174 :             break;
     160           0 :         case XLOG_BTREE_INSERT_POST:
     161           0 :             id = "INSERT_POST";
     162           0 :             break;
     163         212 :         case XLOG_BTREE_DEDUP:
     164         212 :             id = "DEDUP";
     165         212 :             break;
     166         258 :         case XLOG_BTREE_VACUUM:
     167         258 :             id = "VACUUM";
     168         258 :             break;
     169          24 :         case XLOG_BTREE_DELETE:
     170          24 :             id = "DELETE";
     171          24 :             break;
     172           0 :         case XLOG_BTREE_MARK_PAGE_HALFDEAD:
     173           0 :             id = "MARK_PAGE_HALFDEAD";
     174           0 :             break;
     175           0 :         case XLOG_BTREE_UNLINK_PAGE:
     176           0 :             id = "UNLINK_PAGE";
     177           0 :             break;
     178           0 :         case XLOG_BTREE_UNLINK_PAGE_META:
     179           0 :             id = "UNLINK_PAGE_META";
     180           0 :             break;
     181         222 :         case XLOG_BTREE_NEWROOT:
     182         222 :             id = "NEWROOT";
     183         222 :             break;
     184           0 :         case XLOG_BTREE_REUSE_PAGE:
     185           0 :             id = "REUSE_PAGE";
     186           0 :             break;
     187           0 :         case XLOG_BTREE_META_CLEANUP:
     188           0 :             id = "META_CLEANUP";
     189           0 :             break;
     190             :     }
     191             : 
     192       72052 :     return id;
     193             : }
     194             : 
     195             : static void
     196         280 : 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         280 :     appendStringInfoString(buf, ", deleted:");
     205         280 :     deletedoffsets = (OffsetNumber *) block_data;
     206         280 :     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         280 :     appendStringInfoString(buf, ", updated: [");
     216         280 :     updatedoffsets = (OffsetNumber *) (block_data + ndeleted *
     217             :                                        sizeof(OffsetNumber));
     218         280 :     updates = (xl_btree_update *) ((char *) updatedoffsets +
     219         280 :                                    nupdated *
     220             :                                    sizeof(OffsetNumber));
     221        1216 :     for (int i = 0; i < nupdated; i++)
     222             :     {
     223         936 :         OffsetNumber off = updatedoffsets[i];
     224             : 
     225             :         Assert(OffsetNumberIsValid(off));
     226             :         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         936 :         appendStringInfo(buf, "{ off: %u, nptids: %u, ptids: [",
     234         936 :                          off, updates->ndeletedtids);
     235        2180 :         for (int p = 0; p < updates->ndeletedtids; p++)
     236             :         {
     237             :             uint16     *ptid;
     238             : 
     239        1244 :             ptid = (uint16 *) ((char *) updates + SizeOfBtreeUpdate) + p;
     240        1244 :             appendStringInfo(buf, "%u", *ptid);
     241             : 
     242        1244 :             if (p < updates->ndeletedtids - 1)
     243         308 :                 appendStringInfoString(buf, ", ");
     244             :         }
     245         936 :         appendStringInfoString(buf, "] }");
     246         936 :         if (i < nupdated - 1)
     247         896 :             appendStringInfoString(buf, ", ");
     248             : 
     249         936 :         updates = (xl_btree_update *)
     250         936 :             ((char *) updates + SizeOfBtreeUpdate +
     251         936 :              updates->ndeletedtids * sizeof(uint16));
     252             :     }
     253         280 :     appendStringInfoChar(buf, ']');
     254         280 : }

Generated by: LCOV version 1.14