Mysql分区随时间变化

Mysql分区随时间变化,mysql,sql,Mysql,Sql,我有一个表,它会随着时间的推移而变大,而且我只需要少量的数据,比如说过去7天的数据 我想对它进行配置,使7天的数据在一个分区中,然后在下一个分区中。这样,我将只保留两个分区并归档其他分区 我读过关于MySQL分区的文章,但文章中创建分区的方法是,我们在只创建表的同时指定所有分区 我不确定在我们长时间添加分区逻辑的情况下,这是否是最好的方法 有什么想法吗?不幸的是,这将是一个相当手工的过程。最好的办法是每周提前创建分区,然后有一个定期运行的作业将旧数据归档到“catchall”分区中 e、 g.与

我有一个表,它会随着时间的推移而变大,而且我只需要少量的数据,比如说过去7天的数据

我想对它进行配置,使7天的数据在一个分区中,然后在下一个分区中。这样,我将只保留两个分区并归档其他分区

我读过关于MySQL分区的文章,但文章中创建分区的方法是,我们在只创建表的同时指定所有分区

我不确定在我们长时间添加分区逻辑的情况下,这是否是最好的方法


有什么想法吗?

不幸的是,这将是一个相当手工的过程。最好的办法是每周提前创建分区,然后有一个定期运行的作业将旧数据归档到“catchall”分区中

e、 g.与:

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') )
);
MySQL中没有“自动”分区管理。我们必须运行一些特定的SQL语句来从分区表中添加和删除分区

我们使用一个cron作业自动化了任务,该作业运行一个MySQL过程,我们编写该过程来删除(交换)旧分区,并运行另一个过程来添加新分区。这些程序是特定于特定表格的

我们的表在
时间戳
列上按
范围
进行分区。分区表达式类似于
UNIX\u时间戳(col)

为了添加一个新分区,我们重新组织
MAXVALUE
分区,它总是(或应该总是)空的,因此操作非常快。我们动态准备并执行以下形式的语句:

 ALTER TABLE ourtable REORGANIZE PARTITION pmax 
 INTO ( PARTITION pn_name VALUES LESS THAN (UNIX_TIMESTAMP(pn_date))
      , PARTITION pmax    VALUES LESS THAN MAXVALUE)
为了为新分区(pn_name)获取新的日期值,我们从第二个分区到最后一个分区(最后一个分区是MAXVALUE分区)获取
partition_description
值,并向其添加7天以获取要使用的
pn_date
字符串。我们使用相同的值为新分区生成pn_名称。(我们按照如下模式命名分区:
p20161030
基于分区描述中的日期值,例如
UNIX\u时间戳('2016-10-30')

(此信息是从一个相当复杂的查询中获得的,其中包含对
信息\u schema.partitions
视图的两个引用

在另一个删除旧分区的过程中,我们实际上将旧分区“交换”到一个归档表中(归档表稍后会备份,并由另一个任务删除)

该过程基本上运行以下一系列语句:

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` ;
(我希望有一种更干净的方法,在一条语句中创建一个新的未分区表,例如a
create table…LIKE…unpartitioning
,但如果没有,我们就选择了两条单独的语句。)

仅仅删除最旧的分区将是一个更简单的过程

为了获得关于最旧分区的信息,我们的查询可能有些过火了。但这是大多数“魔法”发生的地方。只是想让您了解一下该查询是什么样子的

 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
来自信息\u schema.p1
联接信息\u schema.px分区
在px.table_schema='ourdatabase'
和px.table_name='ourtable'
和px.partition_method='RANGE'
和px.partition_表达式='UNIX_时间戳(ourcol)'
和px.partition_description='MAXVALUE'
其中p1.table_schema='ourdatabase'
和p1.table_name='ourtable'
和p1.partition_method='RANGE'
和p1.partition_表达式='UNIX_时间戳(ourcol)'
和p1.u说明“最大值”

p1.partition_description+0您是否在询问是否可以将现有表更改为使用分区?@e4c5我已经读过,可以这样做,通过更改表以包含新分区,我正在寻找其他方法或至少更容错的方法。为什么您觉得更改表不安全?@e4c5我需要这样做使用计划的方法删除旧分区并创建一个,我最初想将其作为cron作业。刚才我在mysql中搜索并找到了事件调度。我应该使用mysql调度来完成这项工作吗?在生产系统中,我可以更改表(尽管它的分区不同)?Alter table创建分区的速度会很慢,但除此之外别无选择(如果您想使用分区)