删除分区

使用 DROP_PARTITIONS 函数删除给定表的一个或多个分区键。可以指定单个分区键或分区键范围。

例如,对新表进行分区中显示的表按列 order_date 进行分区:

=> CREATE TABLE public.store_orders
(
    order_no int,
    order_date timestamp NOT NULL,
    shipper varchar(20),
    ship_date date
)
PARTITION BY YEAR(order_date);

鉴于此表定义,Vertica 会为每个唯一的 order_date 年份(在本例中为 2017、2016、2015 和 2014 年)创建一个分区键,并相应地将数据划分到不同的 ROS 容器中。

以下 DROP_PARTITIONS 语句从表 store_orders 中删除与分区键 2014 关联的所有订单记录:

=> SELECT DROP_PARTITIONS ('store_orders', 2014, 2014);
Partition dropped

拆分分区组

如果表 partition 子句包括 GROUP BY 子句,则分区将按其分区组键在 ROS 中合并。 DROP_PARTITIONS 随后可以指定给定分区组内或跨多个分区组的分区键范围。无论哪种情况,删除操作都要求 Vertica 拆分存储这些分区的 ROS 容器。为此,该函数的 force_split 参数必须设置为 true。

例如,上面显示的 store_orders 表可以使用 GROUP BY 子句重新分区,如下所示:

=> ALTER TABLE store_orders
     PARTITION BY order_date::DATE GROUP BY DATE_TRUNC('year', (order_date)::DATE) REORGANIZE;

由于之前删除了 2014 年的所有订单记录,order_date 值现在跨越三个年份(2017 年、2016 年和 2015 年)。因此,Tuple Mover 为每年创建三个分区组键,并为每个组指定一个或多个 ROS 容器。然后,它将 store_orders 分区合并到相应的组中。

以下 DROP_PARTITIONS 语句指定删除跨越两个年份(2014 年和 2015 年)的订单日期:

=> SELECT DROP_PARTITIONS('store_orders', '2015-05-30', '2016-01-16', 'true');
Partition dropped

删除操作要求 Vertica 从两个分区组(2015 和 2016)删除分区。这些组至少跨越两个 ROS 容器,必须拆分这些容器才能移除目标分区。因此,将函数的 force_split 参数设置为 true。

调度分区删除

如果硬件具有固定的磁盘空间,则可能需要配置一个定期执行的进程,以便通过删除分区来迁出旧数据。

例如,如果空间只够将数据存储固定的天数,请将 Vertica 配置为删除最旧的分区键。为此,请创建一个基于时间的作业调度程序(例如 cron),以计划在低负载期间删除分区键。

如果数据输入速率具有峰值和谷值,则可以使用以下两种技术来管理分区键删除方式:

  • 设置一个定期(每天)检查磁盘空间的进程。如果已用磁盘空间百分比超出特定阈值(例如 80%),则删除最旧的分区键。

  • 在分区中添加一个可根据行计数等指标递增的假列。例如,每次行计数增加 100 行时,该列可能会递增。设置一个定期(每天)查询此列的进程。如果新列中的值超出特定阈值(例如 100),请删除最旧的分区键,并将该列的值设置回 0。

表锁定

DROP_PARTITIONS 会在目标表上获取一个独占的 O 锁,以阻止可能会影响表数据的任何 DML 操作(DELETEUPDATEINSERTCOPY)。该锁还会阻止在 SERIALIZABLE 隔离级别发出的 SELECT 语句。

如果操作无法在目标表上获取 O lock,Vertica 将尝试关闭该表上运行的任何内部 tuple mover 会话。如果成功,则可以继续操作。在用户会话中运行的显式 Tuple Mover 操作不会关闭。如果显式 Tuple Mover 操作在表上运行,则该操作仅在 Tuple Mover 操作完成后继续。