Concurrency Control II Smile, it is the key that everybody's heart.

advertisement
Concurrency Control II
R &G - Chapter 17
Lecture 20
Smile, it is the key that
fits the lock of
everybody's heart.
Anthony J. D'Angelo,
The College Blue Book
Administrivia
• Homework 4 due today 10 p.m.
• Homework 3 almost graded
Review: Concurrency
• Concurrent users introduce anomalies
– Dirty reads (WR): T2 reads a value A that T1 wrote but
didn’t commit
– Unrepeatable Reads (RW): T1 reads a value A that is then
written by T2
– Lost Updates (WW): T2 overwrites a write by T1
• Serializable schedules:
– A schedule that is equivalent to some serial execution of the
transactions.
•
Definition: Two operations conflict if:
– They are by different transactions,
– they are on the same object,
– and at least one of them is a write.
R(B) W(B)
T1: R(A) W(A)
T2:
R(A) W(A)
R(B) W(B)
Conflict Serializable Schedules
• Definition: Two schedules are conflict equivalent iff:
– They involve the same actions of the same transactions, and
– every pair of conflicting actions is ordered the same way
• Definition: Schedule S is conflict serializable if:
– S is conflict equivalent to some serial schedule.
Conflict serializable schedules imply that
conflicting operations can be arranged as
though they executed serially
Conflict Serializability – Intuition
• A schedule S is conflict serializable if:
– You are able to transform S into a serial schedule by
swapping consecutive non-conflicting operations
of different transactions.
• Example:
T1: R(A) W(A)
R(B) W(B)
T2:
T1:
T2:
R(A)
W(A)
R(B)
W(B)
R(A) W(A) R(B)R(B)
W(B)
W(B)R(B)
W(B)
R(A) R(A)
W(A)R(A)
W(A)W(A) R(B) W(B)
Conflict Serializability
• Every conflict serializable schedule is serializable
• But some serializable schedules are NOT conflict
serializable.
• Example:
T1: R(A)
T2:
T3:
W(A)
W(A)
W(A)
• Serializable because it is
equivalent to the following serial
schedule:
T1: R(A) W(A)
T2:
W(A)
T3:
W(A)
But not conflict
serializable; the
writes of T1 and
T2 are reversed.
Dependency Graph
Ti
Tj
• Dependency graph:
– One node per Xact
– Edge from Ti to Tj if:
• An operation Oi of Ti conflicts with an operation Oj of
Tj and
• Oi appears earlier in the schedule than Oj.
• Theorem: Schedule is conflict serializable if
and only if its dependency graph is acyclic.
Conflict Serializability
Dependency graph
T1: R(A)
T2:
T3:
W(A)
W(A)
T1
W(A)
T2
• Dependency graph:
– One node per Xact
– Edge from Ti to Tj if:
T3
• An operation Oi of Ti conflicts with an operation Oj of Tj and
• Oi appears earlier in the schedule than Oj.
Another Example
• A schedule that is not conflict serializable:
T1:
T2:
R(A), W(A),
R(A), W(A), R(B), W(B)
R(B), W(B)
A
T1
T2
Dependency graph
B
• The cycle in the graph reveals the problem.
• The output of T2 depends on T1’s value of A, and
the output of T1 depends on T2’s value of B.
An Aside: View Serializability
•
•
•
Alternative (weaker) notion of serializability.
Schedules S1 and S2 are view equivalent if:
1. If Ti reads initial value of A in S1, then Ti also reads
initial value of A in S2
2. If Ti reads value of A written by Tj in S1, then Ti
also reads value of A written by Tj in S2
3. If Ti writes final value of A in S1, then Ti also writes
final value of A in S2
Basically, allows all conflict serializable
schedules + “blind writes”
1
T1: R(A)
W(A)
T2:
W(A)
T3:
W(A)
T1: R(A),W(A)
view T2:
W(A)
3
T3:
W(A)
Serializability and Locking
• Locking approaches guarantee schedule
serializability and recovery
• We talked about two of them before the
break…what are they?
Review: Lock-Based Concurrency Control
Two-phase Locking (2PL) Protocol:
–
Each Xact must obtain:
•
•
–
–
–
a S (shared) lock on object before reading, and
an X (exclusive) lock on object before writing.
If an Xact holds an X lock on an object, no other Xact can
get a lock (S or X) on that object.
System can obtain these locks automatically
Two phases: acquiring locks, and releasing them
•
•
No lock is ever acquired after one has been released
“Growing phase” followed by “shrinking phase”.
•Ensures acyclic dependency graphs
•Allows only conflict serializable schedules
Review: Strict 2 Phase Locking
•
Strict Two-phase Locking (Strict 2PL) Protocol:
– Same as 2PL, except All locks held are released only when
the transaction completes
• Advantage: no other transaction reads
anything you write until you commit.
– e.g a transaction will only read committed data.
• Disadvantage: transactions end up waiting.
•Ensures acyclic dependency graphs
•Allows only conflict serializable schedules
•Allows only strict schedules
No values written by an Xact T can be read or
overwritten until T commits or aborts.
Summary: Guarantees provided by locking
All Schedules
View Serializable
2PL
Strict 2PL
recoverable
avoids cascading aborts
Conflict Serializable
Strict
Serial
Lock Management
• Lock and unlock requests are handled by the lock manager
• Lock table entry:
– Number of transactions currently holding a lock
– Type of lock held (shared or exclusive)
– Pointer to queue of lock requests
• Locking and unlocking have to be atomic operations
– requires latches (“semaphores”), which ensure that the process
is not interrupted while managing lock table entries
– see CS162 for implementations of semaphores
• Lock upgrade: transaction that holds a shared lock can be
upgraded to hold an exclusive lock
– Can cause deadlock problems
Deadlocks
• Deadlock: Cycle of transactions waiting for
locks to be released by each other.
• Two ways of dealing with deadlocks:
– Deadlock prevention
– Deadlock detection
Deadlock Prevention
•
•
Assign priorities based on timestamps.
– Oldest xacts have the highest priority
Assume Ti wants a lock that Tj holds. Two policies possible:
– Wait-Die: new transactions aren’t allowed to wait
If timestamp(Ti) < timestamp(Tj) then
wait(Ti)
else
abort(Ti); restart(Ti)
–
Wound-wait: old transactions don’t have to wait
If timestamp(Ti) < timestamp(Tj) then
abort(Tj); restart(Tj);
else
wait(Ti)
•
When transaction re-starts, it gets its original timestamp
– Why?
Deadlock Detection
• Create a waits-for graph:
– Nodes are transactions
– There is an edge from Ti to Tj if Ti is waiting for Tj
to release a lock
• Periodically check for cycles in the waits-for
graph
Deadlock Detection (Continued)
Example:
T1: S(A), S(D),
T2:
X(B)
T3:
T4:
S(A)
S(D)
T1
T4
S(B)
X(C)
S(D), S(C),
S(B)
X(B)
X(A)
T2
X(B)
X(C)
T3
S(D)
S(C)
X(B)
X(A)
Deadlock Detection (cont.)
• In practice, most systems do detection rather
than prevention
– Experiments show that most waits-for cycles are
length 2 or 3
– Hence few transactions need to be aborted
– Implementations can vary
• Can construct the graph and periodically look for cycles
• Can do a “time-out” scheme: if you’ve been waiting on a
lock for a long time, assume you’re deadlock and abort
Lock Management
• What should we lock?
– We assume tuples so far, but that can be expensive!
– If we do table locks, that’s too conservative
– Multi-granularity locking
• Locking in indexes
– don’t want to lock a B-tree root for a whole transaction!
– actually do non-2PL “latches” in B-trees
• CC w/out locking
– “optimistic” concurrency control
– “timestamp” and multi-version concurrency control
– locking usually better, though
Multiple-Granularity Locks
• Hard to decide what granularity to lock (tuples
vs. pages vs. tables).
• Shouldn’t have to make same decision for all
transactions!
• Data “containers” are nested:
Database
contains
Tables
Pages
Tuples
Multiple-Granularity Locks (cont)
• Idea:
– need locks of different granularity,
sometimes need to lock >1 table.
– if transaction wants to rewrite
entire DBMS, get X lock on DBMS.
– if transaction wants to rewrite
entire Table, get X lock on Table
contains
– if transaction wants to read entire
Table, get S lock on Table
– etc.
– but, how to ensure that one
transaction doesn’t lock DBMS while
another locks a tuple?
Database
Tables
Pages
Tuples
Solution: New Lock Modes, Protocol
• Allow Xacts to lock at each level, but with a special protocol
using new “intention” locks.
• Still need S and X locks, but before locking an item, Xact must
have proper intension locks on all its ancestors in the
granularity hierarchy.
Before locking an item, Xact
must set “intention locks”
on all its ancestors.
 For unlock, go from specific
to general (i.e., bottom-up).
--
IS IX S
X





IS 



IX 






--
S
X

Lock compability
Multiple Granularity Lock Protocol
• Each Xact starts from the root of the
hierarchy.
• Special SIX lock used when reading many
records, and updating a few.
– SIX lock conflicts are all S and IX conflicts
(e.g. only compatible with IS locks).
• To get S or IS lock on a node, must hold IS
or IX on parent node.
• To get X or IX or SIX on a node, must hold
IX or SIX on parent node.
• Must release locks in bottom-up order.
Multi-Granularity Example
IS IX
SIX
S
IS   
• Rules
IX  
– Each Xact starts from the root of the hierarchy.
SIX

– To get S or IS lock, must hold IS or IX on parent.
– To get X or IX or SIX, must hold IX or SIX on parent. S 
X
– Must release locks in bottom-up order.
IX Database
IX Sailor Table
IX Page 1
Page 2
Tuple 1 Tuple 2 Tuple 3 Tuple 4
X


T1 wants to read & change tuple 2
•gets IX lock on DBMS
•gets IX lock on Sailor
•gets IX lock on Page 1
•gets X lock on Tuple 2 & changes it
•then releases locks in reverse order
X
Multi-Granularity Example 2
IS IX
SIX
IS   
• Rules
IX  
– Each Xact starts from the root of the hierarchy.
SIX

– To get S or IS lock, must hold IS or IX on parent.
S 
– To get X or IX or SIX, must hold IX or SIX on parent.
X
– Must release locks in bottom-up order.
T2:IX T1:IX Database
Page 2
T2:X

T1 wants to read & change tuple 2
•T1 gets IX lock on DBMS, Sailor, Page 1
T2:IX
Tuple 1 Tuple 2 Tuple 3 Tuple 4
T1:X

T2 wants to read & change tuple 3
T2:IX T1:IX
Sailor Table
T1:IX
Page 1
S
•T1 gets X lock on Tuple 2 & changes it
•T2 gets IX lock on DBMS, Sailor, Page 2
•T2 gets X lock on Tuple 3 & changes it
No problem!
X
Multi-Granularity Example 3
• Rules
– Each Xact starts from the root of the hierarchy.
– To get S or IS lock, must hold IS or IX on parent.
– To get X or IX or SIX, must hold IX or SIX on parent.
– Must release locks in bottom-up order.
T2:IS T1:IX Database
T2:IS T1:IX
Sailor Table
T1:IX Page 1
T2:wait
Page 2
Tuple 1 Tuple 2 Tuple 3 Tuple 4
T1:X
IS IX
IS 
IX 
SIX

S

SIX
 

S
X


X
T1 wants to read & change tuple 2
T2 wants to read all of Page 1
•T1 gets IX lock on DBMS, Sailor, Page 1
•T1 gets X lock on Tuple 2 & changes it
•T2 gets IS lock on DBMS, Sailor
•T2 tries to get S lock on Page 1, but S
conflicts with IX lock. T2 blocks.
What if T2 had started first?
Multi-Granularity Example 3
• Rules
– Each Xact starts from the root of the hierarchy.
– To get S or IS lock, must hold IS or IX on parent.
– To get X or IX or SIX, must hold IX or SIX on parent.
– Must release locks in bottom-up order.
T2:IS T1:IX Database
T2:IS T1:IX
Sailor Table
T1:waits
Page 1
T2:S
Page 2
Tuple 1 Tuple 2 Tuple 3 Tuple 4
IS IX
IS 
IX 
SIX

S

SIX
 

S
X


X
T1 wants to read & change tuple 2
T2 wants to read all of Page 1
•T2 gets IS lock on DBMS, Sailor
•T2 gets S lock on Page 1
•T1 gets IX lock on DBMS, Sailor
•T1 tries to get IX lock on Page 1, waits
Multi-Granularity Example 4
• Rules
– Each Xact starts from the root of the hierarchy.
– To get S or IS lock, must hold IS or IX on parent.
– To get X or IX or SIX, must hold IX or SIX on parent.
– Must release locks in bottom-up order.
T2:IS T1:IX Database
T2:IS T1:SIX Sailor Table
T1:SIXPage 1
IS IX
IS 
IX 
SIX

S

SIX
 

S
X


X
T1 wants to read all tuples, change tuple
1 and Tuple 3
T2 wants to read Tuple 4
T2:IS
•T1 gets IX lock on DBMS
Page 2 T1:SIX
•T1 gets SIX lock on Sailor, Pages
Tuple 1 Tuple 2 Tuple 3 Tuple 4•T1 gets X lock Tuple 1 & 3
T1:X
T1:X T2:S •T2 gets IS lock on DBMS, Sailor, Page 2
•T2 gets S lock on Tuple 4. If T1 had
gotten an X lock on Tuple 4, T2 would
have to wait.
Multi-Granularity Example 5
• Rules
– Each Xact starts from the root of the hierarchy.
– To get S or IS lock, must hold IS or IX on parent.
– To get X or IX or SIX, must hold IX or SIX on parent.
– Must release locks in bottom-up order.
T2:IX
T1:IX Database
IS IX
IS 
IX 
SIX

S

 

S
X


X
T1 wants to read all tuples, change 1&3
T1:SIX Sailor Table
T2:waits
T1:SIXPage 1
Page 2 T1:SIX
T2 wants to change Tuple 4
Tuple 1 Tuple 2 Tuple 3 Tuple 4
•T1 gets X lock on Tuple 1 & 3
T1:X
•T2 gets IX lock on DBMS.
T1:X
SIX
•T1 gets IX lock on DBMS
•T1 gets SIX lock on Sailor, Pages
•T2 tries to get IX lock on Sailor, but this
conflicts with T1’s SIX lock, so T2 blocks.
Locking in B+ Trees
• What about concurrency control for indexes?
• Simplistic solution: Ignore the tree structure, just lock
pages while traversing the tree, following 2PL.
T2: waits
T1 wants to read 11,23
T2:S
T2 wants to read 3
T3 wants to update 33
T2:S
T1:S
10
T1:S
3
T2:S
20
5
11 14
T1:S
 Leads to lock contention at top of the tree
24
T1:S
21 23
30 33
T1:S
– Root nodes become bottlenecks because every tree access begins at
the root.
Two useful observations
1. Higher levels of the tree only
direct searches for leaf pages.
20
2. For inserts:
– a node must be X locked only
if a split can propagate up to it
from the modified leaf.
– Example:
insert 9
vs insert 15
13
7
9
24
15
14 16
15
• We can exploit these observations to design
efficient locking protocols that guarantee
serializability even though they violate 2PL.
16
30
A Simple Tree Locking Algorithm
• Search: Start at root and go down;
– S lock node.
– Unlock its parent.
• Insert/Delete: Start at root and go down,
– X lock node.
– If node is safe, release all locks on ancestors.
• Safe node: Node such that changes will not
propagate up beyond this node.
– Inserts: Node is not full.
– Deletes: Node is not half-empty.
ROOT
•
•
Search:
– S lock node.
– Unlock its
parent.
Insert/Delete:
– X lock node.
– If node is safe,
release all
locks on
ancestors.
T1:S
T2:X
22*
T3:X
T1:S
T2:X
T3:X
B
35
T3:X
F
23
H
G
20*
A
20
Example
T1: Search 38
T2: Insert 45
T3: Insert 25
23*
T1:S
T2:X
38
44
I
24*
35*
T3:X
T3:X
36*
C
D
38*
T1:S
41*
E
44*
T2:X
A Better Tree Locking Algorithm (See
Bayer-Schkolnick paper)
• Search: As before.
• Insert/Delete:
– Set locks as if for search, get to leaf, and set
X lock on leaf.
– If leaf is not safe, release all locks, and
restart Xact using previous Insert/Delete
protocol.
• Gambles that only leaf node will be modified; if
not, S locks set on the first pass to leaf are
wasteful. In practice, better than previous alg.
ROOT
T1:S
Example
•
•
Search:
– S lock node.
– Unlock its
parent.
Insert/Delete:
– Set locks for
search.
– X lock leaf.
– If leaf not
safe, restart
using previous
protocol.
22*
A
20
T2:S
T2:X
T1:S
T2:S
T2:X
B
35
T2:S
T2:X
F
23
H
G
20*
T1: Delete 38
T2: Insert 25
23*
24*
T2:X
38
T1:S
44
I
35*
36*
C
D
38*
T1:X
41*
E
44*
Even Better Algorithm
• Search: As before.
• Insert/Delete:
– Use original Insert/Delete protocol, but set
IX locks instead of X locks at all nodes.
– Once leaf is locked, convert all IX locks to
X locks top-down: i.e., starting from node
nearest to root. (Top-down reduces
chances of deadlock.)
Hybrid Algorithm
• The likelihood that we really need an X lock
decreases as we move up the tree.
• Hybrid approach:
Set S locks
Set SIX locks
Set X locks
Download