Riki Otaki
July 28, 2021

# OCC and SILO

Analyzes the commit protocol of Optimistic Concurrency Control (OCC) in detail.
Explains why SILO uses Epochs and Tids to maintain logs.

July 28, 2021

## Transcript

2. ### Optimistic concurrency control Read Critical Section and Write Critical Section

• Read Critical Section: Read->Verify • Avoid concurrent writing to the reading data by other Txs • Write Critical Section: Lock->Write+Unlock • Avoid concurrent reading/writing of the writing data by other Txs • OCC commit protocol • Read -> Lock -> Verify -> Write+Unlock • Why is it in this order? Is Read->Verify->Lock->Write+Unlock also possible? 2
3. ### Optimistic concurrency control Case1: Read->Verify->Lock->Write+Unlock • This order causes “lost-update”

• If there is a gap between Verify and Lock,  other Txs can write to the same data of  the original Tx’s write set • Tx2’s update is lost • If Verify and Lock are executed indivisibly  (= other Txs are suspended during such   execution), this order works • Lock needs to come before Verify if they   are not an atomic operation Read(x) = 3 Verify(x = 3) Lock(x) Write(x:=x+2=5) Unlock(x) Read(x) = 3 Verify(x = 3) Lock(x) Write(x:=x+1=4) Unlock(x) Tx1 Tx2 Update Lost! 3
4. ### • Lock before Read only works if   writeset is

known before read.   The data of writeset often depends   on the result of a Read so this order is  unlikely to work. • Lock->Read might cause locking of all   possible data that a Tx might write,   which will cause unnecessary locking of data. Lock(x) Write(x:=z+1=6) Unlock(x) Lock(x) Write(x:=y+2=5) Unlock(x) Optimistic Concurrency Control Case2: Lock->Read->Verify->Write+Unlock Read(y) = 3 Verify(y = 3) Tx1 Read(z) = 5 Verify(z = 5) Tx2 4
5. ### • No lost-update problem • This is the order actually

used in OCC Optimistic Concurrency Control Case3: Read->Lock->Verify->Write+Unlock Read(x) = 3 Lock(x) Verify(x=3) Write(x:=x+2=5) Unlock(x) Tx1 Tx2 Read(x) = 3 Lock(x) Verify(x=3) Write(x:=x+1=4) Unlock(x) Abort! 5

7. ### Optimistic Concurrency Control Why serial order is important? • Serial

order is used for recovery. To redo the logs, logs need to be ordered in w-w order of transactions. Serial order contains w-w order. • S = w1(x)r2(x)w1(y)w2(y)c1c2 • Serial order: w1(x)w1(y)c1r2(x)w2(y)c2 i.e. {w1(x), r2(x)}, {w1(y), w2(y)} • w-w order: {w1(y), w2(y)} 7
8. ### Optimistic Concurrency Control How to get serial order of transactions

• Assign transactions an atomically increasing global number that represents serial order • SID (Serial ID) : Atomically fetch and add global counter • Where should this assignment be done? • Read -> Lock -> SID -> Verify -> Write+Unlock • Why is it in this order? 8
9. ### Optimistic Concurrency Control Checking w-w in “Read -> Lock ->

Verify -> Write+Unlock” • Assume that ﬁrst write (Lock->Write+Unlock) of w-w passes • Lock(x) of Tx2 should happen after Unlock(x) of Tx1 • This show that for SID to reﬂect w-w, • SID need to come before Unlock • SID need to come after Lock • Lock … -> SID … -> Unlock … Lock(x) Verify(y=3) Write(x:=y+2=5) Unlock(x) Tx1  (Writer) Tx2  (Writer) … Lock(x) Verify(z=3) Write(x:=z+1=4) Unlock(x) 9
10. ### Optimistic Concurrency Control Checking w-r in “Read -> Lock ->

Verify -> Write+Unlock” • Assume that write (Lock->Write+Unlock) of w-r passes • Read(x) of Tx2 should happen after Unlock(x) of Tx1 because Read(x) checks whether x is currently locked • This show that for SID to reﬂect w-r, • SID need to come before Unlock • SID need to come after Read • Read … -> SID … -> Unlock … Lock(x) Verify(y=3) Write(x:=y+2=5) Unlock(x) Tx1  (Writer) Tx2  (Reader) Read(x) Lock(y) Verify(x=3) … 10
11. ### Optimistic Concurrency Control Checking r-w in “Read -> Lock ->Verify

-> Write+Unlock” • Assume that read (Read->Verify) passes. • Then Lock(x) of Tx2 should happen after Verify(x) of Tx1 because Verify(x) checks whether x is currently locked • This show that for SID to reﬂect r-w, • SID need to come before Verify • SID need to come after Lock • Lock -> SID -> Verify Read(x) = 3 Lock(y) Verify(x=3) … Tx1  (Reader) Tx2  (Writer) … Lock(x) Verify(z=3) Write(x:=z+1=4) Unlock(x) 11
12. ### Optimistic Concurrency Control Serial Schedule = schedule that reﬂects w-w,

w-r, r-w conﬂict Read(x) = 3 Lock(y) SID = 1 Verify(x=3) … Tx1  (Reader) Tx2  (Writer) … Lock(x) SID = 2 Verify(z=3) Write(x:=z+1=4) Unlock(x) … Lock(x) SID = 1 Verify(y=3) Write(x:=y+2=5) Unlock(x) Tx1  (Writer) Tx2  (Writer) … Lock(x) SID = 2 Verify(z=3) Write(x:=z+1=4) Unlock(x) W-W conﬂict W-R conﬂict … Lock(x) SID = 1 Verify(y=3) Write(x:=y+2=5) Unlock(x) Tx1  (Writer) Tx2  (Reader) Read(x) Lock(y) SID = 2 Verify(x=3) … R-W conﬂict If Read -> Lock -> SID -> Verify -> Write+Unlock,  Tx1’s SID < Tx2’s SID is guaranteed in w1-w2, w1-r2, r1-w2 conﬂict 12
13. ### Optimistic Concurrency Control OCC corresponds to 2PL Read -> Lock

-> SID -> Verify -> Write+Unlock 13

14
15. ### SILO Why SILO uses Epochs and Tids • “fetch_and_add”ing global

counter does not scale. • If one thread “fetch_and_add” the global counter, other threads’ cache-line will be invalidated and have to go to memory to get the value. • By committing in a bigger unit (than a single transaction), less “fetch_and_add”s are needed to the global counter thus less cache invalidation. This unit is called epoch. • To crystallize the changes done in an epoch, keeping the w-w order of operations is essential. By using a Tid that is appended to each record, w-w order is maintained. Read Lock SID Verify Write  Unlock 15