页级锁是数据库锁机制中的一种类型,它的锁定粒度介于表锁和行锁之间,以数据页为单位进行加锁。每个数据页是数据库存储数据的基本单元,通常包含多行数据,因此页级锁一次会锁定一个数据页内的所有数据。

页级锁的核心概念
要理解页级锁,首先需要明确数据库的存储单元逻辑。数据库会将数据按页划分,每个页的大小是固定的,比如常见的16KB。当对某一页的数据加页级锁时,该页内的所有行都会被锁定,其他事务无法修改这一页内的任何数据。
页级锁的特点可以从锁定粒度、并发性能和开销三个维度来看:
- 锁定粒度:比表锁小,比行锁大。表锁会锁定整张表,行锁只锁定单行数据,页级锁锁定的是单个数据页。
- 并发性能:比表锁好,比行锁差。因为锁定的数据范围更小,所以允许的并发操作更多,但不如行锁灵活。
- 开销:比表锁大,比行锁小。管理页级锁需要的资源比表锁多,但比维护大量行锁的资源消耗少。
BDB引擎的页级锁实现
BDB(Berkeley DB)引擎是早期MySQL支持的存储引擎之一,它采用的正是页级锁机制。BDB的页级锁会针对操作涉及的数据页加锁,而不是整张表或者单行数据。
我们可以通过一个简单的模拟场景来理解BDB的页级锁行为:假设有一张用户表,每个数据页存储10行用户数据,现在有两个事务同时操作这张表。
-- 事务1:更新用户id为1到10的数据,这些数据在同一个数据页中 START TRANSACTION; UPDATE user SET age = 20 WHERE id BETWEEN 1 AND 10; -- 此时事务1会对这个数据页加页级锁 -- 事务2:尝试更新用户id为5的数据,属于同一个数据页 START TRANSACTION; UPDATE user SET age = 21 WHERE id = 5; -- 事务2会被阻塞,需要等待事务1释放页级锁
页级锁是表锁和行锁的折中方案的原因
页级锁之所以被称为表锁和行锁的折中方案,是因为它在多个维度上平衡了两者的特性:
| 锁类型 | 锁定粒度 | 并发性能 | 锁开销 | 死锁概率 |
|---|---|---|---|---|
| 表锁 | 整张表 | 低 | 小 | 低 |
| 页级锁(BDB引擎) | 单个数据页 | 中等 | 中等 | 中等 |
| 行锁 | 单行数据 | 高 | 大 | 高 |
从表格可以看出,页级锁的各项指标都介于表锁和行锁之间:
- 相比表锁,它锁定的范围更小,允许更多的事务同时操作不同数据页的数据,提升了并发性能,虽然开销比表锁大,但换来了更好的并发能力。
- 相比行锁,它不需要为每一行数据维护锁信息,减少了锁管理的开销,虽然并发性能不如行锁,但降低了系统的资源消耗,同时死锁的概率也比行锁更低。
页级锁的适用场景
页级锁适合以下场景:
- 并发量中等,不需要行锁那样的高并发,但表锁的并发又无法满足需求的业务。
- 数据操作的范围通常是连续的多行数据,这些连续数据大概率在同一个数据页中,页级锁的开销优势可以充分发挥。
- 系统资源有限,无法承担行锁的大量资源消耗的场景。
需要注意的是,现在主流的存储引擎如InnoDB默认使用行锁,BDB引擎已经逐渐被淘汰,但理解页级锁的概念仍然有助于我们理解数据库锁机制的演进逻辑,以及不同锁类型之间的权衡关系。