Fixed two buffer manager performance problems (Markos, Vinayak, thanks for pointing these out!):

- No longer hold global mutex during page writeback
 
 - Don't reserve 90% of the buffer pool for the free list.  Now the freelist reserves 1% of the buffer pool + 6 pages, and expands if it runs out of space.
This commit is contained in:
Sears Russell 2008-10-01 20:43:58 +00:00
parent cf8eb2ca15
commit 220c33cc31

View file

@ -196,7 +196,10 @@ static Page * bhLoadPageImpl_helper(int xid, const int pageid, int uninitialized
// Is the page in cache? // Is the page in cache?
Page * ret = LH_ENTRY(find)(cachedPages, &pageid,sizeof(int)); Page * ret = LH_ENTRY(find)(cachedPages, &pageid,sizeof(int));
// Is the page already being read from disk? (If ret == 0, then no...) do {
// Is the page already in memory or being read from disk?
// (If ret == 0, then no...)
while(ret) { while(ret) {
checkPageState(ret); checkPageState(ret);
if(*pagePendingPtr(ret)) { if(*pagePendingPtr(ret)) {
@ -224,8 +227,32 @@ static Page * bhLoadPageImpl_helper(int xid, const int pageid, int uninitialized
// The page is not in cache, and is not (no longer is) pending. // The page is not in cache, and is not (no longer is) pending.
assert(!ret); assert(!ret);
// Remove a page from the freelist. // Remove a page from the freelist. This may cause writeback, and release our latch.
ret = getFreePage(); Page * ret2 = getFreePage();
// Did some other thread put the page in cache for us?
ret = LH_ENTRY(find)(cachedPages, &pageid,sizeof(int));
if(!ret) {
// No, so we're ready to add it.
ret = ret2;
// Esacpe from this loop.
break;
} else {
// Put the page back on the free list
// It's possible that we wrote this page back even though the
// freeList didn't have any free space; extend free list if necessary.
if(freeListLength == freeCount) {
freeList = realloc(freeList, freeListLength+1);
freeListLength++;
}
freeList[freeCount] = ret2;
freeCount++;
}
// try again.
} while(1);
// Add a pending entry to cachedPages to block like-minded threads and writeback // Add a pending entry to cachedPages to block like-minded threads and writeback
(*pagePendingPtr(ret)) = (void*)1; (*pagePendingPtr(ret)) = (void*)1;
@ -371,7 +398,7 @@ void bhBufInit() {
cachedPages = LH_ENTRY(create)(MAX_BUFFER_SIZE); cachedPages = LH_ENTRY(create)(MAX_BUFFER_SIZE);
freeListLength = 9 * MAX_BUFFER_SIZE / 10; freeListLength = 6 + MAX_BUFFER_SIZE / 100;
freeLowWater = freeListLength - 5; freeLowWater = freeListLength - 5;
freeCount = 0; freeCount = 0;
pageCount = 0; pageCount = 0;