我有一个包含 3.2TB 数据的表,位于名为 default_partition 的分区中,所有写入/读取都进入该分区,因为我们在表上定义了分区,如下所示:
PARTITION BY RANGE (to_days(created_at))
PARTITION 2024_03_19 VALUES LESS THAN (739330) ENGINE = InnoDB,
PARTITION default_partition VALUES LESS THAN MAXVALUE ENGINE = InnoDB)
我们希望从default_partition中删除超过7天的数据,并希望将新数据保存到基于created_at列的单独的每日分区中,例如“2024_06_06”,“2024_06_07”,“2024_06_08”..等。其中我们只想保留最近 7 天的数据,并且我们将通过应用程序调度程序不断删除超过 7 天的分区(如果存在)。
但似乎要实现这一点,我必须使用以下方法重新组织default_partition:
Query 1: ALTER TABLE mytable REORGANIZE PARTITION default_partition INTO (
PARTITION past VALUES LESS THAN (TO_DAYS('2022-04-05')),
PARTITION default_partition VALUES LESS THAN MAXVALUE
)
一旦执行上述查询,default_partition现在应该变空,然后运行日常调度程序,我们可以使用下面给出的示例查询继续创建未来的分区,以便第6/7/8...等的所有新数据都将进入它们的自己的分区。
ALTER TABLE mytable REORGANIZE PARTITION default_partition INTO (
PARTITION '2022-04-05' VALUES LESS THAN (TO_DAYS('2022-04-06')),
PARTITION default_partition VALUES LESS THAN MAXVALUE
)
ALTER TABLE mytable REORGANIZE PARTITION default_partition INTO (
PARTITION '2022-04-06' VALUES LESS THAN (TO_DAYS('2022-04-07')),
PARTITION default_partition VALUES LESS THAN MAXVALUE
)... etc.
问题:-
运行上面的查询 1 会将 3.2TB 的数据复制到分区:“2022-04-05”,我不确定是否可以在生产中完成而无需任何停机。
有没有一种方法可以让我创建未来的分区,如“2024-04-07”、“2024-04-08”等,而无需触摸 default_partition 中的数据,目前和未来的数据将保存到这些分区中&一旦我们在这些分区中拥有了最近 7 天的数据,我们将通过一些停机时间来删除 default_partition 中的旧数据。
我什至在想是否应该创建一个新表并在接下来的 7 天内开始在该表上读/写,然后删除旧表,这也可以使我免于停机,但这需要在很多地方更改代码。
在零停机或根本不停机的情况下删除 default_partition 中超过 7 天的数据的最佳方法是什么?
恐怕如果不对该分区进行表复制,就无法更改当前分区的定义。
实现您想要的目标的正确方法是创建空分区并在表开始填充数据之前扩展表。
换句话说,使用REORGANIZE PARTITION
分割最后一个分区(值小于 MAXVALUE 的分区),同时该分区仍为空。您可以使用在线架构更改工具(例如
pt-online-schema-change 或 gh-ost)来重新分区,从而减少停机时间。停机时间会很短,因为表需要在更改结束时切换到重组版本,但这应该是暂时的。
但即使使用这些工具,您也需要足够的可用磁盘空间来保存表的完整副本。不仅分区被重组,表的其余部分也被重组。还有二进制日志,其大小可能与表大致相同。