Make LC_COLLATE and LC_CTYPE database-level settings. Collation and
[PostgreSQL.git] / src / bin / pg_controldata / pg_controldata.c
blob08e102f391814dbf2d7cae719ab68f0e9e73c5a5
1 /*
2 * pg_controldata
4 * reads the data from $PGDATA/global/pg_control
6 * copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001;
7 * licence: BSD
9 * $PostgreSQL$
11 #include "postgres_fe.h"
13 #include <unistd.h>
14 #include <time.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
18 #include "catalog/pg_control.h"
21 static void
22 usage(const char *progname)
24 printf(_("%s displays control information of a PostgreSQL database cluster.\n\n"), progname);
25 printf
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"
34 progname
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"));
42 static const char *
43 dbState(DBState state)
45 switch (state)
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");
60 return _("unrecognized status code");
64 int
65 main(int argc, char *argv[])
67 ControlFileData ControlFile;
68 int fd;
69 char ControlFilePath[MAXPGPATH];
70 char *DataDir;
71 pg_crc32 crc;
72 time_t time_tmp;
73 char pgctime_str[128];
74 char ckpttime_str[128];
75 char sysident_str[32];
76 const char *strftime_fmt = "%c";
77 const char *progname;
79 set_pglocale_pgservice(argv[0], "pg_controldata");
81 progname = get_progname(argv[0]);
83 if (argc > 1)
85 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
87 usage(progname);
88 exit(0);
90 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
92 puts("pg_controldata (PostgreSQL) " PG_VERSION);
93 exit(0);
97 if (argc > 1)
98 DataDir = argv[1];
99 else
100 DataDir = getenv("PGDATA");
101 if (DataDir == NULL)
103 fprintf(stderr, _("%s: no data directory specified\n"), progname);
104 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
105 exit(1);
108 snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
110 if ((fd = open(ControlFilePath, O_RDONLY, 0)) == -1)
112 fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
113 progname, ControlFilePath, strerror(errno));
114 exit(2);
117 if (read(fd, &ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData))
119 fprintf(stderr, _("%s: could not read file \"%s\": %s\n"),
120 progname, ControlFilePath, strerror(errno));
121 exit(2);
123 close(fd);
125 /* Check the CRC. */
126 INIT_CRC32(crc);
127 COMP_CRC32(crc,
128 (char *) &ControlFile,
129 offsetof(ControlFileData, crc));
130 FIN_CRC32(crc);
132 if (!EQ_CRC32(crc, ControlFile.crc))
133 printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n"
134 "Either the file is corrupt, or it has a different layout than this program\n"
135 "is expecting. The results below are untrustworthy.\n\n"));
138 * This slightly-chintzy coding will work as long as the control file
139 * timestamps are within the range of time_t; that should be the case
140 * in all foreseeable circumstances, so we don't bother importing the
141 * backend's timezone library into pg_controldata.
143 * Use variable for format to suppress overly-anal-retentive gcc warning
144 * about %c
146 time_tmp = (time_t) ControlFile.time;
147 strftime(pgctime_str, sizeof(pgctime_str), strftime_fmt,
148 localtime(&time_tmp));
149 time_tmp = (time_t) ControlFile.checkPointCopy.time;
150 strftime(ckpttime_str, sizeof(ckpttime_str), strftime_fmt,
151 localtime(&time_tmp));
154 * Format system_identifier separately to keep platform-dependent format
155 * code out of the translatable message string.
157 snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
158 ControlFile.system_identifier);
160 printf(_("pg_control version number: %u\n"),
161 ControlFile.pg_control_version);
162 if (ControlFile.pg_control_version % 65536 == 0 && ControlFile.pg_control_version / 65536 != 0)
163 printf(_("WARNING: possible byte ordering mismatch\n"
164 "The byte ordering used to store the pg_control file might not match the one\n"
165 "used by this program. In that case the results below would be incorrect, and\n"
166 "the PostgreSQL installation would be incompatible with this data directory.\n"));
167 printf(_("Catalog version number: %u\n"),
168 ControlFile.catalog_version_no);
169 printf(_("Database system identifier: %s\n"),
170 sysident_str);
171 printf(_("Database cluster state: %s\n"),
172 dbState(ControlFile.state));
173 printf(_("pg_control last modified: %s\n"),
174 pgctime_str);
175 printf(_("Latest checkpoint location: %X/%X\n"),
176 ControlFile.checkPoint.xlogid,
177 ControlFile.checkPoint.xrecoff);
178 printf(_("Prior checkpoint location: %X/%X\n"),
179 ControlFile.prevCheckPoint.xlogid,
180 ControlFile.prevCheckPoint.xrecoff);
181 printf(_("Latest checkpoint's REDO location: %X/%X\n"),
182 ControlFile.checkPointCopy.redo.xlogid,
183 ControlFile.checkPointCopy.redo.xrecoff);
184 printf(_("Latest checkpoint's TimeLineID: %u\n"),
185 ControlFile.checkPointCopy.ThisTimeLineID);
186 printf(_("Latest checkpoint's NextXID: %u/%u\n"),
187 ControlFile.checkPointCopy.nextXidEpoch,
188 ControlFile.checkPointCopy.nextXid);
189 printf(_("Latest checkpoint's NextOID: %u\n"),
190 ControlFile.checkPointCopy.nextOid);
191 printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
192 ControlFile.checkPointCopy.nextMulti);
193 printf(_("Latest checkpoint's NextMultiOffset: %u\n"),
194 ControlFile.checkPointCopy.nextMultiOffset);
195 printf(_("Time of latest checkpoint: %s\n"),
196 ckpttime_str);
197 printf(_("Minimum recovery ending location: %X/%X\n"),
198 ControlFile.minRecoveryPoint.xlogid,
199 ControlFile.minRecoveryPoint.xrecoff);
200 printf(_("Maximum data alignment: %u\n"),
201 ControlFile.maxAlign);
202 /* we don't print floatFormat since can't say much useful about it */
203 printf(_("Database block size: %u\n"),
204 ControlFile.blcksz);
205 printf(_("Blocks per segment of large relation: %u\n"),
206 ControlFile.relseg_size);
207 printf(_("WAL block size: %u\n"),
208 ControlFile.xlog_blcksz);
209 printf(_("Bytes per WAL segment: %u\n"),
210 ControlFile.xlog_seg_size);
211 printf(_("Maximum length of identifiers: %u\n"),
212 ControlFile.nameDataLen);
213 printf(_("Maximum columns in an index: %u\n"),
214 ControlFile.indexMaxKeys);
215 printf(_("Maximum size of a TOAST chunk: %u\n"),
216 ControlFile.toast_max_chunk_size);
217 printf(_("Date/time type storage: %s\n"),
218 (ControlFile.enableIntTimes ? _("64-bit integers") : _("floating-point numbers")));
219 printf(_("Float4 argument passing: %s\n"),
220 (ControlFile.float4ByVal ? _("by value") : _("by reference")));
221 printf(_("Float8 argument passing: %s\n"),
222 (ControlFile.float8ByVal ? _("by value") : _("by reference")));
223 return 0;