From 64eea6c21d5ad64753f3564862572951f80d5c92 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 3 Oct 2005 00:28:43 +0000 Subject: [PATCH] Expand pg_control information so that we can verify that the database was created on a machine with alignment rules and floating-point format similar to the current machine. Per recent discussion, this seems like a good idea with the increasing prevalence of 32/64 bit environments. --- src/backend/access/transam/xlog.c | 18 +++++++++++++++++- src/bin/pg_controldata/pg_controldata.c | 4 +++- src/bin/pg_resetxlog/pg_resetxlog.c | 6 +++++- src/include/catalog/pg_control.h | 20 ++++++++++++++++++-- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 14490a918e..878d7e21ef 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.218 2005/08/22 23:59:04 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.219 2005/10/03 00:28:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -3417,6 +3417,10 @@ WriteControlFile(void) */ ControlFile->pg_control_version = PG_CONTROL_VERSION; ControlFile->catalog_version_no = CATALOG_VERSION_NO; + + ControlFile->maxAlign = MAXIMUM_ALIGNOF; + ControlFile->floatFormat = FLOATFORMAT_VALUE; + ControlFile->blcksz = BLCKSZ; ControlFile->relseg_size = RELSEG_SIZE; ControlFile->xlog_seg_size = XLOG_SEG_SIZE; @@ -3562,6 +3566,18 @@ ReadControlFile(void) " but the server was compiled with CATALOG_VERSION_NO %d.", ControlFile->catalog_version_no, CATALOG_VERSION_NO), errhint("It looks like you need to initdb."))); + if (ControlFile->maxAlign != MAXIMUM_ALIGNOF) + ereport(FATAL, + (errmsg("database files are incompatible with server"), + errdetail("The database cluster was initialized with MAXALIGN %d," + " but the server was compiled with MAXALIGN %d.", + ControlFile->maxAlign, MAXIMUM_ALIGNOF), + errhint("It looks like you need to initdb."))); + if (ControlFile->floatFormat != FLOATFORMAT_VALUE) + ereport(FATAL, + (errmsg("database files are incompatible with server"), + errdetail("The database cluster appears to use a different floating-point format than the server executable."), + errhint("It looks like you need to initdb."))); if (ControlFile->blcksz != BLCKSZ) ereport(FATAL, (errmsg("database files are incompatible with server"), diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c index b1aed8f421..c5573ee59e 100644 --- a/src/bin/pg_controldata/pg_controldata.c +++ b/src/bin/pg_controldata/pg_controldata.c @@ -6,7 +6,7 @@ * copyright (c) Oliver Elphick , 2001; * licence: BSD * - * $PostgreSQL: pgsql/src/bin/pg_controldata/pg_controldata.c,v 1.25 2005/06/08 15:50:27 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/pg_controldata/pg_controldata.c,v 1.26 2005/10/03 00:28:41 tgl Exp $ */ #include "postgres.h" @@ -168,6 +168,8 @@ main(int argc, char *argv[]) printf(_("Latest checkpoint's NextMultiXactId: %u\n"), ControlFile.checkPointCopy.nextMulti); printf(_("Latest checkpoint's NextMultiOffset: %u\n"), ControlFile.checkPointCopy.nextMultiOffset); printf(_("Time of latest checkpoint: %s\n"), ckpttime_str); + printf(_("Maximum data alignment: %u\n"), ControlFile.maxAlign); + /* we don't print floatFormat since can't say much useful about it */ printf(_("Database block size: %u\n"), ControlFile.blcksz); printf(_("Blocks per segment of large relation: %u\n"), ControlFile.relseg_size); printf(_("Bytes per WAL segment: %u\n"), ControlFile.xlog_seg_size); diff --git a/src/bin/pg_resetxlog/pg_resetxlog.c b/src/bin/pg_resetxlog/pg_resetxlog.c index 0c52d321f0..5ee0a2749a 100644 --- a/src/bin/pg_resetxlog/pg_resetxlog.c +++ b/src/bin/pg_resetxlog/pg_resetxlog.c @@ -23,7 +23,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.36 2005/09/29 08:34:50 petere Exp $ + * $PostgreSQL: pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.37 2005/10/03 00:28:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -456,6 +456,8 @@ GuessControlValues(void) ControlFile.logSeg = 1; ControlFile.checkPoint = ControlFile.checkPointCopy.redo; + ControlFile.maxAlign = MAXIMUM_ALIGNOF; + ControlFile.floatFormat = FLOATFORMAT_VALUE; ControlFile.blcksz = BLCKSZ; ControlFile.relseg_size = RELSEG_SIZE; ControlFile.xlog_seg_size = XLOG_SEG_SIZE; @@ -523,6 +525,8 @@ PrintControlValues(bool guessed) printf(_("Latest checkpoint's NextOID: %u\n"), ControlFile.checkPointCopy.nextOid); printf(_("Latest checkpoint's NextMultiXactId: %u\n"), ControlFile.checkPointCopy.nextMulti); printf(_("Latest checkpoint's NextMultiOffset: %u\n"), ControlFile.checkPointCopy.nextMultiOffset); + printf(_("Maximum data alignment: %u\n"), ControlFile.maxAlign); + /* we don't print floatFormat since can't say much useful about it */ printf(_("Database block size: %u\n"), ControlFile.blcksz); printf(_("Blocks per segment of large relation: %u\n"), ControlFile.relseg_size); printf(_("Maximum length of identifiers: %u\n"), ControlFile.nameDataLen); diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h index 73f32b55ad..158a4ee92b 100644 --- a/src/include/catalog/pg_control.h +++ b/src/include/catalog/pg_control.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.23 2005/06/08 15:50:28 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.24 2005/10/03 00:28:43 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -22,7 +22,7 @@ /* Version identifier for this pg_control format */ -#define PG_CONTROL_VERSION 811 +#define PG_CONTROL_VERSION 812 /* * Body of CheckPoint XLOG records. This is declared here because we keep @@ -107,6 +107,22 @@ typedef struct ControlFileData CheckPoint checkPointCopy; /* copy of last check point record */ + /* + * This data is used to check for hardware-architecture compatibility + * of the database and the backend executable. We need not check + * endianness explicitly, since the pg_control version will surely + * look wrong to a machine of different endianness, but we do need + * to worry about MAXALIGN and floating-point format. (Note: storage + * layout nominally also depends on SHORTALIGN and INTALIGN, but in + * practice these are the same on all architectures of interest.) + * + * Testing just one double value is not a very bulletproof test for + * floating-point compatibility, but it will catch most cases. + */ + uint32 maxAlign; /* alignment requirement for tuples */ + double floatFormat; /* constant 1234567.0 */ +#define FLOATFORMAT_VALUE 1234567.0 + /* * This data is used to make sure that configuration of this database * is compatible with the backend executable.