该文章为《MySQL实战45讲》课程学习笔记及部分摘抄,原课程链接MySQL 实战 45 讲 (geekbang.org)
一、分区表是什么?
为了说明分区表的组织形式,我先创建一个表 t:
CREATE TABLE `t` (
`ftime` datetime NOT NULL,
`c` int(11) DEFAULT NULL,
KEY (`ftime`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
PARTITION BY RANGE (YEAR(ftime))
(PARTITION p_2017 VALUES LESS THAN (2017) ENGINE = InnoDB,
PARTITION p_2018 VALUES LESS THAN (2018) ENGINE = InnoDB,
PARTITION p_2019 VALUES LESS THAN (2019) ENGINE = InnoDB,
PARTITION p_others VALUES LESS THAN MAXVALUE ENGINE = InnoDB);
insert into t values('2017-4-1',1),('2018-4-1',1);
图 1 表 t 的磁盘文件
在表 t 中初始化插入了两行记录,按照定义的分区规则,这两行记录分别落在 p_2018 和 p_2019 这两个分区上。
可以看到,这个表包含了一个.frm 文件和 4 个.ibd 文件,每个分区对应一个.ibd 文件。也就是说:
- 对于引擎层来说,这是 4 个表;
- 对于 Server 层来说,这是 1 个表。
你可能会觉得这两句都是废话。其实不然,这两句话非常重要,可以帮我们理解分区表的执行逻辑。
二、分区表的引擎层行为
举个在分区表加间隙锁的例子,目的是说明对于 InnoDB 来说,这是 4 个表。
图 2 分区表间隙锁示例
这里顺便复习一下,在第 21 篇文章和你介绍的间隙锁加锁规则。
我们初始化表 t 的时候,只插入了两行数据, ftime 的值分别是,'2017-4-1' 和'2018-4-1' 。session A 的 select 语句对索引 ftime 上这两个记录之间的间隙加了锁。如果是一个普通表的话,那么 T1 时刻,在表 t 的 ftime 索引上,间隙和加锁状态应该是图 3 这样的。