4
* reads the data from $PGDATA/global/pg_control
6
* copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001;
11
#include "postgres_fe.h"
18
#include "catalog/pg_control.h"
22
usage(const char *progname)
24
printf(_("%s displays control information of a PostgreSQL database cluster.\n\n"), progname);
29
" %s [OPTION] [DATADIR]\n\n"
31
" --help show this help, then exit\n"
32
" --version output version information, then exit\n"
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"));
43
dbState(DBState state)
48
return _("starting up");
50
return _("shut down");
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");
65
main(int argc, char *argv[])
67
ControlFileData ControlFile;
69
char ControlFilePath[MAXPGPATH];
73
char pgctime_str[128];
74
char ckpttime_str[128];
75
char sysident_str[32];
76
const char *strftime_fmt = "%c";
79
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_controldata"));
81
progname = get_progname(argv[0]);
85
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
90
if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
92
puts("pg_controldata (PostgreSQL) " PG_VERSION);
100
DataDir = getenv("PGDATA");
103
fprintf(stderr, _("%s: no data directory specified\n"), progname);
104
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
108
snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
110
if ((fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0)) == -1)
112
fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
113
progname, ControlFilePath, strerror(errno));
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));
128
(char *) &ControlFile,
129
offsetof(ControlFileData, 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
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"),
171
printf(_("Database cluster state: %s\n"),
172
dbState(ControlFile.state));
173
printf(_("pg_control last modified: %s\n"),
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"),
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"),
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")));