LCOV - differential code coverage report
Current view: top level - src/backend/access/rmgrdesc - xlogdesc.c (source / functions) Coverage Total Hit UNC UBC GNC CBC DUB
Current: Differential Code Coverage HEAD vs 15 Lines: 64.0 % 136 87 2 47 87 2
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 3 3 1 2
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

Generated by: LCOV version v1.16-55-g56c0a2a