❖ Buffer Pool (cont) |
Aim of buffer pool:
❖ Buffer Pool (cont) |
Buffer pool operations: (both take single PageID
request_page(pid)
release_page(pid)
request_page()
getBlock()
release_page()
putBlock()
Buffer pool data structures:
Page frames[NBUFS]
FrameData directory[NBUFS]
Page
byte[BUFSIZE]
❖ Buffer Pool (cont) |
For each frame, we need to know: (FrameData
❖ Buffer Pool (cont) |
How scans are performed without Buffer Pool:
Buffer buf; int N = numberOfBlocks(Rel); for (i = 0; i < N; i++) { pageID = makePageID(db,Rel,i); getBlock(pageID, buf); for (j = 0; j < nTuples(buf); j++) process(buf, j) }
Requires N
If we read it again, N
❖ Buffer Pool (cont) |
How scans are performed with Buffer Pool:
Buffer buf; int N = numberOfBlocks(Rel); for (i = 0; i < N; i++) { pageID = makePageID(db,Rel,i); bufID = request_page(pageID); buf = frames[bufID] for (j = 0; j < nTuples(buf); j++) process(buf, j) release_page(pageID); }
Requires N
If we read it again, 0 ≤ page reads ≤ N
❖ Buffer Pool (cont) |
Implementation of request_page()
int request_page(PageID pid) { if (pid in Pool) bufID = index for pid in Pool else { if (no free frames in Pool) evict a page (free a frame) bufID = allocate free frame directory[bufID].page = pid directory[bufID].pin_count = 0 directory[bufID].dirty_bit = 0 } directory[bufID].pin_count++ return bufID }
❖ Buffer Pool (cont) |
The release_page(pid)
The
The
mark_page(pid)
operation:
Note: doesn't actually write to disk; indicates that page changed
flush_page(pid)
Note: not generally used by higher levels of DBMS
write_page
❖ Buffer Pool (cont) |
Evicting a page ...
❖ Page Replacement Policies |
Several schemes are commonly in use:
❖ Page Replacement Policies (cont) |
Cost benefit from buffer pool (with n frames) is determined by:
First scan costs b reads; subsequent scans are "free".
Example (b): sequential scan, MRU, n < b
First scan costs b reads; subsequent scans cost b - n reads.
Example (c): sequential scan, LRU, n < b
All scans cost b reads; known as sequential flooding.
❖ Effect of Buffer Management |
Consider a query to find customers who are also employees:
select c.name from Customer c, Employee e where c.ssn = e.ssn;
This might be implemented inside the DBMS via nested loops:
for each tuple t1 in Customer { for each tuple t2 in Employee { if (t1.ssn == t2.ssn) append (t1.name) to result set } }
❖ Effect of Buffer Management (cont) |
In terms of page-level operations, the algorithm looks like:
Rel rC = openRelation("Customer"); Rel rE = openRelation("Employee"); for (int i = 0; i < nPages(rC); i++) { PageID pid1 = makePageID(db,rC,i); Page p1 = request_page(pid1); for (int j = 0; j < nPages(rE); j++) { PageID pid2 = makePageID(db,rE,j); Page p2 = request_page(pid2); // compare all pairs of tuples from p1,p2 // construct solution set from matching pairs release_page(pid2); } release_page(pid1); }
❖ Effect of Buffer Management (cont) |
Costs depend on relative size of tables, #buffers (n), replacement strategy
Requests: each rC page requested once, each rE page requested rC times
If nPages(rC)+nPages(rE) ≤ n
Produced: 20 Feb 2023