上周讲了Oracle的在线非分区变成分区,今天讲讲其他的。首先是MySQL的,创建一个简单的表,模拟写入一点数据。
实验步骤如下:
mysql> CREATE TABLE t1 (id int NOT NULL
AUTO_INCREMENT, a int, t datetime NOT NULL, PRIMARY KEY (id) );
Query OK, 0 rows affected (0.29 sec)
mysql> insert into t1 (a,t) values
(1,'2022-01-01');
Query OK, 1 row affected (0.06 sec)
mysql> insert into t1 (a,t) values
(2,'2022-02-01');
Query OK, 1 row affected (0.09 sec)
mysql> insert into t1 (a,t) values
(4,'2022-03-01');
Query OK, 1 row affected (0.03 sec)
mysql> insert into t1 (a,t) values
(3,'2022-04-01');
Query OK, 1 row affected (0.02 sec)
mysql> insert into t1 (a,t) values
(5,'2022-05-01');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t1 (a,t) values
(6,'2022-06-01');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t1 (a,t) values
(7,'2022-07-01');
Query OK, 1 row affected (0.00 sec)
查询一下数据,普通的表。顺便看一下表结构。
如果要把非分区表转换成分区表,最主要的是分区键,而MySQL的时间范围分区键不能仅仅是时间,一定要主键+时间构成新的主键。
所以面临的是要删除主键和新建主键。
ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(id,t); 这句看上去简单,但是如果表大的话,实际上实施起来有困难的,如果很大的表几乎不现实。我的意思是停机做都有难度,更别说在线做了。
alter table t1 partition by
range(to_days(t))
-> (
-> PARTITION p1 VALUES LESS
THAN (to_days('2022-02-01')),
-> PARTITION p2 VALUES LESS
THAN (to_days('2022-03-01')),
-> PARTITION p3 VALUES LESS
THAN (to_days('2022-04-01')),
-> PARTITION p4 VALUES LESS
THAN (to_days('2022-05-01')),
-> PARTITION p5 VALUES LESS
THAN (to_days('2022-06-01')),
-> PARTITION p6 VALUES LESS
THAN (to_days('2022-07-01')),
-> PARTITION p7 VALUES LESS
THAN (to_days('2022-08-01'))
-> );
执行这个命令以后,可以看到查询表还是一样的方法。分区是对应用透明的。
但是如果我截断分区以后,分区的数据就被删除了。同样磁盘空间也马上释放。由于DDL很快,所以也不存在锁。最大的问题是在表很大时候,从非分区变成分区,很痛苦。这点上不得不说还是Oracle最省心了。 不过MySQL截断分区倒是省心,没有Oracle的update index的那个小参数。
既然TiDB兼容MySQL看看TiDB怎么做。用MySQL的方法做一遍,报错。不能执行。
查了资料没结果,最后问了原厂,目前看来是不能做的。即设计好了就这样,不要动。设计很重要啊。下一篇我们讲讲PG的。