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_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")));