【发布时间】:2022-01-22 21:16:12
【问题描述】:
我正在尝试为我的test 表按分区进行动态拆分,该表在启动此脚本之前有 2 个分区 p0 和 p1:
DROP PROCEDURE IF EXISTS part_splitting;
DELIMITER //
CREATE PROCEDURE part_splitting()
BEGIN
SELECT DATE_FORMAT(MIN(createdOn), "%Y-%m-%d") INTO @s FROM test;
SELECT DATE_FORMAT(MAX(createdOn), "%Y-%m-%d") + INTERVAL 1 MONTH INTO @e FROM test;
SET @part_init := CONCAT( `ALTER TABLE test
PARTITION BY RANGE COLUMNS(createdOn) (
PARTITION p0 VALUES LESS THAN (`,@s,`)
)`);
PREPARE stmt1 FROM @part_init;
EXECUTE stmt1;
WHILE @s < @e DO
SELECT CONCAT('p', DATE_FORMAT(@s,'%y/%m/%d')) INTO title
SET @part_adding := CONCAT(`ALTER TABLE test ADD PARTITION (PARTITION `,title,` VALUES LESS THAN(`,DATE_FORMAT(@s,'%y/%m/%d'),`))`);
PREPARE stmt2 FROM @part_adding;
EXECUTE stmt2;
SET @s = @s + INTERVAL 1 day;
END WHILE;
END //
DELIMITER ;
CALL part_splitting();
目前,执行后出现此错误:
SQL Error [1054] [42S22]: Unknown column 'ALTER TABLE test
PARTITION BY RANGE COLUMNS(createdOn) (
PARTITION p0 VALUES LESS THAN (' in 'field list'
Unknown column 'ALTER TABLE test
PARTITION BY RANGE COLUMNS(createdOn) (
PARTITION p0 VALUES LESS THAN (' in 'field list'
Unknown column 'ALTER TABLE test
PARTITION BY RANGE COLUMNS(createdOn) (
PARTITION p0 VALUES LESS THAN (' in 'field list'
这里的关键思想是每周通过 SQL 事件动态创建分区,并从表中的最小天开始到最后一个日期加上提前 1 个月按天分割
这里有人有什么想法吗? 感谢您的帮助!
更新:
KUDOS 到 @Bill Karwin 寻求答案 - 真的很酷!
所以我终于有了这个工作语法:
DROP PROCEDURE IF EXISTS part_splitting;
DELIMITER $$
CREATE PROCEDURE part_splitting()
BEGIN
SELECT DATE_FORMAT(MIN(createdOn), "%Y-%m-%d") INTO @s FROM test;
SELECT DATE_FORMAT(MAX(createdOn), "%Y-%m-%d") + INTERVAL 1 MONTH INTO @e FROM test;
SET @part_init := CONCAT( 'ALTER TABLE test
PARTITION BY RANGE COLUMNS(createdOn) (
PARTITION p0 VALUES LESS THAN (',QUOTE(@s),'),
PARTITION pMax VALUES LESS THAN(MAXVALUE)
)');
PREPARE stmt1 FROM @part_init;
EXECUTE stmt1;
WHILE @s < @e DO
SET @s = @s + INTERVAL 1 day;
SELECT CONCAT('p', DATE_FORMAT(@s,"%Y%m%d")) INTO @title;
SET @part_adding := CONCAT('ALTER TABLE test ADD PARTITION ( PARTITION ',@title,' VALUES LESS THAN (',QUOTE(@s),') );');
PREPARE stmt2 FROM @part_adding;
EXECUTE stmt2;
END WHILE;
END
$$
DELIMITER ;
CALL part_splitting();
但是:
看起来这种定期运行和动态添加新分区的方法不起作用,因为我们遇到了错误:
"Error Code: 1493. VALUES LESS THAN value must be strictly increasing for each partition
这来自之前创建某些分区时的情况。
目前,我不知道如何在循环中跳过这些步骤。看起来我们每次都可以使用...REORGANIZE PARTITION pMax...,但为此,我们需要知道pMax之前的最后日期条件,它是在上次运行时创建的。 (但我猜这是另一个故事......)
【问题讨论】:
-
我不确定分区是否是这样工作的。您不想每周更改分区。您将其设置为预先按周分区,分区数量等于您的服务器数量。
PARTITION BY HASH(CONCAT(YEAR(your_date), WEEK(your_date))) -
当涉及到数据的分布时,看看 Ketama 算法,它提供了跨分布式密钥的一致性。也看看这个MongoDB sharding guide,因为它或多或少是等价的,以防你更熟悉MongoDB。
-
@DanielW。是的,这不是分区的常规情况。我们真的想每周(周末)每天重新分区,并根据表中的当前日期为该功能添加一些新分区。另一项工作会不时截断表格时间 - 因此无需保留空白章节,另一方面,我们需要一些新的章节。
标签: mysql stored-procedures partition