Remove the 'slow' path for btree index build, which built the btree
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 1 Apr 2006 03:03:37 +0000 (03:03 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 1 Apr 2006 03:03:37 +0000 (03:03 +0000)
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
src/backend/access/nbtree/nbtree.c
src/backend/access/nbtree/nbtxlog.c
src/include/access/nbtree.h

index fc48055f7ee52943c770048f0bab7f03da25699a..3160a982cc12d6db58d46b2310ab1536e0462d9c 100644 (file)
@@ -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
 #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
  */
index 59c733330b5656632bbed2acc487d58c256dd972..cfd7629bb06b1c075b89ffec863ae1a22e2ac3c3 100644 (file)
@@ -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;
index b8d33f5ae15c472bbe54ef238468dbaa09306764..c10936a8e2788d1cbee0d891fb65bc80e7bf70bf 100644 (file)
@@ -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;
index 744e06147ef29cac1724e726d4a74523e1171244..ba4a8441f1cdc4eab7b67b4d8a1683e481cfa0f9 100644 (file)
@@ -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);