将另一个分区添加到已分区的表中的最佳方法是什么?
原始CREATE TABLE
语句如下:
CREATE TABLE `command_log` (
`id` bigint(20) NOT NULL,
`insert_time` datetime NOT NULL,
`start_time` timestamp NULL DEFAULT '0000-00-00 00:00:00',
`end_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`command` varchar(255) NOT NULL,
`parameters` varchar(255) DEFAULT NULL,
`result` mediumblob,
`status` int(11) NOT NULL,
PRIMARY KEY (`id`,`insert_time`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY RANGE (to_days(insert_time))
(PARTITION p001 VALUES LESS THAN (736237) ENGINE = InnoDB,
PARTITION p002 VALUES LESS THAN (736268) ENGINE = InnoDB,
PARTITION p003 VALUES LESS THAN (736298) ENGINE = InnoDB,
...
PARTITION p064 VALUES LESS THAN (738156) ENGINE = InnoDB,
PARTITION p065 VALUES LESS THAN (738187) ENGINE = InnoDB,
PARTITION p066 VALUES LESS THAN (738215) ENGINE = InnoDB,
PARTITION p067 VALUES LESS THAN MAXVALUE ENGINE = InnoDB)
假设我想只添加一个额外的分区,在本例中为p067
。这是否需要整个ALTER TABLE
语句,例如:
ALTER TABLE command_log
PARTITION by range (to_days(insert_time))
(
partition p059 VALUES LESS THAN (to_days('2020-08-01'))
, partition p060 VALUES LESS THAN (to_days('2020-09-01'))
, partition p061 VALUES LESS THAN (to_days('2020-10-01'))
, partition p062 VALUES LESS THAN (to_days('2020-11-01'))
, partition p063 VALUES LESS THAN (to_days('2020-12-01'))
, partition p064 VALUES LESS THAN (to_days('2021-01-01'))
, partition p065 VALUES LESS THAN (to_days('2021-02-01'))
, partition p066 VALUES LESS THAN (to_days('2021-03-01'))
, partition p067 VALUES LESS THAN (to_days('2021-04-01'))
, partition p068 VALUES LESS THAN (MAXVALUE)
);
如果是这种情况,究竟会发生什么?
此语句中未包含的旧分区是否被删除(例如p001 - p058)?
这样做是否会消除表中的任何现有数据(例如,p059中的数据)?
谢谢!
答案 0 :(得分:1)
您不必重新定义所有早期分区。
它是范围分区表中的常见操作,用于将处理小于MAXVALUE的值的最后一个分区拆分为特定范围的几个新分区。您可以使用REORGANIZE PARTITION执行此操作。
例如,要将最后一个分区拆分为两个新分区以获取固定日期范围,再加上最后一个新的maxvalue分区:
ALTER TABLE command_log REORGANIZE PARTITION p067 INTO (
partition p067 VALUES LESS THAN (TO_DAYS('2021-04-01'))
, partition p068 VALUES LESS THAN (TO_DAYS('2021-05-01'))
, partition p069 VALUES LESS THAN (MAXVALUE)
);
此重组操作不会触及所有早期分区。
如果你在最后一个分区仍为空(即它包含零行)时进行重新组织,那么就不需要复制数据,操作应该是瞬时的。
如果您忘记进行重新组织,并且最后一个分区收集一些行,那么重新组织它还为时不晚 - 但这需要一点时间,比例到您拆分的分区中的行数。重新组织具有数据的分区确实需要复制数据行,但只需要复制要重组的分区的行。早期的分区仍未受到影响。
有关详细信息,请参阅https://dev.mysql.com/doc/refman/5.7/en/partitioning-management-range-list.html。
答案 1 :(得分:0)
对于在 现有表中最初没有任何分区的动态表,在Mysql 8中动态创建分区也存在相同的问题。
我必须为将来的日期添加分区,并不断添加。
我要解决的步骤:
获取最新的分区名称(以包含日期的方式创建分区名称)
如果不存在分区日期,则使用“范围”基本机制创建分区。 查询就像创建分区:
ALTER TABLE <tableName> PARTITION BY RANGE (TO_DAYS(<columnName>)) (
PARTITION p20200527 VALUES LESS THAN (TO_DAYS('2020-05-28')),
PARTITION p20200528 VALUES LESS THAN (TO_DAYS('2020-05-29')),
PARTITION p20200529 VALUES LESS THAN (TO_DAYS('2020-05-30')),
PARTITION p20200530 VALUES LESS THAN MAXVALUE);
一旦在表上有了分区,我们就只能使用“重新组织”添加分区。
ALTER TABLE <tableName> REORGANIZE PARTITION p20200730 INTO (
PARTITION p20200530 VALUES LESS THAN (TO_DAYS('2020-05-31')),
PARTITION p20200531 VALUES LESS THAN (TO_DAYS('2020-06-01')),
PARTITION p20200601 VALUES LESS THAN (TO_DAYS('2020-06-02')),
PARTITION p20200602 VALUES LESS THAN MAXVALUE);
最底行是: 如果表上没有任何分区,并且想在任何日期列中添加它,则可以随时添加。使用基于“范围”的机制在表上按日期划分分区后,如果要添加更多分区,请使用“重新组织”添加这些分区。