diff --git a/src/teaching/cse-562/2021sp/index.erb b/src/teaching/cse-562/2021sp/index.erb index b695d15c..48bee869 100644 --- a/src/teaching/cse-562/2021sp/index.erb +++ b/src/teaching/cse-562/2021sp/index.erb @@ -104,15 +104,18 @@ schedule: slides: slide/2021-04-06-TheoryOfTransactions.html - date: "Apr. 8" topic: "Transactions: Pessimistic" + materials: + slides: slide/2021-04-08-Locking.html + - date: "Apr. 12" due: "Checkpoint 2" - date: "Apr. 13" topic: "Aggregation + Checkpoint 3" - date: "Apr. 15" topic: "Transactions: Optimistic" - due: "Checkpoint 3" - date: "Apr. 20" topic: "Indexing Review + Checkpoint 4" - date: "Apr. 22" + due: "Checkpoint 3" topic: "Logging + Recovery" - date: "Apr. 27" topic: "Distributed Commit" diff --git a/src/teaching/cse-562/2021sp/slide/2021-04-08-Locking.erb b/src/teaching/cse-562/2021sp/slide/2021-04-08-Locking.erb new file mode 100644 index 00000000..db08a145 --- /dev/null +++ b/src/teaching/cse-562/2021sp/slide/2021-04-08-Locking.erb @@ -0,0 +1,590 @@ +--- +template: templates/cse4562_2021_slides.erb +title: Pessimistic Concurrency Control +date: April 8, 2021 +textbook: Ch. 18.3-18.7, 19.2 +--- + + +
+
+
+
+
Schedule
+
A sequence of read and writes from one or more transactions to objects
+
+
+
Serial Schedule
+
A schedule with no interleaving
+
... but with an arbitrary transaction order
+
+
+
Serializable Schedule
+
A schedule that produces the same output as a serial schedule
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TimeT1T2T3
| W(A)
| W(A)
| W(B)
| W(B)
W(B)
+

T1's write to A "happens before" T2's write

+

T2's write to B "happens before" T3's write

+

T2's write to B "happens before" T1's write

+ +

Cycle! No equivalent serial schedule!

+
+ +
+

An acyclic "Happens Before" or Dependency Graph is conflict serializable.

+
+ +
+

Forcing Acyclicity

+
+
+
Locking
+
+
+ +
+
Snapshot Isolation
+
+
+ +
+
Timestamp Concurrency Control*
+
+
+
+
+
+ +
+
+

Goal: Enforce acyclic conflict graphs

+
+ +
+

Observation: Conflicts only occur on accesses to the same object

+
+ +
+

Idea: When a second transaction tries to access an object, require the first to COMMIT or ABORT first.

+
+ +
+

Idea: When a second transaction tries to access an object, require the first to COMMIT or ABORT first agree to never create more conflicts.

+
+ +
+

2-Phase Locking

+ +

Create one lock for each object.

+

Each transaction operates in two "phases".

+
+ +
+
+
+
Acquire Phase
+
Before accessing an object, the transaction must acquire the object's lock.
+
The transaction does not release locks.
+
+ +
+
Release Phase
+
A transaction can release locks
+
A transaction can never again access an object it doesn't have a lock for.
+
+
+ +

In practice, the release phase happens all at once at the end

+
+ +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TimeT1T2T3
| R(C)
| W(A)
| R(B)
| W(C)
| W(B)
W(C)
+ +

Conflict Serializable.

+

Can 2PL create this schedule?

+
+ +
+
+ + + +
L(...)Acquire (Lock)
U(...)Release (Unlock)
+ +

2PL can create this schedule

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TimeT1T2T3
|
|
L(C)
R(C)
|
|
L(A)
W(A)
|
|
L(B)
R(B)
|
|
W(C)
U(C)
|
|
L(C)
U(B)
|
|
L(B)
W(B)
|
L(C)
W(C)
+
+
+ +
+
+

Optimizations

+
+ +
+

Observation 1: Read-Read conflicts aren't a problem

+ +

Solution: Reader/Writer Locks

+ +

(Any number of readers or one writer can hold the lock)

+ +

... also called Shared (S)/Exclusive (X) locks

+
+ +
+ + + + + + + + + + +
Requested
SX
H
e
l
d
SAllowBlock
XBlockBlock
+
+ +
+

An object is ...

+ +

Which should be used?

+
+ +
+

Observation 1: Too coarse locking prevents concurrency

+

Observation 2: Too fine locking is slow

+
+ +
+

Idea 1: Separate locks for tables, pages, rows, cells.

+

Doesn't Work! Need to use the same lock for all conflicts.

+
+ +
+

Idea 2: Organize locks hierarchically. Set a flag in the parent when a child is locked.

+
+ +
+

New Lock Modes

+
+
Exclusive (X)
+
The holding thread can safely modify the object
+
Shared (S)
+
A holding thread can safely read the object
+
+
Intent-Exclusive (IX)
+
Descendant locks may be held Exclusive
+
Intent-Shared (IS)
+
Descendant locks may be held Shared
+
+
+
+ +
+

Before acquiring a descendant lock, a thread must first intent-acquire all ancestors (top-down) +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Requested
ISIXSX
H
e
l
d
NoneAllowAllowAllowAllow
ISAllowAllowAllowBlock
IXAllowAllowBlockBlock
SAllowBlockAllowBlock
XBlockBlockBlockBlock
+
+ +
+

Example 1

+ +
+
+

Example 2

+ +
+ +
+ +
+
+ + + <% + ops = [ + { t: 1, op: "S(A)" }, + { t: 1, op: "R(A)" }, + { t: 2, op: "X(B)" }, + { t: 2, op: "W(B)" }, + { t: 1, op: "S(B)", animate: "highlight-red" }, + { t: 3, op: "S(C)" }, + { t: 3, op: "R(C)" }, + { t: 2, op: "X(C)", animate: "highlight-red" }, + { t: 4, op: "X(B)", animate: "highlight-red" }, + { t: 3, op: "X(A)", animate: "highlight-red" }, + ] + ops.each do |op| + op[:bar] = "|" + if op.has_key? :animate + op[:op] = ''+op[:op]+"" + end + end + ops[-1][:bar] = "↓" + ops.each do |op| %> + + <% (1..4).each do |i| + if i == op[:t] then %> + + <% else %> + + <% end end %> + + <% end %> +
TimeT1T2T3T4
<%=op[:bar]%><%= op[:op] %>
+
+ +
+

Deadlock

+

A cycle of transactions waiting on each other's locks

+
+ +
+

Approach 1 Detect deadlock situations as they occur and abort deadlocked transaction

+

Approach 2 Anticipate deadlock situations before they happen

+
+ +
+

The Waits-For Graph

+
+
Nodes
+
Every running transaction
+
Directed Edges
+
From a transaction blocked to the transaction it's waiting for
+
+
+ +
+ + + <% ops.each do |op| %> + + <% (1..4).each do |i| + if i == op[:t] then %> + + <% else %> + + <% end end %> + + <% end %> +
TimeT1T2T3T4
<%=op[:bar]%><%= op[:op].gsub('', '') %>
+ + + + + + + T1 + T2 + T4 + T3 + <% [ + [[ "50,18 140,18", 1]], + [[ "170,50 170,160", 1]], + [[ "50,160 140,40", 1]], + [[ "140,160 50,40", 1]], + [[ "50,18 140,18", 3], + [ "170,50 170,160", 3], + [ "140,160 50,40", 3]] + ].each do |g| %> + <% g.each do |path, lw| %> + + <% end %><% end %> + +
+ +
+

A cycle is a set of transactions that will never finish

+

Periodically check for cycles in the waits-for graph

+

Abort transactions until the cycle is broken

+
+ +
+ Detecting cycles is expensive! +
+
+ +
+
+

Idea 2: Create an order over the locks (give each a #)
Only allow locks to be acquired in sequence order

+
+ +
+ + + <% ops.each do |op| %> + + <% (1..4).each do |i| + if i == op[:t] then %> + + <% else %> + + <% end end %> + + <% end %> +
TimeT1T2T3T4
<%=op[:bar]%><%= if op[:t] != 3 then op[:op].gsub('', '') else op[:op] end %>
+

T3 can't acquire X(A) because it already has S(C)

+
+ +
+

Idea 2.B: Acquire all locks at the start of a transaction.

+
+ +
+

Pro: No deadlocks... ever.

+

Pro: No (expensive) cycle detection.

+

Con: Not all transactions are supported
or transactions need to know all necessary locks in advance.

+
+
+ +
+
+

Idea 3: False positive deadlock detections are ok

+
+ +
+

Trivial solution: Timeouts

+

... but how long should the timeout be?

+
+
+

Alternative: Create an order over transactions
Only allow a transaction to block on "older" transactions

+
+ +
+

Variant 1

+
+
T1 holds a lock on A
+
T2 tries to acquire the lock on A and blocks
+
(ok, because T1 is "older")
+ +
T2 holds a lock on A
+
T1 tries to acquire the lock on A
+
ABORT T1 and restart it as a "younger" transaction
+
+

"Wait-Die"

+
+ +
+

Variant 2

+
+
T1 holds a lock on A
+
T2 tries to acquire the lock on A and blocks
+
(ok, because T1 is "older")
+ +
T2 holds a lock on A
+
T1 tries to acquire the lock on A
+
ABORT T2 and restart it at the same age.
+
+

"Wait-Wound"

+
+ +
+
+
Wait-Die
+
Abort an older transaction that tries to wait on a younger one.
+ +
Wait-Wound
+
If an older transaction tries to wait on a younger one, kill the younger.
+
+
+ +
+

Managing Deadlocks

+
+
Approach 1: Detection
+
Detect cycles (or conditions that could indicate cycles)
+
Abort transactions until the cycles go away
+ + +
Approach 2: Recovery
+
Enforce an invariant on lock acquisition order
+
Acquire all locks upfront
+
+
+
\ No newline at end of file diff --git a/src/teaching/cse-562/2021sp/slide/2021-04-08/2PLDepGraph.svg b/src/teaching/cse-562/2021sp/slide/2021-04-08/2PLDepGraph.svg new file mode 100644 index 00000000..f1919ac8 --- /dev/null +++ b/src/teaching/cse-562/2021sp/slide/2021-04-08/2PLDepGraph.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + T1 + T2 + T3 + + + + diff --git a/src/teaching/cse-562/2021sp/slide/2021-04-08/2PhaseLocking.svg b/src/teaching/cse-562/2021sp/slide/2021-04-08/2PhaseLocking.svg new file mode 100644 index 00000000..347499de --- /dev/null +++ b/src/teaching/cse-562/2021sp/slide/2021-04-08/2PhaseLocking.svg @@ -0,0 +1,161 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + Acquire + + + + Release + + + + Can only be the LHS of a new conflict edge(would block otherwise) + Can never create anew conflict edge(no new locks) + + + + diff --git a/src/teaching/cse-562/2021sp/slide/2021-04-08/DependencyCycle.svg b/src/teaching/cse-562/2021sp/slide/2021-04-08/DependencyCycle.svg new file mode 100644 index 00000000..c70cc830 --- /dev/null +++ b/src/teaching/cse-562/2021sp/slide/2021-04-08/DependencyCycle.svg @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + T1 + T2 + + + B + A + T3 + + + diff --git a/src/teaching/cse-562/2021sp/slide/2021-04-08/HierarchicalNotOK.svg b/src/teaching/cse-562/2021sp/slide/2021-04-08/HierarchicalNotOK.svg new file mode 100644 index 00000000..a2c01260 --- /dev/null +++ b/src/teaching/cse-562/2021sp/slide/2021-04-08/HierarchicalNotOK.svg @@ -0,0 +1,251 @@ + + + + + + + + + + image/svg+xml + + + + + + + Table + Block1 + Block2 + Block3 + Block4 + Tuple2 + Tuple3 + Tuple4 + Tuple5 + + + + + + T1:IX + T1:IX + T1:X + T2:IS + T2:S + + + diff --git a/src/teaching/cse-562/2021sp/slide/2021-04-08/HierarchicalOK.svg b/src/teaching/cse-562/2021sp/slide/2021-04-08/HierarchicalOK.svg new file mode 100644 index 00000000..dfe093c1 --- /dev/null +++ b/src/teaching/cse-562/2021sp/slide/2021-04-08/HierarchicalOK.svg @@ -0,0 +1,257 @@ + + + + + + + + + + image/svg+xml + + + + + + + Table + Block1 + Block2 + Block3 + Block4 + Tuple2 + Tuple3 + Tuple4 + Tuple5 + + + + + + T1:IX + T1:IX + T1:X + T2:IX + T2:IX + T2:X + +