项目中有的表空间太大,且行数太多,故决定对一些表进行分库分表。再研究选型方案的时候发现经常使用的一些分库分表的解决方案对业务代码修改较多,故决定采用MySQL的分区方案。html
其实在我我的看来,分区表就是MySQL帮咱们实现了底层的分库分表,不须要涉及业务代码的修改,不须要关注分布式事务。由于就访问数据库而言,逻辑上仍是只有一个表,可是实际上确有多个物理分区对象组成,会根据具体的分区规则查询具体的分区。mysql
介绍一下此次实践的表,表空间大小172G,1亿2千万条记录。sql
数据库版本:RDS MySQL 5.6数据库
工具:阿里云DTS分布式
例以下面语句:函数
SELECT * FROM t PARTITION(p0,p1)WHERE c <5 仅选择与WHERE条件匹配的分区p0和p1中的记录工具
目前MySQL支持范围分区(RANGE),列表分区(LIST),哈希分区(HASH)以及KEY分区四种。测试
本文是以范围分区(RANGE)对时间进行的分区的,故我就简单介绍一下RANGE分区。更多分区类型详见官方文档MySQL 5.6 分区类型阿里云
基于一个给定连续区间的列值,根据区间分配分区。最多见的是基于时间字段。其实基于分区的列最好是整型,若是日期型的可使用函数转换为整型。MySQL 5.6支持的分区函数spa
本例中使用TO_DAYS函数
CREATE TABLE members ( id VARCHAR(25) NOT NULL, firstname VARCHAR(25) NOT NULL, lastname VARCHAR(25) NOT NULL, username VARCHAR(16) NOT NULL, email VARCHAR(35), joindate DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY (id,joindate) USING BTREE, KEY idx_joindate (joindate) USING BTREE )ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT PARTITION BY RANGE (TO_DAYS(joindate)) ( PARTITION p0 VALUES LESS THAN (TO_DAYS('1960-01-01')), PARTITION p1 VALUES LESS THAN (TO_DAYS('1970-01-01')), PARTITION p2 VALUES LESS THAN (TO_DAYS('1980-01-01')), PARTITION p3 VALUES LESS THAN (TO_DAYS('1990-01-01')), PARTITION p4 VALUES LESS THAN MAXVALUE );
PS:像例子中的若是你有主键或惟一索引,你必须把你的分区键也加上,其中joindate就是分区键,要不建立会失败!
PS:像上面加了LESS THAN MAXVALUE,后面就不能新加分区了!!!
示例:
以下查询就会落在定义的p2分区内的索引上。故在查询的时候带上你的分区键就会走对应分区查询数据,若是你的条件跨越多个分区进行聚合函数SUM()、COUNT()的查询时,它会在每一个分区上并行处理。若是没有带分区键查询就会全表查询。
explain partitions select * from members WHERE joindate BETWEEN '1970-02-03' AND '1970-02-04';
我在迁移完数据进行查询的时候发现一个特别有意思的现象,同一条SQL若是分区键的时间区间不同,它会根据rows行数少的走不一样的范围索引。至于它底层是怎么实现的我就没去研究了
简单介绍了下范围分区,接下来讲一下对分区经常使用的一下操做。
分区管理包括对于分区的增长,删除,以及查询。更多详见官方文档MySQL 分区管理
对于RANGE和LIST分区:
alter table table_name add partition (partition p0 values ...(exp)) #例 ALTER TABLE members ADD PARTITION (TO_DAYS('2021-03-01'));
删除了分区,同时也将删除该分区中的全部数据。若是删除了分区致使分区不能覆盖全部值,那么插入数据的时候会报错。
alter table table_name drop partition p0;
SELECT * FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 'members';
前面说了那么多概念,我说一下本次把大表数据迁移到分区表的过程。
为何会选择DTS呢?由于它能够不停机迁移数据,支持全量迁移和增量迁移,对原表影响不大。
迁移过程以下:
参考官方文档:MySQL 5.6 分区
以上纯属我的观点,若有不对欢迎指正。