Skip to content

Commit eae456c

Browse files
committed
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.
1 parent 9efee18 commit eae456c

File tree

3 files changed

+90
-11
lines changed

3 files changed

+90
-11
lines changed

src/backend/access/transam/Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# Makefile for access/transam
55
#
66
# IDENTIFICATION
7-
# $Header: /cvsroot/pgsql/src/backend/access/transam/Makefile,v 1.7 1999/09/27 15:47:37 vadim Exp $
7+
# $Header: /cvsroot/pgsql/src/backend/access/transam/Makefile,v 1.8 1999/10/24 20:42:27 tgl Exp $
88
#
99
#-------------------------------------------------------------------------
1010

@@ -26,6 +26,10 @@ depend dep:
2626
clean:
2727
rm -f SUBSYS.o $(OBJS)
2828

29+
# ensure that version checks in xlog.c get recompiled when config.h or
30+
# catversion.h changes, even if "make depend" hasn't been done.
31+
xlog.o: xlog.c $(SRCDIR)/include/config.h $(SRCDIR)/include/catalog/catversion.h
32+
2933
ifeq (depend,$(wildcard depend))
3034
include depend
3135
endif

src/backend/access/transam/xlog.c

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* xlog.c
4+
*
5+
*
6+
* Copyright (c) 1994, Regents of the University of California
7+
*
8+
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.6 1999/10/24 20:42:27 tgl Exp $
9+
*
10+
*-------------------------------------------------------------------------
11+
*/
112
#include <fcntl.h>
213
#include <unistd.h>
314
#include <errno.h>
415
#include <sys/stat.h>
516
#include <sys/time.h>
617

718
#include "postgres.h"
19+
820
#include "access/xlog.h"
921
#include "access/xact.h"
22+
#include "catalog/catversion.h"
1023
#include "storage/sinval.h"
1124
#include "storage/proc.h"
1225
#include "storage/spin.h"
@@ -99,12 +112,15 @@ typedef struct ControlFileData
99112
DBState state; /* */
100113

101114
/*
102-
* following data used to make sure that configurations for this DB
103-
* do not conflict with the backend
115+
* this data is used to make sure that configuration of this DB
116+
* is compatible with the current backend
104117
*/
105118
uint32 blcksz; /* block size for this DB */
106-
uint32 relseg_size; /* segmented file's block number */
107-
/* MORE DATA FOLLOWS AT THE END OF THIS STRUCTURE
119+
uint32 relseg_size; /* blocks per segment of large relation */
120+
uint32 catalog_version_no; /* internal version number */
121+
122+
/*
123+
* MORE DATA FOLLOWS AT THE END OF THIS STRUCTURE
108124
* - locations of data dirs
109125
*/
110126
} ControlFileData;
@@ -1171,6 +1187,7 @@ BootStrapXLOG()
11711187
ControlFile->state = DB_SHUTDOWNED;
11721188
ControlFile->blcksz = BLCKSZ;
11731189
ControlFile->relseg_size = RELSEG_SIZE;
1190+
ControlFile->catalog_version_no = CATALOG_VERSION_NO;
11741191

11751192
if (write(fd, buffer, BLCKSZ) != BLCKSZ)
11761193
elog(STOP, "BootStrapXLOG failed to write control file: %d", errno);
@@ -1179,9 +1196,6 @@ BootStrapXLOG()
11791196
elog(STOP, "BootStrapXLOG failed to fsync control file: %d", errno);
11801197

11811198
close(fd);
1182-
1183-
return;
1184-
11851199
}
11861200

11871201
static char*
@@ -1258,11 +1272,16 @@ StartupXLOG()
12581272
!XRecOffIsValid(ControlFile->checkPoint.xrecoff))
12591273
elog(STOP, "Control file context is broken");
12601274

1275+
/* Check for incompatible database */
12611276
if (ControlFile->blcksz != BLCKSZ)
1262-
elog(STOP, "database was initialized in BLCKSZ(%d), but the backend was compiled in BLCKSZ(%d)",ControlFile->blcksz,BLCKSZ);
1263-
1277+
elog(STOP, "database was initialized with BLCKSZ %d,\n\tbut the backend was compiled with BLCKSZ %d.\n\tlooks like you need to initdb.",
1278+
ControlFile->blcksz, BLCKSZ);
12641279
if (ControlFile->relseg_size != RELSEG_SIZE)
1265-
elog(STOP, "database was initialized in RELSEG_SIZE(%d), but the backend was compiled in RELSEG_SIZE(%d)",ControlFile->relseg_size, RELSEG_SIZE);
1280+
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.",
1281+
ControlFile->relseg_size, RELSEG_SIZE);
1282+
if (ControlFile->catalog_version_no != CATALOG_VERSION_NO)
1283+
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.",
1284+
ControlFile->catalog_version_no, CATALOG_VERSION_NO);
12661285

12671286
if (ControlFile->state == DB_SHUTDOWNED)
12681287
elog(LOG, "Data Base System was shutdowned at %s",

src/include/catalog/catversion.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* catversion.h
4+
* "Catalog version number" for Postgres.
5+
*
6+
* The catalog version number is used to flag incompatible changes in
7+
* the Postgres system catalogs. Whenever anyone changes the format of
8+
* a system catalog relation, or adds, deletes, or modifies standard
9+
* catalog entries in such a way that an updated backend wouldn't work
10+
* with an old database (or vice versa), the catalog version number
11+
* should be changed. The version number stored in pg_control by initdb
12+
* is checked against the version number compiled into the backend at
13+
* startup time, so that a backend can refuse to run in an incompatible
14+
* database.
15+
*
16+
* The point of this feature is to provide a finer grain of compatibility
17+
* checking than is possible from looking at the major version number
18+
* stored in PG_VERSION. It shouldn't matter to end users, but during
19+
* development cycles we usually make quite a few incompatible changes
20+
* to the contents of the system catalogs, and we don't want to bump the
21+
* major version number for each one. What we can do instead is bump
22+
* this internal version number. This should save some grief for
23+
* developers who might otherwise waste time tracking down "bugs" that
24+
* are really just code-vs-database incompatibilities.
25+
*
26+
* The rule for developers is: if you commit a change that requires
27+
* an initdb, you should update the catalog version number (as well as
28+
* notifying the pghackers mailing list, which has been the informal
29+
* practice for a long time).
30+
*
31+
* The catalog version number is placed here since modifying files in
32+
* include/catalog is the most common kind of initdb-forcing change.
33+
* But it could be used to protect any kind of incompatible change in
34+
* database contents or layout, such as altering tuple headers.
35+
*
36+
*
37+
* Copyright (c) 1994, Regents of the University of California
38+
*
39+
* $Id: catversion.h,v 1.1 1999/10/24 20:42:26 tgl Exp $
40+
*
41+
*-------------------------------------------------------------------------
42+
*/
43+
#ifndef CATVERSION_H
44+
#define CATVERSION_H
45+
46+
/*
47+
* We could use anything we wanted for version numbers, but I recommend
48+
* following the "YYYYMMDDN" style often used for DNS zone serial numbers.
49+
* YYYYMMDD are the date of the change, and N is the number of the change
50+
* on that day. (Hopefully we'll never commit ten independent sets of
51+
* catalog changes on the same day...)
52+
*/
53+
54+
#define CATALOG_VERSION_NO 199910241
55+
56+
#endif

0 commit comments

Comments
 (0)