diff options
| author | Vadim B. Mikheev <vadim4o@yahoo.com> | 1999-03-28 20:32:42 +0000 |
|---|---|---|
| committer | Vadim B. Mikheev <vadim4o@yahoo.com> | 1999-03-28 20:32:42 +0000 |
| commit | fdf6be80f993d2908f794c0a33aedff479a92813 (patch) | |
| tree | 01e6047f38baeb4124c6c331de8ed81862647353 /src/backend/access/nbtree | |
| parent | d4ed17842a44853ce339b80e111ec1bc58691c17 (diff) | |
| download | postgresql-fdf6be80f993d2908f794c0a33aedff479a92813.tar.gz | |
1. Vacuum is updated for MVCC.
2. Much faster btree tuples deletion in the case when first on page
index tuple is deleted (no movement to the left page(s)).
3. Remember blkno of new root page in BTPageOpaque of
left/right siblings when root page is splitted.
Diffstat (limited to 'src/backend/access/nbtree')
| -rw-r--r-- | src/backend/access/nbtree/nbtinsert.c | 14 | ||||
| -rw-r--r-- | src/backend/access/nbtree/nbtpage.c | 4 | ||||
| -rw-r--r-- | src/backend/access/nbtree/nbtree.c | 37 | ||||
| -rw-r--r-- | src/backend/access/nbtree/nbtscan.c | 173 | ||||
| -rw-r--r-- | src/backend/access/nbtree/nbtsearch.c | 18 |
5 files changed, 100 insertions, 146 deletions
diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c index d5d245f1ee..a0cec5d85a 100644 --- a/src/backend/access/nbtree/nbtinsert.c +++ b/src/backend/access/nbtree/nbtinsert.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.35 1999/02/13 23:14:34 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.36 1999/03/28 20:31:56 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -853,6 +853,8 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright) lopaque->btpo_next = BufferGetBlockNumber(rbuf); ropaque->btpo_next = oopaque->btpo_next; + lopaque->btpo_parent = ropaque->btpo_parent = oopaque->btpo_parent; + /* * If the page we're splitting is not the rightmost page at its level * in the tree, then the first (0) entry on the page is the high key @@ -1103,6 +1105,7 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) /* get a new root page */ rootbuf = _bt_getbuf(rel, P_NEW, BT_WRITE); rootpage = BufferGetPage(rootbuf); + rootbknum = BufferGetBlockNumber(rootbuf); _bt_pageinit(rootpage, BufferGetPageSize(rootbuf)); /* set btree special data */ @@ -1119,6 +1122,10 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) lpage = BufferGetPage(lbuf); rpage = BufferGetPage(rbuf); + ((BTPageOpaque) PageGetSpecialPointer(lpage))->btpo_parent = + ((BTPageOpaque) PageGetSpecialPointer(rpage))->btpo_parent = + rootbknum; + /* * step over the high key on the left page while building the left * page pointer. @@ -1156,11 +1163,13 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) pfree(new_item); /* write and let go of the root buffer */ - rootbknum = BufferGetBlockNumber(rootbuf); _bt_wrtbuf(rel, rootbuf); /* update metadata page with new root block number */ _bt_metaproot(rel, rootbknum, 0); + + WriteNoReleaseBuffer(lbuf); + WriteNoReleaseBuffer(rbuf); } /* @@ -1559,6 +1568,7 @@ _bt_shift(Relation rel, Buffer buf, BTStack stack, int keysz, pageop->btpo_flags |= BTP_CHAIN; pageop->btpo_prev = npageop->btpo_prev; /* restore prev */ pageop->btpo_next = nbknum; /* next points to the new page */ + pageop->btpo_parent = npageop->btpo_parent; /* init shifted page opaque */ npageop->btpo_prev = bknum = BufferGetBlockNumber(buf); diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index 812481c953..0cace9d360 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.18 1999/02/13 23:14:35 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.19 1999/03/28 20:31:57 vadim Exp $ * * NOTES * Postgres btree pages look like ordinary relation pages. The opaque @@ -421,6 +421,8 @@ _bt_pageinit(Page page, Size size) MemSet(page, 0, size); PageInit(page, size, sizeof(BTPageOpaqueData)); + ((BTPageOpaque) PageGetSpecialPointer(page))->btpo_parent = + InvalidBlockNumber; } /* diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 5ae59ccf12..2ded78b1a6 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.36 1999/02/21 03:48:27 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.37 1999/03/28 20:31:58 vadim Exp $ * * NOTES * This file contains only the public interface routines. @@ -372,11 +372,6 @@ btinsert(Relation rel, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation pfree(btitem); pfree(itup); -#ifdef NOT_USED - /* adjust any active scans that will be affected by this insertion */ - _bt_adjscans(rel, &(res->pointerData), BT_INSERT); -#endif - return res; } @@ -396,15 +391,9 @@ btgettuple(IndexScanDesc scan, ScanDirection dir) if (ItemPointerIsValid(&(scan->currentItemData))) { - /* - * Now we don't adjust scans on insertion (comments in - * nbtscan.c:_bt_scandel()) and I hope that we will unlock current - * index page before leaving index in LLL: this means that current - * index tuple could be moved right before we get here and we have - * to restore our scan position. We save heap TID pointed by - * current index tuple and use it. This will work untill we start - * to re-use (move heap tuples) without vacuum... - vadim 07/29/98 + * Restore scan position using heap TID returned + * by previous call to btgettuple(). */ _bt_restscan(scan); res = _bt_next(scan, dir); @@ -612,16 +601,12 @@ void btdelete(Relation rel, ItemPointer tid) { /* adjust any active scans that will be affected by this deletion */ - _bt_adjscans(rel, tid, BT_DELETE); + _bt_adjscans(rel, tid); /* delete the data from the page */ _bt_pagedel(rel, tid); } -/* - * Reasons are in btgettuple... We have to find index item that - * points to heap tuple returned by previous call to btgettuple(). - */ static void _bt_restscan(IndexScanDesc scan) { @@ -637,6 +622,20 @@ _bt_restscan(IndexScanDesc scan) BTItem item; BlockNumber blkno; + /* + * We use this as flag when first index tuple on page + * is deleted but we do not move left (this would + * slowdown vacuum) - so we set current->ip_posid + * before first index tuple on the current page + * (_bt_step will move it right)... + */ + if (!ItemPointerIsValid(&target)) + { + ItemPointerSetOffsetNumber(&(scan->currentItemData), + OffsetNumberPrev(P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY)); + return; + } + if (maxoff >= offnum) { diff --git a/src/backend/access/nbtree/nbtscan.c b/src/backend/access/nbtree/nbtscan.c index b5e7d1207c..a2a6707d19 100644 --- a/src/backend/access/nbtree/nbtscan.c +++ b/src/backend/access/nbtree/nbtscan.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtscan.c,v 1.19 1999/02/13 23:14:36 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtscan.c,v 1.20 1999/03/28 20:31:58 vadim Exp $ * * * NOTES @@ -43,8 +43,7 @@ typedef BTScanListData *BTScanList; static BTScanList BTScans = (BTScanList) NULL; -static void _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno); -static bool _bt_scantouched(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno); +static void _bt_scandel(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno); /* * _bt_regscan() -- register a new scan. @@ -91,7 +90,7 @@ _bt_dropscan(IndexScanDesc scan) * for a given deletion or insertion */ void -_bt_adjscans(Relation rel, ItemPointer tid, int op) +_bt_adjscans(Relation rel, ItemPointer tid) { BTScanList l; Oid relid; @@ -100,41 +99,25 @@ _bt_adjscans(Relation rel, ItemPointer tid, int op) for (l = BTScans; l != (BTScanList) NULL; l = l->btsl_next) { if (relid == RelationGetRelid(l->btsl_scan->relation)) - _bt_scandel(l->btsl_scan, op, + _bt_scandel(l->btsl_scan, ItemPointerGetBlockNumber(tid), ItemPointerGetOffsetNumber(tid)); } } /* - * _bt_scandel() -- adjust a single scan + * _bt_scandel() -- adjust a single scan on deletion * - * because each index page is always maintained as an ordered array of - * index tuples, the index tuples on a given page shift beneath any - * given scan. an index modification "behind" a scan position (i.e., - * same page, lower or equal offset number) will therefore force us to - * adjust the scan in the following ways: - * - * - on insertion, we shift the scan forward by one item. - * - on deletion, we shift the scan backward by one item. - * - * note that: - * - * - we need not worry about the actual ScanDirection of the scan - * itself, since the problem is that the "current" scan position has - * shifted. - * - modifications "ahead" of our scan position do not change the - * array index of the current scan position and so can be ignored. */ static void -_bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno) +_bt_scandel(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno) { - ItemPointer current; - Buffer buf; - BTScanOpaque so; - - if (!_bt_scantouched(scan, blkno, offno)) - return; + ItemPointer current; + Buffer buf; + BTScanOpaque so; + OffsetNumber start; + Page page; + BTPageOpaque opaque; so = (BTScanOpaque) scan->opaque; buf = so->btso_curbuf; @@ -144,33 +127,23 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno) && ItemPointerGetBlockNumber(current) == blkno && ItemPointerGetOffsetNumber(current) >= offno) { - switch (op) - { -/* - * Problems occure when current scan page is splitted! - * We saw "Non-functional updates" (ie index tuples were read twice) - * and partial updates ("good" tuples were not read at all) - due to - * losing scan position here. Look @ nbtree.c:btgettuple() - * what we do now... - vadim 07/29/98 - case BT_INSERT: - _bt_step(scan, &buf, ForwardScanDirection); - break; - */ - case BT_DELETE: - _bt_step(scan, &buf, BackwardScanDirection); - break; - default: - elog(ERROR, "_bt_scandel: bad operation '%d'", op); - /* NOTREACHED */ - } - so->btso_curbuf = buf; - if (ItemPointerIsValid(current)) + page = BufferGetPage(buf); + opaque = (BTPageOpaque) PageGetSpecialPointer(page); + start = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY; + if (ItemPointerGetOffsetNumber(current) == start) + ItemPointerSetInvalid(&(so->curHeapIptr)); + else { - Page page = BufferGetPage(buf); - BTItem btitem = (BTItem) PageGetItem(page, - PageGetItemId(page, ItemPointerGetOffsetNumber(current))); - - so->curHeapIptr = btitem->bti_itup.t_tid; + _bt_step(scan, &buf, BackwardScanDirection); + so->btso_curbuf = buf; + if (ItemPointerIsValid(current)) + { + Page pg = BufferGetPage(buf); + BTItem btitem = (BTItem) PageGetItem(pg, + PageGetItemId(pg, ItemPointerGetOffsetNumber(current))); + + so->curHeapIptr = btitem->bti_itup.t_tid; + } } } @@ -179,65 +152,39 @@ _bt_scandel(IndexScanDesc scan, int op, BlockNumber blkno, OffsetNumber offno) && ItemPointerGetBlockNumber(current) == blkno && ItemPointerGetOffsetNumber(current) >= offno) { - ItemPointerData tmp; - - tmp = *current; - *current = scan->currentItemData; - scan->currentItemData = tmp; - so->btso_curbuf = so->btso_mrkbuf; - so->btso_mrkbuf = buf; - buf = so->btso_curbuf; - switch (op) - { -/* - * ...comments are above... - case BT_INSERT: - _bt_step(scan, &buf, ForwardScanDirection); - break; - */ - case BT_DELETE: - _bt_step(scan, &buf, BackwardScanDirection); - break; - default: - elog(ERROR, "_bt_scandel: bad operation '%d'", op); - /* NOTREACHED */ - } - so->btso_curbuf = so->btso_mrkbuf; - so->btso_mrkbuf = buf; - tmp = *current; - *current = scan->currentItemData; - scan->currentItemData = tmp; - if (ItemPointerIsValid(current)) - { - Page page = BufferGetPage(buf); - BTItem btitem = (BTItem) PageGetItem(page, - PageGetItemId(page, ItemPointerGetOffsetNumber(current))); - so->mrkHeapIptr = btitem->bti_itup.t_tid; + page = BufferGetPage(so->btso_mrkbuf); + opaque = (BTPageOpaque) PageGetSpecialPointer(page); + start = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY; + + if (ItemPointerGetOffsetNumber(current) == start) + ItemPointerSetInvalid(&(so->mrkHeapIptr)); + else + { + ItemPointerData tmp; + + tmp = *current; + *current = scan->currentItemData; + scan->currentItemData = tmp; + so->btso_curbuf = so->btso_mrkbuf; + so->btso_mrkbuf = buf; + buf = so->btso_curbuf; + + _bt_step(scan, &buf, BackwardScanDirection); + + so->btso_curbuf = so->btso_mrkbuf; + so->btso_mrkbuf = buf; + tmp = *current; + *current = scan->currentItemData; + scan->currentItemData = tmp; + if (ItemPointerIsValid(current)) + { + Page pg = BufferGetPage(buf); + BTItem btitem = (BTItem) PageGetItem(pg, + PageGetItemId(pg, ItemPointerGetOffsetNumber(current))); + + so->mrkHeapIptr = btitem->bti_itup.t_tid; + } } } } - -/* - * _bt_scantouched() -- check to see if a scan is affected by a given - * change to the index - */ -static bool -_bt_scantouched(IndexScanDesc scan, BlockNumber blkno, OffsetNumber offno) -{ - ItemPointer current; - - current = &(scan->currentItemData); - if (ItemPointerIsValid(current) - && ItemPointerGetBlockNumber(current) == blkno - && ItemPointerGetOffsetNumber(current) >= offno) - return true; - - current = &(scan->currentMarkData); - if (ItemPointerIsValid(current) - && ItemPointerGetBlockNumber(current) == blkno - && ItemPointerGetOffsetNumber(current) >= offno) - return true; - - return false; -} diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index 9d9cc0f9aa..593a5453bc 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.41 1999/02/21 03:48:27 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.42 1999/03/28 20:31:58 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -706,15 +706,7 @@ _bt_next(IndexScanDesc scan, ScanDirection dir) so = (BTScanOpaque) scan->opaque; current = &(scan->currentItemData); - /* - * XXX 10 may 91: somewhere there's a bug in our management of the - * cached buffer for this scan. wei discovered it. the following is - * a workaround so he can work until i figure out what's going on. - */ - - if (!BufferIsValid(so->btso_curbuf)) - so->btso_curbuf = _bt_getbuf(rel, ItemPointerGetBlockNumber(current), - BT_READ); + Assert (BufferIsValid(so->btso_curbuf)); /* we still have the buffer pinned and locked */ buf = so->btso_curbuf; @@ -1069,7 +1061,11 @@ _bt_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir) rel = scan->relation; current = &(scan->currentItemData); - offnum = ItemPointerGetOffsetNumber(current); + /* + * Don't use ItemPointerGetOffsetNumber or you risk to get + * assertion due to ability of ip_posid to be equal 0. + */ + offnum = current->ip_posid; page = BufferGetPage(*bufP); opaque = (BTPageOpaque) PageGetSpecialPointer(page); so = (BTScanOpaque) scan->opaque; |
