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
This commit is contained in:
Bruce Momjian 2001-02-23 20:38:35 +00:00
parent e74ce0a566
commit b25e60d887
6 changed files with 182 additions and 0 deletions

View File

@ -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>

View File

@ -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

View File

@ -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>

Binary file not shown.

View File

@ -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);
}

Binary file not shown.