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:
parent
cf8eb2ca15
commit
220c33cc31
1 changed files with 54 additions and 27 deletions
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue