在DB2数据库分区环境中,业务表会依据分区键进行哈希计算,将行分散到分区组内的各个数据库分区。如果分区键基数较低、数据本身存在明显热点,或者后续扩容加入了新分区,原有数据不会自动迁移到新分区上,分区组就会出现数据倾斜。此时执行REDISTRIBUTE DATABASE PARTITION GROUP命令,可以强制DB2重新计算所有符合条件的表的分区哈希值,并按新映射移动行。

一、数据倾斜的识别与影响
要判断是否需要重新分布,首先要观察每个数据库分区上的行数。假设销售订单表sales.orders以order_id作为分区键,在4个分区组成的组中,可以通过下面的SQL查看实际分布。查询需要在数据库连接后执行,DBPARTITIONNUM函数返回行所在分区的编号。
SELECT DBPARTITIONNUM(order_id) AS dbpart,
COUNT(*) AS cnt
FROM sales.orders
GROUP BY DBPARTITIONNUM(order_id)
ORDER BY dbpart;
如果结果类似分区0有500万行,分区1只有20万行,分区2和分区3大约300万行,就说明数据已经出现明显倾斜。倾斜带来的问题不只是磁盘占用不均,更重要的是优化器在做分区内并行扫描时,最慢的分区会拖慢整个查询。对于关联、聚合这类需要跨分区交换数据的操作,单分区热点还会导致内存和临时表空间压力集中。
造成倾斜的常见原因有三个:一是分区键选择不当,例如用性别、状态等低基数字段做哈希键;二是业务数据增长后,某类键值占比突然升高;三是执行过ADD DBPARTITIONNUM新增分区,但已有表没有跟随新分区重新映射。前两种情况需要重新评估分区键,而第三情况通过REDISTRIBUTE命令即可解决。
二、REDISTRIBUTE命令的核心语法
REDISTRIBUTE DATABASE PARTITION GROUP的作用对象是整个分区组,而不是单张表。执行后,该分区组内所有使用分区键的表都会被重新计算哈希分布。常用形式是UNIFORM,即把每个表的数据在所有目标分区上平均分配。这种模式适合新增分区后让数据均匀落到包括新分区在内的所有节点。
db2 "REDISTRIBUTE DATABASE PARTITION GROUP pg_order UNIFORM"
如果不想平均分布,而是根据每个分区的硬件能力或磁盘容量设置不同权重,可以使用USING DISTFILE子句,指定一个分布文件。DISTFILE中描述每个分区的相对权重或行数范围,适合分区节点配置不一致的环境。命令写法如下。
db2 "REDISTRIBUTE DATABASE PARTITION GROUP pg_order USING DISTFILE /db2data/pg_order.dist"
执行窗口内如果希望减少日志压力,可以考虑NOT ROLLFORWARD选项。该选项会阻止重新分布过程被前滚恢复,但操作完成后需要立即做备份,否则数据库可能无法从日志中恢复到一致状态。生产环境除非有明确的备份策略,否则不建议随意添加NOT ROLLFORWARD。
db2 "REDISTRIBUTE DATABASE PARTITION GROUP pg_order UNIFORM NOT ROLLFORWARD"
需要注意,REDISTRIBUTE命令需要在数据库连接可用的情况下执行,通常由具有SYSADM或DBADM权限的用户在catalog分区节点上运行。命令执行期间,分区组内的表会被置于只读或锁定状态,因此必须安排在维护窗口。
三、执行前的检查与准备工作
重新分布不是简单的单条命令操作,之前要完成几项检查。首先确认分区组当前包含哪些分区,以及目标分区是否都已加入数据库分区配置。可以通过系统表SYSCAT.DBPARTITIONGROUPS和SYSCAT.DBPARTITIONGROUPDEF查看分区组定义。另外一个更直接的方法是查询数据库分区号列表,确认没有遗漏。
其次要检查目标分区组的表是否有主键或唯一约束。DB2在重新分布时会移动行,移动过程中需要维护索引和约束,如果存在未提交事务或长事务,移动会等待甚至失败。建议在执行前断开非必要连接,降低并发事务干扰。
日志空间是另一个重点。重新分布会像大量INSERT和DELETE一样产生事务日志,如果活动日志目录空间不足,操作会中断并回滚。可以提前估算分区组表的总大小,按至少同等规模预留归档日志空间。也可以将数据库设置为归档日志模式并保证归档磁盘充足。
此外,重新分布表时如果表中存在LOB列或XML列,可能需要额外的临时表空间。确保临时表空间所在文件系统有足够空间。完成这些检查后,最好先在一个测试分区组上演练命令,并记录执行时间,为生产维护窗口提供参考。
四、执行流程与验证结果
下面给出一个完整的执行流程。假设订单表所在分区组名为pg_order,原始包含0、1、2三个分区,现在新增了分区3,希望订单数据均匀分布到4个分区。首先在catalog节点上执行重新分布命令。
db2 connect to sample db2 "REDISTRIBUTE DATABASE PARTITION GROUP pg_order UNIFORM" db2 terminate
命令执行时间取决于表大小和分区间网络速度。执行期间不要终止进程或重启数据库。完成后,再次运行第一部分的行数查询,检查每个分区的行数是否接近。例如4分区各约300万行,说明重新分布成功。
SELECT DBPARTITIONNUM(order_id) AS dbpart,
COUNT(*) AS cnt
FROM sales.orders
GROUP BY DBPARTITIONNUM(order_id)
ORDER BY dbpart;
除了行数均衡,还可以查看表空间的容器占用变化。倾斜严重的分区在重新分布后,高水位标记可能不会立即下降,但数据页使用会随REORG和RUNSTATS进一步优化。建议重新分布完成后,对相关表执行RUNSTATS更新统计信息,让优化器掌握新的数据分布。
db2 "RUNSTATS ON TABLE sales.orders WITH DISTRIBUTION AND DETAILED INDEXES ALL"
如果重新分布过程中报错,常见的错误包括日志空间不足、分区不可达、表定义与分布键冲突。日志不足需要扩大日志空间后重试;分区不可达要检查db2nodes.cfg以及各分区实例状态;表定义冲突则需要确认分区组内所有表都使用相同的分区键定义。
五、常见误区与维护建议
一个常见的误区是认为REDISTRIBUTE会自动调整所有数据库分区组。实际上它只针对命令中指定的那个分区组,如果数据库有多个分区组,需要分别执行。另一个误区是认为重新分布后必须重建表索引,其实DB2会在移动行时自动维护索引,但RUNSTATS仍然是必要的。
重新分布完成后,新增分区的数据分布会改善,但这并不代表以后不会再倾斜。如果倾斜是由分区键选择不当导致的,应该重新评估键值。比如订单表长期使用地区字段做分区键,而业务集中在一个地区,哈希分布也会受影响,因为哈希算法会把相同键值映射到同一个分区。此时应该结合业务查询模式更换分区键,或者使用随机分布的表。
对于大型表,重新分布的时间可能持续数小时。生产环境建议使用在线重组工具或分区级迁移方案,并提前与应用方沟通停机窗口。如果没有停机窗口,可以分阶段进行,先移动历史分区数据,再处理活跃分区。总之,REDISTRIBUTE DB2数据库分区组是一个有效但有代价的操作,合理规划分区键和提前监控数据分布,才能减少被迫执行重新分布的概率。
DB2重新分布数据库分区组REDISTRIBUTE PARTITION GROUP修改时间:2026-10-07 05:35:41