提交 0c383155 编写于 作者: T Tom Lane

Update for new pg_control format.

上级 4d14fe00
#
# $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
......
......@@ -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>
/* 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);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册