From 89bda95d820faedee8e7fb127f5ba9bd4785c327 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 1 Apr 2006 03:03:37 +0000 Subject: [PATCH] Remove the 'slow' path for btree index build, which built the btree incrementally by successive inserts rather than by sorting the data. We were only using the slow path during bootstrap, apparently because when first written it failed during bootstrap --- but it works fine now AFAICT. Removing it saves a hundred or so lines of code and produces noticeably (~10%) smaller initial states of the system catalog indexes. While that won't make much difference for heavily-modified catalogs, for the more static ones there may be a useful long-term performance improvement. --- src/backend/access/nbtree/nbtpage.c | 69 +-------------------------- src/backend/access/nbtree/nbtree.c | 73 +++++++++-------------------- src/backend/access/nbtree/nbtxlog.c | 28 +---------- src/include/access/nbtree.h | 16 +------ 4 files changed, 25 insertions(+), 161 deletions(-) diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index fc48055f7e..3160a982cc 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtpage.c,v 1.94 2006/03/31 23:32:05 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtpage.c,v 1.95 2006/04/01 03:03:36 tgl Exp $ * * NOTES * Postgres btree pages look like ordinary relation pages. The opaque @@ -28,73 +28,6 @@ #include "storage/lmgr.h" -/* - * _bt_metapinit() -- Initialize the metadata page of a new btree. - * - * Note: this is actually not used for standard btree index building; - * nbtsort.c prefers not to make the metadata page valid until completion - * of build. - * - * 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. (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) -{ - Buffer buf; - Page pg; - BTMetaPageData *metad; - - if (RelationGetNumberOfBlocks(rel) != 0) - elog(ERROR, "cannot initialize non-empty btree index \"%s\"", - RelationGetRelationName(rel)); - - buf = ReadBuffer(rel, P_NEW); - Assert(BufferGetBlockNumber(buf) == BTREE_METAPAGE); - LockBuffer(buf, BT_WRITE); - pg = BufferGetPage(buf); - - /* NO ELOG(ERROR) from here till newmeta op is logged */ - START_CRIT_SECTION(); - - _bt_initmetapage(pg, P_NONE, 0); - metad = BTPageGetMeta(pg); - - MarkBufferDirty(buf); - - /* XLOG stuff */ - if (!rel->rd_istemp) - { - xl_btree_newmeta xlrec; - XLogRecPtr recptr; - XLogRecData rdata[1]; - - xlrec.node = rel->rd_node; - xlrec.meta.root = metad->btm_root; - xlrec.meta.level = metad->btm_level; - xlrec.meta.fastroot = metad->btm_fastroot; - xlrec.meta.fastlevel = metad->btm_fastlevel; - - rdata[0].data = (char *) &xlrec; - rdata[0].len = SizeOfBtreeNewmeta; - rdata[0].buffer = InvalidBuffer; - rdata[0].next = NULL; - - recptr = XLogInsert(RM_BTREE_ID, - XLOG_BTREE_NEWMETA, - rdata); - - PageSetLSN(pg, recptr); - PageSetTLI(pg, ThisTimeLineID); - } - - END_CRIT_SECTION(); - - UnlockReleaseBuffer(buf); -} - /* * _bt_initmetapage() -- Fill a page buffer with a correct metapage image */ diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 59c733330b..cfd7629bb0 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 - * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.143 2006/03/31 23:32:05 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.144 2006/04/01 03:03:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -32,7 +32,6 @@ /* Working state for btbuild and its callback */ typedef struct { - bool usefast; bool isUnique; bool haveDead; Relation heapRel; @@ -48,8 +47,6 @@ typedef struct } BTBuildState; -bool FastBuild = true; /* use SORT instead of insertion build */ - static void _bt_restscan(IndexScanDesc scan); static void btbuildCallback(Relation index, HeapTuple htup, @@ -71,13 +68,6 @@ btbuild(PG_FUNCTION_ARGS) double reltuples; BTBuildState buildstate; - /* - * bootstrap processing does something strange, so don't use sort/build - * for initial catalog indices. at some point i need to look harder at - * this. (there is some kind of incremental processing going on there.) - * -- pma 08/29/95 - */ - buildstate.usefast = (FastBuild && IsNormalProcessingMode()); buildstate.isUnique = indexInfo->ii_Unique; buildstate.haveDead = false; buildstate.heapRel = heap; @@ -98,22 +88,14 @@ btbuild(PG_FUNCTION_ARGS) elog(ERROR, "index \"%s\" already contains data", RelationGetRelationName(index)); - if (buildstate.usefast) - { - buildstate.spool = _bt_spoolinit(index, indexInfo->ii_Unique, false); + buildstate.spool = _bt_spoolinit(index, indexInfo->ii_Unique, false); - /* - * If building a unique index, put dead tuples in a second spool to - * keep them out of the uniqueness check. - */ - if (indexInfo->ii_Unique) - buildstate.spool2 = _bt_spoolinit(index, false, true); - } - else - { - /* if using slow build, initialize the btree index metadata page */ - _bt_metapinit(index); - } + /* + * If building a unique index, put dead tuples in a second spool to + * keep them out of the uniqueness check. + */ + if (indexInfo->ii_Unique) + buildstate.spool2 = _bt_spoolinit(index, false, true); /* do the heap scan */ reltuples = IndexBuildHeapScan(heap, index, indexInfo, @@ -128,17 +110,14 @@ btbuild(PG_FUNCTION_ARGS) } /* - * if we are doing bottom-up btree build, finish the build by (1) - * completing the sort of the spool file, (2) inserting the sorted tuples - * into btree pages and (3) building the upper levels. + * Finish the build by (1) completing the sort of the spool file, (2) + * inserting the sorted tuples into btree pages and (3) building the upper + * levels. */ - if (buildstate.usefast) - { - _bt_leafbuild(buildstate.spool, buildstate.spool2); - _bt_spooldestroy(buildstate.spool); - if (buildstate.spool2) - _bt_spooldestroy(buildstate.spool2); - } + _bt_leafbuild(buildstate.spool, buildstate.spool2); + _bt_spooldestroy(buildstate.spool); + if (buildstate.spool2) + _bt_spooldestroy(buildstate.spool2); #ifdef BTREE_BUILD_STATS if (log_btree_build_stats) @@ -173,24 +152,16 @@ btbuildCallback(Relation index, itup->t_tid = htup->t_self; /* - * if we are doing bottom-up btree build, we insert the index into a spool - * file for subsequent processing. otherwise, we insert into the btree. + * insert the index tuple into the appropriate spool file for subsequent + * processing */ - if (buildstate->usefast) - { - if (tupleIsAlive || buildstate->spool2 == NULL) - _bt_spool(itup, buildstate->spool); - else - { - /* dead tuples are put into spool2 */ - buildstate->haveDead = true; - _bt_spool(itup, buildstate->spool2); - } - } + if (tupleIsAlive || buildstate->spool2 == NULL) + _bt_spool(itup, buildstate->spool); else { - _bt_doinsert(index, itup, - buildstate->isUnique, buildstate->heapRel); + /* dead tuples are put into spool2 */ + buildstate->haveDead = true; + _bt_spool(itup, buildstate->spool2); } buildstate->indtuples += 1; diff --git a/src/backend/access/nbtree/nbtxlog.c b/src/backend/access/nbtree/nbtxlog.c index b8d33f5ae1..c10936a8e2 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 - * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.30 2006/03/31 23:32:05 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.31 2006/04/01 03:03:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -556,18 +556,6 @@ btree_xlog_newroot(XLogRecPtr lsn, XLogRecord *record) } } -static void -btree_xlog_newmeta(XLogRecPtr lsn, XLogRecord *record) -{ - xl_btree_newmeta *xlrec = (xl_btree_newmeta *) XLogRecGetData(record); - Relation reln; - - reln = XLogOpenRelation(xlrec->node); - _bt_restore_meta(reln, lsn, - xlrec->meta.root, xlrec->meta.level, - xlrec->meta.fastroot, xlrec->meta.fastlevel); -} - void btree_redo(XLogRecPtr lsn, XLogRecord *record) @@ -609,9 +597,6 @@ btree_redo(XLogRecPtr lsn, XLogRecord *record) case XLOG_BTREE_NEWROOT: btree_xlog_newroot(lsn, record); break; - case XLOG_BTREE_NEWMETA: - btree_xlog_newmeta(lsn, record); - break; default: elog(PANIC, "btree_redo: unknown op code %u", info); } @@ -727,17 +712,6 @@ btree_desc(StringInfo buf, uint8 xl_info, char *rec) xlrec->rootblk, xlrec->level); break; } - case XLOG_BTREE_NEWMETA: - { - xl_btree_newmeta *xlrec = (xl_btree_newmeta *) rec; - - appendStringInfo(buf, "newmeta: rel %u/%u/%u; root %u lev %u fast %u lev %u", - xlrec->node.spcNode, xlrec->node.dbNode, - xlrec->node.relNode, - xlrec->meta.root, xlrec->meta.level, - xlrec->meta.fastroot, xlrec->meta.fastlevel); - break; - } default: appendStringInfo(buf, "UNKNOWN"); break; diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index 744e06147e..ba4a8441f1 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.94 2006/03/31 23:32:06 tgl Exp $ + * $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.95 2006/04/01 03:03:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -176,7 +176,6 @@ typedef struct BTMetaPageData #define XLOG_BTREE_DELETE_PAGE 0x80 /* delete an entire page */ #define XLOG_BTREE_DELETE_PAGE_META 0x90 /* same, plus update metapage */ #define XLOG_BTREE_NEWROOT 0xA0 /* new root page */ -#define XLOG_BTREE_NEWMETA 0xB0 /* update metadata page */ /* * All that we need to find changed index tuple @@ -291,18 +290,6 @@ typedef struct xl_btree_newroot #define SizeOfBtreeNewroot (offsetof(xl_btree_newroot, level) + sizeof(uint32)) -/* - * New metapage log record. This is not issued during routine operations; - * it's only used when initializing an empty index. - */ -typedef struct xl_btree_newmeta -{ - RelFileNode node; - xl_btree_metadata meta; -} xl_btree_newmeta; - -#define SizeOfBtreeNewmeta (sizeof(xl_btree_newmeta)) - /* * Operator strategy numbers for B-tree have been moved to access/skey.h, @@ -410,7 +397,6 @@ 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_initmetapage(Page page, BlockNumber rootbknum, uint32 level); extern Buffer _bt_getroot(Relation rel, int access); extern Buffer _bt_gettrueroot(Relation rel);