常规锁设计
分区表通过表锁+分区锁两重设计,在表和分区上分别施加8个不同级别的常规锁,来保证DQL、DML、DDL并发过程中的合理行为控制。下表给出了不同级别锁的相容行为,标记为√的两种常规锁互不阻塞,可以并行。
- |
ACCESS_SHARE |
ROW_SHARE |
ROW_EXCLUSIVE |
SHARE_UPDATE_EXCLUSIVE |
SHARE |
SHARE_ROW_EXCLUSIVE |
EXCLUSIVE |
ACCESS_EXCLUSIVE |
---|---|---|---|---|---|---|---|---|
ACCESS_SHARE |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
× |
ROW_SHARE |
√ |
√ |
√ |
√ |
√ |
√ |
× |
× |
ROW_EXCLUSIVE |
√ |
√ |
√ |
√ |
× |
× |
× |
× |
SHARE_UPDATE_EXCLUSIVE |
√ |
√ |
√ |
× |
× |
× |
× |
× |
SHARE |
√ |
√ |
× |
× |
√ |
× |
× |
× |
SHARE_ROW_EXCLUSIVE |
√ |
√ |
× |
× |
× |
× |
× |
× |
EXCLUSIVE |
√ |
× |
× |
× |
× |
× |
× |
× |
ACCESS_EXCLUSIVE |
× |
× |
× |
× |
× |
× |
× |
× |
分区表的不同业务最终都是作用于目标分区上,数据库会给分区表和目标分区施加不同级别的表锁+分区锁,来控制并发行为。表2给出了不同业务的锁粒度控制。其中数字1~8分别代表表1给出的ACCESS_SHARE、ROW_SHARE、ROW_EXCLUSIVE、SHARE_UPDATE_EXCLUSIVE、SHARE、SHARE_ROW_EXCLUSIVE、EXCLUSIVE、ACCESS_EXCLUSIVE这8种级别的常规锁。
业务模型 |
分区表锁级别(表锁+分区锁) |
---|---|
SELECT |
1-1 |
SELECT FOR UPDATE |
2-2 |
DML业务,包括INSERT、UPDATE、DELETE、UPSERT、MERGE INTO、COPY |
3-3 |
大部分分区DDL,包括ADD、DROP、EXCHANGE、TRUNCATE、MOVE、RENAME |
4-8 |
CREATE INDEX(非分类索引)、REBUILD INDEX |
5-5 |
CREATE INDEX(分类索引) |
3-5 |
REBUILD INDEX PARTITION |
1-5 |
ANALYZE、VACUUM |
4-4 |
其他分区表DDL,包括SPLIT/MERGE这两种分区DDL |
8-8 |
如果业务执行施加的表锁和分区锁均满足表1,则可以支持业务并行操作,如果表锁和分区锁有任一不相容,则二者不支持业务并行。

DDL (ADD/DROP/TRUNCATE/EXCHANGE/MOVE/RENAME) 操作对分区表施加的表锁级别受GUC参数enable_partition_ddl_lowlevel_lock控制,当GUC参数enable_partition_ddl_lowlevel_lock设置为on时,对表施加4级锁;当GUC参数enable_partition_ddl_lowlevel_lock设置为off时,对表施加8级锁。