From eae456cd7fcdc5de759b38ef1d114f7770775483 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 24 Oct 1999 20:42:27 +0000 Subject: [PATCH] Add a notion of a 'catalog version number' that can indicate when an initdb-forcing change has been applied within a development cycle. PG_VERSION serves this purpose for official releases, but we can't bump the PG_VERSION number every time we make a change to the catalogs during development. Instead, increase the catalog version number to warn other developers that you've made an incompatible change. See my mail to pghackers for more info. --- src/backend/access/transam/Makefile | 6 +++- src/backend/access/transam/xlog.c | 39 ++++++++++++++------ src/include/catalog/catversion.h | 56 +++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 src/include/catalog/catversion.h diff --git a/src/backend/access/transam/Makefile b/src/backend/access/transam/Makefile index 3c941a323d..46252fa71d 100644 --- a/src/backend/access/transam/Makefile +++ b/src/backend/access/transam/Makefile @@ -4,7 +4,7 @@ # Makefile for access/transam # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/access/transam/Makefile,v 1.7 1999/09/27 15:47:37 vadim Exp $ +# $Header: /cvsroot/pgsql/src/backend/access/transam/Makefile,v 1.8 1999/10/24 20:42:27 tgl Exp $ # #------------------------------------------------------------------------- @@ -26,6 +26,10 @@ depend dep: clean: rm -f SUBSYS.o $(OBJS) +# ensure that version checks in xlog.c get recompiled when config.h or +# catversion.h changes, even if "make depend" hasn't been done. +xlog.o: xlog.c $(SRCDIR)/include/config.h $(SRCDIR)/include/catalog/catversion.h + ifeq (depend,$(wildcard depend)) include depend endif diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 428ca7998e..e8e85b1113 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -1,3 +1,14 @@ +/*------------------------------------------------------------------------- + * + * xlog.c + * + * + * Copyright (c) 1994, Regents of the University of California + * + * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.6 1999/10/24 20:42:27 tgl Exp $ + * + *------------------------------------------------------------------------- + */ #include #include #include @@ -5,8 +16,10 @@ #include #include "postgres.h" + #include "access/xlog.h" #include "access/xact.h" +#include "catalog/catversion.h" #include "storage/sinval.h" #include "storage/proc.h" #include "storage/spin.h" @@ -99,12 +112,15 @@ typedef struct ControlFileData DBState state; /* */ /* - * following data used to make sure that configurations for this DB - * do not conflict with the backend + * this data is used to make sure that configuration of this DB + * is compatible with the current backend */ uint32 blcksz; /* block size for this DB */ - uint32 relseg_size; /* segmented file's block number */ - /* MORE DATA FOLLOWS AT THE END OF THIS STRUCTURE + uint32 relseg_size; /* blocks per segment of large relation */ + uint32 catalog_version_no; /* internal version number */ + + /* + * MORE DATA FOLLOWS AT THE END OF THIS STRUCTURE * - locations of data dirs */ } ControlFileData; @@ -1171,6 +1187,7 @@ BootStrapXLOG() ControlFile->state = DB_SHUTDOWNED; ControlFile->blcksz = BLCKSZ; ControlFile->relseg_size = RELSEG_SIZE; + ControlFile->catalog_version_no = CATALOG_VERSION_NO; if (write(fd, buffer, BLCKSZ) != BLCKSZ) elog(STOP, "BootStrapXLOG failed to write control file: %d", errno); @@ -1179,9 +1196,6 @@ BootStrapXLOG() elog(STOP, "BootStrapXLOG failed to fsync control file: %d", errno); close(fd); - - return; - } static char* @@ -1258,11 +1272,16 @@ tryAgain: !XRecOffIsValid(ControlFile->checkPoint.xrecoff)) elog(STOP, "Control file context is broken"); + /* Check for incompatible database */ if (ControlFile->blcksz != BLCKSZ) - elog(STOP, "database was initialized in BLCKSZ(%d), but the backend was compiled in BLCKSZ(%d)",ControlFile->blcksz,BLCKSZ); - + elog(STOP, "database was initialized with BLCKSZ %d,\n\tbut the backend was compiled with BLCKSZ %d.\n\tlooks like you need to initdb.", + ControlFile->blcksz, BLCKSZ); if (ControlFile->relseg_size != RELSEG_SIZE) - elog(STOP, "database was initialized in RELSEG_SIZE(%d), but the backend was compiled in RELSEG_SIZE(%d)",ControlFile->relseg_size, RELSEG_SIZE); + elog(STOP, "database was initialized with RELSEG_SIZE %d,\n\tbut the backend was compiled with RELSEG_SIZE %d.\n\tlooks like you need to initdb.", + ControlFile->relseg_size, RELSEG_SIZE); + if (ControlFile->catalog_version_no != CATALOG_VERSION_NO) + elog(STOP, "database was initialized with CATALOG_VERSION_NO %d,\n\tbut the backend was compiled with CATALOG_VERSION_NO %d.\n\tlooks like you need to initdb.", + ControlFile->catalog_version_no, CATALOG_VERSION_NO); if (ControlFile->state == DB_SHUTDOWNED) elog(LOG, "Data Base System was shutdowned at %s", diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h new file mode 100644 index 0000000000..6175662908 --- /dev/null +++ b/src/include/catalog/catversion.h @@ -0,0 +1,56 @@ +/*------------------------------------------------------------------------- + * + * catversion.h + * "Catalog version number" for Postgres. + * + * The catalog version number is used to flag incompatible changes in + * the Postgres system catalogs. Whenever anyone changes the format of + * a system catalog relation, or adds, deletes, or modifies standard + * catalog entries in such a way that an updated backend wouldn't work + * with an old database (or vice versa), the catalog version number + * should be changed. The version number stored in pg_control by initdb + * is checked against the version number compiled into the backend at + * startup time, so that a backend can refuse to run in an incompatible + * database. + * + * The point of this feature is to provide a finer grain of compatibility + * checking than is possible from looking at the major version number + * stored in PG_VERSION. It shouldn't matter to end users, but during + * development cycles we usually make quite a few incompatible changes + * to the contents of the system catalogs, and we don't want to bump the + * major version number for each one. What we can do instead is bump + * this internal version number. This should save some grief for + * developers who might otherwise waste time tracking down "bugs" that + * are really just code-vs-database incompatibilities. + * + * The rule for developers is: if you commit a change that requires + * an initdb, you should update the catalog version number (as well as + * notifying the pghackers mailing list, which has been the informal + * practice for a long time). + * + * The catalog version number is placed here since modifying files in + * include/catalog is the most common kind of initdb-forcing change. + * But it could be used to protect any kind of incompatible change in + * database contents or layout, such as altering tuple headers. + * + * + * Copyright (c) 1994, Regents of the University of California + * + * $Id: catversion.h,v 1.1 1999/10/24 20:42:26 tgl Exp $ + * + *------------------------------------------------------------------------- + */ +#ifndef CATVERSION_H +#define CATVERSION_H + +/* + * We could use anything we wanted for version numbers, but I recommend + * following the "YYYYMMDDN" style often used for DNS zone serial numbers. + * YYYYMMDD are the date of the change, and N is the number of the change + * on that day. (Hopefully we'll never commit ten independent sets of + * catalog changes on the same day...) + */ + +#define CATALOG_VERSION_NO 199910241 + +#endif