00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #define FRONTEND 1
00018
00019 #include "postgres.h"
00020
00021 #include <unistd.h>
00022 #include <time.h>
00023 #include <sys/stat.h>
00024 #include <fcntl.h>
00025
00026 #include "access/xlog.h"
00027 #include "access/xlog_internal.h"
00028 #include "catalog/pg_control.h"
00029
00030
00031 static void
00032 usage(const char *progname)
00033 {
00034 printf(_("%s displays control information of a PostgreSQL database cluster.\n\n"), progname);
00035 printf(_("Usage:\n"));
00036 printf(_(" %s [OPTION] [DATADIR]\n"), progname);
00037 printf(_("\nOptions:\n"));
00038 printf(_(" -V, --version output version information, then exit\n"));
00039 printf(_(" -?, --help show this help, then exit\n"));
00040 printf(_("\nIf no data directory (DATADIR) is specified, "
00041 "the environment variable PGDATA\nis used.\n\n"));
00042 printf(_("Report bugs to <[email protected]>.\n"));
00043 }
00044
00045
00046 static const char *
00047 dbState(DBState state)
00048 {
00049 switch (state)
00050 {
00051 case DB_STARTUP:
00052 return _("starting up");
00053 case DB_SHUTDOWNED:
00054 return _("shut down");
00055 case DB_SHUTDOWNED_IN_RECOVERY:
00056 return _("shut down in recovery");
00057 case DB_SHUTDOWNING:
00058 return _("shutting down");
00059 case DB_IN_CRASH_RECOVERY:
00060 return _("in crash recovery");
00061 case DB_IN_ARCHIVE_RECOVERY:
00062 return _("in archive recovery");
00063 case DB_IN_PRODUCTION:
00064 return _("in production");
00065 }
00066 return _("unrecognized status code");
00067 }
00068
00069 static const char *
00070 wal_level_str(WalLevel wal_level)
00071 {
00072 switch (wal_level)
00073 {
00074 case WAL_LEVEL_MINIMAL:
00075 return "minimal";
00076 case WAL_LEVEL_ARCHIVE:
00077 return "archive";
00078 case WAL_LEVEL_HOT_STANDBY:
00079 return "hot_standby";
00080 }
00081 return _("unrecognized wal_level");
00082 }
00083
00084
00085 int
00086 main(int argc, char *argv[])
00087 {
00088 ControlFileData ControlFile;
00089 int fd;
00090 char ControlFilePath[MAXPGPATH];
00091 char *DataDir;
00092 pg_crc32 crc;
00093 time_t time_tmp;
00094 char pgctime_str[128];
00095 char ckpttime_str[128];
00096 char sysident_str[32];
00097 const char *strftime_fmt = "%c";
00098 const char *progname;
00099 XLogSegNo segno;
00100 char xlogfilename[MAXFNAMELEN];
00101
00102 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_controldata"));
00103
00104 progname = get_progname(argv[0]);
00105
00106 if (argc > 1)
00107 {
00108 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
00109 {
00110 usage(progname);
00111 exit(0);
00112 }
00113 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
00114 {
00115 puts("pg_controldata (PostgreSQL) " PG_VERSION);
00116 exit(0);
00117 }
00118 }
00119
00120 if (argc > 1)
00121 DataDir = argv[1];
00122 else
00123 DataDir = getenv("PGDATA");
00124 if (DataDir == NULL)
00125 {
00126 fprintf(stderr, _("%s: no data directory specified\n"), progname);
00127 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
00128 exit(1);
00129 }
00130
00131 snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
00132
00133 if ((fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0)) == -1)
00134 {
00135 fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
00136 progname, ControlFilePath, strerror(errno));
00137 exit(2);
00138 }
00139
00140 if (read(fd, &ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData))
00141 {
00142 fprintf(stderr, _("%s: could not read file \"%s\": %s\n"),
00143 progname, ControlFilePath, strerror(errno));
00144 exit(2);
00145 }
00146 close(fd);
00147
00148
00149 INIT_CRC32(crc);
00150 COMP_CRC32(crc,
00151 (char *) &ControlFile,
00152 offsetof(ControlFileData, crc));
00153 FIN_CRC32(crc);
00154
00155 if (!EQ_CRC32(crc, ControlFile.crc))
00156 printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n"
00157 "Either the file is corrupt, or it has a different layout than this program\n"
00158 "is expecting. The results below are untrustworthy.\n\n"));
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 time_tmp = (time_t) ControlFile.time;
00170 strftime(pgctime_str, sizeof(pgctime_str), strftime_fmt,
00171 localtime(&time_tmp));
00172 time_tmp = (time_t) ControlFile.checkPointCopy.time;
00173 strftime(ckpttime_str, sizeof(ckpttime_str), strftime_fmt,
00174 localtime(&time_tmp));
00175
00176
00177
00178
00179
00180 XLByteToSeg(ControlFile.checkPointCopy.redo, segno);
00181 XLogFileName(xlogfilename, ControlFile.checkPointCopy.ThisTimeLineID, segno);
00182
00183
00184
00185
00186
00187 snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
00188 ControlFile.system_identifier);
00189
00190 printf(_("pg_control version number: %u\n"),
00191 ControlFile.pg_control_version);
00192 if (ControlFile.pg_control_version % 65536 == 0 && ControlFile.pg_control_version / 65536 != 0)
00193 printf(_("WARNING: possible byte ordering mismatch\n"
00194 "The byte ordering used to store the pg_control file might not match the one\n"
00195 "used by this program. In that case the results below would be incorrect, and\n"
00196 "the PostgreSQL installation would be incompatible with this data directory.\n"));
00197 printf(_("Catalog version number: %u\n"),
00198 ControlFile.catalog_version_no);
00199 printf(_("Database system identifier: %s\n"),
00200 sysident_str);
00201 printf(_("Database cluster state: %s\n"),
00202 dbState(ControlFile.state));
00203 printf(_("pg_control last modified: %s\n"),
00204 pgctime_str);
00205 printf(_("Latest checkpoint location: %X/%X\n"),
00206 (uint32) (ControlFile.checkPoint >> 32),
00207 (uint32) ControlFile.checkPoint);
00208 printf(_("Prior checkpoint location: %X/%X\n"),
00209 (uint32) (ControlFile.prevCheckPoint >> 32),
00210 (uint32) ControlFile.prevCheckPoint);
00211 printf(_("Latest checkpoint's REDO location: %X/%X\n"),
00212 (uint32) (ControlFile.checkPointCopy.redo >> 32),
00213 (uint32) ControlFile.checkPointCopy.redo);
00214 printf(_("Latest checkpoint's REDO WAL file: %s\n"),
00215 xlogfilename);
00216 printf(_("Latest checkpoint's TimeLineID: %u\n"),
00217 ControlFile.checkPointCopy.ThisTimeLineID);
00218 printf(_("Latest checkpoint's PrevTimeLineID: %u\n"),
00219 ControlFile.checkPointCopy.PrevTimeLineID);
00220 printf(_("Latest checkpoint's full_page_writes: %s\n"),
00221 ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"));
00222 printf(_("Latest checkpoint's NextXID: %u/%u\n"),
00223 ControlFile.checkPointCopy.nextXidEpoch,
00224 ControlFile.checkPointCopy.nextXid);
00225 printf(_("Latest checkpoint's NextOID: %u\n"),
00226 ControlFile.checkPointCopy.nextOid);
00227 printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
00228 ControlFile.checkPointCopy.nextMulti);
00229 printf(_("Latest checkpoint's NextMultiOffset: %u\n"),
00230 ControlFile.checkPointCopy.nextMultiOffset);
00231 printf(_("Latest checkpoint's oldestXID: %u\n"),
00232 ControlFile.checkPointCopy.oldestXid);
00233 printf(_("Latest checkpoint's oldestXID's DB: %u\n"),
00234 ControlFile.checkPointCopy.oldestXidDB);
00235 printf(_("Latest checkpoint's oldestActiveXID: %u\n"),
00236 ControlFile.checkPointCopy.oldestActiveXid);
00237 printf(_("Latest checkpoint's oldestMultiXid: %u\n"),
00238 ControlFile.checkPointCopy.oldestMulti);
00239 printf(_("Latest checkpoint's oldestMulti's DB: %u\n"),
00240 ControlFile.checkPointCopy.oldestMultiDB);
00241 printf(_("Time of latest checkpoint: %s\n"),
00242 ckpttime_str);
00243 printf(_("Fake LSN counter for unlogged rels: %X/%X\n"),
00244 (uint32) (ControlFile.unloggedLSN >> 32),
00245 (uint32) ControlFile.unloggedLSN);
00246 printf(_("Minimum recovery ending location: %X/%X\n"),
00247 (uint32) (ControlFile.minRecoveryPoint >> 32),
00248 (uint32) ControlFile.minRecoveryPoint);
00249 printf(_("Min recovery ending loc's timeline: %u\n"),
00250 ControlFile.minRecoveryPointTLI);
00251 printf(_("Backup start location: %X/%X\n"),
00252 (uint32) (ControlFile.backupStartPoint >> 32),
00253 (uint32) ControlFile.backupStartPoint);
00254 printf(_("Backup end location: %X/%X\n"),
00255 (uint32) (ControlFile.backupEndPoint >> 32),
00256 (uint32) ControlFile.backupEndPoint);
00257 printf(_("End-of-backup record required: %s\n"),
00258 ControlFile.backupEndRequired ? _("yes") : _("no"));
00259 printf(_("Current wal_level setting: %s\n"),
00260 wal_level_str(ControlFile.wal_level));
00261 printf(_("Current max_connections setting: %d\n"),
00262 ControlFile.MaxConnections);
00263 printf(_("Current max_prepared_xacts setting: %d\n"),
00264 ControlFile.max_prepared_xacts);
00265 printf(_("Current max_locks_per_xact setting: %d\n"),
00266 ControlFile.max_locks_per_xact);
00267 printf(_("Maximum data alignment: %u\n"),
00268 ControlFile.maxAlign);
00269
00270 printf(_("Database block size: %u\n"),
00271 ControlFile.blcksz);
00272 printf(_("Blocks per segment of large relation: %u\n"),
00273 ControlFile.relseg_size);
00274 printf(_("WAL block size: %u\n"),
00275 ControlFile.xlog_blcksz);
00276 printf(_("Bytes per WAL segment: %u\n"),
00277 ControlFile.xlog_seg_size);
00278 printf(_("Maximum length of identifiers: %u\n"),
00279 ControlFile.nameDataLen);
00280 printf(_("Maximum columns in an index: %u\n"),
00281 ControlFile.indexMaxKeys);
00282 printf(_("Maximum size of a TOAST chunk: %u\n"),
00283 ControlFile.toast_max_chunk_size);
00284 printf(_("Date/time type storage: %s\n"),
00285 (ControlFile.enableIntTimes ? _("64-bit integers") : _("floating-point numbers")));
00286 printf(_("Float4 argument passing: %s\n"),
00287 (ControlFile.float4ByVal ? _("by value") : _("by reference")));
00288 printf(_("Float8 argument passing: %s\n"),
00289 (ControlFile.float8ByVal ? _("by value") : _("by reference")));
00290 printf(_("Data page checksum version: %u\n"),
00291 ControlFile.data_checksum_version);
00292 return 0;
00293 }