aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/ref/reindex.sgml9
-rw-r--r--src/backend/access/nbtree/nbtpage.c18
-rw-r--r--src/backend/access/nbtree/nbtree.c5
-rw-r--r--src/backend/access/nbtree/nbtsort.c20
-rw-r--r--src/backend/access/nbtree/nbtxlog.c42
-rw-r--r--src/include/access/nbtree.h5
6 files changed, 71 insertions, 28 deletions
diff --git a/doc/src/sgml/ref/reindex.sgml b/doc/src/sgml/ref/reindex.sgml
index d945112de79..43f0368d64a 100644
--- a/doc/src/sgml/ref/reindex.sgml
+++ b/doc/src/sgml/ref/reindex.sgml
@@ -1,5 +1,5 @@
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/reindex.sgml,v 1.21 2003/09/24 18:54:01 tgl Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/reindex.sgml,v 1.22 2003/09/29 23:40:26 tgl Exp $
PostgreSQL documentation
-->
@@ -180,9 +180,10 @@ REINDEX { DATABASE | TABLE | INDEX } <replaceable class="PARAMETER">name</replac
is crash-safe and transaction-safe. <command>REINDEX</> is not
crash-safe for shared indexes, which is why this case is disallowed
during normal operation. If a failure occurs while reindexing one
- of these catalogs in standalone mode, it is important that the failure
- be rectified and the <command>REINDEX</> operation redone
- before attempting to restart the regular server.
+ of these catalogs in standalone mode, it will not be possible to
+ restart the regular server until the problem is rectified. (The
+ typical symptom of a partially rebuilt shared index is <quote>index is not
+ a btree</> errors.)
</para>
<para>
diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c
index 2cb57aadc23..77ca04601db 100644
--- a/src/backend/access/nbtree/nbtpage.c
+++ b/src/backend/access/nbtree/nbtpage.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.71 2003/09/25 06:57:57 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.72 2003/09/29 23:40:26 tgl Exp $
*
* NOTES
* Postgres btree pages look like ordinary relation pages. The opaque
@@ -31,12 +31,16 @@
/*
* _bt_metapinit() -- Initialize the metadata page of a new btree.
*
+ * If markvalid is true, the index is immediately marked valid, else it
+ * will be invalid until _bt_metaproot() is called.
+ *
* Note: there's no real need for any locking here. Since the transaction
* creating the index hasn't committed yet, no one else can even see the index
- * much less be trying to use it.
+ * much less be trying to use it. (In a REINDEX-in-place scenario, that's
+ * not true, but we assume the caller holds sufficient locks on the index.)
*/
void
-_bt_metapinit(Relation rel)
+_bt_metapinit(Relation rel, bool markvalid)
{
Buffer buf;
Page pg;
@@ -57,7 +61,7 @@ _bt_metapinit(Relation rel)
_bt_pageinit(pg, BufferGetPageSize(buf));
metad = BTPageGetMeta(pg);
- metad->btm_magic = BTREE_MAGIC;
+ metad->btm_magic = markvalid ? BTREE_MAGIC : 0;
metad->btm_version = BTREE_VERSION;
metad->btm_root = P_NONE;
metad->btm_level = 0;
@@ -85,7 +89,9 @@ _bt_metapinit(Relation rel)
rdata[0].len = SizeOfBtreeNewmeta;
rdata[0].next = NULL;
- recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_NEWMETA, rdata);
+ recptr = XLogInsert(RM_BTREE_ID,
+ markvalid ? XLOG_BTREE_NEWMETA : XLOG_BTREE_INVALIDMETA,
+ rdata);
PageSetLSN(pg, recptr);
PageSetSUI(pg, ThisStartUpID);
@@ -611,6 +617,8 @@ _bt_metaproot(Relation rel, BlockNumber rootbknum, uint32 level)
START_CRIT_SECTION();
metad = BTPageGetMeta(metap);
+ Assert(metad->btm_magic == BTREE_MAGIC || metad->btm_magic == 0);
+ metad->btm_magic = BTREE_MAGIC; /* it's valid now for sure */
metad->btm_root = rootbknum;
metad->btm_level = level;
metad->btm_fastroot = rootbknum;
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index da922548205..3979f79c358 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.105 2003/08/04 02:39:57 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.106 2003/09/29 23:40:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -112,7 +112,8 @@ btbuild(PG_FUNCTION_ARGS)
RelationGetRelationName(index));
/* initialize the btree index metadata page */
- _bt_metapinit(index);
+ /* mark it valid right away only if using slow build */
+ _bt_metapinit(index, !buildstate.usefast);
if (buildstate.usefast)
{
diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c
index d8ea19434f9..a56665be5c4 100644
--- a/src/backend/access/nbtree/nbtsort.c
+++ b/src/backend/access/nbtree/nbtsort.c
@@ -36,7 +36,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.76 2003/09/25 06:57:57 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.77 2003/09/29 23:40:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -514,6 +514,8 @@ static void
_bt_uppershutdown(Relation index, BTPageState *state)
{
BTPageState *s;
+ BlockNumber rootblkno = P_NONE;
+ uint32 rootlevel = 0;
/*
* Each iteration of this loop completes one more level of the tree.
@@ -537,7 +539,8 @@ _bt_uppershutdown(Relation index, BTPageState *state)
if (s->btps_next == (BTPageState *) NULL)
{
opaque->btpo_flags |= BTP_ROOT;
- _bt_metaproot(index, blkno, s->btps_level);
+ rootblkno = blkno;
+ rootlevel = s->btps_level;
}
else
{
@@ -556,6 +559,14 @@ _bt_uppershutdown(Relation index, BTPageState *state)
_bt_slideleft(index, s->btps_buf, s->btps_page);
_bt_blwritepage(index, s->btps_buf);
}
+
+ /*
+ * As the last step in the process, update the metapage to point to
+ * the new root (unless we had no data at all, in which case it's
+ * left pointing to "P_NONE"). This changes the index to the "valid"
+ * state by updating its magic number.
+ */
+ _bt_metaproot(index, rootblkno, rootlevel);
}
/*
@@ -672,7 +683,6 @@ _bt_load(Relation index, BTSpool *btspool, BTSpool *btspool2)
}
}
- /* Close down final pages, if we had any data at all */
- if (state != NULL)
- _bt_uppershutdown(index, state);
+ /* Close down final pages and rewrite the metapage */
+ _bt_uppershutdown(index, state);
}
diff --git a/src/backend/access/nbtree/nbtxlog.c b/src/backend/access/nbtree/nbtxlog.c
index 4fecd3116af..721ef6ba0a6 100644
--- a/src/backend/access/nbtree/nbtxlog.c
+++ b/src/backend/access/nbtree/nbtxlog.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.6 2003/08/08 21:41:27 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.7 2003/09/29 23:40:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -109,7 +109,8 @@ _bt_restore_page(Page page, char *from, int len)
static void
_bt_restore_meta(Relation reln, XLogRecPtr lsn,
BlockNumber root, uint32 level,
- BlockNumber fastroot, uint32 fastlevel)
+ BlockNumber fastroot, uint32 fastlevel,
+ bool markvalid)
{
Buffer metabuf;
Page metapg;
@@ -124,7 +125,7 @@ _bt_restore_meta(Relation reln, XLogRecPtr lsn,
_bt_pageinit(metapg, BufferGetPageSize(metabuf));
md = BTPageGetMeta(metapg);
- md->btm_magic = BTREE_MAGIC;
+ md->btm_magic = markvalid ? BTREE_MAGIC : 0;
md->btm_version = BTREE_VERSION;
md->btm_root = root;
md->btm_level = level;
@@ -213,7 +214,8 @@ btree_xlog_insert(bool redo, bool isleaf, bool ismeta,
if (ismeta)
_bt_restore_meta(reln, lsn,
md.root, md.level,
- md.fastroot, md.fastlevel);
+ md.fastroot, md.fastlevel,
+ true);
}
/* Forget any split this insertion completes */
@@ -562,7 +564,8 @@ btree_xlog_delete_page(bool redo, bool ismeta,
sizeof(xl_btree_metadata));
_bt_restore_meta(reln, lsn,
md.root, md.level,
- md.fastroot, md.fastlevel);
+ md.fastroot, md.fastlevel,
+ true);
}
}
}
@@ -607,7 +610,8 @@ btree_xlog_newroot(bool redo, XLogRecPtr lsn, XLogRecord *record)
_bt_restore_meta(reln, lsn,
xlrec->rootblk, xlrec->level,
- xlrec->rootblk, xlrec->level);
+ xlrec->rootblk, xlrec->level,
+ true);
/* Check to see if this satisfies any incomplete insertions */
if (record->xl_len > SizeOfBtreeNewroot &&
@@ -621,7 +625,8 @@ btree_xlog_newroot(bool redo, XLogRecPtr lsn, XLogRecord *record)
}
static void
-btree_xlog_newmeta(bool redo, XLogRecPtr lsn, XLogRecord *record)
+btree_xlog_newmeta(bool redo, XLogRecPtr lsn, XLogRecord *record,
+ bool markvalid)
{
xl_btree_newmeta *xlrec = (xl_btree_newmeta *) XLogRecGetData(record);
Relation reln;
@@ -635,7 +640,8 @@ btree_xlog_newmeta(bool redo, XLogRecPtr lsn, XLogRecord *record)
_bt_restore_meta(reln, lsn,
xlrec->meta.root, xlrec->meta.level,
- xlrec->meta.fastroot, xlrec->meta.fastlevel);
+ xlrec->meta.fastroot, xlrec->meta.fastlevel,
+ markvalid);
}
static void
@@ -707,11 +713,14 @@ btree_redo(XLogRecPtr lsn, XLogRecord *record)
btree_xlog_newroot(true, lsn, record);
break;
case XLOG_BTREE_NEWMETA:
- btree_xlog_newmeta(true, lsn, record);
+ btree_xlog_newmeta(true, lsn, record, true);
break;
case XLOG_BTREE_NEWPAGE:
btree_xlog_newpage(true, lsn, record);
break;
+ case XLOG_BTREE_INVALIDMETA:
+ btree_xlog_newmeta(true, lsn, record, false);
+ break;
default:
elog(PANIC, "btree_redo: unknown op code %u", info);
}
@@ -758,11 +767,14 @@ btree_undo(XLogRecPtr lsn, XLogRecord *record)
btree_xlog_newroot(false, lsn, record);
break;
case XLOG_BTREE_NEWMETA:
- btree_xlog_newmeta(false, lsn, record);
+ btree_xlog_newmeta(false, lsn, record, true);
break;
case XLOG_BTREE_NEWPAGE:
btree_xlog_newpage(false, lsn, record);
break;
+ case XLOG_BTREE_INVALIDMETA:
+ btree_xlog_newmeta(false, lsn, record, false);
+ break;
default:
elog(PANIC, "btree_undo: unknown op code %u", info);
}
@@ -895,6 +907,16 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
xlrec->blkno);
break;
}
+ case XLOG_BTREE_INVALIDMETA:
+ {
+ xl_btree_newmeta *xlrec = (xl_btree_newmeta *) rec;
+
+ sprintf(buf + strlen(buf), "invalidmeta: node %u/%u; root %u lev %u fast %u lev %u",
+ xlrec->node.tblNode, xlrec->node.relNode,
+ xlrec->meta.root, xlrec->meta.level,
+ xlrec->meta.fastroot, xlrec->meta.fastlevel);
+ break;
+ }
default:
strcat(buf, "UNKNOWN");
break;
diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h
index 6d9c0081a92..a852fa24925 100644
--- a/src/include/access/nbtree.h
+++ b/src/include/access/nbtree.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: nbtree.h,v 1.70 2003/08/08 21:42:32 momjian Exp $
+ * $Id: nbtree.h,v 1.71 2003/09/29 23:40:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -198,6 +198,7 @@ typedef BTItemData *BTItem;
#define XLOG_BTREE_NEWROOT 0xA0 /* new root page */
#define XLOG_BTREE_NEWMETA 0xB0 /* update metadata page */
#define XLOG_BTREE_NEWPAGE 0xC0 /* new index page during build */
+#define XLOG_BTREE_INVALIDMETA 0xD0 /* new metadata, temp. invalid */
/*
* All that we need to find changed index tuple
@@ -448,7 +449,7 @@ extern void _bt_insert_parent(Relation rel, Buffer buf, Buffer rbuf,
/*
* prototypes for functions in nbtpage.c
*/
-extern void _bt_metapinit(Relation rel);
+extern void _bt_metapinit(Relation rel, bool markvalid);
extern Buffer _bt_getroot(Relation rel, int access);
extern Buffer _bt_gettrueroot(Relation rel);
extern Buffer _bt_getbuf(Relation rel, BlockNumber blkno, int access);