Index concurrency: protect structure separately from transactions
Distinguish page latches, transaction locks, lock coupling, and B-link recovery from stale routing information.
On this page
The question for today
What you’ll understand
- Separate short structural critical sections from transaction isolation.
- Explain child-before-parent release in a latch-coupling protocol.
- Trace right-link correction after a concurrent split without generalizing one algorithm to every engine.
A database can preserve transaction isolation and still corrupt an index if two workers modify one page inconsistently. Conversely, a structurally correct tree does not automatically make a multi-statement transaction serializable. Index concurrency requires a local protocol for safe navigation and mutation, plus the database's separate rules for which logical results a transaction may observe.
Name the invariant protected by each mechanism
Database literature often distinguishes latches, which protect short-lived in-memory structural operations, from transaction locks, which protect logical data access under an isolation protocol. Terminology varies, so identify the actual mechanism's duration and purpose. A page latch may prevent another worker from observing a partly rewritten slot array. A row or predicate lock may control a conflicting logical operation until transaction end. Releasing the page latch does not imply committing the transaction, and a row lock does not automatically protect every structural byte of the tree.
A buffer pin commonly keeps a page frame available while a worker references it; it is distinct from excluding concurrent content changes. Reclamation also needs to ensure that no active reader will interpret reused storage as an old page. Correct algorithms coordinate page lifetime, structural visibility, and recovery information. When analyzing a contention report, distinguish waiting for a buffer's I/O, waiting for a content latch, and waiting for another transaction. Those waits can have different remedies even when the query text is identical.
Couple navigation only as the algorithm requires
In a basic latch-coupling descent, acquire suitable protection for the child before releasing the parent. This prevents a gap in which the child relationship could be invalidated before the reader safely reaches it. Insertions may need stronger or retained ancestor protection if a child is unsafe for the intended structural change, such as lacking room for an insertion. Exact safety tests and restart rules depend on the algorithm. Holding every ancestor until transaction completion is not the definition of latch coupling and can unnecessarily serialize independent work.
The B-link approach adds fence information and right-sibling links so a reader following an older parent reference can move right after a split. In our distinct-key convention, a page's upper fence h excludes keys k≥h; such a key follows the right link. A parent update can then be coordinated without requiring every reader to have observed the newest separator first. The original Lehman–Yao algorithm establishes its result under a particular model. It does not imply that all B-trees use no reader latches or that publication ordering and memory reclamation can be omitted.
Test the interleaving rather than only the result
Write a schedule where a reader chooses a child, a writer splits that child, and the reader resumes. Show exactly which old reference remains valid and which fence directs recovery. Then consider a second split before the reader catches up, deletion of an empty page, and a crash between logged steps. A correctness argument must account for every permitted state, not merely the final balanced drawing. Optimistic methods can validate version counters and restart, but require their own rules for reading consistent state and preventing unsafe access during validation.
The queue lab illustrates contention pressure without implementing latches. Reset, set λ=4 and μ=4, predict the fluid backlog remains at four, then Play or Step. This is balance in a deterministic model, not a stable stochastic queue claim. For a separate run, Reset, set λ=5 and μ=4, predict growth of one waiting operation per second, then Play or Step. Increasing worker count cannot raise the service rate of an unchanged serial critical section indefinitely. Use an actual latch profile and a critical-section schedule to test whether that mechanism limits the real index.
Work it through
Follow an older pointer after a split
A reader searches for key 35 and has selected a leaf formerly covering [0,40). A writer splits it into [0,30) and [30,40), publishes a right link, and leaves the parent update pending.
The reader arrives at the old left page and observes its valid new upper-exclusive fence 30. Since 35≥30, its target no longer belongs on that page.
Following the published right link reaches the page covering [30,40), where key 35 belongs under the stated convention. The reader does not conclude absence from the left page alone.
If a shared structural critical section takes 40 microseconds per operation, its ideal serial ceiling is 25,000 operations per second. This timing estimate is separate from the navigation proof and ignores all other bottlenecks.
Fence keys and sibling links can repair stale routing under the complete B-link protocol. They do not independently establish transaction isolation or lifetime safety.
The living notebook
Explore the model
Interactive lab · queue
A serialized index resource can saturate
Reset, set λ=4 and μ=4, predict constant fluid backlog four, then Play or Step. Separately Reset, set λ=5 and μ=4, predict growth of one operation per second, then Play or Step. The lab has no latches, lock manager, splits, or transaction protocol; λ=μ is not an M/M/1 stable case.
- Fluid backlog
- 4
- Net rate · λ − μ
- −1 /s
- M/M/1 mean residence
- 1 s
Fluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forMore concurrent callers cannot bypass the capacity of a truly serialized critical section.
Pause & reason
Check your understanding
Your turn
Try it yourself
A fictional latch-protected section consumes 20 microseconds per operation. Find its ideal single-resource ceiling and offered utilization at 40,000 operations per second.
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Convert microseconds to seconds before taking the reciprocal and multiplying by arrival rate.
Compare with the solution
The ideal ceiling is 1/0.000020=50,000 operations per second. Offered utilization is 40,000×0.000020=0.8. This simplified 80% value does not determine a latency percentile: arrival variability, lock hold-time variation, scheduling, and other work remain unspecified.
Keep the idea
Take it with you
- Page structure, buffer lifetime, and transaction isolation are separate invariants.
- Latch coupling and B-link correction are algorithm-specific concurrency techniques.
- A correct final tree drawing does not replace an interleaving and recovery argument.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.