From b25e60d8874e5a32faa43493f95027ff85fcee76 Mon Sep 17 00:00:00 2001 From: Bruce Momjian <bruce@momjian.us> Date: Fri, 23 Feb 2001 20:38:35 +0000 Subject: [PATCH] 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. linda:~$ pg_controldata Log file id: 0 Log file segment: 5 Last modified: Wed Feb 7 19:35:47 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: Oliver Elphick Oliver.Elphick@lfix.co.uk --- contrib/README | 4 + contrib/pg_controldata/Makefile | 36 ++++++ contrib/pg_controldata/README.pg_controldata | 19 +++ contrib/pg_controldata/pg_controldata | Bin 0 -> 11795 bytes contrib/pg_controldata/pg_controldata.c | 123 +++++++++++++++++++ contrib/pg_controldata/pg_controldata.o | Bin 0 -> 8368 bytes 6 files changed, 182 insertions(+) create mode 100644 contrib/pg_controldata/Makefile create mode 100644 contrib/pg_controldata/README.pg_controldata create mode 100755 contrib/pg_controldata/pg_controldata create mode 100644 contrib/pg_controldata/pg_controldata.c create mode 100644 contrib/pg_controldata/pg_controldata.o diff --git a/contrib/README b/contrib/README index 1988c068abe..79d95b2e3e1 100644 --- a/contrib/README +++ b/contrib/README @@ -85,6 +85,10 @@ oid2name - maps numeric files to table names by B Palmer <bpalmer@crimelabs.net> +pg_controldata - + Dump internal database site structures + by Oliver Elphick <olly@lfix.co.uk> + pg_dumplo - Dump large objects by Karel Zak <zakkr@zf.jcu.cz> diff --git a/contrib/pg_controldata/Makefile b/contrib/pg_controldata/Makefile new file mode 100644 index 00000000000..fde5ab1e73b --- /dev/null +++ b/contrib/pg_controldata/Makefile @@ -0,0 +1,36 @@ +# +# $Header: /cvsroot/pgsql/contrib/pg_controldata/Attic/Makefile,v 1.1 2001/02/23 20:38:35 momjian Exp $ +# + +subdir = contrib/pg_controldata +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global + +override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) + +OBJS = pg_controldata.o + +all: pg_controldata + +pg_controldata: $(OBJS) $(libpq_builddir)/libpq.a + $(CC) $(CFLAGS) $(OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@ + +install: all installdirs + $(INSTALL_PROGRAM) pg_controldata$(X) $(bindir) + $(INSTALL_DATA) README.pg_controldata $(docdir)/contrib + +installdirs: + $(mkinstalldirs) $(bindir) $(docdir)/contrib + +uninstall: + rm -f $(bindir)/pg_controldata$(X) $(docdir)/contrib/README.pg_controldata + +clean distclean maintainer-clean: + rm -f pg_controldata$(X) $(OBJS) + +depend dep: + $(CC) -MM -MG $(CFLAGS) *.c > depend + +ifeq (depend,$(wildcard depend)) +include depend +endif diff --git a/contrib/pg_controldata/README.pg_controldata b/contrib/pg_controldata/README.pg_controldata new file mode 100644 index 00000000000..e1c4192cfea --- /dev/null +++ b/contrib/pg_controldata/README.pg_controldata @@ -0,0 +1,19 @@ +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: + +linda:~$ pg_controldata +Log file id: 0 +Log file segment: 5 +Last modified: Wed Feb 7 19:35:47 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: + +-- +Oliver Elphick <olly@lfix.co.uk> diff --git a/contrib/pg_controldata/pg_controldata b/contrib/pg_controldata/pg_controldata new file mode 100755 index 0000000000000000000000000000000000000000..59f2e4d14d0b877646722b816dbfb54fd0d1815a GIT binary patch literal 11795 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 O<?G8;k3U!5lKwB(UKWV} literal 0 HcmV?d00001 diff --git a/contrib/pg_controldata/pg_controldata.c b/contrib/pg_controldata/pg_controldata.c new file mode 100644 index 00000000000..9cd148f6f48 --- /dev/null +++ b/contrib/pg_controldata/pg_controldata.c @@ -0,0 +1,123 @@ +/* pg_controldata + * + * reads the data from $PGDATA/global/pg_control + * + * copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001; + * licence: BSD + * +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.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 +{ + DB_STARTUP = 0, + DB_SHUTDOWNED, + DB_SHUTDOWNING, + DB_IN_RECOVERY, + DB_IN_PRODUCTION +} DBState; + + +typedef struct ControlFileData +{ + 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]; + + DataDir = getenv("PGDATA"); + if ( DataDir == NULL ) { + fprintf(stderr,"PGDATA is not defined\n"); + exit(1); + } + + snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir); + + 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); + + return (0); +} + diff --git a/contrib/pg_controldata/pg_controldata.o b/contrib/pg_controldata/pg_controldata.o new file mode 100644 index 0000000000000000000000000000000000000000..fd6b532b940f4cd363d9733eb1aac48e0702a0b5 GIT binary patch literal 8368 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 literal 0 HcmV?d00001 -- GitLab