ALTER TABLE ourtable REORGANIZE PARTITION pmax
INTO ( PARTITION pn_name VALUES LESS THAN (UNIX_TIMESTAMP(pn_date))
, PARTITION pmax VALUES LESS THAN MAXVALUE)
DROP TABLE IF EXISTS `_et` ;
CREATE TABLE `_et` LIKE `rdg_point_value` ;
ALTER TABLE `_et` REMOVE PARTITIONING ;
ALTER TABLE `ourtable` EXCHANGE PARTITION `oldest_partition` WITH TABLE `_et` ;
ALTER TABLE `ourtable` DROP PARTITION `oldest_partition` ;
RENAME TABLE `et` TO `archive_oldest_partition` ;
(我希望有一种更干净的方法,可以在一条语句中创建一个新的未分区表,例如 CREATE TABLE ... LIKE ... WITHOUT PARTITIONING ,但没有这一点,我们决定在两个单独的声明。) 删除最旧的分区将是一个更简单的过程。 为了获得关于最旧分区的信息,我们的查询可能是过度的。但这是大部分“魔法”发生的地方。只是想让你知道这个查询是什么样的。。。
FROM information_schema.partitions p1
JOIN information_schema.partitions px
ON px.table_schema = 'ourdatabase'
AND px.table_name = 'ourtable'
AND px.partition_method = 'RANGE'
AND px.partition_expression = 'UNIX_TIMESTAMP(ourcol)'
AND px.partition_description = 'MAXVALUE'
WHERE p1.table_schema = 'ourdatabase'
AND p1.table_name = 'ourtable'
AND p1.partition_method = 'RANGE'
AND p1.partition_expression = 'UNIX_TIMESTAMP(ourcol)'
AND p1.partition_description <> 'MAXVALUE'
AND p1.partition_description + 0 <= UNIX_TIMESTAMP(DATE(NOW()) + INTERVAL -187 DAY)
AND p1.partition_ordinal_position = 1
PARTITION BY RANGE ( TO_DAYS(date) ) (
PARTITION pmin VALUES LESS THAN ( TO_DAYS('2016-10-02 00:00:00') ),
PARTITION p1 VALUES LESS THAN ( TO_DAYS('2016-10-09 00:00:00') ),
PARTITION p2 VALUES LESS THAN ( TO_DAYS('2016-10-16 00:00:00') ),
PARTITION p3 VALUES LESS THAN ( TO_DAYS('2016-10-23 00:00:00') ),
PARTITION pmax VALUES LESS THAN (MAXVALUE)
);
ALTER TABLE x REORGANIZE PARTITION pmin,p1 INTO (
PARTITION pmin VALUES LESS THAN ('2016-10-09 00:00:00')
);
ALTER TABLE x
ADD PARTITION px VALUES LESS THAN ( TO_DAYS('2016-10-30 00:00:00') )
);
2条答案
按热度按时间o7jaxewo1#
mysql中没有“自动”分区管理。我们必须运行一些特定的sql语句来从分区表中添加和删除分区。
我们使用cron作业自动化了任务,该作业运行我们编写的mysql过程来删除(交换)旧分区,并运行另一个过程来添加新分区。这些步骤是特定于特定表的。
我们的table是用
RANGE
在TIMESTAMP
列。分区表达式如下UNIX_TIMESTAMP(col)
.为了添加一个新的分区,我们重新组织
MAXVALUE
分区,它总是(或者应该总是)空的,所以操作非常快。我们动态地准备并执行以下形式的语句:要为新分区(pn\u name)获取新的日期值,我们采用
partition_description
从第二个分区到最后一个分区的值(最后一个分区是maxvalue分区),并向其添加7天以获得pn_date
要使用的字符串。我们使用相同的值为新分区生成pnu名称(我们按照如下模式命名分区:p20161030
基于分区描述中的日期值,例如。UNIX_TIMESTAMP('2016-10-30')
.(这些信息是从一个相当复杂的查询中获得的,其中有几个
information_schema.partitions
查看。在另一个删除旧分区的过程中,我们实际上将旧分区“交换”到一个存档表中(存档表稍后会备份,并由其他任务删除。)
该过程基本上运行一系列如下语句:
(我希望有一种更干净的方法,可以在一条语句中创建一个新的未分区表,例如
CREATE TABLE ... LIKE ... WITHOUT PARTITIONING
,但没有这一点,我们决定在两个单独的声明。)删除最旧的分区将是一个更简单的过程。
为了获得关于最旧分区的信息,我们的查询可能是过度的。但这是大部分“魔法”发生的地方。只是想让你知道这个查询是什么样的。。。
你也许可以用一个简单的查询来解决问题(我们的查询被设计成仅当“最旧”分区中的所有时间戳值都至少有六个月大,并且仅当定义了maxvalue分区时,才返回“最旧”分区。
每个过程都使用当前日期来查看添加或删除分区的“时间”(向前和向后的时间量被硬编码到过程中的查询中。。。如果还没有到时间,查询将返回0行。
这些过程每周只需要执行一次,我们将它们设计为任何“额外”运行都不会在指定的时间范围之外添加或删除分区。
我们计划每天执行这些过程,在大多数情况下,该过程运行一个返回零行的查询,然后退出。只有当查询返回一行时,才有工作要做。
shstlldc2#
不幸的是,这将是一个相当手工的过程。最好的办法是每周提前创建分区,然后定期运行一个作业,将旧数据归档到“catchall”分区中。
e、 g.带:
有几个空的分区和更高的日期坐在那里,然后每周做一次“轮班”没有什么坏处。只要在更改分区定义时,数据窗口按分区大小移动,就足够快了。
你的工作会像