mirror of
https://github.com/postgres/postgres.git
synced 2025-08-06 18:42:54 +03:00
Update for new pg_control format.
This commit is contained in:
@@ -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
|
subdir = contrib/pg_controldata
|
||||||
top_builddir = ../..
|
top_builddir = ../..
|
||||||
include $(top_builddir)/src/Makefile.global
|
include $(top_builddir)/src/Makefile.global
|
||||||
|
|
||||||
override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS)
|
OBJS = pg_controldata.o pg_crc.o
|
||||||
|
|
||||||
OBJS = pg_controldata.o
|
|
||||||
|
|
||||||
all: pg_controldata
|
all: pg_controldata
|
||||||
|
|
||||||
pg_controldata: $(OBJS)
|
pg_controldata: $(OBJS)
|
||||||
$(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) $(LIBS) -o $@
|
$(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: all installdirs
|
||||||
$(INSTALL_PROGRAM) pg_controldata$(X) $(bindir)
|
$(INSTALL_PROGRAM) pg_controldata$(X) $(bindir)
|
||||||
$(INSTALL_DATA) README.pg_controldata $(docdir)/contrib
|
$(INSTALL_DATA) README.pg_controldata $(docdir)/contrib
|
||||||
@@ -26,7 +27,7 @@ uninstall:
|
|||||||
rm -f $(bindir)/pg_controldata$(X) $(docdir)/contrib/README.pg_controldata
|
rm -f $(bindir)/pg_controldata$(X) $(docdir)/contrib/README.pg_controldata
|
||||||
|
|
||||||
clean distclean maintainer-clean:
|
clean distclean maintainer-clean:
|
||||||
rm -f pg_controldata$(X) $(OBJS)
|
rm -f pg_controldata$(X) $(OBJS) pg_crc.c
|
||||||
|
|
||||||
depend dep:
|
depend dep:
|
||||||
$(CC) -MM -MG $(CFLAGS) *.c > depend
|
$(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
|
version number from the current database, and couldn't find any existing
|
||||||
program to do that.
|
program to do that.
|
||||||
|
|
||||||
The attached utility produces this output:
|
The attached utility produces output like this:
|
||||||
|
|
||||||
linda:~$ pg_controldata
|
$ pg_controldata
|
||||||
Log file id: 0
|
pg_control version number: 71
|
||||||
Log file segment: 5
|
Catalog version number: 200101061
|
||||||
Last modified: Wed Feb 7 19:35:47 2001
|
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
|
Database block size: 8192
|
||||||
Blocks per segment of large relation: 131072
|
Blocks per segment of large relation: 131072
|
||||||
Catalog version number: 200101061
|
LC_COLLATE: C
|
||||||
LC_COLLATE: en_GB
|
LC_CTYPE: C
|
||||||
LC_CTYPE: en_GB
|
|
||||||
Log archive directory:
|
|
||||||
|
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>
|
Oliver Elphick <olly@lfix.co.uk>
|
||||||
|
@@ -1,87 +1,54 @@
|
|||||||
/* pg_controldata
|
/*
|
||||||
|
* pg_controldata
|
||||||
*
|
*
|
||||||
* reads the data from $PGDATA/global/pg_control
|
* reads the data from $PGDATA/global/pg_control
|
||||||
*
|
*
|
||||||
* copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001;
|
* copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001;
|
||||||
* licence: BSD
|
* 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 <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "catalog/pg_control.h"
|
||||||
|
|
||||||
typedef unsigned int uint32;
|
|
||||||
|
|
||||||
#include "config.h"
|
static const char *
|
||||||
#include "access/xlogdefs.h"
|
dbState(DBState state)
|
||||||
|
|
||||||
/*
|
|
||||||
* #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;
|
switch (state)
|
||||||
uint32 crc2;
|
{
|
||||||
} crc64;
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
#define LOCALE_NAME_BUFLEN 128
|
|
||||||
|
|
||||||
typedef enum DBState
|
int
|
||||||
|
main()
|
||||||
{
|
{
|
||||||
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;
|
ControlFileData ControlFile;
|
||||||
int fd;
|
int fd;
|
||||||
char ControlFilePath[MAXPGPATH];
|
char ControlFilePath[MAXPGPATH];
|
||||||
char *DataDir;
|
char *DataDir;
|
||||||
char tmdt[32];
|
crc64 crc;
|
||||||
|
char pgctime_str[32];
|
||||||
|
char ckpttime_str[32];
|
||||||
|
|
||||||
DataDir = getenv("PGDATA");
|
DataDir = getenv("PGDATA");
|
||||||
if ( DataDir == NULL ) {
|
if ( DataDir == NULL ) {
|
||||||
@@ -91,33 +58,77 @@ int main() {
|
|||||||
|
|
||||||
snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
|
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");
|
perror("Failed to open $PGDATA/global/pg_control for reading");
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
read(fd, &ControlFile, sizeof(ControlFileData));
|
if (read(fd, &ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData))
|
||||||
strftime(tmdt, 32, "%c", localtime(&(ControlFile.time)));
|
{
|
||||||
|
perror("Failed to read $PGDATA/global/pg_control");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
|
||||||
printf("Log file id: %u\n"
|
/* Check the CRC. */
|
||||||
"Log file segment: %u\n"
|
INIT_CRC64(crc);
|
||||||
"Last modified: %s\n"
|
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"
|
"Database block size: %u\n"
|
||||||
"Blocks per segment of large relation: %u\n"
|
"Blocks per segment of large relation: %u\n"
|
||||||
"Catalog version number: %u\n"
|
|
||||||
"LC_COLLATE: %s\n"
|
"LC_COLLATE: %s\n"
|
||||||
"LC_CTYPE: %s\n"
|
"LC_CTYPE: %s\n",
|
||||||
"Log archive directory: %s\n",
|
|
||||||
|
ControlFile.pg_control_version,
|
||||||
|
ControlFile.catalog_version_no,
|
||||||
|
dbState(ControlFile.state),
|
||||||
|
pgctime_str,
|
||||||
ControlFile.logId,
|
ControlFile.logId,
|
||||||
ControlFile.logSeg,
|
ControlFile.logSeg,
|
||||||
tmdt,
|
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.blcksz,
|
||||||
ControlFile.relseg_size,
|
ControlFile.relseg_size,
|
||||||
ControlFile.catalog_version_no,
|
|
||||||
ControlFile.lc_collate,
|
ControlFile.lc_collate,
|
||||||
ControlFile.lc_ctype,
|
ControlFile.lc_ctype);
|
||||||
ControlFile.archdir);
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user