The locks here are divided into two levels: the tree-level lock called tree latch, and the node-level lock called node latch. The tree latch protects all non-leaf nodes, while the node latch naturally protects the node itself.
Why Tree Latch Only Protects Non-Leaf Nodes?
In a B+ tree, leaf nodes store actual data and have high access frequency. If the tree latch included leaf nodes in its protection scope, it would be more prone to trigger lock contention and reduce concurrency performance. From the perspective of non-leaf nodes, in a B+ tree, non-leaf nodes store pointers to child nodes. Protecting non-leaf nodes essentially means protecting the tree structure.
Lock Acquisition Process
When operating on a B-tree, you typically first acquire the tree latch in shared mode (tree-latch-s), which ensures the tree structure won’t be modified. Then you traverse the tree from top to bottom to find the target leaf node and lock it (node-latch). During the process of finding the leaf node, non-leaf nodes are not locked, which saves CPU time—you only need to ensure the corresponding data pages won’t be swapped out of memory (buffer fixed).
Tree Structure Modifications
If an operation changes the tree structure, you must first acquire an exclusive lock on the tree (tree-latch-x). Taking node splitting as an example:
- First, find the leaf node to be split
- Allocate a new data page
- Insert a pointer to the new page into the upper-level non-leaf node
- Release the tree-latch-x (because the tree structure change is complete)
- Migrate some data from the original leaf node to the newly split leaf node
This approach minimizes the duration of exclusive locks on the tree structure, thereby improving concurrency performance.
Reference
- MySQL InnoDB Source Code
- “Database Internals” by Alex Petrov