From 0c383155aeeb9d1efb918ad659ff51ae55983063 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 13 Mar 2001 01:17:40 +0000 Subject: [PATCH] Update for new pg_control format. --- contrib/pg_controldata/Makefile | 11 +- contrib/pg_controldata/README.pg_controldata | 31 +++- contrib/pg_controldata/pg_controldata.c | 181 ++++++++++--------- 3 files changed, 124 insertions(+), 99 deletions(-) diff --git a/contrib/pg_controldata/Makefile b/contrib/pg_controldata/Makefile index 77a1880dd1..f9ffe40080 100644 --- a/contrib/pg_controldata/Makefile +++ b/contrib/pg_controldata/Makefile @@ -1,20 +1,21 @@ # -# $Header: /cvsroot/pgsql/contrib/pg_controldata/Attic/Makefile,v 1.2 2001/02/25 15:57:45 petere Exp $ +# $Header: /cvsroot/pgsql/contrib/pg_controldata/Attic/Makefile,v 1.3 2001/03/13 01:17:40 tgl Exp $ # subdir = contrib/pg_controldata top_builddir = ../.. include $(top_builddir)/src/Makefile.global -override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) - -OBJS = pg_controldata.o +OBJS = pg_controldata.o pg_crc.o all: pg_controldata pg_controldata: $(OBJS) $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) $(LIBS) -o $@ +pg_crc.c: $(top_builddir)/src/backend/utils/hash/pg_crc.c + rm -f $@ && $(LN_S) $< . + install: all installdirs $(INSTALL_PROGRAM) pg_controldata$(X) $(bindir) $(INSTALL_DATA) README.pg_controldata $(docdir)/contrib @@ -26,7 +27,7 @@ uninstall: rm -f $(bindir)/pg_controldata$(X) $(docdir)/contrib/README.pg_controldata clean distclean maintainer-clean: - rm -f pg_controldata$(X) $(OBJS) + rm -f pg_controldata$(X) $(OBJS) pg_crc.c depend dep: $(CC) -MM -MG $(CFLAGS) *.c > depend diff --git a/contrib/pg_controldata/README.pg_controldata b/contrib/pg_controldata/README.pg_controldata index e1c4192cfe..85ca0e1467 100644 --- a/contrib/pg_controldata/README.pg_controldata +++ b/contrib/pg_controldata/README.pg_controldata @@ -2,18 +2,31 @@ I had a need to read such things as the backend locale and the catalog version number from the current database, and couldn't find any existing program to do that. -The attached utility produces this output: +The attached utility produces output like this: -linda:~$ pg_controldata -Log file id: 0 -Log file segment: 5 -Last modified: Wed Feb 7 19:35:47 2001 +$ pg_controldata +pg_control version number: 71 +Catalog version number: 200101061 +Database state: IN_PRODUCTION +pg_control last modified: Sat Mar 10 00:07:55 2001 +Current log file id: 0 +Next log file segment: 9 +Latest checkpoint location: 0/88CAA20 +Prior checkpoint location: 0/70A5D48 +Latest checkpoint's REDO location: 0/88CAA20 +Latest checkpoint's UNDO location: 0/0 +Latest checkpoint's StartUpID: 22 +Latest checkpoint's NextXID: 4711 +Latest checkpoint's NextOID: 444704 +Time of latest checkpoint: Sat Mar 10 00:07:52 2001 Database block size: 8192 Blocks per segment of large relation: 131072 -Catalog version number: 200101061 -LC_COLLATE: en_GB -LC_CTYPE: en_GB -Log archive directory: +LC_COLLATE: C +LC_CTYPE: C + + +To access the pg_control file, the program must be run as the Postgres user, +and PGDATA must be set correctly in its environment. -- Oliver Elphick diff --git a/contrib/pg_controldata/pg_controldata.c b/contrib/pg_controldata/pg_controldata.c index 9cd148f6f4..dc666c1fcf 100644 --- a/contrib/pg_controldata/pg_controldata.c +++ b/contrib/pg_controldata/pg_controldata.c @@ -1,87 +1,54 @@ -/* pg_controldata +/* + * pg_controldata * * reads the data from $PGDATA/global/pg_control * * copyright (c) Oliver Elphick , 2001; * licence: BSD * -*/ + * $Header: /cvsroot/pgsql/contrib/pg_controldata/Attic/pg_controldata.c,v 1.2 2001/03/13 01:17:40 tgl Exp $ + */ +#include "postgres.h" -#include -#include #include #include #include #include #include +#include "catalog/pg_control.h" -typedef unsigned int uint32; - -#include "config.h" -#include "access/xlogdefs.h" - -/* - * #include "access/xlog.h" - * #include "c.h" - */ - -/* The following definitions are extracted from access/xlog.h and its - * recursive includes. There is too much initialisation needed if - * they are included direct. Perhaps someone more knowledgeable can - * fix that. - */ -typedef struct crc64 -{ - uint32 crc1; - uint32 crc2; -} crc64; - -#define LOCALE_NAME_BUFLEN 128 -typedef enum DBState +static const char * +dbState(DBState state) { - DB_STARTUP = 0, - DB_SHUTDOWNED, - DB_SHUTDOWNING, - DB_IN_RECOVERY, - DB_IN_PRODUCTION -} DBState; + switch (state) + { + case DB_STARTUP: + return "STARTUP"; + case DB_SHUTDOWNED: + return "SHUTDOWNED"; + case DB_SHUTDOWNING: + return "SHUTDOWNING"; + case DB_IN_RECOVERY: + return "IN_RECOVERY"; + case DB_IN_PRODUCTION: + return "IN_PRODUCTION"; + } + return "unrecognized status code"; +} -typedef struct ControlFileData +int +main() { - crc64 crc; - uint32 logId; /* current log file id */ - uint32 logSeg; /* current log file segment (1-based) */ - struct - XLogRecPtr checkPoint; /* last check point record ptr */ - time_t time; /* time stamp of last modification */ - DBState state; /* see enum above */ - - /* - * this data is used to make sure that configuration of this DB is - * compatible with the backend executable - */ - uint32 blcksz; /* block size for this DB */ - uint32 relseg_size; /* blocks per segment of large relation */ - uint32 catalog_version_no; /* internal version number */ - /* active locales --- "C" if compiled without USE_LOCALE: */ - char lc_collate[LOCALE_NAME_BUFLEN]; - char lc_ctype[LOCALE_NAME_BUFLEN]; - - /* - * important directory locations - */ - char archdir[MAXPGPATH]; /* where to move offline log files */ -} ControlFileData; - -int main() { ControlFileData ControlFile; int fd; char ControlFilePath[MAXPGPATH]; char *DataDir; - char tmdt[32]; + crc64 crc; + char pgctime_str[32]; + char ckpttime_str[32]; DataDir = getenv("PGDATA"); if ( DataDir == NULL ) { @@ -91,33 +58,77 @@ int main() { snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir); - if ((fd = open(ControlFilePath, O_RDONLY)) == -1) { + if ((fd = open(ControlFilePath, O_RDONLY)) == -1) + { perror("Failed to open $PGDATA/global/pg_control for reading"); exit(2); } - read(fd, &ControlFile, sizeof(ControlFileData)); - strftime(tmdt, 32, "%c", localtime(&(ControlFile.time))); - - printf("Log file id: %u\n" - "Log file segment: %u\n" - "Last modified: %s\n" - "Database block size: %u\n" - "Blocks per segment of large relation: %u\n" - "Catalog version number: %u\n" - "LC_COLLATE: %s\n" - "LC_CTYPE: %s\n" - "Log archive directory: %s\n", - ControlFile.logId, - ControlFile.logSeg, - tmdt, - ControlFile.blcksz, - ControlFile.relseg_size, - ControlFile.catalog_version_no, - ControlFile.lc_collate, - ControlFile.lc_ctype, - ControlFile.archdir); - + if (read(fd, &ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData)) + { + perror("Failed to read $PGDATA/global/pg_control"); + exit(2); + } + close(fd); + + /* Check the CRC. */ + INIT_CRC64(crc); + COMP_CRC64(crc, + (char*) &ControlFile + sizeof(crc64), + sizeof(ControlFileData) - sizeof(crc64)); + FIN_CRC64(crc); + + if (!EQ_CRC64(crc, ControlFile.crc)) + printf("WARNING: Calculated CRC checksum does not match value stored in file.\n" + "Either the file is corrupt, or it has a different layout than this program\n" + "is expecting. The results below are untrustworthy.\n\n"); + + strftime(pgctime_str, 32, "%c", + localtime(&(ControlFile.time))); + strftime(ckpttime_str, 32, "%c", + localtime(&(ControlFile.checkPointCopy.time))); + + printf("pg_control version number: %u\n" + "Catalog version number: %u\n" + "Database state: %s\n" + "pg_control last modified: %s\n" + "Current log file id: %u\n" + "Next log file segment: %u\n" + "Latest checkpoint location: %X/%X\n" + "Prior checkpoint location: %X/%X\n" + "Latest checkpoint's REDO location: %X/%X\n" + "Latest checkpoint's UNDO location: %X/%X\n" + "Latest checkpoint's StartUpID: %u\n" + "Latest checkpoint's NextXID: %u\n" + "Latest checkpoint's NextOID: %u\n" + "Time of latest checkpoint: %s\n" + "Database block size: %u\n" + "Blocks per segment of large relation: %u\n" + "LC_COLLATE: %s\n" + "LC_CTYPE: %s\n", + + ControlFile.pg_control_version, + ControlFile.catalog_version_no, + dbState(ControlFile.state), + pgctime_str, + ControlFile.logId, + ControlFile.logSeg, + ControlFile.checkPoint.xlogid, + ControlFile.checkPoint.xrecoff, + ControlFile.prevCheckPoint.xlogid, + ControlFile.prevCheckPoint.xrecoff, + ControlFile.checkPointCopy.redo.xlogid, + ControlFile.checkPointCopy.redo.xrecoff, + ControlFile.checkPointCopy.undo.xlogid, + ControlFile.checkPointCopy.undo.xrecoff, + ControlFile.checkPointCopy.ThisStartUpID, + ControlFile.checkPointCopy.nextXid, + ControlFile.checkPointCopy.nextOid, + ckpttime_str, + ControlFile.blcksz, + ControlFile.relseg_size, + ControlFile.lc_collate, + ControlFile.lc_ctype); + return (0); } - -- 2.40.0