You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Vertica集群数据库大小限制方法咨询:按时间或容量触发清理

嘿,我来帮你搞定Vertica集群的自动数据清理问题!针对你说的「早于30天删除」或「容量达100GB就清理」的双条件需求,我们可以分步骤实现,确保哪个条件先触发就执行清理操作。

一、优先推荐:用分区表实现高效时间驱动清理

如果你的业务表是按时间字段(比如event_date)分区的,这是最高效的清理方式——直接删除整个分区,比逐行删数据快得多,还能减少性能损耗:

-- 先确认要删除的分区范围
SELECT partition_key, partition_expression 
FROM partitions 
WHERE table_name = '你的表名' 
  AND partition_key < CURRENT_DATE - INTERVAL '30 days';

-- 删除早于30天的分区
ALTER TABLE 你的表名 DROP PARTITION WHERE partition_key < CURRENT_DATE - INTERVAL '30 days';

如果你的表还没分区,建议先做分区改造(比如按天/周分区),这会给后续的日常清理带来极大便利。

要是暂时没法改分区表,就用普通DELETE语句(注意大表删除可能锁表,尽量在业务低峰期执行):

-- 删除早于30天的数据
DELETE FROM 你的表名 WHERE event_timestamp < CURRENT_TIMESTAMP - INTERVAL '30 days';
COMMIT;

-- 可选:更新统计信息,避免查询性能下降
ANALYZE 你的表名;
二、容量驱动的清理逻辑

要实现容量阈值触发,首先得能准确获取当前数据库的使用容量,Vertica的系统视图可以帮我们做到:

-- 计算数据库总使用容量(单位GB)
SELECT SUM(used_bytes)/1024/1024/1024 AS total_used_gb 
FROM v_monitor.storage_containers 
WHERE is_active = TRUE;

当容量超过100GB时,我们可以先按时间清理,要是清理后仍超阈值,就循环删除更早的数据(比如每次多删7天),直到容量降到阈值以下。这里可以写个shell脚本自动化处理:

#!/bin/bash
DB_NAME="你的数据库名"
TABLE_NAME="你的表名"
CAPACITY_THRESHOLD=100  # 单位GB

# 获取当前容量
USED_GB=$(vsql -U dbadmin -d $DB_NAME -t -c "SELECT SUM(used_bytes)/1024/1024/1024 FROM v_monitor.storage_containers WHERE is_active = TRUE;")
USED_GB_NUM=$(printf "%.0f" "$USED_GB")

if [ $USED_GB_NUM -ge $CAPACITY_THRESHOLD ]; then
    echo "数据库容量已达${USED_GB_NUM}GB,触发清理..."
    # 先删30天前的数据(分区表用DROP PARTITION,普通表用DELETE)
    vsql -U dbadmin -d $DB_NAME -c "ALTER TABLE $TABLE_NAME DROP PARTITION WHERE partition_key < CURRENT_DATE - INTERVAL '30 days';"
    
    # 循环检查容量,直到低于阈值
    while [ $USED_GB_NUM -ge $CAPACITY_THRESHOLD ]; do
        USED_GB=$(vsql -U dbadmin -d $DB_NAME -t -c "SELECT SUM(used_bytes)/1024/1024/1024 FROM v_monitor.storage_containers WHERE is_active = TRUE;")
        USED_GB_NUM=$(printf "%.0f" "$USED_GB")
        if [ $USED_GB_NUM -ge $CAPACITY_THRESHOLD ]; then
            echo "容量仍超阈值,继续删除更早7天的数据..."
            vsql -U dbadmin -d $DB_NAME -c "ALTER TABLE $TABLE_NAME DROP PARTITION WHERE partition_key < CURRENT_DATE - INTERVAL '37 days';"
        fi
    done
    echo "清理完成,当前容量为${USED_GB_NUM}GB"
else
    echo "当前容量${USED_GB_NUM}GB,未达阈值"
fi
三、整合双条件,实现自动化定时执行

我们可以把「时间阈值」和「容量阈值」整合到一个脚本里,每天定时运行,只要满足其中一个条件就触发清理:

#!/bin/bash
DB_NAME="你的数据库名"
TABLE_NAME="你的表名"
TIME_THRESHOLD="30 days"
CAPACITY_THRESHOLD=100

# 检查是否有30天前的数据
HAS_OLD_DATA=$(vsql -U dbadmin -d $DB_NAME -t -c "SELECT COUNT(*) FROM $TABLE_NAME WHERE event_timestamp < CURRENT_TIMESTAMP - INTERVAL '$TIME_THRESHOLD';")
HAS_OLD_DATA_NUM=$(printf "%.0f" "$HAS_OLD_DATA")

# 检查当前容量
USED_GB=$(vsql -U dbadmin -d $DB_NAME -t -c "SELECT SUM(used_bytes)/1024/1024/1024 FROM v_monitor.storage_containers WHERE is_active = TRUE;")
USED_GB_NUM=$(printf "%.0f" "$USED_GB")

# 判断是否触发清理
TRIGGER_CLEAN=0
if [ $HAS_OLD_DATA_NUM -gt 0 ]; then
    echo "发现早于${TIME_THRESHOLD}的数据,触发清理"
    TRIGGER_CLEAN=1
fi
if [ $USED_GB_NUM -ge $CAPACITY_THRESHOLD ]; then
    echo "数据库容量达${USED_GB_NUM}GB,超阈值触发清理"
    TRIGGER_CLEAN=1
fi

if [ $TRIGGER_CLEAN -eq 1 ]; then
    # 先按时间清理
    vsql -U dbadmin -d $DB_NAME -c "ALTER TABLE $TABLE_NAME DROP PARTITION WHERE partition_key < CURRENT_DATE - INTERVAL '$TIME_THRESHOLD';"
    
    # 清理后检查容量,仍超则继续删更早数据
    USED_GB=$(vsql -U dbadmin -d $DB_NAME -t -c "SELECT SUM(used_bytes)/1024/1024/1024 FROM v_monitor.storage_containers WHERE is_active = TRUE;")
    USED_GB_NUM=$(printf "%.0f" "$USED_GB")
    DELETE_DAYS=37  # 初始多删7天
    while [ $USED_GB_NUM -ge $CAPACITY_THRESHOLD ]; do
        echo "容量仍超阈值,删除早于${DELETE_DAYS}天的数据..."
        vsql -U dbadmin -d $DB_NAME -c "ALTER TABLE $TABLE_NAME DROP PARTITION WHERE partition_key < CURRENT_DATE - INTERVAL '$DELETE_DAYS days';"
        USED_GB=$(vsql -U dbadmin -d $DB_NAME -t -c "SELECT SUM(used_bytes)/1024/1024/1024 FROM v_monitor.storage_containers WHERE is_active = TRUE;")
        USED_GB_NUM=$(printf "%.0f" "$USED_GB")
        DELETE_DAYS=$((DELETE_DAYS+7))
    done
    echo "清理完成,当前容量${USED_GB_NUM}GB"
else
    echo "未触发清理条件"
fi

然后设置crontab定时执行(比如每天凌晨2点,业务低峰期):

# 编辑定时任务
crontab -e
# 添加一行,日志输出到指定文件
0 2 * * * /path/to/你的清理脚本.sh >> /path/to/清理日志.log 2>&1
注意事项
  • 优先用分区表:分区表的清理操作性能远优于普通DELETE,还能避免大量日志生成。
  • 备份再清理:执行清理前确保数据已备份,或确认这些数据无需保留。
  • 测试先行:先在测试环境验证脚本逻辑,避免误删数据。
  • 监控告警:可以额外设置容量接近阈值的告警,提前预警,避免突发清理影响业务。

内容的提问来源于stack exchange,提问作者aleksss

火山引擎 最新活动