将额外的HASH分区添加到已经HASH分区的表中

问题描述 投票:1回答:2

嗨,我目前有一个有100个HASH分区的表。我已经决定,由于未来的扩展,现在需要增加到1000个分区。

我是否需要从表中删除分区,然后添加1000个分区,或者有没有办法将额外的900个分区添加到已分区的表中?

我分区的方式是使用下面的代码。

ALTER TABLE t1
PARTITION BY HASH(venue_id)
PARTITIONS 100;

还有一种方法可以估算为我的表添加1000个分区需要多长时间?我将使用perconas工具之一来阻止表锁定。 https://www.percona.com/doc/percona-toolkit/LATEST/pt-online-schema-change.html

mysql partitioning
2个回答
1
投票

您无需删除分区以进行重新分区。无论如何,它会将行插入到新表中,因此您可以在一个步骤中执行此操作。

只需ALTER TABLE并定义新的分区方案:

ALTER TABLE t1
PARTITION BY HASH(venue_id)
PARTITIONS 1000;

或者使用pt-online-schema-change:

pt-online-schema-change h=myhost,D=mydatabase,t=t1 
  --alter "PARTITION BY HASH(venue_id) PARTITIONS 1000" 
  --execute

(我在那里放置换行符以避免换行,但这是一个命令。)


关于预测ETA完成,我忘了评论你的另一个问题。

Percona脚本的一个优点是它可以报告进度,您可以从中获得完成的估计。虽然在我们的环境中,我们发现它不是很准确。它有时可以报告它在几小时内完成了99%。

另请注意,Percona脚本不是100%没有锁定。它需要在运行的开始和结束时简要地进行独占元数据锁定,因为它需要创建触发器,然后重命名表并在结束时删除触发器。任何查询,甚至是只读的SELECT,都会阻止元数据锁定。如果您在完成脚本时遇到问题,请确保您对表运行的任何查询和事务都快速完成(否则您必须终止它们)。


0
投票

PARTITION BY HASH几乎没用。我不希望它可以帮助你分100个分区,也不会分1000个分区。

通过安排将venue_id作为PRIMARY KEY的第一列,你可以获得更多的收益。

查询总是有一个venue_id吗? (如果没有选项变得更加混乱。)现在,我将假设你总是有WHERE venue_id = constant

您有一个多维索引问题。 INDEXes只是一个维度,所以事情变得棘手。但是,分区可用于排序获取二维索引。

让我们选择day_epoch作为分区键并使用PARTITION BY RANGE(day_epoch)。 (如果将其从4字节INT更改为3字节DATE,则使用PARTITION BY RANGE(TO_DAYS(day_epoch)))。

然后让我们决定PRIMARY KEY。注意:添加或删除分区时,应重新考虑PK。请记住,PK是一个独特的索引。数据集中在PK上。 (但是,跨分区不保证唯一性。)

所以...

PARTITION BY RANGE(day_epoch)

PRIMARY KEY(venue_id, zone_id, id)  -- in this order

没有分区,我建议

PRIMARY KEY(venue_id, zone_id, day_epoch, id)

通常,任何索引(包括PK)都应该从使用=测试的任何列开始。然后IN,然后最多一个'范围'。

为了PK的唯一性要求,我把id放在了最后。

因此,查询执行如下操作:

  1. “分区修剪” - 可能根据日期分为单个分区。
  2. 将PK直接向下钻到所讨论的一个venue_id的连续行。
  3. 根据zone_ids跨数据进行跳房子。 (在某些情况下,这可能是范围扫描而不是跳跃。这取决于版本,ID的数量,ID的值,以及月亮的相位。
  4. (如果它到目前为止)然后得到所需的日期。

从巨大的表中获取大量行时,最重要的是最小化磁盘命中。我刚刚描述的内容可能比其他情况更好。对venue_id进行分区仅对该列有帮助,但对其余列没有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.