]> granicus.if.org Git - postgresql/blob - src/bin/pg_controldata/pg_controldata.c
682a5cf380779646a197f9c6e3396e5624145630
[postgresql] / src / bin / pg_controldata / pg_controldata.c
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  * licence: BSD
8  *
9  * $PostgreSQL: pgsql/src/bin/pg_controldata/pg_controldata.c,v 1.36 2008/01/21 11:17:46 petere Exp $
10  */
11 #include "postgres.h"
12
13 #include <unistd.h>
14 #include <time.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17
18 #include "catalog/pg_control.h"
19
20
21 static void
22 usage(const char *progname)
23 {
24         printf(_("%s displays control information of a PostgreSQL database cluster.\n\n"), progname);
25         printf
26                 (
27                  _(
28                    "Usage:\n"
29                    "  %s [OPTION] [DATADIR]\n\n"
30                    "Options:\n"
31                    "  --help         show this help, then exit\n"
32                    "  --version      output version information, then exit\n"
33                    ),
34                  progname
35                 );
36         printf(_("\nIf no data directory (DATADIR) is specified, "
37                          "the environment variable PGDATA\nis used.\n\n"));
38         printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
39 }
40
41
42 static const char *
43 dbState(DBState state)
44 {
45         switch (state)
46         {
47                 case DB_STARTUP:
48                         return _("starting up");
49                 case DB_SHUTDOWNED:
50                         return _("shut down");
51                 case DB_SHUTDOWNING:
52                         return _("shutting down");
53                 case DB_IN_CRASH_RECOVERY:
54                         return _("in crash recovery");
55                 case DB_IN_ARCHIVE_RECOVERY:
56                         return _("in archive recovery");
57                 case DB_IN_PRODUCTION:
58                         return _("in production");
59         }
60         return _("unrecognized status code");
61 }
62
63
64 int
65 main(int argc, char *argv[])
66 {
67         ControlFileData ControlFile;
68         int                     fd;
69         char            ControlFilePath[MAXPGPATH];
70         char       *DataDir;
71         pg_crc32        crc;
72         char            pgctime_str[128];
73         char            ckpttime_str[128];
74         char            sysident_str[32];
75         const char *strftime_fmt = "%c";
76         const char *progname;
77
78         set_pglocale_pgservice(argv[0], "pg_controldata");
79
80         progname = get_progname(argv[0]);
81
82         if (argc > 1)
83         {
84                 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
85                 {
86                         usage(progname);
87                         exit(0);
88                 }
89                 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
90                 {
91                         puts("pg_controldata (PostgreSQL) " PG_VERSION);
92                         exit(0);
93                 }
94         }
95
96         if (argc > 1)
97                 DataDir = argv[1];
98         else
99                 DataDir = getenv("PGDATA");
100         if (DataDir == NULL)
101         {
102                 fprintf(stderr, _("%s: no data directory specified\n"), progname);
103                 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
104                 exit(1);
105         }
106
107         snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
108
109         if ((fd = open(ControlFilePath, O_RDONLY, 0)) == -1)
110         {
111                 fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
112                                 progname, ControlFilePath, strerror(errno));
113                 exit(2);
114         }
115
116         if (read(fd, &ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData))
117         {
118                 fprintf(stderr, _("%s: could not read file \"%s\": %s\n"),
119                                 progname, ControlFilePath, strerror(errno));
120                 exit(2);
121         }
122         close(fd);
123
124         /* Check the CRC. */
125         INIT_CRC32(crc);
126         COMP_CRC32(crc,
127                            (char *) &ControlFile,
128                            offsetof(ControlFileData, crc));
129         FIN_CRC32(crc);
130
131         if (!EQ_CRC32(crc, ControlFile.crc))
132                 printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n"
133                                  "Either the file is corrupt, or it has a different layout than this program\n"
134                                  "is expecting.  The results below are untrustworthy.\n\n"));
135
136         /*
137          * Use variable for format to suppress overly-anal-retentive gcc warning
138          * about %c
139          */
140         strftime(pgctime_str, sizeof(pgctime_str), strftime_fmt,
141                          localtime(&(ControlFile.time)));
142         strftime(ckpttime_str, sizeof(ckpttime_str), strftime_fmt,
143                          localtime(&(ControlFile.checkPointCopy.time)));
144
145         /*
146          * Format system_identifier separately to keep platform-dependent format
147          * code out of the translatable message string.
148          */
149         snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
150                          ControlFile.system_identifier);
151
152         printf(_("pg_control version number:            %u\n"),
153                    ControlFile.pg_control_version);
154         if (ControlFile.pg_control_version % 65536 == 0 && ControlFile.pg_control_version / 65536 != 0)
155                 printf(_("WARNING: possible byte ordering mismatch\n"
156                                  "The byte ordering used to store the pg_control file might not match the one\n"
157                                  "used by this program.  In that case the results below would be incorrect, and\n"
158                                  "the PostgreSQL installation would be incompatible with this data directory.\n"));
159         printf(_("Catalog version number:               %u\n"),
160                    ControlFile.catalog_version_no);
161         printf(_("Database system identifier:           %s\n"),
162                    sysident_str);
163         printf(_("Database cluster state:               %s\n"),
164                    dbState(ControlFile.state));
165         printf(_("pg_control last modified:             %s\n"),
166                    pgctime_str);
167         printf(_("Latest checkpoint location:           %X/%X\n"),
168                    ControlFile.checkPoint.xlogid,
169                    ControlFile.checkPoint.xrecoff);
170         printf(_("Prior checkpoint location:            %X/%X\n"),
171                    ControlFile.prevCheckPoint.xlogid,
172                    ControlFile.prevCheckPoint.xrecoff);
173         printf(_("Latest checkpoint's REDO location:    %X/%X\n"),
174                    ControlFile.checkPointCopy.redo.xlogid,
175                    ControlFile.checkPointCopy.redo.xrecoff);
176         printf(_("Latest checkpoint's TimeLineID:       %u\n"),
177                    ControlFile.checkPointCopy.ThisTimeLineID);
178         printf(_("Latest checkpoint's NextXID:          %u/%u\n"),
179                    ControlFile.checkPointCopy.nextXidEpoch,
180                    ControlFile.checkPointCopy.nextXid);
181         printf(_("Latest checkpoint's NextOID:          %u\n"),
182                    ControlFile.checkPointCopy.nextOid);
183         printf(_("Latest checkpoint's NextMultiXactId:  %u\n"),
184                    ControlFile.checkPointCopy.nextMulti);
185         printf(_("Latest checkpoint's NextMultiOffset:  %u\n"),
186                    ControlFile.checkPointCopy.nextMultiOffset);
187         printf(_("Time of latest checkpoint:            %s\n"),
188                    ckpttime_str);
189         printf(_("Minimum recovery ending location:     %X/%X\n"),
190                    ControlFile.minRecoveryPoint.xlogid,
191                    ControlFile.minRecoveryPoint.xrecoff);
192         printf(_("Maximum data alignment:               %u\n"),
193                    ControlFile.maxAlign);
194         /* we don't print floatFormat since can't say much useful about it */
195         printf(_("Database block size:                  %u\n"),
196                    ControlFile.blcksz);
197         printf(_("Blocks per segment of large relation: %u\n"),
198                    ControlFile.relseg_size);
199         printf(_("WAL block size:                       %u\n"),
200                    ControlFile.xlog_blcksz);
201         printf(_("Bytes per WAL segment:                %u\n"),
202                    ControlFile.xlog_seg_size);
203         printf(_("Maximum length of identifiers:        %u\n"),
204                    ControlFile.nameDataLen);
205         printf(_("Maximum columns in an index:          %u\n"),
206                    ControlFile.indexMaxKeys);
207         printf(_("Maximum size of a TOAST chunk:        %u\n"),
208                    ControlFile.toast_max_chunk_size);
209         printf(_("Date/time type storage:               %s\n"),
210                    (ControlFile.enableIntTimes ? _("64-bit integers") : _("floating-point numbers")));
211         printf(_("Maximum length of locale name:        %u\n"),
212                    ControlFile.localeBuflen);
213         printf(_("LC_COLLATE:                           %s\n"),
214                    ControlFile.lc_collate);
215         printf(_("LC_CTYPE:                             %s\n"),
216                    ControlFile.lc_ctype);
217
218         return 0;
219 }