LCOV - code coverage report
Current view: top level - src/backend/access/rmgrdesc - xlogdesc.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 207 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 4 0
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 0.0 % 91 0

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * xlogdesc.c
       4                 :             :  *        rmgr descriptor routines for access/transam/xlog.c
       5                 :             :  *
       6                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7                 :             :  * Portions Copyright (c) 1994, Regents of the University of California
       8                 :             :  *
       9                 :             :  *
      10                 :             :  * IDENTIFICATION
      11                 :             :  *        src/backend/access/rmgrdesc/xlogdesc.c
      12                 :             :  *
      13                 :             :  *-------------------------------------------------------------------------
      14                 :             :  */
      15                 :             : #include "postgres.h"
      16                 :             : 
      17                 :             : #include "access/transam.h"
      18                 :             : #include "access/xlog.h"
      19                 :             : #include "access/xlog_internal.h"
      20                 :             : #include "catalog/pg_control.h"
      21                 :             : #include "utils/guc.h"
      22                 :             : #include "utils/timestamp.h"
      23                 :             : 
      24                 :             : /*
      25                 :             :  * GUC support
      26                 :             :  */
      27                 :             : const struct config_enum_entry wal_level_options[] = {
      28                 :             :         {"minimal", WAL_LEVEL_MINIMAL, false},
      29                 :             :         {"replica", WAL_LEVEL_REPLICA, false},
      30                 :             :         {"archive", WAL_LEVEL_REPLICA, true}, /* deprecated */
      31                 :             :         {"hot_standby", WAL_LEVEL_REPLICA, true},     /* deprecated */
      32                 :             :         {"logical", WAL_LEVEL_LOGICAL, false},
      33                 :             :         {NULL, 0, false}
      34                 :             : };
      35                 :             : 
      36                 :             : /*
      37                 :             :  * Find a string representation for wal_level
      38                 :             :  */
      39                 :             : static const char *
      40                 :           0 : get_wal_level_string(int wal_level)
      41                 :             : {
      42                 :           0 :         const struct config_enum_entry *entry;
      43                 :           0 :         const char *wal_level_str = "?";
      44                 :             : 
      45         [ #  # ]:           0 :         for (entry = wal_level_options; entry->name; entry++)
      46                 :             :         {
      47         [ #  # ]:           0 :                 if (entry->val == wal_level)
      48                 :             :                 {
      49                 :           0 :                         wal_level_str = entry->name;
      50                 :           0 :                         break;
      51                 :             :                 }
      52                 :           0 :         }
      53                 :             : 
      54                 :           0 :         return wal_level_str;
      55                 :           0 : }
      56                 :             : 
      57                 :             : void
      58                 :           0 : xlog_desc(StringInfo buf, XLogReaderState *record)
      59                 :             : {
      60                 :           0 :         char       *rec = XLogRecGetData(record);
      61                 :           0 :         uint8           info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
      62                 :             : 
      63   [ #  #  #  # ]:           0 :         if (info == XLOG_CHECKPOINT_SHUTDOWN ||
      64                 :           0 :                 info == XLOG_CHECKPOINT_ONLINE)
      65                 :             :         {
      66                 :           0 :                 CheckPoint *checkpoint = (CheckPoint *) rec;
      67                 :             : 
      68                 :           0 :                 appendStringInfo(buf, "redo %X/%08X; "
      69                 :             :                                                  "tli %u; prev tli %u; fpw %s; wal_level %s; logical decoding %s; xid %u:%u; oid %u; multi %u; offset %" PRIu64 "; "
      70                 :             :                                                  "oldest xid %u in DB %u; oldest multi %u in DB %u; "
      71                 :             :                                                  "oldest/newest commit timestamp xid: %u/%u; "
      72                 :             :                                                  "oldest running xid %u; %s",
      73                 :           0 :                                                  LSN_FORMAT_ARGS(checkpoint->redo),
      74                 :           0 :                                                  checkpoint->ThisTimeLineID,
      75                 :           0 :                                                  checkpoint->PrevTimeLineID,
      76                 :           0 :                                                  checkpoint->fullPageWrites ? "true" : "false",
      77                 :           0 :                                                  get_wal_level_string(checkpoint->wal_level),
      78                 :           0 :                                                  checkpoint->logicalDecodingEnabled ? "true" : "false",
      79                 :           0 :                                                  EpochFromFullTransactionId(checkpoint->nextXid),
      80                 :           0 :                                                  XidFromFullTransactionId(checkpoint->nextXid),
      81                 :           0 :                                                  checkpoint->nextOid,
      82                 :           0 :                                                  checkpoint->nextMulti,
      83                 :           0 :                                                  checkpoint->nextMultiOffset,
      84                 :           0 :                                                  checkpoint->oldestXid,
      85                 :           0 :                                                  checkpoint->oldestXidDB,
      86                 :           0 :                                                  checkpoint->oldestMulti,
      87                 :           0 :                                                  checkpoint->oldestMultiDB,
      88                 :           0 :                                                  checkpoint->oldestCommitTsXid,
      89                 :           0 :                                                  checkpoint->newestCommitTsXid,
      90                 :           0 :                                                  checkpoint->oldestActiveXid,
      91                 :           0 :                                                  (info == XLOG_CHECKPOINT_SHUTDOWN) ? "shutdown" : "online");
      92                 :           0 :         }
      93         [ #  # ]:           0 :         else if (info == XLOG_NEXTOID)
      94                 :             :         {
      95                 :           0 :                 Oid                     nextOid;
      96                 :             : 
      97                 :           0 :                 memcpy(&nextOid, rec, sizeof(Oid));
      98                 :           0 :                 appendStringInfo(buf, "%u", nextOid);
      99                 :           0 :         }
     100         [ #  # ]:           0 :         else if (info == XLOG_RESTORE_POINT)
     101                 :             :         {
     102                 :           0 :                 xl_restore_point *xlrec = (xl_restore_point *) rec;
     103                 :             : 
     104                 :           0 :                 appendStringInfoString(buf, xlrec->rp_name);
     105                 :           0 :         }
     106   [ #  #  #  # ]:           0 :         else if (info == XLOG_FPI || info == XLOG_FPI_FOR_HINT)
     107                 :             :         {
     108                 :             :                 /* no further information to print */
     109                 :           0 :         }
     110         [ #  # ]:           0 :         else if (info == XLOG_BACKUP_END)
     111                 :             :         {
     112                 :           0 :                 XLogRecPtr      startpoint;
     113                 :             : 
     114                 :           0 :                 memcpy(&startpoint, rec, sizeof(XLogRecPtr));
     115                 :           0 :                 appendStringInfo(buf, "%X/%08X", LSN_FORMAT_ARGS(startpoint));
     116                 :           0 :         }
     117         [ #  # ]:           0 :         else if (info == XLOG_PARAMETER_CHANGE)
     118                 :             :         {
     119                 :           0 :                 xl_parameter_change xlrec;
     120                 :           0 :                 const char *wal_level_str;
     121                 :             : 
     122                 :           0 :                 memcpy(&xlrec, rec, sizeof(xl_parameter_change));
     123                 :           0 :                 wal_level_str = get_wal_level_string(xlrec.wal_level);
     124                 :             : 
     125                 :           0 :                 appendStringInfo(buf, "max_connections=%d max_worker_processes=%d "
     126                 :             :                                                  "max_wal_senders=%d max_prepared_xacts=%d "
     127                 :             :                                                  "max_locks_per_xact=%d wal_level=%s "
     128                 :             :                                                  "wal_log_hints=%s track_commit_timestamp=%s",
     129                 :           0 :                                                  xlrec.MaxConnections,
     130                 :           0 :                                                  xlrec.max_worker_processes,
     131                 :           0 :                                                  xlrec.max_wal_senders,
     132                 :           0 :                                                  xlrec.max_prepared_xacts,
     133                 :           0 :                                                  xlrec.max_locks_per_xact,
     134                 :           0 :                                                  wal_level_str,
     135                 :           0 :                                                  xlrec.wal_log_hints ? "on" : "off",
     136                 :           0 :                                                  xlrec.track_commit_timestamp ? "on" : "off");
     137                 :           0 :         }
     138         [ #  # ]:           0 :         else if (info == XLOG_FPW_CHANGE)
     139                 :             :         {
     140                 :           0 :                 bool            fpw;
     141                 :             : 
     142                 :           0 :                 memcpy(&fpw, rec, sizeof(bool));
     143                 :           0 :                 appendStringInfoString(buf, fpw ? "true" : "false");
     144                 :           0 :         }
     145         [ #  # ]:           0 :         else if (info == XLOG_END_OF_RECOVERY)
     146                 :             :         {
     147                 :           0 :                 xl_end_of_recovery xlrec;
     148                 :             : 
     149                 :           0 :                 memcpy(&xlrec, rec, sizeof(xl_end_of_recovery));
     150                 :           0 :                 appendStringInfo(buf, "tli %u; prev tli %u; time %s; wal_level %s",
     151                 :           0 :                                                  xlrec.ThisTimeLineID, xlrec.PrevTimeLineID,
     152                 :           0 :                                                  timestamptz_to_str(xlrec.end_time),
     153                 :           0 :                                                  get_wal_level_string(xlrec.wal_level));
     154                 :           0 :         }
     155         [ #  # ]:           0 :         else if (info == XLOG_OVERWRITE_CONTRECORD)
     156                 :             :         {
     157                 :           0 :                 xl_overwrite_contrecord xlrec;
     158                 :             : 
     159                 :           0 :                 memcpy(&xlrec, rec, sizeof(xl_overwrite_contrecord));
     160                 :           0 :                 appendStringInfo(buf, "lsn %X/%08X; time %s",
     161                 :           0 :                                                  LSN_FORMAT_ARGS(xlrec.overwritten_lsn),
     162                 :           0 :                                                  timestamptz_to_str(xlrec.overwrite_time));
     163                 :           0 :         }
     164         [ #  # ]:           0 :         else if (info == XLOG_CHECKPOINT_REDO)
     165                 :             :         {
     166                 :           0 :                 int                     wal_level;
     167                 :             : 
     168                 :           0 :                 memcpy(&wal_level, rec, sizeof(int));
     169                 :           0 :                 appendStringInfo(buf, "wal_level %s", get_wal_level_string(wal_level));
     170                 :           0 :         }
     171         [ #  # ]:           0 :         else if (info == XLOG_LOGICAL_DECODING_STATUS_CHANGE)
     172                 :             :         {
     173                 :           0 :                 bool            enabled;
     174                 :             : 
     175                 :           0 :                 memcpy(&enabled, rec, sizeof(bool));
     176                 :           0 :                 appendStringInfoString(buf, enabled ? "true" : "false");
     177                 :           0 :         }
     178                 :           0 : }
     179                 :             : 
     180                 :             : const char *
     181                 :           0 : xlog_identify(uint8 info)
     182                 :             : {
     183                 :           0 :         const char *id = NULL;
     184                 :             : 
     185   [ #  #  #  #  :           0 :         switch (info & ~XLR_INFO_MASK)
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     186                 :             :         {
     187                 :             :                 case XLOG_CHECKPOINT_SHUTDOWN:
     188                 :           0 :                         id = "CHECKPOINT_SHUTDOWN";
     189                 :           0 :                         break;
     190                 :             :                 case XLOG_CHECKPOINT_ONLINE:
     191                 :           0 :                         id = "CHECKPOINT_ONLINE";
     192                 :           0 :                         break;
     193                 :             :                 case XLOG_NOOP:
     194                 :           0 :                         id = "NOOP";
     195                 :           0 :                         break;
     196                 :             :                 case XLOG_NEXTOID:
     197                 :           0 :                         id = "NEXTOID";
     198                 :           0 :                         break;
     199                 :             :                 case XLOG_SWITCH:
     200                 :           0 :                         id = "SWITCH";
     201                 :           0 :                         break;
     202                 :             :                 case XLOG_BACKUP_END:
     203                 :           0 :                         id = "BACKUP_END";
     204                 :           0 :                         break;
     205                 :             :                 case XLOG_PARAMETER_CHANGE:
     206                 :           0 :                         id = "PARAMETER_CHANGE";
     207                 :           0 :                         break;
     208                 :             :                 case XLOG_RESTORE_POINT:
     209                 :           0 :                         id = "RESTORE_POINT";
     210                 :           0 :                         break;
     211                 :             :                 case XLOG_FPW_CHANGE:
     212                 :           0 :                         id = "FPW_CHANGE";
     213                 :           0 :                         break;
     214                 :             :                 case XLOG_END_OF_RECOVERY:
     215                 :           0 :                         id = "END_OF_RECOVERY";
     216                 :           0 :                         break;
     217                 :             :                 case XLOG_OVERWRITE_CONTRECORD:
     218                 :           0 :                         id = "OVERWRITE_CONTRECORD";
     219                 :           0 :                         break;
     220                 :             :                 case XLOG_FPI:
     221                 :           0 :                         id = "FPI";
     222                 :           0 :                         break;
     223                 :             :                 case XLOG_FPI_FOR_HINT:
     224                 :           0 :                         id = "FPI_FOR_HINT";
     225                 :           0 :                         break;
     226                 :             :                 case XLOG_CHECKPOINT_REDO:
     227                 :           0 :                         id = "CHECKPOINT_REDO";
     228                 :           0 :                         break;
     229                 :             :                 case XLOG_LOGICAL_DECODING_STATUS_CHANGE:
     230                 :           0 :                         id = "LOGICAL_DECODING_STATUS_CHANGE";
     231                 :           0 :                         break;
     232                 :             :         }
     233                 :             : 
     234                 :           0 :         return id;
     235                 :           0 : }
     236                 :             : 
     237                 :             : /*
     238                 :             :  * Returns a string giving information about all the blocks in an
     239                 :             :  * XLogRecord.
     240                 :             :  */
     241                 :             : void
     242                 :           0 : XLogRecGetBlockRefInfo(XLogReaderState *record, bool pretty,
     243                 :             :                                            bool detailed_format, StringInfo buf,
     244                 :             :                                            uint32 *fpi_len)
     245                 :             : {
     246                 :           0 :         int                     block_id;
     247                 :             : 
     248         [ #  # ]:           0 :         Assert(record != NULL);
     249                 :             : 
     250   [ #  #  #  # ]:           0 :         if (detailed_format && pretty)
     251                 :           0 :                 appendStringInfoChar(buf, '\n');
     252                 :             : 
     253         [ #  # ]:           0 :         for (block_id = 0; block_id <= XLogRecMaxBlockId(record); block_id++)
     254                 :             :         {
     255                 :           0 :                 RelFileLocator rlocator;
     256                 :           0 :                 ForkNumber      forknum;
     257                 :           0 :                 BlockNumber blk;
     258                 :             : 
     259         [ #  # ]:           0 :                 if (!XLogRecGetBlockTagExtended(record, block_id,
     260                 :             :                                                                                 &rlocator, &forknum, &blk, NULL))
     261                 :           0 :                         continue;
     262                 :             : 
     263         [ #  # ]:           0 :                 if (detailed_format)
     264                 :             :                 {
     265                 :             :                         /* Get block references in detailed format. */
     266                 :             : 
     267         [ #  # ]:           0 :                         if (pretty)
     268                 :           0 :                                 appendStringInfoChar(buf, '\t');
     269         [ #  # ]:           0 :                         else if (block_id > 0)
     270                 :           0 :                                 appendStringInfoChar(buf, ' ');
     271                 :             : 
     272                 :           0 :                         appendStringInfo(buf,
     273                 :             :                                                          "blkref #%d: rel %u/%u/%u fork %s blk %u",
     274                 :           0 :                                                          block_id,
     275                 :           0 :                                                          rlocator.spcOid, rlocator.dbOid, rlocator.relNumber,
     276                 :           0 :                                                          forkNames[forknum],
     277                 :           0 :                                                          blk);
     278                 :             : 
     279         [ #  # ]:           0 :                         if (XLogRecHasBlockImage(record, block_id))
     280                 :             :                         {
     281                 :           0 :                                 uint8           bimg_info = XLogRecGetBlock(record, block_id)->bimg_info;
     282                 :             : 
     283                 :             :                                 /* Calculate the amount of FPI data in the record. */
     284         [ #  # ]:           0 :                                 if (fpi_len)
     285                 :           0 :                                         *fpi_len += XLogRecGetBlock(record, block_id)->bimg_len;
     286                 :             : 
     287         [ #  # ]:           0 :                                 if (BKPIMAGE_COMPRESSED(bimg_info))
     288                 :             :                                 {
     289                 :           0 :                                         const char *method;
     290                 :             : 
     291         [ #  # ]:           0 :                                         if ((bimg_info & BKPIMAGE_COMPRESS_PGLZ) != 0)
     292                 :           0 :                                                 method = "pglz";
     293         [ #  # ]:           0 :                                         else if ((bimg_info & BKPIMAGE_COMPRESS_LZ4) != 0)
     294                 :           0 :                                                 method = "lz4";
     295         [ #  # ]:           0 :                                         else if ((bimg_info & BKPIMAGE_COMPRESS_ZSTD) != 0)
     296                 :           0 :                                                 method = "zstd";
     297                 :             :                                         else
     298                 :           0 :                                                 method = "unknown";
     299                 :             : 
     300                 :           0 :                                         appendStringInfo(buf,
     301                 :             :                                                                          " (FPW%s); hole: offset: %u, length: %u, "
     302                 :             :                                                                          "compression saved: %u, method: %s",
     303                 :           0 :                                                                          XLogRecBlockImageApply(record, block_id) ?
     304                 :             :                                                                          "" : " for WAL verification",
     305                 :           0 :                                                                          XLogRecGetBlock(record, block_id)->hole_offset,
     306                 :           0 :                                                                          XLogRecGetBlock(record, block_id)->hole_length,
     307                 :           0 :                                                                          BLCKSZ -
     308                 :           0 :                                                                          XLogRecGetBlock(record, block_id)->hole_length -
     309                 :           0 :                                                                          XLogRecGetBlock(record, block_id)->bimg_len,
     310                 :           0 :                                                                          method);
     311                 :           0 :                                 }
     312                 :             :                                 else
     313                 :             :                                 {
     314                 :           0 :                                         appendStringInfo(buf,
     315                 :             :                                                                          " (FPW%s); hole: offset: %u, length: %u",
     316                 :           0 :                                                                          XLogRecBlockImageApply(record, block_id) ?
     317                 :             :                                                                          "" : " for WAL verification",
     318                 :           0 :                                                                          XLogRecGetBlock(record, block_id)->hole_offset,
     319                 :           0 :                                                                          XLogRecGetBlock(record, block_id)->hole_length);
     320                 :             :                                 }
     321                 :           0 :                         }
     322                 :             : 
     323         [ #  # ]:           0 :                         if (pretty)
     324                 :           0 :                                 appendStringInfoChar(buf, '\n');
     325                 :           0 :                 }
     326                 :             :                 else
     327                 :             :                 {
     328                 :             :                         /* Get block references in short format. */
     329                 :             : 
     330         [ #  # ]:           0 :                         if (forknum != MAIN_FORKNUM)
     331                 :             :                         {
     332                 :           0 :                                 appendStringInfo(buf,
     333                 :             :                                                                  ", blkref #%d: rel %u/%u/%u fork %s blk %u",
     334                 :           0 :                                                                  block_id,
     335                 :           0 :                                                                  rlocator.spcOid, rlocator.dbOid, rlocator.relNumber,
     336                 :           0 :                                                                  forkNames[forknum],
     337                 :           0 :                                                                  blk);
     338                 :           0 :                         }
     339                 :             :                         else
     340                 :             :                         {
     341                 :           0 :                                 appendStringInfo(buf,
     342                 :             :                                                                  ", blkref #%d: rel %u/%u/%u blk %u",
     343                 :           0 :                                                                  block_id,
     344                 :           0 :                                                                  rlocator.spcOid, rlocator.dbOid, rlocator.relNumber,
     345                 :           0 :                                                                  blk);
     346                 :             :                         }
     347                 :             : 
     348         [ #  # ]:           0 :                         if (XLogRecHasBlockImage(record, block_id))
     349                 :             :                         {
     350                 :             :                                 /* Calculate the amount of FPI data in the record. */
     351         [ #  # ]:           0 :                                 if (fpi_len)
     352                 :           0 :                                         *fpi_len += XLogRecGetBlock(record, block_id)->bimg_len;
     353                 :             : 
     354         [ #  # ]:           0 :                                 if (XLogRecBlockImageApply(record, block_id))
     355                 :           0 :                                         appendStringInfoString(buf, " FPW");
     356                 :             :                                 else
     357                 :           0 :                                         appendStringInfoString(buf, " FPW for WAL verification");
     358                 :           0 :                         }
     359                 :             :                 }
     360      [ #  #  # ]:           0 :         }
     361                 :             : 
     362   [ #  #  #  # ]:           0 :         if (!detailed_format && pretty)
     363                 :           0 :                 appendStringInfoChar(buf, '\n');
     364                 :           0 : }
        

Generated by: LCOV version 2.3.2-1