LCOV - differential code coverage report
Current view: top level - src/bin/pg_controldata - pg_controldata.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 87.3 % 142 124 18 124
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 4 4 4
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*
       2                 :  * pg_controldata
       3                 :  *
       4                 :  * reads the data from $PGDATA/global/pg_control
       5                 :  *
       6                 :  * copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001;
       7                 :  * license: BSD
       8                 :  *
       9                 :  * src/bin/pg_controldata/pg_controldata.c
      10                 :  */
      11                 : 
      12                 : /*
      13                 :  * We have to use postgres.h not postgres_fe.h here, because there's so much
      14                 :  * backend-only stuff in the XLOG include files we need.  But we need a
      15                 :  * frontend-ish environment otherwise.  Hence this ugly hack.
      16                 :  */
      17                 : #define FRONTEND 1
      18                 : 
      19                 : #include "postgres.h"
      20                 : 
      21                 : #include <time.h>
      22                 : 
      23                 : #include "access/transam.h"
      24                 : #include "access/xlog.h"
      25                 : #include "access/xlog_internal.h"
      26                 : #include "catalog/pg_control.h"
      27                 : #include "common/controldata_utils.h"
      28                 : #include "common/logging.h"
      29                 : #include "getopt_long.h"
      30                 : #include "pg_getopt.h"
      31                 : 
      32                 : static void
      33 CBC           1 : usage(const char *progname)
      34                 : {
      35               1 :     printf(_("%s displays control information of a PostgreSQL database cluster.\n\n"), progname);
      36               1 :     printf(_("Usage:\n"));
      37               1 :     printf(_("  %s [OPTION] [DATADIR]\n"), progname);
      38               1 :     printf(_("\nOptions:\n"));
      39               1 :     printf(_(" [-D, --pgdata=]DATADIR  data directory\n"));
      40               1 :     printf(_("  -V, --version          output version information, then exit\n"));
      41               1 :     printf(_("  -?, --help             show this help, then exit\n"));
      42               1 :     printf(_("\nIf no data directory (DATADIR) is specified, "
      43                 :              "the environment variable PGDATA\nis used.\n\n"));
      44               1 :     printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
      45               1 :     printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
      46               1 : }
      47                 : 
      48                 : 
      49                 : static const char *
      50              14 : dbState(DBState state)
      51                 : {
      52              14 :     switch (state)
      53                 :     {
      54               1 :         case DB_STARTUP:
      55               1 :             return _("starting up");
      56              11 :         case DB_SHUTDOWNED:
      57              11 :             return _("shut down");
      58               2 :         case DB_SHUTDOWNED_IN_RECOVERY:
      59               2 :             return _("shut down in recovery");
      60 UBC           0 :         case DB_SHUTDOWNING:
      61               0 :             return _("shutting down");
      62               0 :         case DB_IN_CRASH_RECOVERY:
      63               0 :             return _("in crash recovery");
      64               0 :         case DB_IN_ARCHIVE_RECOVERY:
      65               0 :             return _("in archive recovery");
      66               0 :         case DB_IN_PRODUCTION:
      67               0 :             return _("in production");
      68                 :     }
      69               0 :     return _("unrecognized status code");
      70                 : }
      71                 : 
      72                 : static const char *
      73 CBC          14 : wal_level_str(WalLevel wal_level)
      74                 : {
      75              14 :     switch (wal_level)
      76                 :     {
      77               4 :         case WAL_LEVEL_MINIMAL:
      78               4 :             return "minimal";
      79              10 :         case WAL_LEVEL_REPLICA:
      80              10 :             return "replica";
      81 UBC           0 :         case WAL_LEVEL_LOGICAL:
      82               0 :             return "logical";
      83                 :     }
      84               0 :     return _("unrecognized wal_level");
      85                 : }
      86                 : 
      87                 : 
      88                 : int
      89 CBC          23 : main(int argc, char *argv[])
      90                 : {
      91                 :     static struct option long_options[] = {
      92                 :         {"pgdata", required_argument, NULL, 'D'},
      93                 :         {NULL, 0, NULL, 0}
      94                 :     };
      95                 : 
      96                 :     ControlFileData *ControlFile;
      97                 :     bool        crc_ok;
      98              23 :     char       *DataDir = NULL;
      99                 :     time_t      time_tmp;
     100                 :     char        pgctime_str[128];
     101                 :     char        ckpttime_str[128];
     102                 :     char        mock_auth_nonce_str[MOCK_AUTH_NONCE_LEN * 2 + 1];
     103              23 :     const char *strftime_fmt = "%c";
     104                 :     const char *progname;
     105                 :     char        xlogfilename[MAXFNAMELEN];
     106                 :     int         c;
     107                 :     int         i;
     108                 :     int         WalSegSz;
     109                 : 
     110              23 :     pg_logging_init(argv[0]);
     111              23 :     set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_controldata"));
     112              23 :     progname = get_progname(argv[0]);
     113                 : 
     114              23 :     if (argc > 1)
     115                 :     {
     116              22 :         if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
     117                 :         {
     118               1 :             usage(progname);
     119               1 :             exit(0);
     120                 :         }
     121              21 :         if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
     122                 :         {
     123               5 :             puts("pg_controldata (PostgreSQL) " PG_VERSION);
     124               5 :             exit(0);
     125                 :         }
     126                 :     }
     127                 : 
     128              17 :     while ((c = getopt_long(argc, argv, "D:", long_options, NULL)) != -1)
     129                 :     {
     130               1 :         switch (c)
     131                 :         {
     132 UBC           0 :             case 'D':
     133               0 :                 DataDir = optarg;
     134               0 :                 break;
     135                 : 
     136 CBC           1 :             default:
     137                 :                 /* getopt_long already emitted a complaint */
     138               1 :                 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
     139               1 :                 exit(1);
     140                 :         }
     141                 :     }
     142                 : 
     143              16 :     if (DataDir == NULL)
     144                 :     {
     145              16 :         if (optind < argc)
     146              15 :             DataDir = argv[optind++];
     147                 :         else
     148               1 :             DataDir = getenv("PGDATA");
     149                 :     }
     150                 : 
     151                 :     /* Complain if any arguments remain */
     152              16 :     if (optind < argc)
     153                 :     {
     154 UBC           0 :         pg_log_error("too many command-line arguments (first is \"%s\")",
     155                 :                      argv[optind]);
     156               0 :         pg_log_error_hint("Try \"%s --help\" for more information.", progname);
     157               0 :         exit(1);
     158                 :     }
     159                 : 
     160 CBC          16 :     if (DataDir == NULL)
     161                 :     {
     162               1 :         pg_log_error("no data directory specified");
     163               1 :         pg_log_error_hint("Try \"%s --help\" for more information.", progname);
     164               1 :         exit(1);
     165                 :     }
     166                 : 
     167                 :     /* get a copy of the control file */
     168              15 :     ControlFile = get_controlfile(DataDir, &crc_ok);
     169              14 :     if (!crc_ok)
     170               1 :         printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n"
     171                 :                  "Either the file is corrupt, or it has a different layout than this program\n"
     172                 :                  "is expecting.  The results below are untrustworthy.\n\n"));
     173                 : 
     174                 :     /* set wal segment size */
     175              14 :     WalSegSz = ControlFile->xlog_seg_size;
     176                 : 
     177              14 :     if (!IsValidWalSegSize(WalSegSz))
     178                 :     {
     179               1 :         printf(_("WARNING: invalid WAL segment size\n"));
     180               1 :         printf(ngettext("The WAL segment size stored in the file, %d byte, is not a power of two\n"
     181                 :                         "between 1 MB and 1 GB.  The file is corrupt and the results below are\n"
     182                 :                         "untrustworthy.\n\n",
     183                 :                         "The WAL segment size stored in the file, %d bytes, is not a power of two\n"
     184                 :                         "between 1 MB and 1 GB.  The file is corrupt and the results below are\n"
     185                 :                         "untrustworthy.\n\n",
     186                 :                         WalSegSz),
     187                 :                WalSegSz);
     188                 :     }
     189                 : 
     190                 :     /*
     191                 :      * This slightly-chintzy coding will work as long as the control file
     192                 :      * timestamps are within the range of time_t; that should be the case in
     193                 :      * all foreseeable circumstances, so we don't bother importing the
     194                 :      * backend's timezone library into pg_controldata.
     195                 :      *
     196                 :      * Use variable for format to suppress overly-anal-retentive gcc warning
     197                 :      * about %c
     198                 :      */
     199              14 :     time_tmp = (time_t) ControlFile->time;
     200              14 :     strftime(pgctime_str, sizeof(pgctime_str), strftime_fmt,
     201              14 :              localtime(&time_tmp));
     202              14 :     time_tmp = (time_t) ControlFile->checkPointCopy.time;
     203              14 :     strftime(ckpttime_str, sizeof(ckpttime_str), strftime_fmt,
     204              14 :              localtime(&time_tmp));
     205                 : 
     206                 :     /*
     207                 :      * Calculate name of the WAL file containing the latest checkpoint's REDO
     208                 :      * start point.
     209                 :      *
     210                 :      * A corrupted control file could report a WAL segment size of 0, and to
     211                 :      * guard against division by zero, we need to treat that specially.
     212                 :      */
     213              14 :     if (WalSegSz != 0)
     214                 :     {
     215                 :         XLogSegNo   segno;
     216                 : 
     217              13 :         XLByteToSeg(ControlFile->checkPointCopy.redo, segno, WalSegSz);
     218              13 :         XLogFileName(xlogfilename, ControlFile->checkPointCopy.ThisTimeLineID,
     219                 :                      segno, WalSegSz);
     220                 :     }
     221                 :     else
     222               1 :         strcpy(xlogfilename, _("???"));
     223                 : 
     224             462 :     for (i = 0; i < MOCK_AUTH_NONCE_LEN; i++)
     225             448 :         snprintf(&mock_auth_nonce_str[i * 2], 3, "%02x",
     226             448 :                  (unsigned char) ControlFile->mock_authentication_nonce[i]);
     227                 : 
     228              14 :     printf(_("pg_control version number:            %u\n"),
     229                 :            ControlFile->pg_control_version);
     230              14 :     printf(_("Catalog version number:               %u\n"),
     231                 :            ControlFile->catalog_version_no);
     232              14 :     printf(_("Database system identifier:           %llu\n"),
     233                 :            (unsigned long long) ControlFile->system_identifier);
     234              14 :     printf(_("Database cluster state:               %s\n"),
     235                 :            dbState(ControlFile->state));
     236              14 :     printf(_("pg_control last modified:             %s\n"),
     237                 :            pgctime_str);
     238              14 :     printf(_("Latest checkpoint location:           %X/%X\n"),
     239                 :            LSN_FORMAT_ARGS(ControlFile->checkPoint));
     240              14 :     printf(_("Latest checkpoint's REDO location:    %X/%X\n"),
     241                 :            LSN_FORMAT_ARGS(ControlFile->checkPointCopy.redo));
     242              14 :     printf(_("Latest checkpoint's REDO WAL file:    %s\n"),
     243                 :            xlogfilename);
     244              14 :     printf(_("Latest checkpoint's TimeLineID:       %u\n"),
     245                 :            ControlFile->checkPointCopy.ThisTimeLineID);
     246              14 :     printf(_("Latest checkpoint's PrevTimeLineID:   %u\n"),
     247                 :            ControlFile->checkPointCopy.PrevTimeLineID);
     248              14 :     printf(_("Latest checkpoint's full_page_writes: %s\n"),
     249                 :            ControlFile->checkPointCopy.fullPageWrites ? _("on") : _("off"));
     250              14 :     printf(_("Latest checkpoint's NextXID:          %u:%u\n"),
     251                 :            EpochFromFullTransactionId(ControlFile->checkPointCopy.nextXid),
     252                 :            XidFromFullTransactionId(ControlFile->checkPointCopy.nextXid));
     253              14 :     printf(_("Latest checkpoint's NextOID:          %u\n"),
     254                 :            ControlFile->checkPointCopy.nextOid);
     255              14 :     printf(_("Latest checkpoint's NextMultiXactId:  %u\n"),
     256                 :            ControlFile->checkPointCopy.nextMulti);
     257              14 :     printf(_("Latest checkpoint's NextMultiOffset:  %u\n"),
     258                 :            ControlFile->checkPointCopy.nextMultiOffset);
     259              14 :     printf(_("Latest checkpoint's oldestXID:        %u\n"),
     260                 :            ControlFile->checkPointCopy.oldestXid);
     261              14 :     printf(_("Latest checkpoint's oldestXID's DB:   %u\n"),
     262                 :            ControlFile->checkPointCopy.oldestXidDB);
     263              14 :     printf(_("Latest checkpoint's oldestActiveXID:  %u\n"),
     264                 :            ControlFile->checkPointCopy.oldestActiveXid);
     265              14 :     printf(_("Latest checkpoint's oldestMultiXid:   %u\n"),
     266                 :            ControlFile->checkPointCopy.oldestMulti);
     267              14 :     printf(_("Latest checkpoint's oldestMulti's DB: %u\n"),
     268                 :            ControlFile->checkPointCopy.oldestMultiDB);
     269              14 :     printf(_("Latest checkpoint's oldestCommitTsXid:%u\n"),
     270                 :            ControlFile->checkPointCopy.oldestCommitTsXid);
     271              14 :     printf(_("Latest checkpoint's newestCommitTsXid:%u\n"),
     272                 :            ControlFile->checkPointCopy.newestCommitTsXid);
     273              14 :     printf(_("Time of latest checkpoint:            %s\n"),
     274                 :            ckpttime_str);
     275              14 :     printf(_("Fake LSN counter for unlogged rels:   %X/%X\n"),
     276                 :            LSN_FORMAT_ARGS(ControlFile->unloggedLSN));
     277              14 :     printf(_("Minimum recovery ending location:     %X/%X\n"),
     278                 :            LSN_FORMAT_ARGS(ControlFile->minRecoveryPoint));
     279              14 :     printf(_("Min recovery ending loc's timeline:   %u\n"),
     280                 :            ControlFile->minRecoveryPointTLI);
     281              14 :     printf(_("Backup start location:                %X/%X\n"),
     282                 :            LSN_FORMAT_ARGS(ControlFile->backupStartPoint));
     283              14 :     printf(_("Backup end location:                  %X/%X\n"),
     284                 :            LSN_FORMAT_ARGS(ControlFile->backupEndPoint));
     285              14 :     printf(_("End-of-backup record required:        %s\n"),
     286                 :            ControlFile->backupEndRequired ? _("yes") : _("no"));
     287              14 :     printf(_("wal_level setting:                    %s\n"),
     288                 :            wal_level_str(ControlFile->wal_level));
     289              14 :     printf(_("wal_log_hints setting:                %s\n"),
     290                 :            ControlFile->wal_log_hints ? _("on") : _("off"));
     291              14 :     printf(_("max_connections setting:              %d\n"),
     292                 :            ControlFile->MaxConnections);
     293              14 :     printf(_("max_worker_processes setting:         %d\n"),
     294                 :            ControlFile->max_worker_processes);
     295              14 :     printf(_("max_wal_senders setting:              %d\n"),
     296                 :            ControlFile->max_wal_senders);
     297              14 :     printf(_("max_prepared_xacts setting:           %d\n"),
     298                 :            ControlFile->max_prepared_xacts);
     299              14 :     printf(_("max_locks_per_xact setting:           %d\n"),
     300                 :            ControlFile->max_locks_per_xact);
     301              14 :     printf(_("track_commit_timestamp setting:       %s\n"),
     302                 :            ControlFile->track_commit_timestamp ? _("on") : _("off"));
     303              14 :     printf(_("Maximum data alignment:               %u\n"),
     304                 :            ControlFile->maxAlign);
     305                 :     /* we don't print floatFormat since can't say much useful about it */
     306              14 :     printf(_("Database block size:                  %u\n"),
     307                 :            ControlFile->blcksz);
     308              14 :     printf(_("Blocks per segment of large relation: %u\n"),
     309                 :            ControlFile->relseg_size);
     310              14 :     printf(_("WAL block size:                       %u\n"),
     311                 :            ControlFile->xlog_blcksz);
     312              14 :     printf(_("Bytes per WAL segment:                %u\n"),
     313                 :            ControlFile->xlog_seg_size);
     314              14 :     printf(_("Maximum length of identifiers:        %u\n"),
     315                 :            ControlFile->nameDataLen);
     316              14 :     printf(_("Maximum columns in an index:          %u\n"),
     317                 :            ControlFile->indexMaxKeys);
     318              14 :     printf(_("Maximum size of a TOAST chunk:        %u\n"),
     319                 :            ControlFile->toast_max_chunk_size);
     320              14 :     printf(_("Size of a large-object chunk:         %u\n"),
     321                 :            ControlFile->loblksize);
     322                 :     /* This is no longer configurable, but users may still expect to see it: */
     323              14 :     printf(_("Date/time type storage:               %s\n"),
     324                 :            _("64-bit integers"));
     325              14 :     printf(_("Float8 argument passing:              %s\n"),
     326                 :            (ControlFile->float8ByVal ? _("by value") : _("by reference")));
     327              14 :     printf(_("Data page checksum version:           %u\n"),
     328                 :            ControlFile->data_checksum_version);
     329              14 :     printf(_("Mock authentication nonce:            %s\n"),
     330                 :            mock_auth_nonce_str);
     331              14 :     return 0;
     332                 : }
        

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