-
Notifications
You must be signed in to change notification settings - Fork 0
/
answers.txt
56 lines (38 loc) · 4.7 KB
/
answers.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
Write-up
>>Descriptions
#Bufferpool: Added private class LockManager, which I will describe in the "Changed API" Section.
We also initialized an instance of LockManager to the initialization of BufferPool.
getPage(): We implement blocking here and transactions must acquire the desired lock before returning a page. This method calls LockManger's grantLock() method to check if a lock can be granted before we proceed to get the relevant page.
LOCKING GRANULARITY: page-level: we used Page-Level Locking as suggested by the project guidelines
DEADLOCK DETECTION POLICY: We are detecting deadlocks with timeout. If a thread has been requesting a lock for a set time, then we assume there may be a deadlock. This is easier to implement than with a dependency graph.
Deadlock resolution: Abort myself (the transaction trying to call getPage()).
releasePage(): release a transaction's lock on a page; calls LockManager's releaseLock() method.
holdsLock(): Determines whether a page is already locked by a transaction; calls LockManager's holdsLock() method.
evictPage(): To implement NO STEAL policy, one justification we made is that before evicting a page, we check if the page is dirty or not. If it is, we try to check other pages, and if all the pages are dirty, we throw a DbException.
transactionComplete(): This method aborts or commits a transaction. If it is commit, it retrieves all pages in the buffer pool that have been dirtied by the transaction and flush these pages to disk with flushPages(tid). If it is an abort call, we find all pages in the buffer pool dirtied by the particular transaction and we don't write anything to disk. Instead, we update the page in the buffer pool with the before image with page.getBeforeImage().
Then ask the lockManager to release all locks held by the transaction by calling releaseAllTidLocks().
Questions about FORCE/NO STEAL:
Why does NO STEAL/FORCE and no crashes while processing transactionComplete makes your job easier. In other words, what's complicated about implementing STEAL/NO FORCE buffer management policy and what measures do we need to take if our system could crash while running transactionComplete?
FORCE/NO STEAL is a simplification because we do not have to worry about UNDO/REDO logging which STEAL/NO FORCE would have to consider(mentioned briefly below). In FORCE/NO STEAL, we don't need to consider having to keep extra data for possible REDOs and UNDOs. If our system could crash during transactionComplete, we have to do logging so we can do REDOs and UNDOs, because atomicity and durability may not be maintained with NO STEAL/FORCE alone.
What ACID properties do these simplifications above aim to guarantee?
FORCE ensures DURABILITY because when a transaction commits, we know that all its updates made it to disk. Wont' have a situation where the system crashes before a modification made by a committed transaction is able to make it successfully to disk. Otherwise, we would have to keep data (logs) to REDO "lost" updates.
NO STEAL ensures ATOMICITY because uncommitted data cannot overwrite committed data on disk. Transactions that perform updates may abort or system can crash before a transaction is finished. We would have to worry about old values and would have to UNDO writing.
>>Changed API
#LockManager: A private helper class within BufferPool, and have the synchronized methods holdsLock, releaseLock, releaseAllTidLocks and grantLock. It has 4 instance variables: pageReadLocks, pageWriteLocks, sharedPages, and exclusivePages.
pageReadLocks: maps PageId to its set of shared locks (a set of TransactionIds);
pageWriteLocks: maps PageId to its exclusive lock (a TransactionId),
sharedPages: maps TransactionId to its set of PageIds of pages it is reading;
exclusivePages: maps TransactionId to its set of PageIds of pages it is writing;
holdsLock() checks to see if a transaction has a lock on a page, it it does, reture true;
releaseLock() release a transaction's lock on a page specified by pid;
releaseAllTidLocks() releases all of the locks a transaction holds.
grantLock() not only checks the lock request's type, but also return true if the request if granted.
This design makes the Locking easier in the BufferPool. We also need to add a initialization of an instance of LockManager to the initalizatio of BufferPool.
>>Missing or incomplete elements of your code
#TransactionTest: multi-thread failed; test tuple remains unchanged and is always 0 indicating that no transaction was able to successfully update the tuple. Single thread passes, and all other tests pass as well.
>>Who worked on what
PairProgramming driver and navigator
Shihao Ren(bz): driver for Ex. 1,2,3;
Nan Li(bs): driver for Ex.4,5
>>Time&Difficulty
Roughly 40 hours spanning over 6 days for the entire project.