Review Lecture 30

advertisement
Review
Lecture 30
Administrivia
•
•
•
•
Office hours 1:30 – 2:15 today
Final Exam May 16 8-11 a.m.
Location: 22 Warren
Topics since Midterm 2
– Transactions, concurrency control, locking,
recovery
– Logical design, ER Modeling, Functional
Dependencies, Normalization, Data Mining
– Guest lectures
• Cumulative questions from semester
Review
today
Review
Tuesday
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 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)
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.
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.
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.
Deadlocks
• Deadlock: Cycle of transactions waiting for locks to be
released by each other.
• Two ways of dealing with deadlocks:
– Deadlock prevention
•
•
Wait-die: new transactions aren’t allowed to wait
Wound-wait: old transactions don’t have to wait
Deadlock detection
– Create a waits-for graph:
– 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)
Lock Management
contains
• Multi-granularity locking
– Use database containment hierarchy to vary
granularity of locks
• Full table insert: lock table vs read 1 row: lock record
• 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
Database
Tables
Pages
Tuples
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
• 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
• 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
Locking in B+ Trees
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
Simple Locking in B+ Trees
• 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
Optimistic CC (Kung-Robinson)
• Locking is a conservative approach in which
conflicts are prevented. Disadvantages:
– Lock management overhead.
– Deadlock detection/resolution.
– Lock contention for heavily used objects.
• If conflicts are rare, we might be able to gain
concurrency by not locking, and instead
checking for conflicts before Xacts commit.
Buffer Pool
Kung-Robinson Model
14 23 27
• Xacts have three phases:
– READ: Xacts read from
the database, but make
changes to private
copies of objects.
– VALIDATE: Check for
conflicts.
– WRITE: Make local
copies of changes
public.
R
Tj
Writes back
V
W
14 23
Tj private copies
•
Validation, and Write phase are done inside a critical section!
– i.e., Nothing else goes on concurrently.
Validation Phase
• Tests conditions that are sufficient to ensure
that no conflict occurred.
– If conflict did occur, restart transaction.
• Each Xact is assigned a timestamp at end of
READ phase, just before validation begins.
– Also keep track of xact phase begin & end times
• Compute
– ReadSet(Tj): Set of objects read by Xact Tj.
– WriteSet(Tj): Set of objects modified by Tj.
Validation Test 1 for Tj: no overlap
• For all i and j such that Ti < Tj, check that Ti completes
write phase before Tj begins read phase.
Ti
R
V
Tj
W
R
V
 Implies a serial order for Ti and Tj; Ti came first.
W
Validation Test 2 for Tj: Overlapping read
phase
• For all i and j such that Ti < Tj, check that:
– Ti completes before Tj begins its Write phase +
– WriteSet(Ti)
ReadSet(Tj) is empty.
Ti
R
V
W
R
V
W
Tj
 Ensures Tj does not read any object written by Ti.
 Implies a serial order; Tj might write same set of objects,
but writes are in a serial order; Ti’s writes come first.
Validation Test 3 for Tj: Overlapping write
phase
• For all i and j such that Ti < Tj, check that:
– Ti completes Read phase before Tj does +
– WriteSet(Ti)
ReadSet(Tj) is empty +
– WriteSet(Ti)
WriteSet(Tj) is empty.
Ti
R
V
R
W
V
W
Tj
 Ensures Tj does not read or write any object written by Ti.
 Implies a serial order; Tj reads and writes are to different
objects than those written by Ti.
Optimistic CC Overhead
• Must record read/write activity in ReadSet and
WriteSet per Xact.
– Must create and destroy these sets as needed.
• Must check for conflicts during validation, and
must make validated writes ``global’’.
– Critical section can reduce concurrency.
– Scheme for making writes global can reduce clustering
of objects.
• Optimistic CC restarts Xacts that fail validation.
– Work done so far is wasted; requires clean-up.
Write-Ahead Logging (WAL)
• The Write-Ahead Logging Protocol:
 Must force the log record for an update before the
corresponding data page gets to disk.
 Must force all log records for a Xact before commit.
(or, a transaction is not committed until all of its log
records including its “commit” record are on the
stable log.)
• #1 (with UNDO info) helps guarantee Atomicity.
• #2 (with REDO info) helps guarantee Durability.
• This allows us to implement Steal/No-Force
buffer management policy
Buffer Management summary
No Steal
No Force
Force
Steal
Fastest
Slowest
Performance
Implications
No Steal
No Force No UNDO
REDO
Steal
UNDO
REDO
No UNDO UNDO
Force
No REDO No REDO
Logging/Recovery
Implications
WAL & the Log
DB
LSNs
pageLSNs
RAM
flushedLSN
• Each log record has a unique Log Sequence
Number (LSN).
Log records
– LSNs always increasing.
flushed to disk
• Each data page contains a pageLSN.
– The LSN of the most recent log record
for an update to that page.
• System keeps track of flushedLSN.
– The max LSN flushed so far.
flushedLSN
• WAL: Before page i is written to DB
pageLSN “Log tail”
log must satisfy:
in RAM
pageLSNi flushedLSN
Log Records
LogRecord fields:
update
records
only
LSN
prevLSN
XID
type
pageID
length
offset
before-image
after-image
prevLSN is the LSN of the
previous log record
written by this Xact (so
records of an Xact form a
linked list backwards in
time)
Possible log record types:
• Update, Commit, Abort
• Checkpoint (for log
maintenance)
• Compensation Log
Records (CLRs)
– for UNDO actions
• End (end of commit or
abort)
Other Log-Related State
• Two in-memory tables:
• Transaction Table
– One entry per currently active Xact.
• entry removed when Xact commits or aborts
– Contains XID, status (running/committing/aborting),
and lastLSN (most recent LSN written by Xact).
• Dirty Page Table:
– One entry per dirty page currently in buffer pool.
– Contains recLSN -- the LSN of the log record which
first caused the page to be dirty.
The Big Picture: What’s Stored Where
LOG
DB
LogRecords
LSN
prevLSN
XID
type
pageID
length
offset
before-image
after-image
RAM
Xact Table
Data pages
each
with a
pageLSN
Master record
lastLSN
status
Dirty Page Table
recLSN
flushedLSN
Example
LSN
Prev
1. T1 update 2 (DEF)
(assume written to disk)
2. T2 update 3 (KLM)
3. T2 update 1 (QRS)
4. T1 update 2 (WXY)
5. T2 commit
6. T1 update 4 (RST)
7. SYSTEM CRASH
pageID
Before
After
11
null
END_CHKPT
T1
update
12
null
T2
update
3
HIJ
KLM
13
12
T2
update
1
GDE
QRS
14
11
T1
update
2
DEF
WXY
15
13
T2
commit and end
16
14
T1
update
OPQ
RST
2
ABC
DEF
4
SYSTEM CRASH
Page 2 LSN:14
LSN:4
LSN:11
Page 34LSN:12
LSN:6
LSN:8
LSN:16
WXY
ABC
DEF
Page 1 LSN:13
LSN:2
KLM
OPQ
RST
HIJ
Buffer Frame 1
GDE
Type
BEGIN_CHKPT
To disk
Page 1 LSN:2
XactID
GDE
QRS
Buffer Frame 2
Page 2 LSN:11
LSN:4
ABC
DEF
Buffer Frame 3
Page 3 LSN:12
LSN:6
KLM
HIJ
Page 4 LSN:8
OPQ
Crash Recovery: Big Picture
Oldest log
rec. of Xact
active at crash
Start from a checkpoint (found
via master record).
 Three phases. Need to do:

Smallest
recLSN in
dirty page
table after
Analysis
– Analysis - Figure out which
Xacts committed since
checkpoint, which failed.
– REDO all actions.
(repeat history)
– UNDO effects of failed Xacts.
Last chkpt
CRASH
A R U
End result – goal of recovery
•
•
T1 aborts
Roll back
updates if they
made it to disk.
Page 1 LSN:2
GDE
Page 1 LSN:2
QRS
1.
2.
3.
4.
5.
6.
7.
T1 update 2 (DEF)
T2 update 3 (KLM)
T2 update 1 (QRS)
T1 update 2 (WXY)
T2 commit
T1 update 4 (RST)
SYSTEM CRASH
Page 2 LSN:4
ABC
Page 3 LSN:6
HIJ
Page 3 LSN:12
KLM
•
•
T2 commits
Re-apply
updates if
needed
Page 4 LSN:8
OPQ
Recovery: The Analysis Phase
• Re-establish knowledge of state at checkpoint.
– via transaction table and dirty page table stored in the
checkpoint
• Scan log forward from checkpoint.
– End record: Remove Xact from Xact table.
– All Other records: Add Xact to Xact table, set
lastLSN=LSN, change Xact status on commit.
– also, for Update records: If page P not in Dirty Page Table,
Add P to DPT, set its recLSN=LSN.
• At end of Analysis…
– transaction table says which xacts were active at time of
crash.
– DPT says which dirty pages might not have made it to disk
Analysis
Xact Table
Xact ID
LSN
Prev
XactID
Type
pageID
Before
After
BEGIN_CHKPT
11
null
END_CHKPT
T1
update
2
ABC
DEF
Last LSN
State
12
null
T2
update
3
HIJ
KLM
T1
11
14
U
13
12
T2
update
1
GDE
QRS
T2
12
13
15
U
C
14
11
T1
update
2
DEF
WXY
15
13
T2
commit and end
Page 2 LSN:14
LSN:4
LSN:11
Page 34LSN:12
LSN:6
LSN:8
LSN:16
WXY
ABC
DEF
Page 1 LSN:13
LSN:2
KLM
OPQ
RST
HIJ
Buffer Frame 1
GDE
QRS
Buffer Frame 2
Buffer Frame 3
1. Create entries the Xact table with xacts active at time of crash.
Page 1 LSN:2
GDE
Page 2 LSN:11
DEF
Page 3 LSN:12
LSN:6
KLM
HIJ
Page 4 LSN:8
OPQ
Analysis
Xact Table
Xact ID
T1
Last LSN
14
State
U
Dirty Page Table
Page ID
LSN
Prev
XactID
Type
pageID
Before
After
BEGIN_CHKPT
11
null
END_CHKPT
T1
update
12
null
T2
update
3
HIJ
KLM
13
12
T2
update
1
GDE
QRS
14
11
T1
update
2
DEF
WXY
15
13
T2
commit and end
2
ABC
DEF
rec LSN
2
11
3
12
1
13
Page 2 LSN:14
LSN:4
LSN:11
Page 34LSN:12
LSN:6
LSN:8
LSN:16
WXY
ABC
DEF
Page 1 LSN:13
LSN:2
KLM
OPQ
RST
HIJ
Buffer Frame 1
GDE
QRS
Buffer Frame 2
Buffer Frame 3
2. Create entries in the Dirty Page table with pages that might not have made it to disk.
Page 1 LSN:2
GDE
Page 2 LSN:11
DEF
Page 3 LSN:12
LSN:6
KLM
HIJ
Page 4 LSN:8
OPQ
Phase 2: The REDO Phase
• We Repeat History to reconstruct state at crash:
– Reapply all updates (even of aborted Xacts!), redo
CLRs.
• Scan forward from log rec containing smallest
recLSN in DPT. Q: why start here?
• For each update log record or CLR with a given
LSN, REDO the action unless:
– Affected page is not in the Dirty Page Table, or
– Affected page is in D.P.T., but has recLSN > LSN, or
– pageLSN (in DB) LSN. (this last case requires I/O)
• To REDO an action:
– Reapply logged action.
– Set pageLSN to LSN. No additional logging, no forcing!
Redo
LSN
T1
Type
pageID
Before
After
11
null
END_CHKPT
T1
update
2
ABC
DEF
Last LSN
State
12
null
T2
update
3
HIJ
KLM
14
U
13
12
T2
update
1
GDE
QRS
14
11
T1
update
2
DEF
WXY
15
13
T2
commit and end
Dirty Page Table
Page ID
XactID
BEGIN_CHKPT
Xact Table
Xact ID
Prev
rec LSN
2
11
3
12
1
13
Page 2 LSN:14
LSN:4
LSN:11
Page 34LSN:12
LSN:6
LSN:8
LSN:16
WXY
ABC
DEF
Page 1 LSN:13
LSN:2
KLM
OPQ
RST
HIJ
Buffer Frame 1
GDE
QRS
Buffer Frame 2
Buffer Frame 3
Step 1. Find lowest rec LSN in Dirty Page Table.
Page 1 LSN:2
GDE
Page 2 LSN:11
DEF
Page 3 LSN:12
LSN:6
KLM
HIJ
Page 4 LSN:8
OPQ
Redo
LSN
T1
Type
pageID
Before
After
11
null
END_CHKPT
T1
update
2
ABC
DEF
Last LSN
State
12
null
T2
update
3
HIJ
KLM
14
U
13
12
T2
update
1
GDE
QRS
14
11
T1
update
2
DEF
WXY
15
13
T2
commit and end
Dirty Page Table
Page ID
XactID
BEGIN_CHKPT
Xact Table
Xact ID
Prev
rec LSN
2
11
3
12
1
13
Page 2 LSN:14
LSN:4
LSN:11
Page 34LSN:12
LSN:6
LSN:8
LSN:16
WXY
ABC
DEF
Page 1 LSN:13
LSN:2
KLM
OPQ
RST
HIJ
Buffer Frame 1
GDE
QRS
Buffer Frame 2
Buffer Frame 3
Step 2. Scan forward and redo all redoable log records.
Page 1 LSN:2
GDE
Page 2 LSN:11
DEF
Page 3 LSN:12
LSN:6
KLM
HIJ
Page 4 LSN:8
OPQ
Redo
LSN
T1
Type
pageID
Before
After
11
null
END_CHKPT
T1
update
2
ABC
DEF
Last LSN
State
12
null
T2
update
3
HIJ
KLM
14
U
13
12
T2
update
1
GDE
QRS
14
11
T1
update
2
DEF
WXY
15
13
T2
commit and end
Dirty Page Table
Page ID
XactID
BEGIN_CHKPT
Xact Table
Xact ID
Prev
rec LSN
2
11
3
12
1
13
Page 2 LSN:11
LSN:4
LSN:14
Page 34LSN:12
LSN:6
LSN:8
LSN:16
WXY
ABC
DEF
KLM
OPQ
RST
HIJ
Buffer Frame 1
GDE
GDE
QRS
Buffer Frame 2
1. Reapply LSN 11 T1 update 2 (DEF)
Page 1 LSN:2
Page 1 LSN:13
LSN:2
2. Reapply LSN 12 T2 update 3 (KLM)
Page 2 LSN:11
DEF
Buffer Frame 3
Page 3 LSN:12
LSN:6
KLM
HIJ
Page 4 LSN:8
OPQ
Redo
LSN
T1
Type
pageID
Before
After
11
null
END_CHKPT
T1
update
2
ABC
DEF
Last LSN
State
12
null
T2
update
3
HIJ
KLM
14
U
13
12
T2
update
1
GDE
QRS
14
11
T1
update
2
DEF
WXY
15
13
T2
commit and end
Dirty Page Table
Page ID
XactID
BEGIN_CHKPT
Xact Table
Xact ID
Prev
rec LSN
2
11
3
12
1
13
Page 2 LSN:14
LSN:4
LSN:11
Page 34LSN:12
LSN:6
LSN:8
LSN:16
WXY
ABC
DEF
KLM
OPQ
RST
HIJ
Buffer Frame 1
GDE
GDE
QRS
Buffer Frame 2
3. Reapply LSN 13 T2 update 1 (QRS)
Page 1 LSN:2
Page 1 LSN:13
LSN:2
LSN:2
LSN:13
4. Reapply LSN 14 T1 update 2 (WXY)
Page 2 LSN:11
DEF
Buffer Frame 3
Page 3 LSN:12
LSN:6
KLM
HIJ
Page 4 LSN:8
OPQ
Redo
LSN
T1
Type
pageID
Before
After
11
null
END_CHKPT
T1
update
2
ABC
DEF
Last LSN
State
12
null
T2
update
3
HIJ
KLM
14
U
13
12
T2
update
1
GDE
QRS
14
11
T1
update
2
DEF
WXY
15
13
T2
commit and end
Dirty Page Table
Page ID
XactID
BEGIN_CHKPT
Xact Table
Xact ID
Prev
rec LSN
2
11
3
12
1
13
Page 2 LSN:14
LSN:4
LSN:11
Page 34LSN:12
LSN:6
LSN:8
LSN:16
WXY
ABC
DEF
Page
Page 11 LSN:13
LSN:2
KLM
OPQ
RST
HIJ
Buffer Frame 1
GDE
QRS
Buffer Frame 2
Buffer Frame 3
5. Reapply T2 commit (and we’ll write dirty pages to disk.)
Page 1 LSN:13
LSN:2
GDE
QRS
Page 2 LSN:11
DEF
Page 3 LSN:12
LSN:6
KLM
HIJ
Page 4 LSN:8
OPQ
Phase 3: The UNDO Phase
We undo actions of all active but not committed
xacts at the time of the crash.
– May even need to undo some of what we did in REDO
phase!
ToUndo={lastLSNs of all Xacts in the Trans Table}
a.k.a. “losers”
Repeat:
 CLRs will help
– Choose (and remove) largest LSN among ToUndo.
us remember
– If this LSN is a CLR and undonextLSN==NULL
where we are in
• Write an End record for this Xact.
case of system
crash during
– If this LSN is a CLR, and undonextLSN != NULL
recovery.
• Add undonextLSN to ToUndo
– Else this LSN is an update. Undo the update, write a CLR, add
prevLSN to ToUndo.
Until ToUndo is empty.
Undo
LSN
XactID
Type
pageID
Before
After
2
ABC
DEF
BEGIN_CHKPT
Xact Table
Xact ID
Prev
11
null
END_CHKPT
T1
update
Last LSN
State
12
null
T2
update
3
HIJ
KLM
14
U
13
12
T2
update
1
GDE
QRS
14
11
T1
update
2
DEF
WXY
15
13
T2
commit and end
DEF
ABC
T1
ToUndo
16 undoNextLSN=null T1
Last LSN
14
Page 2 LSN:16
LSN:4
LSN:14
LSN:11
11
KLM
OPQ
RST
HIJ
Buffer Frame 1
Buffer Frame 2
1. Add last LSN for all transactions in Xact table
GDE
QRS
2
Page 34LSN:12
LSN:6
LSN:8
LSN:16
WXY
ABC
DEF
Page 1 LSN:13
LSN:2
CLR
2. Recursively Process each last LSN in To Undo table.
Page 2 LSN:4
LSN:11
ABC
DEF
Buffer Frame 3
Page 3 LSN:12
LSN:6
KLM
HIJ
Page 4 LSN:8
OPQ
Download