Skip to content

Commit 7d443a8

Browse files
committed
Get rid of page-level locking in btree-s.
LockBuffer is used to acquire read/write access to index pages. Pages are released before leaving index internals.
1 parent 0784208 commit 7d443a8

File tree

7 files changed

+73
-132
lines changed

7 files changed

+73
-132
lines changed

src/backend/access/nbtree/nbtinsert.c

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.40 1999/05/25 16:07:23 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.41 1999/05/25 18:20:28 vadim Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -19,7 +19,6 @@
1919
#include <access/nbtree.h>
2020
#include <access/heapam.h>
2121
#include <access/xact.h>
22-
#include <storage/bufmgr.h>
2322
#include <fmgr.h>
2423

2524
#ifndef HAVE_MEMMOVE
@@ -64,14 +63,11 @@ _bt_doinsert(Relation rel, BTItem btitem, bool index_is_unique, Relation heapRel
6463
/* find the page containing this key */
6564
stack = _bt_search(rel, natts, itup_scankey, &buf);
6665

67-
blkno = BufferGetBlockNumber(buf);
68-
6966
/* trade in our read lock for a write lock */
70-
_bt_relbuf(rel, buf, BT_READ);
67+
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
68+
LockBuffer(buf, BT_WRITE);
7169

7270
l1:
73-
buf = _bt_getbuf(rel, blkno, BT_WRITE);
74-
7571
/*
7672
* If the page was split between the time that we surrendered our read
7773
* lock and acquired our write lock, then this page may no longer be
@@ -81,6 +77,7 @@ _bt_doinsert(Relation rel, BTItem btitem, bool index_is_unique, Relation heapRel
8177
*/
8278

8379
buf = _bt_moveright(rel, buf, natts, itup_scankey, BT_WRITE);
80+
blkno = BufferGetBlockNumber(buf);
8481

8582
/* if we're not allowing duplicates, make sure the key isn't */
8683
/* already in the node */
@@ -99,13 +96,13 @@ _bt_doinsert(Relation rel, BTItem btitem, bool index_is_unique, Relation heapRel
9996
/* key on the page before trying to compare it */
10097
if (!PageIsEmpty(page) && offset <= maxoff)
10198
{
102-
TupleDesc itupdesc;
103-
BTItem cbti;
104-
HeapTupleData htup;
105-
BTPageOpaque opaque;
106-
Buffer nbuf;
107-
BlockNumber blkno;
108-
bool chtup = true;
99+
TupleDesc itupdesc;
100+
BTItem cbti;
101+
HeapTupleData htup;
102+
BTPageOpaque opaque;
103+
Buffer nbuf;
104+
BlockNumber nblkno;
105+
bool chtup = true;
109106

110107
itupdesc = RelationGetDescr(rel);
111108
nbuf = InvalidBuffer;
@@ -157,7 +154,8 @@ _bt_doinsert(Relation rel, BTItem btitem, bool index_is_unique, Relation heapRel
157154
_bt_relbuf(rel, nbuf, BT_READ);
158155
_bt_relbuf(rel, buf, BT_WRITE);
159156
XactLockTableWait(xwait);
160-
goto l1;/* continue from the begin */
157+
buf = _bt_getbuf(rel, blkno, BT_WRITE);
158+
goto l1; /* continue from the begin */
161159
}
162160
elog(ERROR, "Cannot insert a duplicate key into a unique index");
163161
}
@@ -177,12 +175,12 @@ _bt_doinsert(Relation rel, BTItem btitem, bool index_is_unique, Relation heapRel
177175
* min key of the right page is the same, ooh - so
178176
* many dead duplicates...
179177
*/
180-
blkno = opaque->btpo_next;
178+
nblkno = opaque->btpo_next;
181179
if (nbuf != InvalidBuffer)
182180
_bt_relbuf(rel, nbuf, BT_READ);
183-
for (nbuf = InvalidBuffer;;)
181+
for (nbuf = InvalidBuffer; ; )
184182
{
185-
nbuf = _bt_getbuf(rel, blkno, BT_READ);
183+
nbuf = _bt_getbuf(rel, nblkno, BT_READ);
186184
page = BufferGetPage(nbuf);
187185
maxoff = PageGetMaxOffsetNumber(page);
188186
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
@@ -193,10 +191,10 @@ _bt_doinsert(Relation rel, BTItem btitem, bool index_is_unique, Relation heapRel
193191
}
194192
else
195193
{ /* Empty or "pseudo"-empty page - get next */
196-
blkno = opaque->btpo_next;
194+
nblkno = opaque->btpo_next;
197195
_bt_relbuf(rel, nbuf, BT_READ);
198196
nbuf = InvalidBuffer;
199-
if (blkno == P_NONE)
197+
if (nblkno == P_NONE)
200198
break;
201199
}
202200
}

src/backend/access/nbtree/nbtpage.c

Lines changed: 14 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.21 1999/05/25 16:07:26 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.22 1999/05/25 18:20:29 vadim Exp $
1212
*
1313
* NOTES
1414
* Postgres btree pages look like ordinary relation pages. The opaque
@@ -27,7 +27,6 @@
2727
#include <storage/bufpage.h>
2828
#include <access/nbtree.h>
2929
#include <miscadmin.h>
30-
#include <storage/bufmgr.h>
3130
#include <storage/lmgr.h>
3231

3332
#ifndef HAVE_MEMMOVE
@@ -36,26 +35,17 @@
3635
#include <string.h>
3736
#endif
3837

39-
static void _bt_setpagelock(Relation rel, BlockNumber blkno, int access);
40-
static void _bt_unsetpagelock(Relation rel, BlockNumber blkno, int access);
41-
4238
#define BTREE_METAPAGE 0
4339
#define BTREE_MAGIC 0x053162
4440

45-
#ifdef BTREE_VERSION_1
4641
#define BTREE_VERSION 1
47-
#else
48-
#define BTREE_VERSION 0
49-
#endif
5042

5143
typedef struct BTMetaPageData
5244
{
5345
uint32 btm_magic;
5446
uint32 btm_version;
5547
BlockNumber btm_root;
56-
#ifdef BTREE_VERSION_1
5748
int32 btm_level;
58-
#endif
5949
} BTMetaPageData;
6050

6151
#define BTPageGetMeta(p) \
@@ -108,9 +98,7 @@ _bt_metapinit(Relation rel)
10898
metad.btm_magic = BTREE_MAGIC;
10999
metad.btm_version = BTREE_VERSION;
110100
metad.btm_root = P_NONE;
111-
#ifdef BTREE_VERSION_1
112101
metad.btm_level = 0;
113-
#endif
114102
memmove((char *) BTPageGetMeta(pg), (char *) &metad, sizeof(metad));
115103

116104
op = (BTPageOpaque) PageGetSpecialPointer(pg);
@@ -246,9 +234,7 @@ _bt_getroot(Relation rel, int access)
246234
rootblkno = BufferGetBlockNumber(rootbuf);
247235
rootpg = BufferGetPage(rootbuf);
248236
metad->btm_root = rootblkno;
249-
#ifdef BTREE_VERSION_1
250237
metad->btm_level = 1;
251-
#endif
252238
_bt_pageinit(rootpg, BufferGetPageSize(rootbuf));
253239
rootopaque = (BTPageOpaque) PageGetSpecialPointer(rootpg);
254240
rootopaque->btpo_flags |= (BTP_LEAF | BTP_ROOT);
@@ -257,8 +243,8 @@ _bt_getroot(Relation rel, int access)
257243
/* swap write lock for read lock, if appropriate */
258244
if (access != BT_WRITE)
259245
{
260-
_bt_setpagelock(rel, rootblkno, BT_READ);
261-
_bt_unsetpagelock(rel, rootblkno, BT_WRITE);
246+
LockBuffer(rootbuf, BUFFER_LOCK_UNLOCK);
247+
LockBuffer(rootbuf, BT_READ);
262248
}
263249

264250
/* okay, metadata is correct */
@@ -322,31 +308,24 @@ _bt_getbuf(Relation rel, BlockNumber blkno, int access)
322308
Buffer buf;
323309
Page page;
324310

325-
/*
326-
* If we want a new block, we can't set a lock of the appropriate type
327-
* until we've instantiated the buffer.
328-
*/
329-
330311
if (blkno != P_NEW)
331312
{
332-
if (access == BT_WRITE)
333-
_bt_setpagelock(rel, blkno, BT_WRITE);
334-
else
335-
_bt_setpagelock(rel, blkno, BT_READ);
336-
337313
buf = ReadBuffer(rel, blkno);
314+
LockBuffer(buf, access);
338315
}
339316
else
340317
{
318+
/*
319+
* Extend bufmgr code is unclean and so we have to
320+
* use locking here.
321+
*/
322+
LockPage(rel, 0, ExclusiveLock);
341323
buf = ReadBuffer(rel, blkno);
324+
UnlockPage(rel, 0, ExclusiveLock);
342325
blkno = BufferGetBlockNumber(buf);
343326
page = BufferGetPage(buf);
344327
_bt_pageinit(page, BufferGetPageSize(buf));
345-
346-
if (access == BT_WRITE)
347-
_bt_setpagelock(rel, blkno, BT_WRITE);
348-
else
349-
_bt_setpagelock(rel, blkno, BT_READ);
328+
LockBuffer(buf, access);
350329
}
351330

352331
/* ref count and lock type are correct */
@@ -359,16 +338,7 @@ _bt_getbuf(Relation rel, BlockNumber blkno, int access)
359338
void
360339
_bt_relbuf(Relation rel, Buffer buf, int access)
361340
{
362-
BlockNumber blkno;
363-
364-
blkno = BufferGetBlockNumber(buf);
365-
366-
/* access had better be one of read or write */
367-
if (access == BT_WRITE)
368-
_bt_unsetpagelock(rel, blkno, BT_WRITE);
369-
else
370-
_bt_unsetpagelock(rel, blkno, BT_READ);
371-
341+
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
372342
ReleaseBuffer(buf);
373343
}
374344

@@ -382,11 +352,8 @@ _bt_relbuf(Relation rel, Buffer buf, int access)
382352
void
383353
_bt_wrtbuf(Relation rel, Buffer buf)
384354
{
385-
BlockNumber blkno;
386-
387-
blkno = BufferGetBlockNumber(buf);
355+
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
388356
WriteBuffer(buf);
389-
_bt_unsetpagelock(rel, blkno, BT_WRITE);
390357
}
391358

392359
/*
@@ -399,9 +366,6 @@ _bt_wrtbuf(Relation rel, Buffer buf)
399366
void
400367
_bt_wrtnorelbuf(Relation rel, Buffer buf)
401368
{
402-
BlockNumber blkno;
403-
404-
blkno = BufferGetBlockNumber(buf);
405369
WriteNoReleaseBuffer(buf);
406370
}
407371

@@ -452,12 +416,10 @@ _bt_metaproot(Relation rel, BlockNumber rootbknum, int level)
452416
Assert(metaopaque->btpo_flags & BTP_META);
453417
metad = BTPageGetMeta(metap);
454418
metad->btm_root = rootbknum;
455-
#ifdef BTREE_VERSION_1
456-
if (level == 0) /* called from _do_insert */
419+
if (level == 0) /* called from _do_insert */
457420
metad->btm_level += 1;
458421
else
459422
metad->btm_level = level; /* called from btsort */
460-
#endif
461423
_bt_wrtbuf(rel, metabuf);
462424
}
463425

@@ -582,32 +544,6 @@ _bt_getstackbuf(Relation rel, BTStack stack, int access)
582544
}
583545
}
584546

585-
static void
586-
_bt_setpagelock(Relation rel, BlockNumber blkno, int access)
587-
{
588-
589-
if (USELOCKING)
590-
{
591-
if (access == BT_WRITE)
592-
LockPage(rel, blkno, ExclusiveLock);
593-
else
594-
LockPage(rel, blkno, ShareLock);
595-
}
596-
}
597-
598-
static void
599-
_bt_unsetpagelock(Relation rel, BlockNumber blkno, int access)
600-
{
601-
602-
if (USELOCKING)
603-
{
604-
if (access == BT_WRITE)
605-
UnlockPage(rel, blkno, ExclusiveLock);
606-
else
607-
UnlockPage(rel, blkno, ShareLock);
608-
}
609-
}
610-
611547
void
612548
_bt_pagedel(Relation rel, ItemPointer tid)
613549
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy