向已经分区的表添加分区

God*_*a74 3 mysql database-partitioning

将另一个分区添加到已分区表的最佳方法是什么?

原始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)
Run Code Online (Sandbox Code Playgroud)

假设我只想添加 1 个额外的分区,在这种情况下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)
);
Run Code Online (Sandbox Code Playgroud)

如果是这种情况,究竟会发生什么?

未包含在此语句中的旧分区是否会被删除(例如 p001 - p058)?

这样做是否会清除表中的任何现有数据(例如,p059 中的数据)?

谢谢!

Bil*_*win 8

您不必重新定义所有较早的分区。

将处理小于 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)
);
Run Code Online (Sandbox Code Playgroud)

此重组操作不会影响所有较早的分区。

如果在最后一个分区仍然是空的(即它包含零行)时执行此重组,则不需要数据复制,并且操作应该几乎是即时的。

如果您忘记进行重新组织,而最后一个分区收集了一些行,那么重新组织它为时不晚——但这需要一点时间,与您拆分的分区中的行数成正比。重组有数据的分区确实需要复制数据行,但只需要复制您正在重组的分区的行。较早的分区仍保持不变。

有关更多详细信息,请参阅https://dev.mysql.com/doc/refman/5.7/en/partitioning-management-range-list.html