Commit 2095206d authored by Tom Lane's avatar Tom Lane

Adjust btree index build to not use shared buffers, thereby avoiding the

locking conflict against concurrent CHECKPOINT that was discussed a few
weeks ago.  Also, if not using WAL archiving (which is always true ATM
but won't be if PITR makes it into this release), there's no need to
WAL-log the index build process; it's sufficient to force-fsync the
completed index before commit.  This seems to gain about a factor of 2
in my tests, which is consistent with writing half as much data.  I did
not try it with WAL on a separate drive though --- probably the gain would
be a lot less in that scenario.
parent 4d0e47d5
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtpage.c,v 1.75 2004/04/21 18:24:25 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtpage.c,v 1.76 2004/06/02 17:28:17 tgl Exp $
* *
* NOTES * NOTES
* Postgres btree pages look like ordinary relation pages. The opaque * Postgres btree pages look like ordinary relation pages. The opaque
...@@ -31,8 +31,9 @@ ...@@ -31,8 +31,9 @@
/* /*
* _bt_metapinit() -- Initialize the metadata page of a new btree. * _bt_metapinit() -- Initialize the metadata page of a new btree.
* *
* If markvalid is true, the index is immediately marked valid, else it * Note: this is actually not used for standard btree index building;
* will be invalid until _bt_metaproot() is called. * 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 * 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 * creating the index hasn't committed yet, no one else can even see the index
...@@ -40,12 +41,11 @@ ...@@ -40,12 +41,11 @@
* not true, but we assume the caller holds sufficient locks on the index.) * not true, but we assume the caller holds sufficient locks on the index.)
*/ */
void void
_bt_metapinit(Relation rel, bool markvalid) _bt_metapinit(Relation rel)
{ {
Buffer buf; Buffer buf;
Page pg; Page pg;
BTMetaPageData *metad; BTMetaPageData *metad;
BTPageOpaque op;
if (RelationGetNumberOfBlocks(rel) != 0) if (RelationGetNumberOfBlocks(rel) != 0)
elog(ERROR, "cannot initialize non-empty btree index \"%s\"", elog(ERROR, "cannot initialize non-empty btree index \"%s\"",
...@@ -55,21 +55,11 @@ _bt_metapinit(Relation rel, bool markvalid) ...@@ -55,21 +55,11 @@ _bt_metapinit(Relation rel, bool markvalid)
Assert(BufferGetBlockNumber(buf) == BTREE_METAPAGE); Assert(BufferGetBlockNumber(buf) == BTREE_METAPAGE);
pg = BufferGetPage(buf); pg = BufferGetPage(buf);
/* NO ELOG(ERROR) from here till newmeta op is logged */ _bt_initmetapage(pg, P_NONE, 0);
START_CRIT_SECTION();
_bt_pageinit(pg, BufferGetPageSize(buf));
metad = BTPageGetMeta(pg); metad = BTPageGetMeta(pg);
metad->btm_magic = markvalid ? BTREE_MAGIC : 0;
metad->btm_version = BTREE_VERSION;
metad->btm_root = P_NONE;
metad->btm_level = 0;
metad->btm_fastroot = P_NONE;
metad->btm_fastlevel = 0;
op = (BTPageOpaque) PageGetSpecialPointer(pg); /* NO ELOG(ERROR) from here till newmeta op is logged */
op->btpo_flags = BTP_META; START_CRIT_SECTION();
/* XLOG stuff */ /* XLOG stuff */
if (!rel->rd_istemp) if (!rel->rd_istemp)
...@@ -90,7 +80,7 @@ _bt_metapinit(Relation rel, bool markvalid) ...@@ -90,7 +80,7 @@ _bt_metapinit(Relation rel, bool markvalid)
rdata[0].next = NULL; rdata[0].next = NULL;
recptr = XLogInsert(RM_BTREE_ID, recptr = XLogInsert(RM_BTREE_ID,
markvalid ? XLOG_BTREE_NEWMETA : XLOG_BTREE_INVALIDMETA, XLOG_BTREE_NEWMETA,
rdata); rdata);
PageSetLSN(pg, recptr); PageSetLSN(pg, recptr);
...@@ -102,6 +92,29 @@ _bt_metapinit(Relation rel, bool markvalid) ...@@ -102,6 +92,29 @@ _bt_metapinit(Relation rel, bool markvalid)
WriteBuffer(buf); WriteBuffer(buf);
} }
/*
* _bt_initmetapage() -- Fill a page buffer with a correct metapage image
*/
void
_bt_initmetapage(Page page, BlockNumber rootbknum, uint32 level)
{
BTMetaPageData *metad;
BTPageOpaque metaopaque;
_bt_pageinit(page, BLCKSZ);
metad = BTPageGetMeta(page);
metad->btm_magic = BTREE_MAGIC;
metad->btm_version = BTREE_VERSION;
metad->btm_root = rootbknum;
metad->btm_level = level;
metad->btm_fastroot = rootbknum;
metad->btm_fastlevel = level;
metaopaque = (BTPageOpaque) PageGetSpecialPointer(page);
metaopaque->btpo_flags = BTP_META;
}
/* /*
* _bt_getroot() -- Get the root page of the btree. * _bt_getroot() -- Get the root page of the btree.
* *
...@@ -609,76 +622,6 @@ _bt_page_recyclable(Page page) ...@@ -609,76 +622,6 @@ _bt_page_recyclable(Page page)
return false; return false;
} }
/*
* _bt_metaproot() -- Change the root page of the btree.
*
* Lehman and Yao require that the root page move around in order to
* guarantee deadlock-free short-term, fine-granularity locking. When
* we split the root page, we record the new parent in the metadata page
* for the relation. This routine does the work.
*
* No direct preconditions, but if you don't have the write lock on
* at least the old root page when you call this, you're making a big
* mistake. On exit, metapage data is correct and we no longer have
* a pin or lock on the metapage.
*
* Actually this is not used for splitting on-the-fly anymore. It's only used
* in nbtsort.c at the completion of btree building, where we know we have
* sole access to the index anyway.
*/
void
_bt_metaproot(Relation rel, BlockNumber rootbknum, uint32 level)
{
Buffer metabuf;
Page metap;
BTPageOpaque metaopaque;
BTMetaPageData *metad;
metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_WRITE);
metap = BufferGetPage(metabuf);
metaopaque = (BTPageOpaque) PageGetSpecialPointer(metap);
Assert(metaopaque->btpo_flags & BTP_META);
/* NO ELOG(ERROR) from here till newmeta op is logged */
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;
metad->btm_fastlevel = level;
/* 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].buffer = InvalidBuffer;
rdata[0].data = (char *) &xlrec;
rdata[0].len = SizeOfBtreeNewmeta;
rdata[0].next = NULL;
recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_NEWMETA, rdata);
PageSetLSN(metap, recptr);
PageSetSUI(metap, ThisStartUpID);
}
END_CRIT_SECTION();
_bt_wrtbuf(rel, metabuf);
}
/* /*
* Delete item(s) from a btree page. * Delete item(s) from a btree page.
* *
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.116 2004/05/31 19:24:04 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.117 2004/06/02 17:28:17 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -112,10 +112,6 @@ btbuild(PG_FUNCTION_ARGS) ...@@ -112,10 +112,6 @@ btbuild(PG_FUNCTION_ARGS)
elog(ERROR, "index \"%s\" already contains data", elog(ERROR, "index \"%s\" already contains data",
RelationGetRelationName(index)); RelationGetRelationName(index));
/* initialize the btree index metadata page */
/* mark it valid right away only if using slow build */
_bt_metapinit(index, !buildstate.usefast);
if (buildstate.usefast) if (buildstate.usefast)
{ {
buildstate.spool = _bt_spoolinit(index, indexInfo->ii_Unique, false); buildstate.spool = _bt_spoolinit(index, indexInfo->ii_Unique, false);
...@@ -127,6 +123,11 @@ btbuild(PG_FUNCTION_ARGS) ...@@ -127,6 +123,11 @@ btbuild(PG_FUNCTION_ARGS)
if (indexInfo->ii_Unique) if (indexInfo->ii_Unique)
buildstate.spool2 = _bt_spoolinit(index, false, true); buildstate.spool2 = _bt_spoolinit(index, false, true);
} }
else
{
/* if using slow build, initialize the btree index metadata page */
_bt_metapinit(index);
}
/* do the heap scan */ /* do the heap scan */
reltuples = IndexBuildHeapScan(heap, index, indexInfo, reltuples = IndexBuildHeapScan(heap, index, indexInfo,
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.12 2004/05/30 23:40:25 neilc Exp $ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.13 2004/06/02 17:28:17 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -110,8 +110,7 @@ _bt_restore_page(Page page, char *from, int len) ...@@ -110,8 +110,7 @@ _bt_restore_page(Page page, char *from, int len)
static void static void
_bt_restore_meta(Relation reln, XLogRecPtr lsn, _bt_restore_meta(Relation reln, XLogRecPtr lsn,
BlockNumber root, uint32 level, BlockNumber root, uint32 level,
BlockNumber fastroot, uint32 fastlevel, BlockNumber fastroot, uint32 fastlevel)
bool markvalid)
{ {
Buffer metabuf; Buffer metabuf;
Page metapg; Page metapg;
...@@ -126,7 +125,7 @@ _bt_restore_meta(Relation reln, XLogRecPtr lsn, ...@@ -126,7 +125,7 @@ _bt_restore_meta(Relation reln, XLogRecPtr lsn,
_bt_pageinit(metapg, BufferGetPageSize(metabuf)); _bt_pageinit(metapg, BufferGetPageSize(metabuf));
md = BTPageGetMeta(metapg); md = BTPageGetMeta(metapg);
md->btm_magic = markvalid ? BTREE_MAGIC : 0; md->btm_magic = BTREE_MAGIC;
md->btm_version = BTREE_VERSION; md->btm_version = BTREE_VERSION;
md->btm_root = root; md->btm_root = root;
md->btm_level = level; md->btm_level = level;
...@@ -223,8 +222,7 @@ btree_xlog_insert(bool redo, bool isleaf, bool ismeta, ...@@ -223,8 +222,7 @@ btree_xlog_insert(bool redo, bool isleaf, bool ismeta,
if (ismeta) if (ismeta)
_bt_restore_meta(reln, lsn, _bt_restore_meta(reln, lsn,
md.root, md.level, md.root, md.level,
md.fastroot, md.fastlevel, md.fastroot, md.fastlevel);
true);
} }
/* Forget any split this insertion completes */ /* Forget any split this insertion completes */
...@@ -594,8 +592,7 @@ btree_xlog_delete_page(bool redo, bool ismeta, ...@@ -594,8 +592,7 @@ btree_xlog_delete_page(bool redo, bool ismeta,
sizeof(xl_btree_metadata)); sizeof(xl_btree_metadata));
_bt_restore_meta(reln, lsn, _bt_restore_meta(reln, lsn,
md.root, md.level, md.root, md.level,
md.fastroot, md.fastlevel, md.fastroot, md.fastlevel);
true);
} }
} }
} }
...@@ -641,8 +638,7 @@ btree_xlog_newroot(bool redo, XLogRecPtr lsn, XLogRecord *record) ...@@ -641,8 +638,7 @@ btree_xlog_newroot(bool redo, XLogRecPtr lsn, XLogRecord *record)
_bt_restore_meta(reln, lsn, _bt_restore_meta(reln, lsn,
xlrec->rootblk, xlrec->level, xlrec->rootblk, xlrec->level,
xlrec->rootblk, xlrec->level, xlrec->rootblk, xlrec->level);
true);
/* Check to see if this satisfies any incomplete insertions */ /* Check to see if this satisfies any incomplete insertions */
if (record->xl_len > SizeOfBtreeNewroot && if (record->xl_len > SizeOfBtreeNewroot &&
...@@ -656,8 +652,7 @@ btree_xlog_newroot(bool redo, XLogRecPtr lsn, XLogRecord *record) ...@@ -656,8 +652,7 @@ btree_xlog_newroot(bool redo, XLogRecPtr lsn, XLogRecord *record)
} }
static void 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); xl_btree_newmeta *xlrec = (xl_btree_newmeta *) XLogRecGetData(record);
Relation reln; Relation reln;
...@@ -671,8 +666,7 @@ btree_xlog_newmeta(bool redo, XLogRecPtr lsn, XLogRecord *record, ...@@ -671,8 +666,7 @@ btree_xlog_newmeta(bool redo, XLogRecPtr lsn, XLogRecord *record,
_bt_restore_meta(reln, lsn, _bt_restore_meta(reln, lsn,
xlrec->meta.root, xlrec->meta.level, xlrec->meta.root, xlrec->meta.level,
xlrec->meta.fastroot, xlrec->meta.fastlevel, xlrec->meta.fastroot, xlrec->meta.fastlevel);
markvalid);
} }
static void static void
...@@ -745,14 +739,11 @@ btree_redo(XLogRecPtr lsn, XLogRecord *record) ...@@ -745,14 +739,11 @@ btree_redo(XLogRecPtr lsn, XLogRecord *record)
btree_xlog_newroot(true, lsn, record); btree_xlog_newroot(true, lsn, record);
break; break;
case XLOG_BTREE_NEWMETA: case XLOG_BTREE_NEWMETA:
btree_xlog_newmeta(true, lsn, record, true); btree_xlog_newmeta(true, lsn, record);
break; break;
case XLOG_BTREE_NEWPAGE: case XLOG_BTREE_NEWPAGE:
btree_xlog_newpage(true, lsn, record); btree_xlog_newpage(true, lsn, record);
break; break;
case XLOG_BTREE_INVALIDMETA:
btree_xlog_newmeta(true, lsn, record, false);
break;
default: default:
elog(PANIC, "btree_redo: unknown op code %u", info); elog(PANIC, "btree_redo: unknown op code %u", info);
} }
...@@ -799,14 +790,11 @@ btree_undo(XLogRecPtr lsn, XLogRecord *record) ...@@ -799,14 +790,11 @@ btree_undo(XLogRecPtr lsn, XLogRecord *record)
btree_xlog_newroot(false, lsn, record); btree_xlog_newroot(false, lsn, record);
break; break;
case XLOG_BTREE_NEWMETA: case XLOG_BTREE_NEWMETA:
btree_xlog_newmeta(false, lsn, record, true); btree_xlog_newmeta(false, lsn, record);
break; break;
case XLOG_BTREE_NEWPAGE: case XLOG_BTREE_NEWPAGE:
btree_xlog_newpage(false, lsn, record); btree_xlog_newpage(false, lsn, record);
break; break;
case XLOG_BTREE_INVALIDMETA:
btree_xlog_newmeta(false, lsn, record, false);
break;
default: default:
elog(PANIC, "btree_undo: unknown op code %u", info); elog(PANIC, "btree_undo: unknown op code %u", info);
} }
...@@ -939,16 +927,6 @@ btree_desc(char *buf, uint8 xl_info, char *rec) ...@@ -939,16 +927,6 @@ btree_desc(char *buf, uint8 xl_info, char *rec)
xlrec->blkno); xlrec->blkno);
break; 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: default:
strcat(buf, "UNKNOWN"); strcat(buf, "UNKNOWN");
break; break;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/smgr/md.c,v 1.106 2004/05/31 20:31:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/smgr/md.c,v 1.107 2004/06/02 17:28:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -661,6 +661,40 @@ mdtruncate(SMgrRelation reln, BlockNumber nblocks, bool isTemp) ...@@ -661,6 +661,40 @@ mdtruncate(SMgrRelation reln, BlockNumber nblocks, bool isTemp)
return nblocks; return nblocks;
} }
/*
* mdimmedsync() -- Immediately sync a relation to stable storage.
*/
bool
mdimmedsync(SMgrRelation reln)
{
MdfdVec *v;
BlockNumber curnblk;
/*
* NOTE: mdnblocks makes sure we have opened all existing segments, so
* that fsync loop will get them all!
*/
curnblk = mdnblocks(reln);
if (curnblk == InvalidBlockNumber)
return false; /* mdnblocks failed */
v = mdopen(reln, false);
#ifndef LET_OS_MANAGE_FILESIZE
while (v != NULL)
{
if (FileSync(v->mdfd_vfd) < 0)
return false;
v = v->mdfd_chain;
}
#else
if (FileSync(v->mdfd_vfd) < 0)
return false;
#endif
return true;
}
/* /*
* mdsync() -- Sync previous writes to stable storage. * mdsync() -- Sync previous writes to stable storage.
* *
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.72 2004/05/31 20:31:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.73 2004/06/02 17:28:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -48,6 +48,7 @@ typedef struct f_smgr ...@@ -48,6 +48,7 @@ typedef struct f_smgr
BlockNumber (*smgr_nblocks) (SMgrRelation reln); BlockNumber (*smgr_nblocks) (SMgrRelation reln);
BlockNumber (*smgr_truncate) (SMgrRelation reln, BlockNumber nblocks, BlockNumber (*smgr_truncate) (SMgrRelation reln, BlockNumber nblocks,
bool isTemp); bool isTemp);
bool (*smgr_immedsync) (SMgrRelation reln);
bool (*smgr_commit) (void); /* may be NULL */ bool (*smgr_commit) (void); /* may be NULL */
bool (*smgr_abort) (void); /* may be NULL */ bool (*smgr_abort) (void); /* may be NULL */
bool (*smgr_sync) (void); /* may be NULL */ bool (*smgr_sync) (void); /* may be NULL */
...@@ -57,7 +58,8 @@ typedef struct f_smgr ...@@ -57,7 +58,8 @@ typedef struct f_smgr
static const f_smgr smgrsw[] = { static const f_smgr smgrsw[] = {
/* magnetic disk */ /* magnetic disk */
{mdinit, NULL, mdclose, mdcreate, mdunlink, mdextend, {mdinit, NULL, mdclose, mdcreate, mdunlink, mdextend,
mdread, mdwrite, mdnblocks, mdtruncate, NULL, NULL, mdsync mdread, mdwrite, mdnblocks, mdtruncate, mdimmedsync,
NULL, NULL, mdsync
} }
}; };
...@@ -582,6 +584,34 @@ smgrtruncate(SMgrRelation reln, BlockNumber nblocks, bool isTemp) ...@@ -582,6 +584,34 @@ smgrtruncate(SMgrRelation reln, BlockNumber nblocks, bool isTemp)
return newblks; return newblks;
} }
/*
* smgrimmedsync() -- Force the specified relation to stable storage.
*
* Synchronously force all of the specified relation down to disk.
*
* This is really only useful for non-WAL-logged index building:
* instead of incrementally WAL-logging the index build steps,
* we can just write completed index pages to disk with smgrwrite
* or smgrextend, and then fsync the completed index file before
* committing the transaction. (This is sufficient for purposes of
* crash recovery, since it effectively duplicates forcing a checkpoint
* for the completed index. But it is *not* workable if one wishes
* to use the WAL log for PITR or replication purposes.)
*
* The preceding writes should specify isTemp = true to avoid
* duplicative fsyncs.
*/
void
smgrimmedsync(SMgrRelation reln)
{
if (! (*(smgrsw[reln->smgr_which].smgr_immedsync)) (reln))
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not sync relation %u/%u: %m",
reln->smgr_rnode.tblNode,
reln->smgr_rnode.relNode)));
}
/* /*
* smgrDoPendingDeletes() -- Take care of relation deletes at end of xact. * smgrDoPendingDeletes() -- Take care of relation deletes at end of xact.
*/ */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.77 2004/04/21 18:24:26 tgl Exp $ * $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.78 2004/06/02 17:28:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -198,7 +198,6 @@ typedef BTItemData *BTItem; ...@@ -198,7 +198,6 @@ typedef BTItemData *BTItem;
#define XLOG_BTREE_NEWROOT 0xA0 /* new root page */ #define XLOG_BTREE_NEWROOT 0xA0 /* new root page */
#define XLOG_BTREE_NEWMETA 0xB0 /* update metadata page */ #define XLOG_BTREE_NEWMETA 0xB0 /* update metadata page */
#define XLOG_BTREE_NEWPAGE 0xC0 /* new index page during build */ #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 * All that we need to find changed index tuple
...@@ -315,8 +314,7 @@ typedef struct xl_btree_newroot ...@@ -315,8 +314,7 @@ typedef struct xl_btree_newroot
/* /*
* New metapage log record. This is not issued during routine operations; * New metapage log record. This is not issued during routine operations;
* it's only used when initializing an empty index and at completion of * it's only used when initializing an empty index.
* index build.
*/ */
typedef struct xl_btree_newmeta typedef struct xl_btree_newmeta
{ {
...@@ -442,7 +440,8 @@ extern void _bt_insert_parent(Relation rel, Buffer buf, Buffer rbuf, ...@@ -442,7 +440,8 @@ extern void _bt_insert_parent(Relation rel, Buffer buf, Buffer rbuf,
/* /*
* prototypes for functions in nbtpage.c * prototypes for functions in nbtpage.c
*/ */
extern void _bt_metapinit(Relation rel, bool markvalid); 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_getroot(Relation rel, int access);
extern Buffer _bt_gettrueroot(Relation rel); extern Buffer _bt_gettrueroot(Relation rel);
extern Buffer _bt_getbuf(Relation rel, BlockNumber blkno, int access); extern Buffer _bt_getbuf(Relation rel, BlockNumber blkno, int access);
...@@ -453,7 +452,6 @@ extern void _bt_wrtbuf(Relation rel, Buffer buf); ...@@ -453,7 +452,6 @@ extern void _bt_wrtbuf(Relation rel, Buffer buf);
extern void _bt_wrtnorelbuf(Relation rel, Buffer buf); extern void _bt_wrtnorelbuf(Relation rel, Buffer buf);
extern void _bt_pageinit(Page page, Size size); extern void _bt_pageinit(Page page, Size size);
extern bool _bt_page_recyclable(Page page); extern bool _bt_page_recyclable(Page page);
extern void _bt_metaproot(Relation rel, BlockNumber rootbknum, uint32 level);
extern void _bt_delitems(Relation rel, Buffer buf, extern void _bt_delitems(Relation rel, Buffer buf,
OffsetNumber *itemnos, int nitems); OffsetNumber *itemnos, int nitems);
extern int _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full); extern int _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/storage/smgr.h,v 1.43 2004/05/31 20:31:33 tgl Exp $ * $PostgreSQL: pgsql/src/include/storage/smgr.h,v 1.44 2004/06/02 17:28:18 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -63,6 +63,7 @@ extern void smgrwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer, ...@@ -63,6 +63,7 @@ extern void smgrwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer,
extern BlockNumber smgrnblocks(SMgrRelation reln); extern BlockNumber smgrnblocks(SMgrRelation reln);
extern BlockNumber smgrtruncate(SMgrRelation reln, BlockNumber nblocks, extern BlockNumber smgrtruncate(SMgrRelation reln, BlockNumber nblocks,
bool isTemp); bool isTemp);
extern void smgrimmedsync(SMgrRelation reln);
extern void smgrDoPendingDeletes(bool isCommit); extern void smgrDoPendingDeletes(bool isCommit);
extern int smgrGetPendingDeletes(bool forCommit, RelFileNode **ptr); extern int smgrGetPendingDeletes(bool forCommit, RelFileNode **ptr);
extern void smgrcommit(void); extern void smgrcommit(void);
...@@ -89,6 +90,7 @@ extern bool mdwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer, ...@@ -89,6 +90,7 @@ extern bool mdwrite(SMgrRelation reln, BlockNumber blocknum, char *buffer,
extern BlockNumber mdnblocks(SMgrRelation reln); extern BlockNumber mdnblocks(SMgrRelation reln);
extern BlockNumber mdtruncate(SMgrRelation reln, BlockNumber nblocks, extern BlockNumber mdtruncate(SMgrRelation reln, BlockNumber nblocks,
bool isTemp); bool isTemp);
extern bool mdimmedsync(SMgrRelation reln);
extern bool mdsync(void); extern bool mdsync(void);
extern void RememberFsyncRequest(RelFileNode rnode, BlockNumber segno); extern void RememberFsyncRequest(RelFileNode rnode, BlockNumber segno);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment