]> granicus.if.org Git - postgresql/commitdiff
Update for new pg_control format.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 13 Mar 2001 01:17:40 +0000 (01:17 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 13 Mar 2001 01:17:40 +0000 (01:17 +0000)
contrib/pg_controldata/Makefile
contrib/pg_controldata/README.pg_controldata
contrib/pg_controldata/pg_controldata.c

index 77a1880dd1b6592491600966be2d03405ac9d5be..f9ffe40080c58c319c9af1d4e8fc4d2730e34dd3 100644 (file)
@@ -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
index e1c4192cfea90f01f627b9a63dfbbe4d5775edea..85ca0e1467a7a81373f3669549a2a2242703de0e 100644 (file)
@@ -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                 <olly@lfix.co.uk>
index 9cd148f6f4863e2ff29f4fdc971ab8c0499da5aa..dc666c1fcf29d12952e4a8bc95eef6dc79378523 100644 (file)
@@ -1,87 +1,54 @@
-/* pg_controldata
+/*
+ * pg_controldata
  *
  * reads the data from $PGDATA/global/pg_control
  *
  * copyright (c) Oliver Elphick <olly@lfix.co.uk>, 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 <stdio.h>
-#include <stdlib.h>
 #include <unistd.h>
 #include <time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 
+#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);
 }
-